[med-svn] [dicom3tools] 01/02: Imported Upstream version 1.00~20151213160232

Gert Wollny gert-guest at moszumanska.debian.org
Thu Dec 17 12:04:11 UTC 2015


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

gert-guest pushed a commit to branch master
in repository dicom3tools.

commit 9b32f0e8e840f58d71e8aba22b2c6f3b5953de6f
Author: Gert Wollny <gw.fossdev at gmail.com>
Date:   Thu Dec 17 13:00:16 2015 +0100

    Imported Upstream version 1.00~20151213160232
---
 BUGS                                               |   65 +
 CHANGES                                            | 3803 ++++++++++
 COPYRIGHT                                          |   28 +
 Configure                                          |   11 +
 Doxyfile                                           |  691 ++
 INSTALL                                            |  598 ++
 Imakefile                                          |  232 +
 Makefile                                           |   20 +
 NotAMakefile                                       |   20 +
 README                                             |   33 +
 TODO                                               |  179 +
 VERSION                                            |    1 +
 WARNINGS                                           |    1 +
 appsrc/Imakefile                                   |    6 +
 appsrc/acrnema/Imakefile                           |   73 +
 appsrc/acrnema/ancp.cc                             |  446 ++
 appsrc/acrnema/ancp.man                            |    0
 appsrc/acrnema/ancreate.cc                         |  703 ++
 appsrc/acrnema/ancreate.man                        |  266 +
 appsrc/acrnema/andiff.man                          |    0
 appsrc/acrnema/andiff.script                       |   21 +
 appsrc/acrnema/andump.cc                           |  569 ++
 appsrc/acrnema/andump.man                          |  134 +
 appsrc/acrnema/test.create.private.un.sh           |  199 +
 appsrc/acrnema/test.create.ut.sh                   |  146 +
 appsrc/dcdisp/Imakefile                            |   32 +
 appsrc/dcdisp/Notes.Web                            |   37 +
 appsrc/dcdisp/dcdisp.cc                            | 1428 ++++
 appsrc/dcdisp/dcdisp.cc.postsignextend             | 1355 ++++
 appsrc/dcdisp/dcdisp.cc_predynamic                 | 1375 ++++
 appsrc/dcdisp/dcdisp.man                           |  208 +
 appsrc/dcfile/Imakefile                            |  784 ++
 appsrc/dcfile/antodc.all.man                       |    0
 appsrc/dcfile/antodc.all.script                    |   40 +
 appsrc/dcfile/antodc.cc                            | 2018 +++++
 appsrc/dcfile/antodc.man                           |   78 +
 appsrc/dcfile/dcacqmap.man                         |  140 +
 appsrc/dcfile/dcacqmap.script                      |  338 +
 appsrc/dcfile/dcanon.man                           |    0
 appsrc/dcfile/dcanon.script                        |  604 ++
 appsrc/dcfile/dcarith.cc                           |  372 +
 appsrc/dcfile/dcarith.man                          |  121 +
 appsrc/dcfile/dcbriggs.cc                          |  160 +
 appsrc/dcfile/dcbriggs.man                         |  161 +
 appsrc/dcfile/dcburn.cc                            |  161 +
 appsrc/dcfile/dcburn.man                           |    0
 appsrc/dcfile/dcbzip2.man                          |   30 +
 appsrc/dcfile/dcbzip2.script                       |   16 +
 appsrc/dcfile/dcckovly.man                         |   36 +
 appsrc/dcfile/dcckovly.script                      |   62 +
 appsrc/dcfile/dccmp.man                            |    0
 appsrc/dcfile/dccmp.script                         |   21 +
 appsrc/dcfile/dccomb.cc                            |  324 +
 appsrc/dcfile/dccomb.man                           |    0
 appsrc/dcfile/dccp.cc                              |  210 +
 appsrc/dcfile/dccp.man                             |  195 +
 appsrc/dcfile/dccreate.cc                          |   58 +
 appsrc/dcfile/dccreate.man                         |   92 +
 appsrc/dcfile/dcdecmpr.cc                          | 1029 +++
 appsrc/dcfile/dcdecmpr.man                         |    0
 appsrc/dcfile/dcdecmpr.test.dcm                    |  Bin 0 -> 408 bytes
 appsrc/dcfile/dcdeflate.man                        |   30 +
 appsrc/dcfile/dcdeflate.script                     |   11 +
 appsrc/dcfile/dcdict.cc                            |   89 +
 appsrc/dcfile/dcdict.man                           |   59 +
 appsrc/dcfile/dcdiff.man                           |    0
 appsrc/dcfile/dcdiff.script                        |   21 +
 appsrc/dcfile/dcdirdmp.cc                          |   83 +
 appsrc/dcfile/dcdirdmp.man                         |  198 +
 appsrc/dcfile/dcdirmk.cc                           | 2176 ++++++
 appsrc/dcfile/dcdirmk.cc_sqlengths                 | 1737 +++++
 appsrc/dcfile/dcdirmk.man                          |  205 +
 appsrc/dcfile/dcdtchg.cc                           |  844 +++
 appsrc/dcfile/dcdtchg.h                            |   47 +
 appsrc/dcfile/dcdtchg.man                          |  200 +
 appsrc/dcfile/dcdump.cc                            |   71 +
 appsrc/dcfile/dcdump.man                           |   74 +
 appsrc/dcfile/dcencap.cc                           |  299 +
 appsrc/dcfile/dcencap.man                          |   82 +
 appsrc/dcfile/dcentvfy.cc                          |  863 +++
 appsrc/dcfile/dcentvfy.man                         |   58 +
 appsrc/dcfile/dcfile.cc                            |  198 +
 appsrc/dcfile/dcfile.man                           |  134 +
 appsrc/dcfile/dchist.cc                            |  228 +
 appsrc/dcfile/dchist.man                           |  117 +
 appsrc/dcfile/dcinflate.man                        |   31 +
 appsrc/dcfile/dcinflate.script                     |   17 +
 appsrc/dcfile/dciodvfy.cc                          | 2250 ++++++
 appsrc/dcfile/dciodvfy.man                         |  125 +
 appsrc/dcfile/dcj2k.man                            |   59 +
 appsrc/dcfile/dcj2k.script                         |   80 +
 appsrc/dcfile/dcjls.man                            |   43 +
 appsrc/dcfile/dcjls.script                         |   58 +
 appsrc/dcfile/dcjpeg.man                           |   63 +
 appsrc/dcfile/dcjpeg.script                        |   58 +
 appsrc/dcfile/dckey.cc                             |  202 +
 appsrc/dcfile/dckey.man                            |  147 +
 appsrc/dcfile/dclutburn.cc                         |  229 +
 appsrc/dcfile/dclutburn.man                        |    0
 appsrc/dcfile/dclutdmp.cc                          |  236 +
 appsrc/dcfile/dclutdmp.man                         |   76 +
 appsrc/dcfile/dclutmix.cc                          |  276 +
 appsrc/dcfile/dclutmix.man                         |    0
 appsrc/dcfile/dcmerge.cc                           |   93 +
 appsrc/dcfile/dcmerge.man                          |  157 +
 appsrc/dcfile/dcmkpres.cc                          |  766 ++
 appsrc/dcfile/dcmkpres.man                         |  101 +
 appsrc/dcfile/dcmulti.cc                           | 7996 ++++++++++++++++++++
 appsrc/dcfile/dcmulti.man                          |  462 ++
 appsrc/dcfile/dcmvhier.8only.man                   |    0
 appsrc/dcfile/dcmvhier.8only.script                |   90 +
 appsrc/dcfile/dcmvhier.all.man                     |    0
 appsrc/dcfile/dcmvhier.all.script                  |   23 +
 appsrc/dcfile/dcmvhier.datedesc.man                |   44 +
 appsrc/dcfile/dcmvhier.datedesc.script             |   85 +
 appsrc/dcfile/dcmvhier.datedescnoid.man            |   44 +
 appsrc/dcfile/dcmvhier.datedescnoid.script         |   77 +
 appsrc/dcfile/dcmvhier.man                         |   45 +
 appsrc/dcfile/dcmvhier.script                      |   73 +
 appsrc/dcfile/dcmvhier.uid.man                     |   45 +
 appsrc/dcfile/dcmvhier.uid.script                  |   73 +
 appsrc/dcfile/dcortho.cc                           |  318 +
 appsrc/dcfile/dcortho.man                          |    0
 appsrc/dcfile/dcostosr.cc                          |  369 +
 appsrc/dcfile/dcostosr.man                         |    0
 appsrc/dcfile/dcpatmpl.man                         |   32 +
 appsrc/dcfile/dcpatmpl.script                      |   51 +
 appsrc/dcfile/dcposn.cc                            |   92 +
 appsrc/dcfile/dcposn.man                           |   73 +
 appsrc/dcfile/dcpost.cc                            |  647 ++
 appsrc/dcfile/dcpost.man                           |    0
 appsrc/dcfile/dcproj.cc                            |  590 ++
 appsrc/dcfile/dcproj.man                           |    0
 appsrc/dcfile/dcrmmeta.cc                          |  157 +
 appsrc/dcfile/dcrmmeta.man                         |   43 +
 appsrc/dcfile/dcrmsfx.all.man                      |    0
 appsrc/dcfile/dcrmsfx.all.script                   |   15 +
 appsrc/dcfile/dcsmpte.cc                           |  144 +
 appsrc/dcfile/dcsmpte.man                          |  142 +
 appsrc/dcfile/dcsort.cc                            |  935 +++
 appsrc/dcfile/dcsort.man                           |  122 +
 appsrc/dcfile/dcsqextr.cc                          |  215 +
 appsrc/dcfile/dcsqextr.man                         |   68 +
 appsrc/dcfile/dcsrdiff.man                         |    0
 appsrc/dcfile/dcsrdiff.script                      |   24 +
 appsrc/dcfile/dcsrdump.cc                          |  518 ++
 appsrc/dcfile/dcsrdump.man                         |   72 +
 appsrc/dcfile/dcsrmrg.cc                           |  423 ++
 appsrc/dcfile/dcsrmrg.man                          |    0
 appsrc/dcfile/dcstats.cc                           |  207 +
 appsrc/dcfile/dcstats.man                          |  110 +
 appsrc/dcfile/dcsub.cc                             |  291 +
 appsrc/dcfile/dcsub.man                            |    0
 appsrc/dcfile/dcswab.man                           |    0
 appsrc/dcfile/dcswab.script                        |   21 +
 appsrc/dcfile/dctable.cc                           |  323 +
 appsrc/dcfile/dctable.man                          |  130 +
 appsrc/dcfile/dctopdf.cc                           |  102 +
 appsrc/dcfile/dctopdf.man                          |   49 +
 appsrc/dcfile/dctopgm8.cc                          | 1167 +++
 appsrc/dcfile/dctopgm8.man                         |  185 +
 appsrc/dcfile/dctopgx.cc                           |  251 +
 appsrc/dcfile/dctopgx.man                          |   74 +
 appsrc/dcfile/dctopnm.cc                           |  268 +
 appsrc/dcfile/dctopnm.cc.firstgo                   |  635 ++
 appsrc/dcfile/dctopnm.man                          |  122 +
 appsrc/dcfile/dctoraw.cc                           |  254 +
 appsrc/dcfile/dctoraw.man                          |   90 +
 appsrc/dcfile/dcuidchg.cc                          |  423 ++
 appsrc/dcfile/dcuidchg.man                         |  115 +
 appsrc/dcfile/dcunbzip2.man                        |   31 +
 appsrc/dcfile/dcunbzip2.script                     |   18 +
 appsrc/dcfile/dcuncat.cc                           |  893 +++
 appsrc/dcfile/dcuncat.man                          |  133 +
 appsrc/dcfile/dcunjls.man                          |   31 +
 appsrc/dcfile/dcunjls.script                       |   46 +
 appsrc/dcfile/dcunjpeg.20000802                    |    1 +
 appsrc/dcfile/dcunjpeg.all.man                     |    0
 appsrc/dcfile/dcunjpeg.all.script                  |   32 +
 appsrc/dcfile/dcunjpeg.man                         |   32 +
 appsrc/dcfile/dcunjpeg.script                      |  146 +
 appsrc/dcfile/dcunrgb.man                          |   32 +
 appsrc/dcfile/dcunrgb.script                       |  125 +
 appsrc/dcfile/makedcdtchgheader.sh                 |   17 +
 appsrc/dcfile/pbmtoovl.cc                          |  207 +
 appsrc/dcfile/pbmtoovl.man                         |   68 +
 appsrc/dcfile/pdftodc.cc                           |  196 +
 appsrc/dcfile/pdftodc.man                          |   61 +
 appsrc/dcfile/pgxtodc.cc                           |  268 +
 appsrc/dcfile/pgxtodc.man                          |   63 +
 appsrc/dcfile/pnmtodc.cc                           |  257 +
 appsrc/dcfile/pnmtodc.man                          |  199 +
 appsrc/dcfile/rawftodc.cc                          |  445 ++
 appsrc/dcfile/rawftodc.man                         |  137 +
 appsrc/dcfile/rawtodc.cc                           |  310 +
 appsrc/dcfile/rawtodc.man                          |  318 +
 appsrc/dcfile/testdcdirmkorder.sh                  |   27 +
 appsrc/dcfile/testy2k.antodc.sh                    |  317 +
 appsrc/dcfile/testy2k.sh                           |  317 +
 appsrc/dcintro/Imakefile                           |   14 +
 appsrc/dcintro/binin.so                            |    6 +
 appsrc/dcintro/binout.so                           |    6 +
 appsrc/dcintro/dcintro.man                         |  296 +
 appsrc/dcintro/gen.so                              |    3 +
 appsrc/dcintro/genin.so                            |    3 +
 appsrc/dcintro/genout.so                           |    3 +
 appsrc/dcintro/optin.so                            |   18 +
 appsrc/dcintro/optout.so                           |   68 +
 appsrc/dconvert/Imakefile                          |    6 +
 appsrc/dconvert/gaw/Imakefile                      |   37 +
 appsrc/dconvert/gaw/gawdump.cc                     |  112 +
 appsrc/dconvert/gaw/gawdump.man                    |   71 +
 appsrc/dconvert/gaw/gawtodc.cc                     |  140 +
 appsrc/dconvert/gaw/gawtodc.man                    |   81 +
 appsrc/dconvert/ge9800/Imakefile                   |   33 +
 appsrc/dconvert/ge9800/ge9800dump.cc               |   46 +
 appsrc/dconvert/ge9800/ge9800dump.man              |   43 +
 appsrc/dconvert/ge9800/ge9800todc.cc               |   77 +
 appsrc/dconvert/ge9800/ge9800todc.man              |   53 +
 appsrc/dconvert/gen/Imakefile                      |   38 +
 appsrc/dconvert/gen/gendump.cc                     |  103 +
 appsrc/dconvert/gen/gendump.man                    |   70 +
 appsrc/dconvert/gen/gentodc.all.script             |   11 +
 appsrc/dconvert/gen/gentodc.cc                     |  131 +
 appsrc/dconvert/gen/gentodc.dat.all.man            |    0
 appsrc/dconvert/gen/gentodc.dat.all.script         |   34 +
 appsrc/dconvert/gen/gentodc.man                    |   80 +
 appsrc/dconvert/gen/testy2k.sh                     |  183 +
 appsrc/dconvert/himr/Imakefile                     |   36 +
 appsrc/dconvert/himr/himrdump.cc                   |   46 +
 appsrc/dconvert/himr/himrdump.man                  |   43 +
 appsrc/dconvert/himr/himrtodc.cc                   |   77 +
 appsrc/dconvert/himr/himrtodc.man                  |   53 +
 appsrc/dconvert/himr/himrunid.man                  |    0
 appsrc/dconvert/himr/himrunid.script               |    0
 appsrc/dconvert/imtn/Imakefile                     |   33 +
 appsrc/dconvert/imtn/imtndump.cc                   |   50 +
 appsrc/dconvert/imtn/imtndump.man                  |   43 +
 appsrc/dconvert/imtn/imtntodc.cc                   |   81 +
 appsrc/dconvert/imtn/imtntodc.man                  |   53 +
 appsrc/dconvert/pace/Imakefile                     |   36 +
 appsrc/dconvert/pace/pacedump.cc                   |   46 +
 appsrc/dconvert/pace/pacedump.man                  |   43 +
 appsrc/dconvert/pace/pacetodc.cc                   |   77 +
 appsrc/dconvert/pace/pacetodc.man                  |   51 +
 appsrc/dconvert/pace/paceunid.man                  |   30 +
 appsrc/dconvert/pace/paceunid.script               |   31 +
 appsrc/dconvert/pq/Imakefile                       |   41 +
 appsrc/dconvert/pq/pqdump.cc                       |   46 +
 appsrc/dconvert/pq/pqdump.man                      |   43 +
 appsrc/dconvert/pq/pqsplit.cc                      |  400 +
 appsrc/dconvert/pq/pqsplit.man                     |    0
 appsrc/dconvert/pq/pqtodc.cc                       |   77 +
 appsrc/dconvert/pq/pqtodc.man                      |   53 +
 appsrc/dconvert/shim/Imakefile                     |   33 +
 appsrc/dconvert/shim/shimdump.cc                   |   50 +
 appsrc/dconvert/shim/shimdump.man                  |   43 +
 appsrc/dconvert/shim/shimtodc.cc                   |   81 +
 appsrc/dconvert/shim/shimtodc.man                  |   53 +
 appsrc/dconvert/signa/Imakefile                    |   35 +
 appsrc/dconvert/signa/sgndump.cc                   |   54 +
 appsrc/dconvert/signa/sgndump.man                  |   32 +
 appsrc/dconvert/signa/sgntodc.cc                   |  111 +
 appsrc/dconvert/signa/sgntodc.man                  |   31 +
 appsrc/dconvert/somp/Imakefile                     |   33 +
 appsrc/dconvert/somp/sompdump.cc                   |   45 +
 appsrc/dconvert/somp/sompdump.man                  |   43 +
 appsrc/dconvert/somp/somptodc.cc                   |   77 +
 appsrc/dconvert/somp/somptodc.man                  |   53 +
 appsrc/dconvert/support/Imakefile                  |    0
 appsrc/dconvert/toshiba/Imakefile                  |    5 +
 appsrc/dconvert/toshiba/toshtodc.man               |   32 +
 appsrc/dconvert/toshiba/toshtodc.script            |   68 +
 appsrc/dconvert/xxxx/Imakefile                     |    0
 appsrc/dconvert/xxxx/Imakefile.tmpl                |   36 +
 appsrc/dconvert/xxxx/replacexxxxwithinfiles.sh     |   18 +
 appsrc/dconvert/xxxx/xxxxdump.cc                   |   46 +
 appsrc/dconvert/xxxx/xxxxdump.man                  |   43 +
 appsrc/dconvert/xxxx/xxxxtodc.cc                   |   77 +
 appsrc/dconvert/xxxx/xxxxtodc.man                  |   53 +
 appsrc/misc/Imakefile                              |  156 +
 appsrc/misc/binpatch.cc                            |  350 +
 appsrc/misc/binpatch.man                           |    0
 appsrc/misc/binpatch.test.sh                       |  111 +
 appsrc/misc/bmpdump.cc                             |  119 +
 appsrc/misc/bmpdump.man                            |    0
 appsrc/misc/dcunmeta.cc                            |  174 +
 appsrc/misc/dcunmeta.man                           |   73 +
 appsrc/misc/dumptiff.cc                            |  139 +
 appsrc/misc/dumptiff.man                           |    0
 appsrc/misc/dumpwhat.cc                            | 1281 ++++
 appsrc/misc/dumpwhat.man                           |    0
 appsrc/misc/gethttp.cc                             |  283 +
 appsrc/misc/gethttp.man                            |    0
 appsrc/misc/gethttp.test.sh                        |   20 +
 appsrc/misc/jpegdump.cc                            | 1168 +++
 appsrc/misc/jpegdump.cc.pre2000                    |  816 ++
 appsrc/misc/jpegdump.man                           |    0
 appsrc/misc/jpegsplit.cc                           |  312 +
 appsrc/misc/jpegsplit.man                          |    0
 appsrc/misc/njlwork.history.tmp                    |   90 +
 appsrc/misc/pbmswbit.cc                            |  178 +
 appsrc/misc/pbmswbit.man                           |    0
 appsrc/misc/pgmtobmp.cc                            |  268 +
 appsrc/misc/pgmtobmp.man                           |    0
 appsrc/misc/pnmpred.cc                             |  237 +
 appsrc/misc/pnmpred.man                            |    0
 appsrc/misc/pnmtoraw.cc                            |  171 +
 appsrc/misc/pnmtoraw.man                           |    0
 appsrc/misc/ppmtrclr.cc                            |  239 +
 appsrc/misc/ppmtrclr.man                           |    0
 appsrc/misc/rawarith.cc                            |  116 +
 appsrc/misc/rawarith.man                           |    0
 appsrc/misc/rawdiff.cc                             |  105 +
 appsrc/misc/rawdiff.man                            |    0
 appsrc/misc/rawmask.cc                             |   86 +
 appsrc/misc/rawmask.man                            |    0
 appsrc/misc/rawnjl.cc                              |  863 +++
 appsrc/misc/rawnjl.man                             |    0
 appsrc/misc/rawnjl2.cc                             | 1538 ++++
 appsrc/misc/rawnjl2.man                            |  133 +
 appsrc/simple/Imakefile                            |    6 +
 appsrc/simple/README                               |   47 +
 appsrc/simple/ge9800/Imakefile                     |   31 +
 appsrc/simple/ge9800/ge98id.cc                     |  129 +
 appsrc/simple/ge9800/ge98id.man                    |   46 +
 appsrc/simple/ge9800/ge98topgm.cc                  |  255 +
 appsrc/simple/ge9800/ge98topgm.man                 |   35 +
 appsrc/simple/genesis/Imakefile                    |   24 +
 appsrc/simple/genesis/gentopgm.cc                  |  247 +
 appsrc/simple/genesis/gentopgm.man                 |   37 +
 appsrc/simple/pace/Imakefile                       |   24 +
 appsrc/simple/pace/pacetopgm.cc                    |  161 +
 appsrc/simple/pace/pacetopgm.man                   |   35 +
 appsrc/simple/signa/Imakefile                      |   24 +
 appsrc/simple/signa/sgntopgm.cc                    |  112 +
 appsrc/simple/signa/sgntopgm.man                   |   35 +
 appsrc/simple/somatom/Imakefile                    |   24 +
 appsrc/simple/somatom/TODO                         |    3 +
 appsrc/simple/somatom/somtopgm.cc                  |  121 +
 appsrc/simple/somatom/somtopgm.man                 |   35 +
 appsrc/simple/sytec/Imakefile                      |   24 +
 appsrc/simple/sytec/syttopgm.cc                    |  118 +
 appsrc/simple/sytec/syttopgm.man                   |   35 +
 appsrc/simple/vision/Imakefile                     |   24 +
 appsrc/simple/vision/TODO                          |    2 +
 appsrc/simple/vision/vsntopgm.cc                   |  128 +
 appsrc/simple/vision/vsntopgm.man                  |   35 +
 config/Configure                                   |  952 +++
 config/Imake.p-rules                               |   90 +
 config/Imake.rules                                 |  654 ++
 config/Imake.tmpl                                  |  613 ++
 config/Imakefile                                   |    1 +
 config/Project.p-tmpl                              |  198 +
 config/Project.p-tmpl.hold                         |  198 +
 config/Project.tmpl                                |   38 +
 config/generic.p-cf                                |    0
 config/site.def                                    |   17 +
 config/site.p-def                                  |  250 +
 libsrc/Imakefile                                   |    6 +
 libsrc/docs/Imakefile                              |    8 +
 libsrc/include/Imakefile                           |    6 +
 libsrc/include/dcdisp/Imakefile                    |    0
 libsrc/include/dcdisp/NOTES                        |   73 +
 libsrc/include/dcdisp/lutclass.h                   |   53 +
 libsrc/include/dcdisp/lutextr.h                    |   10 +
 libsrc/include/dcdisp/rdargb.h                     |   29 +
 libsrc/include/dcdisp/rdcmyk.h                     |   25 +
 libsrc/include/dcdisp/rdgray.h                     |   77 +
 libsrc/include/dcdisp/rdhsv.h                      |   25 +
 libsrc/include/dcdisp/rdimage.h                    |  216 +
 libsrc/include/dcdisp/rdindex.h                    |   44 +
 libsrc/include/dcdisp/rdrgb.h                      |   53 +
 libsrc/include/dcdisp/usegray.h                    |   57 +
 libsrc/include/dcdisp/useindex.h                   |   38 +
 libsrc/include/dcdisp/usepal.h                     |   37 +
 libsrc/include/dcdisp/usetrue.h                    |   39 +
 libsrc/include/dconvert/Imakefile                  |    0
 libsrc/include/dconvert/dateconv.h                 |  242 +
 libsrc/include/dconvert/plane.h                    |  282 +
 libsrc/include/dconvert/planea.h                   |   18 +
 libsrc/include/dconvert/planev.h                   |  291 +
 libsrc/include/dconvert/ptyhdr.h                   |   35 +
 libsrc/include/dctool/Imakefile                    |   12 +
 libsrc/include/dctool/attr.h                       |  157 +
 libsrc/include/dctool/attrlist.h                   |   54 +
 libsrc/include/dctool/attrlsln.h                   |   26 +
 libsrc/include/dctool/attrmxls.README              |   39 +
 libsrc/include/dctool/attrmxls.h                   |  145 +
 libsrc/include/dctool/attrnew.h                    |    7 +
 libsrc/include/dctool/attrothr.h                   |  237 +
 libsrc/include/dctool/attrseq.h                    |   72 +
 libsrc/include/dctool/attrtag.h                    |  137 +
 libsrc/include/dctool/attrtypb.h                   |   17 +
 libsrc/include/dctool/attrtype.h                   |  498 ++
 libsrc/include/dctool/attrtypf.h                   |  474 ++
 libsrc/include/dctool/attrtypn.h                   |  294 +
 libsrc/include/dctool/attrtypo.h                   |  509 ++
 libsrc/include/dctool/attrtyps.h                   |  293 +
 libsrc/include/dctool/attrtypt.h                   |   94 +
 libsrc/include/dctool/attrval.h                    |   77 +
 libsrc/include/dctool/charset.h                    |   32 +
 libsrc/include/dctool/convtype.h                   |   87 +
 libsrc/include/dctool/dcopt.h                      |   97 +
 libsrc/include/dctool/dcstream.h                   |  144 +
 libsrc/include/dctool/dicomdir.h                   |   10 +
 libsrc/include/dctool/elmdict.h                    |   31 +
 libsrc/include/dctool/fltype.h                     |  210 +
 libsrc/include/dctool/ie.h                         |   40 +
 libsrc/include/dctool/iodcomp.h                    |   16 +
 libsrc/include/dctool/listval.h                    |  130 +
 libsrc/include/dctool/misctype.h                   |   10 +
 libsrc/include/dctool/module.h                     |   16 +
 libsrc/include/dctool/pixposn.h                    |   36 +
 libsrc/include/dctool/sopcli.h                     |    7 +
 libsrc/include/dctool/transyn.h                    |   45 +
 libsrc/include/dctool/transynd.h                   |  105 +
 libsrc/include/dctool/uidgen.h                     |  272 +
 libsrc/include/dctool/vr.h                         |  209 +
 libsrc/include/dculsp/dculsp.h                     |  184 +
 libsrc/include/generic/Imakefile                   |    0
 libsrc/include/generic/basetype.h                  |  122 +
 libsrc/include/generic/bnchar.h                    |   98 +
 libsrc/include/generic/bnopt.h                     |   68 +
 libsrc/include/generic/bnstream.h                  |  241 +
 libsrc/include/generic/buffer.h                    |  140 +
 libsrc/include/generic/datetype.h                  |  112 +
 libsrc/include/generic/endtype.h                   |   44 +
 libsrc/include/generic/errclass.h                  |   44 +
 libsrc/include/generic/getoptns.h                  |   92 +
 libsrc/include/generic/hash.h                      |  104 +
 libsrc/include/generic/ioopt.h                     |   50 +
 libsrc/include/generic/listfifo.h                  |   44 +
 libsrc/include/generic/listsimp.h                  |  162 +
 libsrc/include/generic/listsort.h                  |   45 +
 libsrc/include/generic/ntstream.h                  |   75 +
 libsrc/include/generic/platform.h                  |    7 +
 libsrc/include/generic/strtype.h                   |  136 +
 libsrc/include/generic/txstream.h                  |   35 +
 libsrc/include/generic/version.h                   |    7 +
 libsrc/include/locale/Imakefile                    |    0
 libsrc/include/locale/mesgtext.h                   |   27 +
 libsrc/include/ourdisp/Imakefile                   |    0
 libsrc/include/ourdisp/ourdisp.h                   |  217 +
 libsrc/include/pixeldat/Imakefile                  |    7 +
 libsrc/include/pixeldat/briggsrc.h                 |  613 ++
 libsrc/include/pixeldat/briggsrc.h.ptrrotate       |  195 +
 libsrc/include/pixeldat/cnvbit.h                   |  191 +
 libsrc/include/pixeldat/frombyte.h                 |  204 +
 libsrc/include/pixeldat/frompack.h                 |  193 +
 libsrc/include/pixeldat/fromshft.h                 |  104 +
 libsrc/include/pixeldat/makesmptetxt               |   39 +
 libsrc/include/pixeldat/memsrc.h                   |   58 +
 libsrc/include/pixeldat/rawsrc.h                   |  156 +
 libsrc/include/pixeldat/smptesrc.h                 |  843 +++
 libsrc/include/pixeldat/smptetxt.h                 |  113 +
 libsrc/include/pixeldat/srcsink.h                  |  418 +
 libsrc/include/pixeldat/tobyte.h                   |  194 +
 libsrc/include/pixeldat/topack.h                   |  194 +
 libsrc/include/pixeldat/toshft.h                   |  104 +
 libsrc/include/pixeldat/unencap.h                  |  170 +
 libsrc/lib/Imakefile                               |    9 +
 libsrc/src/Imakefile                               |    6 +
 libsrc/src/dcdisp/Imakefile                        |   17 +
 libsrc/src/dcdisp/lutclass.cc                      |  155 +
 libsrc/src/dcdisp/lutextr.cc                       |   75 +
 libsrc/src/dcdisp/rdargb.cc                        |   42 +
 libsrc/src/dcdisp/rdcmyk.cc                        |   34 +
 libsrc/src/dcdisp/rdgray.cc                        |  131 +
 libsrc/src/dcdisp/rdgray.cc.postsignextend         |  118 +
 libsrc/src/dcdisp/rdhsv.cc                         |   35 +
 libsrc/src/dcdisp/rdimage.cc                       |  709 ++
 libsrc/src/dcdisp/rdimage.cc.postsignextend        |  715 ++
 libsrc/src/dcdisp/rdindex.cc                       |   68 +
 libsrc/src/dcdisp/rdrgb.cc                         |   87 +
 libsrc/src/dcdisp/usegray.cc                       |  340 +
 libsrc/src/dcdisp/usegray.cc.signedwork            |  216 +
 libsrc/src/dcdisp/useindex.cc                      |  143 +
 libsrc/src/dcdisp/usepal.cc                        |   34 +
 libsrc/src/dcdisp/usetrue.cc                       |  100 +
 libsrc/src/dconvert/Imakefile                      |    6 +
 libsrc/src/dconvert/gaw/Imakefile                  |   31 +
 libsrc/src/dconvert/gaw/README                     |  159 +
 libsrc/src/dconvert/gaw/gaw.cc                     |   55 +
 libsrc/src/dconvert/gaw/gaw.h                      |   61 +
 libsrc/src/dconvert/gaw/gaw.tpl                    |  634 ++
 libsrc/src/dconvert/gaw/gawcl.h                    |   31 +
 libsrc/src/dconvert/gaw/gawconv.cc                 |    5 +
 libsrc/src/dconvert/gaw/gawdc.cc                   |   96 +
 libsrc/src/dconvert/gaw/gawdc.h                    |    7 +
 libsrc/src/dconvert/gaw/gawdmp.cc                  |   23 +
 libsrc/src/dconvert/gaw/gawdmp.h                   |    4 +
 libsrc/src/dconvert/gaw/gawdmpf.cc                 |    4 +
 libsrc/src/dconvert/gaw/gawhdrc.cc                 |    8 +
 libsrc/src/dconvert/gaw/gawinfo.h                  |   45 +
 libsrc/src/dconvert/gaw/gawmdt.cc                  |  112 +
 libsrc/src/dconvert/gaw/gawmmsc.cc                 |  632 ++
 libsrc/src/dconvert/gaw/gawmpln.cc                 |  191 +
 libsrc/src/dconvert/gaw/gawptrs.h                  |   47 +
 libsrc/src/dconvert/gaw/gawsrc.h                   |  171 +
 libsrc/src/dconvert/ge9800/Imakefile               |   30 +
 libsrc/src/dconvert/ge9800/README                  |  159 +
 libsrc/src/dconvert/ge9800/doubleoffset.awk        |   20 +
 libsrc/src/dconvert/ge9800/ge9800.cc               |   28 +
 libsrc/src/dconvert/ge9800/ge9800.h                |   41 +
 libsrc/src/dconvert/ge9800/ge9800.tpl              |  356 +
 libsrc/src/dconvert/ge9800/ge9800cl.h              |   25 +
 libsrc/src/dconvert/ge9800/ge9800conv.cc           |    5 +
 libsrc/src/dconvert/ge9800/ge9800dc.cc             |   92 +
 libsrc/src/dconvert/ge9800/ge9800dc.h              |    7 +
 libsrc/src/dconvert/ge9800/ge9800dmp.cc            |   37 +
 libsrc/src/dconvert/ge9800/ge9800dmp.h             |    4 +
 libsrc/src/dconvert/ge9800/ge9800dmpf.cc           |    4 +
 libsrc/src/dconvert/ge9800/ge9800hdrc.cc           |    7 +
 libsrc/src/dconvert/ge9800/ge9800mdt.cc            |   64 +
 libsrc/src/dconvert/ge9800/ge9800mmsc.cc           |  174 +
 libsrc/src/dconvert/ge9800/ge9800mpln.cc           |  240 +
 libsrc/src/dconvert/ge9800/ge9800ptrs.h            |   16 +
 libsrc/src/dconvert/ge9800/ge9800src.h             |  121 +
 libsrc/src/dconvert/gen/Imakefile                  |   31 +
 libsrc/src/dconvert/gen/Imakefile.tmpl             |   31 +
 libsrc/src/dconvert/gen/README                     |  159 +
 libsrc/src/dconvert/gen/gen.cc                     |   55 +
 libsrc/src/dconvert/gen/gen.h                      |   61 +
 libsrc/src/dconvert/gen/gen.tpl                    |  634 ++
 libsrc/src/dconvert/gen/gencl.h                    |   31 +
 libsrc/src/dconvert/gen/genconv.cc                 |    5 +
 libsrc/src/dconvert/gen/gendc.cc                   |   96 +
 libsrc/src/dconvert/gen/gendc.h                    |    7 +
 libsrc/src/dconvert/gen/gendmp.cc                  |   23 +
 libsrc/src/dconvert/gen/gendmp.h                   |    4 +
 libsrc/src/dconvert/gen/gendmpf.cc                 |    4 +
 libsrc/src/dconvert/gen/genhdrc.cc                 |    8 +
 libsrc/src/dconvert/gen/geninfo.h                  |   45 +
 libsrc/src/dconvert/gen/genmdt.cc                  |  112 +
 libsrc/src/dconvert/gen/genmmsc.cc                 |  633 ++
 libsrc/src/dconvert/gen/genmpln.cc                 |  191 +
 libsrc/src/dconvert/gen/genptrs.h                  |   47 +
 libsrc/src/dconvert/gen/gensrc.h                   |  171 +
 libsrc/src/dconvert/himr/Imakefile                 |   30 +
 libsrc/src/dconvert/himr/README                    |  159 +
 libsrc/src/dconvert/himr/himr.cc                   |   28 +
 libsrc/src/dconvert/himr/himr.h                    |   39 +
 libsrc/src/dconvert/himr/himr.tpl                  |  189 +
 libsrc/src/dconvert/himr/himrcl.h                  |   25 +
 libsrc/src/dconvert/himr/himrconv.cc               |    5 +
 libsrc/src/dconvert/himr/himrdc.cc                 |   86 +
 libsrc/src/dconvert/himr/himrdc.h                  |    7 +
 libsrc/src/dconvert/himr/himrdmp.cc                |   37 +
 libsrc/src/dconvert/himr/himrdmp.h                 |    4 +
 libsrc/src/dconvert/himr/himrdmpf.cc               |    4 +
 libsrc/src/dconvert/himr/himrhdrc.cc               |    7 +
 libsrc/src/dconvert/himr/himrmdt.cc                |   46 +
 libsrc/src/dconvert/himr/himrmmsc.cc               |  246 +
 libsrc/src/dconvert/himr/himrmpln.cc               |  133 +
 libsrc/src/dconvert/himr/himrptrs.h                |    4 +
 libsrc/src/dconvert/himr/himrsrc.h                 |   61 +
 libsrc/src/dconvert/imtn/Imakefile                 |   30 +
 libsrc/src/dconvert/imtn/NOTES                     |  240 +
 libsrc/src/dconvert/imtn/imtn.cc                   |   28 +
 libsrc/src/dconvert/imtn/imtn.h                    |   37 +
 libsrc/src/dconvert/imtn/imtn.tpl                  |  147 +
 libsrc/src/dconvert/imtn/imtncl.h                  |   23 +
 libsrc/src/dconvert/imtn/imtnconv.cc               |    5 +
 libsrc/src/dconvert/imtn/imtndc.cc                 |   85 +
 libsrc/src/dconvert/imtn/imtndc.h                  |    7 +
 libsrc/src/dconvert/imtn/imtndmp.cc                |   36 +
 libsrc/src/dconvert/imtn/imtndmp.h                 |    4 +
 libsrc/src/dconvert/imtn/imtndmpf.cc               |    4 +
 libsrc/src/dconvert/imtn/imtnhdrc.cc               |  361 +
 libsrc/src/dconvert/imtn/imtnhdrm.h                |   55 +
 libsrc/src/dconvert/imtn/imtnmdt.cc                |   56 +
 libsrc/src/dconvert/imtn/imtnmmsc.cc               |  192 +
 libsrc/src/dconvert/imtn/imtnmpln.cc               |  224 +
 libsrc/src/dconvert/imtn/imtnptrs.h                |   23 +
 libsrc/src/dconvert/imtn/imtnsrc.h                 |   61 +
 libsrc/src/dconvert/pace/Imakefile                 |   30 +
 libsrc/src/dconvert/pace/pace.cc                   |   28 +
 libsrc/src/dconvert/pace/pace.h                    |   45 +
 libsrc/src/dconvert/pace/pace.tpl                  |  222 +
 libsrc/src/dconvert/pace/pacecl.h                  |   25 +
 libsrc/src/dconvert/pace/paceconv.cc               |    5 +
 libsrc/src/dconvert/pace/pacedc.cc                 |   91 +
 libsrc/src/dconvert/pace/pacedc.h                  |    7 +
 libsrc/src/dconvert/pace/pacedmp.cc                |   22 +
 libsrc/src/dconvert/pace/pacedmp.h                 |    4 +
 libsrc/src/dconvert/pace/pacedmpf.cc               |    4 +
 libsrc/src/dconvert/pace/pacehdrc.cc               |    7 +
 libsrc/src/dconvert/pace/pacemdt.cc                |   51 +
 libsrc/src/dconvert/pace/pacemmsc.cc               |  199 +
 libsrc/src/dconvert/pace/pacempln.cc               |  323 +
 libsrc/src/dconvert/pace/paceptrs.h                |   12 +
 libsrc/src/dconvert/pace/pacesrc.h                 |   96 +
 libsrc/src/dconvert/pq/Imakefile                   |   24 +
 libsrc/src/dconvert/pq/README                      |  159 +
 libsrc/src/dconvert/pq/pq.cc                       |   28 +
 libsrc/src/dconvert/pq/pq.h                        |   39 +
 libsrc/src/dconvert/pq/pqcl.h                      |   25 +
 libsrc/src/dconvert/pq/pqconv.cc                   |    5 +
 libsrc/src/dconvert/pq/pqconv.h                    |   65 +
 libsrc/src/dconvert/pq/pqdc.cc                     |   86 +
 libsrc/src/dconvert/pq/pqdc.h                      |    7 +
 libsrc/src/dconvert/pq/pqdmp.cc                    |   37 +
 libsrc/src/dconvert/pq/pqdmp.h                     |    4 +
 libsrc/src/dconvert/pq/pqdmpf.cc                   |    4 +
 libsrc/src/dconvert/pq/pqdmpf.h                    |  336 +
 libsrc/src/dconvert/pq/pqhdrc.cc                   |    7 +
 libsrc/src/dconvert/pq/pqhdrc.h                    |  400 +
 libsrc/src/dconvert/pq/pqhdrp.h                    |   47 +
 libsrc/src/dconvert/pq/pqhdrw.h                    |   62 +
 libsrc/src/dconvert/pq/pqmdt.cc                    |  111 +
 libsrc/src/dconvert/pq/pqmmsc.cc                   |  831 ++
 libsrc/src/dconvert/pq/pqmpln.cc                   |  229 +
 libsrc/src/dconvert/pq/pqptrs.h                    |    2 +
 libsrc/src/dconvert/pq/pqsrc.h                     |   61 +
 libsrc/src/dconvert/shim/Imakefile                 |   30 +
 libsrc/src/dconvert/shim/README                    |  159 +
 libsrc/src/dconvert/shim/shim.cc                   |   28 +
 libsrc/src/dconvert/shim/shim.h                    |   37 +
 libsrc/src/dconvert/shim/shim.tpl                  |  160 +
 libsrc/src/dconvert/shim/shimcl.h                  |   23 +
 libsrc/src/dconvert/shim/shimconv.cc               |    5 +
 libsrc/src/dconvert/shim/shimdc.cc                 |   94 +
 libsrc/src/dconvert/shim/shimdc.h                  |    7 +
 libsrc/src/dconvert/shim/shimdmp.cc                |   36 +
 libsrc/src/dconvert/shim/shimdmp.h                 |    4 +
 libsrc/src/dconvert/shim/shimdmpf.cc               |   12 +
 libsrc/src/dconvert/shim/shimhdrc.cc               |  361 +
 libsrc/src/dconvert/shim/shimhdrm.h                |   55 +
 libsrc/src/dconvert/shim/shimmdt.cc                |   47 +
 libsrc/src/dconvert/shim/shimmmsc.cc               |  195 +
 libsrc/src/dconvert/shim/shimmpln.cc               |  229 +
 libsrc/src/dconvert/shim/shimptrs.h                |   14 +
 libsrc/src/dconvert/shim/shimsrc.h                 |   61 +
 libsrc/src/dconvert/signa/Imakefile                |   30 +
 libsrc/src/dconvert/signa/README                   |  159 +
 libsrc/src/dconvert/signa/sgn.cc                   |   35 +
 libsrc/src/dconvert/signa/sgncl.h                  |   28 +
 libsrc/src/dconvert/signa/sgnconv.cc               |    5 +
 libsrc/src/dconvert/signa/sgndc.cc                 |   92 +
 libsrc/src/dconvert/signa/sgndc.h                  |    7 +
 libsrc/src/dconvert/signa/sgndmp.cc                |   23 +
 libsrc/src/dconvert/signa/sgndmp.h                 |    4 +
 libsrc/src/dconvert/signa/sgndmpf.cc               |    4 +
 libsrc/src/dconvert/signa/sgnhdrc.cc               |    7 +
 libsrc/src/dconvert/signa/sgnmdt.cc                |   83 +
 libsrc/src/dconvert/signa/sgnmmsc.cc               |  361 +
 libsrc/src/dconvert/signa/sgnmpln.cc               |  118 +
 libsrc/src/dconvert/signa/sgnptrs.h                |   13 +
 libsrc/src/dconvert/signa/sgnsrc.h                 |   61 +
 libsrc/src/dconvert/signa/signa.h                  |   48 +
 libsrc/src/dconvert/signa/signa.tpl                |  272 +
 libsrc/src/dconvert/somp/Imakefile                 |   30 +
 libsrc/src/dconvert/somp/README                    |  159 +
 libsrc/src/dconvert/somp/somp.cc                   |   28 +
 libsrc/src/dconvert/somp/somp.h                    |   46 +
 libsrc/src/dconvert/somp/somp.tpl                  |  266 +
 libsrc/src/dconvert/somp/sompcl.h                  |   25 +
 libsrc/src/dconvert/somp/sompconv.cc               |    5 +
 libsrc/src/dconvert/somp/sompdc.cc                 |   90 +
 libsrc/src/dconvert/somp/sompdc.h                  |    7 +
 libsrc/src/dconvert/somp/sompdmp.cc                |   23 +
 libsrc/src/dconvert/somp/sompdmp.h                 |    4 +
 libsrc/src/dconvert/somp/sompdmpf.cc               |    4 +
 libsrc/src/dconvert/somp/somphdrc.cc               |    7 +
 libsrc/src/dconvert/somp/sompmdt.cc                |   31 +
 libsrc/src/dconvert/somp/sompmmsc.cc               |  217 +
 libsrc/src/dconvert/somp/sompmpln.cc               |  372 +
 libsrc/src/dconvert/somp/sompptrs.h                |    5 +
 libsrc/src/dconvert/somp/sompsrc.h                 |   61 +
 libsrc/src/dconvert/support/Imakefile              |   11 +
 libsrc/src/dconvert/support/dateconv.cc            |    7 +
 libsrc/src/dconvert/support/plane.cc               |  253 +
 libsrc/src/dconvert/support/planea.cc              |   50 +
 libsrc/src/dconvert/xxxx/Imakefile                 |    0
 libsrc/src/dconvert/xxxx/Imakefile.tmpl            |   30 +
 libsrc/src/dconvert/xxxx/README                    |  159 +
 libsrc/src/dconvert/xxxx/replacexxxxwithinfiles.sh |   18 +
 libsrc/src/dconvert/xxxx/xxxx.cc                   |   28 +
 libsrc/src/dconvert/xxxx/xxxx.h                    |   46 +
 libsrc/src/dconvert/xxxx/xxxx.tpl                  |   25 +
 libsrc/src/dconvert/xxxx/xxxxcl.h                  |   25 +
 libsrc/src/dconvert/xxxx/xxxxconv.cc               |    5 +
 libsrc/src/dconvert/xxxx/xxxxdc.cc                 |   90 +
 libsrc/src/dconvert/xxxx/xxxxdc.h                  |    7 +
 libsrc/src/dconvert/xxxx/xxxxdmp.cc                |   37 +
 libsrc/src/dconvert/xxxx/xxxxdmp.h                 |    4 +
 libsrc/src/dconvert/xxxx/xxxxdmpf.cc               |    4 +
 libsrc/src/dconvert/xxxx/xxxxhdrc.cc               |    7 +
 libsrc/src/dconvert/xxxx/xxxxmdt.cc                |   51 +
 libsrc/src/dconvert/xxxx/xxxxmmsc.cc               |  199 +
 libsrc/src/dconvert/xxxx/xxxxmpln.cc               |  323 +
 libsrc/src/dconvert/xxxx/xxxxptrs.h                |   12 +
 libsrc/src/dconvert/xxxx/xxxxsrc.h                 |   61 +
 libsrc/src/dctool/Imakefile                        |   56 +
 libsrc/src/dctool/attr.cc                          |  377 +
 libsrc/src/dctool/attrlist.cc                      |  206 +
 libsrc/src/dctool/attrlsln.cc                      |  100 +
 libsrc/src/dctool/attrmxls.cc                      | 1226 +++
 libsrc/src/dctool/attrmxrd copy.cc                 | 1205 +++
 libsrc/src/dctool/attrmxrd.cc                      | 1217 +++
 libsrc/src/dctool/attrmxvr.cc                      |  171 +
 libsrc/src/dctool/attrnew.cc                       |  168 +
 libsrc/src/dctool/attrothr.cc                      |  576 ++
 libsrc/src/dctool/attrseq.cc                       |  155 +
 libsrc/src/dctool/attrtag.cc                       |  139 +
 libsrc/src/dctool/attrtypd.cc                      |   92 +
 libsrc/src/dctool/attrtypo.cc                      |  791 ++
 libsrc/src/dctool/attrtyps.cc                      |  490 ++
 libsrc/src/dctool/attrtypt.cc                      |  119 +
 libsrc/src/dctool/attrtypv.cc                      | 1100 +++
 libsrc/src/dctool/attrvrfy.cc                      |  464 ++
 libsrc/src/dctool/binval.cc                        |   14 +
 libsrc/src/dctool/charset.cc                       |  135 +
 libsrc/src/dctool/condn.cc                         |  401 +
 libsrc/src/dctool/dcoptc.cc                        |  118 +
 libsrc/src/dctool/dcopti.cc                        |  307 +
 libsrc/src/dctool/dcopto.cc                        |  565 ++
 libsrc/src/dctool/dcstream.cc                      |  297 +
 libsrc/src/dctool/dicomdir.cc                      |  297 +
 libsrc/src/dctool/elmdict.cc                       |  231 +
 libsrc/src/dctool/elmentry.h                       |   20 +
 libsrc/src/dctool/elmhash.h                        |  229 +
 libsrc/src/dctool/elmpriv.cc                       |   31 +
 libsrc/src/dctool/elmpriv.h                        |   17 +
 libsrc/src/dctool/elmtype.h                        |   65 +
 libsrc/src/dctool/ie.cc                            |   61 +
 libsrc/src/dctool/iodcompb.cc                      |   14 +
 libsrc/src/dctool/iodcomps.cc                      |   14 +
 libsrc/src/dctool/iodcompv.cc                      |   17 +
 libsrc/src/dctool/iodcompw.cc                      |   12 +
 libsrc/src/dctool/moduleb.cc                       |   10 +
 libsrc/src/dctool/modulev.cc                       |  372 +
 libsrc/src/dctool/modulew.cc                       |    9 +
 libsrc/src/dctool/pixposn.cc                       |  139 +
 libsrc/src/dctool/sopclc.cc                        |    3 +
 libsrc/src/dctool/sopcle.h                         |   13 +
 libsrc/src/dctool/sopcli.cc                        |   20 +
 libsrc/src/dctool/strval.cc                        |   31 +
 libsrc/src/dctool/tagval.cc                        |   14 +
 libsrc/src/dctool/transyn.cc                       |   70 +
 libsrc/src/dctool/transync.cc                      |    3 +
 libsrc/src/dctool/transynd.cc                      |   40 +
 libsrc/src/dctool/transynd.h                       |   27 +
 libsrc/src/dctool/transyne.h                       |   14 +
 libsrc/src/dctool/uidgen.cc                        |  127 +
 libsrc/src/dculsp/dculsp.cc                        |  119 +
 libsrc/src/generic/Imakefile                       |   16 +
 libsrc/src/generic/bnopti.cc                       |  161 +
 libsrc/src/generic/bnopto.cc                       |  159 +
 libsrc/src/generic/datetype.cc                     |  576 ++
 libsrc/src/generic/getoptns.cc                     |  484 ++
 libsrc/src/generic/ioopti.cc                       |  115 +
 libsrc/src/generic/ioopto.cc                       |  112 +
 libsrc/src/generic/ntstream.cc                     |  328 +
 libsrc/src/generic/platform.cc                     |    7 +
 libsrc/src/generic/txstream.cc                     |   31 +
 libsrc/src/generic/version.cc                      |    7 +
 libsrc/src/locale/Imakefile                        |   19 +
 libsrc/src/locale/mesgtext.awk                     |   38 +
 libsrc/src/locale/mesgtext.cc                      |   76 +
 libsrc/src/locale/mesgtext.tpl                     |  316 +
 libsrc/src/ourdisp/Imakefile                       |   16 +
 libsrc/src/ourdisp/ourdisp.cc                      |  901 +++
 libsrc/src/ourdisp/wlcursor.xbm                    |    6 +
 libsrc/src/ourdisp/wlmask.xbm                      |    6 +
 libsrc/standard/Imakefile                          |  248 +
 libsrc/standard/NOTES                              |  120 +
 libsrc/standard/binval.tpl                         |  455 ++
 libsrc/standard/condn.tpl                          | 6581 ++++++++++++++++
 libsrc/standard/elmdict/Imakefile                  |   39 +
 libsrc/standard/elmdict/acuson.tpl                 |  105 +
 libsrc/standard/elmdict/agfa.tpl                   |  210 +
 libsrc/standard/elmdict/camtron.tpl                |   36 +
 libsrc/standard/elmdict/dicom3.tpl                 | 3802 ++++++++++
 libsrc/standard/elmdict/diconde.tpl                |  192 +
 libsrc/standard/elmdict/dicondep.tpl               |  155 +
 libsrc/standard/elmdict/dicos.tpl                  |   89 +
 libsrc/standard/elmdict/elscint.tpl                |  220 +
 libsrc/standard/elmdict/gems.tpl                   | 2167 ++++++
 libsrc/standard/elmdict/hitachi.tpl                |  211 +
 libsrc/standard/elmdict/isg.tpl                    |  127 +
 libsrc/standard/elmdict/other.tpl                  | 2078 +++++
 libsrc/standard/elmdict/papyrus.tpl                |   59 +
 libsrc/standard/elmdict/philips.tpl                | 1991 +++++
 libsrc/standard/elmdict/picker.tpl                 |   24 +
 libsrc/standard/elmdict/siemens.tpl                | 3374 +++++++++
 libsrc/standard/elmdict/spi.tpl                    |   23 +
 libsrc/standard/elmdict/toshiba.tpl                |  240 +
 libsrc/standard/elmdict/wordpart6tabletotpl.awk    |    2 +
 .../standard/iodandmodulerelationshipsbytag.head   |    1 +
 libsrc/standard/iodcomp/Imakefile                  |    0
 libsrc/standard/iodcomp/base.tpl                   |  922 +++
 libsrc/standard/iodcomp/ct.tpl                     |  134 +
 libsrc/standard/iodcomp/dx.tpl                     |  796 ++
 libsrc/standard/iodcomp/file.tpl                   |   21 +
 libsrc/standard/iodcomp/mr.tpl                     |  263 +
 libsrc/standard/iodcomp/pet.tpl                    |  175 +
 libsrc/standard/iodcomp/rt.tpl                     |  311 +
 libsrc/standard/iodcomp/softcopy.tpl               |  212 +
 libsrc/standard/iodcomp/sr.tpl                     |  364 +
 libsrc/standard/iodcomp/us.tpl                     |  105 +
 libsrc/standard/iodcomp/vl.tpl                     |  645 ++
 libsrc/standard/iodcomp/waveform.tpl               |  192 +
 libsrc/standard/iodcomp/xaxrf.tpl                  |  304 +
 libsrc/standard/module/Imakefile                   |    0
 libsrc/standard/module/acqctx.tpl                  |   29 +
 libsrc/standard/module/base.tpl                    | 2704 +++++++
 libsrc/standard/module/ct.tpl                      |  326 +
 libsrc/standard/module/dx.tpl                      |  675 ++
 libsrc/standard/module/file.tpl                    |  310 +
 libsrc/standard/module/mr.tpl                      |  610 ++
 libsrc/standard/module/pet.tpl                     |  437 ++
 libsrc/standard/module/rt.tpl                      | 1464 ++++
 libsrc/standard/module/softcopy.tpl                |  386 +
 libsrc/standard/module/specimen.tpl                |   55 +
 libsrc/standard/module/sr.tpl                      |  380 +
 libsrc/standard/module/us.tpl                      |  522 ++
 libsrc/standard/module/vl.tpl                      |  918 +++
 libsrc/standard/module/waveform.tpl                |  117 +
 libsrc/standard/module/xaxrf.tpl                   |  776 ++
 libsrc/standard/reorder.sh                         |    3 +
 libsrc/standard/sopcl.tpl                          |  270 +
 libsrc/standard/strval/Imakefile                   |    0
 libsrc/standard/strval/base.tpl                    | 1537 ++++
 libsrc/standard/strval/charset.tpl                 |   38 +
 libsrc/standard/strval/ct.tpl                      |  146 +
 libsrc/standard/strval/dx.tpl                      |  317 +
 libsrc/standard/strval/file.tpl                    |   46 +
 libsrc/standard/strval/mr.tpl                      |  669 ++
 libsrc/standard/strval/nm.tpl                      |  158 +
 libsrc/standard/strval/pet.tpl                     |  258 +
 libsrc/standard/strval/rt.tpl                      |  562 ++
 libsrc/standard/strval/sdmdx.tpl                   |  345 +
 libsrc/standard/strval/softcopy.tpl                |  233 +
 libsrc/standard/strval/sr.tpl                      |  202 +
 libsrc/standard/strval/us.tpl                      |  965 +++
 libsrc/standard/strval/vl.tpl                      |  223 +
 libsrc/standard/strval/waveform.tpl                |   58 +
 libsrc/standard/strval/xaxrf.tpl                   |  271 +
 libsrc/standard/tagval.tpl                         |   79 +
 libsrc/standard/transyn.tpl                        |   61 +
 libsrc/standard/vxtldict.txt                       |   74 +
 libsrc/support/DicomDictionary_header.txt          |   24 +
 libsrc/support/DicomDictionary_trailer.txt         |    1 +
 libsrc/support/Imakefile                           |    0
 libsrc/support/binval.awk                          |  196 +
 libsrc/support/canonicalizespacinginelmdict.sed    |    1 +
 libsrc/support/cleanelm.awk                        |   67 +
 libsrc/support/condn.awk                           |  432 ++
 libsrc/support/convcln.awk                         |   94 +
 libsrc/support/convert.awk                         |  693 ++
 libsrc/support/elmdict.awk                         |  172 +
 ...mtojava_DicomDictionary_CreateFullNameByTag.awk |   29 +
 .../elmtojava_DicomDictionary_CreateIEByTag.awk    |  309 +
 .../elmtojava_DicomDictionary_CreateNameByTag.awk  |   65 +
 .../elmtojava_DicomDictionary_CreateTagByName.awk  |  137 +
 .../elmtojava_DicomDictionary_CreateTagList.awk    |   66 +
 .../elmtojava_DicomDictionary_CreateVRByTag.awk    |   67 +
 libsrc/support/elmtojava_TagFromName.awk           |  111 +
 libsrc/support/elmtoxml.awk                        |   76 +
 .../extractiodandmodulerelationshipsbytag.awk      |  166 +
 libsrc/support/inserttagumberbeforekeyword.sh      |   21 +
 libsrc/support/iodcomp.awk                         |  214 +
 libsrc/support/modtype.awk                         |   59 +
 libsrc/support/module.awk                          |  783 ++
 libsrc/support/sopcl.awk                           |   85 +
 libsrc/support/strval.awk                          |  119 +
 libsrc/support/tagval.awk                          |  111 +
 libsrc/support/transyn.awk                         |  124 +
 libsrc/support/unkelm.awk                          |   25 +
 support/Imakefile                                  |    2 +
 support/findpre                                    |    4 +
 support/gzip-1.2.4-patchfornoheader                |  617 ++
 support/gzip-1.3.12-patchfornoheader               |  575 ++
 support/linksb                                     |   32 +
 support/mktime.cc                                  |   71 +
 support/noincsub                                   |   34 +
 support/recurse                                    |   20 +
 support/setplatform                                |   13 +
 support/setversion                                 |   17 +
 support/stanford.pvrg.jpeg.ge.patch.19990405       |  144 +
 support/testapp                                    |  198 +
 support/testapp.SChex0bug                          |  182 +
 support/updatecopyright                            |  107 +
 support/xbmtocbm                                   |   10 +
 support/xxxxto                                     |  121 +
 support/y2kcheck                                   |   10 +
 888 files changed, 173510 insertions(+)

diff --git a/BUGS b/BUGS
new file mode 100755
index 0000000..2d1c6bd
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,65 @@
+000715.0001	open	ancreate	clunie	a-f in group or element without 0x causes death
+
+000220.0001	open	binpatch	clunie	fails on little endian architectures
+
+980519.0001	resolved	Configure	clunie	imake/cpp unprotected substitutions for host/os
+
+	The DependIncludePath's are not protcted by quotes so when imake calls
+	cpp to expnd them, macro substitutaion using pre-defined names like
+	"sun" and "sparc" get replaced by "1".
+
+	980519 Resolved for gcc/g++ case by having Configure quote with double-quotes
+
+980405.0001	open	dcdisp	clunie	"Signed 12 bit images don't sign extend"
+
+	dcsmpte -bits 12 -minval ' -1024' -maxval 3071 /tmp/crap -signed
+
+	dchist -h /tmp/crap
+	[0xcc]	2500	p=0.00953674	e=0.0640134	cum=0.0640134
+	[0x266]	2454	p=0.00936127	e=0.0630863	cum=0.1271
+	[0x3ad]	9893	p=0.0377388	e=0.178422	cum=0.305521
+	[0x3ff]	127210	p=0.485268	e=0.506206	cum=0.811727
+	[0x428]	10198	p=0.0389023	e=0.182218	cum=0.993946
+	[0x47a]	5085	p=0.0193977	e=0.110334	cum=1.10428
+	[0x599]	2453	p=0.00935745	e=0.0630661	cum=1.16735
+	[0x732]	2500	p=0.00953674	e=0.0640134	cum=1.23136
+	[0x7ff]	14442	p=0.0550919	e=0.230395	cum=1.46175
+	[0x8cc]	2500	p=0.00953674	e=0.0640134	cum=1.52577
+	[0xa65]	2500	p=0.00953674	e=0.0640134	cum=1.58978
+	[0xb32]	17426	p=0.0664749	e=0.259986	cum=1.84977
+	[0xbff]	20590	p=0.0785446	e=0.288286	cum=2.13805
+	[0xc00]	19958	p=0.0761337	e=0.282861	cum=2.42091
+	[0xccc]	17435	p=0.0665092	e=0.260071	cum=2.68099
+	[0xd99]	2500	p=0.00953674	e=0.0640134	cum=2.745
+	[0xf33]	2500	p=0.00953674	e=0.0640134	cum=2.80901
+
+	dcdisp /tmp/crap
+	...
+	usegray.cc:146: failed assertion `bottom<=top'
+
+
+980301.0001	open	dcdisp	clunie	"Some large color RGB images skewed"
+
+	Some large RGB images appear skewed eg. VL4 (looks
+	fine in Osiris and Photoshop (dual TIFF))
+
+	Can duplicate with:
+
+	pgmramp -lr 2226 100 | pnmdepth 255 > ramp.pgm
+	rgb3toppm ramp.pgm ramp.pgm ramp.pgm > ramprgb.ppm
+	pnmtodc ramprgb.ppm ramprgb.dc3
+	dcdisp ramprgb.dc3
+
+	Does NOT occur with 2224 or 2228 columns :( !!!
+
+	This is probably related to the odd length buffer problem,
+	since in this case the number of samples is 3.
+
+980301.0002	open	dcdisp	clunie	"RGB images with <8 bits stored appear black"
+
+	VL6 needed to have BitsStored manually set to 8 else was black - this
+	came from a Targa file and tgatoppm probably sets a low maxval.
+
+980920.0001	dcdisp fails when 12 bit signed (rather than 16)
+
+	usegray.cc:144: failed assertion `bottom<=top'
diff --git a/CHANGES b/CHANGES
new file mode 100755
index 0000000..4181fc2
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,3803 @@
+151212:	libsrc/standard/condn.tpl,iodcomp/sr.tpl: Add Acquisition Context SR (Sup 187)
+
+151207:	libsrc/standard/condn.tpl,iodcomp/sr.tpl: Add Radiopharmaceutical RDSR (Sup 159)
+
+151207:	appsrc/dcfile/dcentvfy.cc,libsrc/src/locale/mesgtext.tpl: Check that UIDs are not reused in different parent entities (000481)
+
+151206:	libsrc/standard/condn.tpl,module/ct.tpl,mr.tpl,pet.tpl,xaxrf.tpl: Correct/implement condition on ReferencedImageEvidenceSequence and SourceImageEvidenceSequence to detect when required (000480)
+
+151206:	libsrc/standard/condn.tpl,module,strval/base.tpl: Small animal identification and change to homo sapiens code and conditions for human or animal using it (CPs 1457, 1470, 1472, 1473, 1478)
+
+151206:	libsrc/standard/elmdict/other.tpl: Add some Brainlab private data elements
+
+151125:	libsrc/standard/elmdict/philips.tpl: More Philips MR private data elements
+
+151124:	libsrc/standard/module,strval/base.tpl: Update SOP Common with legacy conversion attributes (Sup 157) and Content Qualification (CP 1356)
+
+151124:	libsrc/standard/condn.tpl,iodcomp/dx.tpl,module/dx.tpl,xaxrf.tpl,strval/dx.tpl: Add Breast Projection X-Ray IOD (Sup 165)
+
+151120:	libsrc/standard/condn.tpl,module/base.tpl,sr.tpl: Check for inappropriate ReferencedFrameNumber or ReferencedSegmentNumber using the ReferencedSOPClassUID (000479)
+
+151120:	libsrc/standard/sopcl.tpl: Add SOP Classes for Sup 173 Wide Field Ophthalmic Photography
+
+151118:	config/Configure: Add yet another place libX11 files hide on Linux (this time in /usr/lib/x86_64-linux-gnu for Ubuntu 14.04)
+
+151116:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1432 final text
+
+151116:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1487 final text
+
+151116:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1431 final text
+
+151116:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1364 final text
+
+151115:	appsrc/dcfile/dcmulti.cc: Do not partition dimension indices of lower rank at less then organization UID scope (i.e., number from one and increment by one for whole instance) (000475)
+
+151115:	appsrc/dcfile/dciodvfy.cc: Check that DimensionIndexValues match InStackPosition and TemporalPosition (000477)
+
+151115:	appsrc/acrnema/ancreate.cc: Correct writing of specified (usually undefined length) VL for SQ that was broken when refactoring to use vr.h (000478)
+
+151115:	libsrc/standard/condn.tpl,module/base.tpl: Check that TemporalPositionIndex is not zero (000476)
+
+151115:	libsrc/standard/elmdict/philips.tpl: More Philips MR private data elements
+
+151111:	libsrc/standard/sopcl.tpl: Add SOP Class for Sup 187 final text
+
+151110:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1478 final text
+
+151110:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1457 final text
+
+151110:	libsrc/standard/elmdict/dicom3.tpl: Add data elements assigned for Sup 184 final text
+
+150926:	libsrc/include/pixeldat/srcsink.h: Supply virtual destructor with default empty implementation to silence compiler warning
+
+150926:	appsrc/acrnema/ancp.cc: Check for bad zero bytes for explicit VR in same manner as andump.cc, attrmxrd.cc (000471)
+
+150926:	appsrc/acrnema/ancp.cc: Check for implicit VR attribute even though explicit transfer syntax in same manner as andump.cc, attrmxrd.cc (000470)
+
+150926:	libsrc/include/dctool/vr.h: Use strncmp rather than strcmp for VR comparisons throughout, because might have passed fixed length array of 2 characters that is not null terminated
+
+150925:	appsrc/acrnema/ancp.cc: Reset endianness after backing up to re-read tag when starting after metaheader (000469)
+
+150925:	appsrc/acrnema/ancp.cc,ancreate.cc,andump.cc,dcfile/dcfile.cc,libsrc/include/dctool/attr.h,attrmxls.h,vr.h,src/dctool/attrlsln.cc,attrmxrd.cc: Factor out all VR check methods into separate header file, check for known short rather than known long value length VRs to cope with future additions, automatically, and use it when computing offsets for DICOMDIR as well (was not handled in last update for OD and OL)
+
+150925:	appsrc/acrnema/ancp.cc,ancreate.cc,andump.cc,libsrc/include/dctool/attrmxls.h,attrtype.h,attrtypo.h,src/dctool/attr.cc,attrmxrd.cc,attrtypo.cc: Add support for reading, writing and copying OD and OL VRs
+
+150918:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Add UIDs and data elements for Sup 181 (note that new OL VR is not yet supported by rest of code)
+
+150916:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1458
+
+150915:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Add UIDs and data elements for Sup 156
+
+150910:	libsrc/standard/elmdict/dicom3.tpl: Add data elements assigned for CPs 1441, 1454 and 1461
+
+150904:	libsrc/standard/elmdict/other.tpl: Add Mediso private elements from samples
+
+150904:	config/Configure: On Darwin since Mavericks and/or Yosemite and/or Xcode6, handle missing makedepend by checking XQuartz /opt/X11 location
+
+150902:	config/Configure: On Darwin since Mavericks and/or Yosemite, handle missing X11 library and include by looking for MacPorts versions (first)
+
+150805:	libsrc/standard/elmdict/other.tpl: Add MDDX PX private elements moved to 7fe1 group
+
+150804:	libsrc/src/dctool/attrmxrd.cc: Show actual tag in error message about PixelData VR since it may be private pixel data
+
+150722:	libsrc/standard/elmdict/diconde.tpl: Add more DICONDE data elements (E2339 update)
+
+150717: libsrc/include/dctool/ie.h,standard/condn.tpl,iodcomp/sr.tpl,iodcomp,module,strval/vl.tpl: Add Ophthalmic Refractive Measurements IODs and Modules (Sup 130)
+
+150717:	libsrc/standard/strval/base.tpl: Synchronize Modality defined terms with 2015c release (was missing ophthalmic measurements from Sup 130, also PLAN, RESP, STAIN)
+
+150713: libsrc/standard/elmdict/philips.tpl: Yet more Philips US private data elements from samples
+
+150712: libsrc/standard/elmdict/philips.tpl: More Philips US private data elements from samples
+
+150705:	libsrc/standard/elmdict/other.tpl: Add PixelMed private data elements for group of patients identification
+
+150705:	libsrc/standard/elmdict/other.tpl: Update PixelMed private data elements for cell line
+
+150704:	libsrc/standard/module/ct.tpl: Do not report error when AcquisitionDateTime or AcquisitionDuration are present in EnhancedCTImage module since mbpo (000463)
+
+150704:	libsrc/standard/strval/base.tpl: Add 99IPCMR coding scheme to MiscellaneousCodingSchemeDesignators
+
+150704:	libsrc/standard/elmdict/other.tpl: Add PixelMed private data elements for cell line
+
+150630:	libsrc/standard/elmdict/gems.tpl: Update GE private data element that is (sometimes ?) noise index (varies between conformance statements)
+
+150623:	libsrc/standard/elmdict/gems.tpl: Update GE DBT private data elements
+
+150615:	libsrc/standard/elmdict/other.tpl: Add PixelMed private data elements for mouse strain (per CP 1457 draft)
+
+150615:	libsrc/standard/transyn.tpl,elmdict/dicom3.tpl,module/base.tpl: Add MPEG 4.2 Transfer Syntax UIDs and Stereo Pairs Present to IODs (Sup 180)
+
+150615:	libsrc/standard/sopcl.tpl: Add Extensible SR SOP Class (Sup 186)
+
+150602:	libsrc/standard/elmdict/dicom3.tpl: Add data elements from CP packet 81 (CPs 1321,1322,1402,1411,1438)
+
+150531:	appsrc/dcfile/dciodvfy.cc: Do not warn about UCUM used in non Units Code Sequence when found in Coding Scheme Identification Sequence (000462)
+
+150531:	libsrc/standard/strval/base.tpl: Add 99IPCMR coding scheme
+
+150514:	libsrc/standard/elmdict/siemens.tpl: Add some Philips US private element descriptions (not 100% sure of private creator match :() from iE33 1.1 DCS
+
+150502:	libsrc/standard/elmdict/siemens.tpl: Add private elements from Siemens Inveon Research Workplace 4.2 DICOM Conformance Statement
+
+150502:	libsrc/standard/elmdict/other.tpl: Mediso NanoSPECT private data elements observed in samples, including those from Scivis GmbH PET recon
+
+150430:	libsrc/standard/strval/us.tpl: Update experimental QT Ultrasound profile with revised impedance mismatch LUT Label that fits in SH
+
+150428:	libsrc/src/dctool/condn.cc: remove dependence of US IOD detection on Instance Number, since curves have been retired (000461)
+
+150424:	libsrc/standard/condn.tpl,module/mr.tpl: Improve condition on Diffusion Anisotropy Type (000460)
+
+150424:	libsrc/src/dctool/condn.cc,standard/condn.tpl,support/condn.awk: Add wildcard or specific value support to binary values in conditions, to be able to check for any DimensionIndexValue not starting at one, not just first one (000459)
+
+150324:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for Sup 173
+
+150324:	libsrc/standard/module/us.tpl,strval/base.tpl,us.tpl: Update experimental QT Ultrasound profile
+
+150324:	libsrc/standard/module/mr.tpl: Move Spacing Between Slices to Pixel Measures Macro and remove from Enhanced MR Image Module (CP 1427)
+
+150324:	libsrc/standard/module/us.tpl: Use Pixel Measures in Enhanced US Volume (CP 1428)
+
+150320:	libsrc/standard/strval/base.tpl: Add 99KINETDX coding scheme
+
+150319:	libsrc/standard/condn.tpl,module/base.tpl: Add condition to Pixel Measures, Plane Position and Orientation Functional Groups for Segmentation objects with Frame of Reference UID (CP 1426)
+
+150319:	libsrc/standard/condn.tpl: Add ethics committee and consent elements to conditions for presence of clinical trials modules (CP 942), and add Clinical Trial Series ID and Description to conditions (000457)
+
+150319:	libsrc/standard/strval/base.tpl: Add NCIt coding scheme (CP 1372)
+
+150318:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CP 1420, CP 1430, CP 1434
+
+150314:	libsrc/standard/tagval.tpl,module/us.tpl,strval/base.tpl,us.tpl: Update experimental QT Ultrasound profile for Enhanced US Volume to check Dimension Index pointers, use Temporal Position Sequence, and check RWVM LUT text and units
+
+150314:	libsrc/support/tagval.awk: recognize uppercase as well as lower case hex characters in tag numbers in templates
+
+150302:	appsrc/dcfile/dcsrdump.cc: Fix missing segment number (000455)
+
+150227:	libsrc/standard/binval.tpl,condn.tpl,iodcomp,module/us.tpl,strval/base.tpl,charset.tpl,us.tpl,waveform.tpl: Add experimental QT Ultrasound profile for Enhanced US Volume
+
+150227:	libsrc/standard/elmdict/other.tpl: Add QT Ultrasound private element
+
+150227:	libsrc/standard/module,strval/us.tpl: Add missing VolumeToTransducerRelationship to Enhanced US Volume (000454)
+
+150225:	libsrc/standard/condn.tpl,iodcomp,module/pet.tpl: Add final text of legacy converted enhanced PET (Sup 157)
+
+150213:	libsrc/standard/elmdict/other.tpl: Add MDDX Allup private elements
+
+150209:	libsrc/standard/strval/base.tpl: Use empty value flag in list for EmptyValue, otherwise empty values in Image and Frame Type values 3 and 4 in Enhanced US Volume are incorrectly flagged as errors (000453)
+
+150203:	libsrc/standard/elmdict/other.tpl: Add DR Systems private element encountered
+
+150127:	appsrc/acrnema/andump.cc,dcfile/dcdirdmp.cc,dcsrdump.cc,libsrc/include/dctool/dcstream.h,libsrc/src/dctool/attrmxrd.cc,dcstream.cc,locale/mesgtext.tpl: Do not give up when empty or missing Transfer Syntax UID in meta information header, but guess and continue (000450)
+
+150127:	libsrc/standard/module,strval/dx.tpl: Add Positioner Primary Angle Direction (CP 1032)
+
+150127:	libsrc/standard/iodcomp/dx.tpl,module/dx.tpl: Add IHE DBT profile (IHE DBT TI 4.8.4.1.2.7 Storage of Digital Breast Tomosynthesis Images)
+
+150127:	libsrc/standard/module/dx.tpl,xaxrf.tpl,vstrval/dx.tpl: Update defined terms and enumerated values for breast tomo biopsy, contrast, dual energy, projections (CP 1342)
+
+150121:	Imakefile: Add dctoraw and dcdiff and dccmp scripts to windows and mac exe release
+
+150117: appsrc/acrnema/ancreate.cc,andump.cc,dcfile/dciodvfy.cc,libsrc/include/dctool/attrmxls.h,attrtype.h,src/dctool/attrmxrd.cc,attrnew.cc,attrtypv.cc,locale/mesgtext.tpl,standard/condn.tpl,module/base.tpl,strval/base.tpl: Add validation and UC VR support for long codes (CP 1031)
+
+150116:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for long codes (CP 1031)
+
+150106:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl,sr.tpl,strval/base.tpl: Add Mapping Resource UID (CP 1417)
+
+150106:	libsrc/standard/condn.tpl: Update list of functional groups used as DimensionIndexPointer for check that FunctionalGroupPointer is not needed in DimensionIndexSequence to include those from PET, Ophthalmic and IV OCT, WSI, SEG, Parametric Map and additional MR stuff
+
+150106:	module/dx.tpl,us.tpl,vl.tpl: Make Shared Functional Group Sequence Type 1 again per Type 1 SQ Empty Items in Functional Groups (missed a few first time this CP was applied) (CP 1274)
+
+150106:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: check that number of items in PerFrameFunctionalGroupsSequence matches number of frames (000449)
+
+141202:	libsrc/standard/elmdict/other.tpl: Add RamSoft binary document in text SR related private data elements
+
+141124:	libsrc/standard/elmdict/philips.tpl: Add more ultrasound private data elements encountered
+
+141119:	libsrc/standard/module/file.tpl: Add Sending and Receiving AETs to file meta information for dciodvfy (CP-1297)
+
+141114:	libsrc/standard/elmdict/dicom3.tpl: Change Sup 172 data elements to FT2, using 08 and 09 to avoid conflict with old ACR-NEMA PS3.2 data compression
+
+141113:	ibsrc/standard/binval.tpl,condn.tpl,iodcomp,module,strval/base.tpl: Add Sup 172 Parametric Map
+
+141113:	libsrc/standard/condn.tpl,module/base.tpl,sr.tpl: Add CP 1387 Quantity Definition Sequence to RWVM, cleanup numeric condition handling in Content Item macro
+
+141110:	libsrc/standard/elmdict/dicom3.tpl: Add data elements CPs 1350, 1383, 1399
+
+141110:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Add Sup 172 FT data elements and SOP Class
+
+141104:	libsrc/standard/elmdict/diconde.tpl: Add new DICONDE data elements for E2663-11
+
+141025:	libsrc/standard/condn.tpl,support/condn.awk: Add StringValueFromRootAttribute mechanism for conditions and test with RT ScanMode (000447)
+
+141019:	libsrc/standard/elmdict/dicom3.tpl: ScheduledProcedureStepStartDateTime is not retired after all:
+
+140917:	appsrc/dcfile/dciodvfy.cc,libsrc/include/dctool/attrmxls.h,src/dctool/attrmxls.cc,attrmxrd.cc: Add parameter to read() methods to control whether or not to fix bit-depth related attributes during reading, make it on by default, and turn it off just for dciodvfy (000445)
+
+140917:	libsrc/standard/binval.tpl,module/base.tpl: Use correct enumerated values for CT Image BitsStored of 12 to 16, not 12 or 16 (000444)
+
+140909:	libsrc/include/dctool/attrmxls.h,attrtype.h,src/dctool/attr.cc,attrmxrd.cc,attrnew.cc,attrtypv.cc,standard/elmdict/dicom3.tpl: Add UR VR (CP 1324)
+
+140903:	libsrc/standard/elmdict/acuson.tpl,siemens.tpl: Siemens ultrasound private data element updates from conformance statements
+
+140902:	libsrc/standard/elmdict/gems.tpl: Update private data elements related to archive
+
+140828:	libsrc/standard/module/base.tpl: Add check for single item to Frame Content Sequence
+
+140828:	libsrc/standard/module/base.tpl,dx.tpl: Support IEC 62494 Exposure Index of Digital X-ray Imaging Systems (CP1024)
+
+140828:	libsrc/standard/module/dx.tpl,xaxrf.tpl: Add Irradiation Event UID to X-Ray 3D IODs (CP1285)
+
+140826:	libsrc/standard/elmdict/gems.tpl: Private data element VRs encountered in DBTs
+
+140826:	libsrc/src/dctool/attrmxrd.cc: Handle skipping over pixel data value larger than 2GB when reading attribute list (use Uint32 not long) (000440)
+
+140826:	config/Configure: detect and warn about any bad Apple LLVM version 5.x, not just version 5.0
+
+140729:	libsrc/standard/elmdict/gems.tpl: Private data elements from echo images
+
+140703:	libsrc/standard/elmdict/gems.tpl,siemens.tpl: Private data elements from echo SRs
+
+140630:	libsrc/standard/elmdict/dicom3.tpl: Remove element (3006,00BA) that was not used in CP 1287 FT after all
+
+140626:	libsrc/standard/elmdict/siemens.tpl: Add VR for another KINETDX private data element
+
+140624:	libsrc/standard/elmdict/philips.tpl: more labels for Philips data elements
+
+140624:	libsrc/standard/elmdict/dicom3.tpl: Add data elements for CPs 1203, 1331, 1343, 1347
+
+140611:	libsrc/standard/elmdict/philips.tpl: label Philips private scale slope and intercept data elements
+
+140527:	libsrc/standard/strval/base.tpl: add QIICR coding scheme UID
+
+140527:	libsrc/src/locale/mesgtext.tpl,appsrc/dcfile/dciodvfy.cc: check appropriate use of UCUM as CSD (000438)
+
+140516:	appsrc/dcfile/dcj2k.sh: Make default (no option) reversible as described in documentation
+
+140508:	libsrc/standard/elmdict/acuson.tpl,philips.tpl: More Acuson private element VRs encountered in samples; move elements to Acuson template
+
+140506:	libsrc/standard/elmdict/other.tpl: Remove spurious trailing characters in element dictionary
+
+140428: libsrc/standard/elmdict/other.tpl: Add Carestream private data elements encountered in sample
+
+140428: appsrc/dcfile/dciodvfy.cc,libsrc/include/dctool/attrmxls.h,attrtag.h,src/dctool/attrmxls.cc,locale/mesgtext.tpl: Do not report bad private group 0xffff as bad standard element, but check specifically for bad groups (000437)
+
+140420:	libsrc/standard/elmdict/dicom3.tpl: Add Sup 124 data element tags
+
+140419:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Sup 159 SOP Class UID and data element
+
+140417:	libsrc/standard/elmdict/gems.tpl: Add GE FUNCTOOL private data elements
+
+140411:	libsrc/standard/elmdict/other.tpl: Add private element encountered in sample
+
+140411:	libsrc/standard/condn.tpl: correct condition for inclusion of Specimen Module when user optional (Sup 122)
+
+140410:	libsrc/standard/elmdict/agfa.tpl: Add private elements enountered in GSPS samples
+
+140409:	libsrc/src/locale/mesgtext.tpl: Clarify leading zeroes in UID message (000436)
+
+140409:	libsrc/standard/elmdict/agfa.tpl,other.tpl: Add private elements (including TomTec) encountered in sample
+
+140331:	libsrc/standard/elmdict/dicom3.tpl: New data elements from WG 6 March CPs
+
+140326:	libsrc/standard/transyn.tpl: Add Sectra Compression private transfer syntaxes
+
+140324: libsrc/standard/elmdict/philips.tpl: Philips US private data elements from samples
+
+140324:	libsrc/standard/elmdict/siemens.tpl: change LT to OB with render as string for KINETDX_GRAPHICS private data element that contains XML
+
+140323:	libsrc/standard/elmdict/philips.tpl: Philips US private data elements from samples
+
+140320:	libsrc/standard/strval/base.tpl: Add RWV to General Series list of modalities
+
+140318:	libsrc/standard/elmdict/other.tpl: Hologic DXA private data elements from conformance statement
+
+140317:	libsrc/standard/strval/softcopy.tpl: add LINEAR_EXACT function defined term (CP1264)
+
+140310: libsrc/standard/elmdict/other.tpl: add iCAD prostate DCE-MR processing private elements from sample
+
+140311:	appsrc/acrnema/andump.cc: add OD support
+
+140310:	libsrc/standard/elmdict/other.tpl: add NNT private elements from sample
+
+140306:	Imakefile,support/setplatform,libsrc/include,src/generic/getoptns.cc,platformn.cc,.h,: include platform information (established at make World) in version message, and gcc version
+
+140306:	Imakefile,support/setversion,appsrc/dcintro/gen.so,appsrc/*.man,libsrc/include,src/generic/getoptns.cc,version.cc,.h,: add command line option "-version"
+
+140301:	libsrc/standard/strval/base.tpl,sr.tpl: add more private and standard coding schemes and UIDs, and change SRT to .96 rather than .5 (??which was for SNM)
+
+140301:	libsrc/standard/module/sr.tpl: include Referenced Segment Number in IMAGE content item macro (Sup 111)
+
+140220:	libsrc/standard/elmdict/other.tpl: more Vital private elements from 6.5 conformance statement
+
+140128:	libsrc/standard/elmdict/elscint.tpl,philips.tpl: Update observed private elements
+
+140128:	libsrc/standard/elmdict/dicom3.tpl,module/us.tpl: Change case of ExclusionStartDateTime keyword
+
+140120:	libsrc/standard/elmdict/dicom3.tpl: Change case of Multi-Frame to Multi-frame in element description
+
+140118:	libsrc/standard/elmdict/dicom3.tpl: Tidy up more data element names and keywords whilst resolving inconsistencies between parts 3 and 6
+
+140111:	libsrc/standard/elmdict/dicom3.tpl: Tidy up some data element names and keywords whilst resolving inconsistencies between parts 3 and 6
+
+140106:	libsrc/standard/elmdict/dicom3.tpl: Update data dictionary with CPack 74
+
+140106:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Add final text attribtues and SOP classes for Breast Tomo Projection (Sup 165)
+
+140105:	libsrc/standard/condn.tpl,iodcomp/ct.tpl,mr.tpl,module/base.tpl,ct.tpl,mr.tpl: Add final text of legacy converted enhanced CT and MR (Sup 157)
+
+131224:	libsrc/standard/elmdict/diconde.tpl: final names of IQI elements
+
+131211:	libsrc/standard/elmdict/other.tpl: Add Soredex private element from example and conformance statement, and render OB as string
+
+131211:	libsrc/include/dctool/elmdict.h,src/dctool/attrtypo.cc,elmdict.cc,elmentry.h,standard/elmdict/agfa.tpl,support/elmdict.awk: update Mitra annotation private elements, use OB VR per conformance statement and samples; add RenderAsString field to dictionary and methods and use for small OB VR dump
+
+131208:	libsrc/standard/elmdict/siemens.tpl: add ABVS private data elements from S2000 CS and samples
+
+131129:	libsrc/standard/elmdict/diconde.tpl: add IQI data elements from revision of ASTM E2767-11
+
+131123:	libsrc/standard/elmdict/other.tpl: Add Instrumentarium private element from conformance statement for CliniView
+
+131120:	module,strval/xaxrf.tpl: Add volume based calculation technique for tomosynthesis (CP 1299)
+
+131120:	module/base.tpl,ct.tpl,mr.tpl,pet.tpl,xaxrf.tpl: Make Shared Functional Group Sequence Type 1 again per Type 1 SQ Empty Items in Functional Groups (CP 1274)
+
+131023:	libsrc/standard/module/base.tpl: check Segment Number is not zero
+
+131020:	libsrc/standard/elmdict/philips.tpl: Some more descriptions for Philips private MR data elements
+
+131019:	libsrc/standard/condn.tpl,module/base.tpl: Implement conditions in Pixel Measures Sequence based on Volumetric Properties values
+
+131018:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl: Add Used Segments Sequence to Spatial Registration Module (CP 1268)
+
+131015:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Add data elements and SOP Class for Corneal Topography Map (Sup 168)
+
+131005:	INSTALL, config/Configure: Handle bad cpp that Apple ships with XCode 5, and change in g++ version string
+
+131005:	support/testapp: Filter out spurious assertion messages from Apple LLVM version 5.0, which interferes with comparison with previous logs
+
+130924:	libsrc/src/dctool/condn.cc: Made ElementPresentInPathFromRoot condition descend recursively, to pick up instance references needed for Common Instance Reference Module conditions ... makes things much slower when lots of per-frame items, but works
+
+130924:	appsrc/dcfile/dciodvfy.cc,libsrc/include/locale/mesgtext.tpl: Check that number of values of DimensionIndexValues matches number of items in DimensionIndexSequence
+
+130924:	libsrc/standard/module/base.tpl: Remove obsolete condition (original or mixed) on Frame Content Sequence in Frame Content functional group macro (was failing to detect missing when derived segmentations)
+
+130917:	libsrc/standard/elmdict/diconde.tpl: Make DICONDE ST attributes VL 1 not 1-n, and retire/rename some elements per final E2339-11
+
+130914:	libsrc/standard/strval/rt.tpl: Correction of Intraoperative Applicator Type In Ion Beam (CP 1277)
+
+130914:	libsrc/standard/module/vl.tpl: In WSI, Navigation Sequence Item references only one frame (CP 1273)
+
+130914:	libsrc/standard/module/dx.tpl: Add Target Information for Mammography Biopsy (CP 1269)
+
+130914:	libsrc/standard/module/base.tpl: Relax rescale restrictions for Multi-frame Grayscale Word IOD to allow use as parametric maps (CP 1263)
+
+130914:	libsrc/standard/strval/base.tpl: Add defined term for MPEG4 (CP 1256)
+
+130914:	libsrc/standard/module/base.tpl: Add Real World Value Mapping to General Image Module (CP 1252)
+
+130914:	libsrc/standard/module/rt.tpl: Include Series Date, Time in RT IODs (CP 1251)
+
+130914:	libsrc/standard/condn.tpl,module/dx.tpl,xaxrf.tpl,strval/dx.tpl: Add sterotactic frame and image type terms for breast tomo (CP 1250)
+
+130914:	libsrc/standard/elmdict/dicom3.tpl: Mark Structure Set Frame of Reference Relationship Sequence and related elements as retired, but leave in module so can check values if present (CP 1249)
+
+130914:	libsrc/standard/condn.tpl,module,strval.rt.tpl: Add spatial transformation of dose (CP 1248)
+
+130912:	libsrc/standard/iod/base.tpl,ct.tpl,dx.tpl,mr.tpl,pet.tpl,rt.tpl,us.tpl,vl.tpl,xaxrf.tpl: Add Common Instance Reference Module to all Image and RT IODs (CP 1243)
+
+130911:	libsrc/standard/condn.tpl,module/us.tpl: Add Zero Velocity Pixel Value (CP 1236)
+
+130911:	libsrc/standard/strval/charset.tpl: Add GBK defined terms (CP 1234)
+
+130909:	libsrc/standard/module/base.tpl: Add InstanceCoercionDateTime (CP 1216)
+
+130909:	libsrc/standard/module,strval/pet.tpl: Add SUVType and IBW (CP 1210)
+
+130909:	libsrc/standard/condn.tpl,module,strval/rt.tpl: Add sessions to Dose Summation Type (CP 1206)
+
+130905:	libsrc/standard/module/base.tpl: Add Isocenter Position and RT Equipment Correlation to CT Image (CP 1205)
+
+130819:	libsrc/standard/module/base.tpl,us.tpl: Change Lossy Image Compression from 1C to 1 in Intravascular OCT, Enhanced US (CP 1283)
+
+130818:	libsrc/standard/module/base.tpl: Add attributes to Surface Mesh Module (CP 1200)
+
+130818:	libsrc/standard/module/base.tpl: Factor out RWV mapping item macro and use it in NM Image (CP 1179)
+
+130818:	libsrc/standard/module/softcopy.tpl: Add creation date and time to Structured Display (CP 1175)
+
+130815:	libsrc/standard/elmdict/dicom3.tpl: Add STOW attributes (Sup 163)
+
+130705:	libsrc/standard/module/rt.tpl: Make StructureSetROISequence mandatory (CP 1158)
+
+130704:	libsrc/standard/module/sr.tpl,appsrc/dcfile/dcsrdump: Add ObservationOID (CP 1147) and have dcsrdump show it as well as ObservationDateTime
+
+130704:	libsrc/standard/elmdict/dicom3.tpl: Retire old beam dose depth attributes from dictionary (already removed from modules and replaced) (CP 1138)
+
+130704:	libsrc/standard/strval/rt.tpl: Remove NORMAL defined term from HighDoseTechnique (CP 1132)
+
+130704:	libsrc/standard/module/rt.tpl: LeafPositionBoundaries mbpo (CP 1131)
+
+130703:	libsrc/standard/module/base.tpl,sr.tpl: Add Protocol Name to SR, KO and Encapsulated Document Series (CP 1125)
+
+130703:	libsrc/standard/module/base.tpl: Add QualityControlSubject (CP 1123)
+
+130703:	libsrc/standard/module/rt.tpl: Add BeamDoseMeaning (CP 1121)
+
+130703:	libsrc/standard/module/rt.tpl: Add source distance for general accessory (CP 1120)
+
+130703:	libsrc/standard/module/rt.tpl: Change recorded SourceApplicatorType to Defined Terms in record (CP 1118)
+
+130703:	libsrc/standard/module/rt.tpl: Add floating point exposure attributes to RT Image (CP 1116)
+
+130703:	libsrc/standard/module/sr.tpl: Add PixelOriginInterpretation to Spatial Coordinates for WSI (CP 1099)
+
+130703:	libsrc/standard/module/softcopy.tpl: Add ImageSetSelectorUsageFlag to FilterOperationsSequence (CP 1098)
+
+130703:	libsrc/standard/elmdict/dicom3.tpl: Allow multiple IrradiationEventUID values (CP 1090)
+
+130702:	libsrc/standard/module/base.tpl: Factor out Segment Description Macro per CP 1258
+
+130626:	libsrc/standard/module/base.tpl,dx.tpl,pet.tpl,softcopy.tpl,xaxrf.tpl: Be consistent in forbidding 0 items in Type 3 sequences, and use SeriesNeedReferencedPerformedProcedureStepSequence consistently rather than NoCondition for 1C ReferencedPerformedProcedureStepSequence
+
+130626: libsrc/standard/condn.tpl,sopcl.tpl,elmdict/dicom3.tpl: Sup 158 retire GPWL
+
+130623: libsrc/standard/condn.tpl,module,strval/vl.tpl: add Purpose of Reference in OCT Ophthalmic Frame Location Macro (CP 1190) and fix condition on per-frame macro inclusion
+
+130619:	libsrc/standard/elmdict/other.tpl: add conformance statement and observed Nucletron Oncentra Prostate private data elements
+
+130615:	libsrc/standard/elmdict/dicom3.tpl: CP 1248, 1258, 1269 data elements
+
+130614:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl,other.tpl: Sup 157 data elements and SOP Classes
+
+130608:	libsrc/standard/elmdict/diconde.tpl: add revised eddy current data elements
+
+130418:	libsrc/standard/elmdict/other.tpl: more observed private tag VRs for Stentor
+
+130417:	libsrc/standard/elmdict/gems.tpl: private tag VRs from Infinia-II conformance statement and some additional observed from dose reports
+
+130416:	libsrc/standard/elmdict/agfa.tpl: more observed private tag VRs
+
+130416:	libsrc/include/dctool/attrtypn.h,/src/dctool/attrmxrd.cc,locale/mesgtext.tpl: allow histograms larger than encodable in EVR since sometimes found in IVR (e.g., RT DVH) and want to be able to validate them despite this (000683)
+
+130415:	libsrc/standard/elmdict/other.tpl: private tag VRs from EOS Imaging digital x-ray conformance statement
+
+130415:	libsrc/standard/elmdict/other.tpl: private tag VRs from Planmed Nuance mammo conformance statement
+
+130408:	libsrc/standard/elmdict/dicom3.tpl: add Autosequence Flag attribute (CP 1246)
+
+130413:	libsrc/standard/elmdict/philips.tpl: more observed private tag VRs
+
+130322:	libsrc/standard/module/mr.tpl.us.tpl: VolumeBasedCalculationTechnique values are defined terms not enumerated values
+
+130322:	libsrc/standard/elmdict/other.tpl: change (0019,0062) Hologic private 2D IP Parameters VR from LO to LT based on observed length and confirmation from Hologic
+
+130322:	libsrc/standard/strval/base.tpl: add 99HOLX private coding scheme
+
+130322:	libsrc/standard/module/base.tpl: relax requirement on presence of Frame Context Sequence when derived image (partial CP 994)
+
+130318:	libsrc/standard/condn.tpl,module/base.tpl: report illegal chrominance downsampled photometric interpretations like YBR_FULL_422 for uncompressed transfer syntaxes
+
+130313:	libsrc/standard/condn.tpl,module,strval/base.tpl: stop incorrectly reporting illegal RGB for lossless JPEG (000432), and add check that is not a lossy photometric interpretation
+
+130312:	appsrc/dcfile/dcsrdump.cc: include template identifier and mapping resource in dump if present (000431)
+
+130301:	libsrc/standard/condn.tpl: do not require laterality if a specimen, since anatomy optional and hard to check
+
+130301:	libsrc/src/dctool/attrothr.cc: correct spurious dciodvfy error for pixel data size when very large but compressed (000430)
+
+130226:	appsrc/dcfile/dciodvfy.cc: Account for rotation and flip when checking displayed area selection TLHC and BRHC (000429)
+
+130223:	appsrc/dcfile/pnmtodc.cc,pbmtoovl.cc: Undo handle extra white space before raw data in PNM files ... fails if pixel data starts with white space values ... go back to previous expectation that only one NL and nothing else is allowed after maxval (000424)
+
+130220:	appsrc/dcfile/dcsrdump.cc,libsrc/standard/condn.tpl,sopcl.tpl,iodcomp,module,strval/sr.tpl: Add SCOORD3D content item and Comprehensive 3D SR IOD (Sup 162)
+
+130212:	libsrc/standard/condn.tpl,sopcl.tpl,iodcomp/mr.tpl,pet.tpl,module/ct.tpl,mr.tpl,pet.tpl: Add private legacy MR and PET SOP Classes and IODs and update private CT IOD
+
+130210:	libsrc/standard/condn.tpl,module/base.tpl: Improve conditions on segmentation functional groups to check interaction between measures, position, orientation and derivation
+
+130210:	appsrc/dcfile/dciodvfy.cc,libsrc/standard/condn.tpl,iodcomp/vl.tpl,module/base.tpl,softcopy.tpl,vl.tpl,strval/softcopy.tpl,vl.tpl: Add Whole Slide Imaging IOD (Sup 145)
+
+130210:	libsrc/standard/condn.tpl,iodcomp/base.tpl,ct.tpl,mr.tpl,us.tpl,vl.tpl: Add ICC Profile module (CP 1017) and Frame Extraction module (Sup 119) to those IODs where they were not already done
+
+130208:	appsrc/acrnema/andump.cc,libsrc/src/dctool/attrmxrd.cc,locale/mesgtext.tpl: work around defect in images from Sante deidentifier (?) that uses pair of null bytes for VR (seen with GE Suite ID) (sacrifices ability to read unrecognized transfer syntaxes that are implicit rather than explicit)
+
+130207:	libsrc/standard/elmdict/dicom3.tpl: Add Zero Velocity Pixel Value (CP 1236)
+
+130206:	libsrc/src/locale/mesgtext.tpl,appsrc/dcfile/dciodvfy.cc: Add generic check that same sequence does not occur in shared and per-frame functional groups
+
+130206:	libsrc/standard/condn.tpl,module/us.tpl,iodcomp/us.tpl,strval/base.tpl,us.tpl: Add Enhanced US Volume IOD for validator
+
+130203:	libsrc/standard/condn.tpl,module/base.tpl,ct.tpl,mr.tpl,pet.tpl,strval/nm.tpl: Add view code sequence and slice progression direction for cardiac views (CP 739)
+
+130203:	libsrc/standard/module/dx.tpl: Add CP 1104 with Compression Force for tomo, and Paddle Description for MG and tomo
+
+130203:	libsrc/standard/elmdict/other.tpl: add observed private IMS data element
+
+130130:	appsrc/dcfile/dciodvfy.cc: Check SNOMED and DICOM code values do not contain illegal characters for those coding schemes
+
+130130:	libsrc/standard/elmdict/other.tpl: Add Volpara breast density private attributes
+
+130123:	appsrc/dcfile/dcsrdump.cc: Show target of relationship by reference (value of Referenced Content Item Identifier)
+
+130123:	config/Configure: On Mac, build only intel binaries; support for building PPC Universal binaries no longer present in recent MacOS XCode releases
+
+130108:	appsrc/dcfile/dctopnm.cc,dctopgx.cc: Ignore Photometric Interpretation for single channel images to allow PALETTE COLOR to be treated as PGM or PGX (000427)
+
+130108:	appsrc/dcfile/dccreate.cc: Add utility to create a de novo dataset using command line options (dccp without the input file)
+
+121227:	libsrc/src/dctool/attr.cc,attrmxrd.cc: Fix copying of datasets with GE Private Thumbnail Sequence containing fixed length compressed PixelData (000426) 
+
+121226:	libsrc/standard/binval.tpl,condn.tpl,sopcl.tpl,iodcomp,module,strval/softcopy.tpl: Add structured display IOD and modules
+
+121224:	appsrc/dcfile/pnmtodc.cc,pbmtoovl.cc: handle extra white space before raw data in PNM files (000424)
+
+121114:	appsrc/acrnema/andump.cc,libsrc/src/dctool/attrmxrd.cc,locale/mesgtext.tpl,standard/elmdict/other.tpl: work around defect in compressed images from CDN PACS that use "--" for "UN" VR in parsers, and add some observed private data elements
+
+121105:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Update data element dictionary and SOP classes for Nov 2012 WG 6 FT, including optical surface scanners (Sup 154)
+
+120911:	libsrc/standard/condn.tpl,sopcl.tpl,iodcomp,module,strval/base.tpl: Add IVOCT IOD per Sup 151 (thanks to Zachary Swanson at St Jude Medical for adding this)
+
+120911:	libsrc/src/dctool/attrvrfy.cc: Insert missing space between components of verify error messages
+
+120910:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl: Tidy up some inconsistencies with PS 3.6 naming and retired status of data elements
+
+120910:	libsrc/standard/elmdict/other.tpl: Add encountered UltraVisual private tags with VRs guessed on observed values that arrived as UN
+
+120910:	libsrc/standard/elmdict/dicom3.tpl: Correct swapped row and column offset in pixel data tags for whole slide imaging (incorrectly incorporated Sup 145)
+
+120830:	libsrc/standard/elmdict/dicom3.tpl,module/rt.tpl: Add CPs 1137, 1138 and 1204
+
+120822:	libsrc/standard/elmdict/elscint.tpl: more Elscint private elements with encountered explicit VRs
+
+120820:	libsrc/standard/condn.tpl,module/base.tpl,ct.tpl,dx.tpl,vl.tpl: report if window width negative (000422)
+
+120810:	libsrc/src/dctool/attrvrfy.cc,standard/condn.tpl,sopcl.tpl,elmdict/other.tpl,iodcomp,module/ct.tpl:	add experimental (private SOP Class) legeacy conversion validation support (Sup 157 draft 05)
+
+120810:	libsrc/standard/condn.tpl,iodcomp.module/base.tpl: add frame of reference, synchronization and MF functional groups and dimensions to MF SC (CP 600)
+
+120810:	libsrc/standard/condn.tpl,module/base.tpl: add RescaleType to CT Image Module (CP 888)
+
+120808:	appsrc/dcfile/dctable.cc: correct handling of multiple values and delimiter when using noembeddedquotes option (000421), add -decimal as synonym for -noembeddedquotes
+
+120705: libsrc/standard/sopcl.tpl,elmdict/dicos.tpl: Add DICOS v02 elements and SOP Class UIDs
+
+120703: libsrc/standard/elmdict/other.tpl: Add PMOD private elements and fix typo in first line
+
+120614: libsrc/standard/elmdict/other.tpl: add MetaEmotion Ginjo CADx private elements per conformance statement and experiments
+
+120611:	libsrc/standard/module/base.tpl,condn.tpl: check multi-frame dimension indices and in-stack position start from 1 not 0
+
+120608:	libsrc/standard/module,strval/base.tpl,condn.tpl: update multi-frame dimensions as per Sup 43
+
+120506: libsrc/standard/elmdict/other.tpl,philips.tpl: various private element additions and updates
+
+120505: libsrc/standard/elmdict/elscint.tpl,gems.tpl,other.tpl,philips.tpl,siemens.tpl: various private element additions and updates
+
+120505: libsrc/standard/elmdict/hitachi.tpl: add observed Hitachi MR private elements (guessed VRs)
+
+120505: libsrc/standard/elmdict/other.tpl: update and add Agfa private elements
+
+120504: libsrc/standard/elmdict/other.tpl: add observed DZDICOM private elements (guessed VRs)
+
+120504: libsrc/include/dctool/attrmxls.h,elmdict.h,src/dctool/attrmxrd.cc,elmdict.cc,standard/elmdict/other.tpl: inherit private owner for nested sequences (non-standard, but helps with Konica CR) (000420); add observed Konica CR private elements
+
+120502:	libsrc/standard/elmdict/siemens.tpl: update and add private data elements
+
+120422:	appsrc/acrnema,dcfile/Imakefile,support/testapp: use both baseappname and role in persistent test output file names to permit use of cp role for multiple base apps and persist explicit outfile without having to add to testapp script every time
+
+120422:	appsrc/dcfile/dcunrgb.script: add even padding byte when number of pixels is odd (000417)
+
+120417:	appsrc/dcfile/dcsrdump.cc: Add dump of float and rational representation in numeric SR content items (CP 1064)
+
+120415:	libsrc/standard/condn.tpl,module/acqctx.tpl,base.tpl,sr.tpl: Add float and rational representation in numeric SR content items (CP 1064)
+
+120415:	libsrc/standard/condn.tpl,module,strval/xaxrf.tpl: update PositionerMotion requirements as per CP 1015, and change NeedModuleMultiFrame (affects XA/XRF and RT) to include FrameIncrementPointer and not require NumberOfFrames to be 1
+
+120413:	appsrc/dcfile/dctopnm.cc,dctoraw.cc: do not copy even padding byte when number of pixels is odd (000417)
+
+120411:	appsrc/dcfile/dctpnm.cc, dcunrgb.script: report specific error when given color-by-plane input (000416)
+
+120408:	libsrc/standard/elmdict/diconde.tpl: Correct VR of (0014,3022) Sensor Name from DS to ST per ASTM E2699-11
+
+120402:	appsrc/dcfile/dcarith.cc: add invert grayscale option (000415)
+
+120401:	libsrc/standard/elmdict/other.tpl: add more encountered Segami NM privata data elements
+
+120328:	appsrc/dcfile/dctable.cc: make recurse option actually recurse, not stop one level deep (000148)
+
+120327:	libsrc/standard/elmdict/dicom3.tpl: add elements for CP 1123 and 1188
+
+120327:	libsrc/standard/elmdict/other.tpl: add PMP private elements to support legacy multi-frame conversion supplement experiments
+
+120327:	libsrc/standard/elmdict/other.tpl: add Hologic mammo tomo private elements
+
+120327:	libsrc/standard/elmdict/dicos.tpl: correct case in ThreatDetectionAlgorithmAndVersion
+
+120311:	libsrc/standard/elmdict/siemens.tpl: more encountered Siemens private data elements
+
+120309:	libsrc/standard/elmdict/other.tpl: add IMS Raffaello private elements for mammo biopsy and tomo
+
+120305:	Configure: add support for kFreeBSD and GNU Hurd as if they were Linux (per Mathieu Malaterre's suggestion)
+
+120305:	Imakefile: add missing cygwin DLLs required for windows executables, and include empty .local files to signal loader to use DLLs in same directory rather than pre-installed ones
+
+120301:	libsrc/standard/strval/base.tpl,sr.tpl: add encountered private Siemens 99SMS_CTMR coding scheme and mapping resource
+
+120301:	appsrc/dcfile/dcmulti.cc: do not fail if ImageType value 4 not present in non-MR source images (000414)
+
+120229: libsrc/standard/condn.tpl: correct RT dose condition for inclusion of multi-frame module (000413)
+
+120226:	config/Configure,Imake.tmpl,appsrc/*/*.cc,libsrc/include/dconvert,generic/*.h,src/dcdisp,dctool,generic,locale,ourdisp/*.cc,dconvert/*/*.cc,support/mktime.cc: add support for compilation under later g++ versions (>=4.3) with no ".h" includes (000311), as well as recent Xorg X11 Linux configurations
+
+120224:	appsrc/dcfile/dcdirmk.cc: tolerate missing ConceptNameCodeSequence (000412)
+
+120224:	libsrc/include/dctool/ie.h,standard/condn.tpl,sopcl.tpl,iodcomp/base.tpl,module/base.tpl,file.tpl,strval/base.tpl,file.tpl,appsrc/dcfile/dcdirmk.cc: add surface segmentation IOD (Sup 132) and directory record (CP 979) per PS 3.3 2011
+
+120224:	libsrc/standard/module/sr.tpl: check for ConceptNameCodeSequence in root content item (000411)
+
+120218:	libsrc/standard/strval/base.tpl: correct string value of Certificate Type
+
+120203:	appsrc/dcfile/dccp.cc: add fixbaddecimalseparator option to change "," to "." in DS values
+
+120117: libsrc/standard/condn.tpl,module/xaxrf.tpl,strval/xaxrf.tpl: correct enhanced XA/XRF image/frame type and PlanesInAcquisition, defined terms and SourceImageSequence
+
+120117:	libsrc/standard/condn.tpl: correct XRayReceptorType to be within local dataset to work with field of view origin condition in tomo
+
+120114:	libsrc/standard/elmdict/gems.tpl: add GE interventional marker private data elements from conformance statement
+
+120114:	libsrc/standard/elmdict/gems.tpl: change mammo private data element ClinicalView VR based on newer conformance statement and encountered VR
+
+120114:	libsrc/standard/elmdict/siemens.tpl: update ultrasound private data elements with encountered VR
+
+120114:	libsrc/standard/elmdict/gems.tpl: add more mammo private data elements from conformance statement
+
+120114:	libsrc/standard/elmdict/siemens.tpl: add PET private data elements from conformance statement
+
+120114:	libsrc/standard/elmdict/siemens.tpl: add ultrasound private data elements from encountered VR
+
+120114:	libsrc/standard/elmdict/other.tpl: add Hitachi OASIS MR private data elements from conformance statement and encountered VR
+
+120112:	libsrc/standard/elmdict/philips.tpl,siemens.tpl: add more Siemens and Philips private NM-related data elements with encountered VR or from conformance statement
+
+120112:	libsrc/standard/elmdict/other.tpl: add dcm4chee private data elements
+
+120109:	libsrc/standard/elmdict/gems.tpl,other.tpl,papyrus.tpl,siemens.tpl,toshiba.tpl: fix typos related to missing quotes etc. in element dictionary found by Mathieu
+
+120108:	libsrc/standard/elmdict/acuson.tpl,siemens.tpl: more add explicit vr siemens private ultrasound elements encountered
+
+120106:	libsrc/standard/elmdict/philips.tpl,strval/base.tpl: add explicit vr philips private ultrasound elements encountered and private philips SR coding scheme
+
+111219:	libsrc/src/dctool/attrmxrd.cc: check for HighBit being more than one less than BitsStored and correct BitsStored accordingly (otherwise will create zero pixel values on copy) (000408)
+
+111213:	appsrc/dcfile/dcuncat.cc: add option to replace instance number starting with a specific number to allow scripts to extend a series with successive invocations
+
+111212:	libsrc/standard/condn.tpl/module,strval/base.tpl,dx.tpl: improve animal versus human conditions to check SRT homo sapiens, and make view position and body part examined human versus animal specific
+
+111212:	libsrc/standard/elmdict/other.tpl: add more Sound private elements
+
+111117:	libsrc/standard/strval/base.tpl: add CSD for 99NCIAIM
+
+111109:	appsrc/dcfile/dcuncat.cc: add options to replace instance number, frame increment pointer and frame increment pointer vectors, as well as add number of frames during unenhance based on SOP class
+
+111106:	libsrc/standard/elmdict/other.tpl: add Vepro private elements
+
+111031:	libsrc/standard/elmdict/other.tpl: add CTP private elements
+
+111030:	libsrc/standard/elmdict/other.tpl: add Segami private elements
+
+111029:	libsrc/standard/elmdict/dicom3.tpl: add (restore from trial) Observation UID (per CP 1147)
+
+111028:	libsrc/standard/elmdict/other.tpl: add NeuroQuant private elements
+
+111024:	libsrc/standard/elmdict/other.tpl: update fuji private attributes with descriptions
+
+110918:	libsrc/standard/elmdict/diconde.tpl: update with new or modified data elements with cleanup from Patrick
+
+110918:	libsrc/standard/elmdict/siemens.tpl: update some private elements based on Artis conformance statement
+
+110916:	libsrc/standard/elmdict/gems.tpl: resolve inconsistencies in GE PET conformance statement VRs SS/SL/FL for private elements by choosing those most commonly seen in the field (still some inconsistencies between models)
+
+110904:	libsrc/standard/elmdict/camtron.tpl: add private data elements encountered in DICOMDIR, as well as QCA private data elements from GEMS/Camtronics CRS conformance statement
+
+110901:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: Sup 152 FT ophthalmic thickness map (dictionary and SOP class only; not IOD yet)
+
+110822:	libsrc/standard/elmdict/dicom3.tpl: update data dictionary (only) for CPs for FT Aug 2011 WG 6 meeting
+
+110714:	libsrc/standard/elmdict/dicom3.tpl: remove 'unified' from names of various attributes (per Sup 96 FT)
+
+110716:	libsrc/standard/strval/base.tpl: add 99PMP CSD
+
+110714:	libsrc/standard/elmdict/dicom3.tpl: exposure index etc are DS not FD (CP 1024)
+
+110709:	libsrc/standard/elmdict/dicom3.tpl: change (0018,9430) from US to FL per Sup 139
+
+110612:	libsrc/standard/elmdict/diconde.tpl: update for DICONDE eddy current standard
+
+110612:	libsrc/standard/elmdict/dicondep.tpl: correct case of DICONDE DX (Dx) private owner for E2699
+
+110609:	libsrc/standard/elmdict/dicom3.tpl: add Sup 151 FT data elements
+
+110608:	libsrc/standard/elmdict/elscint.tpl: update Elscint private elements
+
+110531:	libsrc/standard/elmdict/other.tpl: update Hitachi CT private elements
+
+110531:	libsrc/standard/elmdict/siemens.tpl: update mammo private elements
+
+110529:	libsrc/standard/condn.tpl,iodcomp/dx.tpl,module/base.tpl,dx.tpl,xaxrf.tpl,strval/dx.tpl,xaxrf.tpl: add breast tomosynthesis IOD, refactoring 3D XRay accordingly
+
+110529:	libsrc/standard/elmdict/other.tpl: more private data elements for Hologic 
+
+110528:	appsrc/dcfile/dciodvfy.cc: do not complain about SCOORD without child IMAGE when SELECTED FROM is by reference (000406)
+
+110527:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: check that references to instances in content tree are in top level evidence sequences in SR (000405)
+
+110526:	libsrc/standard/elmdict/gems.tpl: add names for CT iterative reconstruction private data elements
+
+110522:	libsrc/src/dctool/attrothr.cc: do not throw assertion if computed length is equal (which may occur for single bit images)
+
+110522:	libsrc/standard/iodcomp/base.tpl,libsrc/standard/condn.tpl: permit FoR Module in Segementation (and do CP to standard to allow may be present otherwise)
+
+110522:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: detect SCOORD without child IMAGE (000403)
+
+110522:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: detect quotes in code meaning of measurement units (000404)
+
+110522:	libsrc/src/dctool/attrtypv.cc,locale/mesgtext.tpl: permit PN with multiple carets in multiple component groups (000402)
+
+110521:	libsrc/standard/elmdict/acuson.tpl,agfa.tpl,isg.tpl,other.tpl,siemens.tpl,strval/base.tpl: more private elements and coding scheme designators
+
+110517:	libsrc/standard/module/base.tpl: correct type (1->2) and number of items (1->0-n) in SourceImageSequence in DerivationImageMacro
+
+110517:	libsrc/standard/elmdict/siemens.tpl: yet more syngo private elements
+
+110516:	libsrc/standard/cond.tpl: no longer require version for UCUM codes (CP 1060)
+
+110516:	libsrc/standard/strval/base.tpl: add 99_MI private coding scheme designator
+
+110516:	libsrc/include/dctool/attr.h,attrseq.h,generic/listsimp.h,src/dctool/attrseq.cc,attrvrfy.cc,standard/condn.tpl,module/softcopy.tpl,sr.tpl,support/module.awk:
+		though VM for sequences number of items was being specified in modules, it was not being applied;
+		apply it (000256), as well as make it work (since number of items was not being computed correctly
+		in SequenceAttribute::verifyVM()); also add support for conditional check of VM, for example for
+		GraphicData depending on Grahic Type (000401)
+
+110516:	libsrc/standard/elmdict/toshiba.tpl: update CT private elements from conformance statement for V4.70 or later version
+
+110514:	libsrc/standard/elmdict/siemens.tpl: add more syngo private elements, and update guessed VRs of existing ones with observed explicit VRs
+
+110511:	libsrc/standard/elmdict/gems.tpl,toshiba.tpl: add more encountered explicit VR private elements
+
+110511:	libsrc/standard/elmdict/other.tpl: update/add McKesson private elements from conformance statement
+
+110511:	libsrc/standard/transyn.tpl: recognize ALI Wavelet private transfer syntax (though cannot decompress it)
+
+110510:	appsrc/misc/jpegdump.cc: add JPEG 2000 COD marker segment dump in order to detect whether trabsform is reversible or irreversible
+
+110506:	libsrc/include/dctool/attrmxls.h,src/dctool/attrmxrd.cc,locale/mesgtext.tpl: allow fixed length pixel data within sequence in encapsulated transfer syntaxes (000400)
+
+110504:	libsrc/support/elmtojava_TagFromName.awk,elmtojava_DicomDictionary_CreateTagByName.awk: include aliases for old keywords (pre CP 850) in generated Java dictionary
+
+110501:	appsrc/dcfile/dcdirdmp.cc,libsrc/src/dctool/dicomdir.cc: add option to control inclusion of descriptions, and include SeriesDescription in series level record display (000399)
+
+110430:	libsrc/standard/elmdict/diconde.tpl,dicondep.tpl: add DICONDE standard and private elements
+
+110423:	libsrc/standard/elmdict/siemens.tpl: add more private elements
+
+110422:	libsrc/standard/elmdict/gems.tpl.other.tpl: add more private elements
+
+110406:	libsrc/standard/transyn.tpl,sopcl.tpl,elmdict/dicom3.tpl,module/vl.tpl: update data elements, sop classes and transfer syntaxes after WG 6 2011/04
+
+110222:	appsrc/dcfile/dcsrdiff.script: change "==" to "=" operator, since former doesn't work in Solaris Bourne shell
+
+110207:	appsrc/dconvert/ge9800/Imakefile: remove commented out references to non-existent ge98unid script (else causes problems with Solaris imake/make at install)
+
+110207:	libsrc/include/pixeldat/srcsink.h: fix incorrect zero constant assigned as const char padding (clean up warning)
+
+110207:	libsrc/include/dctool/attrval.h,libsrc/src/dctool/strval.cc,appsrc/acrnema/ancp.cc,ancreate.cc: start cleanup of assignment of "const char*" to "char*" (g++ 4.2 warning)
+
+110128:	libsrc/standard/elmdict/dicom3.tpl: add sup 96 FT data elements
+
+110128:	libsrc/standard/elmdict/dicom3.tpl: correct data element tag for ImplantTemplateGroupName (sup131_ft3)
+
+110127:	libsrc/standard/sopcl.tpl: correct plurality of spectacle report(s) storage
+
+110124:	libsrc/standard/elmdict/dicom3.tpl: add data elements to dictionary for CP 1037 and 1080
+
+110119:	libsrc/standard/module,strval/base.tpl,elmdict/dicom3.tpl: Add Sup 142 data elements to dictionary and IODs
+
+110116:	libsrc/standard/elmdict/other.tpl: change VR of Sound Elkin private tag (f001,0006) as requested by vendor
+
+110113:	appsrc/dcfile/dcunrgb.script: add script to convert 8 bit RGB to MONOCHROME2
+
+101204:	appsrc/dcfile/dctopgm8.cc: correct problem windowing MONOCHROME1 images (000398)
+
+101204:	appsrc/dcfile/dctopgm8.cc,.man: add command line options to select and override VOI LUTs,
+		override any VOI LUT if window values explicitly specified on command line, use center
+		instead of level throughout but allow level as synonym on command line, and populate man page (000397)
+
+101117:	libsrc/standard/elmdict/elscint.tpl: more private tags encountered
+
+101117:	libsrc/standard/iodcomp,module/sr.tpl: add IHE REM profile variant of RDSR to check of additinal required attributes; also fix KOS RequestAttributesSequence, which was not current
+
+101116:	appsrc/dcfile/dcsrdiff.script: make use of -identifier an option rather than the only choice
+
+101115:	libsrc/standard/elmdict/other.tpl: add emageon private attributes
+
+101115:	appsrc/dcfile/dcunjpeg.script: extend to support multi-component 8 bit J2K files
+
+101110:	libsrc/standard/elmdict/dicom3.tpl: add CP 1036 data element (not IOD yet)
+
+101106:	appsrc/dcfile/dcsrdiff.script: add script to compare dumps of SR files
+
+101101:	libsrc/standard/elmdict/dicom3.tpl: add Sup 131 and 134 and RT UPS data elements (not IOD yet)
+
+101031:	appsrc/dcfile/dcj2k.script: do not add disclaimer or additional dicom attributes
+
+101031:	appsrc/dcfile/dcj2k.script: add lossy image compression parameters when not reversible (000360)
+
+101030:	libsrc/standard/elmdict/other.tpl: add Terarecon private elements
+
+101026:	appsrc/dcfile/dcckovly.script: check for Agfa/Mitra private annotation data elements
+
+101026:	libsrc/standard/elmdict/other.tpl: add Etiam DICOMDIR private element
+
+101026:	libsrc/standard/elmdict/toshiba.tpl: Add private data elements encountered in RSNA 2010 dose demo Toshiba samples
+
+101014:	libsrc/standard/condn.tpl,module/base.tpl: detect illegal TBD code values and meaning, and supress laterality errors in segmentation objects
+
+101014:	libsrc/standard/elmdict/elscint.tpl: add Philips dose phantom type private element
+
+100910:	libsrc/include/generic/basetype.h,src/dctool/attrothr.cc: allow dcuncat to handle large files by using unsigned long long intermediate precision in number of bytes calculation (000396)
+
+100908:	libsrc/standard/sopcl,tpl,elmdict/dicom3.tpl: add SOP Classes and data elements (not IOD yet) for Sup 144 and 146
+
+100824:	libsrc/standard/sopcl,tpl,elmdict/dicom3.tpl: add SOP Class and data elements (not IOD yet) for Sup 145 whole slide imaging
+
+100815:	appsrc/dcfile/dcsrdump.cc: show FL SCOORDs with greater precision in dump (000395)
+
+100803:	appsrc/dcfiler/dcanon.script: use ls rather than find when doing hierarchical move to avoid removing stuff already done (000394)
+
+100801:	libsrc/standard/Imakefile,sopcl.tpl,elmdict/dicos.tpl,Imakefile: Add DICOS data elements to dictionary (only) as per post-LB draft prior to final text
+
+100707:	libsrc/standard/elmdict/other.tpl: add some private tags encountered in Intelerad presentation states related to annotations
+
+100608:	appsrc/dcfile/dcckovly.script: add detection of energy (or not) in OverlayData element
+
+100530:	libsrc/standard/elmdict/elscint.tpl: add keyword and description for private DLP attribute as observed in samples of dose info screens
+
+100518:	appsrc/dcfile/dcacqmap.script: add ability to split by ImageOrientationPatient to handle multiple angulations in same series (000393)
+
+100409:	libsrc/include/pixeldat/srcsink.h: handle needed extra byte for odd rows*columns single byte copy that affects pnmtodc and rawtodc (000136),(000185)
+
+100405:	libsrc/standard/elmdict/agfa.tpl: add/change some private agfa *(mitra) annotation data elements
+
+100402:	appsrc/dconvert,libsrc/src/dconvert/ge9800: port old dicom3tools GE CT9800 convertor to new toolkit
+
+100415:	appsrc/dcfile/dciodvfy.cc: handle incorrect zero value for number of frames when computing pixel data length (000393)
+
+100325:	libsrc/standard/elmdict/dicom3.tpl: add Sup 120 extended presentation state data elements
+
+100323:	libsrc/standard/elmdict/*.tpl: add more private elements from IHE 2010 NA connectathon samples from explicit VR or conformance statements available
+
+100323:	appsrc/dcfile/dctable.cc: add option to remove quotes in tabulated values (000392)
+
+100319:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: check presentation state displayed area selection sequence coordinate consistency (000391)
+
+100310:	appsrc/dcintro/dcintro.man,optout.so,libsrc/include/dctool/attrmxls.h,dcopt.h,libsrc/src/dctool/attrmxls.cc,dcoptc.cc,dcopto.cc: add disambiguateseriesbydescription option (000390)
+
+100214:	libsrc/standard/elmdict/other.tpl: add DR Systems private tags
+
+100211:	*.man: updated copyright notice to include 2010 and DBA PixelMed to match COPYRIGHT file
+
+100211:	appsrc/dcfile/dcdirdmp.cc,.man: add -filename option for use in scripts to be consistent with other dump tools (000201)
+
+100206:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl,module,strval/mr.tpl: Add Arterial Spin Labeling attributes for Enhanced MR Images per CP 981 FT2
+
+100206:	libsrc/standard/condn.tpl,module,strval/mr.tpl: Changes to diffusion defined terms and sequence conditions per CP 984
+
+100206:	appsrdc/dcfile/dcmulti.cc,libsrc/standard/condn.tpl,module/mr.tpl: Add separate, multiple, velocity encoding directions for reconstruction versus acquisition in Enhanced MR per CP 998
+
+100206:	libsrc/standard/iod,module/vl.tpl: Add Angle of View and Acquisition Context Module to Ophthalmic Photography IODs per CP 999
+
+100206:	libsrc/standard/module/base.tpl: add Patient Size Code Sequence to Patient Study Module per CP 650
+
+100204:	libsrc/standard/elmdict/dicom3.tpl,support/elmdict.awk: per CP 950, LUT Data is never SS
+
+100204:	libsrc/standard/iod/vl.tpl: ophthalmic photography images should not complain when number of frames more than one (000389)
+
+100131:	appsrc/dcfile/dcmulti.cc: do not add empty FrameVOILUTSequence when no window or minimal attributes, since changed from Type 2 to Type 1 by Sup 83, but is U macro in CT and MR
+
+100131:	appsrc/dcfile/dcanon.script,dcdirmk.cc,dcmkpres.cc,dcmulti.cc,libsrc/src/dconvert/gaw/gaw.tpl,gen/gen.tpl,himr/himr.tpl,imtn/imtn.tpl,pace/pace.tpl,pace/pacemmsc.cc,pq/pqmmsc.cc,signa/signa.tpl,somp/somp.tpl,
+		dctool/attrmxvr.cc,dicomdir.cc,standard/condn.tpl,elmdict/dicom3.tpl,module/*.tpl,strval/softcopy.tpl,support/elmtojava_DicomDictionary_CreateIEByTag.awk:
+		update keywords, descriptions and VRs to match CP850 modified 2009 edition of standard
+
+100131:	appsrc/dcfile/dcuncat.cc: add SOPInstanceUIDOfConcatenationSource per CP 809
+
+100127:	libsrc/standard/elmdict/dicom3.tpl: add elements to dictionary from Jan 2010 WG 6 FT CPs and Sups
+
+100119:	libsrc/standard/condn.tpl,module.vl.tpl: handle derived versus no-derived ImageType value 3 defined terms (000388)
+
+100119:	libsrc/standard/condn.tpl,module.vl.tpl: nest mydriatic stuff within sequence as per Sup 110 (Ophthalmic Tomography) which also affects all OP image IODs (000387)
+
+100103:	libsrc/standard/sopcl.tpl: add colon CAD and macular grid thickness SOP Classes
+
+100101:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl,iodcomp/*.tpl,module/mr.tpl,specimen.tpl,xaxrf.tpl,strval/base.tpl,mr.tpl: add Sup 122 specimen module and retire specimen identification, add Sup 141 enhanced color MR image, add device module to all IODs per CP 613
+
+091230:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl,iodcomp/*.tpl,module/base.tpl: add module and data elements for Sup 119
+
+091230:	libsrc/support/elmdict.awk: handle parsing of dictionary VM of 2-2n etc. from template as VMUNLIMITED (000386)
+
+091229:	libsrc/support/iodcomp.awk,module.awk,appsrc/dcfile/dciodvfy.cc: add verbose success status, correct sense of success when macro invoked to restore correct dciodvfy return status (000385)
+
+091228:	appsrc/dcfile/dcanon.script: remove RequestedProcedureID during de-identification (000384)
+
+091228:	appsrc/dcfile/dciodvfy.cc: should not report missing composite model attribute values for DICOMDIR when not a composite IOD, e.g., for hanging protocol and color palette storage (000383)
+
+091228:	libsrc/include/dctool/ie.h,standard/condn.tpl,sopcl.tpl,iodcomp/softcopy.tpl,module/base.tpl,softcopy.tpl; Add color palette IOD per Sup 133 FT2
+
+091228:	libsrc/standard/module/rt.tpl: add AccessoryCode to patient setup per CP 939
+
+091228:	libsrc/src/dctool/condn.cc,support/condn.awk,standard/condn.tpl,module/rt.tpl,strval/rt.tpl: add mechanism to check number of items in conditions and use it to support MULTI_PLAN DoseSummationType as per CP 938
+
+091228:	libsrc/standard/module/rt.tpl: add General Accessory in RT Image per CP 937
+
+091228:	libsrc/standard/condn.tpl: include enhanced color MR SOP Class in patient position condition per CP 920 (which is otherwise already implemented)
+
+091228:	appsrc/dcfile/dciodvfy.cc,libsrc/standard/elmdict/dicom3.tpl,module/base.tpl,strval/base.tpl: add quadruped orientation per CP 919
+
+091228:	libsrc/standard/condn.tpl,module/rt.tpl,strval/rt.tpl: add FluenceMode stuff from CP 805 and CP 916
+
+091227:	libsrc/standard/condn.tpl,module/dx.tpl: make PatientOrientation for DX conditional upon view not being specimen CP 911
+
+091227:	libsrc/standard/module/base.tpl: allow PatientOrientation to be present if condition unsatisfied per CP 894
+
+091224:	appsrc/dcfile/dcanon.script: allow selective removal of descriptions at patient, study, seriese (PPS) and image levels (000382)
+
+091224:	appsrc/dcfile/dcanon.script: always remove Original and Modified Attributes Sequence (000381)
+
+091222:	appsrc/dcfile/dcsort.cc: add a tolerance factor when comparing slice intervals and make it a command line option (000380)
+
+091222:	appsrc/dcfile/dciodvfy.cc,libsrc/include/dctool/ie.h,iodcomp.h,src/locale/mesgtext.tpl,standard/iodcomp/base.tpl,module/base.tpl,support/iodcomp.awk: 
+		restore the retired standalone curve, overlay and LUT IODs and related modules and flag these IODs as retired in the dciodvfy report (000374)
+
+091222:	appsrc/dcfile/dcentvfy.cc: remove unnecessary check for recognized composite IOD (000378)
+
+091221:	libsrc/standard/elmdict/siemens.tpl: add some ultrasound private attributes (as encountered and per ACUSON S2000 R1.5 conformance statement, guessing at some VRs)
+
+091220:	libsrc/standard/module,strval/dx.tpl: add stereotactic image type for mammo per CP 889
+
+091219:	libsrc/standard/module/rt.tpl: Move OperatorName to series level in RT per CP 829
+
+091219:	libsrc/standard/strval/base.tpl: Add more responsible person role defined terms per CP 826
+
+091219:	libsrc/standard/condn.tpl,module/softcopy.tpl: Tidy up PS bounding box and anchor point conditions per CP 821
+
+091219:	libsrc/standard/module/xaxrf.tpl: Add enhanced XA/XRF FrameType per CP 819
+
+091219:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl: Add SOPInstanceUIDOfConcatenationSource per CP 809
+
+091216:	libsrc/standard/module/base.tpl,strval/base.tpl: do not report error for RGB in RLE (000377)
+
+091216:	libsrc/standard/condn.tpl,module/base.tpl,strval/base.tpl: detect inconsistent MONOCHROME1 Photometric Interpretation and Presentation LUT Shape not INVERSE (000376)
+
+091216:	libsrc/standard/elmdict/agfa.tpl: add some more private tag VRs encountered
+
+091121:	libsrc/support/strval.awk,strval/charset.tpl,dx.tpl,vl.tpl: support comments and explicit empty values in string value templates (silences warnings and errors when parsing template)
+
+091121:	libsrc/standard/condn.tpl,module/pet.tpl,strval/pet.tpl: add missing Randoms Correction Method condition and correct defined terms for enhanced PET
+
+091121:	libsrc/standard/condn.tpl,module/sr.tpl,strval/sr.tpl: CP 931 Verification, completion, preliminary, final and amended SR status
+
+091121:	libsrc/standard/condn.tpl,module/base.tpl,strval/base.tpl: CP 942 Consent for distribution and ethics committee approval
+
+091121:	libsrc/standard/condn.tpl,module/base.tpl,strval/base.tpl: CP 953 extend Content Item Macro to include IMAGE and COMPOSITE
+
+091117:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl,module/base.tpl,ct.tpl,rt.tpl,sr.tpl,vl.tpl,xaxrf.tpl,strval/base.tpl,ct.tpl: incorporate Oct 2009 CP FT
+
+091114:	appsrc/dcfile/dcpost.cc: correct segmentation fault (000375)
+
+091113:	Imakefile: add dcdirdmp to executable packages
+
+091029:	libsrc/standard/sopcl.tpl,/elmdict/dicom3.tpl: add new data elements and SOP class from Oct 2009 WG6
+
+090917:	appsrc/dcfile/dcsrdump.cc: display presentation state UIDs etc. in image reference (000372)
+
+090831:	libsrc/standard/elmdict/dicom3.tpl: add new data elements from CPs, change case of some tags
+
+090831:	appsrc/dcfile/dcmvhier.*.script: Make dcmvhier scripts more robust against read errors during dckey (000371)
+
+090809:	libsrc/standard/sopcl.tpl, elmdict/dicom3.tpl,module/dx.tpl: rename ImplantPresent to BreastImplantPresent and add breast tomo UID (Sup 125)
+
+090718:	appsrc/dcfile/dcsrdump.cc: add -showidentifier option to dump identifier of content items (000370)
+
+090718:	appsrc/dcfile/dcunjpeg.script: remove data elements after pixel data like DataSetTrailingPadding and DigitalSignaturesSequence prior to adding decompressed pixel data (000368)
+
+090716:	Imakefile: add dcsort to win and mac binary distributions (000367)
+
+090716:	appsrc/dcfile/dcsort: show interval between each slice when also showing sort key value (000366)
+
+090709:	libsrc/src/dctool/attrmxrd.cc: if Overlay Data VR is OX use OW not OB, so as to handle Overlay Data correctly for implicit VR per PS 3.5 (as before changing from OW to OX); leave Curve Data as OB per PS 3.5 (000364)
+
+090709:	libsrc/include/dctool/attrtag.h,src/dctool/attrmxls.cc: correct erroneous warnings about unused repeating group elements during validation (000365)
+
+090709:	libsrc/standard/elmdict/dicom3.tpl: VR of Overlay Data can be OB, not just OW (000364)
+
+090520:	libsrc/stndard/elmdict/dicom3.tpl: change VM of (0040,0001) Scheduled AET Title to "1-m" to match part 6
+
+090514: libsrc/standard/condn.tpl,module/base.tpl: Do not complain about missing R-R Interval Nominal when Cardiac Synchronization Technique is NONE (000363)
+
+090514: libsrc/standard/condn.tpl,module/base.tpl: Correct condition on color palettes for monochrome Photometric Interpretaion but Pixel Presentation of COLOR or MIXED (enhanced with supplemental palette color) (000362)
+
+090514:	libsrc/standard/strval/base.tpl: add PixelMed Publishing NEMA MRMF private coding scheme
+
+090514:	libsrc/include/dctool/module.h,src/dctool/condn.cc,support/iodcomp.awk,module.awk: correct absent method to verify conditions in rootlist passed through modules and macros (000361)
+
+090502:	libsrc/standard/condn.tpl: correct condition on PETTableDynamicsSequence (000359)
+
+090430:	libsrc/standard/module/base.tpl: allow coding scheme version even if condition unsatisfied, per CP 887
+
+090430:	libsrc/standard/elmdict/elscint.tpl,gems.tpl,other.tpl,philips.tpl,siemens.tpl,toshiba.tpl: Add private data elements encountered in IHE Connectathon 2009 NA
+
+090429:	appsrc/dcfile/dciodvfy.cc: Fix bus error if target of FrameIncrementPointer not an attribute in the list (000358)
+
+090429:	libsrc/standard/module/base.tpl: add CP 898 Operator information to Contributing Equipment Sequence
+
+090428: libsrc/standard/module/pet.tpl: add mbpo to Acquisition Datetime; allow MIXED in ImageType (Sup 117 Enhanced PET)
+
+090419:	appsrc/dcfile/dcjpeg.man: add note that only single frames are supported (000357)
+
+090419:	appsrc/dcfile/dcencap.cc: add ability to write compressed stream as single item, e.g., for MPEG (000356)
+
+090419:	libsrc/src/dctool/condn.cc,standard/condn.tpl,module/base.tpl: add check for conditions on MPEG2 MP at HL, and check conditions on MP at HL regardless of IOD (since specific to Transfer Suntax, not IOD) (000355)
+
+090415: libsrc/standard/condn.tpl,elmdict/dicom3.tpl,iodcomp/pet.tpl,module/base.tpl,pet.tpl,strval/base.tpl,ct.tpl,mr.tpl,pet.tpl: add Sup 117 Enhanced PET IOD
+
+090415:	libsrc/include/dctool/attrtyps.h,src/dctool/attrtyps.cc,attrtypv.cc: check for illergal trailing space in UI, DA, AS VRs (000353),(000354)
+
+090414:	libsrc/standard/elmdict/dicom3.tpl: fix VL of (0018,9510)
+
+090412:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: add sup 43 Volume US data elements and UIDs
+
+090408:	libsrc/standard/sopcl.tpl: add sup 141 Enhanced MR Color sop class UID
+
+090408:	libsrc/standard/transyn.tpl: add sup 137 MPEG2 MP at HL transfer syntax to list of transfer syntaxes
+
+090408:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: add sup 133 Color Palette data elements and UIDs
+
+090408:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: add Sup 130 Ophthalmic Refractive Measurements Storage data elements and UIDs
+
+090408:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl,module/ct.tpl,mr.tpl: add Sup 123 structured display data elements and UIDs
+
+090408:	libsrc/standard/elmdict/dicom3.tpl: add Sup 122 ft2 revised pathology identification data elements
+
+090408:	libsrc/standard/sopcl.tpl,elmdict/dicom3.tpl: add Sup 117 ft2 enhanced PET data elements and UIDs
+
+090404:	libsrc/standard/strval/base.tpl: add 99PDL-rad coding scheme designator
+
+090403:	libsrc/standard/strval/base.tpl: add 99GEMS coding scheme designator
+
+090403:	libsrc/standard/elmdict/gems.tpl: add DEXA private elements from enCORETM 11.3 conformance statement
+
+090402:	libsrc/standard/strval/base.tpl,sr.tpl:	add 99RPH as mapping resource, and other 99RPH related coding scheme designators
+
+090318:	libsrc/standard/strval/base.tpl:	add 99RPH as private coding scheme
+
+090317:	libsrc/standard/elmdict/other.tpl:	add "private" data elements for WG 12 testing of US 3D
+
+090305: libsrc/standard/condn.tpl,module/base.tpl: do not complain about palette color LUT data
+	missing in Image Pixel Module when segmented LUT present in US image (000352)
+
+090303:	libsrc/standard/condn.tpl,module/base.tpl: do not report modality as required for SC objects (000349)
+
+090303:	libsrc/standard/condn.tpl,module/base.tpl,ct.tpl,mr.tpl,vl.tpl,xaxrf.tpl: report when lossy transfer syntax does not match lossy image compression method in dciodvfy (000348)
+
+090303:	libsrc/include/dctool/attrtyps.h,src/dctool/attrtyps.cc,attrtypv.cc,locale/mesgtext.tpl:
+	report null embedded or trailing byte in string in dciodvfy (000347)
+
+090226:	libsrc/standard/elmdict/dicom3.tpl: add Sup 132 Surface Segmentation data dictionary (with Surface Number of Points corrected)
+
+090209:	libsrc/src/dctool/transyn.cc,standard/transyn.tpl,elmdict/elscint.tpl: do not abort if meta header contains
+	unrecognized transfer syntax, instead assume EVRLE, also add specific transfer syntax for Algotec compression (000346)
+
+090209:	libsrc/standard/elmdict/other.tpl,philips.tpl: add some more private tags for Philips and Hermes NM
+
+090204:	libsrc/standard/module/base.tpl: do not report Referenced Performed Procedure Step Sequence as missing in Enhanced Series (000345)
+
+090204:	libsrc/standard/condn.tpl,module/xaxrf.tpl: correct XA 3D, including X-Ray 3D Frame Type Macro (000342b),
+	optional Pixel Value Transformation Sequence (000343) and FrameType value 4 enumerated value (000344)
+
+090204:	libsrc/standard/condn.tpl: Patient Orientation is not required for Segmentation if Plane Position Macro used (000342a)
+
+090204:	libsrc/standard/condn.tpl,iodcomp/base.tpl,module/base.tpl: make Referenced Series Sequence in
+	Common Instance Reference Module conditional on there being references (per CP 926 LB), and make
+	module inclusion in Segmentation IOD conditional on Derivation Image functional group being present (000341)
+
+090201:	libsrc/standard/condn.tpl,sopcl.tpl,iodcomp/base.tpl,module/base.tpl,strval/base.tpl: add support for validating segmentation IOD (000208)
+
+090126:	appsrc/dcfile/dcacqmap.script: add TemporalPositionIdentifier as acquisition parameter (000340)
+
+090123:	appsrc/dcfile/dciodvfy.cc: add check that nuclear medicine vectors match number of frames and number of vector values (000339)
+
+090123:	libsrc/standard/elmdict/other.tpl: add McKesson private tag observed with UI VR
+
+090120:	libsrc/standard/module/softcopy.tpl: move RelativeOpacity to correct location in PresentationStateBlending
+	Module, and add NoCondition to ReferencedImageSequence in SoftcopyVOILUTSequence (000338)
+
+090119:	libsrc/standard/condn.tpl,module/base.tpl: do not report that PixelPaddingValue should not be present for non-images if it is not actually present (!) (000337)
+	
+090106:	libsrc/standard/elmdict/philips.tpl,appsrc/dcfile/Imakefile,antodc.cc: label (2005,xx33,"Philips MR Imaging DD 001") as Acquisition Duration,
+	based on observation that value is the same as (0018,9073) in enhanced MR IODs, describe some other Philips MR attributes similarly,
+	and use Philips Acqisition Duration and known GE private scan time tag in antodc to derive standard attribute, and add DICOM
+	as well as ACR-NEMA files to antodc test suite (000336)
+
+081122:	libsrc/standard/module/base.tpl,xaxrf.tpl: detect when 'wrong' x-ray technique attributes are used in not just DX images but also CR, XA/XRF and CT (000334)
+
+081119:	appsrc/dcfile/dckey.cc,dctable.cc: add ignorereaderrors option to try to extract key even if parsing fails (000333)
+
+081106:	libsrc/standard/condn.tpl.module/waveform.tpl,elmdict/dicom3.tpl: rename WaveformAnnotationSequence (was inconsistent between PS 3.3 and 3.6)
+
+081027:	appsrc/dcfile/dciodvfy.cc: check length of PixelData with bytes rather than bits
+	else overflows 32 bit integer (000332)
+
+080929: appsrc/dcfile/dcentvfy.cc: set failure if error, relax errors about different attributes and
+	IEs in instances to warnings, warn about equal numeric value but different string encoding
+	(including times), error if different VRs, check VM difference for special case when missing
+	value and warn rather than error, tidy up different IE message
+
+080928:	appsrc/dcfile/Imakefile,dciodvfy.cc,dcentvfy.cc,libsrc/include/dctool/attr.h,attrmxls.h,
+	attrothr.h,attrseq.h,attrtype.h,attrtypf.h,attrtypn.h,attrtypo.h,attrtyps.h,
+	attrtypt.h,ie.h,iodcomp.h,module.h,src/dctool/Imakefile,attr.cc,attrmxls.cc,attrothr.cc,
+	attrseq.cc,attrtypo.cc,locale/mesgtext.tpl,support/iodcomp.awk,module.awk:
+	Add dcentvfy utility to check consistency of IE-level attributes (000229); requires adding IE
+	enumeration, extending attributes to store IE information acquired from validation; also added
+	option to dciodvfy to dump this information with attribute list
+
+080928:	libsrc/standard/elmdict/other.tpl: add SoundTech vet private tags from conformance statement
+
+080924:	libsrc/standard/elmdict/other.tpl: add SoundTech vet private tags from conformance statement
+
+080909:	libsrc/standard/elmdict/elscint.tpl: add Philips private attribute encountered in explicit VR CT dataset
+
+080908:	appsrc/dcfile/dcdirmk.cc: update to use new method call for validateVR() with null value for character set
+
+080908:	libsrc/include/dctool/attr.h,attrlist.h,attrtype.h,charset.h,src/dctool/Imakefile,attrlist.cc,attrmxls.cc,attrtypv.cc,charset.cc,locale/mesgtext.tpl:
+	improve validation of character sets, including detection of illegal characters outside ASCII (7-bit)
+	range for default character set (000325), allowing escape character in appropriate VRs (000105),
+	detecting illegal control characters other than CR, LF, FF and ESC (including C1 high bit
+	set control characters) (000326) and validating UT VR (000327)
+
+080904:	appsrc/dcfile/dcuncat.cc,libsrc/include/generic/errclass.h,libsrc/src/dctool/attrmxls.cc: change dcuncat to not re-read the input file
+	multiple times to prevent running out of memory when "unenhancing" large number of frames; need to relax some assertions to allow repeated
+	re-writing of same attribute list (000324)
+
+080902:	Imakefile,config/Configure: Build Mac apps as universal binaries for intel and ppc, and add target for Mac executable files corresponding to same files as Windows target
+
+080830:	libsrc/standard/condn.tpl,module/dx.tpl: detect when view position is present but view code sequence is not, for DX objects (000323)
+
+080828:	libsrc/standard/elmdict/other.tpl: add Imaging Dynamics veterinary private tags
+
+080824:	libsrc/standard/condn.tpl: add SNOMED code for "skeletal" (not in DICOM but seen in Siemens bone scan NM images) as unpaired for laterality condition check
+
+080823: libsrc/src/dctool/condn.cc,support/condn.awk,standard/condn.tpl: add mechanism to check string values of
+	elements within sequences, and use it to check SNOMED code values for paired body parts to assist check of
+	condition for Laterality (more work on (000298))
+
+080823:	appsrc/dcfile/dciodvfy.cc: check that SpacingBetweenSlices is not negative unless NM image (000314)
+
+080823:	appsrc/dcfile/dciodvfy.cc: check that direction cosines are orthogonal (000321)
+
+080822:	libsrc/standard/support/Imakefile: add missing elements in repeating groups to Java dictionary (000320)
+
+080817:	libsrc/standard/condn.tpl,module/base.tpl: warn about deprecated 99SDM and SNM3 (rather than SRT) coding scheme designator, as per CP 730 (000319)
+
+080814:	libsrc/include/dctool/attr.h,attrothr.h,attrseq.h,attrtypf.h,attrtypn.h,attrtypo.h,attrtyps.h,attrtypt.h,src/dctool/attrmxrd.cc,locale/mesgtext.tpl:
+		do not give up parsing dataset when one bad attribute with VL mismatch for VR (000318)
+
+080814:	appsrc/dcfile/dcmvhier.datedescnoid.script,dcmvhier*.man: add script to use simpler form of hierarchy without Study ID/Description and Modality, and tidy up man pages
+
+080811:	libsrc/standard/condn.tpl,module/base.tpl: report presence of Pixel Padding Value as being incorrect when not an image (000317)
+
+080811:	libsrc/standard/condn.tpl: require Patient Position for Enhanced CT Image SOP Class (000316)
+
+080808:	libsrc/standard/strval/base.tpl: add FID (Fiducials) to Modality used in General Series (000315)
+
+080808:	libsrc/standard/module/base.tpl: warn about zero patient weight and height (000313)
+
+080723:	libsrc/standard/condn.tpl,module/dx.tpl: detect when 'wrong' x-ray technique attributes are used in DX images (000312)
+
+080718:	libsrc/src/dctool/attrmxrd.cc: check that waveform data is OW when 16 bit and OB when 8 bit whether explicit or implicit VR, and override if incorrect explicit VR (000309)
+
+080718:	libsrc/standard/elmdict/other.tpl: add Mortara ECG tags based on observed VR and conformance statement names
+
+080712:	libsrc/standard/condn.tpl,module/base.tpl: detect empty Type 2 Antatomic Region Sequence when Body Part Examined has a value (000307)
+
+080706:	libsrc/standard/module/dx.tpl: ImageType should be Type 1, not 3, in DX Image Module (000306)
+
+080701:	libsrc/standard/module/base.tpl: improve message for empty Laterality (000298)
+
+080701:	libsrc/standard/condn.tpl,module/base.tpl: make code meaning optional and require 99SDM for NM/PET codes (000304) and (000305)
+
+080630:	Imakefile: add dchist an dcstats to archive.winexe target
+
+080628:	libsrc/standard/elmdict/other.tpl: add some private element VRs encountered in Nordion RT Structure Sets
+
+080628:	libsrc/standard/condn.tpl: do not report PatientOrientation missing for RT Dose (000303)
+
+080628:	appsrc/dcfile/dcanon.script: remove issuers
+
+080628:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl,module/base.tpl,sr.tpl,xaxrf.tpl,strval/base.tpl: update with FT CPs from June 2008 WG6
+
+080626:	libsrc/src/dctool/attrmxls.cc: report error for unrecognized even group element (000299)
+
+080626:	libsrc/standard/condn.tpl,module/base.tpl: report absence of Laterality for paired body parts as an error, and warn when empty (000298)
+
+080624:	libsrc/standard/elmdict/other.tpl: add/update Brit Systems private elements with names and VRs
+
+080623:	libsrc/standard/elmdict/dicom3.tpl: add Sup 23 frozen draft data elements as trial (except where conflict with standard elements)
+
+080623:	libsrc/standard/elmdict/other.tpl: add some VRs for Brit Systems private elements encountered in instances
+
+080621:	libsrc/standard/elmdict/gems.tpl: add some descriptions for GE/Applicare private elements related to annotations used in presentation states, deduced from samples and old conformance statements
+
+080609:	libsrc/standard/cond.tpl: include DX Positioning module when some optional attributes are present that are not included else where, like View Code Sequence (000296)
+
+080609:	libsrc/standard/cond.tpl: use ValuePresent rather than not string value of "", which doesn't work; encountered in ResponsiblePersonRole check (000295) (more on 000277)
+
+080608:	appsrc/dcfile/dciodvfy.cc: check that UIDs begin with reasonable root (000293)
+
+080608:	appsrc/dcfile/dciodvfy.cc: check consistency of scaled values for same concept, e.g., Exposure in uAs - allow for either rounding or trunction (000292)
+
+080608:	appsrc/dcfile/dciodvfy.cc: check for invalid enumerated values and illegal combinations for Patient Orientation, including identical (non-zero length) values (000118)
+
+080531:	libsrc/standard/elmdict/others.tpl: more private attributes encountered in veterinary showdown 2007
+
+080530:	appsrc/dcfile/dcanon.script: preserve known safe private tags (e.g., Philips PET SUV factor) but remove all others (000291)"
+
+080530:	libsrc/standard/elmdict/philips.tpl: add more Philips PET private tags, including activity concentration factor
+
+080526:	libsrc/standard/condn.tpl: do not presume animal just because sex neutered is present (000290)
+
+080526:	appsrc/dcfile/dciodvfy.cc: do not stop checking for specific errors after first failure (000288) and check that all orientation vectors are unit vectors (000289)
+
+080524:	libsrc/standard/module/dx.tpl:	for IHE Mammo profile, allow Gantry ID to be mbpo if condition of Detector Type STORAGE not satisfied (000287)
+
+080524:	libsrc/src/dctool/attrmxrd.cc: detect and recover from incorrect explicit (rather than implicit) vr inside fixed length sequence encoded as unknown VR (000286)
+
+080521:	libsrc/standard/elmdict/*.tpl: add some more private elements with VR encountered as explicit VR
+
+080521:	libsrc/src/dctool/attrmxrd.cc: do not abort parsing but skip incorrectly encoded fixed length UN VR known to be sequence from dictionary (000286)
+
+080521:	libsrc/src/dctool/attrmxrd.cc: recurse into fixed length UN VR known from dictionary to be sequences (000285)
+
+080521:	appsrc/acrnema/andump.cc,libsrc/include/dctool/attrmxls.h,libsrc/src/dctool/attrmxls.cc,attrmxrd.cc,src/locale/mesgtext.tpl:
+	Do not warn about overriding UN with dictionary when reading attribute list (000282) and
+	do not report error when UN SQ contents contain elements as implicit VR (000283)
+
+080430: appsrc/dcfile/dcunjpeg.script: fix typo to support both J2K transfer syntaxes (000280)
+
+080506:	appsrc/dcfile/dcanon.script: add option to remove clinical trial attributes (000281)
+
+080430:	appsrc/dcfile/dcunjpeg.script: decompress JPEG 2000 with Kakadu (000280)
+
+080420:	libsrc/standard/elmdict/*.tpl: add private elements with explicit VR encountered in 2008 European Connectathon
+
+080420:	appsrc/dcfile/dciodvfy.cc: report expected and actual lengths when pixel data incorrect length (000278)
+
+080419:	libsrc/src/dctool/attrvrfy.cc: when reporting warnings and errors, include value number (000153)
+
+080419:	libsrc/standard/condn.tpl,module/*.tpl: add check for missing or empty value 3 for ImageType in modality-specific images (000276)
+
+080419:	libsrc/support/condn.awk,libsrc/src/dctool/condn.cc:  correctly perform empty string value checks in conditions and add valuepresent mechanism (000277)
+
+080418:	appsrc/dcfile/dcarith.cc: add option to fix PixelPaddingValue to match changed stored pixel values (000275)
+
+080418: appsrc/dcfile/dcarith.cc: fix PixelPaddingValue to match changed stored pixel values for -makeidentityrescale option (000274)
+
+080409:	ppsrc/dcfile/dciodvfy.cc: check that PixelSpacing matches ImagerPixelSpacing or NominalScannedPixelSpacing
+	if PixelSpacingCalibrationType not present (000273) 
+
+080409:	libsrc/standard/condn.tpl,module/dx.tpl: check that PixelSpacing is not present for IHE Mammo Profile (000272)
+
+080407:	support/gzip-1.3.12-patchfornoheader: update gzip noheader patch to support 1.3.12 version (000271)
+
+080407:	appsrc/dcfile/dcsrdump: show qualifier in numeric content items if present, for NaN, etc., as per CP 260 (000270)
+
+080307:	libsrc/standard/module/base.tpl: FoR UID and image references may both be present in spatial registration
+
+080307:	libsrc/standard/elmdict/elscint.tpl,other.tpl: add some private tags encountered in IHE-RO datasets
+
+080203:	libsrc/standard/elmdict/*.tpl: add VR of private tags encountered in 2008 IHE NA Connectathon
+
+080203:	libsrc/src/dctool/attrmxrd.cc: improve error messages for bad private owner
+
+080202: appsrc/dcfile/dcuncat.cc: Add option to convert enhanced to old style CT and MR SOP Classes (000267)
+
+080202: appsrc/dcfile/dcuncat.cc: Fix incorrect SeriesInstanceUID that was not the same for all split files (000266)
+
+080131:	libsrc/standard/module/base.tpl: allow AcquisitionDateTime in US images when condition not satisfed (000265)
+
+080129:	libsrc/standard/module/base.tpl,dx.tpl,pet.tpl,strval/base.tpl: correct various string zero and
+	one checks to use binary values to be independent of precision (000264)
+
+080129: libsrc/standard/condn.tpl,module/dx.tpl: do not report missing DateOfLastDetectorCalibration
+	for DetectorType STORAGE in IHEMammo profile (000263)
+
+080129:	libsrc/standard/elmdict/gems.tpl: add some private NM VRs encountered
+
+080129:	libsrc/standard/condn.tpl: show error if empty ShutterShape in image or
+	presentation states supporting shutters (000262)
+
+080129:	libsrc/standard/condn.tpl,module/base.tpl: do not warn about non-grayscale photometric
+	interpretation when Modality or VOI LUT present in presentation state (000261)
+
+080118:	libsrc/standard/condn.tpl,module/base.tpl: fix broken mutually exclusive pixel aspect ratio
+	vs. pixel spacing check (000260)
+
+080116:	appsrc/dcfile/dcanon.script: use Allergies instead of ContrastAllergies (name changed in CP) (000259)
+
+080114: appsrc/dcfile/dcarith.cc,libsrc/include,src/dctool/attrothr.h,.cc: add feature to force rescale slope
+	and intercept to identity, converting pixel values appropriately; also need to have better control
+	over the automatic scaling that was happening when bit depth change in pixel data writes (000258) 
+
+080112:	libsrc/standard/*.tpl,libsrc/src/dctool/attrtypv.cc,elmdict.cc,libsrc/dconvert/*.tpl,pq/pqmmsc.cc,
+	appsrc/dcfile/antodc.cc,dcdirmk.cc,dcmkpres.cc,dcmulti.cc: add all 2007 to 2008 supplements (107,110,114,116,127) and CPs
+
+080102:	appsrc/dcfile/dcdirmk.cc: add support for encapsulated CDA (Sup 114) when creating directory records
+
+080102:	libsrc/standard/sopcl.tpl,iod.module/base.tpl: add deformable registration (Sup 112)
+
+071201:	appsrc/dcfile/dcanon.script: do not remove protocol name unless removing descriptions
+
+071201:	appsrc/dcfile/dcanon.script: remove gantry, plate, cassette, generator, detector ID (000255)
+
+071201:	libsrc/standard/elmdict/agfa.tpl: add some private tags encountered in CR images (with
+	help from Agfa ADC PRID conformance statement)
+
+071125:	libsrc/src/dconvert/signa,appsrc/dconvert/signa: port Signa conversion from old tools
+
+071125:	libsrc/src/dconvert/gen,gaw/g*mmsc.cc: use OTHER rather than MPR for third value of Image
+	Type in MR images (000254)
+
+071125: libsrc/include/dctool/fltype.h: add support for DG floats (for Signa)
+
+071125:	libsrc/support/convert.awk: add support for DG floats (for Signa); use dummy structure name
+	when missing in template; correct filename in generated header
+
+071124:	appsrc/acrnema/ancp.cc: do not add private owner (or change transfer syntax) if empty value
+
+071112:	libsrc/standard/strval/base.tpl: Add RADLEX CSD and UID from CP 751.
+
+071110:	appsrc/dcfile/dcpatmpl.script: add script to apply patient and study attributes from one file
+	to a bunch of other files
+
+071109:	libsrc/include,src/generic/getoptns.h,.cc: add support for "long long" type, as used for delta
+	value in dcdtchg delta command line argument
+
+071109:	appsrc/dcfile/dcdtchg.cc: try to use first image's Study Date to set delta from epoch time, since
+	otherwise too commonly wraps study date to previous day if a later attribute processed first; also
+	report and allow as command line parameter the delta, so it can be applied to a separate set
+
+071105: libsrc/standard/condn.tpl,module/base.tpl: check for grayscale Photometric Interpretation
+	when window or rescale values present (000253)
+
+071105:	libsrc/standard/condn.tpl: include General Equipment Module if any optional attributes present,
+	not just the one mandatory attribute, since is type U module in SC IOD (000252)
+
+071011:	appsrc/dcfile/dcacqmap.script: remove dependence on external CSS, which PDI forbids (000251)
+
+071010:	appsrc/dcfile/dcacqmap.script: add support for creating XHTML (000246), short ISO filenames (000247),
+	sort by ScanOptions (000248), supress generation of dump report (000249) and fix incorrect combining of
+	positions caused by unescaped period fed to grep string (000250)
+
+071005:	appsrc/dcfile/dcanon.script: in dcanon do not add zero length Requesting Physician (000245)
+
+071005:	appsrc/dcfile/dcanon.script: make dcanon follow symbolic links in srcdir (000244)
+
+071002:	libsrc/standard/strval/base.tpl: update modality list per CP 713, 749, Sup 110 with BDUS,BMD,DOC,OPT
+
+070828:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl,ct.tpl: CP 764 CTDI Phantom Type Code Sequence
+
+070828:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl,ct.tpl: CP 763 CT Calibration Factors for the Mass Score of the Calcium Scoring
+
+070828:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl: CP 747 Clinical Trial Series attributes
+
+070828:	libsrc/standard/condn.tpl,elmdict/dicom3.tpl,module/mr.tplstrval/mr.tpl: CP 744 Diffusion b-matrix
+
+070820:	appsrc/dcfile/dchist.cc,dcuncat.cc,dcmulti.cc,libsrc/include,src/dctool/attrothr.h,.cc: extend dchist to detect
+	energy in high bits (potential embedded overlay bits) (000243)
+
+070809:	appsrc/dcfile/dcdirmk: Add command line option to generate test bad missing LowerLevelDirectoryOffset (000242)
+
+070729:	appscr/dcfile/dcj2k.script: add script to compress as JPEG 2000 (needs Kakadu kdu_compress present)
+
+070726:	libsrc/standard/elmdict/other.tpl: add Sirona private elements from ADA 2007 and fix some Fuji elements
+
+070726:	libsrc/standard/module/vl.tpl: in VL Image, Anatomic Regions Sequence and Referenced Image Sequence may
+	be present otherwise (000240) and (000241)
+
+070707: appsrc/dcfile/dcdirmk.cc: clean up "bad" Decimal String attribute values copied from source images (000237)
+
+070707: appsrc/dcfile/dcdirmk.cc: do not include ReferencedImageSequence twice when -position option used (000238)
+
+070707: appsrc/dcfile/dcdirmk.cc: use ST rather than SH for Document Title for encapsulated documents (000236)
+
+070621: appsrc/dcfile/dcckovly.script: add script to check for overlays, curves, graphics
+	annotations and non-zero high bits (000235)
+
+070621: appsrc/dcfile/dccmp.script: stop script failing when files same but warning or error
+	during parsing of one and not the other (000234)
+
+070602: libsrc/standard/condn.tpl,module/base.tpl,strval/base.tpl: fix limited subset of photometric
+	interpretations allowed for multi-frame true-color SC to include compressed values,
+	and match against transfer syntax (000232)
+
+070423:	libsrc/standard/elmdict/*.tpl: add IHE-E connectathon encountered private tags with explicit VR
+
+070423:	libsrc/standard/elmdict/dicom3.tpl: Fix VR of some retired attributes to match standard (000228)
+
+070421:	libsrc/standard/strval/base.tpl: add new modality types from standard
+
+070421:	libsrc/src/dctool/attrmxrd.cc,locale/mesgtext.tpl: during parsing, distinguishing between overriding
+	unrecognized tag VR with explicit, or explicit being UN (000227)
+
+070404:	support/elmtojava_DicomDictionary_CreateIEByTag.awk: change java dictionary generation
+	to set Institution Name back to series instead of instance (000225)
+
+070327:	config/Configure: fix failure on Solaris since Cygwin on XP check added (000224)
+
+070326:	libsrc/standard/module/base.tpl,libsrc/standard/condn.tpl: detect illegal or
+	deprecated code values in view code sequence (000223)
+
+070326: libsrc/support/module.awk: show attribute value in verify message (000222)
+
+070321:	libsrc/support/DicomDictionary_header.txt,DicomDictionary_trailer.txt,
+	elmtojava_DicomDictionary_CreateFullNameByTag.awk,standard/Imakefile: add full name not just
+	keyword to java dictionary (pixelmed 000294)
+
+070318:	appsrc/dcfile/dciodvfy.cc: check EstimatedRadiographicMagnificationFactor matches ratio of
+	DistanceSourceToDetector and DistanceSourceToPatient(000221)
+
+070318:	appsrc/dcfile/dciodvfy.cc: fix PixelApectRatio check - was checking the first value against
+	itself (000220)
+
+070317:	appsrc/dconvert/toshiba/: add script to assemble separate header and pixel data for Toshiba images
+
+070317:	appsrc/dcfile/antodc.cc: make wrong Y sign on Toshiba CT work for prone images as well
+
+070317:	libsrc/standard/Imakefile,module/base.tpl,ct.tpl,mr.tpl,xaxrf.tpl,
+	support/elmtojava_DicomDictionary_CreateIEByTag.awk,inserttagumberbeforekeyword.sh:
+	When generating IE by tag, null module at end of IE/IOD to prevent carrying over
+	first macro/module definition as SOP common (e.g., for CodeValue, etc.), treat
+	frame as instance in macros unless explicitly in functional group, add role to
+	generate CSV file
+
+070315: libsrc/include/dctool/attrmxls.h,dcopt.h,src/dctool/attrmxls.cc,attrmxrd.cc,dcopti.cc,
+	appsrc/dcdisp/dcdisp.cc,dcfile/*.cc: add option during read to use US rather than OW VR
+	for LUT Data (000219)
+
+070315:	libsrc/standard/module/vl.tpl: Acquisition Datetime in Ophthalmic Photography
+	Image Module may be present otherwise when condition not satisifed
+
+070315:	libsrc/src/dctool/attrothr.cc: Avoid throwing assertion for images whose bits
+	allocated is not a multiple of 8, introduced when fixing truncation of value
+	length for large (multi-frame) images (000218)
+
+070315:	: Handle bad images that have explicit VR encoded data elements in implicit VR
+	datasets, but only if ignoreoutofordertags flag set (000217)
+
+070315:	config/Configure: make Cygwin detection less dependent on specific version of
+	operating system included in uname -s string (000216)
+
+070315:	config/Configure: add date of cvs version to header generated by Configure,
+	rather than manually inserted date that has not been kept current
+
+070314:	libsrc/standard/condn.tpl,iod/dx.tpl,module/dx.tpl: distinguish between Partial
+	View Option present or not in IHE Mammo Profile, by adding separate named profile
+	and reporting warning rather than error on missing ParialView if not requested (000215)
+
+070311:	libsrc/module/base.tpl: add missing optional attributes to Request Attributes macro
+
+070311:	libsrc/standard/elmdict/other.tpl: add IMS private mammo tags from examples
+
+070311:	libsrc/module/dx.tpl,elmdict/dicom3.tpl: add IDs in CP 649
+
+070311:	appsrc/dcfile/dcuidchg.cc: add -map option to store file containing map of original
+	to replacement UIDs (000215)
+
+070311:	libsrc/standard/condn.tpl,module/sr.tpl: stop incorrect complaints about missing concept
+	name in SR (000214), also add series date, time and description as per CP 703 (000213)
+
+070311: appsrc/acrnema/andump.cc: Prevent or fail when andump in ancreate mode will otherwise
+	truncate dump of values when VL is long (000212)
+
+070309: libsrc/standard/module/file.tpl: refactor to use macros instead of shared conditions
+	for each directory record (000123), (000134), (000140)
+
+070309:	libsrc/standard: extensive cleaning up to make use of mbpo condition modifier (000202),
+	improve various conditions accordingly, emit specific messages (000203),
+	add CP 692 Pixel Padding Range Limit to dictionary and module,
+	and add segmentation data elements (not yet IODs), implement content
+	identification macro, and extend SpatialLocationsPreserved with REORIENTED_ONLY (CP 665)
+
+070309:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: object when pixel aspect ratio present when 1:1 (000211)
+
+070309:	libsrc/support/module.awk,libsrc/src/dctool/modulev.cc,libsrc/src/locale/mesgtext.tpl:
+	add mbpo (may be present otherwise) to condition mechanism and make non-mbpo presence
+	an error rather than warning (000202), and add generic mechanism to be able to issue
+	specific messages on certain conditions (000203)
+
+070309:	libsrc/src/dctool/attrothr.cc: Correct truncation of value length for large (multi-frame) images (000210)
+
+070308:	appsrc/dcfile/dcuidchg.cc: add -descriptor option to update De-identification Method (000209)
+
+070306:	libsrc/include/dctool/dcopt.h,src/dctool/dcopti.cc,dcopto.cc,appsrc/dcfile/dcdump.cc,
+	dcfile.cc,dchist.cc,dciodvfy.cc,dckey.cc,dclutdmp.cc,dcposn.cc,dcsrdump.cc,dcstats.cc,
+	appsrc/acrnema/andump.cc: make dump and verify utilities display filename to simplify scripts (000201)
+
+070302: libsrc/support/elmtojava_DicomDictionary_CreateIEByTag.awk: revise java dictionary generation
+	to better handle series/instance/frame conflicts and supress descent into sequences (000200)
+
+070302: libsrc/standard/module/dx.tpl: specify Image IE for DigitalXrayDetectorMacro (for Java dict)
+
+070302: libsrc/standard/module/base.tpl: add GantryID to General Equipment Module
+
+070227:	libsrc/standard/elmdict/philips.tpl: update Philips private MR based on conformance statement
+	"http://www.medical.philips.com/main/company/connectivity/assets/docs/dicomcs/mr91.pdf" (which is
+	a good reference because it has descriptions and defined terms)
+
+070227:	libsrc/src/dctool/attrmxls.cc: validation of which attributes are used in IOD should not descend
+	into private sequences (000199)
+
+070224:	libsrc/standard/elmdict/gems.tpl: update PET data dictionary from Discovery conformance statement
+
+070204:	config/Configure: make dcdisp link properly on cygwin (000198)
+
+070202:	config/Configure: remove dependency on libX11.a regardless of OS and version -
+	fixes (000197) dcdisp fails to compile on Solaris 10
+
+070202:	appsrc/misc/bmpdump.cc: add utility to dump header of BMP file in readable form
+
+070202:	appsrc/misc/pgmtobmp.cc: correct number of padding bytes when width is odd, and
+	include padding bytes in file length (000196)
+
+070126: libsrc/standard/condn.tpl: Amend coding scheme version condition to check for known coding
+	schemes that require version as per PS 3.16 (000195)
+
+070121:	libsrc/standard/condn.tpl,module/base.tpl,strval/base.tpl: update Coding Scheme Designator list and
+	add cross-check against UID in Coding Scheme Identification Sequence
+
+070121:	libsrc/src/dctool/attrmxrd.cc: make private creator LO under all circumstances, even if explicit
+	VR is not LO, so as to recognize subsequent private tags (000194)
+
+070120:	libsrc/standard/elmdict/*.tpl: update private data elements to handle IHE 2007 connectathon objects
+
+070119:	appsrc/dcfile/dclutdmp.cc: add ancreate option to dclutdmp (000191)
+
+070119:	appsrc/acrnema/ancreate.cc: allow longer input lines for ancreate (partial fix for 000192)
+
+070119:	libsrc/standard/cond.tpl,module/dx.tpl: check GantryID for CR detector type for IHE Mammo profile (000193)
+
+070118:	libsrc/standard/module/dx.tpl,iodcomp/dx.tpl: validate IHE Mammo profile for processing images (000189)
+
+070118:	libsrc/standard/elmdict/dicom3.tpl: add GantryID
+
+070115:	libsrc/standard/elmdict/siemens.tpl: update Siemens private tags based on encountered
+	CR gateway images (changed VR for some attributes already known)
+
+070115:	appsrc/dcfile/dcanon.script: removed retired attribute Manipulated Image (000188)
+
+070115:	libsrc/standard/sopcl.tpl,cond.tpl,strval/base.tpl,elmdict/dicom3.tpl: spell fluoroscopy
+	correctly (000187)
+
+070113:	libsrc/standard/elmdict/other.tpl: add Fuji private tags from CR conformance statement
+
+070113:	libsrc/standard/elmdict/other.tpl: add Hologic private tags with from bone density
+	conformance statement
+
+070112:	libsrc/standard/elmdict/siemens.tpl: update Siemens private tags with from Fluorospot Compact
+	conformance statement
+
+070112:	libsrc/standard/elmdict/gems.tpl: update GE IIS tags with names from Centricity 3.0
+	conformance statement
+
+070111:	libsrc/standard/elmdict/gems.tpl: update GE IIS tags
+
+070110:	appsrc/misc/pgmtobmp.cc: add utility to convert 8 bit grayscale PGM images into BMP files
+	with a fixed 256 grayscale palette (unlike netpbm ppmtobmp that actually tunes palette to
+	number of values)
+
+070105:	libsrc/support/module.awk,standard/module/base.tpl: add ability to supress setting used flag
+	on element use in module; use it to supress use flagging on check of number of frames in
+	SC image (000186)
+
+061226:	appsrc/dcfile/dcdirmk.cc: use null values when no content date, etc, since type 2, rather than
+	throwing assertion failure
+
+061226:	libsrc/include,src/dctool/attrtypo.h,.cc: pad large non-pixel data OB read from file to even
+	length with zero byte when necessary (e.g. when encapsulating PDF) (000183)
+
+061224:	libsrc/standard/iodcomp.tpl.module.tpl: modality values are defined terms not enumerated values
+	in secondary capture and encapsulated documents (000182)
+
+061214:	appsrc/dcfile/dcanon.script: add PatientIdentityRemoved and DeidentificationMethod based on options
+
+061210:	libsrc/standard/elmdict/dicom3.tpl: correct BeamDosePointEquivalentDepth name entry
+
+061127:	libsrc/standard/elmdict/dicom3.tpl: Correct spelling of "Operators' Name" to match standard
+
+061120:	appsrc/dcfile/dcacqmap.script: Add a script to create a visual map of pattern of CT acquisition
+	in space and time as an html page (000180)
+
+061109:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl: Add CP 526 original attribute sequence
+
+061107: libsrc/src/dctool/attrmxrd.cc,appsrc/acrnema/andump.cc: tolerate (grudgingly) a TransferSyntaxUID
+	that occurs outside the meta information header (encountered in GE ultrasound which uses this in
+	sequence items with small images) (000179)
+
+061022:	appsrc/dcfile/dcmulti.cc: do not insert Trigger Window in cardiac macro - it is not (yet) standard,
+	and often is present in non-cardiac single frame source images with a value of 0, and its presence without
+	the other cardiac sequence and module attributes creates an invalid IOD
+
+061021:	appsrc/dcfile/dcmulti.cc: minimal attributes should not force anatomic region sequence to be empty
+
+061021:	appsrc/dcfile/dcmulti.cc: correct wrong tag in shared functional group sequence - should be
+	RRIntervalTimeMeasured not TriggerWindow
+
+061021:	libsrc/include,src/uidgen.cc,.h,appsrc/dcfile/dcmulti.cc: generate IrradiationEventUID
+	and BurnedInAnnotation == NO when not supplied
+
+061020:	libsrc/standard/elmdict/philips.tpl: add VRs observed for private attributes in Philips
+	Achieva release 2 enhanced MR and spectroscopy objects
+
+061014:	libsrc/standard/elmdict/picker.tpl: add some VRs encountered for Picker MR private tags
+
+061007:	appsrc/dcfile/dcanon.script: do not look in Mac .DS_Store file (very slow if large)
+
+061005:	config/Imake.p-rules: make install is broken on Solaris (or 2.95 ?) due to executable suffix concatenation
+
+061005:	libsrc/standard/module/*.tpl: check for inappropriate zero values
+
+061005:	libsrc/include/dctool/attr.h,src/dctool/attrvrfy.cc,src/locale/mesgtext.tpl,standard/module/vl.tpl,,
+	support/module.awk: add mechanism to check for value of zero during validation and use with ophthalmology IOD
+
+061004:	libsrc/standard/elmdict/dicom3.tpl,module,strval/base.tpl,cond.tpl: add veterinary
+	stuff from CP 643 (and avoid conflict with coding scheme ResponsibleOrganization
+	by renaming it)
+
+061004:	libsrc/support/condn.awk,src/condn.cc: extend conditions to allow nested boolean
+	operations in conditions and add sequence has items condition test
+
+060922:	libsrc/standard/elmdict/gems.tpl: update GE MR tags for 14.0
+
+060918:	libsrc/support/strval.awk: fix trailing space removal code that was failing on FC5
+
+060918:	libsrc/include/dctool/attrtypf.h: mask low word in FD extraction else incorrect
+	on 64 bit platform
+
+060918:	libsrc/src/dctool/uidgen.cc: mask integer values to 16 bits, otherwise gives
+	different results on 64 bit platforms when value is large
+
+060917:	config,libsrc,appsrc: make compilable under Cygwin - involves allowing for .exe
+	extensions on binaries, changes to log2 invocation (which lead to factoring out math.h
+	into basetype.h)
+
+060909:	libsrc/standard: add script to build spreadsheets of use of elements in modules and IODs
+
+060905:	libsrc/standard/iod/rt.tpl: provide condition for Frame of Reference Module in
+	RT Plan (000167)
+
+060817:	appsrc/dcfile/dciodvfy.cc: do not check DICOMDIR instances for attributes needed
+	to build DICOMDIR (000176)
+
+060810:	appsrc/dcfile/dcjls.script,dcunljs.script: add scripts to make DICOM encapsulated
+	JPEG-LS images
+
+060809:	appsrc/dcfile/dcmulti.cc: Start adding composite body part detection for coded anatomy
+
+060803:	appsrc/dcfile/dciodvfy.cc: Report on missing attributes or values in instance
+	needed to build DICOMDIR (000173)
+
+060801:	appsrc/dcfile/dcmulti.cc: add Irradiation Event UID and Sequence
+
+060801:	libsrc/standard/condn.tpl,iod,module,strval/dx.tpl,file.tpl: add dental media profile
+
+060801:	libsrc/standard/elmdict/other.tpl: add more Schick private attributes
+
+060728:	appsrc/dcfile/dcdtchg.cc: add utility to consistently change dates and times
+	within a set of files for de-identification purposes (similar to dcuidchg)
+
+060727:	libsrc/src/dctool/attrtypv.cc,locale/mesgtext.tpl: change group length verification
+	from retired to undesirable (000172)
+
+060725:	libsrc/standard/support/module.awk,module/*.tpl,libsrc/src/modulev.cc: specify and
+	check number of sequence items (000169)
+
+060720:	appsrc/dcfile.dcanon,script,dcuidchg.cc: update list of UIDs to remove/preserve (000168)
+
+060717:	libsrc/src/dctool/attrothr.cc: remove assertion failures on zero value for rows
+	etc, to allow empty pixel data in standard extended SOP classes (000166)
+
+060716:	libsrc/standard/*.tpl,appsrc/dcfile/dcdirmk.cc: update to 2006 standard + first
+	2007 CP packet,including retirements,RT Ion,enhanced XA/XRF,new presentation
+	states,encapsulated PDF,procedure log,dose SR
+
+060708:	appsrc/dcfile/dctable.cc: add option to recurse into sequences if key
+	not found at top level (000148)
+
+060704:	appsrc/dcfile/dciodvfy.cc,libsrc/include/dctool/attr.h,attrmxls.h,
+	libsrc/src/dctool/attr.cc,attrmxls.cc,libsrc/src/locale/mesgtext.tpl,
+	libsrc/support/module.awk: detect and report presence of standard extended
+	sop class attributes (000164)
+
+060704:	libsrc/standard/module/file.tpl: add Media Storage SOP Class UID (000165)
+
+060704:	appsrc/dcfile/dciodvfy.cc,libsrc/include/dctool/attr.h,attrmxls.h,elmdict.h,
+	libsrc/src/dctool/attrmxls.cc,attrtypv.cc,elmdict.cc,elmentry.h,
+	libsrc/src/locale/mesgtext.tpl,libsrc/standard/elmdict/dicom3.tpl,
+	libsrc/support/elmdict.awk: check for presence of retired attributes based
+	on data dictionary (000163)
+
+060704:	libsrc/standard/elmdict/dicom3.tpl,libsrc/standard/module/rt.tpl: update data
+	dictionary to 2006 standard
+
+060630:	libsrc/standard/elmdict/dicom3.tpl: change ImageType VM from 1-n to 2-n to detect when
+	too few values in dciodvfy (000162)
+
+060629:	libsrc/standard/elmdict/*.tpl: move all standard elmdict tags into single file
+
+060628:	libsrc/standard/module/vl.tpl: change SOPInstanceReference to ImageSOPInstanceReferenceMacro in
+	Ophthalmology image (000158)
+
+060627:	appsrc/dcfile/dcfile.cc,.man: add brief mode
+
+060627:	libsrc/strval/base.tpl,module/base.tpl,ct.tpl.mr.tpl.vl.tpl: add defined terms for
+	Lossy Image Compression
+
+060601:	appsrc/dcfile/dciodvfy: check values of frame increment pointer are in dataset (bug 000156)
+
+060427:	libsrc/standard/condn.tpl: fix ConceptNameCodeSequenceNotPresent to look for correct
+	attribute ... was erroneously flagging missing UnformattedTextValue in waveform annotations
+
+060425:	appsrc/dcfile/dcanon.script: add more control over hierarchical file rearrangement after
+	anonymizing
+
+060408:	config/Imake.tmpl,libsrc/standard/Imakefile,elmdict/Imakefile,docs/Imakefile: handle
+	FC5 change in POSIX arguments for coreutils like sort that causes them to break with
+	numeric field arguments (use _POSIX2_VERSION=199209'; see "info coreutils Standards")
+
+060324:	libsrc/standard/module/base.tpl,iod/base.tpl,dx.tpl,pet.tpl,vl.tpl: make dciodvfy detect
+	presence of multiple frames in single frame objects (bug 000154)
+
+060211:	libsrc/standard/cond.tpl,module/dx.tpl,strval/dx.tpl: update to validate public comment
+	draft of IHE mammo profile
+
+060205:	libsrc/standard/elmdict/mr.tpl,appsrc/dcfile/dcmulti.cc: add attributes from CP 593 and
+	draft CP to include trigger window (CP 593 not completely done yet)
+
+060122: libsrc/include,src/dctool/attrmxls.h,.cc,appsrc/dcfile/dccp.cc: add removecommandgroup option
+
+060105:	appsrc/dcfile/dcuidchg.cc: use strrchr() not rindex() else breaks on Solaris
+
+051220:	appsrc/dcfile/dcanon.script: remove additional attributes relating to admission
+
+051218:	appsrc/dcdisp/dcdisp.cc: add support for applying OW, not just US, VOI LUT a la dclutdmp.cc
+
+051216:	libsrc/include/dctool/attrtag.h,src/dctool/attrmxrd.cc: handle illegal private creators < 0x0010
+
+051215:	libsrc/standard/iodcomp/dx.tpl,module/dx.tpl,strval/base.tpl,dx,tpl: add draft IHE profile to validator
+
+051215:	appsrc/dcfile/dciodvfy.cc,libsrc/include/dctool/iodcomp.h,support/iodcomp.awk: add profile mechanism to validator
+
+051215:	libsrc/standard/elmdict/dicom3.tpl,module/base.tpl: Add CP 564 Spatial Locations Preserved
+
+051214:	appsrc/dcfile/dclutmix.cc: add utility to create VOI LUT and scramble pixels if LUT not used for displayif/Imake.tmpl
+051213:	appsrc/dcfile/dcarith.cc: add replacevalue (range)
+
+051212:	appsrc/dcfile/dcuidchg.cc: add utility to change all UIDs of a set of files
+
+051210:	appsrc/dcfile/dccp.cc: add option to copy only selected VOI LUT item and to remove others
+
+051209:	appsrc/dcfile/pnmtodc.cc,rawtodc.cc: add option to make only image pixel module attributes
+	and not all the other SC IOD mandatory attributes
+
+051207:	appsrc/dcfile/dclutburn.cc: add utility to burn selected voi lut into pixel data
+
+051203:	libsrc/standard/elmdict/toshiba.tpl: update some private Toshiba CT tags
+
+051123:	appsrc/simple/ge9800/ge98id.cc: dump a few more attributes like position and thickness and
+	add Data General real conversion
+
+051115:	libsrc/standard/cond.tpl,module/xaxrf.tpl,iodcomp/dx.tpl,xaxrf.tpl,elmdict/dicom3.tpl: change
+	therapy to intervention as per CP 159
+
+051115:	libsrc/standard/elmdict/softcopy.tpl: add Sup 100 Color presentation State elements
+
+051010:	appsrc/dcfile/dcsort.cc: add option to show interval along sort key, e.g., to find reconstruction
+	interval along position direction
+
+051009:	appsrc/dcfile/dctopdf.cc,pdftodc.cc: add utilities to encapsulate and unencapsulate PDF
+
+051009: libsrc/standard/condn.tpl,elmdict/dicom3.tpl,iodcomp/base.tpl,module/acqctx.tpl,base.tpl,
+	strval/base.tpl,file.tpl: implement validation of encapsulated PDF IOD
+
+051009: libsrc/include/dctool/attrtyp*.h,src/dctool/attrtypo.cc: implement writeData() using existing
+	writeValues()
+
+051006:	appsrc/dcfile/dckey.cc,dctable.cc: dump code sequence when any (not all) code sequence item attribute present
+
+051003:	libsrc/standard/strval/charset.tpl: allow empty string as legal defined term (meaning ISO-IR 6)
+
+051003:	libsrc/include/locale/msgtext.tpl,appsrc/dcfile/dciodvfy.cc: add specific check for empty Referenced
+	File ID components (assumes Referenced File ID is always type 1)
+
+051003:	libsrc/include,src/attr.h,attrtyps.*,modulev.cc: make check for Type 1 for string attributes
+	OK if any value is not empty (rather than all of them) - this has the side effect of no
+	longer detecting empty Referenced File ID components in DICOMDIRs, for which a specific
+	check needs to be added
+
+050913:	libsrc/standard/*/vl.tpl,cond.tpl,binval.tpl: add opthalmology and stereometric SOP classes
+
+050819:	libsrc/src/locale/mesgtext.tpl,libsrc/src/dctool/attrmxrd.cc,appsrc/acrnema/ancp.cc,andump.cc: detect when
+	UN is incorrectly encoded with short rather than long form of VL and tolerate (as has already been done for
+	UT VR)
+
+050805:	appsrc/dcfile/dcanon.script: Add more patient related attributes to remove (from detached patient mx modules)
+
+050804: libsrc/src/dctool/attrmxrd.cc,attrtypo.cc,include/dctool/attrmxls.h,appsrc/acrnema/andump.cc: Tolerate
+	DicomWorks bug during de-identification that inserts invalid implicit VR elements with odd lengths in
+	explicit VR files and allow copying without throwing assertion failure on odd length (and do this
+	without compromising andump functionality when tolerating GE endianness bug in item tags in encapsulated
+	pixel data)
+
+050721:	appsrc/dcfile/dcdirmk.cc: needs to include ctype.h for isspace() on Solaris
+
+050706:	libsrc/support/elmtojava_DicomDictionary_CreateIEByTag.awk: include ModalitiesInStudy, SOPClassesInStudy,
+	NumberOfPatient/Study/Series Related Studies/Series/Instances with appropriate informationEntityByTag
+
+050706:	libsrc/standard/elmdict/dicom3.tpl: add CP 397 SOP Classes in Study
+
+050703:	appsrc/dcfile/dcdirmk.cc: compare only significant parts of Patient's Name
+
+050628:	libsrc/standard/module/base.tpl,ct.tpl,mr.tpl,elmdict/dicom3.tpl: Add Lossy Image Compression Method
+	(CP 400 and CP 498)
+
+050625:	libsrc/include/dctool/attr.h,attrseq.h,include/generic/listsimp.h: detect empty type 1 or 1C
+	sequences correctly in dciodvfy, by making isEmptyOrHasAnyEmptyValue() and related methods
+	work properly for sequences by checking number of items rather than VM (which is always 1) - fixes
+	(000141) dciodvfy does not check number of sequence items
+
+050623:	appsrc/dcfile/dckey.cc,dctable.cc: dump sequences as triplet if code sequences
+
+050612:	appsrc/acrnema/andump.cc: add option to extract Siemens CSA header "attributes"
+
+050612:	appsrc/acrnema/andump.cc: add support for dumping FD properly (was only doing FL) (000146)
+
+050611:	libsrc/standard/elmdict/philips.tpl: add Digital Diagnost 1.4 private elements
+
+050531:	appsrc/dcfile/dclutdmp.cc: fix handling of multiple items (000145), add support for OW encoded LUT (000144)
+
+050530:	libsrc/standard/elmdict/softcopy.tpl,module/base,ct,mr,softcopy.tpl: CP 467 Sigmoid VOI LUT type
+
+050528:	appsrc/dcfile/dchist.cc: add option to generate CSV file of histogram
+
+050522:	appsrc/dcfile/dcdirmk.cc: add Number of Frames to spectroscopy directory record (is required)
+
+050520:	libsrc/include,src/dctool/dicomdir.h,.cc,appsrc/dcfile/dcdirdmp.cc: add option to display only
+	the paths of referenced files
+
+050505: libsrc/standard/module/dx.tpl,pet.tpl: make check of rescale slope/intercept use various string
+	equivalents of 0 and 1, e.g., to allow 0. and 1. etc. (don't use binary enum, since rounding
+	error)
+
+050505: libsrc/support/strval.awk: generalize characters allowed in string value codes to all but comma and equals
+
+050505: libsrc/standard/elmdict/other.tpl: update Dexis private tags to ADA 2005 demo values encountered
+
+050430:	libsrc/standard/elmdict/Imakefile: make dependencies for more granular java.install
+
+050430:	libsrc/standard/elmdict/mr.tpl: correct tag value of Parallel Reduction Factor In-plane (CP 319)
+
+050422:	libsrc/standard/elmdict/gems.tpl,other.tpl: Add some unknown GE PET Discovery private tags, and a few
+	Stentor private tags that were in a GE PET sample
+
+050419:	libsrc/standard/module/vl.tpl,strval/vl.tpl: CP 536 make YBR_FULL_420 YBR_PARTIAL_420 for MPEG2 in VL
+
+050411:	libsrc/standard/elmdict/dicom3.tpl,module/dx.tpl: Add CP 393
+
+050409:	libsrc/standard/elmdict/toshiba.tpl: add Toshiba Aplio US private elements
+
+050407:	libsrc/standard/cond.tpl,sopcl.tpl,binval.tpl,libsrc/standard/elmdict,iod,module,strval/softcopy.tpl:
+	add Sup 60 hanging protocols (dcdirmk not done yet)
+
+050406:	libsrc/standard/elmdict/dicom3.tpl: CP 507
+
+050406:	libsrc/standard/cond.tpl,sopcl.tpl,elmdict/dicom3.tpl,module/file.tpl,strval/file.tpl,appsrc/dcfile/dcdirmk.cc: 
+	add Sup 104 encapsulated documents (pdf)
+
+050310:	libsrc/standard/condn.tpl,module/base.tpl,strval/base.tpl: check photometric interpretation against
+	transfer syntax to detect bad RGB when JPEG, etc.
+
+050305:	appsrc/dcfile/dcmulti.cc: allow contrast bolus usage to be shared functional group (CP 503)
+
+050305:	appsrc/dcfile/dcmulti.*,libsrc/include/dctool/uidgen.h: add support for multiple dimension organizations
+
+050226:	libsrc/include,src/generic/txstream.*,appsrc/acrnema/andump.cc: Fix (000102) andump -showoffset-oct and -dec
+	still show offset in hex only
+
+050221:	appsrc/acrnema/ancp.cc,support/testapp: add utility to blank out elements without changing length
+
+050217:	libsrc/standard/condn.tpl,sopcl.tpl,elmdict/dicom3.tpl,iodcomp/base.tpl,module/base.tpl,strval/base.tpl:
+	add spatial registration and fiducials objects
+
+050214:	appsrc/dcfile/dciodvfy.cc: don't stop LUT Data checks after first failure but check all
+
+050214:	libsrc/standard/elmdict/elscint.tpl: update data dictionary with yet more VRs based on IHE PDI CD
+
+050212:	appsrc/dcfile/dciodvfy.cc: LUT Data checks need to not report error for length of zero used as 65536
+
+050212:	libsrc/src/dctool/attrmxrd.cc: don't check stream->fail() unless we have to, either at end of dataset
+	read or sequence read - seems to fail inappropriately on AMD 64 Linux with Siemens PDI 2004 demo DICOMDIR
+
+050209:	libsrc/src/dctool/modulev.cc: distinguish complaint about empty 1C values when condition satisfied or not
+
+050209:	libsrc/src/dctool/attrmxrd.cc: check for non-even VLs and incorrect explicit sequence and item lengths
+
+050206:	appsrc/dcfile/dciodvfy.cc: add specific check on maximum value in LUT Data
+
+050206:	libsrc/standard/cond.tpl,binval.tpl,module/base.tpl,softcopy.tpl,dx.tpl: check enum val for LUT Descriptor
+	value 3
+
+050121:	appsrc/dcfile/dcmulti.cc: add k-space filtering for all MR images (CP 379)
+
+050119:	appsrc/dcfile/dcmulti.cc: add CP570 (Mar 2005 VP) and other image derivation codes
+
+050119:	appsrc/dcfile/dcmulti.cc: include rescale type in shared versus per frame decision for pixel value
+	transformation sequence
+
+050115:	libsrc/src/dctool/condn.cc: fix (000133) dciodvfy curve module presence is incorrectly triggered
+	by private 50xx attributes 
+
+050115:	libsrc/standard/elmdict/*.tpl: update data dictionary with yet more VRs based on IHE PDI CD
+
+050116:	appsrc/dcfile/dcunjpeg.script: make more robust in the face of jpeg codec reporting components starting
+	at 0 or 1, also silence warnings from dccp
+
+050115:	libsrc/standard/elmdict/siemens.tpl,philips.tpl: update data dictionary with VRs based on IHE PDI CD
+
+050106:	libsrc/include/dctool/attrothr.h,src/dctool/attrothr.cc,attrmxrd.cc: detect a strange image bug that
+	swaps US VR bytes and pixel data bytes (only) and fix during reading
+
+050105:	libsrc/include/dctool/attrmxls.h,src/dctool/attrmxrd.cc: recognize illegal explicit OB with > 8 bits
+	allocated, report error and force OW during read to keep the peace
+
+050102:	appsrc/dcfile/dcmulti.cc: always use canonical time form hhmmss in case source content
+	or acquisition time uses fewer components
+
+050102:	libsrc/src/generic/datetime.cc: while parsing string times, allow for everything after
+	hour to be missing, and make sure missing values are intitialized to zero
+
+041227:	libsrc/src/dctool/attrmxrd.cc: work around platform-specific bug in implicit versus
+	explicit distinction (see [bugs.dicom3tools] (000130))
+
+041227:	appsrc/acrnema/ancreate.cc: add option to include preamble
+
+041224:	libsrc/standard/module/file.tpl: make group length type 1 in meta information header
+
+041224:	appsrc/acrnema/ancreate.cc: remove check during hex read from string - seems to fail on
+	trailing ']' delimiter with gcc 3; also allow spaces between numeric values
+
+041221:	libsrc/include/dctool/attrtypo.h,dcopt.h,libsrc/src/dctool/attrtypo.cc,dcoptc.cc,dcopto.cc,
+	appsrc/dcfile/dckey.cc,dctable.cc: factor out specifying element in command line argument by
+	hex values rather than name as used in dctable and dckey into getAttributeTagFromStringHexForm
+	in dcopt.h and dcoptc.cc, and make it available in -r, -rb and -d options, and add method to
+	add string values to UN since that is required for -r, -rb options that must have an argument
+
+041221:	appsrc/dcfile/dciodvfy.cc,libsrc/src/locale/mesgtext.tpl: check for illegal groups
+	0x0001,0x0003,0x0005 and 0x0007
+
+041210:	config/Configure: check for 64 bit X11R6 libraries for AMD x86_64 Linux FC3
+
+041208:	libsrc/src/dctool/attrmxrd.cc: do not override explicit UN with dictionary SQ since UN payload
+	is encoded implicit VR (encountered this with a Philips MR image with private sequences via
+	DJ2002 with fixed length UN payload)
+
+041207:	appsrc/dcfile/dcmvhier.8only.*: use Study Date in preference to Study ID for hierarchy
+
+041207:	libsrc/src/dctool/attr.cc,attrnew.cc: make dictionary XO VR create an OW, and check to make sure
+	that XO, XS and XO never get written in explicit VR just in case (need triggered by encountering
+	VOI LUT in implicit VR)
+
+041202:	appsrc/dcfile/dcmkpres.cc,dcmkpres.man: add selection of whether or not to use OW or US for LUTs,
+	and add capability to add VOI LUT to images rather than make presentation state
+
+041202:	libsrc/standard/elmdict/dicom3.tpl: LUT Data may be OW, US or SS
+
+041202:	libsrc/include/dctool/attrtypn.h: detect when someone tries to add more values than
+	will fit in the explicit value representation value length limit of 16 bits (65536 bytes)
+
+041124:	appsrc/dcfile/dccomb.cc,appsrc/dcfile/dcmulti.cc,appsrc/misc/binpatch.cc,
+	libsrc/include/generic/listfifo.h,listsort.h,libsrc/include/pixeldat/srcsink.h: update to support
+	g++ 3.4, in particular new ANSI C++ template wierdness
+
+041112:	appsrc/acrnema/ancreate.cc,appsrc/dcfile/antodc.cc,dckey.cc,dctable.cc,appsrc/dconvert/pq/pqsplit.cc,
+	appsrc/misc/dumpwhat.cc,jpegsplit.cc,config/Configure,libsrc/include/dctool/attrtag.h,attrtypb.h,
+	libsrc/include/generic/basetype.h,errclass.h,txstream.h,libsrc/src/dcdisp/lutextr.cc,
+	libsrc/src/dconvert/pq/pqhdrc.h,libsrc/src/dctool/attrtypd.cc,attrtyps.cc,binval.cc,strval.cc,
+	tagval.cc,uidgen.cc,libsrc/src/generic/getoptns.cc,libsrc/src/locale/mesgtext.cc,
+	libsrc/src/ourdisp/ourdisp.cc: update to support g++ 3.3, in particular strstream stuff
+
+041111:	libsrc/standard/strval/ct.tpl,mr.tpl: spell fluoroscopy correctly for Value 3 defined term
+
+041031:	appsrc/dcfile/dcuncat.cc,.man,libsrc/include/dctool/uidgen.h: include instance number in concatenation
+	UID and add sameseries option
+
+041031:	appsrc/dcfile/dcmulti.cc: if minimal attributes use zero length Acquisition Duration
+
+041030:	appsrc/dcfile/dcmulti.cc,.man: add ability to force derivation and referenced image sequences to
+	be encoded at per-frame level; also add some more derivation codes
+
+041030:	libsrc/src/dctool/attrmxls.cc,appsrc/dcfile/dcmulti.cc: move Synchronization FoR UID generation into
+	attribute list write, otherwise it may get removed with other UIDs if added earlier
+
+041029:	appsrc/dcfile/dcmulti.cc: portal venous phase precedes systemic venous phase in dimension sort order
+
+041029:	appsrc/dcfile/dcmulti.cc: allow more than one item in functional group sequence that is the
+	target of a dimension, and use the first item only (e.g. for ContrastBolusUsageSequence)
+
+041029:	appsrc/dcfile/antodc.cc: recognize "/1.4:1" pattern for GE spiral pitch factor
+
+041029:	appsrc/dcfile/dcmulti.cc,libsrc/include,src/dctool/uidgen.h,.cc: create Raw Data UID references
+	based on Acquisition Number
+
+041029:	libsrc/src/dctool/attrmxls.cc: include Synchronization FoR in UIDs removed
+
+041029:	appsrc/dcfile/antodc.cc,libsrc/standard/elmdict/elscint.tpl,libsrc/include/dctool/attrtag.h: add more
+	private Elscint CT support
+
+041026:	appsrc/dcfile/dcmulti.cc,libsrc/include,src/uidgen.*: add copy and creation of Synchronization Module
+	and related UID
+
+041026:	appsrc/dcfile/dcmulti.cc: add more convolution kernel group choices and detection when none and localizer
+
+041026:	appsrc/dcfile/dcmulti.cc: allow sort for dimensions on unrecognized non-numerics (hash-like)
+
+041026:	libsrc/standard/elmdict/gems.tpl: DeltaStartTime, RotationSpeed are in seconds, not milliseconds as
+	claimed in conformance statement
+
+041026:	appsrc/dcfile/andump.cc,.man: add -ancreate option to create item and delimiter tags for round trip
+
+041026:	appsrc/dcfile/ancreate.cc,.man: allow for white space, comments and create OB values properly,
+	as well as tidy up man page
+
+041024:	appsrc/dcfile/dcmulti.cc: make default ReconstructionAngle dependent on AcquisitionType
+
+041024:	appsrc/dcfile/dcmulti.cc: make DistanceSourceToDataCollectionCenter from DistanceSourceToPatient if present
+
+041024:	appsrc/dcfile/dcmulti.cc: make DistanceSourceToDataCollectionCenter default to half DistanceSourceToDetector
+
+041024:	appsrc/dcfile/dcmulti.cc: add Optiray/Ioversol to list of contrast agent codes
+
+041021:	libsrc/standard/elmdict/gems.tpl: fix spelling of PeristalticFlag
+
+041021:	appsrc/dcfile/dcmulti.cc: RescaleType HU if CT and !derived, rather than (!(MR and !derived)),
+	and replace equivalents of HU including incorrect spelling of Hounsfield
+
+041021:	appsrc/dcfile/antodc.cc: GEMS DeltaStartTime is in seconds, not milliseconds
+
+041019:	appsrc/dcfile/dcmulti.cc: track and add cardiac and respiratory position indices
+
+041017:	appsrc/dcfile/antodc.cc: add correct attribute for ExposureInuAs, handle string rather than
+	numeric GEMS SpiralPitchFactor, add GEMS DeltaStartTime to AcquisitionTime
+
+041017:	appsrc/dcfile/dcmulti.cc,.man: add IAC anatomic term, round rather than truncate reference datetime
+
+041016:	appsrc/dcfile/dcmvhier.*.script.cc: succeed even if tags are out of order
+
+041016:	appsrc/dcfile/dcmulti.cc,.man: add support to sort dimension of ContrastBolusAgentPhase
+
+041016:	appsrc/dcfile/antodc.cc: Also derive TableFeedPerRotation from Siemens private Feed per Rotation
+
+041016:	libsrc/standard/elmdict/philips.tpl: add some CT Aura private tags encountered
+
+041012:	appsrc/dcfile/dcmvhier.*.script: use mkdir -p not mkdirhier, to work on Solaris
+
+041012:	appsrc/dcfile/dcanon.script: correct fix to match entire UIDs in mapping file only,
+	not sub-strings, to work on Solaris
+
+040930:	libsrc/standard/elmdict/other.tpl: add Lodox Statscan private tags
+
+040929:	appsrc/dcfile/dcdirmk.cc: add manufacturer and model name to series directory record
+
+040925:	libsrc/standard/sopcl.tpl,appsrc/dcfile/dcdirmk.cc: add support for Key Object Selection
+	DICOMDIR record, rather than using generic SR ([bugs.dicom3tools] (000126))
+
+040921:	libsrc/standard/elmdict/dicom3.tpl,module/rt.tpl,strval/rt.tpl: update for final text of CP packet 27
+
+040917:	appsrc/dcfile/dcmulti.cc,.man: separate descending option for stack and main sort,
+	track and use TriggerDelayTime in preference to TriggerTime, track and use
+	TemporalPositionIndex if present rather than deriving it
+
+040917:	libsrc/standard/elmdict/dicom3.tpl: change Overlay Subtype VR from CS to LO (Sup 5)
+
+040916:	appsrc/dcfile/dcdirmk.cc: add additional image level directory keys for enhanced
+	CT, not just enhanced MR
+
+040916:	appsrc/dcfile/dcmulti.cc,.man: change rescale type extraction to not ignore that
+	in source images, and to not insist on HU for CT if derived
+
+040914:	appsrc/dcfile/dcdirmk.cc: look for Verification Datetime nested in Verifying
+	Observer Sequence (fix for [bugs.dicom3tools] (000125))
+
+040914:	libsrc/src/dctool/attrtypv.cc: don't flag timezone offset in DT as an error
+	(fix for [bugs.dicom3tools] (000124))
+
+040914:	libsrc/standard/cond.tpl,module,strval/file.tpl: add registration and key object directory records
+
+040914:	libsrc/standard/cond.tpl,module/softcopy.tpl: don't flag error when bounding box
+	and anchor point, or graphic and text, both present
+
+040914:	libsrc/standard/elmdict,module/softcopy.tpl,appsrc/dcfile/dcdirmk.cc,dcmkpres.cc: rename
+	presentation to content attributes as per Sup 72 registration
+
+040914:	libsrc/standard/elmdict/gems.tpl: add GE Applicare private tags from PDI demo
+
+040910:	libsrc/include,src/attr.h,attrtyps.h,.cc,modulev.cc: when checking Type 1 and 1C
+	attribute values, also check that if multi-valued any value is not zero length
+	once leading padding is removed (e.g., to detect empty values for Patient
+	Orientation, even though a delimiter is present hence VL != 0; counter example
+	is potentially valid empty values for Image Type, which will now be signalled
+	as an error) ([bugs.dicom3tools] (000117))
+
+040908:	appsrc/dcfile/dcmulti.cc,.man: change real world value LUT stuff to all attributes
+	specified on a per-frame basis (encoded in input files), rather than a command
+	line option; includes allowing for missing per frame based on absence of Units
+	(though this may generate illegal IODs since all per-frame functional group
+	macros have to be present for all frames)
+
+040908:	appsrc/dcfile/dcmulti.cc,.man: tidy up some measurement units code sequence stuff
+	related to unary (no units) and to elide braces in meaning derived from value
+
+040907:	appsrc/dcfile/dcmulti.cc,.man: option to add timing attributes to derived images, and
+	tidy up some man page formatting issues
+
+040903:	appsrc/dcdisp/dcdisp.cc: allow overlays in separate group that have odd expected
+	length but padded to even length (as they should be)
+
+040827:	libsrc/src/dctool/attrtypv.cc: report CodeStringFileComponentAttribute maximum length
+	as 8 not 16 (was checking correctly, just message was wrong)
+
+040826:	appsrc/dcfile/dcencap.cc: include SamplesPerPixel in frame size calculation; still
+	potentially problematic if compressed bytes stream larger than uncompressed !
+
+040821:	libsrc/standard: add CPs from Sep 2004 final text package
+
+040817:	libstrc/standard/elmdict/other.tpl: add some private dental tags from ADA demo CD
+
+040802:	appsrc/dcfile/antodc.cc: Solaris needs strchr() not index()
+
+040801:	appsrc/dcfile/dcmulti.cc: add support for enhanced contrast bolus module and
+	contrast usage sequence
+
+040731:	appsrc/dcfile/antodc.cc: create new CT table/pitch/collimation attributes from
+	GEMS private attributes
+
+040731:	appsrc/dcfile/dcmulti.cc: create CT Position Sequence, assuming no zoom and recon
+	and data collection centers equal
+
+040723:	appsrc/dcfile/dcunjpeg.script: add support for color and lossy JPEG, and use both PVRG & IJG codecs
+
+040723:	appsrc/misc/jpegdump.cc: fix hex offset display, and dump APP0 JFIF
+
+040721:	appsrc/dcfile/dcdirmk.cc: use default Instance Number if missing
+
+040721: appsrc/dcfile/dcanon.script: add options to keep uids, private tags and attributes for PET SUV
+
+040718:	libsrc/standard/elmdict/dicom3.tpl: correct VR for FilterMaterial to CS per CP 187
+
+040718:	appsrc/dcfile/dctable.cc: add nofilename option
+
+040718:	appsrc/dcfile/dckey.cc,.man,dctable.cc,.man: allow -k by hex pair
+
+040718: libsrc/standard/elmdict/gems.tpl: update GE CT private tags
+
+040716:	appsrc/dcfile/dcunjpeg.script: quote arguments to allow spaces, quieten, and nodisclaimer
+
+040716:	appsrc/dcfile/dcanon.script: fix to match entire UIDs in mapping file only, not sub-strings
+
+040713:	libsrc/standard/condn.tpl: fix condition on PatientOrientation (was wrong for PET)
+
+040713:	libsrc/standard/elmdict/philips.tpl: update Philips PET private tags
+
+040709:	config/Configure: specifically check for gcc-2.95, not just gcc2
+
+040709:	libsrc/src/dctool/attrmxrd.cc: improve message on in correct group lengths
+
+040709: libsrc/standard/elmdict/gems.tpl: update GE MG private tags
+
+040709:	libsrc/standard/elmdict/gems.tpl: update GE MR private tags
+
+040709:	libsrc/standard/elmdict/gems.tpl: update GE DX private tags as per Revolution XQ/i
+
+040709:	libsrc/standard/elmdict/agfa.tpl: update Agfa CR tags (old as well as new ADC Compact)
+
+040709:	libsrc/standard/elmdict/picker.tpl: update NM private tags as per Odyssey VP and FX Rev 4.1,
+	January 27, 1999,P/N 892086,DICOM software release 1.5 conformance statement from Philips
+
+040708:	appsrc/dcfile/dctopgm8.cc: remove restriction to only single frame images
+
+040708:	appsrc/dcfile/dcmvhier.8only.script: add script to make fileset 8 character limit hierarchy
+
+040708:	appsrc/dcfile/dcanon.script: add script to anonymize a directory of images
+
+040707:	appsrc/dcfile/dcmvhier.datedesc.script: add modality to series label
+
+040618:	libsrc/standard/module/acqctx.tpl,../condn.tpl,../strval/vl.tpl: tidy up conditions on
+	acquisition context value types and incorporate CP 368 (fixed as in 2004 standard)
+
+040617:	libsrc/standard/elmdict/elscint.tpl: add recent Philips/Elscint private data elements
+
+040616:	libsrc/standard/elmdict/gems3.tpl: add recent Lightspeed CT private data elements
+
+040616:	appsrc/dcfile/dcmulti.cc: copy multiframe modules when not recognized new MF SOP class
+
+040615:	libsrc/standard/elmdict/dicom3.tpl,../module/dx.tpl: add Sup 92 data elements
+
+040611:	appsrc/acrnema/andiff.script: quote filename argument strings to allow spaces in filenames
+
+040605:	appsrc/dcfile/dcmvhier.datedesc.script: add new script to build different hierarchy
+
+040529:	libsrc/standard/condn.tpl: correct MultiFrameIODAndNotSpecimen condition for VL
+	images (was incorrectly flagging Anatomic Region Sequence as missing for single
+	frame VLs)
+
+040508:	libsrc/src/dctool/attrtypv.cc: add check for UI with all components == 0 and flag error
+
+040505:	libsrc/standard/elmdict/gems.tpl: add latest NM (from eNTEGRA) and PET Discovery private
+	tags from conformance statement
+
+040505:	libsrc/src,include/dcfile/emdict.*,attrmxrd.cc: detect absence of private owner
+	when reading dataset and warn
+
+040429:	appsrc/dcfile/dcdirmk.cc: use default Modality of "OT" in series directory record
+	if no value found, rather than flagging an error (Type 1 in directory record
+	but not required in SC SOP Class instances)
+
+040423:	appsrc/dcfile/dciodvfy.cc: don't flag pixel data length error when odd length
+	padded ([bugs.dicom3tools] (000113))
+
+040406:	libsrc/standard/*: add CP 392,395,409
+
+040331:	libsrc/standard/*: add Sups 42 and 47 (MPEG and multiframe VL)
+
+040225:	libsrc/standard/sopcl.tpl: add old VL draft image storage SOP classes
+
+040212:	appsrc/dcfile/dckey.cc: stop after start of PixelData, add brief option
+
+040212:	libsrc/src/dctool/attrmxls.cc,attrmxrd.cc: add option to stop reading past a certain tag
+
+040122:	libsrc/src/dctool/attrmxrd.cc: don't just skip pixel data, actually read and discard
+	it, to be sure to detect truncated last attribute
+
+040122:	appsrc/dcfile/dciodvfy.cc: explicitly check that claimed VL for pixel data attributes
+	is appropriate for rows, columns and bits allocated ... does not actually try to read
+	the pixel data to see if the file is too short
+
+040122:	appsrc/dcfile/dciodvfy.cc: check number of waveform channels in waveform sequence matches
+	number of channel definition sequences
+
+040119:	libsrc/standard/elmdict/philips.tpl: remove private SQ elements that have been encountered
+	as SQ before, but don't always seem to be encoded as SQ ... allows the UN code to deal
+	with as fixed or variable as required - UNDO THIS CHANGE - the images causing a problem
+	had been corrupted during conversion with DJ
+
+040118:	appsrc/dcintro/optin.so: fix ignoreoutofordertags option description
+
+040101:	appsrc/misc/jpegsplit.cc: zero pad count value used to construct filenames
+
+031211:	appsrc/dcfile/dcdirmk.cc: add Photometric Interpretation as directory record key
+
+031211:	libsrc/standard/elmdict,module/mr.tpl,appsrc/dcfile/dcmulti.cc: add CP 353 new echo train
+	length attributes for MR, including generating them automatically based on computed value
+	of EchoPulseSequence
+
+031211:	appsrc/dcfile/dcdirmk.cc: add default values if Patient ID, Name or Series Number missing
+
+031206:	appsrc/dcfile/dcencap.cc: pad odd length items
+
+031206:	libsrc/include/pixeldat/unencap.cc: change fragment message to include VL
+
+031119:	appsrc/dcfile/dcmulti.cc: factor out CT from MR stuff and begin work on adding CT; checked
+	that it didn't break nemamfmr; only difference for MR is adding WindowCenterWidthExplanation
+
+031118:	libsrc/standard/*: add Sup 58 LB Enhanced CT, and refactor Enhanced MR accordingly
+
+031116:	appsrc/dcfile/antodc.cc: add some fixes for Toshiba CT images with incorrect column Y
+	sign, as well as detect head/feet first and supine/prone from Toshiba private attributes
+
+031116:	appsrc/dcfile/dcencap.cc: add multi-frame support, to handle the case when
+	pixel data is not compressed but needs to be encapsulated anyway
+
+031116:	libsrc/standard/transyn.tpl: add PixelMedEncapsulatedRawLittleEndian
+
+031015:	libsrc/standard/elmdict/siemens.tpl: update some VRs based on explicit VR from a Siemens
+	Volume Zoom CT MOD (SIEMENS_S5VA40A)
+
+030914:	appsrc/dcfile/dcmulti.cc: add support for inserting metabolite code sequence as per draft CP 386_02
+	and update dictionary accordingly
+
+030914:	appsrc/dcfile/dcdirmk.cc: add ImageComments to spectroscopy directory record 
+
+030913:	appsrc/dcfile/dcmulti.cc: add support for inserting metabolite map sequence
+
+030913:	appsrc/dcfile/dcdirmk.cc: don't assert on icon upsampling, just don't make the icon
+
+030913:	appsrc/dcfile/dcmulti.cc: add nowindow option to not include default values
+
+030806:	appsrc/dcfile/dcdirmk.cc: use name as well as ID to disambiguate patient entity in case ID is missing or empty
+
+030731:	libsrc/standard/strval/charset.tpl: add CP 155 korean, CP 194 thai, CP 252 UTF8 and GB18030
+
+030731:	libsrc/standard/strval/file.tpl: add CP 343 spectroscopy and raw data directory record types
+
+030725:	libsrc/src/dctool/attrmxrd.cc: workaround GE item/sequence delimiter encoding bug in mammo images
+
+030721:	libsrc/standard/elmdict/dicom3.tpl: add CP 340 Scheduled Procedure Step Modification Date and Time
+
+030710:	libsrc/standard/module/base.tpl: Make USImageModule PlanarConfiguration conditional
+	on SamplesPerPixel
+
+030620: libsrc/standard/elmdict/mr.tpl: Correct VR of TagSpacingSecondDimension
+
+030611: appsrc/dcfile/pgxtodc.cc: add pgx to dicom secondary capture tool
+
+030611:	appsrc/dcfile/dcjpeg.script: add JPEG compression script
+
+030611:	appsrc/dcfile/dckey.cc: add decimal output option
+
+030610:	libsrc/include/pixeldat/unencap.h: ignore bad VL in sequence delimitation items
+
+030609:	appsrc/dcfile/dcencap.cc: add encapsulation tool
+
+030531:	libsrc/include/pixeldat,srcsink.h,libsrc/include,src/dctool/attrtypo.*,
+	libsrc/include/dctool/attrtype.h,libsrc/src/dctool/attr.cc,attrmxrd.cc,attrnew.cc:
+	tidy up OF stuff, including swap byte order on write of large with different
+	endian; disable (unused) small OF stuff until swap byte order done there too
+
+030523:	appsrc/dcfile/dcpost.cc: fix cols and rows wrong way around when calculating lengths
+	of rows and cols to use for corners or rectangle
+
+030516:	libsrc/support/elmtojava_DicomDictionary_CreateIEByTag.awk: make sure SOPClassUID is
+	treated specially (i.e. at the instance level)
+
+030516:	appsrc/dcfile/dcdirmk.cc: add ImageOrientationPatient from SharedFunctionGroupsSequence
+	if doing position and MR multiframe (useful for specifying orientation when all
+	frames parallel in order to find reference images)
+
+030508:	libsrc/support/elmtojava_*.awk: update to handle new base class and javadoc 
+
+030501:	config/Configure: add " -Wno-deprecated" flag to g++ to shut up g++ 3
+	complaints about old style headers; still check for and use by
+	preference g++2, since shipped version of 3 with MacOSX is broken
+	and not everyone will have compiled and installed 3.2.3 (which works OK)
+
+030501:	appsrc/acrnema/ancreate.cc,andump.cc,libsrc/include/dctool/attrtypf.h,attrtypn.h,
+	libsrc/include/generic/txstream.h,libsrc/src/generic/txstream.cc,
+	libsrc/src/dctool/attr.cc,attrmxrd.cc,attrtag.cc,attrtypo.cc,attrtypt.cc:
+	because of g++ 3 "feature" that makes does not show "0x" for zero values
+	despite ios::showbase (apparently what the C++ standard says), factor out
+	all hex dumps of values into method in txstream.cc
+
+030501:	appsrc/acrnema/andump.cc: length of hex dump of binary values was incorrect,
+	was 1,2,4 and should have been 2,4,8 (already correct in dcdump.cc)
+
+030430:	libsrc/src/dctool/attrmxls.cc,libsrc/support/condn.awk: remove duplicate default
+	argument declarations (g++ 3 is finicky about this, and it has gone from a warning
+	to an error in 3.2.2, and the C++ standard says duplicates defaults are illegal)
+
+030425:	appsrc/dcfile/dccmp/dcdiff,dccmp.script: quote filename arguments since may contain
+	spaces
+
+030424:	appsrc/dcfile/dccmp/dccmp.script: compare pixel data of two files
+
+030424:	appsrc/dcfile/dcburn.cc: add utility to burn in (first) overlay (6000,xxxx) to pixel
+	data
+
+030424: appsrc/dcfile/dcarith.cc,libsrc/include/pixeldat/srcsink.h,libsrc/src/dctool/attrothr.cc:
+	factor out point filter into position independent and position dependent variants
+
+030412:	libsrc/src/dctool/attrmxvr.cc: add some more XS attributes to change using Pixel Representation
+
+030412: appsrc/dcfile/dcdiff.sh: add -ignoreoutofordertags to use of dccp while finding differences
+
+030403:	appsrc/dcfile/dcmulti.cc: add Referenced and Source Image Evidence Sequences
+
+030402:	appsrc/dcfile/dcmulti.cc: do not copy Laterality in General Series (CP 365) if MF MR
+
+030402:	libsrc/standard/elmdict/mr.tpl: Make LUT Label have VR of SH, as per the CP
+
+030402:	appsrc/dcfile/dcmulti.cc: only add venc stuff if -phasecontrast option
+
+030318:	libsrc/standard/elmdict/siemens.tpl,acrnema.tpl,spi.tpl: more VR updating based on
+	experience with MR sample images
+
+030318:	libsrc/src/attrmxrd.cc: more explicit (sic) message when explicit vr does not
+	match dictionary vr
+
+030315:	appsrc/dcfile/dcmulti.cc: uncouple real world value stuff from rescale stuff,
+	add velocity encoding stuff
+
+030315:	libsrc/include/dctool/attrmxls.h,dcopt.h,libsrc/src/dctool/attrmxls.cc,dcoptc.cc,
+	dcopto.cc,appsrc/dcfile,dconvert/*/Imakefile: add command line options to set values for
+	instance creation date and time and timezone offset to simplify regression testing
+
+030311:	libsrc/standard/elmdict/siemens.tpl,acrnema.tpl,compress.tpl,spi.tpl: update
+	dictionary based on explicit VR received from Leonardo Somatom conversions
+	as well as Leonardo conformance statement
+
+030301:	appsrc/dcfile/dcmulti.cc: add empty per-frame functional group macros
+	when derived frames
+
+030226: appsrc/dcfile/dcmulti.cc: add LUT Label and EXplanation arguments to
+	real world value mapping sequence; not that the VR for LUT Label as
+	added is SH, as per the CP, but the dictionary remains the incorrect
+	SS for now as a reminder
+
+030225:	libsrc/standard/strval/mr.tpl: correct spelling mistake in gradient output
+	type defined term
+
+030225:	appsrc/dcfile/dcdirmk.cc: add extra attributes to directory record for MR
+	multiframe including PixelPresentation and NumberOfFrames
+
+030225:	appsrc/dcfile/dcmulti.cc: add support for minimal attributes, adding just
+	position attributes to derived images anyway, sorting dimensions by Frame Type
+
+030223:	appsrc/dcfile/dc[un]bzip2.script,libsrc/standard/transyn.tpl: add support for
+	private PixelMed transfer syntax fort bzip2 compression along the same
+	principles as deflate (and without the 'BZ' file header bytes)
+
+030222:	appsrc/misc/rawarith.cc: add prediction and reversal based on previous pixel
+	value
+
+030201:	libsrc/src/dconvert/gen,gaw/*.tpl: have rescale type be HU or US, not longer
+	string values
+
+030201:	appsrc/dcfile/dcmulti.cc: add copying of actual rescale attributes into pixel
+	transformation sequence rather than always assuming 1 and 0
+
+030121:	libsrc/standard: add sup 70 clinical trials and 65 chest cad (just sop class)
+
+030114:	libsrc/standard: update code sequence macro to reflect CP324, and then
+	make sure it is used everywhere (note that this removes some of the
+	checks for particular enum/defined coding scheme designators)
+
+021123:	libsrc/include,src/attrmxrd.cc,attrmxls.h,attrype.h,attrtypo.*: add interim
+	OF VR the same as UN VR (probably not right for big endian copy though)
+
+021122:	libsrc/standard/*mr.tpl,cond.tpl,sopcl.tpl: add spectroscopy
+
+021122:	libsrc/standard: tidy up dictionary and modules as per draft 2003
+
+021116:	libsrc/standard/elmdict/dicom3.tpl,security.tpl;module/base.tpl: add Sup 55
+	attributes to dictionary and SOP common, move signature elements
+
+021025:	libsrc/standard/sopcl.tpl,appsrc/dcfile/dcdirmk.cc: add spectroscopy and raw
+	data directory record types
+
+021020:	appsrc/acrnema/ancreate.cc: add FL and FD values specified as floats in {} rather than hex
+
+021017:	appsrc/acrnema/*: add OF support
+
+021017:	libsrc/standard/sopclass.tpl: add spectro, raw data
+
+021017:	libsrc/standard/elmdict/mr.tpl: fix name of SignalDomainColumns
+
+021015:	appsrc/dcfile/rawftodc.cc: add ability to select complex components
+
+021012:	appsrc/dcfile/dcdirmk.cc: add specific character set to all directory records
+
+020929:	libsrc/src/dconvert/gen,gaw: convert variable bandwidth to Hz and double
+
+020928:	appsrc/dcfile/dcstats.cc,.man: add decimal value as well as hex
+
+020928:	libsrc/include/dctool/attrtypf.h: modify creation of float values to handle values
+	less than one - decrement exponent after log2, otherwise mantissa goes -ve (this
+	fixes the problem noted on 020706 with NM image (back to 1.9)
+
+020928:	appsrc/dcfile/dcmulti.cc: do not add acquisition stuff at image and frame levels if
+	derived unless specifically required on command line
+
+020926:	libsrc/src/dconvert/gaw,gen/g*mmsc.cc: assume col direction for freq encoding when
+	unknown in deriving acquisition matrix
+
+020923: appsrc/dcfile/dcmulti.cc: move frame image type sequence to shared if possible
+
+020923:	appsrc/dcfile/dcmulti.cc: fix date/time sort (was using Uint32 entries, unsigned hence
+	always +ve return)
+
+020923:	appsrc/dcfile/dcdirmk.cc: add ImageComments to IMAGE record
+
+020923:	appsrc/dcfile/dcmulti.cc: add real world value mapping sequence
+
+020923:	appsrc/dcfile/raw*todc.cc: add multi-frames, also add scale factor to float
+
+020918: appsrc/acrnema/andiff.script: create similar tool to dcdiff to show DataSetTrailingPadding
+
+020914:	appsrc/dcfile/dcostosr.cc: change rindex() to strrchr() (for Solaris)
+
+020914:	config/Configure,Imake.tmpl;libsrc/src/generic/datetype.cc: use timezone external 
+	variable rather than glibc based tm_gmtoff struct member (for other than Linux
+	and Darwin, e.g. Solaris)
+
+020911:	appsrc/dcfile/dcuncat.cc;libsrc/src/dctool/attrmxls.cc;libsrc/include/dctool/uidgen.h:
+	take InConcatenationNumber into account (if present) when making SOPInstanceUIDs,
+	and make sure InstanceNumber remains the same for all instances of a concatenation
+
+020911:	appsrc/dcfile/dcdirmk.cc: add concatention stuff for IMAGE records if present
+
+020911:	appsrc/dcfile/pnmtodc.cc: require -big or -little when bits > 8
+
+020902:	libsrc/src/dcdisp/rdimage.cc: fails on palette color images since getPixelMap()
+	not implemented in usepal.cc ... this must have been true since early work on
+	optimizing display speed ... not fixed yet :(
+
+020902;	libsrc/standard/elmdict/dicom3.tpl,acrnema.tpl;libsrc/src/dctool/attrmxvr.cc: more
+	work on tidying up LUT VR ... essentially always make it OW as per current PS 3.5
+	rules instead of (erroneously) trying to depend on pixel representation (or not for
+	palette color LUT as in 020815 changes)
+
+020901:	config/Configure: tweak to support MacOS X 10.2 changes (but still doesn't
+	provide good include depend path for gcc version 3 since .h versions of headers
+	no longer included; worse, the version 3 libraries have a problem with 0x padding
+	fixed width hex numbers when the value is 0, so test for gcc2 and g++2 and use
+	them if present instead :) (do not know if this is just a Mac thing or a general
+	version 3 problem)
+
+020816:	appsrc/dcfile/rawftodc.cc: add raw (4-byte) float to DICOM SC utility; also
+	involved moving libsrc/include/dconvert/fltype.h to libsrc/include/dctool/
+
+020815:	appsrc/dcfile/dccomb.cc: combine two images into different pixel value ranges
+
+020815:	appsrc/dcfile/dcmulti.cc: add supplemental color LUT
+
+020813: libsrc/standard/condn.tpl,module/mr.tpl: tidy up checks of real-world conditions
+	(by maing them NoConditions)
+
+020813:	libsrc/src/dconvert/gaw,gen/g*mmsc.cc: assume row direction for phase encoding when
+	unknown (actually col direction for freq)
+
+020811:	libsrc/include,src/dctool/attrmxls.*; appsrc/dcfile/dciodvfy.cc: (finally) deal with
+	making sure that meta-information header SOP Class and Instance UIDs match what is
+	in the dataset, rather than copying (obsolete) information - needed a special check
+	for DICOMDIRs since no UIDs in the actual instance - make them up; add a special check
+	in dciodvfy to make sure that meta-information header values (if present) match those
+	in the dataset (or is a directory)
+
+020811:	libsrc/include/dctool/attrtyf.h: add support for addValue(const char *)
+
+020810: libsrc/src/generic/getopns.cc: kip spaces in getoptions to allow -ve floating point 
+	and integer values
+
+020810:	appsrc/dcfile/dcmulti.cc: MR MF - use AcquisitionDuration and
+	MRAcquisitionPhaseEncodingStepsOutOfPlane
+
+020810: libsrc/dconvert/gen.gaw/g*mmsc.cc: add some MRMF attributes including Acquisition
+	Duration and MRAcquisitionPhaseEncodingStepsOutOfPlane
+
+020809:	libsrc/standard/module/mr.tpl;libsrc/support/*java*.awk: manually add IE to macros;
+	not quite right for some (e.g. Frame Type)
+
+020805:	appsrc/dcfile/dcdirmk.cc: add some new MR specific and general optional keys
+
+020802:	libsrc/support/elmtojava*.awk: add tagByName
+
+020730:	appsrc/dcfile/dcmulti.cc: MR MF - add Frame VOI LUT Sequence based on
+	window center and width racked in single images else default
+
+020729:	appsrc/dcfile/antodc.cc: find private attributes in any block, not just 
+	pre-defined; use for Siemens (only)" antodc.cc
+
+020729:	libsrc/support/module.awk: implement VM="" on Condition="" line and pass the
+	desired multiplicity (or 0 if absent) to verifyXX() (which already had the
+	required support for this in place). Use it in module/mr.tpl for Image and
+	Frame Type.
+
+020728:	libsrc/include,src/generic/datetype.*;libsrc/dctool/attrmxls.cc;config/: add
+	Instance Creator UID, Creation Date and Time and Timezone Offset From UTC 
+	derived from current time
+
+020727:	appsrc/dcfile/dcmulti.cc: MR MF - automatically detect temporal position index
+
+020726:	appsrc/dcfile/dcmulti.cc: MR MF - automatically detect stacks
+
+020725:	libsrc/standard/condn.tpl,module/mr.tpl,appsrc/dcfile/dcmulti.cc: do lossy image
+	compression (and ratio) attributes as per CP319 proposal
+
+020723:	libsrc: add root attribute capability to conditions, to use for new MR macros
+
+020722:	appsrc/dcfile/dcmulti.cc: MR multiframe - earliest acq and content DTs
+
+020721:	appsrc/dcfile/dcmulti.cc: more work on MR multiframe, including dates
+	and times in MR Enhanced Image Module, and only copying specific attributes
+	in specific modules, not everything
+
+020720:	appsrc/dcfile/antodc.cc: add Philips private Cardiac Trigger Time
+
+020720:	appsrc/dcfile/dcmulti.cc: more work on MR multiframe, including Image and
+	Frame Type
+
+020720: libsrc/include/dctool/attrval.h: used to return a value only if VM == 1, this
+	was causing dcdirmk to fail on some potentially multi-valued string attributes,
+	now make it return a value if VM >= 1
+
+020717:	libsrc/standard/,appsrc/dcfile/dcostosr.cc: CP 251, 257, 260, Sup 61
+
+020715:	libsrc/src/dcfile/attrmxrd.cc: work around Philips bug with extraneous Item
+	tags nested inside fixe length Items (there is also a wierd group length tag
+	for the 0xfffe group but that is already ignored)
+
+020707: libsrc/standard/support/elmtojava_CreateIEByTag.awk: constrain a few special
+        cases like StudyInstanceUID
+
+020706:	libsrc/standard/support/elmtojava*: generate java dictionary for pixelmed,
+	including information entity by element
+
+020706:	libsrc/standard/module/mr.tpl: include macros in per-frame as well as
+	shared functional group sequence
+
+020706:	libsrc/include/attrtype.h,attrtypf.h: add support for creation of FD
+	values (crude and not yet well tested), also replaced int with float
+	in single-valued constructor of FL and FD - need to check if this has
+	broken anything (e.g. images/dicom/forjpeg2000/discimg/NM1 (0x0009,0x102e)
+	is now 0 rather than 1.9)
+
+020705:	appsrc/dcfile/dcmulti: start to add support for derivation of functional
+	groups for MR multi-frame
+
+020620:	INSTALL,config/Configure: add support for Darwin
+
+020620:	libsrc/support/*.awk: use "next" rather than "break" (Darwin)
+
+020529:	libsrc/standard: rename realworld value first/last value mapped
+
+020529:	libsrc/standard;,libsrc/src/dconvert/gaw,gen/*mmsc.cc;appsrc/dcfile/antodc.cc:
+	rename phase encoding direction to be in-plane
+
+20518:	config/Configure: gzip best argument needs two hyphens in 1.3.3 in
+	RH Linux 7.3
+
+020518:	libsrc/standard/module/pet.tpl: fix typo in condition in PET Series
+
+020506:	appsrc/dcfile/dcmulti.cc: check for and create multiframe MR and SC 
+
+020504:	appsrc/dcfile/dcmulti.cc: allow source multiframe objects if only 1 frame
+
+020501:	libsrc/standard: add new MR objects (sup 49 final text)
+
+020420:	Imakefile: be more explicit than [A-Z]* due to wierd bash expansion
+	that includes lowercase as well; also explicitly exclude CVS files
+	from archive
+
+020420:	config/Configure: cpp is now cpp0 in gcc 2.96 so use cpp* to generate
+	include paths for make depend phase
+
+020419:	appsrc/dcfile/dcdirmk.*: add default values for missing study attributes 
+
+020404:	appsrc/dcfile/dcdirmk.*: add -f option for file with list of files
+
+020316: libsrc/standard/elmdict/philips.tpl: remove duplicate private tags
+
+020215: libsrc/standard/*: update for 2001 standard changes, including CPs
+	for icon image sequence, digital signatures in SOP common; note
+	that including digital sig attributes as a macro caused dciodvfy
+	to fail on some test images ... implemented in-line as work around but
+	there may be an issue with success propagation from macros (try
+	jpeg2000 CT1 for example)
+
+011006:	appsrc/dcfile/dcdirmk: add command line option to set FilesetID
+
+011006: appsrc/dcfile/dcsrmrg.cc: added utility to merge top-level content
+	items (children of root) of several different SR documents
+
+011006: appsrc/dcfile/dcostosr.cc: copy AccessionNumber, StudyDescriptor
+	and make UNVERIFIED
+
+011002:	libsrc/include/attrtypf.h: add conversion from internal float and
+	other numerics to IEEE to support creation of Graphic Data from
+	within appsrc/dcfile/dcostosr.cc.
+
+011001:	libsrc/include/attrtypf.h: copy algorithms from dconvert/fltype.h
+	here to implement getValue(), and have writeData() use them to
+	dump as floating point values, not binary.as before ... later
+	will need to control text dump form and precision to make regression
+	tests repeat OK on different platforms
+
+011001: appsrc/dcfile/dcostosr.cc: added Osiris overlays to SR utility; note
+	big problem is lack of add/get float values to attributes for use
+	with SCOORDs; parsing of label from osiris into measurements is also
+	pretty horrible :(
+
+011001:	appsrc/dcfile/dcsrdump.cc: add a few more value types and details
+
+010706:	appsrc/dconvert/gen/testy2k.sh: use path to appsrc/misc/binpatch
+	rather than assuming it is installed
+
+010704:	*.*: Convert to standard C++ library when using gcc 3.0: this
+	includes:
+	- revised stream seek behavior (use seekg everywhere not rdbuf.streampos)
+	- no stream read of unsigned char arrays
+	- ios::fmtflags not unsigned long
+	- log2() exists in library (don't use own, e.g. for linux)
+	- stream.clear() takes no argument
+	- strstream.h (deprectated) doesn't include iomanip.h
+	- dec and hex need to be scoped with ios:: (sometimes)
+	- strstream extract to integer doesn't leave stsream.good() (getoptns.cc)
+
+	These changes work with gcc 2.96; still don't work with 3.0 since seekg()
+	doesn't seem to set fail() state when past end of stream :(
+
+010523:	appsrc/dcfile/dcswab.script: add script to swap bytes of pixel data
+	leaving everything else alone (e.g. when transfer syntax doesn't
+	match reality)
+
+010523:	appsrc/dcfile/antodc.cc: handle toshiba files with bad VM
+	on PatientOrientation and ImageOrientation and PixelSpacing
+	(trailing backslash) and missing HighBit
+
+010523:	libsrc/src/dcfile/attrmxrd.cc: if ignore out of order tags
+	don't set good flag false else read eventually fails
+
+010523:	config/Configure: notiny version number for gcc 2.96
+
+010523:	config/,docs/: add docs tree derived from doxygen and graphviz
+
+010429:	appsrc/dcdisp/dcdisp.cc: playing around with windowing dynamically
+	rather than after mouse release (not currently active)
+
+010425:	libsrc/standard: RT Treatment Record
+
+010424:	libsrc/support/condn.awk: include else on test for or
+
+010424:	libsrc/standard: continue working on sup 57 support, especially
+	adding "pseudo" modules to test for conditions on attributes defined
+	in the IODs (rather than the modules), as well as multiframe attribute
+	conditionality (re. frame increment pointer)
+
+010423:	libsrc/standard: update to include CP packets 9, 10, Sups 52,
+	53, 57
+
+010323: appsrc/dcfile/dctopgm8.cc,antodc.cc: add include math.h
+        (failed on RH Linux 7 with gcc 2.96) 
+
+010225: appsrc/misc/jpegdump.cc: start work on dumping JPEG 2000
+        bitstream
+
+010217: libsrc/standard/sopcl.tpl: add old trial SR and waveform
+        storage SOP class UIDs (no support for them in the IOD and
+        module stuff though)
+
+010216: appsrc/dcfile/dcbriggs.cc,dcsmpte.cc: Fix yesterday's changes
+	which broke the explicit specification of options with defaults
+
+010215: libsrc/include,src/attrlsln.h,.cc;libsrc/src/attrmxls.cc;
+        appsrc/dcfile/dcdirmk.cc: finally add a generic length and
+        offset calculation that works for nested sequences, abstracted
+        it into a separate module, and used it both to make DICOMDIRs,
+        add tiff IFDs and to insert group lengths; in the process
+        noticed that UT and UN hadn't been added to the fixed length
+        calculation (that is now in attrlsln.cc)
+
+010215: appsrc/dcfile/dcdirmk.cc: High Bit should be set to 7 not 8
+        in Icon Image Sequences
+
+010215: appsrc/dcfile/dcsmpte.cc: add all defaults just like dcbriggs
+
+010215: appsrc/dcfile/dcbriggs.cc: make it default to 8 bits with
+        minval of 0 and maxval of 2^bits-1
+
+010215: libsrc/standard/condn.tpl,module/file.tpl: add remainder of
+        directory record checks in 2000 standard
+
+010215: libsrc/standard/condn.tpl,module/file.tpl: add checks for SR
+        DOCUMENT directory record ... PRESENTATION already there, still
+        others to do.
+
+010215: appsrc/dcfile/dcdirmk.cc: include content date and time for SR
+        DOCUMENT directory record
+
+010214:	appsrc/dcfile/dcdirmk.cc: create lowest level directory records
+	differently depending on sop class ... i.e. not always images as
+	it was before ... added SR DOCUMENT and PRESENTATION, but still
+	more to do; also encountered limit on length of nested sequence
+	attributes (need to fix this before PRESENTATION referenced seqs
+	can be done correctly). ... also highlighted need for general
+	sequence attribute deep clone method
+
+010214:	libsrc/standard,include,libsrc,support/sopcl*: add a new field
+	of directory record type for each sop class, and add a new global
+	function and table to query to get directory record type based on
+	sop class
+
+010115:	libsrc/src/dcfile/attrmxrd.cc,appsrc/dcfile/acrnema/andump.cc:
+	detect incorrect short form of VL for UT VR that some people have
+	used in tests: rather than freaking give error and continue; based
+	on reserved bytes not being zero (risky) :(
+
+010115:	libsrc/src/dcfile/attrmxrd.cc: propagate warnings from sequence
+	item reads upwards
+
+001223:	dcfile/dcunjpeg.script: add support for 8/16 OB/OW selection, as
+	well as extracting decompressed component file name from JPEG log
+	rather than assuming .0 (not always the case)
+
+001223:	support: update gzip noheader patch to not put trailing crc and
+	length on deflated stream, and to not expect it
+
+001220:	appsrc/dcfile/dcdirdmp.cc: add showrecordinfo option
+
+001220:	appsrc/dcfile/dcdirmk.cc: add options to generate directory records in
+	different orders, to generate test cases to see if DICOMDIR parsers can
+	handle backward as well as forward references
+
+001220: libsrc/standard: further updating of dictionary and IODs for consistency
+	with 2000 standard, as well as addition of missing modules for MWL,
+	MPPS, Storage Commitment (still need to do recent print stuff).
+
+001218:	libsrc/standard: update dictionary and IODs for consistency with 2000
+	standard
+
+001218:	libsrc/standard/Imakefile;libsrc/support/elmtoxml.awk: add script
+	to convert standard tags into XML form of data dictionary, creating
+	libsrc/standard/elmdict.xml
+
+001217:	libsrc/standard/elmdict/dicom3.tpl: Referenced Frame Number VM
+	has changed from 1 to 1-n
+
+001217:	libsrc/standard/transyn.tpl: add JPEG-LS and Deflate UIDs
+
+001217:	appsrc/dcinflate.script,dcdeflate.script: add scripts to create and
+	expand deflated transfer syntax, using patched version of gzip with
+	the -x option to not add/expect the gzip header on the deflated data
+	stream.
+
+001217:	libsrc/../dcoptc.cc,dcopto.*,attrmxls.h: add "-justmeta" option to
+	write only the metaheader and not the dataset during a
+	usualManagedAttributeListWrite()
+
+001217:	appsrc/dcrmmeta.cc: add a new utility to strip the metaheader and
+	copy the dataset (only) to a new file, making use of the mandatory
+	metaheader group length element to skip the metaheader rather than
+	parsing it (and backing up when not a group 2 tag); this is to allow
+	support for transfer syntaxes like deflate that don't have a recognizable
+	tag at the start of the dataset
+
+001205:	libsrc/../dcopti,dcstream.h,cc: use command line options to override
+	metaheader and transfer syntax UID (these options were present, just
+	not being used); propagate new argumets to all utilities that create
+	DicomInputStreams (appsrc/dcfile/* and appsrc/dcdisp/*)
+
+001109: config/Imake.tmpl: add DefineBinaryIOFlags as an option that can be
+	defined in site.def or similar to trigger use of ios::binary while
+	opening files (used on non-Unix systems only) - no idea whether it
+	still works or not 
+
+001013:	libsrc/standard/module/sr.tpl: referenced request seq conditional
+	not required
+
+001002:	libsrc/standard/module/waveform.tpl: correct text annotation
+	condition
+
+001002:	libsrc/standard/elmdict/wave.tpl: correct VR for waveform data
+
+000907:	appsrc/misc/jpegsplit.cc: write SOI to start of next file
+	not end of last !
+
+000823: libsrc/include,src/dctool/attrmxls.*,dcopti.cc,dcopt.h;
+	appsrc/dcfile,dcdisp/*.cc: add "-ignoreoutofordertags"
+	option to assist in debugging out of order tags in objects
+	with complex sequence nesting like SR and waveform
+
+000801:	libsrc/standard: update dictionary for Sup 30 FT
+
+000715:	appsrc/dcfile/dcsrdump: created crude tool to traverse sr tree
+	and dump content in form similar to shorthand in book
+
+000625:	libsrc/src,include/dctool/attrlist.*,attrmxls.*,dicomdir.cc;
+	appsrc/dcfile/dciodvfy.cc: earlier fix to add dictionary
+	for private tags to readable AttributeLists wasn't working
+	for dicomdir.cc ... needed to push the saved dictionary pointer
+	all the way up to AttributeList; this allowed a bit of global
+	tidying up of passing dictionaries around as parameters, since
+	any AttributeList user can now getDictionary(). Also renamed and
+	changed the way ManagedAttributeList was allocating the top level
+	dictionary (use "new" rather than class attribute) for consistency
+	of destructors (added to ~AttributeList).
+
+000625:	config/site.p-def: Use new ID for Implementation Class UID as well
+
+000625:	libsrc/include/pixeldat/rawsrc.h: take into account frames when
+	counting rows (bug limited to 1 frame only) ... thanks Alexandre
+	Guimond
+
+000612:	config/site.p-def: Add new UseClunieID 1.3.6.1.4.1.5962
+
+000609: appsrc/misc/jpegsplit.cc: split a jpeg file that has multiple images
+	(between SOI and EOI markers) into separate files; e.g. to take the
+	output of dcraw from a multi-frame encapsulated image with the frames
+	crossing fragment boundaries, and make individual jpeg files suitable
+	to feed to a jpeg decompressor.
+
+000412:	appsrc/dcfile/dcarith.cc: add scale pixels by a floating point factor.
+
+000403:	libsrc/src/dconvert/pq/pqhdrc.h: change string parsing to handle g++
+	library (not istrstream), search for recognition string, not ***,
+	and change calculation of pixel_offset to handle PQ2000 (use the
+	(data_offset-data_offset_actual) rather than assuming \n=END--\n)
+
+000403:	appsrc/dconvert/pq/pqsplit.cc: change string parsing to handle g++
+	library (not istrstream), and change calculation of copy size to
+	handle PQ2000 (use the (data_offset-data_offset_actual) rather
+	than assuming \n=END--\n)
+
+000327:	appsrc/dcfile/antodc: found a Philips MR (T5) that writes different
+	values for row and col pixel spacing (!@#$) that caused the value
+	computed for ReconstructionDiameter to be wrong also - switch
+	to use private FieldOfView value instead, as well as check for bug
+	in PixelSpacing and correct second value.
+
+000320:	appsrc/dconvert/gen/testy2k.sh: make mktime path relative
+
+000319:	libsrc/src/dctool/attrtypv.cc: checking VR routines were deleting the
+	char * returned by the ValueListIterator - stop this; was manifest
+	by condition not matching SOPClassUID in dciodvfy after loosing
+	StringCopy for Linux; moral of the story, getValue() returns copies,
+	(as does AttributeValue which calls it), but directly accessing the
+	values using a ValueListIterator does not (obviously)
+
+000313:	libsrc/standard/elmdict/sr.tpl: fix Referenced Content Item Identifier
+
+000220:	libsrc/include/generic/endtype.h: possible bug in Linux gcc
+	caused test after cast to fail, causing bytes to be swapped
+	in 16 bit words - worked around by assigning it to something
+	before test. Seems to be fixed in gcc 2.95.2, but leave work
+	around in there anyway for old compilers (and what is shipped
+	with most Linux installs).
+
+000220:	libsrc/include/generic/strtype.h,libsrc/include,src/dctool/attrtyps.h,
+	libsrc/src/dctool/attrtypv.cc:
+	strangeness with destructor of StringCopy in list of values on Linux
+	regardless of gcc version; loose StringCopy and use char * instead and
+	remove the delete[]s ... memory leak that will have to be dealt with
+	later
+
+000212:	appsrc/dcfile/dcarith.cc: add zerovalue option (e.g. to remove pixel
+	padding values from CT images)
+
+000206:	appsrc/dcfile/dcsort.cc: quick hack to add secondary key of SeriesNumber;
+	needed to support dcsub of two series keyed by registered dcsort else
+	alternating images from different series not always sorted in same
+	order even if same primary key; need to make secondary key a selectable
+	option later.
+
+000130:	config/Configure: fixes for Linux and X11F86
+
+000130:	libsrc/include/dconvert/fltype.h: Use FLT_MAX rather than HUGE_VAL for
+	missing infinity (Linux)
+
+000130: appsrc/dcfile/pbmtoovl.cc: read bitplane from BinaryInputStream,
+	not invalid cast to istream that older gcc didn't puke on (but
+	should have) - note that the previous behaviour required byte
+	swapping the input which was odd- mirror this with the current
+	LittleEndian setting - should fix this when updating the softcopy
+	demo tests (which will break if changed now)
+
+000130: libsrc/include,src/dctool/attr*: use Binary not DICOMInputStream
+	for value reads, since only endian not VR is required - this allows
+	cleaner fix to pbmtoovl.cc
+
+000130:	appsrc/dcfile/Imakefile: add test for pbmtoovl
+
+000130:	libsrc/src/generic/datetype.cc: correct test on return value of
+	getDDMMYYFromString()
+
+000129:	libsrc/standard: add draft FT of SR
+
+000129:	appsrc/dcfile/dcsort.cc,dcmulti.cc,dcdirmk.cc,libsrc/src/dconvert/pace:
+	tidy up const stuff for gcc 2.95.2 without -permissive
+
+000126	config/Configure: add -isystem rather than -I for X11 includes if
+	gcc 2.95
+
+000126	appsrc/dcfile/dcsort.cc: add -show option to show value of sort key on index 
+
+000126	appsrc/dcfile/dcsort.cc: add Frame of Reference UID check, and make
+	-k synonym for -sortby option
+
+000107	libsrc/src/dctool/attrmxrd.c: when a new sequence item is encountered,
+	create a new data dictionary attached to the item list to allow new set
+	of private creators (ReadableAttributeList::readNewSequenceAttribute);
+	before it was just passing on the main dictionary from the parent list;
+	this does not cause overhead for the standard dictionary because the
+	ElementDictionary constructor already uses reference counting to avoid
+	this.
+
+000107	libsrc/src/dctool/attrseq.cc: change TextOutputStream& SequenceAttribute::write()
+	to use the item specific dictionary - involves downcasting the AttributeList
+	to a ReadableAttributeList - should really add getDictionary() as a method
+	to AttributeList (and return null if none, and then use parent's dictionary)
+
+991222	appsrc/dcfile/dcsub.cc: subtract two 16 bit files
+
+991215	libsrc/support/modtype.awk: support macro as well as module
+
+991215	libsrc/standard: update data dictionary for normalized stuff such
+	as PPS
+
+991215	config/Configure: add -fpermissive to g++ else 2.95.2 under Solaris 8
+	beta fails on Xlib.h without type declarations
+
+991213	appsrc/dcfile/dcdiff.script: compare the dumps of two files
+
+991127	appsrc/dcfile/antodc.cc: more work on Siemens AcquisitionMatrix
+	and add PhaseEncodingDirection and NumberOfPhaseEncodingSteps;
+	still question about Fourier Lines Nominal - phase or freq ?;
+	checked PhaseEncodingDirection with image appearance motion
+	artifact - ok
+
+991127	libsrc/src/dconvert/gen,gaw/g??mmsc.cc: add AcquisitionMatrix and
+	NumberOfPhaseEncodingSteps and correct PhaseEncodingDirection
+	to use freq_dir not swappf
+
+991101	libsrc/standard/: add LB of Waveform Sup 30
+
+991101	libsrc/dconvert/: update Image Date/Time to Content Date/Time
+
+991029	libsrc/standard/: add LB of SR Sup 23
+
+991022	libsrc/standard/: add rev 8 of SR Sup 23
+
+991020	libsrc/standard/elmdict: make VRs consistent with what Easyvision
+	writes on CD for private Philips elements and some SPI, retired ACR-NEMA
+
+991019	appsrc/dcfile/antodc.cc: make flip angle from Philips MR private
+
+991019	appsrc/dcfile/antodc.cc,libsrc/src/generic/datetype.cc: fix all
+	times in dataset to handle Philips MR hh:mm:ssff case (and update
+	getHHMMSSFromString() to handle fraction without . as well as
+	handle no delimiter at all case)
+
+990928	appsrc/dcfile/dcmkpres.cc: add softcopy voi lut sequence to the
+	top level attribute list (!)
+
+990927	appsrc/dcfile/dcmvhier.uid.script: add script to use UIDs rather than
+	study ID and series number for when these are absent or not unique
+	(e.g. Philips AVEU)
+
+990927	appsrc/dcfile/antodc.all.script: always remove Referenced/Source Image
+	Sequence and Icon Image Sequence
+
+990927	appsrc/dcfile/antodc.all.script: do NOT removeinstanceuid because
+	if converting existing DICOM they may be the only series disamiguators
+
+990927	appsrc/dcfile/antodc.all.script: exclude hidden (.) files
+
+990927	appsrc/dcfile/antodc.cc: rewrite image position/orientation(patient)
+	to avoid problems with scientific notation
+
+990914	config/Configure: update some Linux options (log2, gethostid)
+	based on experiments with mklinux DR3
+
+990907	appsrc/dcfile/antodc.cc: try to construct orienation and position
+	from private Philips MR attributes (in exported ANI format even
+	on recent systems like NT5.3)
+
+990907	libsrc/src/dctool/attrmxvr.cc: add SmallestValidPixelValue and
+	LargestValidPixelValue to XS attributes that get fixed up by
+	PixelRepresentation (encountered them in Philips NT5.3)
+
+990905	libsrc/src/dctool/dcattrv.cc: UI verification was failing to
+	detect leading zeroes and empty components
+
+990905	libsrc/src/dctool/dcattrv.cc: ST verification was wrong (<=64
+	and no control chars rather than <=1024 and control chars)
+
+990903	appsrc/dcfile/dcmvhier.script: use BADPAITENT rather than abort
+	if no patient ID and name
+
+990809	appsrc/dcfile/antodc.cc: revisit Series Number generation again -
+	use Acquisition Number for Siemens CT even if Series Number is
+	present but 1 (a la Philips MR), but only if "reasonable" i.e. <100
+	(otherwise had problems with very large different numbers per image
+	with old somatom plus images)
+
+990803	appsrc/dcfile/rawtodc.cc: add byte offset command line parameter
+
+990802	libsrc/standard/elmdict/papyrus.tpl,libsrc/support/elmdict.awk,
+	libsrc/src/elmdict.cc,attrtag.cc: support for dumping Papyrus 60xx
+	private annotations, including fix to Tag::getRepeatingBase() (was
+	using %1 instead of %2 !!)
+
+990722	libsrc/standard/elmdict/: clean up various typos
+
+990722	config/*,libsrc/include/basetype.h: add gethostid use/prototype support
+
+990722	INSTALL, config/site.p-def: add UseClunieQI2ID
+
+990721	appsrc/dcfile/antodc.cc: revisit Series Number generation again -
+	use StudyID for Siemens MR, and Acquisition Number for Siemens
+	CT even if Series Number is present but 1 (a la Philips MR)
+
+990721	appsrc/dcintro/dcintro.man: add -stamp example using date and
+	process number
+
+990719	appsrc/dcfile/antodc.cc: copy private philips slice number into
+	instance number even if present (i.e. overwrite)
+
+990716	libsrc/standard: update for letter ballot text of Sup 33
+
+990716	libsrc/standard: update for final text of Sup 15
+
+990716	libsrc/standard: clean up and add some private elements
+
+990716	libsrc/standard: put old acrnema and spi stuff LO back to LT
+
+990707	appsrc/dcfile/antodc.cc: revisit Series Number generation, and
+	use Study ID for all Siemens, and Acquisition Number for Philips
+	MR, as well as incorporate Philips private Dynamic Scan Number
+	in Series Number (since same value for private Slice Number
+	used to make Instance Number)
+
+990707	appsrc/dcfile/dcmvhier*.script: add check for Warning as well
+	as Error in grep; disambiguate overwrites with counter rather
+	than abort
+
+990622	appsrc/dcfile/dcdirmk.cc: add -novalidatename option to make it
+	more useful for validating patient/study/series keys of sets of images
+	even though filenames are too long or have extensions
+
+990622	libsrc/standard: update VL as per letter ballot text
+
+990622	libsrc/standard/module.tpl,compiod.tpl,strval.tpl: split into separate
+	files per version for various parts/extensions and reassemble on make
+
+990618	libsrc/src/generic/datetype.cc: constructor from string wasn't handling
+	purely numeric (undelimited) strings (e.g. good dicom date strings),
+	so add some special cases for now ... could do better later :(
+
+990618	appsrc/dconvert/genesis/Imakefile,testy2k.sh: add date tests based
+	on patched source images
+
+990618	support/mktime.cc: add utility to use mktime(3) to get unix seconds
+	from yyy/mm/dd/hh/min/ss
+
+990618	libsrc/include/dconvert/dateconv.h: unix: make leap year handle %400
+	for y2k (affects genesis)
+
+990618	libsrc/include/dconvert/dateconv.h: unix: fix day numbering from 0 not
+	1 (affects genesis)
+
+990618	support/testapp: create missing testlog dir on create, not compare
+
+990618	appsrc/misc/binpatch.cc: add integer value patch as well as string,
+	and add tests to see if it works
+
+990618	libsrc/standard: split elmdict.tpl into separate files per version
+	and vendor and reassemble on make
+
+990609	libsrc/standard/condn.tpl: clean up PatientOrientation condition to
+	extend exhaustive list of images to more recent - need to check PET
+	and VL
+
+990609	libsrc/standard/*.tpl: update codes for Sup 32 Final Text
+
+990609	appsrc/dcfile/antodc.cc: assume supine and head first if not
+	otherwise detectable
+
+990609	appsrc/dcfile/antodc.cc: Patient Position - detect supine on
+	truncated to 4 SPI values e.g. SUPI (?Pyramid)
+
+990527	libsrc/dctool/attryps.cc: see atof not atod even for integer getval
+	in order to handle exponential notation (e.g. in window width/center)
+	which are DS VR
+
+990527	appsrc/dcfile/dcarith.cc: generalize to specify operation on command
+	line
+
+990524	libsrc/standard/elmdict.tpl: tidy up some Philips private elements
+	for CT and MR
+
+990520	appsrc/dcfile/dcarith.cc: do single point transform arithmetic on
+	a dicom image ... also involved adding insertPixelPointTransform()
+	method to OtherUnspecifiedLargeAttributeBase, using it in writeData(),
+	and adding filter template PointFilter<Uint16,Uint16> to srcsink.h
+
+990517	libsrc/src/dconvert/pq/*: update to handle leading garbage before
+	header (depends on how files were extracted from tar like file
+	on tape), as well as support later PQ models (e.g. spiral IMTYPE)
+	and clean up pilot vs. axial diameters.
+
+990517	appsrc/dcfile/antodc.cc: clean up CT Rescale Slope/Intercept
+	since too long on some Somatom
+
+990517	appsrc/dcfile/antodc.cc: use Acquisition Number for missing
+	Series Number only for MR (since some Somatom increments per
+	image or two images)
+
+990427	appsrc/dcfile/antodc.cc: fix typo that was causing "null" in
+	StudyID if StudyTime absent
+
+990513	appsrc/dcfile/antodc.all.script: add -removeprivate for all
+
+990427	appsrc/dcfile/antodc.cc: if no Study ID, make one from Study
+	Date and Time
+
+990427	appsrc/dcfile/antodc.cc: create series number from acquisition
+	number if study ID not found
+
+990423	appsrc/dcdisp/dcdisp.cc,libsrc/include,src/rdgray,rdimage.*: add
+	default to ignore Pixel Padding Value when computing image
+	statistics for auto window, and "ignorepadvalue" option to dcdisp
+	to turn this feature off; update man page (long overdue)
+
+990401	appsrc/dcfile/dccp.cc: add "ignorereaderrors" option to copy
+	anyway (e.g. to clean up if trailing garbage)
+
+990331	appsrc/dcfile/dctopgm8.cc: make 8 bit pgm file (e.g. for conversion
+	to GIF) using strategy copied from dcdisp (perhaps more complex than
+	necessary but wanted consistent pipeline).
+
+990329	appsrc/dcfile/antodc.cc: use BaseRawMatrixSize not AcquisitionColumns
+	to derive phase encoding count in AcquisitionMatrix - AcquisitionColumns
+	seems to always be a factor of two greater than shown on film
+
+990329	appsrc/dcfile/antodc.cc: add exposure/time/current conversions
+
+990331	appsrc/dcfile/dctopgx.cc: make PGX file (8 or 16 bit grayscale
+	signed or unsigned litte or big endian (a la PGM) as used in
+	core experiments JPEG2000 VM3.2A.
+
+990211	libsrc/include/dctool/attrtype.h,libsrc/src/dctool/attrmxrd.cc:
+	increase LARGESTOTHERDATATOKEEPINMEMORY to 524288 since using
+	overlays a lot and getValue() not implemented for large other base
+
+990211	appsrc/dcdisp/dcdisp.cc: overlays from 0 to <= 1E not < 1E - was
+	causing "activated" for plane 15 to be uninitialized (and hence
+	sometimes erroneously on)
+
+990210	appsrc/dcfile/dcpost.cc: post localizer with lines in overlay
+
+990210	appsrc/dconvert/pq: convert Picker PQ CT to DICOM
+
+990121	appsrc/dcfile/antodc.cc: complete Overlay Module if present but
+	attributes missing (eg. Siemens Somatom CT)
+
+990121	appsrc/dcfile/antodc.cc: if no Bits Allocated make from Bits Stored
+
+990118	appsrc/dcfile/dcmvhier.script: add ".dcm" suffix
+
+990118	appsrc/dcfile: add some ".all" scripts for antodc, dcunjpeg
+
+990115	libsrc/dcdisp,ourdisp;appsrc/dcdisp: turn off debugging and
+	timing messages
+
+990112	libsrc/standard/elmdict.tpl: make DS not IS VR of some guessed Philips
+	MR private elements
+
+990111	appsrc/dcfile/antodc.cc: if no image orientation/position (early
+	GBS III) then guess it from patient orientation/(slice) location
+
+990106	libsrc/src/dcfile/attrmxrd.cc: support GE bug in skip encapsulated
+	so that doesn't return can't read tag error after skipping wrong
+	length and not recognizing wrong sequence delimiter item - allows
+	dccp to succeed in dcunjpeg.script
+
+990104	libsrc/include/pixeldat/unencap.h: swap item fragment VL bytes when
+	GE tag delimiter byte order bug is present
+
+981222	appsrc/dcfile/antodc.cc: copy private philips slice number into
+	instance number if absent
+
+981222	appsrc/dcfile/Imakefile: move script isntall later so doesn't become
+	default
+
+981218	appsrc/dcfile/dcmulti.cc: add utility to concatenate single frame files
+	into (nonencapsulated) multiframe files, and sort slices by position,
+	orientation, or other numeric parameters (generates non-standard
+	SOP Classes)
+
+981214	appsrc/dcfile/dctable.cc: add utility to dump attribute values into
+	tab delimited table (eg. for spreadsheet)
+
+981118	*/dconvert/himr: convert hitachi mr ... image plane stuff still
+	needs a lot of work
+
+981109	appsrc/dcfile/dcmvhier.script: add script that creates patient/study/
+	series/image hierarchy of DICOM files
+
+981109	appsrc/dcfile/antodc.cc: copy study into series level attributes
+	if no series level (eg. Siemens MR)
+
+981030	appsrc/dcfile/dcmkpres.cc: add linear lut generation
+
+981029	libsrc/src/dctool/dcopto.cc: make default transfer syntax explicit
+	value representation if not specified
+
+981029	appsrc/dcfile/dcmkpres.cc: add utility to create presentation
+	states that reference an image
+
+981029	libsrc/standard/*, et al: ImageNumber becomes InstanceNumber
+
+981029	libsrc/standard/*: add support for frozen sup 33
+
+981028	libsrc/src/generic/getoptns.cc: fix bug that was invalidating leading
+	'-' in option arguments, and allow leading '-' on float args
+
+981027	appsrc/dcfile/antodc.cc: add utility to convert ACR-NEMA or SPI
+	to dicom - currently setup for CT and MR esp. Siemens - special
+	attention to image orientation and position
+
+981027	libsrc/src/dctool/attrmxls.cc: add empty Accession Number with UIDs
+
+981027	libsrc/src,include/dctool/dcopt*.*;appsrc/dcfile/*: add option to
+	suppress use of lengthtoend on read (which is now default)
+
+981015	libsrc/src/dconvert/gen,gaw/genmmsc.cc: make bit depth always 16
+
+981015	libsrc/src/dconvert/gen,gaw/genmmsc.cc: make Filter Type <= 16 chars
+
+981010	appsrc/misc/rawnjl2.cc: update to match DIS N703 document and
+	test against HP LOCO 0.90, add man page, command line options
+	and man page.
+
+980928	libsrc/standard/condn,iodcomp.tpl: DX Positioning is U not M
+
+980926	libsrc/standard,support/module.*,cond.*;libsrc/src/dctool/condn.cc:
+	add ElementPresentAbove/Within capability to conditions to better
+	validate Intra-oral attribute.
+
+980925	libsrc/standard/module.tpl: add dummy 1C Never condition to check for
+	toplevel AnatomicRegionModifierSequence in DXAnatomy to warn about
+	mistake in Sup 32.
+
+980920	libsrc/include/pixeldat/briggsrc.h and appsrc/dcfile/dcbriggs.cc: add
+	ability to generate arbitrary sized patterns, and do signed and invert.
+
+980913	libsrc/include/pixeldat/briggsrc.h and appsrc/dcfile/dcbriggs.cc: add
+	capability to generate 8 target briggs pattern for various bit
+	depth unsigned from minimum to maximum specified values.
+
+980824	appsrc/dcdisp/dcdisp.cc: fix bug from VOI LUT stuff that broke WW/L
+
+980820	appsrc/dcfile/dclutdmp.cc: add utility to dump VOI LUT
+
+980818	libsrc/include/dcdisp/usegray.h,rdgray.h,rdimage.h
+	libsrc/src/dcdisp/usegray.cc,rdgray.cc,rdimage.cc
+	appsrc/dcdisp/dcdisp.cc: add support for VOI LUT
+
+980817	libsrc/src/dctool/attr.cc,attrnew.cc,attrmxrd.cc,
+	libsrc/include/dctool/attrmxls.h,attrtype.h,
+	appsrc/acrnema/ancreate.cc,andump.cc: add support for UT VR
+
+980814	libsrc/standard/elmdict.tpl: add more Senovision private tags
+
+980807	libsrc/standard/module.tpl: fix incorrect mammo image types
+
+980807	appsrc/acrnema/ancreate.cc: add sequence item commands
+
+980806	libsrc/include/pixeldat/smpte*.*: generate from algorithm for any
+	row and column size ... slow but effective
+
+980713	appsrc/acrnema/andump.cc: add ability to dump FL value (but not FD)
+
+980713	libsrc/standard,support/strval.*: support zero length strvals in order
+	to handle DX Image Type 3rd value for dciodvfy
+
+980708	appsrc/misc/rawarith.cc: Add support for signed, clip and mask
+
+980707	appsrc/dcdisp/dcdisp.cc: Add support for displaying 60xx,3000 overlays.
+
+980707	libsrc/src&include/ourdisp/ourdisp.*: Add OurWindowImage::putPoint() to
+	support overlay drawing, and explicitly set foreground/background for
+	imagegc rather than using default graphics context.
+
+980613	appsrc/dcfile/pbmtoovl.cc: Overlay Origin is 1\1 not 0\0
+
+980612	libsrc/standard/elmdict.tpl: add private Senovision 02 tags
+
+980612	libsrc/standard: add DX letter ballot objects
+
+980612	libsrc/dctool/attrmxrd.cc: correct high bit checking to warn if
+	greater than bits stored-1 and change if greater than bits allocated-1
+	(was actually checking wrong because bits stored-1 wasn't in
+	parentheses)
+
+980601	appsrc/dcfile/pbmtoovl.cc: add standalone option with addition
+	of all necessary attributes, as well as force VR of overlay
+	to always be OW and even length VL
+
+980601	config/Configure,Imake.tmpl: Add Xext to library load paths to
+	support shared memory extension
+
+980601	libsrc/src&include/ourdisp/ourdisp.*: add support for X MIT-SHM
+	extension to speed up put'ing X images - dramatically improves
+	the put (down to a few mS) but only works for smaller images
+	(else exceeds shared memory limit and falls back to normal put
+	that uses over-the-wire protocol). One can change /etc/system
+	on Solaris to increase shminfo_shmmax to avoid this if you want.
+	See INSTALL. Once this was done for 4.5k*3k mammo, put went from
+	2.8 secs to 1 or 2 mSecs !!!
+
+980531  libsrc/src&include/dcdisp/rdimage.*,rdgray.*,usegray.*: optimize
+	inner loops of pixel indexing and separate file read from remap
+	on window level/width by caching whole (full depth) image - file
+	read on 4.5k*3k mammo still takes 30secs but rewindow takes 2.2 sec
+	for remap and 2.8 sec for X put, rather than total of 50 secs each
+	time - on smaller images window op is nearly instantaneous - 512
+	square is 150mS. The pixel indexing was optimized by using LUT
+	directly not via virtual call, 8 bit rather than 16 bit LUT,
+	using pointer end check rather than counters (huge gain),
+	and unrolling loop for case of mod 8 row length.
+
+980530	libsrc/src/dconvert/shim/shimptrs.h: use byte not _B extraction of
+	pixel data offset pointer since previous casts break gcc 2.8.1
+
+980519	appsrc/dcfile/pbmtoovl.cc: create standalone overlay from PBM
+
+980519	appsrc/dcfile/dcmerge.cc: merge two DICOM datasets into one
+
+980519	dcopt.h/dcopti.cc: add 2nd opener constructor for use without cin
+
+980519	config/Configure: quote depend path includes to avoid imake/cpp
+	substitution of host and os macros
+
+980405	support/testapp.sh: add test for stdin/stdout filter
+
+980405	appsrc/simple: port all over from old dicom3tools version
+
+980405	config and libsrc/include/generic/datetype.h: Add option to
+	define DEFAULTGUESSEDDATEORDER (defaults to mmddyy). Override in
+	config as "DefaultGuessedDateOrder".
+
+980405	libsrc/src/dctool/attrtypd.h: create new module to handle data/time
+	constructors previously in attrtype.h, add make them check date
+	time value is good else (quietly) add zero length value instead.
+
+980405	libsrc/include/dctool/attrtype.h: move data/time constructors outline
+
+980405	libsrc/include,src/generic/datetype.h,.cc: better error handling
+	and propagation; Y2K changeover 1910
+
+980405	tidy up examples in man pages
+
+980405	libsrc/include/pixeldat/smptesrc.h and appsrc/dcfile/dcsmpte.cc: add
+	capability to generate smpte pattern for any combination of bit
+	depth signed or unsigned from minimum to maximum specified values.
+
+980314	appsrc/dcfile/dctopnm: add a quick and dirty dctopnm based on
+	dctoraw ... it checks byte order, rgb interleaved etc but will
+	not convert them.
+
+980216	libsrc/src/dconvert/gaw,gen: check height/width in image header non-zero
+	else use CT/MR - Synergy broke this - pixel data offset is still not
+	right
+
+980207  libsrc/src/dctool/attrnew.cc: allow OB,OW and UN as well
+
+980206  appsrc/misc/dumptiff: renamed from tiffdump to avoid conflict
+	with Sam Leffler's utility of the same name from the libtiff
+	kit.
+
+980205	appsrc/*,dctool/attrmxls.h,.cc: add ability to write TIFF IFD in
+	DataSetTrailingPadding attribute (works only if no undefined
+	length attributes like sequences)
+
+980205	dctool/dcstream.h,.cc: add pointer to TIFF IFD in metaheader, also
+	made sure NOT to call writing writingMetaHeader() at the time of
+	initializeTransferSyntax() ... the offset isn't known yet ... this
+	is the caller's responsibility before doing any actual writing.
+
+980205	generic/bnchar.h: some generic unpacking/packing byte order functions
+
+980205	dctool/dcopt.h,dcoptc.cc,dcopto.cc: options to control TIFF
+
+980205	libsrc/src/dctool/attrnew.cc: allow addition of Sequence Attribute
+        (found when command line delete of sequence failed)
+
+980105	libsrc/include/dctool/convtype.h: add sign extension to make
+	safe when actual return type is longer, eg. on 64 bit alpha
+
+980105	libsrc/src/dctool/attrmxrd.cc: undefined length + UN is assumed to
+	be SQ (doesn't make any sense otherwise)
+
+980105	libsrc/src/attrtyps.cc: test against 0xffffffff not INTMAX (fails
+	on alpha 64 bit native)
+
+980101	config/Imake.tmpl: add support to pass C_DEBUGFLAGS and 
+	CPLUSPLUS_DEBUGFLAGS and clean up Imakefiles to not wipe out
+
+971229	libsrc/standard/elmdict.tpl: make (0008,0103) SH not CS
+
+971226	libsrc/standard/*: add waveform frozen draft and update VLI frozen
+	draft definition - also added part 6 from SR frozen draft
+
+971121	support/testapp: make stdout binary cmp not string diff
+
+971121	appsrc/dcdisp/dcdisp.cc: add "writeimage" to stdout and include in test
+
+971121	libsrc/src/ourdisp/ourdisp.cc: add write8BitDataTo...Stream()
+
+971121	appsrc/dcdisp/dcdisp.cc: add "ignorewindow"
+
+971121	libsrc/src/ourdisp/ourdisp.cc: mapwidthmin to 0 not 1
+
+971121	libsrc/src/dcdisp/usegray.cc: setImageLevelWidth clamp BOTH lbottom
+	and ltop to mingray AND maxgray else lbottom can go > ltop if
+	fed really screwy values (eg. on command line or in object)
+	
+971120	appsrc/dcdisp/dcdisp.cc: use BitsAllocated not BitsStored for 8 vs. 16
+
+971119	libsrc/src/dcdisp/rdimage.cc: warn if stats sign different but don't
+	override what was specified in object (or overridden on command line)
+
+971119	appsrc/dcintro/dcintro.man: add comment about hyphen in replace string
+
+971002	appsrc/dcfile/dcdirmk.cc: Check Patient, Study, Series values match
+
+971002	appsrc/dcfile/dcdirmk.cc: Missing Image Number is error not assert(0)
+
+970930	libsrc/standard/module.tpl: US Image Planar Config is Type 1 not 1C !!
+
+970919	libsrc/include/dcfile/attrtypn.h: no sign extension of 2 byte text write
+
+970919	libsrc/standard/elmdict.tpl,sopcl.tpl: add ARM, new DLX private stuff
+	(including private overlay elements ... that will be interesting)
+
+970916	libsrc/include,src/dctool/dcopto.cc,h,dcstream.cc,h: add option to
+	write implicit VR metaheaders (old draft ... used inside SdC).
+
+970912	appsrc/acrnema/: add test for UN and private element create/copy/dump
+
+970912	libsrc/src/dctool/attr.cc: write UN VL in long form
+
+970912	appsrc/acrnema/ancreate.cc: write UN VL in long form
+
+970912	libsrc/src/dcdisp/rdimage.cc: color by plane unsigned char to mapPixel()
+
+970909	libsrc/src/dctool/attrmxrd.cc: handle UN VR that changes to different
+	VR based in dictionary but still need to read UN style VL !!
+
+970909	libsrc/src/locale/mesgtext.awk: add 0,0 to end of table (caused seg flt)
+
+970909	libsrc/standard/elmdict.tpl: update some GEMS MR private attributes
+
+970909	libsrc/src,include/dcdisp/rdrgb,rdimage.h,cc: add 24 bit color by plane
+
+970905	config/Imake.tmpl: add Templates.DB to FilesToClean in Imake.tmpl (SC 4.0)
+
+970905  libsrc/src/dctool/attrmxrd.cc: use explicit VR not dict if
+	mismatch (was being left unfilled leading to cascade of
+	warnings and loss of attribute)
+
+970905  libsrc/src/dconvert/gen/genmmsc.cc,
+	libsrc/src/dconvert/gaw/gawmmsc.cc,
+	libsrc/src/dconvert/somp/sompmmsc.cc:
+		fix IntegerStringAttribute ambiguities with SC 4.0
+
+970826  config/Configure: fix source browser flags for -ge 3 version
+
+970820	libsrc/standard/*.tpl: revise VLI for frozen draft version
+
+970808	config/Imake.tmpl: add ii_files to FilesToClean in Imake.tmpl (SGI CC)
+
+970808	appsrc/dcfile.cc,libsrc/src/dctool/attrmxrd.cc: when re-reading
+	tag after changing from meta-header to dataset TS, only do this
+	once ... previously checking and seeking back everytime exposed
+	native SGI Irix CC bug in seek code - doesn't seem to happen
+	early in stream.
+
+970805	config/Configure,Project.p-tmpl,Imake.tmpl: parameterize lbX11.a
+	dependency
+
+970805	config/Configure,Project.p-tmpl: add bin & lib platform dirs
+
+970805	config/Configure: add Irix native CC stuff
+
+970709	libsrc/standard/elmdict.tpl: add revised DRS private VRs (V2.0 CS)
+
+970606	libsrc/standard/cond.tpl: add conditions dependent on sequences.
+
+970523	libsrc/standard/cond.tpl: add multi-value check for MR attributes.
+
+970523	libsrc/src/dcfile/attrtypv.cc: add check for IS > 2^31-1
+
+970519	config/Configure: add path/booleans for native Irix CC.
+
+970505	libsrc/standard/condn.tpl,module.tpl: fix NM Phase Trigger Vector
+        condition.
+
+970425	libsrc/include/dctool/attrtypf.h, etc: add read/write FL/FD support.
+
+970425	libsrc/src/dctool/attrmxrd.cc: add specific message that some VRs
+        are unsupported (specifically FL and FD).
+
+970423	libsrc/*/tagval.*,attrvrfy.cc,attr.h: add support for tag
+        enumerated values.
+
+970423	libsrc/standard/strval.tpl: add ISO_IR 13 and cleanup Specific
+	Character Set (had spaces not tabs).
+
+970423	libsrc/standard/module.tpl: fix Scan Options defined terms in
+	XRay Image to be OK for multiple values.
+
+970423	libsrc/standard/*.tpl: use more NoConditions, eg. for Specific
+        Character Set.
+
+970423	libsrc/standard/*.tpl: fix US Region Calibration conditions and bug
+        in enum values for PixelComponentPhysicalUnits
+
+970423	libsrc/src/dctool/attrmxrd.cc: Add hardwired check for File
+        Meta Information Version of 0x00,0x01
+
+970422	libsrc/standard/*.tpl: add PET stuff from final text (same as lb) draft
+
+970421	libsrc/support/module.awk: add item separator during write
+
+970421	libsrc/standard/*.tpl: add RT stuff from letter ballot draft
+
+970403	appsrc/misc/dcunmeta: add command to remove metaheader
+
+970402	libsrc/standard/elmdict.tpl: add CP72 (0040,0020)
+
+970219	libsrc/standard/elmdict.tpl: add GE CTI and MRLX private dictionaries
+
+970219	libsrc/src/dctool/attrothr.cc,transyn.cc: add pixel endian support
+        to large pixel attribute (cp14), works for read so far.
+
+970217	libsrc/standard/transyn.tpl: add GE big endian pixels, and begin
+        to add support for PixelEndian stuff everywhere
+
+970210	libsrc/standard/sopcl.tpl: add new (real) UIDs for VLI and remove
+	Accession SOP class
+
+970125	libsrc/standard/transyn.tpl: add bad transfer syntax to read bad
+	ecr demo dir to allow further testing (temporary) removed 970210
+
+970125	libsrc/src/dctool/dicomdir.cc: identify 1st record of
+	directory record entry by any attribute ... not just next
+	record pointer ... allows for group length to be present
+
+970113	libsrc/src/dctool/dcstream.cc: initializer bug ... not setting
+	TransferSyntaxToWriteMetaHeader to 0 when not using metaheader -
+	manifest as core dump on Solaris during destruction.
+
+970113	libsrc/src/dctool/attrtypv.cc, etc: validate UID components,
+	not zero length, no leading zeroes.
+
+970113	libsrc/src/dctool/attrmxls.cc, etc: add addlengthtoend support
+
+970113	libsrc/src/dctool/dcopto.cc: add noadddisclaimer to options usage
+
+970106	appsrc/dcfile/dcdirmk.cc: validate filename, check for null type 1's
+
+970106	libsrc/standard/elmdict.tpl: fix type in GE CR QA tags
+
+970102	libsrc/standard/elmdict.tpl: add more Elscint private tags from
+	Passport CS V 2.05
+
+961217  libsrc/include/pixeldat/unencap.h: remove vl==0 assert for fragment
+	table
+
+961217  libsrc/standard/strval.tpl: update SpecificCharacterSet for Supp 9 FT.
+
+961217	libsrc/standard/transyn.tpl: describe .70 as non-hiearchical
+
+961129	libsrc/src/dconvert/gen/genmmsc.cc: Fix VR for Rotation Direction
+
+961121	INSTALL: Added comments about defining a UID root.
+
+961121	libsrc/dctool/uidgen.cc: Use DEFAULTUIDROOT
+
+961120	config/site.def-p: Parameterize all UID related stuff and add
+	a clunie at ge specific option (UseClunieGEID) which no one else
+	should use.
+
+961112	appsrc/dcfile/dcdirmk.cc: Created it, added icon image support.
+
+961112	libsrc/standard/*: Changed some element names to match the current
+	state of the standards documents
+
+961105	appsrc/misc/jpegdump.cc: Cleanup to handle cardiac JPEGs including:
+	- dump contents of variable segments (eg. quant tabs, huffman tabs)
+	- handle wierd "markers" eg 0xffff
+	- get offset right
+	- add setbuf to speed things up
+
+961105	libsrc/include/pixeldat/unencap.h: Initialize lefttoreadthisfragment
+	to zero ... was sometimes not, and failed on some JPEGs
+
+961101	libsrc/standard/elmdict.tpl,module.tpl: Update to vl33lb
+
+961014	config/Configure: For HPUX add UseOwnLog2
+
+961011	appsrc/dcfile/dcfile.cc: add data dump for meta-header
+
+961011	appsrc/acrnema/andump.cc: add UN to long VL check
+
+961011	man/man1: fill in lots of man pages and use source options
+
+961011	libsrc/src/dctool/dicomdir.cc: write VM > 1 filename
+
+961010	appsrc/gXX/gXXmmsc.cc and gxxmmdt.cc add explicit casts to Uint32
+	and DateTime all over to shut old gcc 2.6.3 up (on Ultrix)
+
+961010	appsrc/.../*.cc: explicit casts on input/output opener stuff to
+	istream/ostream * to shut old gcc 2.6.3 up (on Ultrix)
+
+961010	config/Configure: For Ultrix add UseOwnLog2 (log(x)/log(2))
+	(indeed log base n of x is always log(x)/log(n))
+
+961009	libsrc/support/elmdict.awk: Ultrix version of nawk exposed a bug
+	in this script that wasn't checking on the owner match being
+	successful (and resulted in empty elmconst.h etc). Amazing this
+	hadn't shown up before.
+
+961009	./Configure: For Ultrix modify config/Configure to use /bin/sh5
+
+961009	config/Configure: For Ultrix add UseDumbInfinityAndNAN
+
+961009	config/Configure: OSF1 add UseDumbInfinityAndNAN (g++ on Alpha V3.2)
+	(could in theory also pass "-Wl,S" to the linker, but confusing)
+
+961004	Make encountered but unknown private tags UN not OB in dictionary
+
+961004	Add Philips SPI tags for DCI
+
+961002	Add draft Visible Light image (vl33pr document) to data dictionary,
+	IOD and modules. Made up new tags for some conflicting elements
+	and sent them to Dean - BE WARNED ... THESE ARE NOT FINAL. Also
+	had to make up SOP Class UIDs.
+
+961001	dicomdir.*,dcdirdmp.cc: Parse directory record structure within
+	a DICOMDIR and dump its contents quickly, verbosely (-v) or
+	very verbosely (-vv)
+
+960930	attrtypn.h: Allow VL to be shorter than VR specifies (some Siemens
+	SPI lengths of headers and things rae supposed to be UL but are
+	US in some files). Same sort of thing in andump.cc.
+
+960930	Support for UN VR
+
+960930	elmdict.tpl: Update with SPI from latest Numaris
+
+960930	attrmxrd.cc: Warn about duplicate tags but let them through
+
+960929	elmdict.tpl: Table Motion CS not DS
+
+960929	attrvrfy.cc: Add element id to error messages for enum tests etc.
+
+960929	module.tpl, et al: Lossy Compression enum values string not bin
+
+960929	elmdict.tpl: wrong name for 0020,0000
+
+960202	dcdisp: failing on images with high bits set (above bits stored),
+	fixed by adding fromshft stuff to pixel data in attributes to
+	handle shifting and masking (in case funky high bit) - does
+	not yet handle sign extension (? if necessary) - encountered
+	this on an image apparently from UCDMC PACS conversion of a
+	Siemens CT angio recon which has some annotation in overlay
+	planes (Evolution Siemens)
+
+960202	dcdisp: implemented grayscale inversion in usegray.cc to support
+	MONOCHROME1 and added flag for manual inversion - the choice
+	of where the inversion is performed is dubious and probably
+	inefficient
+
+960202	gethttp: needed it anyway and tests ntstream stuff - seems to
+	be a problem with ios or streambuf or whatever returning a
+	bad stream status and less bytes than asked for in a read,
+	but not zero ... clearing the status and continuing seems to
+	work (yuck) ... still occasionally just quits for no reason
+	on really big files :(
+
+
+
+
+
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100755
index 0000000..eaf93f1
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,28 @@
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of
+   conditions and the following disclaimers.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of
+   conditions and the following disclaimers in the documentation and/or other materials
+   provided with the distribution.
+
+3. Neither the name of PixelMed Publishing nor the names of its contributors may
+   be used to endorse or promote products derived from this software.
+
+This software is provided by the copyright holders and contributors "as is" and any
+express or implied warranties, including, but not limited to, the implied warranties
+of merchantability and fitness for a particular purpose are disclaimed. In no event
+shall the copyright owner or contributors be liable for any direct, indirect, incidental,
+special, exemplary, or consequential damages (including, but not limited to, procurement
+of substitute goods or services; loss of use, data or profits; or business interruption)
+however caused and on any theory of liability, whether in contract, strict liability, or
+tort (including negligence or otherwise) arising in any way out of the use of this software,
+even if advised of the possibility of such damage.
+
+This software has neither been tested nor approved for clinical use or for incorporation in
+a medical device. It is the redistributor's or user's responsibility to comply with any
+applicable local, state, national or international regulations.
diff --git a/Configure b/Configure
new file mode 100755
index 0000000..69dff19
--- /dev/null
+++ b/Configure
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+cd config
+if [ `uname -s` = "ULTRIX" -a -f "/bin/sh5" ]
+then
+	mv Configure Configure.bak
+	echo "#!/bin/sh5" >Configure
+	sed '1d' <Configure.bak >>Configure
+	chmod +x Configure
+fi
+./Configure $*
diff --git a/Doxyfile b/Doxyfile
new file mode 100755
index 0000000..aeec82b
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,691 @@
+# Doxyfile 1.2.1
+
+# This file describes the settings to be used by doxygen for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project. 
+
+PROJECT_NAME           = "dicom3tools"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, 
+# Spanish, Russian, Croatian, Polish, and Portuguese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES 
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation. 
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation. 
+
+EXTRACT_STATIC         = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled. 
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these class will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled. 
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this. 
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed. 
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description. 
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used. 
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = 
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation. 
+
+INTERNAL_DOCS          = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a class diagram (in Html and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. 
+
+CLASS_DIAGRAMS         = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation. 
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible. 
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen 
+# will only generate file names in lower case letters. If set to 
+# YES upper case letters are also allowed. This is useful if you have 
+# classes or files whose names only differ in case and if your file system 
+# supports case sensitive file names. 
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden. 
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this. 
+
+VERBATIM_HEADERS       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put list of the files that are included by a file in the documentation 
+# of that file. 
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the Javadoc-style will 
+# behave just like the Qt-style comments. 
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# reimplements. 
+
+INHERIT_DOCS           = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members. 
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order. 
+
+SORT_MEMBER_DOCS       = YES
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments. 
+
+TAB_SIZE               = 8
+
+# The ENABLE_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif. 
+
+ENABLED_SECTIONS       = 
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used. 
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used. 
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled. 
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. 
+
+WARN_FORMAT            = "$file:$line: $text"
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces. 
+
+INPUT                  = appsrc libsrc
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included. 
+
+FILE_PATTERNS          = *.h *.c *.cc
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used. 
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag. 
+
+EXCLUDE                = 
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. 
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command). 
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included. 
+
+EXAMPLE_PATTERNS       = 
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command). 
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output. 
+
+INPUT_FILTER           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces. 
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20]) 
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers. 
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output. 
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path. 
+
+HTML_OUTPUT            = html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet 
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used. 
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation. 
+
+GENERATE_HTMLHELP      = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it. 
+
+DISABLE_INDEX          = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output. 
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path. 
+
+LATEX_OUTPUT           = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general. 
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used. 
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output. 
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing! 
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer. 
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation. 
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML. 
+
+LATEX_BATCHMODE        = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path. 
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general. 
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using a WORD or other. 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links. 
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value. 
+
+RTF_STYLESHEET_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages 
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path. 
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3) 
+
+MAN_EXTENSION          = .3
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Warning: This feature 
+# is still experimental and very incomplete.
+
+GENERATE_XML           = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files. 
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES. 
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags. 
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found. 
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor. 
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used. 
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. 
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition. 
+
+EXPAND_AS_DEFINED      = 
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles. 
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads. 
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed. 
+
+ALLEXTERNALS           = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl'). 
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default) 
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes. 
+
+COLLABORATION_GRAPH    = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to 
+# YES then doxygen will generate a graph for each documented file showing 
+# the direct and indirect include dependencies of the file with other 
+# documented files. 
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to 
+# YES then doxygen will generate a graph for each documented header file showing 
+# the documented files that directly or indirectly include this file 
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one. 
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path. 
+
+DOT_PATH               = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images. 
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images. 
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored. 
+
+SEARCHENGINE           = NO
+
+# The CGI_NAME tag should be the name of the CGI script that 
+# starts the search engine (doxysearch) with the correct parameters. 
+# A script with this name will be generated by doxygen. 
+
+CGI_NAME               = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the 
+# cgi binaries are located. See the documentation of your http daemon for 
+# details. 
+
+CGI_URL                = 
+
+# The DOC_URL tag should be the absolute URL to the directory where the 
+# documentation is located. If left blank the absolute path to the 
+# documentation, with file:// prepended to it, will be used. 
+
+DOC_URL                = 
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the 
+# documentation is located. If left blank the directory on the local machine 
+# will be used. 
+
+DOC_ABSPATH            = 
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
+# is installed. 
+
+BIN_ABSPATH            = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
+# documentation generated for other projects. This allows doxysearch to search 
+# the documentation for these projects as well. 
+
+EXT_DOC_PATHS          = 
diff --git a/INSTALL b/INSTALL
new file mode 100755
index 0000000..910da80
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,598 @@
+Last modified: Fri Sep  4 13:28:51 EDT 2015
+
+Quick start:
+
+	Edit config/site.p-def to set your UID root (a la UseClunieID, to be
+	selected with a UseXXXXID define on the imake command line).
+	
+	NB. Don't ever use any UseClunie*ID or your instances
+	will conflict with mine !
+
+	./Configure
+	setenv IMAKEINCLUDE -I./config		# only needed for suns
+	imake -I./config -DInstallInTopDir -DUseXXXXID
+	make World
+	make install		# into ./bin
+	make install.man	# into ./man
+
+Assuming that imake, makedepend, and mkdirhier (not to mention the C and C++
+compilers) are in your PATH, and that your system isn't too far off then:
+
+	1. ./Configure
+
+	   This checks for certain things and makes config/generic.cf
+	   which is subsequently used in the imake process.
+
+	   It chooses gnu tools and compilers by preference over native
+	   tools or compilers, if they are in the current execution path,
+	   and it also tries to figure out the appropriate include paths
+	   to feed to later makedepend's. If you want to suppress the
+	   choice of gnu over the native compiler and both are in the
+	   PATH, say "notgcc" as an argument to ./Configure.
+
+	   Configure will warn if it does not find gcc and g++; if this
+	   happens and you were not planning on using other compilers,
+	   you will need to install them. If your proceed despite these
+	   warnings, chances are make World will fail and report an
+	   error like "CC not found".
+
+	   Configure uses whatever is the first compiler found in
+	   the PATH, so be sure to set the path to find gcc, g++,
+	   (or CC, cc or acc if you are not using gcc/g++).
+
+	   If Configure fails with a syntax error, you may have a wierd
+	   /bin/sh ... try changing the first line of config/Configure
+	   to "#!/bin/sh5" (eg. under Ultrix).
+
+	2. Make the (absent) top level Makefile, either:
+
+		imake -I./config
+
+	   Note that -I./config is VERY important, otherwise imake
+	   will go looking for "standard" config files in "standard"
+	   places which will not work. Note that the version of imake
+	   supplied with OpenWindows ALWAYS looks in standard places
+	   first unless you define an IMAKEINCLUDE environment variable.
+	   Set it to "-I./config" and it will work. Symptoms of this
+	   problem are messages like "Can't find `Makefile.ini'".
+
+	   The default is to install things in /usr/local/bin and man. If
+	   you imake with -DInstallInTopDir, then they go into ./bin, etc.:
+
+		imake -I./config -DInstallInTopDir
+
+	   One can specify a UID root for your organization by adding
+           "-DDefaultUIDRoot=n.n.nnnn.nnnnn" to the imake command, eg.:
+
+		imake -I./config -DDefaultUIDRoot=1.2.840.99999
+
+           though it is better to properly configure all identification
+           related stuff in config/site.def-p.
+
+	   One can specify the level of optimization (default is -O) by
+           "-DOptimizeLevel=-On" where n is the level (from 1 to 3 for
+           g++, for 1 to 4 for SunPro) to the imake command, eg.:
+
+		imake -I./config -DOptimizeLevel=-O3
+
+           Note that serious optimization requires seriously large
+           amounts of memory/swap space, and temporary file space.
+           The entire package has been compiled with maximum levels
+           of optimization turned on without exposing any wierd bugs.
+	   If you keep running out of memory try -O0.
+
+	   One can specify an alternative SunPro temporary path by adding
+           "-DTmpPath=/path" to the imake command, eg.:
+
+		imake -I./config -DTmpPath=/usr1/tmp
+
+           (This does not work for g++ which looks in the environment
+           variable TMPDIR instead).
+
+	   Check the man pages on your c and CC compilers to determine
+	   which is more appropriate.
+
+	   Obviously imake needs to be found in PATH. You may need to
+	   add "/usr/bin/X11/imake". Else see "Imake" below.
+
+	2. Make everything (subdirectory makefiles, clean, depend, all):
+
+		make World
+
+	3. To install the binaries in ./bin or /usr/local/bin:
+
+		make install
+
+	4. To test the conversion routines, and some of the dicom and
+	   miscellaneous utilities, if you have the sample images, which
+	   are distributed separately, having set the PATH, correctly, do:
+
+		make test
+
+	   This takes ages, does lots of repetitive things, compares
+	   binary output, and times the commands. To see what is being
+	   done look in scripts/testconv.sh.
+
+	5. To install what manuals there are in ./man or /usr/local/man:
+
+		make install.man
+
+	6. If you are root and hence can update whatis database:
+
+		make install.whatis
+
+If you change your mind about one/split you need to go all the way back
+to step 1, as the Makefiles are created differently. Other useful targets
+are:
+
+	make Makefile		- makes the Makefile from Imakefile
+	make Makefiles		- makes the Makefiles in sub-directories
+	make depend		- does as it usually does
+	make			- makes all the libraries and applications
+	make all		- same
+	make library		- makes just the libraries
+	make clean		- cleans all directories
+	make archive		- for posterity, includes cleaning
+	make update.version	- before posterity
+
+Debugging Flags
+
+Debugging flags for both the c and c++ compilation steps are defined
+and recursively passed down the subdirectory hierarchy. These also
+override any optimization options set.
+
+For example, to compile with no debugging or optimization:
+
+	make "C_DEBUGFLAGS=" "CPLUSPLUS_DEBUGFLAGS="
+
+To compile with the "-g" option to include debugging information:
+
+	make "C_DEBUGFLAGS=-g" "CPLUSPLUS_DEBUGFLAGS=-g"
+
+To compile with the "-g" option and the "-pg" option to include
+code to write a gmon.out file for gprof call graph profiling:
+
+	make "C_DEBUGFLAGS=-g -pg" "CPLUSPLUS_DEBUGFLAGS=-g -pg"
+
+This is done at make time, and an imake/make Makefiles cycle is
+not required.
+
+Imake.
+
+(See also Darwin (Mac OS X) Stuff).
+
+If you don't have imake, I suggest you get it from Paul DuBois's archive
+(he has also hacked up the X11 files to produce "extensible" imake
+configurations, and I have culled them down further). Everything for
+this project is in config ... you don't have to worry about moving things
+to /usr/lib/X11/config ... I hate that. You just need to supply the
+programs. I don't use imboot, use "imake -I./config" instead. Everything
+here is based on Paul's EA version of the config files.
+
+Everything you need for this project is available at:
+
+	ftp://ftp.uu.net/published/oreilly/nutshell/imake/imake.tar.Z
+
+It is also probably at the site where you found dicom3tools.
+
+Get and read the book too ... it is one of the best Nutshell handbooks I
+have seen.
+
+One of the nicest thing about using imake is the ability to generate
+Makefiles in multiple sub-directories, which contain all the right paths
+and definitions without them needing to be passed by "parent" makes, so
+one can happily work and change things in each sub-directory issuing
+"local" make commands -  really speeds up the edit/compile/test cycle.
+
+C++ features required.
+
+Templates are used. Exceptions are not.
+
+Different template instantiation mechanisms were driving me crazy so now
+declarations are not separated from definitions ... all in one header file.
+This may be inefficient but it avoids maintaining different #pragma's and
+file name/directory conventions for different compilers (yuck).
+
+This may change now that gnu g++ (almost) supports template repositories,
+and hopefully this might avoid the current code bloat.
+
+With some compilers if things are missing at link time because certain
+templates weren't instantiated at compile time (ie. statically into
+the object), you may need to use a compile option (eg. -pto for SC 4.0).
+
+The old (pre-ANSI C++ standard) strstream stuff is used; this means that
+g++ version 2, not 3, is required, since version 3 does not support the
+older headers. The Configure script looks for this, and usually both
+compilers are available, but if not, you may need to manually install
+a gcc package (such as 2.95).
+
+Porting.
+
+Porting to another unix version or site should be painless, as there are
+no vendor specific features used. The config really only applies to the
+tools used to build and compile the toolkit, not to any of the toolkit
+behaviour.
+
+All the site specific stuff (paths et al.) should be in site.def (shared 
+between projects) and the stuff specific to this project should be in
+site.p-def, and so on. These rarely need to be changed however.
+
+There are no specific operating system or compiler targets specified
+in Imake.tmpl ... it assumes that generic.cf has been created by the
+Configure script.
+
+To port, it is easiest to try running with an empty generic.cf, using
+the defaults in Imake.tmpl, and see what fails. Examine the shell script
+config/Configure to get an idea of what things you might need to replace,
+and build a manual generic.cf. When you have it working, send it to me,
+or fold it back into config/Configure and send that to me, and I will
+include it in the next release (dclunie at dclunie.com).
+
+It is best not to go editing the other files such as rules and so on, 
+unless absolutely necessary, as the principle is to define everything 
+local early on to override the default definitions that come later.
+
+NEVER edit a Makefile by hand ... these will get overwritten and your
+changes will be lost.
+
+The X stuff has been tested under OpenWindows 3 only but is so primitive
+it should run on any version of X11R4 and above at least.
+
+Missing Prototypes.
+
+SunOS and Solaris do not include declarations for a host of functions,
+particularly in the network related code, and using g++ in these
+environments, despite fixincludes, means that no prototypes are
+available. Accordingly -DNEEDMISSINGPROTOTYPES brings these in, and
+probably isn't necessary in any other environment, and will create
+conflicts if it is used when correct prototypes are available.
+
+GNU libg++ and makedepend wierdness.
+
+Some versions of makedepend that are shipped with X11 don't recognize
+the #if construct ... if you are using gcc then this shows up as
+complaints like "Make:  Don't know how to make _IO_config.h." because
+the makedepend has ignored an #if 1/#else/#include "_IO_config.h"/#endif
+that occurs in g++-include/libio.h, and created a dependency on the
+_IO_config.h file that of course doesn't exist.
+
+Solutions are manually edit g++-include/libio.h or get a real
+makedepend, such as with the imake package.
+
+Sunpro SC wierdness.
+
+Configure will use the first CC and cc or acc compilers it finds
+in the path, and check for versions of SC to create make depend
+include paths. These will be relative to LANGHOME so don't forget
+to set itif using Sun SC.
+
+You also may need LD_LIBRARY_PATH set to the Sun SC lib directory
+at run time.
+
+At compile time for later versions you may need to set LM_LICENSE_FILE.
+
+For example:
+
+	setenv LANGHOME /usr/3p/SUNWspro
+	setenv PATH ${LANGHOME}/SC4.2/bin:${PATH}
+	setenv LM_LICENSE_FILE ${LANGHOME}/license_dir/sunpro.lic
+	setenv LD_LIBRARY_PATH ${LANGHOME}/SC4.2/lib
+
+More recent versions of SunPro have not been tested.
+
+Solaris Notes.
+
+You can find makedepend and imake in /usr/openwin/bin.
+
+You can find make in /usr/ccs/bin.
+
+The Solaris nawk works fine ... you don't need gawk.
+
+These all need to be in your PATH.
+
+Solaris and GNU Binaries Wierdness.
+
+You can get pre-packaged binaries for Solaris from:
+
+	http://metalab.unc.edu/pub/packages/solaris/sparc/
+
+amongst other places.
+
+These are installed using the Solaris pkgadd mechanism.
+
+Unfortunately older gcc packages don't know about the libg++
+package, so dctool Configure doesn't pickup the include and
+library paths. Newer releases (libstdc++) should be better.
+
+You may need to manually link /opt/FSFlibg++/lib/g++-include into
+/opt/GCC2721/lib, for example, if you get errors from makedepend
+about not finding c++ header files.
+
+You probably also need to link /opt/FSFlibg++/lib/lib*.a into
+/opt/GCC2721/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2.1, or deal
+with the problem in site.def, if you get errors at link time
+about not finding g++ or stdc++, etc.
+
+The package has compiled OK under Solaris releases from 2.5 up
+to Solaris 8 Early Access, the latter both on Sparc and X86.
+
+X86 Stuff.
+
+A few of the tools, notably binpatch, are big-endian byte order
+dependent and won't work on Solaris X86 or Linux on X86.
+
+Linux Stuff.
+
+Recent "distributions" of Linux should have no problem compiling
+the tools. The Configure script should set up everything required.
+earlier versions of egcs were a problem, but no longer seem to be.
+
+Finding the X11 static libraries can be painful and Configure does
+its best; under FC5 they have stopped distributing the static
+library libX11.a in the RPM, so one has to build it oneself,
+which is a pain (but described by Michael Peters in a thread on
+the subject at "http://forums.fedoraforum.org/showthread.php?t=108049")
+that I adapt here:
+
+  wget http://download.fedora.redhat.com/pub/fedora/linux/core/5/source/SRPMS/libX11-1.0.0-3.src.rpm
+  sudo yum install fedora-rpmdevtools
+  fedora-buildrpmtree
+  rpm -i libX11-1.0.0-3.src.rpm
+  vi rpmbuild/SPECS/libX11.spec
+    ... change Release from 3 to 3.1
+    ... change %define with_static from 0 to 1
+  rpmbuild -bb rpmbuild/SPECS/libX11.spec
+  sudo rpm -U rpmbuild/RPMS/x86_64/libX11*.rpm
+  ls -l /usr/lib64/libX11.a
+
+  wget http://download.fedora.redhat.com/pub/fedora/linux/core/5/source/SRPMS/libXext-1.0.0-3.2.src.rpm
+  rpm -i libXext-1.0.0-3.2.src.rpm
+  vi rpmbuild/SPECS/libXext.spec
+    ... change Release from 3.2 to 3.3
+    ... change %define with_static from 0 to 1
+  rpmbuild -bb rpmbuild/SPECS/libXext.spec
+  sudo rpm -U rpmbuild/RPMS/x86_64/libXext*.rpm
+  ls -l /usr/lib64/libXext.a
+
+Irix Stuff.
+
+It has been a long time since the package was compiled under any
+version of Irix using the SGI compilers ... it may no longer compile.
+I have never tried it with gcc and the SGI development libraries.
+
+OSF Stuff.
+
+It has been a long time since it was compiled on a Dec Alpha.
+
+Darwin (Mac OS X) Stuff.
+
+On recent Mac OS versions (Yosemite, Mavericks (?)), the X11 library and
+include files may not be present even if XQuartz is installed, and
+these are necessary for the dcdisp stuff to build. Installing the
+MacPorts package "xorg-libX11" ("port install xorg-libX11") will make
+these available (and the Configure script will use these on Darwin by
+preference if they are available) (a "port contents xorg-libX11" will
+show the files that are installed). You may also need the package
+"xorg-libXext" installed.
+
+With XCode 5, the default cpp behavior has changed such that it is incompatible
+with imake ... you need to use the earlier llvm-cpp-4.2. If you already had
+XCode 4 installed, it will already be there, and Configure will warn you that
+you need to set the IMAKECPP environment variable prior to running imake or
+any make that invokes imake (like Make World), e.g.:
+
+	in csh:
+
+		env IMAKECPP=llvm-cpp-4.2 imake -v -I./config
+		env IMAKECPP=llvm-cpp-4.2 make World
+
+	in Bourne shells:
+	
+		IMAKECPP=llvm-cpp-4.2 imake -v -I./config
+		IMAKECPP=llvm-cpp-4.2 make World
+
+Fortunately with XCode 6 this seems to no longer be necessary.
+
+Recent versions also have a makedepend binary that just pops up a warning
+dialog that makedepend isn't installed :( To get around this the Configure
+script now checks for /opt/X11/bin/makedepend, which is where XQuartz
+puts it.
+
+On Snow Leopard (10.6), X11 (an optional install) no longer contains
+imake; the easiest way to get it is to install MacPorts and then install
+the port of imake ("port install imake").
+
+On earlier versions, the XQuartz or the Apple (optional) installation of
+X11 contains imake (in /usr/X11R6/bin).
+
+The version of awk supplied is not sufficient ... use gawk, which is available
+from MacPorts (the Configure script will use it); installing the port of
+coreutils will include this.
+
+On early Darwin versions, the gcc compiler is installed as "cc" not "gcc", so unless
+you make symbolic links named "gcc" you will get a lot of can't find the header errors
+from the make depend phase. Unfortunately these can't just be ignored, so you need to do
+something like add /usr/local/bin to your path if not already there, as root, make
+/usr/local/bin if not already there and create symbolic links named "gcc" and "g++"
+to "/usr/bin/cc" and "/usr/bin/c++" respectively.
+
+This should not be necessary if you have the Dec 2002 Developer package installed,
+either from the Apple developer site or from a more recent Jaguar set of install
+disks (e.g. 10.2.3 or later).
+
+Linux Stuff.
+
+Depending on your distribution, gcc will likely already be installed but g++
+may well not be, nor will imake.
+
+E.g., on Debian or Ubuntu, to get g++ you will probably need to run:
+
+  sudo apt-get install g++
+  
+and imake:
+
+  sudo apt-get install xutils-dev
+
+and the X11 development libraries to allow dcdisp to compile:
+
+  sudo apt-get install libX11-dev
+  sudo apt-get install libXext-dev
+
+Cygwin Stuff.
+
+As long as you have installed the necessary packages with Cygwin (including X11
+in order to get imake and build dcdisp), then everything compiles just fine. The
+executables will be named with a .exe extension as expected.
+
+This can be achieved by installing the default Cygwin set of packages, and
+additionally selecting the following (binary) packages:
+
+- gcc-g++ (NOT gcc4-g++)
+- imake
+- make
+- makedepend
+- libX11-devel
+- libXext-devel
+- zip (only needed to make archive.winexe target, not to compile and install)
+
+which will also select all of the necessary dependencies.
+
+Note that if you are getting make time errors that mention "strip" not
+being found, then the wrong version of make is being used.
+
+If you want to run the executables in a command shall without Cygwin installed,
+then you just need to have a copy the cygwin1.dll file in your current path.
+
+UID Related Stuff.
+
+This is best configured in config/site.def-p, though you can do it
+with defines on the command line of the first imake.
+
+All generated DICOM SOP Instances should have a globally unique UIDu
+and the scheme for this presumes that the user of the tools has a "root"
+that is unique to their implementation (or compilation of these tools),
+from which subsequent UIDs for instances can be generated by adding stuff
+to the end of the root that disambiguates instances ... the default is
+to use a date/time stamp, though one can supply one's own "stamp" with
+a command line option if necessary to ensure consistency of series, study
+and frame of reference UID's between invocations of various tools that
+create instances.
+
+This is all done by setting the macro 'DefaultUIDRoot' to an appropriate
+value. There are also various implementation specific things in a DICOM
+metaheader that can be set with 'DefaultImplementationClassUID',
+'DefaultImplementationVersionName' and 'DefaultSourceApplicationEntityTitle',
+though these are less vital.
+
+An example of how to do this easily is the definition of my own macro,
+'UseClunieGEID' in config/site.def-p. Use this as a model if you like
+but DO NOT UNDER ANY CIRCUMSTANCES use my root ID or your instances
+will conflict with mine !
+
+If you don't have a real root and just want to experiment, define nothing
+and '0.0.0.0' will be used ... this is bad, and means you can't send
+these instances out into the real world, but at least it is obviously
+not a valid root, whereas using mine would appear to be.
+
+How to you get one of these roots ? ISO delagates responsibility for
+assigning them to national member bodies such as ANSI, BSI, DIN, etc.
+See the alt.image.medical FAQ for further information and contacts. You
+can find it at:
+
+	http://www.dclunie.com/medical-image-faq/html/
+
+Tuning for faster image display.
+
+If you use dcdisp and want to increase the speed of the image refresh
+after window/level width etc., then compile with USEXMITSHMEXTENSION,
+and if you display a lot of large images (eg. mammo or CR), tune your
+OS System V shared memory maximum size. On Solaris, edit /etc/system
+to include:
+
+	set shmsys:shminfo_shmmax=16777216
+
+where 16777216 is big enough to hold a 16MB 8 bit image, etc.
+
+Note that the default configuration is specifically set up to
+activiate shared memory (ie. UseXMitShmExtension is turned on
+in config/Configure. You can turn it off by putting in site.def
+in the BeforeVendorCF section:
+
+	#ifndef UseXMitShmExtension
+	#define UseXMitShmExtension 0
+	#endif	UseXMitShmExtension
+
+JPEG Stuff
+
+A script (dcunjpeg) is available that makes use of the Stanford PVRG
+JPEG codec that supports lossless compression. A patch is included in
+the "support" directory to apply to the Stanford codec to support some
+GE implementation bugs on decompression.
+
+For more information, including source of the Stanford codec, see:
+
+	"http://www.dclunie.com/jpegge.html"
+
+The PVRG codec (jpeg) is required to be available in the PATH at runtime.
+
+For color 8 bit images, the IJG codec (djpeg) is required to be available
+in the PATH at runtime (on MacOS, port install jpeg).
+
+For JPEG 2000 images, the Kakadu codec (kdu_expand) is required to be
+available in the PATH at runtime.
+
+Deflate Stuff
+
+Scripts (dcdeflate and dcinflate) are provided to support the proposed
+use of the gzip/pkzip deflate algorithm as a standard DICOM transfer
+syntax, compressing the entire DICOM dataset beyond the metaheader,
+rather than just the pixel data. It is intended for use with reports,
+waveforms and presentation states.
+
+The scripts depend on the availability of the gzip utility, patched to
+take an extra option (-x) that outputs just the deflated bitstream and
+not the gzip header. The patches to gzip versions 1.2.4 and 1.3.12 are
+included in the "support" directory. The source to gzip is available from
+many sites, including:
+
+	"http://www.gzip.org/"
+
+Netpbm Stuff
+
+Some of the scripts (e.g. dcunrgb) depend on utilities from the netpbm
+library, and hence the netpbm utilities are required to be available in
+the PATH at runtime, though the library is not required for compilation of
+dicom3tools. See:
+
+	"http://netpbm.sourceforge.net/"
+	
+On a Mac, installation of a recent port of netpbm using MacPorts will
+suffice.
+
+Documentation
+
+There is a marvellous set of tools called "doxygen" that creates javadoc
+style documentation for C++ but goes way beyond and draws class diagrams
+and even collaboration diagrams if the ATT "graphviz" package is also
+available.
+
+If one does "make docs" then a "docs"directory is created in which the
+"html" folder contains an "index.html" that may be used to read the
+documentation of class, files, etc. This depends on both doxygen and
+dot (from graphiz) being in the current path.
+
+See the following URLs to get these excellent packages:
+
+	http://www.doxygen.org/
+	http://www.research.att.com/sw/tools/graphviz/
+
+BTW. The generated docs are way to bulky to distribute and can always
+be generated, so please don't ask.
+
+Note also that the docs are generated from the class definitions as is,
+and there has been no effort (yet) to actually insert any comments that
+get included in the generated docs to explain what the classes and methods
+actually do !
+
+The end.
+
diff --git a/Imakefile b/Imakefile
new file mode 100755
index 0000000..71ab465
--- /dev/null
+++ b/Imakefile
@@ -0,0 +1,232 @@
+#define IHaveSubdirs
+
+SUBDIRS        = appsrc config libsrc support
+ALLSUBDIRS     = libsrc appsrc support
+DEPENDSUBDIRS  = libsrc appsrc support
+SBSOURCEDIRS   = libsrc appsrc support
+SBDIR          = .sb
+INSTALLDIRS    = bin include lib man
+
+ARCHIVENAME        = dicom3tools
+ARCHIVEFILES       = $(SUBDIRS) BUGS CHANGES Configure COPYRIGHT Doxyfile Imakefile INSTALL Makefile NotAMakefile README TODO VERSION WARNINGS 
+
+ARCHIVEIMAGESNAME  = dicom3tools_images
+ARCHIVEIMAGESFILES  = images
+
+ARCHIVETESTNAME  = dicom3tools_test
+ARCHIVETESTFILES  = test
+
+ARCHIVEMANNAME  = dicom3tools_man
+ARCHIVEMANFILES  = man
+
+ARCHIVEWINEXENAME = dicom3tools_winexe
+ARCHIVEWINEXEFILES = \
+	appsrc/acrnema/andump.exe \
+	/usr/bin/cygwin1.dll \
+	/usr/bin/cyggcc_s-1.dll \
+	/usr/bin/cygstdc++-6.dll \
+	appsrc/dcfile/dcdump.exe \
+	appsrc/dcfile/dcentvfy.exe \
+	appsrc/dcfile/dcfile.exe \
+	appsrc/dcfile/dchist.exe \
+	appsrc/dcfile/dciodvfy.exe \
+	appsrc/dcfile/dckey.exe \
+	appsrc/dcfile/dcsrdump.exe \
+	appsrc/dcfile/dcstats.exe \
+	appsrc/dcfile/dctable.exe \
+	appsrc/dcfile/dcsort.exe \
+	appsrc/dcfile/dcdirdmp.exe \
+	appsrc/dcfile/dctoraw.exe \
+	appsrc/dcfile/dccmp.script \
+	appsrc/dcfile/dcdiff.script
+
+ARCHIVEMACEXENAME = dicom3tools_macexe
+ARCHIVEMACEXEFILES = \
+	appsrc/acrnema/andump \
+	appsrc/dcfile/dcdump \
+	appsrc/dcfile/dcentvfy \
+	appsrc/dcfile/dcfile \
+	appsrc/dcfile/dchist \
+	appsrc/dcfile/dciodvfy \
+	appsrc/dcfile/dckey \
+	appsrc/dcfile/dcsrdump \
+	appsrc/dcfile/dcstats \
+	appsrc/dcfile/dctable \
+	appsrc/dcfile/dcsort \
+	appsrc/dcfile/dcdirdmp \
+	appsrc/dcfile/dctoraw \
+	appsrc/dcfile/dccmp.script \
+	appsrc/dcfile/dcdiff.script
+
+LINKTOIMAGEDIR = ../dctool.support/images
+LINKTOTESTDIR = ../dctool.support/test
+
+
+MakeSubdirs($(ALLSUBDIRS))
+DependSubdirs($(DEPENDSUBDIRS))
+
+World:
+	$(MAKE) $(MFLAGS) Makefile
+	$(MAKE) $(MFLAGS) Makefiles
+	$(MAKE) $(MFLAGS) clean
+	$(MAKE) $(MFLAGS) depend
+	$(MAKE) $(MFLAGS) setplatform
+	$(MAKE) $(MFLAGS)
+
+World.unclean:
+	$(MAKE) $(MFLAGS) Makefile
+	$(MAKE) $(MFLAGS) Makefiles
+	$(MAKE) $(MFLAGS) depend
+	$(MAKE) $(MFLAGS) setplatform
+	$(MAKE) $(MFLAGS)
+
+NamedTargetSubdirs(library,libsrc,NullParameter,NullParameter,all)
+
+InstallWhatis(NullParameter)
+
+sb:	$(SBSOURCEDIRS)
+	support/linksb $(SBDIR) $(SBSOURCEDIRS)
+
+update.copyright:
+	support/updatecopyright
+
+setversion:
+	support/setversion
+
+setplatform:
+	support/setplatform
+
+archive:	setversion clean clean.makefiles clean.config clean.docs archive.unclean
+
+archive.unclean:
+	$(CP) NotAMakefile Makefile; \
+	version=""; \
+	if [ -f VERSION ]; \
+		then version="_"`cat VERSION`; fi; \
+	link=$(ARCHIVENAME)$$version; \
+	ln -s . $$link; \
+	archive=$(ARCHIVENAME)$$version.$(TAREXT).$(COMPRESSEXT); \
+	sedstring="s/^[.]/$$link/"; \
+	export COPY_EXTENDED_ATTRIBUTES_DISABLE=true; export COPYFILE_DISABLE=true; \
+	echo 'CVS' >Exclude; echo '.DS_Store' >>Exclude; \
+	if [ -f $$archive ]; then $(MV) $$archive $$archive.old; fi; \
+	$(TAR) -X Exclude -cvf - `for i in $(ARCHIVEFILES); do echo $$link/$$i; done` \
+		| $(COMPRESS) > $$archive; \
+	$(RM) $$link Exclude
+
+archive.images:
+	version=""; \
+	if [ -f VERSION ]; \
+		then version="_"`cat VERSION`; fi; \
+	link=$(ARCHIVEIMAGESNAME)$$version; \
+	ln -s . $$link; \
+	archive=$(ARCHIVEIMAGESNAME)$$version.$(TAREXT).$(COMPRESSEXT); \
+	sedstring="s/^[.]/$$link/"; \
+	export COPY_EXTENDED_ATTRIBUTES_DISABLE=true; export COPYFILE_DISABLE=true; \
+	find . -path '*/CVS/*' | sed -e "$$sedstring" >Exclude; \
+	if [ -f $$archive ]; then $(MV) $$archive $$archive.old; fi; \
+	$(TAR) -X Exclude -cvh -f - `for i in $(ARCHIVEIMAGESFILES); do echo $$link/$$i; done` \
+		| $(COMPRESS) > $$archive; \
+	$(RM) $$link Exclude
+
+archive.test:
+	version=""; \
+	if [ -f VERSION ]; \
+		then version="_"`cat VERSION`; fi; \
+	link=$(ARCHIVETESTNAME)$$version; \
+	ln -s . $$link; \
+	archive=$(ARCHIVETESTNAME)$$version.$(TAREXT).$(COMPRESSEXT); \
+	sedstring="s/^[.]/$$link/"; \
+	export COPY_EXTENDED_ATTRIBUTES_DISABLE=true; export COPYFILE_DISABLE=true; \
+	find . -path '*/CVS/*' | sed -e "$$sedstring" >Exclude; \
+	if [ -f $$archive ]; then $(MV) $$archive $$archive.old; fi; \
+	$(TAR) -X Exclude -cvh -f - `for i in $(ARCHIVETESTFILES); do echo $$link/$$i; done` \
+		| $(COMPRESS) > $$archive; \
+	$(RM) $$link Exclude
+
+archive.man: install.man
+	version=""; \
+	if [ -f VERSION ]; \
+		then version="_"`cat VERSION`; fi; \
+	link=$(ARCHIVEMANNAME)$$version; \
+	ln -s . $$link; \
+	archive=$(ARCHIVEMANNAME)$$version.$(TAREXT).$(COMPRESSEXT); \
+	sedstring="s/^[.]/$$link/"; \
+	export COPY_EXTENDED_ATTRIBUTES_DISABLE=true; export COPYFILE_DISABLE=true; \
+	find . -path '*/CVS/*' | sed -e "$$sedstring" >Exclude; \
+	if [ -f $$archive ]; then $(MV) $$archive $$archive.old; fi; \
+	$(TAR) -X Exclude -cvf - `for i in $(ARCHIVEMANFILES); do echo $$link/$$i; done` \
+		| $(COMPRESS) > $$archive; \
+	$(RM) $$link Exclude
+
+archive.winexe:
+	version=""; \
+	if [ -f VERSION ]; \
+		then version="_"`cat VERSION`; fi; \
+	link=$(ARCHIVEWINEXENAME)$$version; \
+	$(RM) $$link; \
+	mkdir -p $$link; \
+	cp $(ARCHIVEWINEXEFILES) $$link; \
+	archive=$(ARCHIVEWINEXENAME)$$version.zip; \
+	$(RM) $$archive; \
+	(cd $$link; for i in *.exe; do touch $$i.local; done); \
+	(cd $$link; zip ../$$archive *.script *.exe *.dll *.exe.local); \
+	$(RM) $$link
+
+archive.macexe:
+	#version="_"`uname -p`"_"`uname -s`"_"`uname -r`
+	version=""; \
+	if [ -f VERSION ]; \
+		then version=$$version"_"`cat VERSION`; fi; \
+	link=$(ARCHIVEMACEXENAME)$$version; \
+	$(RM) $$link; \
+	mkdir -p $$link; \
+	cp $(ARCHIVEMACEXEFILES) $$link; \
+	archive=$(ARCHIVEMACEXENAME)$$version.zip; \
+	$(RM) $$archive; \
+	(cd $$link; zip ../$$archive dc* an*); \
+	$(RM) $$link
+
+clean.installed:
+	$(RM) $(INSTALLDIRS)
+
+clean.sb:
+	$(RM) $(SBDIR)
+
+clean.makefiles:
+	$(RM) `find . -name 'Makefile*' -print`
+
+clean.config:
+	$(RM) config/generic.cf
+
+clean.docs:
+	$(RM) docs
+
+clean.dist: clean clean.makefiles clean.config clean.installed clean.sb clean.docs
+	$(RM) Exclude
+
+find.pre:
+	support/findpre
+
+clean.pre:
+	$(RM) `support/findpre`
+
+install.minimal:
+	$(INSTALL) $(INSTPGMFLAGS) $(INSTBINFLAGS) \
+		appsrc/acrnema/andump /usr/local/bin
+	$(INSTALL) $(INSTPGMFLAGS) $(INSTBINFLAGS) \
+		appsrc/dcdisp/dcdisp /usr/local/bin
+	$(INSTALL) $(INSTPGMFLAGS) $(INSTBINFLAGS) \
+		appsrc/dcfile/dcdump /usr/local/bin
+	$(INSTALL) $(INSTPGMFLAGS) $(INSTBINFLAGS) \
+		appsrc/dcfile/dciodvfy /usr/local/bin
+	$(INSTALL) $(INSTPGMFLAGS) $(INSTBINFLAGS) \
+		appsrc/dcfile/dcdict /usr/local/bin
+links:
+	ln -s $(LINKTOIMAGEDIR)
+	ln -s $(LINKTOTESTDIR)
+
+docs:	. clean.docs
+	$(MKDIR) docs
+	$(DOXYGEN) Doxyfile
+
diff --git a/Makefile b/Makefile
new file mode 100755
index 0000000..bd8d4f4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+all:
+	@echo "Didn't read the INSTALL instructions, eh ?"
+	@echo
+	@echo "       1. ./Configure"
+	@echo "       2. imake -I./config"
+	@echo "       3. make World"
+	@echo
+
+install: all
+
+config: all
+
+configure: all
+
+depend: all
+
+World: all
+
+clean: all
+
diff --git a/NotAMakefile b/NotAMakefile
new file mode 100755
index 0000000..bd8d4f4
--- /dev/null
+++ b/NotAMakefile
@@ -0,0 +1,20 @@
+all:
+	@echo "Didn't read the INSTALL instructions, eh ?"
+	@echo
+	@echo "       1. ./Configure"
+	@echo "       2. imake -I./config"
+	@echo "       3. make World"
+	@echo
+
+install: all
+
+config: all
+
+configure: all
+
+depend: all
+
+World: all
+
+clean: all
+
diff --git a/README b/README
new file mode 100755
index 0000000..301862e
--- /dev/null
+++ b/README
@@ -0,0 +1,33 @@
+Last updated Mon Aug 16 18:00:45 EDT 2004
+
+Compile and install instructions are in INSTALL.
+
+Restrictions on use and redistribution are in COPYRIGHT.
+
+A log of changes over time is in CHANGES.
+
+This is even more ultra-alpha than the previous generation of
+dicom3tools 0.nn.
+
+It is being released as a snapshot of work in progress for
+people to see the future direction of the toolkit, and assess
+its portability.
+
+Some of the tools, such as dcdisp provided significantly
+increased functionality over the earlier toolkit. The convertors
+from proprietary formats do a much better job of creating DICOM
+files than their predecssors, but are not as complete in their
+coverage of formats (yet).
+
+Sequences are supported, as are all "modern" DICOM encoding
+features, such as UN VR. Compressed transfer syntaxes are
+not explicitly supported except by scripts using external
+codecs. The data dictionary is kept up to date with the latest
+supplements and corrections to the standard.
+
+Part 10 style files with a meta-header are now the default
+form of output, though this can be suppressed with an option.
+
+Comments, criticism and general abuse are greatly appreciated and
+should be directed to "dclunie at dclunie.com".
+
diff --git a/TODO b/TODO
new file mode 100755
index 0000000..e97a345
--- /dev/null
+++ b/TODO
@@ -0,0 +1,179 @@
+021122 - add GPWL modules
+
+010424 - dciodvfy issues:
+
+	- need to be able to specify attributes that may be present with conditional unsatisfied
+	- need to be able to specialize attributes and weaken conditions (defined terms, presence
+	  or absence)
+	- need to be able to forbid the presence of modules
+
+970916 - Using zero length for -r "" doesn't work
+
+
+/home/gsaohome/clunie/images/rsna97cd/ge/round0/ct/SC.1.2.840.113619.2.25.1.1762306543.872804962.246
+Linking /home/gsaohome/clunie/images/rsna97cd/ge/round1cd/ct/IM117.
+
+before adding
+
+(0x0009,0x10e8)  ?  - Warning - Unrecognized tag - assuming explicit value representation OK
+
+to dictionary, caused a problem on writing as EVRLE ->
+
+(0x0009,0x10e8)  ? 	 VR=<UN>   VL=<0x31305443>  [...]
+
+same for
+
+/home/gsaohome/clunie/images/rsna97cd/ge/round0/nm/NM.1.2.840.113619.2.43.16112.2141964.41.48.870878841.6
+Linking /home/gsaohome/clunie/images/rsna97cd/ge/round1cd/nm/IM268.
+
+Creating /home/gsaohome/clunie/images/rsna97cd/ge/round0/nm/NM.1.2.840.113619.2.43.16112.2141964.41.48.870878841.7
+Linking /home/gsaohome/clunie/images/rsna97cd/ge/round1cd/nm/IM269.
+
+Creating /home/gsaohome/clunie/images/rsna97cd/ge/round0/nm/NM.1.2.840.113619.2.43.16112.2141964.41.61.870879458.16
+Linking /home/gsaohome/clunie/images/rsna97cd/ge/round1cd/nm/IM270.
+
+> (0x0009,0x1029)  ?  - Warning - Unrecognized tag - assuming explicit value representation OK
+< (0x0009,0x1029)  ? 	 VR=<UN>   VL=<0x0004>  [0x18,0x00,0x00,0x00] 
+> (0x0009,0x1029)  ? 	 VR=<UN>   VL=<0x0018>  [0x09,0x00,0x2a,0x10,0x53,0x4c,0x04,0x00,
+> 	0x00,0x00,0x00,0x00,0x09,0x00,0x2c,0x10,0x4c,0x4f,0x00,0x00,0x09,0x00,0x2d,0x10] 
+
+need to check the VL writing logic for UN with EVRLE or something.
+
+	/home/gsaohome/clunie/dctool/appsrc/dcfile/dccp -addlengths \
+		-vr explicit -endian little \
+		-ra SourceApplicationEntityTitle NEMADEMO -nodisclaimer \
+		$from $to
+
+-------------
+
+bad tags are being silently ignored:
+
+britt{dclunie}% ancreate > test
+(0x0008,0x0000) VR=<OW> VL=<0> []
+(0x0008,0x4237) VR=<OW> VL=<0> []
+(0x0010,0x0000) VR=<OW> VL=<0> []
+britt{dclunie}% ../dcfile/dcdump <test
+(0x0008,0x0000) UL Identifying Group Length      VR=<UL>   VL=<0x0000>  [] 
+(0x0010,0x0000) UL Patient Group Length          VR=<UL>   VL=<0x0000>  [] 
+
+things that freak out transfer syntax guess ...
+
+britt{dclunie}% ancreate > test
+(0x7fe0,0x0010) VR=<OW> VL=<6> []
+10 20 30
+40 50 60
+britt{dclunie}% ../dcfile/dcdump <test
+britt{dclunie}% 
+
+britt{dclunie}% ancreate > test
+(0x0008,0x0000) VR=<OW> VL=<0> []
+(0x7fe0,0x0010) VR=<OW> VL=<0xffffffff> []
+10 20 30
+40 50 60
+britt{dclunie}% ../dcfile/dcdump <test
+Assertion failed: file "../../.././libsrc/include/dctool/attrothr.h", line 33
+
+removed the 000xnn support from ancreate ... update this in the man
+page.
+
+Check that all awk scripts that use make and match $ work on both
+buggy sun nawk and others re. RLENGTH.
+
+	- checked convert,elmdict,sopcl,transyn ... ok
+
+  4. Type `make install prefix=/usr/gnu/' (or the appropriate root
+     of your local GNU software installation tree) to copy bash to
+     your binaries directory, assumed to be ${prefix}/bin.  This will
+     also attempt to install the manual pages under ${prefix}/man
+     and the info file under ${prefix}/info.
+
+pacedump and pacetodc are not failing on an empty input file ... loop
+forever :(
+
+Clean up the use of C options (esp. defines) in imake stuff
+
+Make dctoraw work for other than -endian little (or at least where
+endian matches the ts) and 8 bit data.
+
+Check the use of Binary options vs. WithByteOrder, etc.
+
+Better implementation of attribute list ... sparse arrays with access
+and append cache ?
+
+Add to dcdisp
+	- annotation: side indicators
+	- save window/level'd image ...
+		- as DICOM with new attributes
+		- as something 8 bit
+
+The srcsink buffering stuff is still pretty horrible,
+especially wrt. checking premature eof ... probably should
+switch to bool rather than int and consider changing read()
+return value to flag rather than length. Note that currently
+read() will still be good and will return < chunksize bytes on
+last read (ie. byteswanted doesn't have to be multiple of chunksize);
+if read() is called again it will return 0 and set bad.
+However if less bytes returned than "expected", will set bad and
+return 0 immediately (though what was read will still be in the buffer
+and the getBufferCount() will be what was actually read).
+
+dccp from 12/16 bits to -r BitsAllocated 8 runs but image is wrong.
+This is not suprising, because in writing in attrothr.cc
+
+OtherUnspecifiedLargeAttributeBase::writeData(BinaryOutputStream& stream)
+{
+...
+	if (dstbytesinword == 1) {
+		Assert(dstbitsallocated == 8);	// No PackByte() yet !
+		ConvertUint16ToByte   tobyte   (*srcpixeldata,dstendian);
+		Sink<unsigned char>   output   (stream,tobyte);
+		output.write(dstlength);
+	}
+	else {
+		PackUint16            topack   (*srcpixeldata,dstbitsallocated);
+		ConvertUint16ToByte   tobyte   (topack,dstendian);
+		Sink<unsigned char>   output   (stream,tobyte);
+		output.write(dstlength);
+	}
+...
+
+ther is no shifting before topack, which just uses the low dstbitsallocated
+of the Unit16 to pack (topcak.cc line 149).
+
+Contrast this with copied reading:
+
+OtherUnspecifiedLargeAttributeCopied::activateSource(void)
+...
+		if (srcbytesinword == 1) {
+			Assert(srcbitsallocated == 8);	// No UnpackByte() yet !
+			Assert(!srcfrompack);
+			srcpixeldata=srcfrombyte;
+		}
+		else {
+			if (srcfrompack) delete srcfrompack;
+			srcfrompack = new UnpackUint16(*srcfrombyte,srcbitsallocated);
+			Assert(srcfrompack);
+			if (srcfromshift) delete srcfromshift;
+			srcfromshift = new UnshiftUint16(*srcfrompack,srcbitsallocated,srcbitsstored,srchighbit);
+			Assert(srcfromshift);
+			srcpixeldata=srcfromshift;
+		}
+
+where an UnshiftUint16 is done after unpacking.
+
+
+8 bit input with odd number of columns is wrong. For implicit VR where
+they need to be packed into OW's topack.c line 135 fails assertion. This
+affects pnmtodc
+
+Add MRDR support do dcdirdmp
+
+For dcdirdmp when an attribute for a dir record is missing, one
+still gets an assertion failure on string addValue() :(
+
+This should be cleaner !
+
+Also need to extend dir record types to handle RT that doesn't
+have images !
+
+Document raw tools in misc
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..2fc458f
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+1.00.snapshot.20151213160232
diff --git a/WARNINGS b/WARNINGS
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/WARNINGS
@@ -0,0 +1 @@
+
diff --git a/appsrc/Imakefile b/appsrc/Imakefile
new file mode 100755
index 0000000..b1493c4
--- /dev/null
+++ b/appsrc/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = acrnema dcdisp dcfile dcintro misc simple dconvert
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/appsrc/acrnema/Imakefile b/appsrc/acrnema/Imakefile
new file mode 100755
index 0000000..0837f75
--- /dev/null
+++ b/appsrc/acrnema/Imakefile
@@ -0,0 +1,73 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES = $(PROJECTAPPACRNEMAEXTRAINCLUDES)
+
+SRCSANCREATE = ancreate.cc
+OBJSANCREATE = ancreate.o
+
+SRCSANDUMP = andump.cc
+OBJSANDUMP = andump.o
+
+SRCSANCP = ancp.cc
+OBJSANCP = ancp.o
+
+CPLUSPLUS_SRCS = $(SRCSANCREATE) $(SRCSANDUMP) $(SRCSANCP)
+OBJS           = $(OBJSANCREATE) $(OBJSANDUMP) $(OBJSANCP)
+
+AllTarget(ancreate)
+NormalCCProgramTarget(ancreate,$(OBJSANCREATE),$(PROJECTACRNEMADEPLIBS),$(PROJECTACRNEMALIBS),-lm)
+InstallProgram(ancreate,$(INSTALLBINDIR))
+InstallManPage(ancreate,$(INSTALLMANDIR)/man1)
+
+AllTarget(andump)
+NormalCCProgramTarget(andump,$(OBJSANDUMP),$(PROJECTACRNEMADEPLIBS),$(PROJECTACRNEMALIBS),-lm)
+InstallProgram(andump,$(INSTALLBINDIR))
+InstallManPage(andump,$(INSTALLMANDIR)/man1)
+
+AllTarget(ancp)
+NormalCCProgramTarget(ancp,$(OBJSANCP),$(PROJECTACRNEMADEPLIBS),$(PROJECTACRNEMALIBS),-lm)
+InstallProgram(ancp,$(INSTALLBINDIR))
+InstallManPage(ancp,$(INSTALLMANDIR)/man1)
+
+InstallScript(andiff,$(INSTALLBINDIR))
+InstallManPage(andiff,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@./test.create.ut.sh compare
+	@./test.create.private.un.sh compare
+	@$(TOP)/support/testapp testlist ./andump "" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./andump "" $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare dump
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@$(TOP)/support/testapp testlist ./ancp "-d PatientName -d PatientBirthDate -d PatientSex -d PatientAge -d StudyDate -removeprivate -removeinstanceuid"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare ancp
+	@$(TOP)/support/testapp testlist ./ancp "-d PatientName -d PatientBirthDate -d PatientSex -d PatientAge -d StudyDate -removeprivate -removeinstanceuid"      $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare ancp
+	
+
+test.create::
+	@./test.create.ut.sh create
+	@./test.create.private.un.sh create
+	@$(TOP)/support/testapp testlist ./andump "" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./andump "" $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create dump
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./andump "" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@$(TOP)/support/testapp testlist ./ancp "-d PatientName -d PatientBirthDate -d PatientSex -d PatientAge -d StudyDate -removeprivate -removeinstanceuid"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create ancp
+	@$(TOP)/support/testapp testlist ./ancp "-d PatientName -d PatientBirthDate -d PatientSex -d PatientAge -d StudyDate -removeprivate -removeinstanceuid"      $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create ancp
+
+testcompareandcwithoriginal:
+	for i in `cat $(TOP)/images/acrnema/testlist` ; \
+	do \
+		echo "acrnema/$$i"; \
+		andiff $(TOP)/images/acrnema/$$i $(TOP)/test/$(CURRENT_DIR)/`echo $$i | sed 's:/:.:g'`.ancp.ancp.outfile; \
+	done
+	for i in `cat $(TOP)/images/dicom/testlist`; \
+	do \
+		echo "dicom/$$i"; \
+		andiff $(TOP)/images/dicom/$$i $(TOP)/test/$(CURRENT_DIR)/`echo $$i | sed 's:/:.:g'`.ancp.ancp.outfile; \
+	done
+
diff --git a/appsrc/acrnema/ancp.cc b/appsrc/acrnema/ancp.cc
new file mode 100644
index 0000000..c5e4fcc
--- /dev/null
+++ b/appsrc/acrnema/ancp.cc
@@ -0,0 +1,446 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ancp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#include <cctype>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtag.h"
+#include "dcstream.h"
+#include "dcopt.h"
+#include "ioopt.h"
+#include "elmconst.h"
+#include "elmdict.h"
+#include "mesgtext.h"
+
+static Uint16
+extract16(const char *buffer,Endian endian)
+{
+	Assert(endian!=NoEndian);
+	Uint16 u;
+	if (endian == BigEndian) {
+		u =  (Uint16)((unsigned char *)buffer)[0];
+		u <<= 8;
+		u |= (Uint16)((unsigned char *)buffer)[1];
+	}
+	else {
+		u =  (Uint16)((unsigned char *)buffer)[1];
+		u <<= 8;
+		u |= (Uint16)((unsigned char *)buffer)[0];
+	}
+	return u;
+}
+
+static Uint32
+extract32(const char *buffer,Endian endian,bool swapped32big)
+{
+	Assert(endian!=NoEndian);
+	Uint32 u;
+	if (endian == BigEndian) {
+		if (swapped32big) {
+			u =  (Uint32)((unsigned char *)buffer)[2];
+			u <<= 8;
+			u |= (Uint32)((unsigned char *)buffer)[3];
+			u <<= 8;
+			u |= (Uint32)((unsigned char *)buffer)[0];
+			u <<= 8;
+			u |= (Uint32)((unsigned char *)buffer)[1];
+		}
+		else {
+			u =  (Uint32)((unsigned char *)buffer)[0];
+			u <<= 8;
+			u |= (Uint32)((unsigned char *)buffer)[1];
+			u <<= 8;
+			u |= (Uint32)((unsigned char *)buffer)[2];
+			u <<= 8;
+			u |= (Uint32)((unsigned char *)buffer)[3];
+		}
+	}
+	else {
+		u =  (Uint32)((unsigned char *)buffer)[3];
+		u <<= 8;
+		u |= (Uint32)((unsigned char *)buffer)[2];
+		u <<= 8;
+		u |= (Uint32)((unsigned char *)buffer)[1];
+		u <<= 8;
+		u |= (Uint32)((unsigned char *)buffer)[0];
+	}
+	return u;
+}
+
+static bool
+copyAll(DicomInputStream& in,ostream& out,TextOutputStream& log,ElementDictionary& dict,
+		AttributeList *replaceafterlist,AttributeList *replacebeforelist,AttributeList *deletelist,
+		bool removeprivate,bool removeinstanceuid)
+{
+//cerr << "copyAll(): start" << endl;
+	if (in.haveMetaHeader()) {
+		char buffer[132];
+		char *ptr=buffer;
+		for (int i=0; i<128; ++i) {
+			*ptr++=0;
+		}
+		buffer[128]='D';
+		buffer[129]='I';
+		buffer[130]='C';
+		buffer[131]='M';
+		out.write(buffer,132);
+	}
+	
+	bool lastwasencapOXorItem=false;
+	bool donewithmetaheader=false;
+	while (in.peek() != istream::traits_type::eof()) {
+		Endian endian = in.getEndian();			// update each time through in case changed after metaheader
+		bool swapped32big = in.isSwapped32Big();
+		char buffer[6];
+		in.read(buffer,4);
+		if (in.fail()) {
+			cerr << EMsgDC(TagReadFailed) << endl;
+			return false;
+		}
+		Uint16 group = extract16(buffer,endian);
+		Uint16 element = extract16(buffer+2,endian);
+		Tag tag(group,element);
+//tag.write(log,&dict);
+//cerr << endl;
+		if (!donewithmetaheader && !tag.isMetaheaderGroup()) {
+//cerr << "Not done with meta header and no longer meta header group" << endl;
+			if (in.getTransferSyntaxToReadDataSet()) {
+				in.readingDataSet();
+				donewithmetaheader=true;
+				// backup and read again in case endian changed ...
+				in.seekg(-4l,ios::cur);
+				if (in.fail()) {
+					cerr << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+					return false;
+				}
+				in.read(buffer,4);
+				if (in.fail()) {
+					cerr << EMsgDC(TagReadFailed) << endl;
+					return false;
+				}
+				endian = in.getEndian();			// don't forget to actually update each time through in case changed after metaheader
+				group = extract16(buffer,endian);
+				element = extract16(buffer+2,endian);
+			}
+			else {
+				cerr << EMsgDC(NoTransferSyntaxInMetaHeader) << endl;
+				return false;
+			}
+		}
+		out.write(buffer,4);			// we always write - "deletion" is actually replacement by null
+		
+		char vre[3];
+		const char *vr;
+		Uint32 vl;
+
+		if (tag == TagFromName(ItemDelimitationItem)
+		 || tag == TagFromName(SequenceDelimitationItem)
+		 || tag == TagFromName(Item)) {
+			vr=0;
+			in.read(buffer,4);
+			if (in.fail()) {
+				cerr << EMsgDC(VLReadFailed) << endl;
+				return false;
+			}
+			out.write(buffer,4);
+			vl = extract32(buffer,endian,swapped32big);
+		}
+		else  {
+			if (in.getTransferSyntaxInUse()->isExplicitVR()) {
+//cerr << "Explicit VR" << endl;
+				in.read(vre,2);
+				if (in.fail()) {
+					cerr << EMsgDC(VRReadFailed) << endl;
+					return false;
+				}
+				out.write(vre,2);
+				vre[2]=0;
+//cerr << "Explicit VR is " << vre[0] << vre[1] << endl;
+				vr=vre;
+				if (vr[0] == 0 && vr[1] == 0) {			// illegal two bytes of zero VR encountered in Sante de-identifier output (followed by two byte length) (000471)
+					vr="UN";
+					in.read(buffer,2);
+					if (in.fail()) {
+						cerr << EMsgDC(VLReadFailed) << endl;
+						return false;
+					}
+					out.write(buffer,2);
+					vl = extract16(buffer,endian);
+				}
+				else if (vr[0] < 'A' || vr[1] < 'A') {		// DicomWorks bug ... occasional implicit VR attribute even though explicit transfer syntax (000470)
+//cerr << "Implicit VR encoding when Explicit required" << endl;
+					vr="UN";
+					buffer[0] = vre[0];		// first two bytes of VL are not VR after all
+					buffer[1] = vre[2];
+					in.read(buffer+2,2);	// read two more bytes to get 4 byte implicit VL
+					if (in.fail()) {
+						cerr << EMsgDC(VLReadFailed) << endl;
+						return false;
+					}
+					out.write(buffer+2,2);
+					vl = extract32(buffer,endian,swapped32big);
+				}
+				else if (isUniversalResourceVR(vr) || isUnlimitedCharactersVR(vr) || isUnlimitedTextVR(vr) || isUnknownVR(vr)) {
+//cerr << "Checking for possible incorrect short rather than long form of VL" << endl;
+					in.read(buffer,2);
+					if (in.fail()) {
+						cerr << EMsgDC(VLReadFailed) << endl;
+						return false;
+					}
+					out.write(buffer,2);
+					vl = extract16(buffer,endian);
+					if (vl == 0) {		// if reserved bytes not zero, assume used for short form of length (risky) :(
+//cerr << "Reserved bytes are zero" << endl;
+						in.read(buffer,4);	// VL
+						if (in.fail()) {
+							cerr << EMsgDC(VLReadFailed) << endl;
+							return false;
+						}
+						out.write(buffer,4);
+						vl = extract32(buffer,endian,swapped32big);
+					}
+					else {
+//cerr << "Reserved bytes are not zero - using vl of " << dec << vl << endl;
+						cerr << EMsgDC(IncorrectShortVLForUTOrUN) << endl;
+					}
+				}
+				else if (isLongValueLengthInExplicitValueRepresentation(vr)) {		// some of these already handled above
+//cerr << "Not checking for possible incorrect short rather than long form of VL" << endl;
+					in.read(buffer,6);	// "Reserved" + VL
+					if (in.fail()) {
+						cerr << EMsgDC(VLReadFailed) << endl;
+						return false;
+					}
+					out.write(buffer,6);
+					vl = extract32(buffer+2,endian,swapped32big);
+				}
+				else {
+					in.read(buffer,2);
+					if (in.fail()) {
+						cerr << EMsgDC(VLReadFailed) << endl;
+						return false;
+					}
+					out.write(buffer,2);
+					vl = extract16(buffer,endian);
+				}
+			}
+			else {
+				vr=(tag.isPrivateGroup() && tag.isPrivateOwner())
+					? "LO"	// PS3.5-7.8.1
+					: dict.getValueRepresentation(tag);
+				in.read(buffer,4);
+				if (in.fail()) {
+					cerr << EMsgDC(VLReadFailed) << endl;
+					return false;
+				}
+				out.write(buffer,4);
+				vl = extract32(buffer,endian,swapped32big);
+			}
+		}
+//if (vr) cerr << "VR = " << vr[0] << vr[1] << endl; else cerr << "VR missing" << endl;
+//cerr << "VL = " << dec << vl << endl;
+		
+		if (vl == 0xffffffff		// SQ or OX both will contain items
+		 || vl == 0			// includes ItemDelimitationItem,SequenceDelimitationItem
+		 || isSequenceVR(vr)		// SQ with defined length
+		 || (tag == TagFromName(Item) && !lastwasencapOXorItem)	// Item with element contents
+		) {
+			// do nothing ... we have already written all there is to this element
+		}
+		else {
+			bool zeroThisElement = (deletelist && (*deletelist)[tag])
+					    || (replaceafterlist && (*replaceafterlist)[tag])
+					    || (replacebeforelist && (*replacebeforelist)[tag])
+					    || (removeprivate && tag.isPrivateGroup() && !tag.isPrivateOwner() && !tag.isLengthElement())
+					    || (removeinstanceuid && isUIStringVR(vr)
+					        && tag != TagFromName(TransferSyntaxUID)
+					        && tag != TagFromName(SOPClassUID)
+					        && tag != TagFromName(MediaStorageSOPClassUID)
+					        && tag != TagFromName(ImplementationClassUID)
+					       )
+					    ;
+
+			if (isStringVR(vr)) {
+//cerr << "isStringVR" << endl;
+				char buffer[vl+1];
+				in.read(buffer,vl);
+				buffer[vl]=0;
+				if (in.fail() || in.gcount() != vl) {
+					cerr << EMsgDC(ReadFailed) << endl;
+					return false;
+				}
+				else {
+					if (!zeroThisElement) {
+						out.write(buffer,vl);
+					}
+					// else replacement written later after we are finished with value in buffer
+					char *ptr=buffer+vl;
+					while (ptr >= buffer && (*ptr == 0 || isspace(*ptr))) *ptr--=0;		// null trailing spaces
+					ptr=buffer;
+					while (*ptr && isspace(*ptr)) ++ptr;					// skip leading spaces
+					if (*ptr) {												// only if not empty string
+						if (tag == TagFromName(TransferSyntaxUID)) {
+							in.setTransferSyntaxToReadDataSet(new TransferSyntax(ptr));
+						}
+						else if (tag.isPrivateGroup() && tag.isPrivateOwner()) {
+							dict.addOwner(tag,ptr);
+						}
+					}
+					if (zeroThisElement) {
+						if (isAgeStringVR(vr) && vl == 4) {
+							const char *replacementString = "000Y";
+							out.write(replacementString,vl);
+						}
+						else if (isDateStringVR(vr) && vl == 8) {
+							const char *replacementString = "19000101";
+							out.write(replacementString,vl);
+						}
+						else if (isDateStringVR(vr) && vl == 10) {
+							const char *replacementString = "1900.01.01";
+							out.write(replacementString,vl);
+						}
+						else if (isTimeStringVR(vr) && vl <= 14) {
+							const char *replacementString = "000000.000000 ";
+							out.write(replacementString,vl);
+						}
+						else if (isTimeStringVR(vr) && vl <= 16) {
+							const char *replacementString = "00:00:00.0000000 ";
+							out.write(replacementString,vl);
+						}
+						else if (isDateTimeStringVR(vr) && vl <= 26) {
+							const char *replacementString = "19000101000000.000000+0000";
+							out.write(replacementString,vl);
+						}
+						else if (isUIStringVR(vr) && vl <= 64) {
+							const char *replacementString = "1234567891234567891234567891234567891234567891234567891234567891";
+							Assert(strlen(replacementString) == 64);
+							out.write(replacementString,vl);
+						}
+						else if (tag == TagFromName(PatientSex) && vl == 2) {
+							const char *replacementString = "O ";
+							out.write(replacementString,vl);
+						}
+						else {
+							long lengthToReplace = vl;
+							bool numeric = isNonOtherNumericOrDateOrTimeOrUIStringVR(vr) || (*buffer && isdigit(*buffer));	// e.g. for a string private attribute
+							char replacementValue = numeric ? '1' : 'X';
+							char subsequentReplacementValue = numeric ? ' ' : 'X';
+							char *ptr=buffer;
+							for (long i=0; i<lengthToReplace; ++i) {
+								*ptr++=replacementValue;
+								replacementValue=subsequentReplacementValue;
+							}
+							out.write(buffer,vl);
+						}
+					}
+				}
+			}
+			else {
+				if (zeroThisElement) {
+					long lengthToReplace = vl;
+					char replacementValue = 0;
+					char buffer[1];					// blech - could be faster :(
+					for (long i=0; i<lengthToReplace; ++i) {
+						in.read(buffer,1);
+						if (in.fail()) {
+							cerr << EMsgDC(ReadFailed) << endl;
+							return false;
+						}
+						buffer[0] = replacementValue;
+						out.write(buffer,1);
+					}
+				}
+				else {
+					long lengthToCopy = vl;
+					size_t bufsize=1000;
+					char buffer[bufsize];
+					while (lengthToCopy > 0) {
+						in.read(buffer,lengthToCopy < bufsize ? lengthToCopy : bufsize);
+						size_t count = in.gcount();
+						if (count > 0) {
+							out.write(buffer,count);
+							lengthToCopy-=count;
+						}
+						else {
+							break;
+						}
+					}
+					if (in.fail() || lengthToCopy > 0) {
+						cerr << EMsgDC(ReadFailed) << endl;
+						return false;
+					}
+				}
+			}
+		}
+		lastwasencapOXorItem=
+			(isOtherByteOrWordOrUnspecifiedVR(vr)
+			 || tag == TagFromName(Item)
+			 || tag == TagFromName(ItemDelimitationItem)
+			) && in.getTransferSyntaxInUse()->isEncapsulated();
+	}
+	return true;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions    	options(argc,argv);
+	DicomInputOptions 	input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << options.errors();
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		input_options.transfersyntaxuid,
+		input_options.usemetaheader);
+	ostream out(output_opener);
+	TextOutputStream log(cerr);
+	ElementDictionary dictionary;
+
+	copyAll(din,out,log,dictionary,
+		dicom_output_options.replaceafterlist,dicom_output_options.replacebeforelist,dicom_output_options.deletelist,
+		dicom_output_options.removeprivate,dicom_output_options.removeinstanceuid);
+}
+
+
+
diff --git a/appsrc/acrnema/ancp.man b/appsrc/acrnema/ancp.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/acrnema/ancreate.cc b/appsrc/acrnema/ancreate.cc
new file mode 100644
index 0000000..809812a
--- /dev/null
+++ b/appsrc/acrnema/ancreate.cc
@@ -0,0 +1,703 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ancreate.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#include <cctype>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+//#include <string.h>
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "txstream.h"
+#include "getoptns.h"
+#include "mesgtext.h"
+#include "vr.h"
+
+#define INPUTLINEBUFFERLENGTH 32768
+
+// all the following is copied from dconvert/fltype.h
+
+#include <float.h>
+
+#ifdef POWINTEGEREXPONENTTYPE
+#define	powi(m,e)	pow(m,(POWINTEGEREXPONENTTYPE)(e))
+#else
+#define	powi(m,e)	pow(m,(long)(e))
+#endif
+
+#ifdef __SC__
+#define infinity()    HUGE_VAL
+#define quiet_nan(x)  0
+#endif /* __SC__ */
+
+#ifdef __MWERKS__
+#define infinity()    __inf()
+#define quiet_nan(x)  0
+#endif /* __MWERKS__ */
+
+#ifdef USEDUMBINFINITYANDNAN
+#if USEDUMBINFINITYANDNAN
+#define infinity()    FLT_MAX
+#define quiet_nan(x)  0
+#endif
+#endif
+
+
+static void
+write32(ostream& out,Uint32 u,int big)
+{
+//cerr << "write32 0x" << hex << u << dec << endl;
+	unsigned char buffer[4];
+	if (big) {
+		buffer[0]=(unsigned char)(u>>24);
+		buffer[1]=(unsigned char)(u>>16);
+		buffer[2]=(unsigned char)(u>>8);
+		buffer[3]=(unsigned char)u;
+	}
+	else {
+		buffer[3]=(unsigned char)(u>>24);
+		buffer[2]=(unsigned char)(u>>16);
+		buffer[1]=(unsigned char)(u>>8);
+		buffer[0]=(unsigned char)u;
+	}
+	out.write((char *)buffer,4);
+}
+
+static void
+write16(ostream& out,Uint16 u,int big)
+{
+	unsigned char buffer[4];
+	if (big) {
+		buffer[0]=(unsigned char)(u>>8);
+		buffer[1]=(unsigned char)u;
+	}
+	else {
+		buffer[1]=(unsigned char)(u>>8);
+		buffer[0]=(unsigned char)u;
+	}
+	out.write((char *)buffer,2);
+}
+
+static void
+write8(ostream& out,unsigned char u)
+{
+	unsigned char buffer[1];
+	buffer[0]=u;
+	out.write((char *)buffer,1);
+}
+
+static void
+writeFloat64(ostream& out,double value,int big) {
+//cerr << "writeFloat64: " << value << endl;
+
+	// copied from libsrc/include/dctool/attrtypf.h newSize8Value()
+
+	Uint32 sign=0;
+	Int32 exponent;
+	Uint32 mantissahigh;
+	Uint32 mantissalow;
+
+	if (value < 0) {
+		sign=0x80000000;
+		value=-value;
+	}
+
+	if (value == 0) {
+		exponent=0;
+		mantissahigh=0;
+		mantissalow=0;
+	}
+	else {
+		exponent=(int)ourlog2(value);
+		if (value < 1) --exponent;
+		if (exponent <= -1022) {
+			double mantissavalue = value/pow(2,-1022);
+			mantissahigh=(Uint32)(mantissavalue*powi(2.0,20));
+			mantissalow =(Uint32)(mantissavalue*powi(2.0,52));
+			exponent=0;
+		}
+		else {
+			if (exponent > 1023) exponent=1023;
+			double mantissavalue = value/pow(2,exponent) - 1.0;
+			mantissahigh=(Uint32)(mantissavalue*powi(2.0,20));
+			mantissalow =(Uint32)(mantissavalue*powi(2.0,52));
+			exponent=((exponent+1023)<<20)&0x7ff00000;
+		}
+	}
+
+	Uint32 binaryhigh=sign+exponent+mantissahigh;
+
+	unsigned char *barray = new unsigned char[8];
+	if (big) {
+		barray[0]=(unsigned char)(binaryhigh>>24);
+		barray[1]=(unsigned char)(binaryhigh>>16);
+		barray[2]=(unsigned char)(binaryhigh>>8);
+		barray[3]=(unsigned char)(binaryhigh);
+		barray[4]=(unsigned char)(mantissalow>>24);
+		barray[5]=(unsigned char)(mantissalow>>16);
+		barray[6]=(unsigned char)(mantissalow>>8);
+		barray[7]=(unsigned char)(mantissalow);
+	}
+	else {
+		barray[7]=(unsigned char)(binaryhigh>>24);
+		barray[6]=(unsigned char)(binaryhigh>>16);
+		barray[5]=(unsigned char)(binaryhigh>>8);
+		barray[4]=(unsigned char)(binaryhigh);
+		barray[3]=(unsigned char)(mantissalow>>24);
+		barray[2]=(unsigned char)(mantissalow>>16);
+		barray[1]=(unsigned char)(mantissalow>>8);
+		barray[0]=(unsigned char)(mantissalow);
+	}
+	out.write((char *)barray,8);
+}
+
+static void
+writeFloat32(ostream& out,float value,int big) {
+//cerr << "writeFloat32: " << f << endl;
+
+	// copied from libsrc/include/dctool/attrtypf.h newSize4Value()
+	
+	Uint32 sign=0;
+	Int32 exponent;
+	Uint32 mantissa;
+
+	if (value < 0) {
+		sign=0x80000000;
+		value=-value;
+	}
+
+	if (value == 0) {
+		exponent=0;
+		mantissa=0;
+	}
+	else {
+		exponent=(int)ourlog2(value);
+		if (value < 1) --exponent;
+		if (exponent <= -126) {
+			mantissa=(Uint32)((value/pow(2,-126))*(1<<23));
+			exponent=0;
+		}
+		else {
+			if (exponent > 127) exponent=127;
+			mantissa=(Uint32)(((value/pow(2,exponent))-1)*(1<<23));
+			exponent=((exponent+127)<<23)&0x7f800000;
+		}
+	}
+
+	Uint32 binary=sign+exponent+mantissa;
+
+	unsigned char *barray = new unsigned char[4];
+	if (big) {
+		barray[0]=(unsigned char)(binary>>24);
+		barray[1]=(unsigned char)(binary>>16);
+		barray[2]=(unsigned char)(binary>>8);
+		barray[3]=(unsigned char)(binary);
+	}
+	else {
+		barray[3]=(unsigned char)(binary>>24);
+		barray[2]=(unsigned char)(binary>>16);
+		barray[1]=(unsigned char)(binary>>8);
+		barray[0]=(unsigned char)(binary);
+	}
+	out.write((char *)barray,4);
+}
+
+/* Recognized commands are:
+
+(hex group,hex element) anything VR=<vr> VL=<hex vl> [hexvals]
+(hex group,hex element) anything VR=<vr> VL=<hex vl> <strvals>
+%implicit
+%explicit
+%little
+%big
+
+%item
+%enditem
+%endseq
+
+datavalues
+
+VL will be replaced with actual VL unless OB,OW or SQ
+
+*/
+
+static void
+parseError(const char *str,char c)
+{
+	cerr << "Parse error in entry - \"" << str 
+	     << "\" expected, got \'" << c << "\'\n" << flush;
+}
+
+static int
+getCommand(istream& in)
+{
+	int command=0;
+	const unsigned buflng = 10;
+	char buffer[buflng];
+		char c;
+		do {
+			in >> c;
+			if (!in.good()) return 0;
+		} while (isspace(c));
+		if (c == '#') {					// start of comment
+			do {					// skip to end of line
+				in >> c;
+				if (!in.good()) return 0;
+			} while (c != '\n' && c != '\r');
+			do {					// skip ends of lines
+				in >> c;
+				if (!in.good()) return 0;
+			} while (c == '\n' || c == '\r');
+		}
+		// c should now be non-white space beginning of command
+		switch (c) {
+			case '(':
+				command='(';
+				break;
+			case '%':
+				in >> setw(buflng-1) >> buffer;
+				if (!in.good()) break;
+				if (strcmp(buffer,"implicit") == 0) command='i';
+				if (strcmp(buffer,"explicit") == 0) command='e';
+				if (strcmp(buffer,"little") == 0)   command='l';
+				if (strcmp(buffer,"big") == 0)      command='b';
+				if (strcmp(buffer,"byte") == 0)     command='B';
+				if (strcmp(buffer,"short") == 0)    command='S';
+				if (strcmp(buffer,"word") == 0)     command='S';
+				if (strcmp(buffer,"long") == 0)     command='L';
+				if (strcmp(buffer,"item") == 0)     command='T';
+				if (strcmp(buffer,"enditem") == 0)  command='M';
+				if (strcmp(buffer,"endseq") == 0)   command='Q';
+				break;
+			default:
+				if (isdigit(c)) {
+					command=c;
+					in.putback(c);
+				}
+				else {
+					parseError("attribute,command or value",
+						c);
+				}
+				break;
+		}
+	return command;
+}
+
+static void
+getFloat64FromString(istream& in,double &d) {
+	in >> dec >> d;
+}
+
+static void
+getFloat32FromString(istream& in,float &f) {
+	in >> dec >> f;
+}
+
+static void
+getHex32(istream& in,Uint32& v)
+{
+	char c;
+	int i;
+
+	in >> hex >> v;
+	if (v == 0 && (i=in.peek()) == 'x') {
+		in.get(c);
+		in >> hex >> v;
+	}
+	// this check seems to fail on trailing ']' delimiter with gcc 3 :(
+	//if (!in.good()) {
+	//	parseError("hex number",0);
+	//}
+}
+
+static void
+getHex16(istream& in,Uint16& v)
+{
+	Uint32 v32;
+	getHex32(in,v32);
+	v=(Uint16)v32;
+}
+
+
+static int
+getParsedEntry(istream& in,Uint16& group,Uint16& element,
+	char *VR,Uint32& VL,int& valuetype,char **valuestring,bool verbose,int commandcount)
+{
+	char c;
+	const unsigned buflng = INPUTLINEBUFFERLENGTH;
+	char buffer[buflng];	// enough for longest value string
+	char *p;
+
+	// First '(' has already been read as command
+
+	// Find "nnnn,nnnn)" ...
+
+	in >> resetiosflags(ios::basefield) >> group;
+	if (!in.good()) {
+		return -1;	// Failure
+	}
+	in >> c;
+	if (c != ',') {
+		parseError(",",c);
+		return -1;	// Failure
+	}
+	in >> resetiosflags(ios::basefield) >> element;
+	if (!in.good()) {
+		return -1;	// Failure
+	}
+	in >> c;
+	if (c != ')') {
+		parseError(")",c);
+		return -1;	// Failure
+	}
+
+	if (verbose) {
+		cerr << dec << commandcount << ": (";
+		writeZeroPaddedHexNumber(cerr,group,4);
+		cerr << ",";
+		writeZeroPaddedHexNumber(cerr,element,4);
+		cerr << ") " << endl;
+	}
+
+	// Skip any fields (eg. from dc3dump) found "VR=<xx>" ...
+	do {
+		in >> buffer;
+	} while (in.good() && strncmp(buffer,"VR",2) != 0);
+
+	if (!in.good()) {
+		parseError("VR",0);
+		return -1;	// Failure
+	}
+	for (p=buffer; *p && *p != '<';++p);
+	strncpy(VR,p+1,2);
+	VR[2]=0;
+	if (*(p+3) != '>') {
+		parseError("> after VR",*(p+3));
+		return -1;	// Failure
+	}
+
+	// Find "VL=<nn>" ... 	(nn is in hex)
+
+	do {
+		in >> buffer;
+	} while (in.good() && strncmp(buffer,"VL",2) != 0);
+
+	if (!in.good()) {
+		parseError("VL",0);
+		return -1;	// Failure
+	}
+	for (p=buffer; *p && *p != '<';++p);
+	istrstream istr(p+1);
+	istr >> resetiosflags(ios::basefield) >> VL;
+//cerr << "vl=" << VL << endl;
+	if (!istr.good()) {
+		return -1;	// Failure
+	}
+ 	istr >> c;
+	if (c != '>') {
+		parseError("> after VL",c);
+		return -1;	// Failure
+	}
+
+	in >> c;
+	char traildelim;
+	switch (c) {
+		case '<':
+			traildelim='>';
+			break;
+		case '[':
+			traildelim=']';
+			break;
+		case '{':
+			traildelim='}';
+			break;
+		default:
+			parseError("<values> or [values] or {values}",c);
+			return -1;	// Failure
+	}
+	valuetype=c;
+	for (p=buffer; p<buffer+buflng; ++p) {
+		in.get(c);	// Don't skip whitespace
+		if (!in.good()) {
+			parseError("> or ] or } after value",0);
+			return -1;	// Failure
+		}
+		else {
+			if (c == traildelim) {
+				*p=0;
+				break;
+			}
+			else {
+				*p=c;
+			}
+		}
+	}
+	*valuestring=new char[strlen(buffer)+1];
+	strcpy(*valuestring,buffer);
+
+	return 0;		// Success
+}
+
+static void
+writeAttribute(ostream& out,Uint16 group,Uint16 element,
+	const char *vr,Uint32 vl,int type,char *string,
+	int explicitvr,int big)
+{
+	write16(out,group,big);
+	write16(out,element,big);
+
+	Uint32 actualvl;
+	switch (type) {
+		case '<':	// string
+			if ((actualvl=strlen(string))%2) ++actualvl;
+			break;
+		case '[':	// hex
+			if (*string) {
+				char *p;
+				for (actualvl=1,p=string; *p; ++p)
+					if (!isxdigit(*p) && *p != 'x' && !isspace(*p)) 
+						++actualvl;
+			}
+			else actualvl=0;
+			actualvl*=(vr[1] == 'L')?4:2;
+			break;
+		case '{':	// float
+			if (*string) {
+				char *p;
+				for (actualvl=1,p=string; *p; ++p)
+					if (!isdigit(*p) && *p != '.' && *p != '-' && *p != 'e' && *p != 'E' && !isspace(*p)) 
+						++actualvl;
+			}
+			else actualvl=0;
+			actualvl*=(vr[1] == 'D')?8:4;
+			break;
+	}
+
+	if (actualvl != vl) {
+		if (isOtherByteOrLongOrWordOrFloatOrDoubleVR(vr) || isSequenceVR(vr)) {
+			actualvl=vl;
+		}
+		else {
+			cerr << "Specified VL ";
+			writeZeroPaddedHexNumber(cerr,vl,8);
+			cerr << " wrong, using ";
+			writeZeroPaddedHexNumber(cerr,actualvl,8);
+			cerr << " (VR is " << vr << ")\n" << flush;
+			//cerr << "VR[0]=" << (unsigned)(vr[0]) << endl;
+			//cerr << "VR[1]=" << (unsigned)(vr[1]) << endl;
+			//cerr << "VR[2]=" << (unsigned)(vr[2]) << endl;
+		}
+	}
+
+	if (explicitvr) {
+		out.write(vr,2);			// 2 byte explicitvr vr
+		if (isLongValueLengthInExplicitValueRepresentation(vr)) {
+			write16(out,0,big);		// 2 byte reserved
+			write32(out,actualvl,big);	// 4 byte value length
+		}
+		else {
+			write16(out,(Uint16)actualvl,big);	// 2 byte length
+		}
+	}
+	else {
+		write32(out,actualvl,big);
+	}
+
+	char pad = isUIStringVR(vr) ? 0 : ' ';
+	switch (type) {
+		case '<':	// string
+			out << string;
+			if (strlen(string)%2) out << pad;
+			break;
+		case '[':	// hex
+			if (*string) {
+				istrstream istr(string);
+				while (istr.good()) {
+					Uint32 u;
+					char c;
+					getHex32(istr,u);
+					istr >> c;		// delimiter
+					if (vr[1] == 'B')
+						write8(out,(unsigned char)u);
+					else if (vr[1] == 'L')
+						write32(out,u,big);
+					else
+						write16(out,(Uint16)u,big);
+				}
+			}
+			break;
+		case '{':	// float
+			if (*string) {
+				istrstream istr(string);
+				while (istr.good()) {
+					if (vr[1] == 'D') {
+						double d;
+						getFloat64FromString(istr,d);
+						char c;
+						istr >> c;		// delimiter
+						writeFloat64(out,d,big);
+					}
+					else {
+						float f;
+						getFloat32FromString(istr,f);
+						char c;
+						istr >> c;		// delimiter
+						writeFloat32(out,f,big);
+					}
+				}
+			}
+			break;
+	}
+}
+
+static void
+writeItem(ostream& out,int explicitvr,int big)
+{
+	write16(out,0xfffe,big);
+	write16(out,0xe000,big);
+	write32(out,0xffffffff,big);
+}
+
+static void
+writeItemDelimiter(ostream& out,int explicitvr,int big)
+{
+	write16(out,0xfffe,big);
+	write16(out,0xe00d,big);
+	write32(out,0x00000000,big);
+}
+
+static void
+writeSequenceDelimiter(ostream& out,int explicitvr,int big)
+{
+	write16(out,0xfffe,big);
+	write16(out,0xe0dd,big);
+	write32(out,0x00000000,big);
+}
+
+static void
+writePreamble(ostream& out)
+{
+	char zeroes[128];
+	memset(zeroes,0,128);
+	out.write(zeroes,128);
+	out.write("DICM",4);
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions options(argc,argv);
+	bool explicitvr	=options.get("explicit")||options.get("e");
+	bool big	=options.get("big")||options.get("b");
+	if (big) explicitvr=true;
+
+	bool preamble=options.get("preamble")||options.get("p");
+
+	bool verbose=options.get("verbose")||options.get("v");
+
+	options.done();
+
+	cerr << options.errors();
+
+	if (!options.good() || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< " [-b|big]"
+			<< " [-e|explicit]"
+			<< " [-p|preamble]"
+			<< " [-v|verbose]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (preamble) {
+		writePreamble(cout);
+	}
+
+	int datawordlength=1;
+	int commandcount=0;
+	int command;
+	while (command=getCommand(cin)) {
+		++commandcount;
+		Uint16 group;
+		Uint16 element;
+		char vr[3];
+		Uint32 vl;
+		int type;
+		char *string;
+		switch (command) {
+			case '(':
+				if (getParsedEntry(cin,group,element,
+						vr,vl,type,&string,verbose,commandcount) == 0) {
+					writeAttribute(cout,group,element,
+						vr,vl,type,string,
+						explicitvr,big);
+				}
+				if (strcmp(vr,"OB") == 0) { datawordlength=1; }
+				else if (strcmp(vr,"OW") == 0) { datawordlength=2; }
+				else if (strcmp(vr,"OL") == 0) { datawordlength=4; }
+				break;
+			case 'i':
+				explicitvr=0;
+				break;
+			case 'e':
+				explicitvr=1;
+				break;
+			case 'l':
+				big=0;
+				break;
+			case 'b':
+				big=1;
+				explicitvr=1;	// no such thing as implicit big
+				break;
+			case 'B':
+				datawordlength=1;
+				break;
+			case 'S':
+				datawordlength=2;
+				break;
+			case 'L':
+				datawordlength=4;
+				break;
+			case 'T':
+				writeItem(cout,explicitvr,big);
+				break;
+			case 'M':
+				writeItemDelimiter(cout,explicitvr,big);
+				break;
+			case 'Q':
+				writeSequenceDelimiter(cout,explicitvr,big);
+				break;
+			default:
+				if (isdigit(command)) {
+					Uint32 value;
+					cin >> resetiosflags(ios::basefield)
+					    >> value;
+					switch (datawordlength) {
+						case 1:
+							cout.put((char)value);
+							break;
+						case 2:
+							write16(cout,
+							    (Uint16)value,big);
+							break;
+						case 4:
+							write32(cout,value,big);
+							break;
+					}
+				}
+				break;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/acrnema/ancreate.man b/appsrc/acrnema/ancreate.man
new file mode 100755
index 0000000..0f4815a
--- /dev/null
+++ b/appsrc/acrnema/ancreate.man
@@ -0,0 +1,266 @@
+.TH ANCREATE 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Create dicom file"
+.SH NAME
+ancreate \- ACR/NEMA DICOM PS3 ... Create dicom file
+.SH SYNOPSIS
+.HP 10
+.B ancreate
+.so man1/gen.so
+[
+.B \-b|big
+]
+[
+.B \-e|explicit
+]
+[
+.B \-p|preamble
+]
+[
+.B \-v|verbose
+]
+<
+.I inputfilename
+>
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B ancreate
+creates a dicom 3 or earlier acr/nema file from a description of attributes. The description of attributes matches the output of dcdump, so that pieces of dumped files can be edited and files reconstructed. Note that the library of dicom attribute handling, dictionary, and transfer syntax routines are NOT used in this program, which allows it to be used as a standalone program to test the library and other utilities.
+.LP
+Everything needed to create a file is specified in a description read from standard input, apart from some very simple rules that recognize certain value representations for special treatment of the output format (eg. OW, OB and SQ in explicit value representation transfer syntaxes are handled differently).
+.LP
+The description consists of lines of the following format:
+.LP
+.B attributes  ...
+.RE
+
+.RE
+(group,element) .* VR=<vr> VL=<vl> [vals]
+.RE
+(group,element) .* VR=<vr> VL=<vl> <vals>
+.RE
+(group,element) .* VR=<FD|FL> VL=<vl> {vals}
+.RE
+
+Note that the group, element, value length, and values are always in hexadecimal format, whether a leading "0x" is present or not. Hence "14" and "014" are both interpreted as "0x14", or 20 decimal, in these positions (unlike data descriptions). Multiple values should be delimited with a '\\' for string values (CS, DS. etc.) and a ',' for binary attributes (US, etc.).
+Make sure there are no spaces between values or the value length will be computed incorrectly (i.e. the number of values are computed from the number of non-value characters).
+.LP
+The value length is measured against the value length specified, and a warning is issued if they are different. The actual value, rather than the specified value is used, for all except value representations of OW, OB and SQ. This allows the special value of 0xffffffff to be passed (which means "unspecified" to dicom), as well as allowing the actual values to be included on separate lines following the attribute description. Remember that the value length is in bytes, not the number of v [...]
+.LP
+If the values for an OB or OW attribute are to be specified on suceeding lines, remember to include an empty value list "[]" or the parser will freak.
+.LP
+An empty value list like "[]" is also required after each SQ (Sequence) element, even though the "payload" of the
+sequence follows enclosed in delimited items.
+.LP
+Anything after a # either at the start of a line, or after the value of a data element, will be treated as
+a comment and skipped.
+.LP
+White space may preceed the the first symbol of a command or data element.
+.LP
+.B transfer syntax commands ...
+.RE
+
+.RE
+%implicit
+.RE
+%explicit
+.RE
+%little
+.RE
+%big
+.RE
+
+Note that the use of big always forces explicit value representation, as there is no valid "implicit value representation big endian" transfer syntax in dicom. These commands are present here, as well as in the command-line options, to allow a change in transfer syntax, such as after a metaheader.
+.LP
+.B sequence commands ...
+.RE
+
+.RE
+%item
+.RE
+%enditem
+.RE
+%endseq
+.RE
+
+Use these commands to insert contents of undefined length sequences - remember to set
+the VL of the enclosing sequence attribute to 0xFFFFFFFF and include an empty value "[]".
+Note that the "-ancreate" option of the andump utility can be used to generate these.
+
+.LP
+.B data value format commands ...
+.RE
+
+.RE
+%byte
+.RE
+%short
+.RE
+%word
+.RE
+%long
+.RE
+
+Specify the interpretation of subsequent data values, as 8, 16 or 32 bit values. Short and word are synonymous. Use of these commands is usually unnecessary, as the presence of an OB or OW value representation in an attribute description automagically sets the data type to byte or short as appropriate. Prior to such an attribute, and in the absence of a data value format command, the default type is byte.
+.LP
+.B data ...
+.RE
+
+.RE
+hexvalue(s)
+.RE
+octalvalue(s)
+.RE
+decvalue(s)
+\n
+Note that the C convention of hexvalues starting with "0x", octal values starting with "0", and others being decimal values is followed for data values (unlike attribute descriptions). The data values are included in the output at the current position.
+.LP
+.SH OPTIONS
+Only redirection from standard input or to standard output are
+supported. Input and output file names may not
+be specified. Errors and warnings goes to standard error.
+.LP
+The default transfer syntax is implicit value representation, little endian.
+.PP
+Options specific to this program are:
+.TP
+.B \-b|big
+.RS
+Big endian transfer syntax.
+.RE
+.TP
+.B \-e|explicit
+.RS
+Explicit value representation transfer syntax.
+.RE
+.TP
+.B \-p|preamble
+.RS
+Include file preamble (128 bytes of zero plus "DICM" magic string) before writing anything.
+Note that this option is completely independent of whether or not any meta information header
+(group 0x0002) elements are manually added from the input stream or not.
+.RE
+.TP
+.B \-v|verbose
+.RS
+Dump data element tags and command numnber (not precisely the same as
+the input line number) to stderr while parsing. Helps to localize errors
+in the input.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+Sample attributes that can be fed to ancreate:
+.RE
+
+.RE
+% ancreate >test
+.RE
+(0000x8,0000x8) VR=<CS> VL=<0x14> <ORIGINAL\\PRIMARY\\MPR> 
+.RE
+(0000x8,000x16) VR=<UI> VL=<0x10> <1.2.840.10008.0> 
+.RE
+(0x0018,0x9104) VR=<FD> VL=<0x0010> {13.69,1.36e-08} 
+.RE
+(000x28,0000x0) VR=<UL> VL=<0x4> [0xb6]
+.RE
+(000028,000002) VR=<US> VL=<2> [1]
+.RE
+(000028,000004) VR=<CS> VL=<c> <MONOCHROME2> 
+.RE
+(0x6000,000x50) VR=<SS> VL=<0x4> [0x5c31,0x2031]
+.LP
+.RE
+Sample use of unspecified vl ...
+.RE
+
+.RE
+% ancreate >test
+.RE
+(0x7fe0,000x10) OX PixelData VR=<OW> VL=<0xffffffff> []
+.LP
+.RE
+Sample use of data values ...
+.RE
+
+.RE
+% ancreate >test
+.RE
+(0x7fe0,000x10) OX PixelData VR=<OW> VL=<0x8> []
+.RE
+0x10 0x12
+.RE
+0x24 0x36
+.RE
+
+.RE
+% dcdump test
+.RE
+(0x7fe0,000x10) OX PixelData     VR=<OW>   VL=<0x8> 
+.RE
+
+.RE
+% od -x test
+.RE
+0000000  e07f 1000 0800 0000 1000 1200 2400 3600
+.RE
+0000020
+.LP
+.RE
+
+.RE
+Sample use of metaheader, then explicit big syntax ...
+.RE
+
+.RE
+% ancreate >test
+.RE
+(0000x2,000x10) UI TransferSyntaxUID VR=<UI> VL=<0x14>
+.RE
+                <1.2.840.10008.1.2.2>
+.RE
+%big
+.RE
+(000028,000002) VR=<US> VL=<2> [1]
+.LP
+.RE
+Should be able to find no differences:
+.RE
+
+.RE
+% dcdump test 2>test.dump
+.RE
+% ancreate <test.dump >test2
+.RE
+% cmp test test2
+.RE
+% dcdump test2 2>test2.dump
+.RE
+% diff -b test.dump test2.dump
+.RE
+
+.RE
+(unless of course there are OB or OW attributes, in which case the data will be elided, and the comparison will fail, or there is a metaheader present which changes the transfer syntax in the middle of the file).
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR andump(1) ,
+.BR dcdump(1) ,
+.BR dcintro(1) ,
+.BR dcintro(3) ,
+.BR dcintro(5)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+In the attribute descriptions, the group, element, value length, and values are always in hexadecimal format, whether a leading "0x" is present or not. This is because dcdump adopts such a convention, with slightly different output on different platforms and compilers. In particular lib-g++ does not output the "x" in hexadecimal formats :(
+.LP
+It would be nice to have the verbose output reference actual line numbers rather
+than just command numbers.
+.LP
+It would be nice to have the error messages reference actual line numbers.
+.LP
+The maximum input line length is 32768 and will be truncated after that causing errors and corruption - this really should be unlimited.
+
diff --git a/appsrc/acrnema/andiff.man b/appsrc/acrnema/andiff.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/acrnema/andiff.script b/appsrc/acrnema/andiff.script
new file mode 100755
index 0000000..8f3417f
--- /dev/null
+++ b/appsrc/acrnema/andiff.script
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# compare the dumps of two ACR-NEMA files
+
+if [ $# != 2 ]
+then
+	echo "usage: `basename $0` file1 file2"
+	exit 1
+fi
+
+TMPFILE1=/tmp/`basename $0`.$$.tmp1
+TMPFILE2=/tmp/`basename $0`.$$.tmp2
+
+andump "$1" >"$TMPFILE1" 2>&1
+andump "$2" >"$TMPFILE2" 2>&1
+diff "$TMPFILE1" "$TMPFILE2"
+
+rm "$TMPFILE1" "$TMPFILE2"
+
+exit 0
+
diff --git a/appsrc/acrnema/andump.cc b/appsrc/acrnema/andump.cc
new file mode 100644
index 0000000..aed954d
--- /dev/null
+++ b/appsrc/acrnema/andump.cc
@@ -0,0 +1,569 @@
+static const char *CopyrightIdentifier(void) { return "@(#)andump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#include <cctype>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#ifdef POWINTEGEREXPONENTTYPE
+#define	powi(m,e)	pow(m,(POWINTEGEREXPONENTTYPE)(e))
+#else
+#define	powi(m,e)	pow(m,(long)(e))
+#endif
+
+#ifdef __SC__
+#define infinity()    HUGE_VAL
+#define quiet_nan(x)  0
+#endif /* __SC__ */
+
+#ifdef __MWERKS__
+#define infinity()    __inf()
+#define quiet_nan(x)  0
+#endif /* __MWERKS__ */
+
+#ifdef USEDUMBINFINITYANDNAN
+#if USEDUMBINFINITYANDNAN
+#define infinity()    HUGE_VAL
+#define quiet_nan(x)  0
+#endif
+#endif
+
+#include "attrtag.h"
+#include "dcstream.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "elmdict.h"
+#include "mesgtext.h"
+#include "vr.h"
+
+#ifndef MAXVLTODUMP
+#define MAXVLTODUMP 32768
+#endif
+
+static TextOutputStream& 
+writebase(TextOutputStream& stream,ElementDictionary& dict,const Tag tag,const char *vr,Uint32 vl)
+{
+	tag.write(stream,&dict);
+	stream << "\t VR=<" << (vr ? vr : "") << ">  " << flush;
+	stream << " VL=<";
+	writeZeroPaddedHexNumber(stream,vl,4);
+	stream << ">  " << flush;
+	return stream;
+}
+
+static TextOutputStream&
+doStringValues(DicomInputStream& in,TextOutputStream& log,Uint32 vl,const char * &rstr)
+{
+	static char buffer[MAXVLTODUMP];
+	Assert(vl < MAXVLTODUMP);
+	if (vl) in.read(buffer,(int)vl);
+	buffer[vl]=0;
+	if (!in.fail()) {
+		log << "<";
+		char *ptr=buffer;
+		while (vl--) {
+			if (*ptr)
+				log << *ptr;
+			else if (vl) {	// Allow single trailing null eg. for UI string
+				log << endl << WMsgDC(UnexpectedNullInString) << endl;
+				break;
+			}
+			++ptr;
+		}
+		log << "> ";
+		// return value has no leading or trailing space
+		ptr=buffer+strlen(buffer);
+		while (ptr >= buffer && (*ptr == 0 || isspace(*ptr))) *ptr--=0;
+		rstr=buffer;
+		while (*rstr && isspace(*rstr)) ++rstr;
+	}
+	else {
+		cerr << EMsgDC(ReadFailed) << endl;
+		rstr=0;
+	}
+	return log;
+}
+
+static TextOutputStream&
+doTagValues(DicomInputStream& in,TextOutputStream& log,Uint32 vl)
+{
+	if (vl%4) {
+		cerr << EMsgDC(BadValueLength) << endl;
+		in.seekg(vl,ios::cur);
+		if (in.fail()) {
+			cerr << EMsgDC(SeekFailed) << endl;
+		}
+	}
+	else {
+		log << "{";
+		while (vl) {
+			Uint16 group;
+			Uint16 element;
+			in >> group;
+			in >> element;
+			log << "(";
+			writeZeroPaddedHexNumber(log,group,4);
+			log << ",";
+			writeZeroPaddedHexNumber(log,element,4);
+			log << ")";
+			vl-=4;
+		}
+		log << "} ";
+		if (in.fail()) {
+			cerr << EMsgDC(ReadFailed) << endl;
+		}
+	}
+	return log;
+}
+
+static TextOutputStream&
+doBinaryValues(DicomInputStream& in,TextOutputStream& log,Uint32 vl,size_t size,Uint32& rval)
+{
+	rval=0;
+	if (vl < size) size=vl;	// handles special case of 1 US where UL wanted
+	if (vl%size) {
+		cerr << EMsgDC(BadValueLength) << endl;
+		in.seekg(vl,ios::cur);
+		if (in.fail()) {
+			cerr << EMsgDC(SeekFailed) << endl;
+		}
+	}
+	else {
+		log << "[";
+		while (vl) {
+			Uint32 value;
+			switch(size) {
+				case 1: { Uint8  v; in >> v; value=v; } break;
+				case 2: { Uint16 v; in >> v; value=v; } break;
+				case 4: { Uint32 v; in >> v; value=v; } break;
+				default: Assert(0); break;
+			}
+			rval=value;
+			writeZeroPaddedHexNumber(log,value,size*2);
+			vl-=size;
+			if (vl) log << ",";
+		}
+		log << "] ";
+		if (in.fail()) {
+			cerr << EMsgDC(ReadFailed) << endl;
+		}
+	}
+	return log;
+}
+
+static TextOutputStream&
+doFloatValues(DicomInputStream& in,TextOutputStream& log,Uint32 vl,size_t size)
+{
+	if (vl%size) {
+		Uint32 ival;
+		doBinaryValues(in,log,vl,1,ival);
+		cerr << EMsgDC(BadValueLength) << endl;
+		//in.seekg(vl,ios::cur);
+		//if (in.fail()) {
+		//	cerr << EMsgDC(SeekFailed) << endl;
+		//}
+	}
+	else {
+		log << "{";
+		while (vl) {
+			if (size == 4) {
+				Uint32 binary; in >> binary;
+
+				double value;
+				Int16 sign	=(Int16)((binary&0x80000000)>>31);
+				Int16 exponent	=(Int16)((binary&0x7f800000)>>23);
+				Uint32 mantissa	= binary&0x007fffff;
+
+				if (exponent == 0) {
+					if (mantissa == 0)
+						value=0;
+					else {
+						value=((double)mantissa/
+							(1<<23))*powi(2.0,-126);
+						value = (sign == 0) ? value : -value;
+					}
+				}
+				else if (exponent == 255) {
+					if (mantissa)
+						value=quiet_nan(0);
+					else
+						value=infinity();
+				}
+				else {
+					value=(1.0+(double)mantissa/
+						(1<<23))*powi(2.0,exponent-127);
+					value = (sign == 0) ? value : -value;
+				}
+				log << dec << value;
+			}
+			else if (size == 8) {
+				Uint32 binary1; in >> binary1;
+				Uint32 binary2; in >> binary2;
+
+				double value;
+				Uint32 high = in.isBigEndian() ? binary1 : binary2;
+				Uint32 low  = in.isBigEndian() ? binary2 : binary1;
+
+				Int16 sign	=(Int16)((high&0x80000000)>>31);
+				Int16 exponent	=(Int16)((high&0x7ff00000)>>20);
+				Uint32 mantissahigh = high&0x000fffff;
+				Uint32 mantissalow  = low &0xffffffff;
+				double mantissavalue = (double)mantissahigh * powi(2.0,32)
+						     + (double)mantissalow;
+
+				if (exponent == 0) {
+					if (mantissahigh == 0 && mantissalow == 0)
+						value=0;
+					else {
+						value=(mantissavalue/powi(2.0,52))
+							*powi(2.0,-1022);
+						value = (sign == 0) ? value : -value;
+					}
+				}
+				else if (exponent == 255) {
+					if (mantissahigh || mantissalow)
+						value=quiet_nan(0);
+					else
+						value=infinity();
+				}
+				else {
+					value=(1.0+mantissavalue/powi(2.0,52))
+						*powi(2.0,exponent-1023);
+					value = (sign == 0) ? value : -value;
+				}
+				log << dec << value;
+			}
+			else {
+				Assert(0);
+			}
+
+			vl-=size;
+			if (vl) log << ",";
+		}
+		log << "} ";
+		if (in.fail()) {
+			cerr << EMsgDC(ReadFailed) << endl;
+		}
+	}
+	return log;
+}
+
+static bool
+readAll(DicomInputStream& stream,TextOutputStream& log,ElementDictionary& dict,bool showoffset,ios::fmtflags showoffsetbase,bool ancreate,bool extractCSA)
+{
+	Uint32 n=stream.haveMetaHeader() ? 132 : 0;
+	Uint32 length=0xffffffff;
+	bool lastwasencapOXorItem=false;
+	bool donewithmetaheader=false;
+	Tag *siemensCSAHeaderInfoTag = NULL;
+	while (stream.peek() != istream::traits_type::eof() && (length == 0xffffffff || n < length)) {
+		if (showoffset) {
+			log << "@";
+			writeZeroPaddedNumber(log,n,showoffsetbase,8);
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+			log << "(";
+			writeZeroPaddedHexNumber(log,stream.rdbuf()->PubSeekOff(0,ios::cur),8);
+			log << ")";
+#endif
+			log << ": ";
+		}
+		Tag tag;
+		stream >> tag;
+		if (stream.fail()) {
+			cerr << EMsgDC(TagReadFailed) << endl;
+			return false;
+		}
+		n+=4;
+
+		if (!donewithmetaheader && !tag.isMetaheaderGroup()) {
+			{
+				// backup and read again in case endian changed ...
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+log << endl << "Before endian check backup @";
+writeZeroPaddedHexNumber(log,n,8);
+log << "(";
+writeZeroPaddedHexNumber(log,stream.rdbuf()->PubSeekOff(0,ios::cur),8);
+log << ")"
+    << ": ";
+#endif
+				stream.seekg(-4l,ios::cur);
+				if (stream.fail()) {
+					cerr << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+					return false;
+				}
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+log << endl << "Before endian check backup @";
+writeZeroPaddedHexNumber(log,n,8);
+log << "(";
+writeZeroPaddedHexNumber(log,stream.rdbuf()->PubSeekOff(0,ios::cur),8);
+log << ")"
+    << ": " << endl;
+#endif
+				if (!stream.getTransferSyntaxToReadDataSet()) {
+					cerr << EMsgDC(NoTransferSyntaxInMetaHeader) << endl;
+					bool setswapped32big;
+					stream.guessTransferSyntaxToReadDataSet(setswapped32big);		// always guesses something
+				}
+				stream.readingDataSet();
+				donewithmetaheader=true;
+				stream >> tag;
+				if (stream.fail()) {
+					cerr << EMsgDC(TagReadFailed) << endl;
+					return false;
+				}
+			}
+		}
+
+		char vre[3];
+		const char *vr;
+		Uint32 vl;
+
+		if (tag == TagFromName(ItemDelimitationItem)
+		 || tag == TagFromName(SequenceDelimitationItem)
+		 || tag == TagFromName(Item)
+		 || tag == Tag(0xfeff,0x00e0)				// GE bug (endianness of Item tag in encapsulated pixel data)
+		 || tag == Tag(0xfeff,0xdde0)				// GE bug (endianness of Sequence Delimitation Item tag in encapsulated pixel data)
+		) {
+			vr=0;
+			stream >> vl;
+			if (tag == Tag(0xfeff,0x00e0)) {
+				vl = ((vl>>24)&0xff) + (((vl>>16)&0xff)<<8) + (((vl>>8)&0xff)<<16) +((vl&0xff)<<24);	// GE bug - swap VL endianness as well
+			}
+			n+=4;
+		}
+		else  {
+			if (stream.getTransferSyntaxInUse()->isExplicitVR()) {
+				stream.read(vre,2);
+				if (stream.fail()) {
+					cerr << EMsgDC(VRReadFailed) << endl;
+					return false;
+				}
+				if (vre[0] == '-' && vre[1] == '-') {			// illegal proprietary equivalent of UN VR used by Australian Central Data Networks (CDN) PACS
+					vr="UN";
+					vl=stream.read16();
+					n+=2;
+				}
+				else if (vre[0] == 0 && vre[1] == 0) {			// illegal two bytes of zero VR encountered in Sante de-identifier output (followed by two byte length)
+					vr="UN";
+					vl=stream.read16();
+					n+=2;
+				}
+				else if (vre[0] < 'A' || vre[1] < 'A') {		// DicomWorks bug ... occasional implicit VR attribute even though explicit transfer syntax
+					//cerr << EMsgDC(TagReadFailed) << " - " << MMsgDC(ImplicitVREncodingWhenExplicitRequired) << endl;
+					vr="UN";
+					stream.seekg(-2l,ios::cur);
+					if (stream.fail()) {
+						cerr << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+						return false;
+					}
+					stream >> vl;				// read VL as if implicit VR
+					n+=4;
+				}
+				else {
+					n+=2;
+					vre[2]=0;
+					vr=vre;
+					if (isUniversalResourceVR(vr) || isUnlimitedCharactersVR(vr) || isUnlimitedTextVR(vr) || isUnknownVR(vr)) {
+						// should be long form, but check for bad implementations that use short form ...
+						vl=stream.read16();
+						n+=2;
+						if (vl == 0) {		// if reserved bytes not zero, assume used for short form of length (risky) :(
+							stream >> vl;
+							n+=4;
+						}
+						else {
+							cerr << EMsgDC(IncorrectShortVLForUROrUCOrUTOrUN) << endl;
+						}
+					}
+					else if (isLongValueLengthInExplicitValueRepresentation(vr)) {	// some of these already handled above
+						(void)stream.read16();	// "Reserved"
+						stream >> vl;
+						n+=6;
+					}
+					else {
+						vl=stream.read16();
+						n+=2;
+					}
+				}
+			}
+			else {
+				vr=(tag.isPrivateGroup() && tag.isPrivateOwner())
+					? "LO"	// PS3.5-7.8.1
+					: dict.getValueRepresentation(tag);
+				stream >> vl;
+				n+=4;
+			}
+		}
+		if (stream.fail()) {
+			cerr << EMsgDC(VLReadFailed) << endl;
+			return false;
+		}
+
+		if (ancreate) {
+			if (tag == TagFromName(ItemDelimitationItem)) {
+				log << "%enditem";
+			}
+			else if (tag == TagFromName(SequenceDelimitationItem)) {
+				log << "%endseq";
+			}
+			else if (tag == TagFromName(Item)) {
+				log << "%item";
+			}
+			else {
+				writebase(log,dict,tag,vr,vl);
+			}
+		}
+		else {
+			writebase(log,dict,tag,vr,vl);
+		}
+		
+		if (vl == 0xffffffff		// SQ or OX both will contain items
+		 || vl == 0			// includes ItemDelimitationItem,SequenceDelimitationItem
+		 || isSequenceVR(vr)		// SQ with defined length
+		 || (tag == TagFromName(Item) && !lastwasencapOXorItem)	// Item with element contents
+		) {
+			if (!ancreate
+			 || (tag != TagFromName(ItemDelimitationItem)
+			  && tag != TagFromName(SequenceDelimitationItem)
+			  && tag != TagFromName(Item))) {
+				log << "\t[]";
+			}
+		}
+		else {
+			if (extractCSA && siemensCSAHeaderInfoTag && *siemensCSAHeaderInfoTag == tag) {
+				// do nothing - treat it as containing DICOM tags and loop around - works for EVRLE only
+				// should also check to stop at (0xffff,0xffff)
+			}
+			else if (vl < MAXVLTODUMP) {
+				if (isStringVR(vr)) {
+					const char *sval;
+					doStringValues(stream,log,vl,sval);
+					if (!stream.fail() && vl && sval && *sval) {
+						if (tag == TagFromName(TransferSyntaxUID)) {
+							if (!donewithmetaheader) {
+								stream.setTransferSyntaxToReadDataSet(new TransferSyntax(sval));
+							}
+						}
+						else if (tag.isPrivateGroup() && tag.isPrivateOwner()) {
+							dict.addOwner(tag,sval);
+							if (tag.getGroup() == 0x0029 && strcmp(sval,"SIEMENS CSA HEADER") == 0) {
+								Uint16 siemensCSAHeaderInfoElement=((tag.getElement() << 8) & 0xff00)+0x0010;
+								siemensCSAHeaderInfoTag = new Tag(0x0029,siemensCSAHeaderInfoElement);
+							}
+						}
+					}
+				}
+				else if (isAttributeTagVR(vr))
+					doTagValues(stream,log,vl);
+				else if (isNumericVR(vr)) {
+					Uint32 ival;
+					size_t size=sizeofNumericVR(vr);
+					doBinaryValues(stream,log,vl,size,ival);
+					if (!stream.fail() && vl == size) {
+						if (tag == TagFromName(LengthToEnd)
+						 && length == 0xffffffff) {
+							// Retired, but if you've got it use it
+							//length=n+ival+vl;
+						}
+					}
+				}
+				else if (isFloatVR(vr)) {
+					size_t size=sizeofFloatVR(vr);
+					doFloatValues(stream,log,vl,size);
+				}
+				else {
+					//cerr << endl << WMsgDC(UnrecognizedVR) << endl;
+					Uint32 ival;
+					doBinaryValues(stream,log,vl,1,ival);
+				}
+			}
+			else {
+				Assert(!ancreate);
+				log << "\t[]\t# skipping ...";		
+				stream.seekg(vl,ios::cur);
+				if (stream.fail()) {
+					cerr << EMsgDC(SeekFailed) << endl;
+					return false;
+				}
+			}
+			n+=vl;
+		}
+		lastwasencapOXorItem=
+			(isOtherByteOrWordOrUnspecifiedVR(vr)
+			 || tag == TagFromName(Item)
+			 || tag == TagFromName(ItemDelimitationItem)
+			) && stream.getTransferSyntaxInUse()->isEncapsulated();
+
+		log << endl;
+	}
+	return true;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions    options(argc,argv);
+	DicomInputOptions input_options(options);
+
+	bool showfilename=options.get("filename");
+	bool ancreate=options.get("ancreate");
+	bool extractCSA=options.get("extractCSA");
+	bool showoffset=false;
+	ios::fmtflags showoffsetbase;
+	if (options["showoffset"]||options["showoffset-hex"])
+		{ showoffset=true; showoffsetbase=ios::hex; }
+	else if (options["showoffset-octal"]||options["showoffset-oct"])
+		{ showoffset=true; showoffsetbase=ios::oct; }
+	else if (options["showoffset-decimal"]||options["showoffset-dec"])
+		{ showoffset=true; showoffsetbase=ios::dec; }
+
+	input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+
+	cerr << options.errors();
+	cerr << input_options.errors();
+	cerr << input_opener.errors();
+
+	if (!input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< " [-ancreate]"
+			<< " [-extractCSA]"
+			<< " [-showoffset|-showoffset-hex"
+			<< "|-showoffset-octal|-showoffset-oct"
+			<< "|-showoffset-decimal|-showoffset-dec]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		input_options.transfersyntaxuid,
+		input_options.usemetaheader);
+	TextOutputStream log(cerr);
+
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		log << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	ElementDictionary dictionary;
+
+	readAll(din,log,dictionary,showoffset,showoffsetbase,ancreate,extractCSA);
+}
diff --git a/appsrc/acrnema/andump.man b/appsrc/acrnema/andump.man
new file mode 100755
index 0000000..77f0b6a
--- /dev/null
+++ b/appsrc/acrnema/andump.man
@@ -0,0 +1,134 @@
+.TH ANDUMP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Describe ACR-NEMA file content"
+.SH NAME
+andump \- ACR/NEMA DICOM PS3 ... Describe ACR-NEMA file content
+.SH SYNOPSIS
+.HP 10
+.B andump
+.so man1/gen.so
+[
+.B \-ancreate
+]
+[
+.B \-extractCSA
+]
+[
+.B \-showoffset|-showoffset-hex
+|-showoffset-octal|-showoffset-oct
+|-showoffset-decimal|-showoffset-dec
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B andump
+reads the named acr-nema input file and describes the information contained, without attempting to interpret the structure of the message (cf. dcdump).
+.LP
+The group and element number, dictionary and explicit value representation, description of tag, value length and value of the element are displayed, 
+optionally with an offset byte count from the start of the file.
+.SH OPTIONS
+The attribute values, description and verbose output go to standard error.
+.LP
+Binary attributes are written in hexadecimal with a preceding
+"0x". Numeric string attributes are written in decimal. Attribute values
+are displayed in hexadecimal or string format as determined by the value representation.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-ancreate
+.RS
+Display item, end item and end sequence delimiter tags in a form suitable to feed into ancreate.
+.RE
+.TP
+.B \-extractCSA
+.RS
+Extract the DICOM-like attributes buried within the Siemens private CSA header OB value.
+.RE
+.TP
+.B \-showoffset|-showoffset-hex
+.RS
+Display byte offset from file start in hexadecimal.
+.RE
+.TP
+.B \-showoffset-octal|-showoffset-oct
+.RS
+Display byte offset from file start in octal.
+.RE
+.TP
+.B \-showoffset-decimal|-showoffset-dec
+.RS
+Display byte offset from file start in decimal.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% andump NM.dc3
+.RE
+(0x0008,0x0000) UL Group Length  VR=<UL> VL=<0x0004> [0x08] 
+.RE
+(0x0008,0x0008) CS Image Type    VR=<CS> VL=<0x0024> <...> 
+.RE
+...
+.RE
+(0x0054,0x0013) SQ ... Sequence  VR=<SQ> VL=<0xffffffff> []
+.RE
+(0xfffe,0xe000) NONE Item        VR=<> VL=<0xffffffff> []
+.RE
+(0x0054,0x0014) DS Energy Win LL VR=<DS> VL=<0x0006> <1.0 > 
+.RE
+(0x0054,0x0015) DS Energy Win UL VR=<DS> VL=<0x0006> <9.0 > 
+.RE
+(0xfffe,0xe00d) NONE Item Del .. VR=<> VL=<0x0000> []
+.RE
+(0xfffe,0xe0dd) NONE Seq Del ..  VR=<> VL=<0x0000> []
+.RE
+...
+.RE
+\ 
+.RE
+\ 
+.RE
+% andump -ancreate NM.dc3
+.RE
+(0x0008,0x0000) UL Group Length  VR=<UL> VL=<0x0004> [0x08] 
+.RE
+(0x0008,0x0008) CS Image Type    VR=<CS> VL=<0x0024> <...> 
+.RE
+...
+.RE
+(0x0054,0x0013) SQ ... Sequence  VR=<SQ> VL=<0xffffffff> []
+.RE
+%item
+.RE
+(0x0054,0x0014) DS Energy Win LL VR=<DS> VL=<0x0006> <1.0 > 
+.RE
+(0x0054,0x0015) DS Energy Win UL VR=<DS> VL=<0x0006> <9.0 > 
+.RE
+%enditem
+.RE
+%endseq
+.RE
+...
+.RE
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR ancreate(1) ,
+.BR dcdump(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/acrnema/test.create.private.un.sh b/appsrc/acrnema/test.create.private.un.sh
new file mode 100755
index 0000000..dab3162
--- /dev/null
+++ b/appsrc/acrnema/test.create.private.un.sh
@@ -0,0 +1,199 @@
+#!/bin/sh
+
+# Usage: $0 create|compare
+
+TMPROOT="/tmp/`basename $0`.$$"
+
+TESTLOGDIR="../../test/appsrc/acrnema"
+
+ANCREATE="./ancreate"
+ANDUMP="./andump"
+DCDUMP="../dcfile/dcdump"
+DCCP="../dcfile/dccp"
+
+bad="false"
+
+if [ "$#" != 1 ]
+then
+	bad="true"
+else
+	mode="$1"	# eg. create|compare
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 create|compare" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	WHERE="$TESTLOGDIR"
+else
+	WHERE="$TMPROOT"
+fi
+
+if [ ! -d "$WHERE" ]; then mkdirhier "$WHERE"; fi
+
+comparebinaries() {
+	echo Comparing $1
+	cmp $TESTLOGDIR/$1 $WHERE/$1
+}
+
+comparedumps() {
+	echo Diffs for $1
+	diff -b $TESTLOGDIR/$1 $WHERE/$1
+}
+
+echo $0 starting
+
+# Specify VR but will be lost in implicit stream ...
+
+$ANCREATE <<EOF > $WHERE/private.ile.nm
+(0x0008,0x0008) VR=<CS>   VL=<0x14>   <ORIGINAL\PRIMARY\MPR>
+(0x0008,0x0016) VR=<UI>   VL=<0x001a> <1.2.840.10008.5.1.4.1.1.7>
+(0x0009,0x0010) VR=<LO>   VL=<0x001a> <CREATOR_THAT_DOESNT_EXIST > 
+(0x0009,0x1010) VR=<LO>   VL=<0x000e> <Test VL of LO>
+(0x0009,0x1011) VR=<US>   VL=<0x0002> [0x00]
+EOF
+
+if [ "$mode" = "compare" ]; then comparebinaries private.ile.nm ; fi
+
+$ANDUMP $WHERE/private.ile.nm > $WHERE/private.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.andump ; fi
+$DCDUMP  $WHERE/private.ile.nm > $WHERE/private.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.dcdump ; fi
+od -b $WHERE/private.ile.nm > $WHERE/private.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.odx ; fi
+od -c $WHERE/private.ile.nm > $WHERE/private.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.odc ; fi
+
+
+$DCCP $WHERE/private.ile.nm $WHERE/private.ile.nm.cp.ile.nm -n -nodisclaimer > $WHERE/private.ile.nm.cp.ile.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries private.ile.nm.cp.ile.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ile.nm.dccp ; fi
+$ANDUMP $WHERE/private.ile.nm.cp.ile.nm > $WHERE/private.ile.nm.cp.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ile.nm.andump ; fi
+$DCDUMP  $WHERE/private.ile.nm.cp.ile.nm > $WHERE/private.ile.nm.cp.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ile.nm.dcdump ; fi
+od -b $WHERE/private.ile.nm.cp.ile.nm > $WHERE/private.ile.nm.cp.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ile.nm.odx ; fi
+od -c $WHERE/private.ile.nm.cp.ile.nm > $WHERE/private.ile.nm.cp.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ile.nm.odc ; fi
+
+$DCCP $WHERE/private.ile.nm $WHERE/private.ile.nm.cp.ele.nm -n -vr explicit -endian little -nodisclaimer > $WHERE/private.ile.nm.cp.ele.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries private.ile.nm.cp.ele.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ele.nm.dccp ; fi
+$ANDUMP $WHERE/private.ile.nm.cp.ele.nm > $WHERE/private.ile.nm.cp.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ele.nm.andump ; fi
+$DCDUMP  $WHERE/private.ile.nm.cp.ele.nm > $WHERE/private.ile.nm.cp.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ele.nm.dcdump ; fi
+od -b $WHERE/private.ile.nm.cp.ele.nm > $WHERE/private.ile.nm.cp.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ele.nm.odx ; fi
+od -c $WHERE/private.ile.nm.cp.ele.nm > $WHERE/private.ile.nm.cp.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ile.nm.cp.ele.nm.odc ; fi
+
+
+# Specify VRs directly for private elements in explicit stream ...
+
+$ANCREATE <<EOF > $WHERE/private.ele.nm -explicit
+(0x0008,0x0008) VR=<CS>   VL=<0x14>   <ORIGINAL\PRIMARY\MPR>
+(0x0008,0x0016) VR=<UI>   VL=<0x001a> <1.2.840.10008.5.1.4.1.1.7>
+(0x0009,0x0010) VR=<LO>   VL=<0x001a> <CREATOR_THAT_DOESNT_EXIST > 
+(0x0009,0x1010) VR=<LO>   VL=<0x000e> <Test VL of LO>
+(0x0009,0x1011) VR=<US>   VL=<0x0002> [0x00]
+EOF
+
+if [ "$mode" = "compare" ]; then comparebinaries private.ele.nm ; fi
+
+$ANDUMP $WHERE/private.ele.nm > $WHERE/private.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.andump ; fi
+$DCDUMP  $WHERE/private.ele.nm > $WHERE/private.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.dcdump ; fi
+od -b $WHERE/private.ele.nm > $WHERE/private.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.odx ; fi
+od -c $WHERE/private.ele.nm > $WHERE/private.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.odc ; fi
+
+$DCCP $WHERE/private.ele.nm $WHERE/private.ele.nm.cp.ile.nm -n -nodisclaimer > $WHERE/private.ele.nm.cp.ile.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries private.ele.nm.cp.ile.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ile.nm.dccp ; fi
+$ANDUMP $WHERE/private.ele.nm.cp.ile.nm > $WHERE/private.ele.nm.cp.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ile.nm.andump ; fi
+$DCDUMP  $WHERE/private.ele.nm.cp.ile.nm > $WHERE/private.ele.nm.cp.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ile.nm.dcdump ; fi
+od -b $WHERE/private.ele.nm.cp.ile.nm > $WHERE/private.ele.nm.cp.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ile.nm.odx ; fi
+od -c $WHERE/private.ele.nm.cp.ile.nm > $WHERE/private.ele.nm.cp.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ile.nm.odc ; fi
+
+$DCCP $WHERE/private.ele.nm $WHERE/private.ele.nm.cp.ele.nm -n -vr explicit -endian little -nodisclaimer > $WHERE/private.ele.nm.cp.ele.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries private.ele.nm.cp.ele.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ele.nm.dccp ; fi
+$ANDUMP $WHERE/private.ele.nm.cp.ele.nm > $WHERE/private.ele.nm.cp.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ele.nm.andump ; fi
+$DCDUMP  $WHERE/private.ele.nm.cp.ele.nm > $WHERE/private.ele.nm.cp.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ele.nm.dcdump ; fi
+od -b $WHERE/private.ele.nm.cp.ele.nm > $WHERE/private.ele.nm.cp.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ele.nm.odx ; fi
+od -c $WHERE/private.ele.nm.cp.ele.nm > $WHERE/private.ele.nm.cp.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.cp.ele.nm.odc ; fi
+
+
+# Insert UN VR directly into explicit stream ...
+
+$ANCREATE <<EOF > $WHERE/private.ele.nm.un -explicit
+(0x0008,0x0008) VR=<CS>   VL=<0x14>   <ORIGINAL\PRIMARY\MPR>
+(0x0008,0x0016) VR=<UI>   VL=<0x001a> <1.2.840.10008.5.1.4.1.1.7>
+(0x0009,0x0010) VR=<LO>   VL=<0x001a> <CREATOR_THAT_DOESNT_EXIST > 
+(0x0009,0x1010) VR=<UN>   VL=<0x000e> <Test VL of LO>
+(0x0009,0x1011) VR=<UN>   VL=<0x0002> [0x00]
+EOF
+
+if [ "$mode" = "compare" ]; then comparebinaries private.ele.nm.un ; fi
+
+$ANDUMP $WHERE/private.ele.nm.un > $WHERE/private.ele.nm.un.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.andump ; fi
+$DCDUMP  $WHERE/private.ele.nm.un > $WHERE/private.ele.nm.un.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.dcdump ; fi
+od -b $WHERE/private.ele.nm.un > $WHERE/private.ele.nm.un.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.odx ; fi
+od -c $WHERE/private.ele.nm.un > $WHERE/private.ele.nm.un.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.odc ; fi
+
+$DCCP $WHERE/private.ele.nm.un $WHERE/private.ele.nm.un.cp.ile.nm -n -nodisclaimer > $WHERE/private.ele.nm.un.cp.ile.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries private.ele.nm.un.cp.ile.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ile.nm.dccp ; fi
+$ANDUMP $WHERE/private.ele.nm.un.cp.ile.nm > $WHERE/private.ele.nm.un.cp.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ile.nm.andump ; fi
+$DCDUMP  $WHERE/private.ele.nm.un.cp.ile.nm > $WHERE/private.ele.nm.un.cp.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ile.nm.dcdump ; fi
+od -b $WHERE/private.ele.nm.un.cp.ile.nm > $WHERE/private.ele.nm.un.cp.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ile.nm.odx ; fi
+od -c $WHERE/private.ele.nm.un.cp.ile.nm > $WHERE/private.ele.nm.un.cp.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ile.nm.odc ; fi
+
+$DCCP $WHERE/private.ele.nm.un $WHERE/private.ele.nm.un.cp.ele.nm -n -vr explicit -endian little -nodisclaimer > $WHERE/private.ele.nm.un.cp.ele.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries private.ele.nm.un.cp.ele.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ele.nm.dccp ; fi
+$ANDUMP $WHERE/private.ele.nm.un.cp.ele.nm > $WHERE/private.ele.nm.un.cp.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ele.nm.andump ; fi
+$DCDUMP  $WHERE/private.ele.nm.un.cp.ele.nm > $WHERE/private.ele.nm.un.cp.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ele.nm.dcdump ; fi
+od -b $WHERE/private.ele.nm.un.cp.ele.nm > $WHERE/private.ele.nm.un.cp.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ele.nm.odx ; fi
+od -c $WHERE/private.ele.nm.un.cp.ele.nm > $WHERE/private.ele.nm.un.cp.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    private.ele.nm.un.cp.ele.nm.odc ; fi
+
+if [ "$mode" = "compare" ]
+then
+	rm -rf "$TMPROOT"
+fi
+
+echo $0 finished
diff --git a/appsrc/acrnema/test.create.ut.sh b/appsrc/acrnema/test.create.ut.sh
new file mode 100755
index 0000000..9576c0b
--- /dev/null
+++ b/appsrc/acrnema/test.create.ut.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+# Usage: $0 create|compare
+
+TMPROOT="/tmp/`basename $0`.$$"
+
+TESTLOGDIR="../../test/appsrc/acrnema"
+
+ANCREATE="./ancreate"
+ANDUMP="./andump"
+DCDUMP="../dcfile/dcdump"
+DCCP="../dcfile/dccp"
+
+bad="false"
+
+if [ "$#" != 1 ]
+then
+	bad="true"
+else
+	mode="$1"	# eg. create|compare
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 create|compare" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	WHERE="$TESTLOGDIR"
+else
+	WHERE="$TMPROOT"
+fi
+
+if [ ! -d "$WHERE" ]; then mkdirhier "$WHERE"; fi
+
+comparebinaries() {
+	echo Comparing $1
+	cmp $TESTLOGDIR/$1 $WHERE/$1
+}
+
+comparedumps() {
+	echo Diffs for $1
+	diff -b $TESTLOGDIR/$1 $WHERE/$1
+}
+
+echo $0 starting
+
+# Specify VR but will be lost in implicit stream ...
+
+$ANCREATE <<EOF > $WHERE/ut.ile.nm
+(0x0040,0xa160) UT Text Value 	 VR=<UT>   VL=<0x000e> <Test VR of UT>
+EOF
+
+if [ "$mode" = "compare" ]; then comparebinaries ut.ile.nm ; fi
+
+$ANDUMP $WHERE/ut.ile.nm > $WHERE/ut.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.andump ; fi
+$DCDUMP  $WHERE/ut.ile.nm > $WHERE/ut.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.dcdump ; fi
+od -b $WHERE/ut.ile.nm > $WHERE/ut.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.odx ; fi
+od -c $WHERE/ut.ile.nm > $WHERE/ut.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.odc ; fi
+
+
+$DCCP $WHERE/ut.ile.nm $WHERE/ut.ile.nm.cp.ile.nm -n -nodisclaimer > $WHERE/ut.ile.nm.cp.ile.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries ut.ile.nm.cp.ile.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ile.nm.dccp ; fi
+$ANDUMP $WHERE/ut.ile.nm.cp.ile.nm > $WHERE/ut.ile.nm.cp.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ile.nm.andump ; fi
+$DCDUMP  $WHERE/ut.ile.nm.cp.ile.nm > $WHERE/ut.ile.nm.cp.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ile.nm.dcdump ; fi
+od -b $WHERE/ut.ile.nm.cp.ile.nm > $WHERE/ut.ile.nm.cp.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ile.nm.odx ; fi
+od -c $WHERE/ut.ile.nm.cp.ile.nm > $WHERE/ut.ile.nm.cp.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ile.nm.odc ; fi
+
+$DCCP $WHERE/ut.ile.nm $WHERE/ut.ile.nm.cp.ele.nm -n -vr explicit -endian little -nodisclaimer > $WHERE/ut.ile.nm.cp.ele.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries ut.ile.nm.cp.ele.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ele.nm.dccp ; fi
+$ANDUMP $WHERE/ut.ile.nm.cp.ele.nm > $WHERE/ut.ile.nm.cp.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ele.nm.andump ; fi
+$DCDUMP  $WHERE/ut.ile.nm.cp.ele.nm > $WHERE/ut.ile.nm.cp.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ele.nm.dcdump ; fi
+od -b $WHERE/ut.ile.nm.cp.ele.nm > $WHERE/ut.ile.nm.cp.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ele.nm.odx ; fi
+od -c $WHERE/ut.ile.nm.cp.ele.nm > $WHERE/ut.ile.nm.cp.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ile.nm.cp.ele.nm.odc ; fi
+
+
+# Specify VRs directly for ut elements in explicit stream ...
+
+$ANCREATE <<EOF > $WHERE/ut.ele.nm -explicit
+(0x0040,0xa160) UT Text Value 	 VR=<UT>   VL=<0x000e> <Test VR of UT>
+EOF
+
+if [ "$mode" = "compare" ]; then comparebinaries ut.ele.nm ; fi
+
+$ANDUMP $WHERE/ut.ele.nm > $WHERE/ut.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.andump ; fi
+$DCDUMP  $WHERE/ut.ele.nm > $WHERE/ut.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.dcdump ; fi
+od -b $WHERE/ut.ele.nm > $WHERE/ut.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.odx ; fi
+od -c $WHERE/ut.ele.nm > $WHERE/ut.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.odc ; fi
+
+$DCCP $WHERE/ut.ele.nm $WHERE/ut.ele.nm.cp.ile.nm -n -nodisclaimer > $WHERE/ut.ele.nm.cp.ile.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries ut.ele.nm.cp.ile.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ile.nm.dccp ; fi
+$ANDUMP $WHERE/ut.ele.nm.cp.ile.nm > $WHERE/ut.ele.nm.cp.ile.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ile.nm.andump ; fi
+$DCDUMP  $WHERE/ut.ele.nm.cp.ile.nm > $WHERE/ut.ele.nm.cp.ile.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ile.nm.dcdump ; fi
+od -b $WHERE/ut.ele.nm.cp.ile.nm > $WHERE/ut.ele.nm.cp.ile.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ile.nm.odx ; fi
+od -c $WHERE/ut.ele.nm.cp.ile.nm > $WHERE/ut.ele.nm.cp.ile.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ile.nm.odc ; fi
+
+$DCCP $WHERE/ut.ele.nm $WHERE/ut.ele.nm.cp.ele.nm -n -vr explicit -endian little -nodisclaimer > $WHERE/ut.ele.nm.cp.ele.nm.dccp 2>&1
+if [ "$mode" = "compare" ]; then comparebinaries ut.ele.nm.cp.ele.nm ; fi
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ele.nm.dccp ; fi
+$ANDUMP $WHERE/ut.ele.nm.cp.ele.nm > $WHERE/ut.ele.nm.cp.ele.nm.andump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ele.nm.andump ; fi
+$DCDUMP  $WHERE/ut.ele.nm.cp.ele.nm > $WHERE/ut.ele.nm.cp.ele.nm.dcdump 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ele.nm.dcdump ; fi
+od -b $WHERE/ut.ele.nm.cp.ele.nm > $WHERE/ut.ele.nm.cp.ele.nm.odx 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ele.nm.odx ; fi
+od -c $WHERE/ut.ele.nm.cp.ele.nm > $WHERE/ut.ele.nm.cp.ele.nm.odc 2>&1
+if [ "$mode" = "compare" ]; then comparedumps    ut.ele.nm.cp.ele.nm.odc ; fi
+
+
+if [ "$mode" = "compare" ]
+then
+	rm -rf "$TMPROOT"
+fi
+
+echo $0 finished
diff --git a/appsrc/dcdisp/Imakefile b/appsrc/dcdisp/Imakefile
new file mode 100755
index 0000000..dace324
--- /dev/null
+++ b/appsrc/dcdisp/Imakefile
@@ -0,0 +1,32 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES = $(PROJECTAPPDCDISPEXTRAINCLUDES)
+
+SRCSDISP = dcdisp.cc
+OBJSDISP = dcdisp.o
+
+CPLUSPLUS_SRCS = $(SRCSDISP)
+OBJS           = $(OBJSDISP)
+
+AllTarget(dcdisp)
+NormalCCProgramTarget(dcdisp,$(OBJSDISP),$(PROJECTDCDISPDEPLIBS),$(PROJECTDCDISPLIBS),-lm)
+InstallProgram(dcdisp,$(INSTALLBINDIR))
+InstallManPage(dcdisp,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare dump
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+
+test.create::
+	@$(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create dump
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcdisp "-v -nodisplayloop -writeimage" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) create dump; fi
diff --git a/appsrc/dcdisp/Notes.Web b/appsrc/dcdisp/Notes.Web
new file mode 100755
index 0000000..40fe054
--- /dev/null
+++ b/appsrc/dcdisp/Notes.Web
@@ -0,0 +1,37 @@
+To use dcdisp with web server/browser:
+
+1. In the unix browser's mailcap file (perhaps your home .mailcap) add:
+
+	application/x-dicom; echo "Press 'Q' in DICOM display window to quit" \; /usr/local/bin/dcdisp -noattributes %s
+
+  (obviously with the path replaced as required)
+  (note that if ; is used, it must be escaped \;)
+
+  or, if full help information is wanted:
+
+	application/x-dicom; /usr/local/bin/dcdisp -noattributes -showwithhelp %s
+
+  or, if you need no guidance:
+
+	application/x-dicom; /usr/local/bin/dcdisp -noattributes %s
+
+  the reload the file by using Options/Preferences/Helpers in Netscape
+
+2. In the servers conf/mime.types (if using CERN httpd) add a mapping
+   from some convenient extension to application/x-dicom:
+
+	application/x-dicom            dicom dc3 dcm d10 ctn
+
+
+If on a Mac, with Netscape, use the preferences/general/helpers
+panel to link application/x-dicom to some viewing application - I tried
+Dr.Razz from ftp.u.washington.edu/public/razz (versions 0.8a5 and 0.91b6
+both worked fine). Choose the "acrN" from the mac file type list.
+
+I also tried Osiris 2.5 but it didn't seem to recognize any other
+mac file type than PAPY or PICT, it wouldn't even open the sample
+DICOM files on the CD-ROM when they were double clicked. It did
+recognized them if they were opened from within Osiris from the File
+menu, but this is no use from Netscape. These CD-ROM files had a file
+type of DICM for future reference.
+
diff --git a/appsrc/dcdisp/dcdisp.cc b/appsrc/dcdisp/dcdisp.cc
new file mode 100644
index 0000000..32bd36f
--- /dev/null
+++ b/appsrc/dcdisp/dcdisp.cc
@@ -0,0 +1,1428 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdisp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+//#define PROFILETIME
+//#define DYNAMICWINDOW
+//#define DONTSENDEXPOSEEVENT
+
+#ifdef PROFILETIME
+#include <sys/types.h>
+#include <sys/time.h>
+static long g_starttime;
+static long g_lasttime;
+static long g_newtime;
+static struct timeval g_rtime;
+#define STARTTHETIME		((void)gettimeofday(&g_rtime,0),g_lasttime=g_starttime=g_rtime.tv_sec*1000+g_rtime.tv_usec/1000)
+#define ECHOTHETIME(s)		((void)gettimeofday(&g_rtime,0), \
+				  g_newtime=g_rtime.tv_sec*1000+g_rtime.tv_usec/1000, \
+				  cerr << "***TIME***: " << s << ": " << dec << g_newtime-g_starttime \
+				       << "(" << g_newtime-g_lasttime << ") mS"<< endl, \
+				  g_lasttime=g_newtime)
+#else
+#define STARTTHETIME
+#define ECHOTHETIME(s)
+#endif
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+#include "errclass.h"
+
+#include "attrothr.h"
+
+#include "ourdisp.h"
+
+#include "lutclass.h"
+#include "lutextr.h"
+
+#include "usepal.h"
+#include "usegray.h"
+#include "useindex.h"
+#include "usetrue.h"
+
+#include "rdimage.h"
+#include "rdgray.h"
+#include "rdindex.h"
+#include "rdrgb.h"
+#include "rdhsv.h"
+#include "rdargb.h"
+#include "rdcmyk.h"
+
+#include "pixposn.h"
+
+class OverlayBuffer {
+private:
+	bool		present[16];
+	bool		activated[16];
+
+	Uint16		vOverlayRows[16];
+	Uint16		vOverlayColumns[16];
+	const char *	vOverlayType[16];
+	Uint16		vOverlayBitsAllocated[16]; 
+	Uint16		vOverlayBitPosition[16];
+	Uint16		vOverlayLocation[16];			// old ACR-NEMA, defaults to 0x7FEO if no pixel data
+	Int16		vOverlayOriginRow[16];
+	Int16 		vOverlayOriginColumn[16];
+
+	Attribute *	aOverlayData[16];
+
+	Uint32		vOverlayDataLength[16];
+	const Uint16 *	vOverlayDataValues[16];
+
+	void dump(TextOutputStream& log,const char *msg);
+
+public:
+	OverlayBuffer(ManagedAttributeList& list,TextOutputStream& log,bool noattributes);
+
+	bool getOverlayValues(Uint16 which,const Uint16 * &data, Uint32 &length, Uint16 &bitsallocated, Uint16 &bitposition) const
+		{
+			Assert(which<16);
+			if (activated[which]) {
+				bitsallocated=vOverlayBitsAllocated[which];
+				bitposition=vOverlayBitPosition[which];
+				Assert(aOverlayData[which]);
+				return aOverlayData[which]->getValue(data,length);
+			}
+			else {
+				return false;
+			}
+		}
+
+	void putOverlay(OurWindowImage &wimage,unsigned which);
+	void putOverlay(OurWindowImage &wimage);
+};
+
+OverlayBuffer::OverlayBuffer(ManagedAttributeList& list,TextOutputStream& log,bool noattributes)
+{
+	unsigned u;
+	for (u=0; u<=0x1E; u+=2) {
+
+		activated[u/2] = false;
+
+		Attribute *aOverlayRows = list[Tag(OverlayRows_GROUP+u,OverlayRows_ELEMENT)];
+		Attribute *aOverlayColumns = list[Tag(OverlayColumns_GROUP+u,OverlayColumns_ELEMENT)];
+		Attribute *aOverlayType = list[Tag(OverlayType_GROUP+u,OverlayType_ELEMENT)];
+		Attribute *aOverlayBitsAllocated = list[Tag(OverlayBitsAllocated_GROUP+u,OverlayBitsAllocated_ELEMENT)];
+		Attribute *aOverlayBitPosition = list[Tag(OverlayBitPosition_GROUP+u,OverlayBitPosition_ELEMENT)];
+		Attribute *aOverlayLocation = list[Tag(OverlayLocation_GROUP+u,OverlayLocation_ELEMENT)];
+		Attribute *aOverlayOrigin = list[Tag(OverlayOrigin_GROUP+u,OverlayOrigin_ELEMENT)];
+		aOverlayData[u/2] = list[Tag(OverlayData_GROUP+u,OverlayData_ELEMENT)];
+
+		present[u/2] = (aOverlayRows || aOverlayColumns || aOverlayType
+			       || aOverlayBitsAllocated || aOverlayBitPosition
+			       || aOverlayLocation || aOverlayOrigin || aOverlayData[u/2]);
+
+		vOverlayRows[u/2] = Uint16(AttributeValue(list[TagFromName(Rows)]));	// default
+		if (!aOverlayRows) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayRows\" for group " << hex << u << dec
+				    << " - using \"Rows\" = " << vOverlayRows[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayRows[u/2]=AttributeValue(aOverlayRows);
+
+		vOverlayColumns[u/2] = Uint16(AttributeValue(list[TagFromName(Columns)]));	// default
+		if (!aOverlayColumns) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayColumns\" for group " << hex << u << dec
+				    << " - using \"Columns\" = " << vOverlayColumns[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayColumns[u/2]=AttributeValue(aOverlayColumns);
+
+		vOverlayType[u/2] = "G";
+		if (!aOverlayType) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayType\" for group " << hex << u << dec
+				    << " - using \"G\""
+				    << endl;
+			}
+		}
+		else {
+			const char *v=AttributeValue(aOverlayType);
+			if (v && strcmp(v,"G") == 0)
+				vOverlayType[u/2]="G";
+			else if (v && strcmp(v,"R") == 0)
+				vOverlayType[u/2]="R";
+			else
+				log << EMsgDC(BadAttributeValue)
+				    << " - \"OverlayType\" for group " << hex << u << dec
+				    << " = <" << (v ? v : "") << ">"
+				    << " - using \"G\""
+				    << endl;
+		}
+
+		vOverlayBitsAllocated[u/2] = Uint16(AttributeValue(list[TagFromName(BitsAllocated)]));	// default
+		if (!aOverlayBitsAllocated) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayBitsAllocated\" for group " << hex << u << dec
+				    << " - using \"BitsAllocated\" = " << vOverlayBitsAllocated[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayBitsAllocated[u/2]=AttributeValue(aOverlayBitsAllocated);
+
+		vOverlayBitPosition[u/2] = 0;	// default
+		if (!aOverlayBitPosition) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayBitPosition\" for group " << hex << u << dec
+				    << " - using 0"
+				    << endl;
+			}
+		}
+		else
+			vOverlayBitPosition[u/2]=AttributeValue(aOverlayBitPosition);
+
+		vOverlayOriginRow[u/2] = 1;	// default
+		vOverlayOriginColumn[u/2] = 1;	// default
+		if (!aOverlayOrigin) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayOrigin\" for group " << hex << u << dec
+				    << " - using 1\\1"
+				    << endl;
+			}
+		}
+		else if (aOverlayOrigin->getVM() != 2)
+			log << EMsgDC(BadAttributeValueMultiplicity)
+			    << " - \"OverlayOrigin\" for group " << hex << u << dec
+			    << " != 2 "
+			    << " - using 1\\1"
+			    << endl;
+		else {
+			bool success;
+			success=aOverlayOrigin->getValue(0,vOverlayOriginRow[u/2]);
+			Assert(success);
+			success=aOverlayOrigin->getValue(1,vOverlayOriginColumn[u/2]);
+			Assert(success);
+		}
+
+		vOverlayLocation[u/2] = 0;	// missing flag (not required in DICOM 3.0)
+		if (aOverlayLocation)
+			vOverlayLocation[u/2]=AttributeValue(aOverlayLocation);
+
+		if (present[u/2] && aOverlayData[u/2]) {
+			Assert(aOverlayData[u/2]->getValue(vOverlayDataValues[u/2],vOverlayDataLength[u/2]));
+			Assert(vOverlayDataLength[u/2]);
+			Assert(vOverlayDataValues[u/2]);
+		}
+
+		if (present[u/2] && !vOverlayLocation[u/2] && !aOverlayData[u/2])
+			vOverlayLocation[u/2]=0x7FE0;
+
+		// Only Overlay Data supported for now :(
+
+		if (present[u/2] && aOverlayData[u/2]) {
+			activated[u/2]=true;
+
+			Assert(vOverlayOriginRow[u/2] == 1);
+			Assert(vOverlayOriginColumn[u/2] == 1);
+			Assert(vOverlayRows[u/2]== Uint16(AttributeValue(list[TagFromName(Rows)])));
+			Assert(vOverlayColumns[u/2] == Uint16(AttributeValue(list[TagFromName(Columns)])));
+			long expectedLength = vOverlayRows[u/2]*vOverlayColumns[u/2]*vOverlayBitsAllocated[u/2]/16;
+//cerr << "OverlayBuffer::OverlayBuffer(): expectedLength = " << expectedLength << endl;
+			if (expectedLength%2 != 0) ++expectedLength;	// pad odd length to even length
+//cerr << "OverlayBuffer::OverlayBuffer(): expectedLength after padding = " << expectedLength << endl;
+//cerr << "OverlayBuffer::OverlayBuffer(): vOverlayDataLength[u/2] = " << vOverlayDataLength[u/2] << endl;
+//cerr << "OverlayBuffer::OverlayBuffer(): vOverlayRows[u/2] = " << vOverlayRows[u/2] << endl;
+//cerr << "OverlayBuffer::OverlayBuffer(): vOverlayColumns[u/2] = " << vOverlayColumns[u/2] << endl;
+//cerr << "OverlayBuffer::OverlayBuffer(): vOverlayBitsAllocated[u/2] = " << vOverlayBitsAllocated[u/2] << endl;
+			Assert(vOverlayDataLength[u/2] == expectedLength);
+		}
+
+	}
+
+	if (!noattributes) dump(log,"Using");
+}
+
+void
+OverlayBuffer::dump(TextOutputStream& log,const char *msg)
+{
+	Assert(msg);
+	unsigned u;
+	for (u=0; u<=0x1E; u+=2) {
+		if (present[u/2]) {
+			log << msg << " Overlay Group " << hex << u << dec << " ..." << endl;
+			log << "\tpresent = " << (present[u/2] ? "yes" : "no") << endl;
+			log << "\tactivated = " << (activated[u/2] ? "yes" : "no") << endl;
+			log << "\tRows = " << dec << vOverlayRows[u/2] << endl;
+			log << "\tColumns = " << dec << vOverlayColumns[u/2] << endl;
+			log << "\tType = " << dec << vOverlayType[u/2] << endl;
+			log << "\tBitsAllocated = " << dec << vOverlayBitsAllocated[u/2] << endl;
+			log << "\tBitPosition = " << dec << vOverlayBitPosition[u/2] << endl;
+			log << "\tOrigin (Row) = " << dec << vOverlayOriginRow[u/2] << endl;
+			log << "\tOrigin (Column) = " << dec << vOverlayOriginColumn[u/2] << endl;
+			log << "\tLocation = " << hex << vOverlayLocation[u/2] << dec << endl;
+			log << "\tData " << (aOverlayData[u/2] ? "is" : "is not") << " present" << endl;
+			if (aOverlayData[u/2])
+				log << "\tData Length = " << dec << vOverlayDataLength[u/2] << endl;
+			if (aOverlayData[u/2] && vOverlayDataValues[u/2] && vOverlayDataLength[u/2])
+				log << "\tData Value[0] = " << hex << vOverlayDataValues[u/2][0] << dec << endl;
+		}
+	}
+}
+
+void
+OverlayBuffer::putOverlay(OurWindowImage &wimage,unsigned which)
+{
+cerr << "OverlayBuffer::putOverlay(" << which << "):" << endl;
+	Assert(which < 16);
+	if (activated[which]) {
+cerr << "OverlayBuffer::putOverlay(" << which << "): activated" << endl;
+		Assert(vOverlayBitsAllocated[which] <= 16);
+		Assert(16%vOverlayBitsAllocated[which] == 0);
+		Assert(vOverlayBitPosition[which] < vOverlayBitsAllocated[which]);
+
+		unsigned bitincrement = vOverlayBitsAllocated[which];
+		unsigned bitmask = 1 << vOverlayBitPosition[which];
+		unsigned bitgroupsperword = 16 / bitincrement;
+
+		const Uint16 *ptr = vOverlayDataValues[which];
+		const Uint16 *last = ptr + vOverlayDataLength[which];
+
+		unsigned rows = vOverlayRows[which];
+		unsigned cols = vOverlayColumns[which];
+		unsigned row = 0;
+		unsigned col = 0;
+
+		while (ptr < last) {
+			Uint16 word=*ptr++;
+			Assert (row < rows);
+			// optimize here for word == 0 later
+			unsigned bit = 0;
+			while (bit < 16) {
+				bit+=bitincrement;
+				if (word & bitmask) wimage.putPoint(col,row);
+				word=word>>bitincrement;
+				if (++col >= cols) {
+					col=0;
+					++row;
+				}
+			}
+		}
+	}
+}
+
+void
+OverlayBuffer::putOverlay(OurWindowImage &wimage)
+{
+	unsigned which;
+	for (which=0; which<16; ++which) {
+		if (activated[which]) putOverlay(wimage,which);
+	}
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+STARTTHETIME;
+ECHOTHETIME("start");
+
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool nodisplayloop=options.get("nodisplayloop");
+	bool noattributes=options.get("noattributes");
+	bool showwithhelp=options.get("showwithhelp");
+	bool justhelp=options.get("help") || options.get("h");
+	bool invertedgrayscaleoption=options.get("invertedgray");
+	bool forcesigned=options.get("signed");
+	bool forceunsigned=options.get("unsigned");
+	bool ignorewindowinobject=options.get("ignorewindow");
+	bool writeimage=options.get("writeimage");
+	bool showoverlays=options.get("showoverlays");
+	bool ignorepadvalue=options.get("ignorepadvalue");;
+
+	unsigned windowwidthvalue=0;
+	bool windowwidthset=options.get("windowwidth",windowwidthvalue);
+	unsigned windowlevelvalue=0;
+	bool windowlevelset=options.get("windowlevel",windowlevelvalue);
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (forcesigned && forceunsigned) {
+		cerr << EMsgDC(NotBothSignedOrUnsigned) << endl;
+		bad=true;
+	};
+
+	if ( (windowwidthset && !windowlevelset)
+	 || (!windowwidthset &&  windowlevelset)) {
+		cerr << EMsgDC(NeedBothWindowLevelWidth) << endl;
+		bad=true;
+	};
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-h|-help]"
+			<< " [-showwithhelp]"
+			<< " [-nodisplayloop]"
+			<< " [-noattributes]"
+			<< " [-windowwidth width]"
+			<< " [-windowlevel level]"
+			<< " [-ignorewindow]"
+			<< " [-invertedgray]"
+			<< " [-[signed|unsigned]]"
+			<< " [-ignorepadvalue]"
+			<< " [-showoverlays]"
+			<< " [-writeimage]"
+			<< " [" << MMsgDC(InputFile)
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	if (showwithhelp || justhelp) {
+		cerr << "Window level/width:" << endl;
+		cerr << endl;
+		cerr << "\t- for > 8 bit deep grayscale images only" << endl;
+		cerr << "\t- controlled by cursor movement while the left mouse button is down" << endl;
+		cerr << "\t- left or right decreases or increases width" << endl;
+		cerr << "\t- down or up decreases or increases level" << endl;
+		cerr << endl;
+		cerr << "\t- if shift key held, effect is multiplied 10 fold" << endl;
+		cerr << "\t- if control key held, effect is multiplied 100 fold" << endl;
+		cerr << "\t- if both shift & control keys held, effect is multiplied 1000 fold" << endl;
+		cerr << endl;
+		cerr << "\t- arrow keys (with or without shift and control) do the same" << endl;
+		cerr << endl;
+		cerr << "Cursor feedback:" << endl;
+		cerr << endl;
+		cerr << "\t- crosshair cursor when quiescent" << endl;
+		cerr << "\t- ramp  cursor while setting new values" << endl;
+		cerr << "\t- watch cursor while recomputing ... BE PATIENT" << endl;
+		cerr << endl;
+		cerr << "Key commands:" << endl;
+		cerr << endl;
+		cerr << "\t- o or O toggles overlays on or off." << endl;
+		cerr << endl;
+		cerr << "\t- v or V restores the VOI LUT or toggles to the next VOI LUT." << endl;
+		cerr << endl;
+		cerr << "\t- q or Q or x or X or return quits." << endl;
+		cerr << endl;
+		cerr << "Annotation:" << endl;
+		cerr << endl;
+		cerr << "\t- top left   - Patient ID" << endl;
+		cerr << "\t- top center - Study ID/Series Number/Image Number" << endl;
+		cerr << "\t- top right  - Patient Name" << endl;
+		cerr << endl;
+	}
+
+	if (justhelp) return 0;
+
+ECHOTHETIME("reading");
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		//return 1;	// Press on regardless ...
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Float32 vRescaleIntercept = 0;
+	Attribute *aRescaleIntercept = list[TagFromName(RescaleIntercept)];
+	if (aRescaleIntercept)	// optional
+		vRescaleIntercept=AttributeValue(aRescaleIntercept);
+
+	Float32 vRescaleSlope = 0;
+	Attribute *aRescaleSlope = list[TagFromName(RescaleSlope)];
+	if (aRescaleSlope)	// optional
+		vRescaleSlope=AttributeValue(aRescaleSlope);
+
+	Uint16 vWindowCenter = 0;
+	Attribute *aWindowCenter = list[TagFromName(WindowCenter)];
+	if (aWindowCenter)	// optional
+		vWindowCenter=AttributeValue(aWindowCenter);
+
+	Uint16 vWindowWidth = 0;
+	Attribute *aWindowWidth = list[TagFromName(WindowWidth)];
+	if (aWindowWidth)	// optional
+		vWindowWidth=AttributeValue(aWindowWidth);
+
+	Uint16 vPixelPaddingValue;
+	Attribute *aPixelPaddingValue = list[TagFromName(PixelPaddingValue)];
+	if (aPixelPaddingValue)	{	// optional
+		vPixelPaddingValue=AttributeValue(aPixelPaddingValue);
+	}
+	bool usepadvalue=aPixelPaddingValue && !ignorepadvalue;
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+
+	if (!aPixelData) {
+		if (!noattributes)
+			log << "\tPixeldata not in normal place ... checking for ImageLocation attribute" << endl;
+		Uint16 groupstart;
+		Uint16 groupend;
+		Attribute *aImageLocation=list[TagFromName(ImageLocation)];
+		if (aImageLocation) {
+			Uint16 vImageLocation=AttributeValue(aImageLocation);
+			if (!noattributes)
+				log << "\tImageLocation = " << hex << vImageLocation << dec << endl;
+			groupstart=vImageLocation;
+			groupend=vImageLocation;
+		}
+		else {
+			groupstart=0x7fe0;
+			groupend=0x7ffd;
+		}
+		if (!noattributes)
+			log << "\tNow searching for Pixeldata" << endl;
+		Uint16 group;
+		for (group=groupstart; !aPixelData && group <= groupend; ++group) {
+			Uint32 owner;
+			for (owner=((group&0x0001) ? 0x0100 : 0x0000);
+					!aPixelData && owner <= ((group&0x0001) ? 0xff00 : 0x0000); owner+=0x0100) {
+				if ((aPixelData=list[Tag(group,Uint16(owner|0x0010))]) && aPixelData->isOtherData()) {
+					if (!noattributes)
+						log << "\tFound Pixeldata in ";
+						aPixelData->getTag().write(log);
+						log << endl;
+					break;
+				}
+				aPixelData=0;
+			}
+		}
+	}
+
+	if (!aPixelData) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelData\""
+		    << endl;
+		log << EMsgDC(NothingToDisplay) << endl;
+		return 1;
+	}
+
+	Uint32 length=aPixelData->getVL();
+
+	Attribute *aVOILUTSequence = list[TagFromName(VOILUTSequence)];
+	int nVOILUT=0;
+	Uint16 *VOILUT_first = 0;
+	Uint16 *VOILUT_number = 0;
+	Uint16 *VOILUT_depth = 0;
+	Uint16 const **VOILUT_table = 0;
+	if (aVOILUTSequence) {
+cerr << "Have VOILUTSequence" << endl;
+		AttributeList **items;
+		nVOILUT=aVOILUTSequence->getLists(&items);
+		if (nVOILUT) {
+			VOILUT_first = new Uint16[nVOILUT];
+			Assert(VOILUT_first);
+			VOILUT_number = new Uint16[nVOILUT];
+			Assert(VOILUT_number);
+			VOILUT_depth = new Uint16[nVOILUT];
+			Assert(VOILUT_depth);
+			VOILUT_table = new const Uint16 *[nVOILUT];
+			Assert(VOILUT_table);
+			int i;
+			for (i=0; i<nVOILUT; ++i) {
+				Assert(items[i]);
+				Attribute *aLUTDescriptor=items[i]->operator[](TagFromName(LUTDescriptor));
+				Assert(aLUTDescriptor);
+				Assert(aLUTDescriptor->getVM() == 3);
+				Assert(aLUTDescriptor->getValue(0,VOILUT_number[i]));
+				Assert(aLUTDescriptor->getValue(1,VOILUT_first[i]));
+				Assert(aLUTDescriptor->getValue(2,VOILUT_depth[i]));
+cerr << "VOILUTSequence" << endl
+     << "\t first[" << dec << i << "]=" << VOILUT_first[i] << endl
+     << "\t number[" << dec << i << "]=" << VOILUT_number[i] << endl
+     << "\t depth[" << dec << i << "]=" << VOILUT_depth[i] << endl;
+
+				Attribute *aLUTData=items[i]->operator[](TagFromName(LUTData));
+				Assert(aLUTData);
+				if (aLUTData->isOtherWordNonPixel()) {
+					Uint32 nLUTData;
+					const Uint16 *vLUTData = NULL;
+					Assert(aLUTData->getValue(vLUTData,nLUTData));
+					VOILUT_table[i] = vLUTData;
+				}
+				else if (aLUTData->isNumericBinary()) {		// e.g. US VR
+					Uint16 *vLUTData = new Uint16[VOILUT_number[i]];
+					Assert(VOILUT_table[i]);
+					int j;
+					for (j=0; j<VOILUT_number[i]; ++j) {
+						Assert(aLUTData->getValue(j,vLUTData[j]));
+					}
+					VOILUT_table[i] = vLUTData;
+				}
+				else {
+					Assert(0);
+				}
+			}
+		}
+	}
+
+	if (!noattributes) {
+		log << "Read ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (aWindowCenter) log << vWindowCenter; log << endl;
+		log << "\tWindowWidth = "; if (aWindowWidth) log << vWindowWidth; log << endl;
+		log << "\tPixelPaddingValue = "; if (aPixelPaddingValue) log << vPixelPaddingValue; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tPixelData Value Length = " << hex << length << dec << endl;
+	}
+
+
+	// Try to guess some missing attributes ...
+
+	if (vRescaleSlope*vRescaleSlope < 0.00001) vRescaleSlope=1;
+
+	if (vPixelRepresentation == 0xffff) vPixelRepresentation=0;
+	if (forceunsigned) vPixelRepresentation=0;
+	if (forcesigned) vPixelRepresentation=1;
+
+	if (!vNumberOfFrames) vNumberOfFrames=1;
+
+	if (!vSamplesPerPixel && !vPhotometricInterpretation) {
+		vSamplesPerPixel=1;
+		vPhotometricInterpretation=StrDup("MONOCHROME2");
+	}
+	else if (!vSamplesPerPixel && vPhotometricInterpretation) {
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0
+		 || strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0
+		 || strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0
+		) {
+			vSamplesPerPixel=1;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"RGB") == 0
+		 || strcmp(vPhotometricInterpretation,"HSV") == 0
+		) {
+			vSamplesPerPixel=3;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"ARGB") == 0
+		 || strcmp(vPhotometricInterpretation,"CMYK") == 0
+		) {
+			vSamplesPerPixel=4;
+		}
+	}
+	else if (!vPhotometricInterpretation && vSamplesPerPixel) {
+		switch (vSamplesPerPixel) {
+			case 1:	// could check for presence of palette
+				vPhotometricInterpretation=StrDup("MONOCHROME2");
+				break;
+			case 3:	vPhotometricInterpretation=StrDup("RGB");
+				break;
+			case 4:	vPhotometricInterpretation=StrDup("ARGB");
+				break;
+		}
+	}
+
+	if (!vBitsAllocated && length && length != 0xffffffff
+	 && (vRows && vColumns && vNumberOfFrames && vSamplesPerPixel)) {
+		vBitsAllocated=Uint16(length/((Uint32)vRows*vColumns*vNumberOfFrames*vSamplesPerPixel)*8);
+	}
+
+	if (!vBitsAllocated && vBitsStored)
+		vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+
+	if (!vBitsAllocated) {
+		if (strcmp(aPixelData->getVR(),"OW") == 0)
+			vBitsAllocated=16;
+		else
+			vBitsAllocated=8;
+	}
+
+	Assert(vBitsAllocated <= 16);
+
+	if (!vBitsStored) vBitsStored=vBitsAllocated;
+	if (!vHighBit) vHighBit=vBitsStored-1;
+
+	Uint32 framelengthinwords=length/vNumberOfFrames*8/vBitsAllocated;
+
+	if (!vRows) {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vRows=Uint16(sqrt(framelengthinwords));
+				vColumns=Uint16(length/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				Uint32 left=framelengthinwords/vSamplesPerPixel;
+				vRows=Uint16(sqrt(left));
+				vColumns=Uint16(left/vRows);
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				Uint32 left=framelengthinwords/vColumns;
+				vRows=Uint16(sqrt(length));
+				vSamplesPerPixel=1;
+			}
+			else {
+				vRows=Uint16(framelengthinwords/(vColumns*vSamplesPerPixel));
+			}
+		}
+	}
+	else {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vColumns=Uint16(framelengthinwords/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				vColumns=Uint16(framelengthinwords/(vRows*vSamplesPerPixel));
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				vSamplesPerPixel=Uint16(framelengthinwords/(vRows*vColumns));
+			}
+			// else we know all three
+		}
+	}
+
+	// use object values if present and not zero, unless overridden by command line ...
+
+	if (!windowwidthset && !windowlevelset && !ignorewindowinobject && aWindowCenter && vWindowCenter && aWindowWidth && vWindowWidth) {
+		windowwidthset=true;
+		windowwidthvalue=vWindowWidth;
+		windowlevelset=true;
+		windowlevelvalue=vWindowCenter;
+	}
+
+	if (!noattributes) {
+		log << "Using ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (windowlevelset) log << windowlevelvalue; log << endl;
+		log << "\tWindowWidth = "; if (windowwidthset) log << windowwidthvalue; log << endl;
+		log << "\tPixelPaddingValue = "; if (usepadvalue) log << vPixelPaddingValue; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tRows*Columns*SamplesPerPixel*BitsAllocated/8 = "
+		    << hex << (Uint32)vRows*vColumns*vSamplesPerPixel*vBitsAllocated/8
+		    << dec << endl;
+	}
+
+	Assert((Uint32)vRows*vColumns*vSamplesPerPixel <= framelengthinwords);
+
+	if (!vRows || !vColumns
+	 || !vPhotometricInterpretation || !vSamplesPerPixel
+	 || !vBitsAllocated
+	 || (vSamplesPerPixel > 1 && vPlanarConfiguration == 0xffff)) {
+		log << EMsgDC(MissingMandatoryAttributes) << endl;
+		return 1;
+	}
+
+ECHOTHETIME("attributes done ... setting up overlays");
+
+	OverlayBuffer overlays(list,log,noattributes);
+
+ECHOTHETIME("attributes done ... setting up pixel data");
+
+	ReadableImage *image = 0;
+	SupplySourceFromAttribute sPixelData(aPixelData);
+
+	// The standard doesn't say it, but what could a
+	// signed PixelRepresentation mean for other than grayscale ?
+
+	bool pixelrepresentationok = (vPixelRepresentation == 0);
+	bool windowlevelwidthok = !windowlevelset && !windowwidthset;
+
+	if (vSamplesPerPixel == 1) {
+		bool monochrome=false;
+		bool invertedgrayscale=false;
+		bool palettecolor=false;
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0) {
+			monochrome=true;
+			invertedgrayscale=true;
+		}
+		else if (strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0) {
+			monochrome=true;
+			invertedgrayscale=false;
+		}
+		else if (strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0) {
+			palettecolor=true;
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+
+		if (invertedgrayscaleoption) invertedgrayscale=!invertedgrayscale;
+
+		DicomLUT *RedLUT;
+		DicomLUT *GreenLUT;
+		DicomLUT *BlueLUT;
+
+		if (palettecolor && !extractLookUpTables(log,list,RedLUT,GreenLUT,BlueLUT))
+			return 1;
+
+		if (vBitsAllocated <= 8) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				image=new ReadableWindowed8BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale);
+			}
+			else if (palettecolor)
+				image=new Readable8BitIndexedColorImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+		}
+		else if (vBitsAllocated <= 16) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				windowlevelwidthok=true;	// allowed to specify width & level on command line
+				image=new ReadableWindowed16BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale,
+						usepadvalue,vPixelPaddingValue);
+			}
+			else if (palettecolor)
+				image=new Readable16BitIndexedColorImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - BitsStored = " << vBitsStored << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 3) {
+		if (strcmp(vPhotometricInterpretation,"RGB") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else if (strcmp(vPhotometricInterpretation,"HSV") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved24BitHSVImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved24BitHSVImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 4) {
+		if (strcmp(vPhotometricInterpretation,"ARGB") == 0) {
+			DicomLUT *RedLUT;
+			DicomLUT *GreenLUT;
+			DicomLUT *BlueLUT;
+
+			if (!extractLookUpTables(log,list,RedLUT,GreenLUT,BlueLUT))
+				return 1;
+
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved32BitARGBImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved32BitARGBImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else if (strcmp(vPhotometricInterpretation,"CMYK") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved32BitCMYKImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved32BitCMYKImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else {
+		log << EMsgDC(Unsupported) << " - SamplesPerPixel = " << vSamplesPerPixel << endl;
+		return 1;
+	}
+
+	if (!pixelrepresentationok) {
+		log << WMsgDC(NonMonochromeSignedPixelRepresentation) << endl;
+	}
+	if (!windowlevelwidthok) {
+		log << WMsgDC(NoNeedForWindowLevelWidth) << endl;
+	}
+
+	char *vPatientName=AttributeValue(list[TagFromName(PatientName)]);
+	char *vPatientID=AttributeValue(list[TagFromName(PatientID)]);
+	char *vStudyID=AttributeValue(list[TagFromName(StudyID)]);
+	Uint16 vSeriesNumber=AttributeValue(list[TagFromName(SeriesNumber)]);
+	Uint16 vInstanceNumber=AttributeValue(list[TagFromName(InstanceNumber)]);
+
+	ostrstream topleftostr;
+	topleftostr << (vPatientID ? vPatientID : "?") << ends;
+	char *topleftstring=topleftostr.str();
+
+	ostrstream toprightostr;
+	toprightostr << (vPatientName ? vPatientName : "?") << ends;
+	char *toprightstring=toprightostr.str();
+
+	ostrstream topcenterostr;
+	topcenterostr << (vStudyID ? vStudyID : "?") << "/" << vSeriesNumber << "/" << vInstanceNumber << ends;
+	char *topcenterstring=topcenterostr.str();
+
+ECHOTHETIME("opening and setting up display");
+
+	OurDisplay display;
+	if (!display.good()) {
+		log << display.errors() << endl;
+		return 1;
+	}
+
+	OurWindow window(&display,
+		vColumns,
+		vRows*vNumberOfFrames,
+		20,20);
+	if (!window.good()) {
+		log << window.errors() << endl;
+		return 1;
+	}
+
+	OurWindowImage wimage(&window);
+	log << wimage.errors() << endl;
+	if (!wimage.good()) {
+		return 1;
+	}
+
+	OurColorMap map(&display);
+	if (!map.good()) {
+		log << map.errors() << endl;
+		return 1;
+	}
+	else {
+		unsigned nwanted;
+		unsigned nminimum;
+		unsigned n;
+		unsigned long *cells;
+		unsigned short *red;
+		unsigned short *green;
+		unsigned short *blue;
+		if (!(image->getColorCellsWanted(nwanted,nminimum)
+		   && map.setColorCellsWanted(nwanted,nminimum)
+		   && map.getColorCellsAvailable(n,cells)
+		   && image->setColorCellsAvailable(n,cells)
+		   && image->getColorCellValues(n,red,green,blue)
+		   && map.setColorCellValues(n,red,green,blue)
+		)) {
+			log << map.errors();
+			log << "Color map establishment failed" << endl;
+			return 1;
+		}
+		window.setColormap(&map);
+	}
+
+	OurWindowLevelWidthUpdator wlwupdate(
+		window,image->getBits(),	// Probably still same as BitsStored
+		image->getSigned(),		// May have been changed by statistics
+		vRescaleIntercept,vRescaleSlope);
+
+	bool usewlm = !nVOILUT && image->hasWindowLevelWidth();
+
+	int usewhichlut=0;
+
+	if (nVOILUT) {
+		image->setVOILUT(VOILUT_first[usewhichlut],VOILUT_number[usewhichlut],VOILUT_depth[usewhichlut],VOILUT_table[usewhichlut]);
+	}
+
+	if (usewlm && windowlevelset && windowwidthset) {
+		Uint16 width;
+		Uint16 level;
+			level=(Uint16)wlwupdate.getStoredLevelFromDisplayedLevel(windowlevelvalue);
+			width=(Uint16)wlwupdate.getStoredWidthFromDisplayedWidth(windowwidthvalue);
+			image->setWindowLevelWidth(level,width);
+	}
+
+	if (usewlm) {
+		Uint16 width;
+		Uint16 level;
+		image->getWindowLevelWidth(level,width);
+		wlwupdate.set(level,width);
+	}
+
+	char *pixels=wimage.get8BitDataAddress();
+	if (!pixels) {
+		log << EMsgDC(PixelDataTargetNotAvailable) << endl;
+		return 1;
+	}
+
+ECHOTHETIME("first put8BitIndexedPixels");
+
+	if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+			0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+		log << EMsgDC(PixelDataReadFailed) << endl;
+		//return 1;
+	}
+
+	window.useCursorCrossHair();
+	window.start();
+
+	PositionOfPixel positioner(list,log,false);
+
+ECHOTHETIME("about to enter event loop");
+
+	bool shifton=false;
+	bool controlon=false;
+	bool button1down=false;
+	while (1) {
+		XEvent report = display.nextEvent();
+		switch (report.type) {
+			case Expose:
+//cerr << "report.xexpose.count == " << report.xexpose.count << endl;
+				if (report.xexpose.count != 0) break;
+				if (usewlm) wlwupdate.put();
+				window.writeHeaderText(topleftstring,topcenterstring,toprightstring);
+ECHOTHETIME("wimage.put() start");
+				wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+				if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+				if (nodisplayloop) goto done;
+				break;
+			case ButtonPress:
+				if (report.xbutton.button == Button1) {
+					button1down=true;
+					if (usewlm) {
+						wlwupdate.press(report.xbutton.x,report.xbutton.y);
+						window.useCursorLevelWidth();
+					}
+					else {
+						window.alarm();
+					}
+				}
+				break;
+			case ButtonRelease:
+				if (report.xbutton.button == Button1) {
+					button1down=false;
+					if (usewlm) {
+#ifndef DYNAMICWINDOW
+						window.useCursorWatch();
+						wlwupdate.release(report.xbutton.x,report.xbutton.y);
+						Uint16 width;
+						Uint16 level;
+						wlwupdate.get(level,width);
+						if (!image->setWindowLevelWidth(level,width)) {
+							log << map.errors();
+							log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+							return 1;
+						}
+ECHOTHETIME("put8BitIndexedPixels start");
+						if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+								0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+							log << EMsgDC(PixelDataReadFailed) << endl;
+							//return 1;
+						}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+						wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+						if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+						window.redraw();							
+#endif
+						window.useCursorCrossHair();
+#endif
+					}
+				}
+				break;
+			case MotionNotify:
+				if (button1down) {
+					int multiplier=(report.xkey.state&ShiftMask ? 10 : 1)
+						      *(report.xkey.state&ControlMask ? 100 : 1);
+					if (usewlm) {
+						wlwupdate.update(report.xmotion.x,report.xmotion.y,multiplier);
+#ifdef DYNAMICWINDOW
+						window.useCursorWatch();
+						wlwupdate.release(report.xbutton.x,report.xbutton.y);
+						Uint16 width;
+						Uint16 level;
+						wlwupdate.get(level,width);
+						if (!image->setWindowLevelWidth(level,width)) {
+							log << map.errors();
+							log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+							return 1;
+						}
+ECHOTHETIME("put8BitIndexedPixels start");
+						if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+								0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+							log << EMsgDC(PixelDataReadFailed) << endl;
+							//return 1;
+						}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+						wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+						if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+						window.redraw();							
+#endif
+						window.useCursorCrossHair();
+#endif
+					}
+				}
+				else {
+					unsigned short row;
+					unsigned short col;
+					window.reportPosition(
+						report.xmotion.x,report.xmotion.y,
+						row,col);
+					Float64 patientX,patientY,patientZ;
+					if (positioner.getPosition(row,col,patientX,patientY,patientZ)) {
+//cerr <<  "row=" << row
+//     << " col=" << col
+//     << " X=" << patientX
+//     << " Y=" << patientY
+//     << " Z=" << patientZ
+//     << endl;
+						window.clearFooter();
+						ostrstream rowcolostr;
+						rowcolostr <<  "R" << setw(4) << row
+							   << " C" << setw(4) << col
+							   << ends;
+						char *rowcolstr = rowcolostr.str();
+
+						ostrstream xyzostr;
+						xyzostr <<  setiosflags(ios::fixed|ios::showpoint)
+							<<  "X" <<  setprecision(1) << setw(6) << patientX
+							<< " Y" <<  setprecision(1) << setw(6) << patientY
+							<< " Z" <<  setprecision(1) << setw(6) << patientZ
+							<< ends;
+						char *xyzstr = xyzostr.str();
+
+						window.writeFooterText(rowcolstr,0,xyzstr);
+
+						if (rowcolstr) delete[] rowcolstr;
+						if (xyzstr) delete[] xyzstr;
+					}
+
+				}
+				break;
+			case KeyPress:
+				{
+					int deltax=0;
+					int deltay=0;
+					KeySym keysym;
+					(void)XLookupString(&report.xkey,0,0,&keysym,0);
+					switch (keysym) {
+						case XK_Shift_L:
+						case XK_Shift_R:
+						case XK_Shift_Lock:
+						case XK_Control_L:
+						case XK_Control_R:
+							break;		// handled by state, but must be allowed to press them
+						case XK_Left:
+						case XK_R10:		// the shifted state is a different keysym :(
+							deltax=-1;
+							break;
+						case XK_Right:
+						case XK_R12:		// the shifted state is a different keysym :(
+							deltax=1;
+							break;
+						case XK_Up:
+						case XK_R8:		// the shifted state is a different keysym :(
+							deltay=-1;
+							break;
+						case XK_Down:
+						case XK_R14:		// the shifted state is a different keysym :(
+							deltay=1;
+							break;
+						case XK_Escape:
+						case XK_Return:
+						case XK_q:
+						case XK_Q:
+						case XK_x:
+						case XK_X:
+							goto done;
+							// break;
+						case XK_o:
+						case XK_O:
+							showoverlays=!showoverlays;
+#ifdef DONTSENDEXPOSEEVENT
+							if (showoverlays) {
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+								overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+							}
+							else {
+ECHOTHETIME("wimage.put() start");
+								wimage.put();
+ECHOTHETIME("wimage.put() done");
+							}
+#else
+							window.redraw();							
+#endif
+							break;
+						case XK_v:
+						case XK_V:
+							if (nVOILUT) {
+								window.useCursorWatch();
+								if (++usewhichlut >= nVOILUT) usewhichlut=0;
+								image->setVOILUT(VOILUT_first[usewhichlut],VOILUT_number[usewhichlut],
+									VOILUT_depth[usewhichlut],VOILUT_table[usewhichlut]);
+								if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+									0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+									log << EMsgDC(PixelDataReadFailed) << endl;
+									//return 1;
+								}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+								wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+								if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+								window.redraw();							
+#endif
+								window.useCursorCrossHair();
+
+							}
+							else
+								window.alarm();
+							break;
+						default:
+							window.alarm();
+							break;
+					}
+					if (deltax || deltay) {
+						if (usewlm) {
+							int multiplier=(report.xkey.state&ShiftMask ? 10 : 1)
+								      *(report.xkey.state&ControlMask ? 100 : 1);
+							window.useCursorWatch();
+							wlwupdate.move(deltax,deltay,multiplier);
+							Uint16 width;
+							Uint16 level;
+							wlwupdate.get(level,width);
+							if (!image->setWindowLevelWidth(level,width)) {
+								log << map.errors();
+								log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+								return 1;
+							}
+							if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+									0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+								log << EMsgDC(PixelDataReadFailed) << endl;
+								//return 1;
+							}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+							wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+							if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+							window.redraw();							
+#endif
+							window.useCursorCrossHair();
+						}
+						else {
+							window.alarm();
+						}
+					}
+				}
+				break;
+			default:
+				break;
+		}
+	}
+
+	// not reached ...
+
+	// if (topleftstring) delete[] topleftstring;
+	// if (toprightstring) delete[] toprightstring;
+	// if (topcenterstring) delete[] topcenterstring;
+	// if (vPatientName) delete[] vPatientName;
+	// if (vPatientID) delete[] vPatientID;
+	// if (vStudyID) delete[] vStudyID;
+
+done:
+	if (writeimage && !wimage.write8BitDataToPGMStream(cout)) {
+		log << EMsgDC(PixelDataWriteFailed) << endl;
+		return 1;
+	}
+	else {
+		return 0;
+	}
+}
+
diff --git a/appsrc/dcdisp/dcdisp.cc.postsignextend b/appsrc/dcdisp/dcdisp.cc.postsignextend
new file mode 100755
index 0000000..1095336
--- /dev/null
+++ b/appsrc/dcdisp/dcdisp.cc.postsignextend
@@ -0,0 +1,1355 @@
+#define PROFILETIME
+
+#include <math.h>
+
+#ifdef PROFILETIME
+#include <sys/types.h>
+#include <sys/time.h>
+static long g_starttime;
+static long g_lasttime;
+static long g_newtime;
+static struct timeval g_rtime;
+#define STARTTHETIME		((void)gettimeofday(&g_rtime,0),g_lasttime=g_starttime=g_rtime.tv_sec*1000+g_rtime.tv_usec/1000)
+#define ECHOTHETIME(s)		((void)gettimeofday(&g_rtime,0), \
+				  g_newtime=g_rtime.tv_sec*1000+g_rtime.tv_usec/1000, \
+				  cerr << "***TIME***: " << s << ": " << dec << g_newtime-g_starttime \
+				       << "(" << g_newtime-g_lasttime << ") mS"<< endl, \
+				  g_lasttime=g_newtime)
+#endif
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+#include "errclass.h"
+
+#include "attrothr.h"
+
+#include "ourdisp.h"
+
+#include "lutclass.h"
+#include "lutextr.h"
+
+#include "usepal.h"
+#include "usegray.h"
+#include "useindex.h"
+#include "usetrue.h"
+
+#include "rdimage.h"
+#include "rdgray.h"
+#include "rdindex.h"
+#include "rdrgb.h"
+#include "rdhsv.h"
+#include "rdargb.h"
+#include "rdcmyk.h"
+
+#include "pixposn.h"
+
+class OverlayBuffer {
+private:
+	bool		present[16];
+	bool		activated[16];
+
+	Uint16		vOverlayRows[16];
+	Uint16		vOverlayColumns[16];
+	const char *	vOverlayType[16];
+	Uint16		vOverlayBitsAllocated[16]; 
+	Uint16		vOverlayBitPosition[16];
+	Uint16		vOverlayLocation[16];			// old ACR-NEMA, defaults to 0x7FEO if no pixel data
+	Int16		vOverlayOriginRow[16];
+	Int16 		vOverlayOriginColumn[16];
+
+	Attribute *	aOverlayData[16];
+
+	Uint32		vOverlayDataLength[16];
+	const Uint16 *	vOverlayDataValues[16];
+
+	void dump(TextOutputStream& log,const char *msg);
+
+public:
+	OverlayBuffer(ManagedAttributeList& list,TextOutputStream& log,bool noattributes);
+
+	bool getOverlayValues(Uint16 which,const Uint16 * &data, Uint32 &length, Uint16 &bitsallocated, Uint16 &bitposition) const
+		{
+			Assert(which<16);
+			if (activated[which]) {
+				bitsallocated=vOverlayBitsAllocated[which];
+				bitposition=vOverlayBitPosition[which];
+				Assert(aOverlayData[which]);
+				return aOverlayData[which]->getValue(data,length);
+			}
+			else {
+				return false;
+			}
+		}
+
+	void putOverlay(OurWindowImage &wimage,unsigned which);
+	void putOverlay(OurWindowImage &wimage);
+};
+
+OverlayBuffer::OverlayBuffer(ManagedAttributeList& list,TextOutputStream& log,bool noattributes)
+{
+	unsigned u;
+	for (u=0; u<0x1E; u+=2) {
+
+		activated[u/2] = false;
+
+		Attribute *aOverlayRows = list[Tag(OverlayRows_GROUP+u,OverlayRows_ELEMENT)];
+		Attribute *aOverlayColumns = list[Tag(OverlayColumns_GROUP+u,OverlayColumns_ELEMENT)];
+		Attribute *aOverlayType = list[Tag(OverlayType_GROUP+u,OverlayType_ELEMENT)];
+		Attribute *aOverlayBitsAllocated = list[Tag(OverlayBitsAllocated_GROUP+u,OverlayBitsAllocated_ELEMENT)];
+		Attribute *aOverlayBitPosition = list[Tag(OverlayBitPosition_GROUP+u,OverlayBitPosition_ELEMENT)];
+		Attribute *aOverlayLocation = list[Tag(OverlayLocation_GROUP+u,OverlayLocation_ELEMENT)];
+		Attribute *aOverlayOrigin = list[Tag(OverlayOrigin_GROUP+u,OverlayOrigin_ELEMENT)];
+		aOverlayData[u/2] = list[Tag(OverlayData_GROUP+u,OverlayData_ELEMENT)];
+
+		present[u/2] = (aOverlayRows || aOverlayColumns || aOverlayType
+			       || aOverlayBitsAllocated || aOverlayBitPosition
+			       || aOverlayLocation || aOverlayOrigin || aOverlayData[u/2]);
+
+		vOverlayRows[u/2] = Uint16(AttributeValue(list[TagFromName(Rows)]));	// default
+		if (!aOverlayRows) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayRows\" for group " << hex << u << dec
+				    << " - using \"Rows\" = " << vOverlayRows[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayRows[u/2]=AttributeValue(aOverlayRows);
+
+		vOverlayColumns[u/2] = Uint16(AttributeValue(list[TagFromName(Columns)]));	// default
+		if (!aOverlayColumns) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayColumns\" for group " << hex << u << dec
+				    << " - using \"Columns\" = " << vOverlayColumns[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayColumns[u/2]=AttributeValue(aOverlayColumns);
+
+		vOverlayType[u/2] = "G";
+		if (!aOverlayType) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayType\" for group " << hex << u << dec
+				    << " - using \"G\""
+				    << endl;
+			}
+		}
+		else {
+			const char *v=AttributeValue(aOverlayType);
+			if (v && strcmp(v,"G") == 0)
+				vOverlayType[u/2]="G";
+			else if (v && strcmp(v,"R") == 0)
+				vOverlayType[u/2]="R";
+			else
+				log << EMsgDC(BadAttributeValue)
+				    << " - \"OverlayType\" for group " << hex << u << dec
+				    << " = <" << (v ? v : "") << ">"
+				    << " - using \"G\""
+				    << endl;
+		}
+
+		vOverlayBitsAllocated[u/2] = Uint16(AttributeValue(list[TagFromName(BitsAllocated)]));	// default
+		if (!aOverlayBitsAllocated) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayBitsAllocated\" for group " << hex << u << dec
+				    << " - using \"BitsAllocated\" = " << vOverlayBitsAllocated[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayBitsAllocated[u/2]=AttributeValue(aOverlayBitsAllocated);
+
+		vOverlayBitPosition[u/2] = 0;	// default
+		if (!aOverlayBitPosition) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayBitPosition\" for group " << hex << u << dec
+				    << " - using 0"
+				    << endl;
+			}
+		}
+		else
+			vOverlayBitPosition[u/2]=AttributeValue(aOverlayBitPosition);
+
+		vOverlayOriginRow[u/2] = 1;	// default
+		vOverlayOriginColumn[u/2] = 1;	// default
+		if (!aOverlayOrigin) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayOrigin\" for group " << hex << u << dec
+				    << " - using 1\\1"
+				    << endl;
+			}
+		}
+		else if (aOverlayOrigin->getVM() != 2)
+			log << EMsgDC(BadAttributeValueMultiplicity)
+			    << " - \"OverlayOrigin\" for group " << hex << u << dec
+			    << " != 2 "
+			    << " - using 1\\1"
+			    << endl;
+		else {
+			bool success;
+			success=aOverlayOrigin->getValue(0,vOverlayOriginRow[u/2]);
+			Assert(success);
+			success=aOverlayOrigin->getValue(1,vOverlayOriginColumn[u/2]);
+			Assert(success);
+		}
+
+		vOverlayLocation[u/2] = 0;	// missing flag (not required in DICOM 3.0)
+		if (aOverlayLocation)
+			vOverlayLocation[u/2]=AttributeValue(aOverlayLocation);
+
+		if (present[u/2] && aOverlayData[u/2]) {
+			Assert(aOverlayData[u/2]->getValue(vOverlayDataValues[u/2],vOverlayDataLength[u/2]));
+			Assert(vOverlayDataLength[u/2]);
+			Assert(vOverlayDataValues[u/2]);
+		}
+
+		if (present[u/2] && !vOverlayLocation[u/2] && !aOverlayData[u/2])
+			vOverlayLocation[u/2]=0x7FE0;
+
+		// Only Overlay Data supported for now :(
+
+		if (present[u/2] && aOverlayData[u/2]) {
+			activated[u/2]=true;
+
+			Assert(vOverlayOriginRow[u/2] == 1);
+			Assert(vOverlayOriginColumn[u/2] == 1);
+			Assert(vOverlayRows[u/2]== Uint16(AttributeValue(list[TagFromName(Rows)])));
+			Assert(vOverlayColumns[u/2] == Uint16(AttributeValue(list[TagFromName(Columns)])));
+			Assert(vOverlayDataLength[u/2] == vOverlayRows[u/2]*vOverlayColumns[u/2]*vOverlayBitsAllocated[u/2]/16);
+		}
+
+	}
+
+	if (!noattributes) dump(log,"Using");
+}
+
+void
+OverlayBuffer::dump(TextOutputStream& log,const char *msg)
+{
+	Assert(msg);
+	unsigned u;
+	for (u=0; u<0x1E; u+=2) {
+		if (present[u/2]) {
+			log << msg << " Overlay Group " << hex << u << dec << " ..." << endl;
+			log << "\tpresent = " << (present[u/2] ? "yes" : "no") << endl;
+			log << "\tactivated = " << (activated[u/2] ? "yes" : "no") << endl;
+			log << "\tRows = " << dec << vOverlayRows[u/2] << endl;
+			log << "\tColumns = " << dec << vOverlayColumns[u/2] << endl;
+			log << "\tType = " << dec << vOverlayType[u/2] << endl;
+			log << "\tBitsAllocated = " << dec << vOverlayBitsAllocated[u/2] << endl;
+			log << "\tBitPosition = " << dec << vOverlayBitPosition[u/2] << endl;
+			log << "\tOrigin (Row) = " << dec << vOverlayOriginRow[u/2] << endl;
+			log << "\tOrigin (Column) = " << dec << vOverlayOriginColumn[u/2] << endl;
+			log << "\tLocation = " << hex << vOverlayLocation[u/2] << dec << endl;
+			log << "\tData " << (aOverlayData[u/2] ? "is" : "is not") << " present" << endl;
+			if (aOverlayData[u/2])
+				log << "\tData Length = " << dec << vOverlayDataLength[u/2] << endl;
+			if (aOverlayData[u/2] && vOverlayDataValues[u/2] && vOverlayDataLength[u/2])
+				log << "\tData Value[0] = " << hex << vOverlayDataValues[u/2][0] << dec << endl;
+		}
+	}
+}
+
+void
+OverlayBuffer::putOverlay(OurWindowImage &wimage,unsigned which)
+{
+	Assert(which < 16);
+	if (activated[which]) {
+		Assert(vOverlayBitsAllocated[which] <= 16);
+		Assert(16%vOverlayBitsAllocated[which] == 0);
+		Assert(vOverlayBitPosition[which] < vOverlayBitsAllocated[which]);
+
+		unsigned bitincrement = vOverlayBitsAllocated[which];
+		unsigned bitmask = 1 << vOverlayBitPosition[which];
+		unsigned bitgroupsperword = 16 / bitincrement;
+
+		const Uint16 *ptr = vOverlayDataValues[which];
+		const Uint16 *last = ptr + vOverlayDataLength[which];
+
+		unsigned rows = vOverlayRows[which];
+		unsigned cols = vOverlayColumns[which];
+		unsigned row = 0;
+		unsigned col = 0;
+
+		while (ptr < last) {
+			Uint16 word=*ptr++;
+			Assert (row < rows);
+			// optimize here for word == 0 later
+			unsigned bit = 0;
+			while (bit < 16) {
+				bit+=bitincrement;
+				if (word & bitmask) wimage.putPoint(col,row);
+				word=word>>bitincrement;
+				if (++col >= cols) {
+					col=0;
+					++row;
+				}
+			}
+		}
+	}
+}
+
+void
+OverlayBuffer::putOverlay(OurWindowImage &wimage)
+{
+	unsigned which;
+	for (which=0; which<16; ++which) {
+		if (activated[which]) putOverlay(wimage,which);
+	}
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+STARTTHETIME;
+ECHOTHETIME("start");
+
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool nodisplayloop=options.get("nodisplayloop");
+	bool noattributes=options.get("noattributes");
+	bool showwithhelp=options.get("showwithhelp");
+	bool justhelp=options.get("help") || options.get("h");
+	bool invertedgrayscaleoption=options.get("invertedgray");
+	bool forcesigned=options.get("signed");
+	bool forceunsigned=options.get("unsigned");
+	bool ignorewindowinobject=options.get("ignorewindow");
+	bool writeimage=options.get("writeimage");
+	bool showoverlays=options.get("showoverlays");
+
+	unsigned windowwidthvalue=0;
+	bool windowwidthset=options.get("windowwidth",windowwidthvalue);
+	unsigned windowlevelvalue=0;
+	bool windowlevelset=options.get("windowlevel",windowlevelvalue);
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (forcesigned && forceunsigned) {
+		cerr << EMsgDC(NotBothSignedOrUnsigned) << endl;
+		bad=true;
+	};
+
+	if ( (windowwidthset && !windowlevelset)
+	 || (!windowwidthset &&  windowlevelset)) {
+		cerr << EMsgDC(NeedBothWindowLevelWidth) << endl;
+		bad=true;
+	};
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-h|-help]"
+			<< " [-showwithhelp]"
+			<< " [-nodisplayloop]"
+			<< " [-noattributes]"
+			<< " [-windowwidth width]"
+			<< " [-windowlevel level]"
+			<< " [-ignorewindow]"
+			<< " [-invertedgray]"
+			<< " [-[signed|unsigned]]"
+			<< " [-showoverlays]"
+			<< " [-writeimage]"
+			<< " [" << MMsgDC(InputFile)
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	if (showwithhelp || justhelp) {
+		cerr << "Window level/width:" << endl;
+		cerr << endl;
+		cerr << "\t- for > 8 bit deep grayscale images only" << endl;
+		cerr << "\t- controlled by cursor movement while the left mouse button is down" << endl;
+		cerr << "\t- left or right decreases or increases width" << endl;
+		cerr << "\t- down or up decreases or increases level" << endl;
+		cerr << endl;
+		cerr << "\t- if shift key held, effect is multiplied 10 fold" << endl;
+		cerr << "\t- if control key held, effect is multiplied 100 fold" << endl;
+		cerr << "\t- if both shift & control keys held, effect is multiplied 1000 fold" << endl;
+		cerr << endl;
+		cerr << "\t- arrow keys (with or without shift and control) do the same" << endl;
+		cerr << endl;
+		cerr << "Cursor feedback:" << endl;
+		cerr << endl;
+		cerr << "\t- crosshair cursor when quiescent" << endl;
+		cerr << "\t- ramp  cursor while setting new values" << endl;
+		cerr << "\t- watch cursor while recomputing ... BE PATIENT" << endl;
+		cerr << endl;
+		cerr << "Key commands:" << endl;
+		cerr << endl;
+		cerr << "\t- o or O toggles overlays on or off." << endl;
+		cerr << endl;
+		cerr << "\t- v or V restores the VOI LUT or toggles to the next VOI LUT." << endl;
+		cerr << endl;
+		cerr << "\t- q or Q or x or X or return quits." << endl;
+		cerr << endl;
+		cerr << "Annotation:" << endl;
+		cerr << endl;
+		cerr << "\t- top left   - Patient ID" << endl;
+		cerr << "\t- top center - Study ID/Series Number/Image Number" << endl;
+		cerr << "\t- top right  - Patient Name" << endl;
+		cerr << endl;
+	}
+
+	if (justhelp) return 0;
+
+ECHOTHETIME("reading");
+
+	DicomInputStream din(*(istream *)input_opener);
+
+	ManagedAttributeList list;
+
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		//return 1;	// Press on regardless ...
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Float32 vRescaleIntercept = 0;
+	Attribute *aRescaleIntercept = list[TagFromName(RescaleIntercept)];
+	if (aRescaleIntercept)	// optional
+		vRescaleIntercept=AttributeValue(aRescaleIntercept);
+
+	Float32 vRescaleSlope = 0;
+	Attribute *aRescaleSlope = list[TagFromName(RescaleSlope)];
+	if (aRescaleSlope)	// optional
+		vRescaleSlope=AttributeValue(aRescaleSlope);
+
+	Uint16 vWindowCenter = 0;
+	Attribute *aWindowCenter = list[TagFromName(WindowCenter)];
+	if (aWindowCenter)	// optional
+		vWindowCenter=AttributeValue(aWindowCenter);
+
+	Uint16 vWindowWidth = 0;
+	Attribute *aWindowWidth = list[TagFromName(WindowWidth)];
+	if (aWindowWidth)	// optional
+		vWindowWidth=AttributeValue(aWindowWidth);
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+
+	if (!aPixelData) {
+		if (!noattributes)
+			log << "\tPixeldata not in normal place ... checking for ImageLocation attribute" << endl;
+		Uint16 groupstart;
+		Uint16 groupend;
+		Attribute *aImageLocation=list[TagFromName(ImageLocation)];
+		if (aImageLocation) {
+			Uint16 vImageLocation=AttributeValue(aImageLocation);
+			if (!noattributes)
+				log << "\tImageLocation = " << hex << vImageLocation << dec << endl;
+			groupstart=vImageLocation;
+			groupend=vImageLocation;
+		}
+		else {
+			groupstart=0x7fe0;
+			groupend=0x7ffd;
+		}
+		if (!noattributes)
+			log << "\tNow searching for Pixeldata" << endl;
+		Uint16 group;
+		for (group=groupstart; !aPixelData && group <= groupend; ++group) {
+			Uint32 owner;
+			for (owner=((group&0x0001) ? 0x0100 : 0x0000);
+					!aPixelData && owner <= ((group&0x0001) ? 0xff00 : 0x0000); owner+=0x0100) {
+				if ((aPixelData=list[Tag(group,Uint16(owner|0x0010))]) && aPixelData->isOtherData()) {
+					if (!noattributes)
+						log << "\tFound Pixeldata in ";
+						aPixelData->getTag().write(log);
+						log << endl;
+					break;
+				}
+				aPixelData=0;
+			}
+		}
+	}
+
+	if (!aPixelData) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelData\""
+		    << endl;
+		log << EMsgDC(NothingToDisplay) << endl;
+		return 1;
+	}
+
+	Uint32 length=aPixelData->getVL();
+
+	Attribute *aVOILUTSequence = list[TagFromName(VOILUTSequence)];
+	int nVOILUT=0;
+	Uint16 *VOILUT_first = 0;
+	Uint16 *VOILUT_number = 0;
+	Uint16 *VOILUT_depth = 0;
+	Uint16 **VOILUT_table = 0;
+	if (aVOILUTSequence) {
+cerr << "Have VOILUTSequence" << endl;
+		AttributeList **items;
+		nVOILUT=aVOILUTSequence->getLists(&items);
+		if (nVOILUT) {
+			VOILUT_first = new Uint16[nVOILUT];
+			Assert(VOILUT_first);
+			VOILUT_number = new Uint16[nVOILUT];
+			Assert(VOILUT_number);
+			VOILUT_depth = new Uint16[nVOILUT];
+			Assert(VOILUT_depth);
+			VOILUT_table = new Uint16 *[nVOILUT];
+			Assert(VOILUT_table);
+			int i;
+			for (i=0; i<nVOILUT; ++i) {
+				Assert(items[i]);
+				Attribute *aLUTDescriptor=items[i]->operator[](TagFromName(LUTDescriptor));
+				Assert(aLUTDescriptor);
+				Assert(aLUTDescriptor->getVM() == 3);
+				Assert(aLUTDescriptor->getValue(0,VOILUT_number[i]));
+				Assert(aLUTDescriptor->getValue(1,VOILUT_first[i]));
+				Assert(aLUTDescriptor->getValue(2,VOILUT_depth[i]));
+cerr << "VOILUTSequence" << endl
+     << "\t first[" << dec << i << "]=" << VOILUT_first[i] << endl
+     << "\t number[" << dec << i << "]=" << VOILUT_number[i] << endl
+     << "\t depth[" << dec << i << "]=" << VOILUT_depth[i] << endl;
+
+				Attribute *aLUTData=items[i]->operator[](TagFromName(LUTData));
+				Assert(aLUTData);
+				VOILUT_table[i]=new Uint16[VOILUT_number[i]];
+				Assert(VOILUT_table[i]);
+				int j;
+				for (j=0; j<VOILUT_number[i]; ++j) {
+					Assert(aLUTData->getValue(j,VOILUT_table[i][j]));
+				}
+			}
+		}
+	}
+
+	if (!noattributes) {
+		log << "Read ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (aWindowCenter) log << vWindowCenter; log << endl;
+		log << "\tWindowWidth = "; if (aWindowWidth) log << vWindowWidth; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tPixelData Value Length = " << hex << length << dec << endl;
+	}
+
+	// Try to guess some missing attributes ...
+
+	if (vRescaleSlope*vRescaleSlope < 0.00001) vRescaleSlope=1;
+
+	if (vPixelRepresentation == 0xffff) vPixelRepresentation=0;
+	if (forceunsigned) vPixelRepresentation=0;
+	if (forcesigned) vPixelRepresentation=1;
+
+	if (!vNumberOfFrames) vNumberOfFrames=1;
+
+	if (!vSamplesPerPixel && !vPhotometricInterpretation) {
+		vSamplesPerPixel=1;
+		vPhotometricInterpretation=StrDup("MONOCHROME2");
+	}
+	else if (!vSamplesPerPixel && vPhotometricInterpretation) {
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0
+		 || strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0
+		 || strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0
+		) {
+			vSamplesPerPixel=1;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"RGB") == 0
+		 || strcmp(vPhotometricInterpretation,"HSV") == 0
+		) {
+			vSamplesPerPixel=3;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"ARGB") == 0
+		 || strcmp(vPhotometricInterpretation,"CMYK") == 0
+		) {
+			vSamplesPerPixel=4;
+		}
+	}
+	else if (!vPhotometricInterpretation && vSamplesPerPixel) {
+		switch (vSamplesPerPixel) {
+			case 1:	// could check for presence of palette
+				vPhotometricInterpretation=StrDup("MONOCHROME2");
+				break;
+			case 3:	vPhotometricInterpretation=StrDup("RGB");
+				break;
+			case 4:	vPhotometricInterpretation=StrDup("ARGB");
+				break;
+		}
+	}
+
+	if (!vBitsAllocated && length && length != 0xffffffff
+	 && (vRows && vColumns && vNumberOfFrames && vSamplesPerPixel)) {
+		vBitsAllocated=Uint16(length/((Uint32)vRows*vColumns*vNumberOfFrames*vSamplesPerPixel)*8);
+	}
+
+	if (!vBitsAllocated && vBitsStored)
+		vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+
+	if (!vBitsAllocated) {
+		if (strcmp(aPixelData->getVR(),"OW") == 0)
+			vBitsAllocated=16;
+		else
+			vBitsAllocated=8;
+	}
+
+	Assert(vBitsAllocated <= 16);
+
+	if (!vBitsStored) vBitsStored=vBitsAllocated;
+	if (!vHighBit) vHighBit=vBitsStored-1;
+
+	Uint32 framelengthinwords=length/vNumberOfFrames*8/vBitsAllocated;
+
+	if (!vRows) {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vRows=Uint16(sqrt(framelengthinwords));
+				vColumns=Uint16(length/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				Uint32 left=framelengthinwords/vSamplesPerPixel;
+				vRows=Uint16(sqrt(left));
+				vColumns=Uint16(left/vRows);
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				Uint32 left=framelengthinwords/vColumns;
+				vRows=Uint16(sqrt(length));
+				vSamplesPerPixel=1;
+			}
+			else {
+				vRows=Uint16(framelengthinwords/(vColumns*vSamplesPerPixel));
+			}
+		}
+	}
+	else {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vColumns=Uint16(framelengthinwords/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				vColumns=Uint16(framelengthinwords/(vRows*vSamplesPerPixel));
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				vSamplesPerPixel=Uint16(framelengthinwords/(vRows*vColumns));
+			}
+			// else we know all three
+		}
+	}
+
+	// use object values if present and not zero, unless overridden by command line ...
+
+	if (!windowwidthset && !windowlevelset && !ignorewindowinobject && aWindowCenter && vWindowCenter && aWindowWidth && vWindowWidth) {
+		windowwidthset=true;
+		windowwidthvalue=vWindowWidth;
+		windowlevelset=true;
+		windowlevelvalue=vWindowCenter;
+	}
+
+	if (!noattributes) {
+		log << "Using ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (windowlevelset) log << windowlevelvalue; log << endl;
+		log << "\tWindowWidth = "; if (windowwidthset) log << windowwidthvalue; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tRows*Columns*SamplesPerPixel*BitsAllocated/8 = "
+		    << hex << (Uint32)vRows*vColumns*vSamplesPerPixel*vBitsAllocated/8
+		    << dec << endl;
+	}
+
+	Assert((Uint32)vRows*vColumns*vSamplesPerPixel <= framelengthinwords);
+
+	if (!vRows || !vColumns
+	 || !vPhotometricInterpretation || !vSamplesPerPixel
+	 || !vBitsAllocated
+	 || (vSamplesPerPixel > 1 && vPlanarConfiguration == 0xffff)) {
+		log << EMsgDC(MissingMandatoryAttributes) << endl;
+		return 1;
+	}
+
+ECHOTHETIME("attributes done ... setting up overlays");
+
+	OverlayBuffer overlays(list,log,noattributes);
+
+ECHOTHETIME("attributes done ... setting up pixel data");
+
+	ReadableImage *image = 0;
+	SupplySourceFromAttribute sPixelData(aPixelData);
+
+	// The standard doesn't say it, but what could a
+	// signed PixelRepresentation mean for other than grayscale ?
+
+	bool pixelrepresentationok = (vPixelRepresentation == 0);
+	bool windowlevelwidthok = !windowlevelset && !windowwidthset;
+
+	if (vSamplesPerPixel == 1) {
+		bool monochrome=false;
+		bool invertedgrayscale=false;
+		bool palettecolor=false;
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0) {
+			monochrome=true;
+			invertedgrayscale=true;
+		}
+		else if (strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0) {
+			monochrome=true;
+			invertedgrayscale=false;
+		}
+		else if (strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0) {
+			palettecolor=true;
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+
+		if (invertedgrayscaleoption) invertedgrayscale=!invertedgrayscale;
+
+		DicomLUT *RedLUT;
+		DicomLUT *GreenLUT;
+		DicomLUT *BlueLUT;
+
+		if (palettecolor && !extractLookUpTables(log,list,RedLUT,GreenLUT,BlueLUT))
+			return 1;
+
+		if (vBitsAllocated <= 8) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				image=new ReadableWindowed8BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale);
+			}
+			else if (palettecolor)
+				image=new Readable8BitIndexedColorImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+		}
+		else if (vBitsAllocated <= 16) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				windowlevelwidthok=true;	// allowed to specify width & level on command line
+				image=new ReadableWindowed16BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale);
+			}
+			else if (palettecolor)
+				image=new Readable16BitIndexedColorImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - BitsStored = " << vBitsStored << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 3) {
+		if (strcmp(vPhotometricInterpretation,"RGB") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else if (strcmp(vPhotometricInterpretation,"HSV") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved24BitHSVImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved24BitHSVImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 4) {
+		if (strcmp(vPhotometricInterpretation,"ARGB") == 0) {
+			DicomLUT *RedLUT;
+			DicomLUT *GreenLUT;
+			DicomLUT *BlueLUT;
+
+			if (!extractLookUpTables(log,list,RedLUT,GreenLUT,BlueLUT))
+				return 1;
+
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved32BitARGBImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved32BitARGBImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else if (strcmp(vPhotometricInterpretation,"CMYK") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved32BitCMYKImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved32BitCMYKImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else {
+		log << EMsgDC(Unsupported) << " - SamplesPerPixel = " << vSamplesPerPixel << endl;
+		return 1;
+	}
+
+	if (!pixelrepresentationok) {
+		log << WMsgDC(NonMonochromeSignedPixelRepresentation) << endl;
+	}
+	if (!windowlevelwidthok) {
+		log << WMsgDC(NoNeedForWindowLevelWidth) << endl;
+	}
+
+	char *vPatientName=AttributeValue(list[TagFromName(PatientName)]);
+	char *vPatientID=AttributeValue(list[TagFromName(PatientID)]);
+	char *vStudyID=AttributeValue(list[TagFromName(StudyID)]);
+	Uint16 vSeriesNumber=AttributeValue(list[TagFromName(SeriesNumber)]);
+	Uint16 vImageNumber=AttributeValue(list[TagFromName(ImageNumber)]);
+
+	ostrstream topleftostr;
+	topleftostr << (vPatientID ? vPatientID : "?") << ends;
+	char *topleftstring=topleftostr.str();
+
+	ostrstream toprightostr;
+	toprightostr << (vPatientName ? vPatientName : "?") << ends;
+	char *toprightstring=toprightostr.str();
+
+	ostrstream topcenterostr;
+	topcenterostr << (vStudyID ? vStudyID : "?") << "/" << vSeriesNumber << "/" << vImageNumber << ends;
+	char *topcenterstring=topcenterostr.str();
+
+ECHOTHETIME("opening and setting up display");
+
+	OurDisplay display;
+	if (!display.good()) {
+		log << display.errors() << endl;
+		return 1;
+	}
+
+	OurWindow window(&display,
+		vColumns,
+		vRows*vNumberOfFrames,
+		20,20);
+	if (!window.good()) {
+		log << window.errors() << endl;
+		return 1;
+	}
+
+	OurWindowImage wimage(&window);
+	log << wimage.errors() << endl;
+	if (!wimage.good()) {
+		return 1;
+	}
+
+	OurColorMap map(&display);
+	if (!map.good()) {
+		log << map.errors() << endl;
+		return 1;
+	}
+	else {
+		unsigned nwanted;
+		unsigned nminimum;
+		unsigned n;
+		unsigned long *cells;
+		unsigned short *red;
+		unsigned short *green;
+		unsigned short *blue;
+		if (!(image->getColorCellsWanted(nwanted,nminimum)
+		   && map.setColorCellsWanted(nwanted,nminimum)
+		   && map.getColorCellsAvailable(n,cells)
+		   && image->setColorCellsAvailable(n,cells)
+		   && image->getColorCellValues(n,red,green,blue)
+		   && map.setColorCellValues(n,red,green,blue)
+		)) {
+			log << map.errors();
+			log << "Color map establishment failed" << endl;
+			return 1;
+		}
+		window.setColormap(&map);
+	}
+
+	OurWindowLevelWidthUpdator wlwupdate(
+		window,vBitsAllocated,		// image->getBits() is BitsStored
+		image->getSigned(),		// May have been changed by statistics
+		vRescaleIntercept,vRescaleSlope);
+
+	bool usewlm = !nVOILUT && image->hasWindowLevelWidth();
+
+	int usewhichlut=0;
+
+	if (nVOILUT) {
+		image->setVOILUT(VOILUT_first[usewhichlut],VOILUT_number[usewhichlut],VOILUT_depth[usewhichlut],VOILUT_table[usewhichlut]);
+	}
+
+	if (usewlm && windowlevelset && windowwidthset) {
+		Uint16 width;
+		Uint16 level;
+			level=(Uint16)wlwupdate.getStoredLevelFromDisplayedLevel(windowlevelvalue);
+			width=(Uint16)wlwupdate.getStoredWidthFromDisplayedWidth(windowwidthvalue);
+			image->setWindowLevelWidth(level,width);
+	}
+
+	if (usewlm) {
+		Uint16 width;
+		Uint16 level;
+		image->getWindowLevelWidth(level,width);
+		wlwupdate.set(level,width);
+	}
+
+	char *pixels=wimage.get8BitDataAddress();
+	if (!pixels) {
+		log << EMsgDC(PixelDataTargetNotAvailable) << endl;
+		return 1;
+	}
+
+ECHOTHETIME("first put8BitIndexedPixels");
+
+	if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+			0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+		log << EMsgDC(PixelDataReadFailed) << endl;
+		//return 1;
+	}
+
+	window.useCursorCrossHair();
+	window.start();
+
+	PositionOfPixel positioner(list,log,false);
+
+ECHOTHETIME("about to enter event loop");
+
+	bool shifton=false;
+	bool controlon=false;
+	bool button1down=false;
+	while (1) {
+		XEvent report = display.nextEvent();
+		switch (report.type) {
+			case Expose:
+cerr << "report.xexpose.count == " << report.xexpose.count << endl;
+				if (report.xexpose.count != 0) break;
+				if (usewlm) wlwupdate.put();
+				window.writeHeaderText(topleftstring,topcenterstring,toprightstring);
+ECHOTHETIME("wimage.put() start");
+				wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+				if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+				if (nodisplayloop) goto done;
+				break;
+			case ButtonPress:
+				if (report.xbutton.button == Button1) {
+					button1down=true;
+					if (usewlm) {
+						wlwupdate.press(report.xbutton.x,report.xbutton.y);
+						window.useCursorLevelWidth();
+					}
+					else {
+						window.alarm();
+					}
+				}
+				break;
+			case ButtonRelease:
+				if (report.xbutton.button == Button1) {
+					button1down=false;
+					if (usewlm) {
+						window.useCursorWatch();
+						wlwupdate.release(report.xbutton.x,report.xbutton.y);
+						Uint16 width;
+						Uint16 level;
+						wlwupdate.get(level,width);
+						if (!image->setWindowLevelWidth(level,width)) {
+							log << map.errors();
+							log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+							return 1;
+						}
+ECHOTHETIME("put8BitIndexedPixels start");
+						if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+								0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+							log << EMsgDC(PixelDataReadFailed) << endl;
+							//return 1;
+						}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+						wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+						if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+						window.redraw();							
+#endif
+						window.useCursorCrossHair();
+					}
+				}
+				break;
+			case MotionNotify:
+				if (button1down) {
+					int multiplier=(report.xkey.state&ShiftMask ? 10 : 1)
+						      *(report.xkey.state&ControlMask ? 100 : 1);
+					if (usewlm)
+						wlwupdate.update(report.xmotion.x,report.xmotion.y,multiplier);
+				}
+				else {
+					unsigned short row;
+					unsigned short col;
+					window.reportPosition(
+						report.xmotion.x,report.xmotion.y,
+						row,col);
+					Float64 patientX,patientY,patientZ;
+					if (positioner.getPosition(row,col,patientX,patientY,patientZ)) {
+//cerr <<  "row=" << row
+//     << " col=" << col
+//     << " X=" << patientX
+//     << " Y=" << patientY
+//     << " Z=" << patientZ
+//     << endl;
+						window.clearFooter();
+						ostrstream rowcolostr;
+						rowcolostr <<  "R" << setw(4) << row
+							   << " C" << setw(4) << col
+							   << ends;
+						char *rowcolstr = rowcolostr.str();
+
+						ostrstream xyzostr;
+						xyzostr <<  setiosflags(ios::fixed|ios::showpoint)
+							<<  "X" <<  setprecision(1) << setw(6) << patientX
+							<< " Y" <<  setprecision(1) << setw(6) << patientY
+							<< " Z" <<  setprecision(1) << setw(6) << patientZ
+							<< ends;
+						char *xyzstr = xyzostr.str();
+
+						window.writeFooterText(rowcolstr,0,xyzstr);
+
+						if (rowcolstr) delete[] rowcolstr;
+						if (xyzstr) delete[] xyzstr;
+					}
+
+				}
+				break;
+			case KeyPress:
+				{
+					int deltax=0;
+					int deltay=0;
+					KeySym keysym;
+					(void)XLookupString(&report.xkey,0,0,&keysym,0);
+					switch (keysym) {
+						case XK_Shift_L:
+						case XK_Shift_R:
+						case XK_Shift_Lock:
+						case XK_Control_L:
+						case XK_Control_R:
+							break;		// handled by state, but must be allowed to press them
+						case XK_Left:
+						case XK_R10:		// the shifted state is a different keysym :(
+							deltax=-1;
+							break;
+						case XK_Right:
+						case XK_R12:		// the shifted state is a different keysym :(
+							deltax=1;
+							break;
+						case XK_Up:
+						case XK_R8:		// the shifted state is a different keysym :(
+							deltay=-1;
+							break;
+						case XK_Down:
+						case XK_R14:		// the shifted state is a different keysym :(
+							deltay=1;
+							break;
+						case XK_Escape:
+						case XK_Return:
+						case XK_q:
+						case XK_Q:
+						case XK_x:
+						case XK_X:
+							goto done;
+							// break;
+						case XK_o:
+						case XK_O:
+							showoverlays=!showoverlays;
+#ifdef DONTSENDEXPOSEEVENT
+							if (showoverlays) {
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+								overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+							}
+							else {
+ECHOTHETIME("wimage.put() start");
+								wimage.put();
+ECHOTHETIME("wimage.put() done");
+							}
+#else
+							window.redraw();							
+#endif
+							break;
+						case XK_v:
+						case XK_V:
+							if (nVOILUT) {
+								window.useCursorWatch();
+								if (++usewhichlut >= nVOILUT) usewhichlut=0;
+								image->setVOILUT(VOILUT_first[usewhichlut],VOILUT_number[usewhichlut],
+									VOILUT_depth[usewhichlut],VOILUT_table[usewhichlut]);
+								if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+									0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+									log << EMsgDC(PixelDataReadFailed) << endl;
+									//return 1;
+								}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+								wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+								if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+								window.redraw();							
+#endif
+								window.useCursorCrossHair();
+
+							}
+							else
+								window.alarm();
+							break;
+						default:
+							window.alarm();
+							break;
+					}
+					if (deltax || deltay) {
+						if (usewlm) {
+							int multiplier=(report.xkey.state&ShiftMask ? 10 : 1)
+								      *(report.xkey.state&ControlMask ? 100 : 1);
+							window.useCursorWatch();
+							wlwupdate.move(deltax,deltay,multiplier);
+							Uint16 width;
+							Uint16 level;
+							wlwupdate.get(level,width);
+							if (!image->setWindowLevelWidth(level,width)) {
+								log << map.errors();
+								log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+								return 1;
+							}
+							if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+									0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+								log << EMsgDC(PixelDataReadFailed) << endl;
+								//return 1;
+							}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+							wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+							if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+							window.redraw();							
+#endif
+							window.useCursorCrossHair();
+						}
+						else {
+							window.alarm();
+						}
+					}
+				}
+				break;
+			default:
+				break;
+		}
+	}
+
+	// not reached ...
+
+	// if (topleftstring) delete[] topleftstring;
+	// if (toprightstring) delete[] toprightstring;
+	// if (topcenterstring) delete[] topcenterstring;
+	// if (vPatientName) delete[] vPatientName;
+	// if (vPatientID) delete[] vPatientID;
+	// if (vStudyID) delete[] vStudyID;
+
+done:
+	if (writeimage && !wimage.write8BitDataToPGMStream(cout)) {
+		log << EMsgDC(PixelDataWriteFailed) << endl;
+		return 1;
+	}
+	else {
+		return 0;
+	}
+}
+
diff --git a/appsrc/dcdisp/dcdisp.cc_predynamic b/appsrc/dcdisp/dcdisp.cc_predynamic
new file mode 100755
index 0000000..5ab6d73
--- /dev/null
+++ b/appsrc/dcdisp/dcdisp.cc_predynamic
@@ -0,0 +1,1375 @@
+//#define PROFILETIME
+
+#include <math.h>
+
+#ifdef PROFILETIME
+#include <sys/types.h>
+#include <sys/time.h>
+static long g_starttime;
+static long g_lasttime;
+static long g_newtime;
+static struct timeval g_rtime;
+#define STARTTHETIME		((void)gettimeofday(&g_rtime,0),g_lasttime=g_starttime=g_rtime.tv_sec*1000+g_rtime.tv_usec/1000)
+#define ECHOTHETIME(s)		((void)gettimeofday(&g_rtime,0), \
+				  g_newtime=g_rtime.tv_sec*1000+g_rtime.tv_usec/1000, \
+				  cerr << "***TIME***: " << s << ": " << dec << g_newtime-g_starttime \
+				       << "(" << g_newtime-g_lasttime << ") mS"<< endl, \
+				  g_lasttime=g_newtime)
+#else
+#define STARTTHETIME
+#define ECHOTHETIME(s)
+#endif
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+#include "errclass.h"
+
+#include "attrothr.h"
+
+#include "ourdisp.h"
+
+#include "lutclass.h"
+#include "lutextr.h"
+
+#include "usepal.h"
+#include "usegray.h"
+#include "useindex.h"
+#include "usetrue.h"
+
+#include "rdimage.h"
+#include "rdgray.h"
+#include "rdindex.h"
+#include "rdrgb.h"
+#include "rdhsv.h"
+#include "rdargb.h"
+#include "rdcmyk.h"
+
+#include "pixposn.h"
+
+class OverlayBuffer {
+private:
+	bool		present[16];
+	bool		activated[16];
+
+	Uint16		vOverlayRows[16];
+	Uint16		vOverlayColumns[16];
+	const char *	vOverlayType[16];
+	Uint16		vOverlayBitsAllocated[16]; 
+	Uint16		vOverlayBitPosition[16];
+	Uint16		vOverlayLocation[16];			// old ACR-NEMA, defaults to 0x7FEO if no pixel data
+	Int16		vOverlayOriginRow[16];
+	Int16 		vOverlayOriginColumn[16];
+
+	Attribute *	aOverlayData[16];
+
+	Uint32		vOverlayDataLength[16];
+	const Uint16 *	vOverlayDataValues[16];
+
+	void dump(TextOutputStream& log,const char *msg);
+
+public:
+	OverlayBuffer(ManagedAttributeList& list,TextOutputStream& log,bool noattributes);
+
+	bool getOverlayValues(Uint16 which,const Uint16 * &data, Uint32 &length, Uint16 &bitsallocated, Uint16 &bitposition) const
+		{
+			Assert(which<16);
+			if (activated[which]) {
+				bitsallocated=vOverlayBitsAllocated[which];
+				bitposition=vOverlayBitPosition[which];
+				Assert(aOverlayData[which]);
+				return aOverlayData[which]->getValue(data,length);
+			}
+			else {
+				return false;
+			}
+		}
+
+	void putOverlay(OurWindowImage &wimage,unsigned which);
+	void putOverlay(OurWindowImage &wimage);
+};
+
+OverlayBuffer::OverlayBuffer(ManagedAttributeList& list,TextOutputStream& log,bool noattributes)
+{
+	unsigned u;
+	for (u=0; u<=0x1E; u+=2) {
+
+		activated[u/2] = false;
+
+		Attribute *aOverlayRows = list[Tag(OverlayRows_GROUP+u,OverlayRows_ELEMENT)];
+		Attribute *aOverlayColumns = list[Tag(OverlayColumns_GROUP+u,OverlayColumns_ELEMENT)];
+		Attribute *aOverlayType = list[Tag(OverlayType_GROUP+u,OverlayType_ELEMENT)];
+		Attribute *aOverlayBitsAllocated = list[Tag(OverlayBitsAllocated_GROUP+u,OverlayBitsAllocated_ELEMENT)];
+		Attribute *aOverlayBitPosition = list[Tag(OverlayBitPosition_GROUP+u,OverlayBitPosition_ELEMENT)];
+		Attribute *aOverlayLocation = list[Tag(OverlayLocation_GROUP+u,OverlayLocation_ELEMENT)];
+		Attribute *aOverlayOrigin = list[Tag(OverlayOrigin_GROUP+u,OverlayOrigin_ELEMENT)];
+		aOverlayData[u/2] = list[Tag(OverlayData_GROUP+u,OverlayData_ELEMENT)];
+
+		present[u/2] = (aOverlayRows || aOverlayColumns || aOverlayType
+			       || aOverlayBitsAllocated || aOverlayBitPosition
+			       || aOverlayLocation || aOverlayOrigin || aOverlayData[u/2]);
+
+		vOverlayRows[u/2] = Uint16(AttributeValue(list[TagFromName(Rows)]));	// default
+		if (!aOverlayRows) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayRows\" for group " << hex << u << dec
+				    << " - using \"Rows\" = " << vOverlayRows[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayRows[u/2]=AttributeValue(aOverlayRows);
+
+		vOverlayColumns[u/2] = Uint16(AttributeValue(list[TagFromName(Columns)]));	// default
+		if (!aOverlayColumns) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayColumns\" for group " << hex << u << dec
+				    << " - using \"Columns\" = " << vOverlayColumns[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayColumns[u/2]=AttributeValue(aOverlayColumns);
+
+		vOverlayType[u/2] = "G";
+		if (!aOverlayType) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayType\" for group " << hex << u << dec
+				    << " - using \"G\""
+				    << endl;
+			}
+		}
+		else {
+			const char *v=AttributeValue(aOverlayType);
+			if (v && strcmp(v,"G") == 0)
+				vOverlayType[u/2]="G";
+			else if (v && strcmp(v,"R") == 0)
+				vOverlayType[u/2]="R";
+			else
+				log << EMsgDC(BadAttributeValue)
+				    << " - \"OverlayType\" for group " << hex << u << dec
+				    << " = <" << (v ? v : "") << ">"
+				    << " - using \"G\""
+				    << endl;
+		}
+
+		vOverlayBitsAllocated[u/2] = Uint16(AttributeValue(list[TagFromName(BitsAllocated)]));	// default
+		if (!aOverlayBitsAllocated) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayBitsAllocated\" for group " << hex << u << dec
+				    << " - using \"BitsAllocated\" = " << vOverlayBitsAllocated[u/2]
+				    << endl;
+			}
+		}
+		else
+			vOverlayBitsAllocated[u/2]=AttributeValue(aOverlayBitsAllocated);
+
+		vOverlayBitPosition[u/2] = 0;	// default
+		if (!aOverlayBitPosition) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayBitPosition\" for group " << hex << u << dec
+				    << " - using 0"
+				    << endl;
+			}
+		}
+		else
+			vOverlayBitPosition[u/2]=AttributeValue(aOverlayBitPosition);
+
+		vOverlayOriginRow[u/2] = 1;	// default
+		vOverlayOriginColumn[u/2] = 1;	// default
+		if (!aOverlayOrigin) {
+			if (present[u/2]) {
+				log << WMsgDC(MissingAttribute)
+				    << " - \"OverlayOrigin\" for group " << hex << u << dec
+				    << " - using 1\\1"
+				    << endl;
+			}
+		}
+		else if (aOverlayOrigin->getVM() != 2)
+			log << EMsgDC(BadAttributeValueMultiplicity)
+			    << " - \"OverlayOrigin\" for group " << hex << u << dec
+			    << " != 2 "
+			    << " - using 1\\1"
+			    << endl;
+		else {
+			bool success;
+			success=aOverlayOrigin->getValue(0,vOverlayOriginRow[u/2]);
+			Assert(success);
+			success=aOverlayOrigin->getValue(1,vOverlayOriginColumn[u/2]);
+			Assert(success);
+		}
+
+		vOverlayLocation[u/2] = 0;	// missing flag (not required in DICOM 3.0)
+		if (aOverlayLocation)
+			vOverlayLocation[u/2]=AttributeValue(aOverlayLocation);
+
+		if (present[u/2] && aOverlayData[u/2]) {
+			Assert(aOverlayData[u/2]->getValue(vOverlayDataValues[u/2],vOverlayDataLength[u/2]));
+			Assert(vOverlayDataLength[u/2]);
+			Assert(vOverlayDataValues[u/2]);
+		}
+
+		if (present[u/2] && !vOverlayLocation[u/2] && !aOverlayData[u/2])
+			vOverlayLocation[u/2]=0x7FE0;
+
+		// Only Overlay Data supported for now :(
+
+		if (present[u/2] && aOverlayData[u/2]) {
+			activated[u/2]=true;
+
+			Assert(vOverlayOriginRow[u/2] == 1);
+			Assert(vOverlayOriginColumn[u/2] == 1);
+			Assert(vOverlayRows[u/2]== Uint16(AttributeValue(list[TagFromName(Rows)])));
+			Assert(vOverlayColumns[u/2] == Uint16(AttributeValue(list[TagFromName(Columns)])));
+			Assert(vOverlayDataLength[u/2] == vOverlayRows[u/2]*vOverlayColumns[u/2]*vOverlayBitsAllocated[u/2]/16);
+		}
+
+	}
+
+	if (!noattributes) dump(log,"Using");
+}
+
+void
+OverlayBuffer::dump(TextOutputStream& log,const char *msg)
+{
+	Assert(msg);
+	unsigned u;
+	for (u=0; u<=0x1E; u+=2) {
+		if (present[u/2]) {
+			log << msg << " Overlay Group " << hex << u << dec << " ..." << endl;
+			log << "\tpresent = " << (present[u/2] ? "yes" : "no") << endl;
+			log << "\tactivated = " << (activated[u/2] ? "yes" : "no") << endl;
+			log << "\tRows = " << dec << vOverlayRows[u/2] << endl;
+			log << "\tColumns = " << dec << vOverlayColumns[u/2] << endl;
+			log << "\tType = " << dec << vOverlayType[u/2] << endl;
+			log << "\tBitsAllocated = " << dec << vOverlayBitsAllocated[u/2] << endl;
+			log << "\tBitPosition = " << dec << vOverlayBitPosition[u/2] << endl;
+			log << "\tOrigin (Row) = " << dec << vOverlayOriginRow[u/2] << endl;
+			log << "\tOrigin (Column) = " << dec << vOverlayOriginColumn[u/2] << endl;
+			log << "\tLocation = " << hex << vOverlayLocation[u/2] << dec << endl;
+			log << "\tData " << (aOverlayData[u/2] ? "is" : "is not") << " present" << endl;
+			if (aOverlayData[u/2])
+				log << "\tData Length = " << dec << vOverlayDataLength[u/2] << endl;
+			if (aOverlayData[u/2] && vOverlayDataValues[u/2] && vOverlayDataLength[u/2])
+				log << "\tData Value[0] = " << hex << vOverlayDataValues[u/2][0] << dec << endl;
+		}
+	}
+}
+
+void
+OverlayBuffer::putOverlay(OurWindowImage &wimage,unsigned which)
+{
+cerr << "OverlayBuffer::putOverlay(" << which << "):" << endl;
+	Assert(which < 16);
+	if (activated[which]) {
+cerr << "OverlayBuffer::putOverlay(" << which << "): activated" << endl;
+		Assert(vOverlayBitsAllocated[which] <= 16);
+		Assert(16%vOverlayBitsAllocated[which] == 0);
+		Assert(vOverlayBitPosition[which] < vOverlayBitsAllocated[which]);
+
+		unsigned bitincrement = vOverlayBitsAllocated[which];
+		unsigned bitmask = 1 << vOverlayBitPosition[which];
+		unsigned bitgroupsperword = 16 / bitincrement;
+
+		const Uint16 *ptr = vOverlayDataValues[which];
+		const Uint16 *last = ptr + vOverlayDataLength[which];
+
+		unsigned rows = vOverlayRows[which];
+		unsigned cols = vOverlayColumns[which];
+		unsigned row = 0;
+		unsigned col = 0;
+
+		while (ptr < last) {
+			Uint16 word=*ptr++;
+			Assert (row < rows);
+			// optimize here for word == 0 later
+			unsigned bit = 0;
+			while (bit < 16) {
+				bit+=bitincrement;
+				if (word & bitmask) wimage.putPoint(col,row);
+				word=word>>bitincrement;
+				if (++col >= cols) {
+					col=0;
+					++row;
+				}
+			}
+		}
+	}
+}
+
+void
+OverlayBuffer::putOverlay(OurWindowImage &wimage)
+{
+	unsigned which;
+	for (which=0; which<16; ++which) {
+		if (activated[which]) putOverlay(wimage,which);
+	}
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+STARTTHETIME;
+ECHOTHETIME("start");
+
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool nodisplayloop=options.get("nodisplayloop");
+	bool noattributes=options.get("noattributes");
+	bool showwithhelp=options.get("showwithhelp");
+	bool justhelp=options.get("help") || options.get("h");
+	bool invertedgrayscaleoption=options.get("invertedgray");
+	bool forcesigned=options.get("signed");
+	bool forceunsigned=options.get("unsigned");
+	bool ignorewindowinobject=options.get("ignorewindow");
+	bool writeimage=options.get("writeimage");
+	bool showoverlays=options.get("showoverlays");
+	bool ignorepadvalue=options.get("ignorepadvalue");;
+
+	unsigned windowwidthvalue=0;
+	bool windowwidthset=options.get("windowwidth",windowwidthvalue);
+	unsigned windowlevelvalue=0;
+	bool windowlevelset=options.get("windowlevel",windowlevelvalue);
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (forcesigned && forceunsigned) {
+		cerr << EMsgDC(NotBothSignedOrUnsigned) << endl;
+		bad=true;
+	};
+
+	if ( (windowwidthset && !windowlevelset)
+	 || (!windowwidthset &&  windowlevelset)) {
+		cerr << EMsgDC(NeedBothWindowLevelWidth) << endl;
+		bad=true;
+	};
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-h|-help]"
+			<< " [-showwithhelp]"
+			<< " [-nodisplayloop]"
+			<< " [-noattributes]"
+			<< " [-windowwidth width]"
+			<< " [-windowlevel level]"
+			<< " [-ignorewindow]"
+			<< " [-invertedgray]"
+			<< " [-[signed|unsigned]]"
+			<< " [-ignorepadvalue]"
+			<< " [-showoverlays]"
+			<< " [-writeimage]"
+			<< " [" << MMsgDC(InputFile)
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	if (showwithhelp || justhelp) {
+		cerr << "Window level/width:" << endl;
+		cerr << endl;
+		cerr << "\t- for > 8 bit deep grayscale images only" << endl;
+		cerr << "\t- controlled by cursor movement while the left mouse button is down" << endl;
+		cerr << "\t- left or right decreases or increases width" << endl;
+		cerr << "\t- down or up decreases or increases level" << endl;
+		cerr << endl;
+		cerr << "\t- if shift key held, effect is multiplied 10 fold" << endl;
+		cerr << "\t- if control key held, effect is multiplied 100 fold" << endl;
+		cerr << "\t- if both shift & control keys held, effect is multiplied 1000 fold" << endl;
+		cerr << endl;
+		cerr << "\t- arrow keys (with or without shift and control) do the same" << endl;
+		cerr << endl;
+		cerr << "Cursor feedback:" << endl;
+		cerr << endl;
+		cerr << "\t- crosshair cursor when quiescent" << endl;
+		cerr << "\t- ramp  cursor while setting new values" << endl;
+		cerr << "\t- watch cursor while recomputing ... BE PATIENT" << endl;
+		cerr << endl;
+		cerr << "Key commands:" << endl;
+		cerr << endl;
+		cerr << "\t- o or O toggles overlays on or off." << endl;
+		cerr << endl;
+		cerr << "\t- v or V restores the VOI LUT or toggles to the next VOI LUT." << endl;
+		cerr << endl;
+		cerr << "\t- q or Q or x or X or return quits." << endl;
+		cerr << endl;
+		cerr << "Annotation:" << endl;
+		cerr << endl;
+		cerr << "\t- top left   - Patient ID" << endl;
+		cerr << "\t- top center - Study ID/Series Number/Image Number" << endl;
+		cerr << "\t- top right  - Patient Name" << endl;
+		cerr << endl;
+	}
+
+	if (justhelp) return 0;
+
+ECHOTHETIME("reading");
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		//return 1;	// Press on regardless ...
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Float32 vRescaleIntercept = 0;
+	Attribute *aRescaleIntercept = list[TagFromName(RescaleIntercept)];
+	if (aRescaleIntercept)	// optional
+		vRescaleIntercept=AttributeValue(aRescaleIntercept);
+
+	Float32 vRescaleSlope = 0;
+	Attribute *aRescaleSlope = list[TagFromName(RescaleSlope)];
+	if (aRescaleSlope)	// optional
+		vRescaleSlope=AttributeValue(aRescaleSlope);
+
+	Uint16 vWindowCenter = 0;
+	Attribute *aWindowCenter = list[TagFromName(WindowCenter)];
+	if (aWindowCenter)	// optional
+		vWindowCenter=AttributeValue(aWindowCenter);
+
+	Uint16 vWindowWidth = 0;
+	Attribute *aWindowWidth = list[TagFromName(WindowWidth)];
+	if (aWindowWidth)	// optional
+		vWindowWidth=AttributeValue(aWindowWidth);
+
+	Uint16 vPixelPaddingValue;
+	Attribute *aPixelPaddingValue = list[TagFromName(PixelPaddingValue)];
+	if (aPixelPaddingValue)	{	// optional
+		vPixelPaddingValue=AttributeValue(aPixelPaddingValue);
+	}
+	bool usepadvalue=aPixelPaddingValue && !ignorepadvalue;
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+
+	if (!aPixelData) {
+		if (!noattributes)
+			log << "\tPixeldata not in normal place ... checking for ImageLocation attribute" << endl;
+		Uint16 groupstart;
+		Uint16 groupend;
+		Attribute *aImageLocation=list[TagFromName(ImageLocation)];
+		if (aImageLocation) {
+			Uint16 vImageLocation=AttributeValue(aImageLocation);
+			if (!noattributes)
+				log << "\tImageLocation = " << hex << vImageLocation << dec << endl;
+			groupstart=vImageLocation;
+			groupend=vImageLocation;
+		}
+		else {
+			groupstart=0x7fe0;
+			groupend=0x7ffd;
+		}
+		if (!noattributes)
+			log << "\tNow searching for Pixeldata" << endl;
+		Uint16 group;
+		for (group=groupstart; !aPixelData && group <= groupend; ++group) {
+			Uint32 owner;
+			for (owner=((group&0x0001) ? 0x0100 : 0x0000);
+					!aPixelData && owner <= ((group&0x0001) ? 0xff00 : 0x0000); owner+=0x0100) {
+				if ((aPixelData=list[Tag(group,Uint16(owner|0x0010))]) && aPixelData->isOtherData()) {
+					if (!noattributes)
+						log << "\tFound Pixeldata in ";
+						aPixelData->getTag().write(log);
+						log << endl;
+					break;
+				}
+				aPixelData=0;
+			}
+		}
+	}
+
+	if (!aPixelData) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelData\""
+		    << endl;
+		log << EMsgDC(NothingToDisplay) << endl;
+		return 1;
+	}
+
+	Uint32 length=aPixelData->getVL();
+
+	Attribute *aVOILUTSequence = list[TagFromName(VOILUTSequence)];
+	int nVOILUT=0;
+	Uint16 *VOILUT_first = 0;
+	Uint16 *VOILUT_number = 0;
+	Uint16 *VOILUT_depth = 0;
+	Uint16 **VOILUT_table = 0;
+	if (aVOILUTSequence) {
+cerr << "Have VOILUTSequence" << endl;
+		AttributeList **items;
+		nVOILUT=aVOILUTSequence->getLists(&items);
+		if (nVOILUT) {
+			VOILUT_first = new Uint16[nVOILUT];
+			Assert(VOILUT_first);
+			VOILUT_number = new Uint16[nVOILUT];
+			Assert(VOILUT_number);
+			VOILUT_depth = new Uint16[nVOILUT];
+			Assert(VOILUT_depth);
+			VOILUT_table = new Uint16 *[nVOILUT];
+			Assert(VOILUT_table);
+			int i;
+			for (i=0; i<nVOILUT; ++i) {
+				Assert(items[i]);
+				Attribute *aLUTDescriptor=items[i]->operator[](TagFromName(LUTDescriptor));
+				Assert(aLUTDescriptor);
+				Assert(aLUTDescriptor->getVM() == 3);
+				Assert(aLUTDescriptor->getValue(0,VOILUT_number[i]));
+				Assert(aLUTDescriptor->getValue(1,VOILUT_first[i]));
+				Assert(aLUTDescriptor->getValue(2,VOILUT_depth[i]));
+cerr << "VOILUTSequence" << endl
+     << "\t first[" << dec << i << "]=" << VOILUT_first[i] << endl
+     << "\t number[" << dec << i << "]=" << VOILUT_number[i] << endl
+     << "\t depth[" << dec << i << "]=" << VOILUT_depth[i] << endl;
+
+				Attribute *aLUTData=items[i]->operator[](TagFromName(LUTData));
+				Assert(aLUTData);
+				VOILUT_table[i]=new Uint16[VOILUT_number[i]];
+				Assert(VOILUT_table[i]);
+				int j;
+				for (j=0; j<VOILUT_number[i]; ++j) {
+					Assert(aLUTData->getValue(j,VOILUT_table[i][j]));
+				}
+			}
+		}
+	}
+
+	if (!noattributes) {
+		log << "Read ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (aWindowCenter) log << vWindowCenter; log << endl;
+		log << "\tWindowWidth = "; if (aWindowWidth) log << vWindowWidth; log << endl;
+		log << "\tPixelPaddingValue = "; if (aPixelPaddingValue) log << vPixelPaddingValue; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tPixelData Value Length = " << hex << length << dec << endl;
+	}
+
+
+	// Try to guess some missing attributes ...
+
+	if (vRescaleSlope*vRescaleSlope < 0.00001) vRescaleSlope=1;
+
+	if (vPixelRepresentation == 0xffff) vPixelRepresentation=0;
+	if (forceunsigned) vPixelRepresentation=0;
+	if (forcesigned) vPixelRepresentation=1;
+
+	if (!vNumberOfFrames) vNumberOfFrames=1;
+
+	if (!vSamplesPerPixel && !vPhotometricInterpretation) {
+		vSamplesPerPixel=1;
+		vPhotometricInterpretation=StrDup("MONOCHROME2");
+	}
+	else if (!vSamplesPerPixel && vPhotometricInterpretation) {
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0
+		 || strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0
+		 || strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0
+		) {
+			vSamplesPerPixel=1;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"RGB") == 0
+		 || strcmp(vPhotometricInterpretation,"HSV") == 0
+		) {
+			vSamplesPerPixel=3;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"ARGB") == 0
+		 || strcmp(vPhotometricInterpretation,"CMYK") == 0
+		) {
+			vSamplesPerPixel=4;
+		}
+	}
+	else if (!vPhotometricInterpretation && vSamplesPerPixel) {
+		switch (vSamplesPerPixel) {
+			case 1:	// could check for presence of palette
+				vPhotometricInterpretation=StrDup("MONOCHROME2");
+				break;
+			case 3:	vPhotometricInterpretation=StrDup("RGB");
+				break;
+			case 4:	vPhotometricInterpretation=StrDup("ARGB");
+				break;
+		}
+	}
+
+	if (!vBitsAllocated && length && length != 0xffffffff
+	 && (vRows && vColumns && vNumberOfFrames && vSamplesPerPixel)) {
+		vBitsAllocated=Uint16(length/((Uint32)vRows*vColumns*vNumberOfFrames*vSamplesPerPixel)*8);
+	}
+
+	if (!vBitsAllocated && vBitsStored)
+		vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+
+	if (!vBitsAllocated) {
+		if (strcmp(aPixelData->getVR(),"OW") == 0)
+			vBitsAllocated=16;
+		else
+			vBitsAllocated=8;
+	}
+
+	Assert(vBitsAllocated <= 16);
+
+	if (!vBitsStored) vBitsStored=vBitsAllocated;
+	if (!vHighBit) vHighBit=vBitsStored-1;
+
+	Uint32 framelengthinwords=length/vNumberOfFrames*8/vBitsAllocated;
+
+	if (!vRows) {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vRows=Uint16(sqrt(framelengthinwords));
+				vColumns=Uint16(length/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				Uint32 left=framelengthinwords/vSamplesPerPixel;
+				vRows=Uint16(sqrt(left));
+				vColumns=Uint16(left/vRows);
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				Uint32 left=framelengthinwords/vColumns;
+				vRows=Uint16(sqrt(length));
+				vSamplesPerPixel=1;
+			}
+			else {
+				vRows=Uint16(framelengthinwords/(vColumns*vSamplesPerPixel));
+			}
+		}
+	}
+	else {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vColumns=Uint16(framelengthinwords/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				vColumns=Uint16(framelengthinwords/(vRows*vSamplesPerPixel));
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				vSamplesPerPixel=Uint16(framelengthinwords/(vRows*vColumns));
+			}
+			// else we know all three
+		}
+	}
+
+	// use object values if present and not zero, unless overridden by command line ...
+
+	if (!windowwidthset && !windowlevelset && !ignorewindowinobject && aWindowCenter && vWindowCenter && aWindowWidth && vWindowWidth) {
+		windowwidthset=true;
+		windowwidthvalue=vWindowWidth;
+		windowlevelset=true;
+		windowlevelvalue=vWindowCenter;
+	}
+
+	if (!noattributes) {
+		log << "Using ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (windowlevelset) log << windowlevelvalue; log << endl;
+		log << "\tWindowWidth = "; if (windowwidthset) log << windowwidthvalue; log << endl;
+		log << "\tPixelPaddingValue = "; if (usepadvalue) log << vPixelPaddingValue; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tRows*Columns*SamplesPerPixel*BitsAllocated/8 = "
+		    << hex << (Uint32)vRows*vColumns*vSamplesPerPixel*vBitsAllocated/8
+		    << dec << endl;
+	}
+
+	Assert((Uint32)vRows*vColumns*vSamplesPerPixel <= framelengthinwords);
+
+	if (!vRows || !vColumns
+	 || !vPhotometricInterpretation || !vSamplesPerPixel
+	 || !vBitsAllocated
+	 || (vSamplesPerPixel > 1 && vPlanarConfiguration == 0xffff)) {
+		log << EMsgDC(MissingMandatoryAttributes) << endl;
+		return 1;
+	}
+
+ECHOTHETIME("attributes done ... setting up overlays");
+
+	OverlayBuffer overlays(list,log,noattributes);
+
+ECHOTHETIME("attributes done ... setting up pixel data");
+
+	ReadableImage *image = 0;
+	SupplySourceFromAttribute sPixelData(aPixelData);
+
+	// The standard doesn't say it, but what could a
+	// signed PixelRepresentation mean for other than grayscale ?
+
+	bool pixelrepresentationok = (vPixelRepresentation == 0);
+	bool windowlevelwidthok = !windowlevelset && !windowwidthset;
+
+	if (vSamplesPerPixel == 1) {
+		bool monochrome=false;
+		bool invertedgrayscale=false;
+		bool palettecolor=false;
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0) {
+			monochrome=true;
+			invertedgrayscale=true;
+		}
+		else if (strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0) {
+			monochrome=true;
+			invertedgrayscale=false;
+		}
+		else if (strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0) {
+			palettecolor=true;
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+
+		if (invertedgrayscaleoption) invertedgrayscale=!invertedgrayscale;
+
+		DicomLUT *RedLUT;
+		DicomLUT *GreenLUT;
+		DicomLUT *BlueLUT;
+
+		if (palettecolor && !extractLookUpTables(log,list,RedLUT,GreenLUT,BlueLUT))
+			return 1;
+
+		if (vBitsAllocated <= 8) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				image=new ReadableWindowed8BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale);
+			}
+			else if (palettecolor)
+				image=new Readable8BitIndexedColorImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+		}
+		else if (vBitsAllocated <= 16) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				windowlevelwidthok=true;	// allowed to specify width & level on command line
+				image=new ReadableWindowed16BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale,
+						usepadvalue,vPixelPaddingValue);
+			}
+			else if (palettecolor)
+				image=new Readable16BitIndexedColorImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - BitsStored = " << vBitsStored << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 3) {
+		if (strcmp(vPhotometricInterpretation,"RGB") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else if (strcmp(vPhotometricInterpretation,"HSV") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved24BitHSVImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved24BitHSVImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 4) {
+		if (strcmp(vPhotometricInterpretation,"ARGB") == 0) {
+			DicomLUT *RedLUT;
+			DicomLUT *GreenLUT;
+			DicomLUT *BlueLUT;
+
+			if (!extractLookUpTables(log,list,RedLUT,GreenLUT,BlueLUT))
+				return 1;
+
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved32BitARGBImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved32BitARGBImage(
+						&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						RedLUT,GreenLUT,BlueLUT);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else if (strcmp(vPhotometricInterpretation,"CMYK") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new ReadableInterleaved32BitCMYKImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else if (vPlanarConfiguration == 1)
+				image=new ReadableNonInterleaved32BitCMYKImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else {
+		log << EMsgDC(Unsupported) << " - SamplesPerPixel = " << vSamplesPerPixel << endl;
+		return 1;
+	}
+
+	if (!pixelrepresentationok) {
+		log << WMsgDC(NonMonochromeSignedPixelRepresentation) << endl;
+	}
+	if (!windowlevelwidthok) {
+		log << WMsgDC(NoNeedForWindowLevelWidth) << endl;
+	}
+
+	char *vPatientName=AttributeValue(list[TagFromName(PatientName)]);
+	char *vPatientID=AttributeValue(list[TagFromName(PatientID)]);
+	char *vStudyID=AttributeValue(list[TagFromName(StudyID)]);
+	Uint16 vSeriesNumber=AttributeValue(list[TagFromName(SeriesNumber)]);
+	Uint16 vInstanceNumber=AttributeValue(list[TagFromName(InstanceNumber)]);
+
+	ostrstream topleftostr;
+	topleftostr << (vPatientID ? vPatientID : "?") << ends;
+	char *topleftstring=topleftostr.str();
+
+	ostrstream toprightostr;
+	toprightostr << (vPatientName ? vPatientName : "?") << ends;
+	char *toprightstring=toprightostr.str();
+
+	ostrstream topcenterostr;
+	topcenterostr << (vStudyID ? vStudyID : "?") << "/" << vSeriesNumber << "/" << vInstanceNumber << ends;
+	char *topcenterstring=topcenterostr.str();
+
+ECHOTHETIME("opening and setting up display");
+
+	OurDisplay display;
+	if (!display.good()) {
+		log << display.errors() << endl;
+		return 1;
+	}
+
+	OurWindow window(&display,
+		vColumns,
+		vRows*vNumberOfFrames,
+		20,20);
+	if (!window.good()) {
+		log << window.errors() << endl;
+		return 1;
+	}
+
+	OurWindowImage wimage(&window);
+	log << wimage.errors() << endl;
+	if (!wimage.good()) {
+		return 1;
+	}
+
+	OurColorMap map(&display);
+	if (!map.good()) {
+		log << map.errors() << endl;
+		return 1;
+	}
+	else {
+		unsigned nwanted;
+		unsigned nminimum;
+		unsigned n;
+		unsigned long *cells;
+		unsigned short *red;
+		unsigned short *green;
+		unsigned short *blue;
+		if (!(image->getColorCellsWanted(nwanted,nminimum)
+		   && map.setColorCellsWanted(nwanted,nminimum)
+		   && map.getColorCellsAvailable(n,cells)
+		   && image->setColorCellsAvailable(n,cells)
+		   && image->getColorCellValues(n,red,green,blue)
+		   && map.setColorCellValues(n,red,green,blue)
+		)) {
+			log << map.errors();
+			log << "Color map establishment failed" << endl;
+			return 1;
+		}
+		window.setColormap(&map);
+	}
+
+	OurWindowLevelWidthUpdator wlwupdate(
+		window,image->getBits(),	// Probably still same as BitsStored
+		image->getSigned(),		// May have been changed by statistics
+		vRescaleIntercept,vRescaleSlope);
+
+	bool usewlm = !nVOILUT && image->hasWindowLevelWidth();
+
+	int usewhichlut=0;
+
+	if (nVOILUT) {
+		image->setVOILUT(VOILUT_first[usewhichlut],VOILUT_number[usewhichlut],VOILUT_depth[usewhichlut],VOILUT_table[usewhichlut]);
+	}
+
+	if (usewlm && windowlevelset && windowwidthset) {
+		Uint16 width;
+		Uint16 level;
+			level=(Uint16)wlwupdate.getStoredLevelFromDisplayedLevel(windowlevelvalue);
+			width=(Uint16)wlwupdate.getStoredWidthFromDisplayedWidth(windowwidthvalue);
+			image->setWindowLevelWidth(level,width);
+	}
+
+	if (usewlm) {
+		Uint16 width;
+		Uint16 level;
+		image->getWindowLevelWidth(level,width);
+		wlwupdate.set(level,width);
+	}
+
+	char *pixels=wimage.get8BitDataAddress();
+	if (!pixels) {
+		log << EMsgDC(PixelDataTargetNotAvailable) << endl;
+		return 1;
+	}
+
+ECHOTHETIME("first put8BitIndexedPixels");
+
+	if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+			0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+		log << EMsgDC(PixelDataReadFailed) << endl;
+		//return 1;
+	}
+
+	window.useCursorCrossHair();
+	window.start();
+
+	PositionOfPixel positioner(list,log,false);
+
+ECHOTHETIME("about to enter event loop");
+
+	bool shifton=false;
+	bool controlon=false;
+	bool button1down=false;
+	while (1) {
+		XEvent report = display.nextEvent();
+		switch (report.type) {
+			case Expose:
+//cerr << "report.xexpose.count == " << report.xexpose.count << endl;
+				if (report.xexpose.count != 0) break;
+				if (usewlm) wlwupdate.put();
+				window.writeHeaderText(topleftstring,topcenterstring,toprightstring);
+ECHOTHETIME("wimage.put() start");
+				wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+				if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+				if (nodisplayloop) goto done;
+				break;
+			case ButtonPress:
+				if (report.xbutton.button == Button1) {
+					button1down=true;
+					if (usewlm) {
+						wlwupdate.press(report.xbutton.x,report.xbutton.y);
+						window.useCursorLevelWidth();
+					}
+					else {
+						window.alarm();
+					}
+				}
+				break;
+			case ButtonRelease:
+				if (report.xbutton.button == Button1) {
+					button1down=false;
+					if (usewlm) {
+						window.useCursorWatch();
+						wlwupdate.release(report.xbutton.x,report.xbutton.y);
+						Uint16 width;
+						Uint16 level;
+						wlwupdate.get(level,width);
+						if (!image->setWindowLevelWidth(level,width)) {
+							log << map.errors();
+							log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+							return 1;
+						}
+ECHOTHETIME("put8BitIndexedPixels start");
+						if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+								0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+							log << EMsgDC(PixelDataReadFailed) << endl;
+							//return 1;
+						}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+						wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+						if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+						window.redraw();							
+#endif
+						window.useCursorCrossHair();
+					}
+				}
+				break;
+			case MotionNotify:
+				if (button1down) {
+					int multiplier=(report.xkey.state&ShiftMask ? 10 : 1)
+						      *(report.xkey.state&ControlMask ? 100 : 1);
+					if (usewlm)
+						wlwupdate.update(report.xmotion.x,report.xmotion.y,multiplier);
+				}
+				else {
+					unsigned short row;
+					unsigned short col;
+					window.reportPosition(
+						report.xmotion.x,report.xmotion.y,
+						row,col);
+					Float64 patientX,patientY,patientZ;
+					if (positioner.getPosition(row,col,patientX,patientY,patientZ)) {
+//cerr <<  "row=" << row
+//     << " col=" << col
+//     << " X=" << patientX
+//     << " Y=" << patientY
+//     << " Z=" << patientZ
+//     << endl;
+						window.clearFooter();
+						ostrstream rowcolostr;
+						rowcolostr <<  "R" << setw(4) << row
+							   << " C" << setw(4) << col
+							   << ends;
+						char *rowcolstr = rowcolostr.str();
+
+						ostrstream xyzostr;
+						xyzostr <<  setiosflags(ios::fixed|ios::showpoint)
+							<<  "X" <<  setprecision(1) << setw(6) << patientX
+							<< " Y" <<  setprecision(1) << setw(6) << patientY
+							<< " Z" <<  setprecision(1) << setw(6) << patientZ
+							<< ends;
+						char *xyzstr = xyzostr.str();
+
+						window.writeFooterText(rowcolstr,0,xyzstr);
+
+						if (rowcolstr) delete[] rowcolstr;
+						if (xyzstr) delete[] xyzstr;
+					}
+
+				}
+				break;
+			case KeyPress:
+				{
+					int deltax=0;
+					int deltay=0;
+					KeySym keysym;
+					(void)XLookupString(&report.xkey,0,0,&keysym,0);
+					switch (keysym) {
+						case XK_Shift_L:
+						case XK_Shift_R:
+						case XK_Shift_Lock:
+						case XK_Control_L:
+						case XK_Control_R:
+							break;		// handled by state, but must be allowed to press them
+						case XK_Left:
+						case XK_R10:		// the shifted state is a different keysym :(
+							deltax=-1;
+							break;
+						case XK_Right:
+						case XK_R12:		// the shifted state is a different keysym :(
+							deltax=1;
+							break;
+						case XK_Up:
+						case XK_R8:		// the shifted state is a different keysym :(
+							deltay=-1;
+							break;
+						case XK_Down:
+						case XK_R14:		// the shifted state is a different keysym :(
+							deltay=1;
+							break;
+						case XK_Escape:
+						case XK_Return:
+						case XK_q:
+						case XK_Q:
+						case XK_x:
+						case XK_X:
+							goto done;
+							// break;
+						case XK_o:
+						case XK_O:
+							showoverlays=!showoverlays;
+#ifdef DONTSENDEXPOSEEVENT
+							if (showoverlays) {
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+								overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+							}
+							else {
+ECHOTHETIME("wimage.put() start");
+								wimage.put();
+ECHOTHETIME("wimage.put() done");
+							}
+#else
+							window.redraw();							
+#endif
+							break;
+						case XK_v:
+						case XK_V:
+							if (nVOILUT) {
+								window.useCursorWatch();
+								if (++usewhichlut >= nVOILUT) usewhichlut=0;
+								image->setVOILUT(VOILUT_first[usewhichlut],VOILUT_number[usewhichlut],
+									VOILUT_depth[usewhichlut],VOILUT_table[usewhichlut]);
+								if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+									0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+									log << EMsgDC(PixelDataReadFailed) << endl;
+									//return 1;
+								}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+								wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+								if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+								window.redraw();							
+#endif
+								window.useCursorCrossHair();
+
+							}
+							else
+								window.alarm();
+							break;
+						default:
+							window.alarm();
+							break;
+					}
+					if (deltax || deltay) {
+						if (usewlm) {
+							int multiplier=(report.xkey.state&ShiftMask ? 10 : 1)
+								      *(report.xkey.state&ControlMask ? 100 : 1);
+							window.useCursorWatch();
+							wlwupdate.move(deltax,deltay,multiplier);
+							Uint16 width;
+							Uint16 level;
+							wlwupdate.get(level,width);
+							if (!image->setWindowLevelWidth(level,width)) {
+								log << map.errors();
+								log << EMsgDC(ColorCellValueReplacementFailed) << endl;
+								return 1;
+							}
+							if (!image->put8BitIndexedPixels(pixels,wimage.getBytesPerRow(),
+									0,0,vColumns-1,vRows*vNumberOfFrames-1)) {
+								log << EMsgDC(PixelDataReadFailed) << endl;
+								//return 1;
+							}
+#ifdef DONTSENDEXPOSEEVENT
+ECHOTHETIME("wimage.put() start");
+							wimage.put();
+ECHOTHETIME("wimage.put() done");
+ECHOTHETIME("overlays.putOverlay(wimage) start");
+							if (showoverlays) overlays.putOverlay(wimage);
+ECHOTHETIME("overlays.putOverlay(wimage) done");
+#else
+							window.redraw();							
+#endif
+							window.useCursorCrossHair();
+						}
+						else {
+							window.alarm();
+						}
+					}
+				}
+				break;
+			default:
+				break;
+		}
+	}
+
+	// not reached ...
+
+	// if (topleftstring) delete[] topleftstring;
+	// if (toprightstring) delete[] toprightstring;
+	// if (topcenterstring) delete[] topcenterstring;
+	// if (vPatientName) delete[] vPatientName;
+	// if (vPatientID) delete[] vPatientID;
+	// if (vStudyID) delete[] vStudyID;
+
+done:
+	if (writeimage && !wimage.write8BitDataToPGMStream(cout)) {
+		log << EMsgDC(PixelDataWriteFailed) << endl;
+		return 1;
+	}
+	else {
+		return 0;
+	}
+}
+
diff --git a/appsrc/dcdisp/dcdisp.man b/appsrc/dcdisp/dcdisp.man
new file mode 100755
index 0000000..b16a7fc
--- /dev/null
+++ b/appsrc/dcdisp/dcdisp.man
@@ -0,0 +1,208 @@
+.TH DCDISP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Display file on X window"
+.SH NAME
+dcdisp \- ACR/NEMA DICOM PS3 ... Display file on X window
+.SH SYNOPSIS
+.HP 10
+.B dcdisp
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-h|help
+]
+[
+.B \-showwithhelp
+]
+[
+.B \-noattributes
+]
+[
+.B \-nodisplayloop
+]
+[
+.BI \-windowwidth " n"
+.BI \-windowlevel " n"
+]
+[
+.B \-ignorewindow
+]
+[
+.B \-invertedgray
+]
+[
+.B \-[signed|unsigned]
+]
+[
+.B \-ignorepadvalue
+]
+[
+.B \-showoverlays
+]
+[
+.B \-writeimage " >pgmfile"
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcdisp
+reads the named dicom input file and displays its contents, using the barest minimum of X Windows features. Does its best to guess missing image pixel modules attributes in order to support older ACR/NEMA or SPI images.
+.LP
+Once displayed, for those photometric interpretations supporting window level and width (ie. 9-16 bit monochrome), the left/right/up/down arrow keys, or the dragging the mouse with the left button depressed, can be used to alter the window width and level. The unit of change is 1 normally, 10 if the shift key is simultaneously depressed, 100 if the control key is simultaneously depressed, and 1000 if both are depressed.
+.LP
+Typing q, Q, x, X, Return or Escape quits.
+.SH OPTIONS
+The attribute and verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-h|\-help
+.RS
+Display help information on standard error, without displaying image.
+.RE
+.TP
+.B \-showwithhelp
+.RS
+Display help information on standard error, as well as displaying image
+(useful when called as an external application from a browser)
+.RE
+.TP
+.B \-noattributes
+.RS
+Suppress the default description of important image attributes.
+.RE
+.TP
+.B \-nodisplayloop
+.RS
+Parse the input, map the display, but don't hang around, automatically exits, useful only for automated testing.
+.RE
+.TP
+.B \-windowwidth " n" \-windowlevel " n"
+.RS
+Use the specified values, rather than trying to guess them from the image statistics or using the attributes in the dataset. Values are specified in so-called displayed values (ie. after rescaling with rescale intercept and rescale slope and taking into account the unsigned or signed pixel representation) rather than stored values.
+.RE
+.TP
+.B \-ignorewindow
+.RS
+Ignore any window level/width attributes in the image object and instead
+try to guess them from the image statistics. Useful if the values in the
+object are wrong or screwy. Implied if window level and width are explicitly
+specified on the command line.
+.RE
+.TP
+.B \-invertedgray
+.RS
+Invert the image grayscale.
+.RE
+.TP
+.B \-[signed|unsigned]
+.RS
+Force the pixel representation to be signed or unsigned.
+.RE
+.TP
+.B \-ignorepadvalue
+.RS
+Ignore the Pixel Padding Value, i.e. don't exclude it when computing
+image statistics for automatic window center and width.
+.RE
+.TP
+.B \-showoverlays
+.RS
+Display any overlays present in the image object by default (may be toggled
+on and off with the "o" or "O" keys. regardless of whether or not this command
+line option is specified).
+.RE
+.TP
+.B \-writeimage
+.RS
+On exit, write an 8 bit version of the displayed image with the last window
+level/width used, as a raw 8 bit PGM file to stdout. The range of grayscale
+used in the 8 bits will depend on the colormap used to display the image, and
+may be less than expected on wierd hardware or if some other application has
+been hogging the colormap. Color images will be written as 8 bit index values,
+not RGB PPM files. Multiframe images will be really long and thin.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.TP
+\ 
+.RE
+% dcdisp test.dc3
+.RE
+Read ...
+.RE
+ Rows = 512
+.RE
+ Columns = 512
+.RE
+ NumberOfFrames = 0
+.RE
+ PhotometricInterpretation = MONOCHROME2
+.RE
+ SamplesPerPixel = 1
+.RE
+ BitsAllocated = 16
+.RE
+ BitsStored = 16
+.RE
+ HighBit = 15
+.RE
+ PixelRepresentation = 1
+.RE
+ PlanarConfiguration = 0x0
+.RE
+ RescaleIntercept = 0
+.RE
+ RescaleSlope = 1
+.RE
+ PixelData Value Length = 0x80000
+.RE
+Using ...
+.RE
+ Rows = 512
+.RE
+ Columns = 512
+.RE
+ NumberOfFrames = 1
+.RE
+ PhotometricInterpretation = MONOCHROME2
+.RE
+ SamplesPerPixel = 1
+.RE
+ BitsAllocated = 16
+.RE
+ BitsStored = 16
+.RE
+ HighBit = 15
+.RE
+ PixelRepresentation = 1
+.RE
+ PlanarConfiguration = 0x0
+.RE
+ RescaleIntercept = 0
+.RE
+ RescaleSlope = 1
+.RE
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Only handles 8-16 bit monochrome, palette color, and rgb photometric interpretations (with color-by-pixel planar configuration) only.
+.LP
+Multiple frames are handled in the sense that one big (long) image is built, which may exceed available memory, and is certainly hard to pull around the screen.
+.LP
+If necessary resorts to a private color map which makes for terrible flashing. Even when using the default color map, if invoked twice, the same colors are not shared.
+.LP
+Window level/width support involves remapping the entire pixel array which is a little (sic) slow. Palette animation for previewing is not yet implemented.
+.LP
+Overlay display is restricted to the (60xx,3000) group, and may fail under
+various circumstances.
+.LP
+VOI LUT currently ignores Rescale Slope/Intercept :(.
diff --git a/appsrc/dcfile/Imakefile b/appsrc/dcfile/Imakefile
new file mode 100755
index 0000000..80c6f4d
--- /dev/null
+++ b/appsrc/dcfile/Imakefile
@@ -0,0 +1,784 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES = $(PROJECTAPPDCFILEEXTRAINCLUDES)
+
+SRCSDCCREATE = dccreate.cc
+OBJSDCCREATE = dccreate.o
+
+SRCSDCLUTMIX = dclutmix.cc
+OBJSDCLUTMIX = dclutmix.o
+
+SRCSDCDTCHG = dcdtchg.cc
+OBJSDCDTCHG = dcdtchg.o
+
+SRCSDCUIDCHG = dcuidchg.cc
+OBJSDCUIDCHG = dcuidchg.o
+
+SRCSDCLUTBURN = dclutburn.cc
+OBJSDCLUTBURN = dclutburn.o
+
+SRCSDCTOPDF = dctopdf.cc
+OBJSDCTOPDF = dctopdf.o
+
+SRCSPDFTODC = pdftodc.cc
+OBJSPDFTODC = pdftodc.o
+
+SRCSPGXTODC = pgxtodc.cc
+OBJSPGXTODC = pgxtodc.o
+
+SRCSDCENCAP = dcencap.cc
+OBJSDCENCAP = dcencap.o
+
+SRCSDCBURN = dcburn.cc
+OBJSDCBURN = dcburn.o
+
+SRCSRAWFTODC = rawftodc.cc
+OBJSRAWFTODC = rawftodc.o
+
+SRCSDCCOMB = dccomb.cc
+OBJSDCCOMB = dccomb.o
+
+SRCSDCUNCAT = dcuncat.cc
+OBJSDCUNCAT = dcuncat.o
+
+SRCSDCSRMRG = dcsrmrg.cc
+OBJSDCSRMRG = dcsrmrg.o
+
+SRCSDCOSTOSR = dcostosr.cc
+OBJSDCOSTOSR = dcostosr.o
+
+SRCSDCSUB = dcsub.cc
+OBJSDCSUB = dcsub.o
+
+SRCSDCDECMPR = dcdecmpr.cc
+OBJSDCDECMPR = dcdecmpr.o
+
+SRCSDCSORT = dcsort.cc
+OBJSDCSORT = dcsort.o
+
+SRCSDCPROJ = dcproj.cc
+OBJSDCPROJ = dcproj.o
+
+SRCSDCARITH = dcarith.cc
+OBJSDCARITH = dcarith.o
+
+SRCSDCTOPGM8 = dctopgm8.cc
+OBJSDCTOPGM8 = dctopgm8.o
+
+SRCSDCTOPGX = dctopgx.cc
+OBJSDCTOPGX = dctopgx.o
+
+SRCSDCPOST = dcpost.cc
+OBJSDCPOST = dcpost.o
+
+SRCSDCMULTI = dcmulti.cc
+OBJSDCMULTI = dcmulti.o
+
+SRCSDCTABLE = dctable.cc
+OBJSDCTABLE = dctable.o
+
+SRCSDCMKPRES = dcmkpres.cc
+OBJSDCMKPRES = dcmkpres.o
+
+SRCSDCORTHO = dcortho.cc
+OBJSDCORTHO = dcortho.o
+
+SRCSANTODC = antodc.cc
+OBJSANTODC = antodc.o
+
+SRCSCP = dccp.cc
+OBJSCP = dccp.o
+
+SRCSDICT = dcdict.cc
+OBJSDICT = dcdict.o
+
+SRCSDIRDMP = dcdirdmp.cc
+OBJSDIRDMP = dcdirdmp.o
+
+SRCSDIRMK = dcdirmk.cc
+OBJSDIRMK = dcdirmk.o
+
+SRCSDUMP = dcdump.cc
+OBJSDUMP = dcdump.o
+
+SRCSFILE = dcfile.cc
+OBJSFILE = dcfile.o
+
+SRCSHIST = dchist.cc
+OBJSHIST = dchist.o
+
+SRCSKEY = dckey.cc
+OBJSKEY = dckey.o
+
+SRCSIODVFY = dciodvfy.cc
+OBJSIODVFY = dciodvfy.o
+
+SRCSLUTDMP = dclutdmp.cc
+OBJSLUTDMP = dclutdmp.o
+
+SRCSMERGE = dcmerge.cc
+OBJSMERGE = dcmerge.o
+
+SRCSPOSN = dcposn.cc
+OBJSPOSN = dcposn.o
+
+SRCSSMPTE = dcsmpte.cc
+OBJSSMPTE = dcsmpte.o
+
+SRCSBRIGGS = dcbriggs.cc
+OBJSBRIGGS = dcbriggs.o
+
+SRCSSQEXTR = dcsqextr.cc
+OBJSSQEXTR = dcsqextr.o
+
+SRCSSTATS = dcstats.cc
+OBJSSTATS = dcstats.o
+
+SRCSTORAW = dctoraw.cc
+OBJSTORAW = dctoraw.o
+
+SRCSTOPNM = dctopnm.cc
+OBJSTOPNM = dctopnm.o
+
+SRCSPBMTOOVL = pbmtoovl.cc
+OBJSPBMTOOVL = pbmtoovl.o
+
+SRCSPNMTO = pnmtodc.cc
+OBJSPNMTO = pnmtodc.o
+
+SRCSRAWTO = rawtodc.cc
+OBJSRAWTO = rawtodc.o
+
+SRCSDCSRDUMP = dcsrdump.cc
+OBJSDCSRDUMP = dcsrdump.o
+
+SRCSDCRMMETA = dcrmmeta.cc
+OBJSDCRMMETA = dcrmmeta.o
+
+SRCSDCENTVFY = dcentvfy.cc
+OBJSDCENTVFY = dcentvfy.o
+
+CPLUSPLUS_SRCS = $(SRCSDCCREATE) $(SRCSDCENTVFY) $(SRCSDCLUTMIX) $(SRCSDCUIDCHG) $(SRCSDCDTCHG) $(SRCSDCLUTBURN) $(SRCSDCTOPDF) $(SRCSPDFTODC) $(SRCSPGXTODC) $(SRCSDCENCAP) $(SRCSDCBURN) $(SRCSRAWFTODC) $(SRCSDCCOMB) $(SRCSDCUNCAT) $(SRCSDCSRMRG) $(SRCSDCOSTOSR) $(SRCSDCRMMETA) $(SRCSDCSRDUMP) $(SRCSDCDECMPR) $(SRCSDCSUB) $(SRCSDCSORT) $(SRCSDCPROJ) $(SRCSDCARITH) $(SRCSDCTOPGM8) $(SRCSDCTOPGX) $(SRCSDCPOST) $(SRCSDCTABLE) $(SRCSDCMKPRES) $(SRCSDCORTHO) $(SRCSANTODC) $(SRCSCP) $(SRCSDICT [...]
+OBJS           = $(OBJSDCCREATE) $(OBJSDCENTVFY) $(OBJSDCLUTMIX) $(OBJSDCUIDCHG) $(OBJSDCDTCHG) $(OBJSDCLUTBURN) $(OBJSDCTOPDF) $(OBJSPDFTODC) $(OBJSPGXTODC) $(OBJSDCENCAP) $(OBJSDCBURN) $(OBJSRAWFTODC) $(OBJSDCCOMB) $(OBJSDCUNCAT) $(OBJSDCSRMRG) $(OBJSDCOSTOSR) $(OBJSDCRMMETA) $(OBJSDCSRDUMP) $(OBJSDCDECMPR) $(OBJSDCSUB) $(OBJSDCSORT) $(OBJSDCPROJ) $(OBJSDCARITH) $(OBJSDCTOPGM8) $(OBJSDCTOPGX) $(OBJSDCPOST) $(OBJSDCTABLE) $(OBJSDCMKPRES) $(OBJSDCORTHO) $(OBJSANTODC) $(OBJSCP) $(OBJSDICT [...]
+
+AllTarget(dccreate)
+NormalCCProgramTarget(dccreate,$(OBJSDCCREATE),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dccreate,$(INSTALLBINDIR))
+InstallManPage(dccreate,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcentvfy)
+NormalCCProgramTarget(dcentvfy,$(OBJSDCENTVFY),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcentvfy,$(INSTALLBINDIR))
+InstallManPage(dcentvfy,$(INSTALLMANDIR)/man1)
+
+AllTarget(dclutmix)
+NormalCCProgramTarget(dclutmix,$(OBJSDCLUTMIX),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dclutmix,$(INSTALLBINDIR))
+InstallManPage(dclutmix,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcuidchg)
+NormalCCProgramTarget(dcuidchg,$(OBJSDCUIDCHG),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcuidchg,$(INSTALLBINDIR))
+InstallManPage(dcuidchg,$(INSTALLMANDIR)/man1)
+
+depend::	dcdtchg.h
+
+dcdtchg.h:	${PROJECTLIBSTANDARDDIR}/elmdict/dicom3.tpl makedcdtchgheader.sh
+	./makedcdtchgheader.sh ${PROJECTLIBSTANDARDDIR}/elmdict/dicom3.tpl dcdtchg.h
+	
+AllTarget(dcdtchg)
+NormalCCProgramTarget(dcdtchg,$(OBJSDCDTCHG),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcdtchg,$(INSTALLBINDIR))
+InstallManPage(dcdtchg,$(INSTALLMANDIR)/man1)
+
+AllTarget(dclutburn)
+NormalCCProgramTarget(dclutburn,$(OBJSDCLUTBURN),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dclutburn,$(INSTALLBINDIR))
+InstallManPage(dclutburn,$(INSTALLMANDIR)/man1)
+
+AllTarget(dctopdf)
+NormalCCProgramTarget(dctopdf,$(OBJSDCTOPDF),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dctopdf,$(INSTALLBINDIR))
+InstallManPage(dctopdf,$(INSTALLMANDIR)/man1)
+
+AllTarget(pdftodc)
+NormalCCProgramTarget(pdftodc,$(OBJSPDFTODC),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(pdftodc,$(INSTALLBINDIR))
+InstallManPage(pdftodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(pgxtodc)
+NormalCCProgramTarget(pgxtodc,$(OBJSPGXTODC),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(pgxtodc,$(INSTALLBINDIR))
+InstallManPage(pgxtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcencap)
+NormalCCProgramTarget(dcencap,$(OBJSDCENCAP),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcencap,$(INSTALLBINDIR))
+InstallManPage(dcencap,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcburn)
+NormalCCProgramTarget(dcburn,$(OBJSDCBURN),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcburn,$(INSTALLBINDIR))
+InstallManPage(dcburn,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawftodc)
+NormalCCProgramTarget(rawftodc,$(OBJSRAWFTODC),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(rawftodc,$(INSTALLBINDIR))
+InstallManPage(rawftodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(dccomb)
+NormalCCProgramTarget(dccomb,$(OBJSDCCOMB),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dccomb,$(INSTALLBINDIR))
+InstallManPage(dccomb,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcuncat)
+NormalCCProgramTarget(dcuncat,$(OBJSDCUNCAT),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcuncat,$(INSTALLBINDIR))
+InstallManPage(dcuncat,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcsrmrg)
+NormalCCProgramTarget(dcsrmrg,$(OBJSDCSRMRG),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcsrmrg,$(INSTALLBINDIR))
+InstallManPage(dcsrmrg,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcostosr)
+NormalCCProgramTarget(dcostosr,$(OBJSDCOSTOSR),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcostosr,$(INSTALLBINDIR))
+InstallManPage(dcostosr,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcrmmeta)
+NormalCCProgramTarget(dcrmmeta,$(OBJSDCRMMETA),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcrmmeta,$(INSTALLBINDIR))
+InstallManPage(dcrmmeta,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcsrdump)
+NormalCCProgramTarget(dcsrdump,$(OBJSDCSRDUMP),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcsrdump,$(INSTALLBINDIR))
+InstallManPage(dcsrdump,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcsub)
+NormalCCProgramTarget(dcsub,$(OBJSDCSUB),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcsub,$(INSTALLBINDIR))
+InstallManPage(dcsub,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcdecmpr)
+NormalCCProgramTarget(dcdecmpr,$(OBJSDCDECMPR),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcdecmpr,$(INSTALLBINDIR))
+InstallManPage(dcdecmpr,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcsort)
+NormalCCProgramTarget(dcsort,$(OBJSDCSORT),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcsort,$(INSTALLBINDIR))
+InstallManPage(dcsort,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcproj)
+NormalCCProgramTarget(dcproj,$(OBJSDCPROJ),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcproj,$(INSTALLBINDIR))
+InstallManPage(dcproj,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcarith)
+NormalCCProgramTarget(dcarith,$(OBJSDCARITH),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcarith,$(INSTALLBINDIR))
+InstallManPage(dcarith,$(INSTALLMANDIR)/man1)
+
+AllTarget(dctopgm8)
+NormalCCProgramTarget(dctopgm8,$(OBJSDCTOPGM8),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dctopgm8,$(INSTALLBINDIR))
+InstallManPage(dctopgm8,$(INSTALLMANDIR)/man1)
+
+AllTarget(dctopgx)
+NormalCCProgramTarget(dctopgx,$(OBJSDCTOPGX),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dctopgx,$(INSTALLBINDIR))
+InstallManPage(dctopgx,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcpost)
+NormalCCProgramTarget(dcpost,$(OBJSDCPOST),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcpost,$(INSTALLBINDIR))
+InstallManPage(dcpost,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcmulti)
+NormalCCProgramTarget(dcmulti,$(OBJSDCMULTI),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcmulti,$(INSTALLBINDIR))
+InstallManPage(dcmulti,$(INSTALLMANDIR)/man1)
+
+AllTarget(dctable)
+NormalCCProgramTarget(dctable,$(OBJSDCTABLE),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dctable,$(INSTALLBINDIR))
+InstallManPage(dctable,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcmkpres)
+NormalCCProgramTarget(dcmkpres,$(OBJSDCMKPRES),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcmkpres,$(INSTALLBINDIR))
+InstallManPage(dcmkpres,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcortho)
+NormalCCProgramTarget(dcortho,$(OBJSDCORTHO),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcortho,$(INSTALLBINDIR))
+InstallManPage(dcortho,$(INSTALLMANDIR)/man1)
+
+AllTarget(antodc)
+NormalCCProgramTarget(antodc,$(OBJSANTODC),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(antodc,$(INSTALLBINDIR))
+InstallManPage(antodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(dclutdmp)
+NormalCCProgramTarget(dclutdmp,$(OBJSLUTDMP),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dclutdmp,$(INSTALLBINDIR))
+InstallManPage(dclutdmp,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcbriggs)
+NormalCCProgramTarget(dcbriggs,$(OBJSBRIGGS),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcbriggs,$(INSTALLBINDIR))
+InstallManPage(dcbriggs,$(INSTALLMANDIR)/man1)
+
+AllTarget(dccp)
+NormalCCProgramTarget(dccp,$(OBJSCP),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dccp,$(INSTALLBINDIR))
+InstallManPage(dccp,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcdict)
+NormalCCProgramTarget(dcdict,$(OBJSDICT),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcdict,$(INSTALLBINDIR))
+InstallManPage(dcdict,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcdirdmp)
+NormalCCProgramTarget(dcdirdmp,$(OBJSDIRDMP),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcdirdmp,$(INSTALLBINDIR))
+InstallManPage(dcdirdmp,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcdirmk)
+NormalCCProgramTarget(dcdirmk,$(OBJSDIRMK),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcdirmk,$(INSTALLBINDIR))
+InstallManPage(dcdirmk,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcdump)
+NormalCCProgramTarget(dcdump,$(OBJSDUMP),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcdump,$(INSTALLBINDIR))
+InstallManPage(dcdump,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcfile)
+NormalCCProgramTarget(dcfile,$(OBJSFILE),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcfile,$(INSTALLBINDIR))
+InstallManPage(dcfile,$(INSTALLMANDIR)/man1)
+
+AllTarget(dchist)
+NormalCCProgramTarget(dchist,$(OBJSHIST),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dchist,$(INSTALLBINDIR))
+InstallManPage(dchist,$(INSTALLMANDIR)/man1)
+
+AllTarget(dckey)
+NormalCCProgramTarget(dckey,$(OBJSKEY),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dckey,$(INSTALLBINDIR))
+InstallManPage(dckey,$(INSTALLMANDIR)/man1)
+
+AllTarget(dciodvfy)
+NormalCCProgramTarget(dciodvfy,$(OBJSIODVFY),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dciodvfy,$(INSTALLBINDIR))
+InstallManPage(dciodvfy,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcmerge)
+NormalCCProgramTarget(dcmerge,$(OBJSMERGE),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcmerge,$(INSTALLBINDIR))
+InstallManPage(dcmerge,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcposn)
+NormalCCProgramTarget(dcposn,$(OBJSPOSN),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcposn,$(INSTALLBINDIR))
+InstallManPage(dcposn,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcsmpte)
+NormalCCProgramTarget(dcsmpte,$(OBJSSMPTE),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcsmpte,$(INSTALLBINDIR))
+InstallManPage(dcsmpte,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcsqextr)
+NormalCCProgramTarget(dcsqextr,$(OBJSSQEXTR),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcsqextr,$(INSTALLBINDIR))
+InstallManPage(dcsqextr,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcstats)
+NormalCCProgramTarget(dcstats,$(OBJSSTATS),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dcstats,$(INSTALLBINDIR))
+InstallManPage(dcstats,$(INSTALLMANDIR)/man1)
+
+AllTarget(dctoraw)
+NormalCCProgramTarget(dctoraw,$(OBJSTORAW),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dctoraw,$(INSTALLBINDIR))
+InstallManPage(dctoraw,$(INSTALLMANDIR)/man1)
+
+AllTarget(dctopnm)
+NormalCCProgramTarget(dctopnm,$(OBJSTOPNM),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(dctopnm,$(INSTALLBINDIR))
+InstallManPage(dctopnm,$(INSTALLMANDIR)/man1)
+
+AllTarget(pbmtoovl)
+NormalCCProgramTarget(pbmtoovl,$(OBJSPBMTOOVL),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(pbmtoovl,$(INSTALLBINDIR))
+InstallManPage(pbmtoovl,$(INSTALLMANDIR)/man1)
+
+AllTarget(pnmtodc)
+NormalCCProgramTarget(pnmtodc,$(OBJSPNMTO),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(pnmtodc,$(INSTALLBINDIR))
+InstallManPage(pnmtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawtodc)
+NormalCCProgramTarget(rawtodc,$(OBJSRAWTO),$(PROJECTDCFILEDEPLIBS),$(PROJECTDCFILELIBS),-lm)
+InstallProgram(rawtodc,$(INSTALLBINDIR))
+InstallManPage(rawtodc,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcpatmpl,$(INSTALLBINDIR))
+InstallManPage(dcpatmpl,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcswab,$(INSTALLBINDIR))
+InstallManPage(dcswab,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcjls,$(INSTALLBINDIR))
+InstallManPage(dcjls,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcunjls,$(INSTALLBINDIR))
+InstallManPage(dcunjls,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcj2k,$(INSTALLBINDIR))
+InstallManPage(dcj2k,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcjpeg,$(INSTALLBINDIR))
+InstallManPage(dcjpeg,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcunjpeg,$(INSTALLBINDIR))
+InstallManPage(dcunjpeg,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcunjpeg.all,$(INSTALLBINDIR))
+InstallManPage(dcunjpeg.all,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcunrgb,$(INSTALLBINDIR))
+InstallManPage(dcunrgb,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcanon,$(INSTALLBINDIR))
+InstallManPage(dcanon,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcmvhier,$(INSTALLBINDIR))
+InstallManPage(dcmvhier,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcmvhier.uid,$(INSTALLBINDIR))
+InstallManPage(dcmvhier.uid,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcmvhier.datedesc,$(INSTALLBINDIR))
+InstallManPage(dcmvhier.datedesc,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcmvhier.datedescnoid,$(INSTALLBINDIR))
+InstallManPage(dcmvhier.datedescnoid,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcmvhier.8only,$(INSTALLBINDIR))
+InstallManPage(dcmvhier.8only,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcmvhier.all,$(INSTALLBINDIR))
+InstallManPage(dcmvhier.all,$(INSTALLMANDIR)/man1)
+
+InstallScript(antodc.all,$(INSTALLBINDIR))
+InstallManPage(antodc.all,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcrmsfx.all,$(INSTALLBINDIR))
+InstallManPage(dcrmsfx.all,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcdeflate,$(INSTALLBINDIR))
+InstallManPage(dcdeflate,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcinflate,$(INSTALLBINDIR))
+InstallManPage(dcinflate,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcbzip2,$(INSTALLBINDIR))
+InstallManPage(dcbzip2,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcunbzip2,$(INSTALLBINDIR))
+InstallManPage(dcunbzip2,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcsrdiff,$(INSTALLBINDIR))
+InstallManPage(dcsrdiff,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcdiff,$(INSTALLBINDIR))
+InstallManPage(dcdiff,$(INSTALLMANDIR)/man1)
+
+InstallScript(dccmp,$(INSTALLBINDIR))
+InstallManPage(dccmp,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcacqmap,$(INSTALLBINDIR))
+InstallManPage(dcacqmap,$(INSTALLMANDIR)/man1)
+
+InstallScript(dcckovly,$(INSTALLBINDIR))
+InstallManPage(dcckovly,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test:: testdchist testy2k testpbmtoovl testdcfile testdccp testantodc testpnmtodc testdcdirdmp testdcdump testdciodvfy testdcposn testpack testdcsrdump testdcunrgb
+
+testpbmtoovl:
+	@$(TOP)/support/testapp testlist ./pbmtoovl "-overlaygroup 0 -r SOPClassUID 0 -r SOPInstanceUID 0" $(TOP)/images/ovltest $(TOP)/test/$(CURRENT_DIR) compare pbmtoovl
+
+testy2k:
+	./testy2k.sh $(TOP)/test/$(CURRENT_DIR) compare
+	./testy2k.antodc.sh $(TOP)/test/$(CURRENT_DIR) compare
+
+testpack:
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"                                $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack1
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n"                             $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack2
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little"    $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack3
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack4
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big"       $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack5
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n"    $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack6
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -rb BitsAllocated 12 -rb BitsStored 12 -rb HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack11
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -rb BitsAllocated 12 -rb BitsStored 12 -rb HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack12
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -rb BitsAllocated 12 -rb BitsStored 12 -rb HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack13
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -rb BitsAllocated 12 -rb BitsStored 12 -rb HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack14
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -rb BitsAllocated 12 -rb BitsStored 12 -rb HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack15
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -rb BitsAllocated 12 -rb BitsStored 12 -rb HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack16
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -rb BitsAllocated 16 -rb BitsStored 16 -rb HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack21
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -rb BitsAllocated 16 -rb BitsStored 16 -rb HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack22
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -rb BitsAllocated 16 -rb BitsStored 16 -rb HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack23
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -rb BitsAllocated 16 -rb BitsStored 16 -rb HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack24
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -rb BitsAllocated 16 -rb BitsStored 16 -rb HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack25
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -rb BitsAllocated 16 -rb BitsStored 16 -rb HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack26
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -rb BitsAllocated 8 -rb BitsStored 8 -rb HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack31
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -rb BitsAllocated 8 -rb BitsStored 8 -rb HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack32
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -rb BitsAllocated 8 -rb BitsStored 8 -rb HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack33
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -rb BitsAllocated 8 -rb BitsStored 8 -rb HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack34
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -rb BitsAllocated 8 -rb BitsStored 8 -rb HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack35
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -rb BitsAllocated 8 -rb BitsStored 8 -rb HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack36
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack111
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack112
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack113
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack114
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack115
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack116
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack121
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack122
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack123
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack124
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack125
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack126
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack131
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack132
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack133
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack134
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack135
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) compare pack136
+
+testdciodvfy:
+	@$(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare iodvfy
+	@$(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare iodvfy
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare iodvfy; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare iodvfy; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare iodvfy; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) compare iodvfy; fi
+
+testdcfile:
+	@$(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare file
+	@$(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare file
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare file; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare file; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare file; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) compare file; fi
+
+testdcsrdump:
+	@$(TOP)/support/testapp testsrs ./dcsrdump "-identifier"           $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) compare dcsrdump
+
+testdcdirdmp:
+	@$(TOP)/support/testapp testdirs ./dcdirdmp "-vv"                  $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) compare dcdirdmp
+
+testdchist:
+	@$(TOP)/support/testapp testlist ./dchist "-h"                $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare hist
+	@$(TOP)/support/testapp testlist ./dchist "-h"                $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare hist
+
+testdcdump:
+	@$(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare dump
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare dump; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) compare dump; fi
+
+testdccp:
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare cp
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare cp
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare cp; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare cp; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare cp; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) compare cp; fi
+
+testantodc:
+	@$(TOP)/support/testapp testlist ./antodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare todc
+	@$(TOP)/support/testapp testlist ./antodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare todc
+
+testpnmtodc:
+	@$(TOP)/support/testapp testlist ./pnmtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/pnm $(TOP)/test/$(CURRENT_DIR) compare todc
+
+testdctopnm:
+	@$(TOP)/support/testapp testlist ./dctopnm "-output-endian little"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare cp
+	@$(TOP)/support/testapp testlist ./dctopnm "-output-endian little"      $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) compare cp
+
+testdctopgx:
+	@$(TOP)/support/testapp testlist ./dctopgx ""      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) compare cp
+	@$(TOP)/support/testapp testlist ./dctopgx ""      $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) compare cp
+
+testdcposn:
+	@$(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare posnTLHC
+	@$(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare posnRRHC
+	@$(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare posnBLHC
+	@$(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) compare posnBRHC
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare posnTLHC; fi
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare posnRRHC; fi
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare posnBLHC; fi
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) compare posnBRHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare posnTLHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare posnRRHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare posnBLHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) compare posnBRHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare posnTLHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare posnRRHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare posnBLHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) compare posnBRHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) compare posnTLHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) compare posnRRHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) compare posnBLHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) compare posnBRHC; fi
+
+$(TOP)/images/dicom/testrgb:	$(TOP)/images/dicom/testlist  
+	xargs <"$<" -L1 -I% $(TOP)/appsrc/dcfile/dctable -k PhotometricInterpretation "$(TOP)/images/dicom/%" 2>&1 | grep '"RGB' | sed -e 's/^"\([^"]*\)".*$$/\1/' -e 's/^.*\/images\/dicom\///' >"$@"
+
+testdcunrgb:	$(TOP)/images/dicom/testrgb
+	@$(TOP)/support/testapp testrgb ./dcunrgb.script ""      $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create:: testdchist.create testy2k.create testpbmtoovl.create testdcfile.create testdccp.create testantodc.create testpnmtodc.create testdcdirdmp.create testdcdump.create testdciodvfy.create testdcposn.create testpack.create testdcsrdump.create testdcunrgb.create
+
+testy2k.create:
+	./testy2k.sh $(TOP)/test/$(CURRENT_DIR) create
+	./testy2k.antodc.sh $(TOP)/test/$(CURRENT_DIR) create
+
+testpbmtoovl.create:
+	@$(TOP)/support/testapp testlist ./pbmtoovl "-overlaygroup 0 -r SOPClassUID 0 -r SOPInstanceUID 0" $(TOP)/images/ovltest $(TOP)/test/$(CURRENT_DIR) create pbmtoovl
+
+testpack.create:
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"                                $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack1
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n"                             $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack2
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little"    $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack3
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack4
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big"       $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack5
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n"    $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack6
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -r BitsAllocated 12 -r BitsStored 12 -r HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack11
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -r BitsAllocated 12 -r BitsStored 12 -r HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack12
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -r BitsAllocated 12 -r BitsStored 12 -r HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack13
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -r BitsAllocated 12 -r BitsStored 12 -r HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack14
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -r BitsAllocated 12 -r BitsStored 12 -r HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack15
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -r BitsAllocated 12 -r BitsStored 12 -r HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack16
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -r BitsAllocated 16 -r BitsStored 16 -r HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack21
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -r BitsAllocated 16 -r BitsStored 16 -r HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack22
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -r BitsAllocated 16 -r BitsStored 16 -r HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack23
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -r BitsAllocated 16 -r BitsStored 16 -r HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack24
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -r BitsAllocated 16 -r BitsStored 16 -r HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack25
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -r BitsAllocated 16 -r BitsStored 16 -r HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack26
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -r BitsAllocated 8 -r BitsStored 8 -r HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack31
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -r BitsAllocated 8 -r BitsStored 8 -r HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack32
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -r BitsAllocated 8 -r BitsStored 8 -r HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack33
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -r BitsAllocated 8 -r BitsStored 8 -r HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack34
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -r BitsAllocated 8 -r BitsStored 8 -r HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack35
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -r BitsAllocated 8 -r BitsStored 8 -r HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack36
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack111
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack112
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack113
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack114
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack115
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -ra BitsAllocated 12 -ra BitsStored 12 -ra HighBit 11" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack116
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack121
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack122
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack123
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack124
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack125
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -ra BitsAllocated 16 -ra BitsStored 16 -ra HighBit 15" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack126
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100                                -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack131
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -n                             -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack132
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little    -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack133
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian little -n -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack134
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big       -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack135
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100 -vr explicit -endian big -n    -ra BitsAllocated 8 -ra BitsStored 8 -ra HighBit 7" $(TOP)/images/packtest $(TOP)/test/$(CURRENT_DIR) create pack136
+
+testdciodvfy.create:
+	@$(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create iodvfy
+	@$(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create iodvfy
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create iodvfy; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create iodvfy; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create iodvfy; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dciodvfy ""                $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) create iodvfy; fi
+
+testdcfile.create:
+	@$(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create file
+	@$(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create file
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create file; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create file; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create file; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcfile ""                  $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) create file; fi
+
+testdcsrdump.create:
+	@$(TOP)/support/testapp testsrs ./dcsrdump "-identifier"           $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) create dcsrdump
+
+testdcdirdmp.create:
+	@$(TOP)/support/testapp testdirs ./dcdirdmp "-vv"                  $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) create dcdirdmp
+
+testdchist.create:
+	@$(TOP)/support/testapp testlist ./dchist "-h"                $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create hist
+	@$(TOP)/support/testapp testlist ./dchist "-h"                $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create hist
+
+testdcdump.create:
+	@$(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create dump
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create dump; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcdump ""                  $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) create dump; fi
+
+testdccp.create:
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create cp
+	@$(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create cp
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create cp; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create cp; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create cp; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dccp "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/wuerlim  $(TOP)/test/wuerlim/$(CURRENT_DIR) create cp; fi
+
+testantodc.create:
+	@$(TOP)/support/testapp testlist ./antodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create todc
+	@$(TOP)/support/testapp testlist ./antodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create todc
+
+testpnmtodc.create:
+	@$(TOP)/support/testapp testlist ./pnmtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100"      $(TOP)/images/pnm $(TOP)/test/$(CURRENT_DIR) create todc
+
+testdctopnm.create:
+	@$(TOP)/support/testapp testlist ./dctopnm "-output-endian little"      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create cp
+	@$(TOP)/support/testapp testlist ./dctopnm "-output-endian little"      $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) create cp
+
+testdctopgx.create:
+	@$(TOP)/support/testapp testlist ./dctopgx ""      $(TOP)/images/acrnema $(TOP)/test/$(CURRENT_DIR) create cp
+	@$(TOP)/support/testapp testlist ./dctopgx ""      $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) create cp
+
+testdcposn.create:
+	@$(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create posnTLHC
+	@$(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create posnRRHC
+	@$(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create posnBLHC
+	@$(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/dicom   $(TOP)/test/$(CURRENT_DIR) create posnBRHC
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create posnTLHC; fi
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create posnRRHC; fi
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create posnBLHC; fi
+	@if [ -f $(TOP)/images/disc95/us000001. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/disc95   $(TOP)/test/$(CURRENT_DIR) create posnBRHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create posnTLHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create posnRRHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create posnBLHC; fi
+	@if [ -f $(TOP)/images/disc95am/cine01. ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/disc95am $(TOP)/test/$(CURRENT_DIR) create posnBRHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create posnTLHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create posnRRHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create posnBLHC; fi
+	@if [ -f $(TOP)/images/osiriscd/dicom/ctspine.dcm ]; then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/osiriscd $(TOP)/test/$(CURRENT_DIR) create posnBRHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col   0" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) create posnTLHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row   0 -col 255" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) create posnRRHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col   0" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) create posnBLHC; fi
+	@if [ -d $(TOP)/images/wuerlim/version3 ];           then $(TOP)/support/testapp testlist ./dcposn "-row 255 -col 255" $(TOP)/images/wuerlim  $(TOP)/test/$(CURRENT_DIR) create posnBRHC; fi
+
+testdcunrgb.create:	$(TOP)/images/dicom/testrgb
+	@$(TOP)/support/testapp testrgb ./dcunrgb.script ""      $(TOP)/images/dicom $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dcfile/antodc.all.man b/appsrc/dcfile/antodc.all.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/antodc.all.script b/appsrc/dcfile/antodc.all.script
new file mode 100755
index 0000000..adee0eb
--- /dev/null
+++ b/appsrc/dcfile/antodc.all.script
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# Usage: antodc.all dirname
+#
+# where dirname is the directory name where images are
+#
+# converts files in place and adds .dcm extension
+#
+# removes private tags to avoid UN VR in explicit endian
+# for those private tags that aren't in the dictionary
+#
+# removes any (obvious) sequences since they mess up some viewers
+#
+
+DCMSUFFIX="dcm"
+
+STAMP=`date +%Y%m%d%H%M%S`.$$
+
+ANTODC="antodc"
+
+if [ ! $# = 1 ]
+then
+	echo 1>&2 "Usage: `basename $0` dirname"
+	exit 1
+fi
+
+for i in `find "$1" -type f -a ! -name '.*' -print`
+do
+	if [ -f "$i" ]
+	then
+		echo "Converting $i to $i.$DCMSUFFIX"
+
+		$ANTODC -output-vr explicit -output-endian little -stamp "$STAMP" \
+			-removeprivate \
+			-d ReferencedImageSequence -d IconImageSequence -d SourceImageSequence \
+			"$i" "$i.$DCMSUFFIX"
+	fi
+done
+
+exit 0
diff --git a/appsrc/dcfile/antodc.cc b/appsrc/dcfile/antodc.cc
new file mode 100644
index 0000000..d1b03c3
--- /dev/null
+++ b/appsrc/dcfile/antodc.cc
@@ -0,0 +1,2018 @@
+static const char *CopyrightIdentifier(void) { return "@(#)antodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>
+#else
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static bool
+isPrivateCreatorPresent(AttributeList &list,Uint16 group,Uint16 element,const char *creator)
+{
+//cerr << "isPrivateCreatorPresent: (" << hex << group << "," << element << dec << ") want <" << creator << ">" << endl;
+	bool same=false;
+
+	Assert(creator
+	    && strlen(creator) > 0
+	    && creator[strlen(creator)-1] != ' ');	// no trailing blanks
+
+//cerr << "isPrivateCreatorPresent: looking for attribute" << endl;
+	Attribute *a=list[Tag(group,element)];
+	char *value=0;
+//cerr << "isPrivateCreatorPresent: checking attribute" << endl;
+	if (a && a->isString() && a->getValue(0,value) && value) {
+//cerr << "isPrivateCreatorPresent: found value <" << value << ">" << endl;
+		char *p = value+strlen(value);
+		while (p-- > value && *p == ' ') *p=0;	// remove trailing spaces
+
+//cerr << "isPrivateCreatorPresent: checking against <" << value << ">" << endl;
+		if (strcmp(value,creator) == 0) {
+//cerr << "isPrivateCreatorPresent: same" << endl;
+			same=true;
+		}
+	}
+//cerr << "isPrivateCreatorPresent: done" << endl;
+	if (value) delete[] value;
+//cerr << "isPrivateCreatorPresent: result " << (same ? "T" : "F") << endl;
+	return same;
+}
+
+static Attribute *
+findPrivateAttribute(AttributeList &list,Uint16 group,const char *creatorID,Uint16 element) {
+	Attribute *a=NULL;
+	int tryBlock;
+	for (tryBlock=0; tryBlock < 0x0100; ++tryBlock) {
+		if (isPrivateCreatorPresent(list,group,tryBlock,creatorID)) {
+//cerr << "findPrivateAttribute: found " << creatorID << " " << hex << group << "," << ((tryBlock<<8)|(element&0x00ff)) << dec << endl;
+			a=list[Tag(group,(tryBlock<<8)|(element&0x00ff))];
+			break;
+		}
+	}
+	return a;
+}
+
+static void
+AcrNEMA_FixImagePlaneModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixImagePlaneModule:" << endl;
+
+//cerr << "AcrNEMA_FixImagePlaneModule: SliceLocation" << endl;
+
+	{
+		Attribute *aSliceLocation=list[TagFromName(SliceLocation)];	// the DICOM attribute
+		if (!aSliceLocation) {
+			Attribute *aLocation=list[TagFromName(Location)];	// old ACR-NEMA - retired in DICOM
+			if (aLocation) {
+				char *vLocation=AttributeValue(aLocation);
+				if (vLocation) {
+					aSliceLocation=new DecimalStringAttribute(TagFromName(SliceLocation),vLocation);
+					Assert(aSliceLocation);
+					list+=aSliceLocation;
+				}
+			}
+		}
+	}
+
+	// Try to make patient relative orientation and position ...
+
+	bool headfirst = false;
+	bool feetfirst = false;
+
+	bool prone = false;
+	bool supine = false;
+	bool left = false;
+	bool right = false;
+
+	bool viewcranial = false;
+	bool viewcaudal = false;
+	bool viewleft = false;
+	bool viewright = false;
+	bool viewfront = false;
+	bool viewback = false;
+	
+	bool patientOrientationClaimsColumnsPosterior = false;		// To check for and fix a Toshiba CT bug
+	bool patientOrientationClaimsColumnsAnterior = false;		// To check for and fix a Toshiba CT bug
+
+	{
+		// Fix Toshiba bug ... trailing backslash on PatientOrientation
+
+		Attribute *aPatientOrientation=list[TagFromName(PatientOrientation)];
+
+		if (aPatientOrientation && aPatientOrientation->getVM() >= 3) {
+			// don't have "removeValue" method so replace attribute:
+
+			char *row_direction=0;	(void)aPatientOrientation->getValue(0,row_direction);
+			char *col_direction=0;	(void)aPatientOrientation->getValue(1,col_direction);
+
+			list-=aPatientOrientation;
+			delete aPatientOrientation;
+
+			aPatientOrientation=new CodeStringAttribute(TagFromName(PatientOrientation));
+			Assert(aPatientOrientation);
+
+			aPatientOrientation->addValue(row_direction);
+			aPatientOrientation->addValue(col_direction);
+
+			list+=aPatientOrientation;
+//cerr << "PatientOrientation col_direction = " << col_direction << endl;
+			if (col_direction && strcmp(col_direction,"P") == 0) {
+				patientOrientationClaimsColumnsPosterior=true;		// To check for and fix a Toshiba CT bug
+			}
+//cerr << "patientOrientationClaimsColumnsPosterior = " << patientOrientationClaimsColumnsPosterior << endl;
+			if (col_direction && strcmp(col_direction,"A") == 0) {
+				patientOrientationClaimsColumnsAnterior=true;		// To check for and fix a Toshiba CT bug
+			}
+//cerr << "patientOrientationClaimsColumnsPosterior = " << patientOrientationClaimsColumnsPosterior << endl;
+		}
+
+		// Fix Toshiba bug ... trailing backslash on ImageOrientation
+
+		Attribute *aImageOrientation=list[TagFromName(ImageOrientation)];
+
+		if (aImageOrientation && aImageOrientation->getVM() >= 7) {
+			// don't have "removeValue" method so replace attribute:
+
+			Float32 orientation_row_X; (void)aImageOrientation->getValue(0,orientation_row_X);
+			Float32 orientation_row_Y; (void)aImageOrientation->getValue(1,orientation_row_Y);
+			Float32 orientation_row_Z; (void)aImageOrientation->getValue(2,orientation_row_Z);
+			Float32 orientation_col_X; (void)aImageOrientation->getValue(3,orientation_col_X);
+			Float32 orientation_col_Y; (void)aImageOrientation->getValue(4,orientation_col_Y);
+			Float32 orientation_col_Z; (void)aImageOrientation->getValue(5,orientation_col_Z);
+			
+			list-=aImageOrientation;
+			delete aImageOrientation;
+
+			aImageOrientation=new DecimalStringAttribute(TagFromName(ImageOrientation));
+			Assert(aImageOrientation);
+
+			aImageOrientation->addValue(orientation_row_X);
+			aImageOrientation->addValue(orientation_row_Y);
+			aImageOrientation->addValue(orientation_row_Z);
+			aImageOrientation->addValue(orientation_col_X);
+			aImageOrientation->addValue(orientation_col_Y);
+			aImageOrientation->addValue(orientation_col_Z);
+
+			list+=aImageOrientation;
+		}
+
+		// Fix Toshiba bug ... trailing backslash on PixelSpacing
+
+		Attribute *aPixelSpacing=list[TagFromName(PixelSpacing)];
+
+		if (aPixelSpacing && aPixelSpacing->getVM() >= 3) {
+			// don't have "removeValue" method so replace attribute:
+
+			double vPixelSpacing_Row; 	(void)aPixelSpacing->getValue(0,vPixelSpacing_Row);
+			double vPixelSpacing_Column;	(void)aPixelSpacing->getValue(1,vPixelSpacing_Column);
+
+			list-=aPixelSpacing;
+			delete aPixelSpacing;
+
+			aPixelSpacing=new DecimalStringAttribute(TagFromName(PixelSpacing));
+			Assert(aPixelSpacing);
+
+			aPixelSpacing->addValue(vPixelSpacing_Row);
+			aPixelSpacing->addValue(vPixelSpacing_Column);
+
+			list+=aPixelSpacing;
+		}
+	}
+
+	{
+		Attribute *aPatientPosition=findPrivateAttribute(list,0x0013,"SIEMENS CM VA0  CMS",0x0044);	// Patient Position (Siemens SPI modified)
+
+		if (!aPatientPosition) aPatientPosition=list[TagFromName(PatientPosition)];	// Patient Position (ACR/NEMA and DICOM)
+
+		char *vPatientPosition=0;
+		if (aPatientPosition) {
+			aPatientPosition->getValue(0,vPatientPosition);
+			list-=TagFromName(PatientPosition);			// will replace it later
+		}
+
+//cerr << "AcrNEMA_FixImagePlaneModule: PatientPosition = " << vPatientPosition << endl;
+
+		// check for DICOM values ... (and check for Philips bug with space between values)
+
+		if (!headfirst) headfirst = vPatientPosition && (strcmp(vPatientPosition,"HFS") == 0 || strcmp(vPatientPosition,"HF S") == 0);
+		if (!headfirst) headfirst = vPatientPosition && (strcmp(vPatientPosition,"HFP") == 0 || strcmp(vPatientPosition,"HF P") == 0);
+		if (!headfirst) headfirst = vPatientPosition && (strcmp(vPatientPosition,"HFDR") == 0 || strcmp(vPatientPosition,"HF DR") == 0);
+		if (!headfirst) headfirst = vPatientPosition && (strcmp(vPatientPosition,"HFDL") == 0 || strcmp(vPatientPosition,"HF DL") == 0);
+		if (!feetfirst) feetfirst = vPatientPosition && (strcmp(vPatientPosition,"FFS") == 0 || strcmp(vPatientPosition,"FF S") == 0);
+		if (!feetfirst) feetfirst = vPatientPosition && (strcmp(vPatientPosition,"FFP") == 0 || strcmp(vPatientPosition,"FF P") == 0);
+		if (!feetfirst) feetfirst = vPatientPosition && (strcmp(vPatientPosition,"FFDR") == 0 || strcmp(vPatientPosition,"FF DR") == 0);
+		if (!feetfirst) feetfirst = vPatientPosition && (strcmp(vPatientPosition,"FFDL") == 0 || strcmp(vPatientPosition,"FF DL") == 0);
+
+		if (!supine) supine = vPatientPosition && (strcmp(vPatientPosition,"HFS") == 0 || strcmp(vPatientPosition,"HF S") == 0);
+		if (!supine) supine = vPatientPosition && (strcmp(vPatientPosition,"FFS") == 0 || strcmp(vPatientPosition,"FF S") == 0);
+		if (!prone)  prone  = vPatientPosition && (strcmp(vPatientPosition,"HFP") == 0 || strcmp(vPatientPosition,"HF P") == 0);
+		if (!prone)  prone  = vPatientPosition && (strcmp(vPatientPosition,"FFP") == 0 || strcmp(vPatientPosition,"FF P") == 0);
+		if (!right)  right  = vPatientPosition && (strcmp(vPatientPosition,"HFDR") == 0 || strcmp(vPatientPosition,"HF DR") == 0);
+		if (!right)  right  = vPatientPosition && (strcmp(vPatientPosition,"FFDR") == 0 || strcmp(vPatientPosition,"FF DR") == 0);
+		if (!left)   left   = vPatientPosition && (strcmp(vPatientPosition,"HFDL") == 0 || strcmp(vPatientPosition,"HF DL") == 0);
+		if (!left)   left   = vPatientPosition && (strcmp(vPatientPosition,"FFDL") == 0 || strcmp(vPatientPosition,"FF DL") == 0);
+
+		if (!supine) supine = vPatientPosition && (strcmp(vPatientPosition,"SUPINE") == 0 || strcmp(vPatientPosition,"SUPI") == 0);	// Some Siemens SPI +/- truncated to 4 chars
+		if (!prone)  prone  = vPatientPosition && (strcmp(vPatientPosition,"PRONE") == 0  || strcmp(vPatientPosition,"PRON") == 0);
+		if (!right)  right  = vPatientPosition && (strcmp(vPatientPosition,"RIGHT") == 0  || strcmp(vPatientPosition,"RIGH") == 0);
+		if (!left)   left   = vPatientPosition &&  strcmp(vPatientPosition,"LEFT") == 0;
+
+		if (!vPatientPosition && isPrivateCreatorPresent(list,0x0019,0x0011,"TOSHIBA_MEC_CT_1.0")
+		      && list[Tag(0x0019,0x1108)]	// OrientationHeadFeet (HF, ? what else)
+		      && list[Tag(0x0019,0x110a)]	// OrientationSupineProne (SU, ? what else)
+		) {
+cerr << "Warning - Patient Position absent - reconstructing from private CT Toshiba attributes" << endl;
+			Attribute *aOrientationHeadFeet=findPrivateAttribute(list,0x0019,"TOSHIBA_MEC_CT_1.0",0x0008);		// OrientationHeadFeet (HF, ? what else)
+			char *vOrientationHeadFeet=0;
+			if (aOrientationHeadFeet) aOrientationHeadFeet->getValue(0,vOrientationHeadFeet);
+			if (vOrientationHeadFeet) {
+//cerr << "Got vOrientationHeadFeet " << vOrientationHeadFeet << endl;
+				if (strcmp(vOrientationHeadFeet,"HF") == 0) headfirst=true;
+				else if (strcmp(vOrientationHeadFeet,"FF") == 0) feetfirst=true;		// guess at string value
+			}
+			
+			Attribute *aOrientationSupineProne=findPrivateAttribute(list,0x0019,"TOSHIBA_MEC_CT_1.0",0x000a);		// OrientationHeadFeet (HF, ? what else)
+			char *vOrientationSupineProne=0;
+			if (aOrientationSupineProne) aOrientationSupineProne->getValue(0,vOrientationSupineProne);
+			if (vOrientationSupineProne) {
+//cerr << "Got vOrientationSupineProne " << vOrientationSupineProne << endl;
+				if (strcmp(vOrientationSupineProne,"SU") == 0) supine=true;
+				else if (strcmp(vOrientationSupineProne,"PR") == 0) prone=true;		// guess at string value
+			}
+			
+		}
+
+		if (!vPatientPosition && isPrivateCreatorPresent(list,0x0019,0x0010,"PHILIPS MR/PART")
+		      && list[Tag(0x0019,0x1008)]	// PatientPosition
+		      && list[Tag(0x0019,0x1009)]	// PatientOrientation
+		) {
+cerr << "Warning - Patient Position absent - reconstructing from private MR Philips attributes" << endl;
+
+			Attribute *aPatientPosition=list[Tag(0x0019,0x1008)];
+			Uint16 vPatientPosition=0;
+
+			if (aPatientPosition && aPatientPosition->getVM() == 1) (void) aPatientPosition->getValue(0,vPatientPosition);
+
+			switch (vPatientPosition) {
+				case 1:		headfirst=true;
+						break;
+				case 2:		feetfirst=true;
+						break;
+			}
+
+			Attribute *aPatientOrientation=list[Tag(0x0019,0x1009)];
+			Uint16 vPatientOrientation=0;
+
+			if (aPatientOrientation && aPatientOrientation->getVM() == 1) (void) aPatientOrientation->getValue(0,vPatientOrientation);
+
+			switch (vPatientOrientation) {
+				case 1:		supine=true;
+						break;
+				case 2:		prone=true;
+						break;
+				case 3:		left=true;
+						break;
+				case 4:		right=true;
+						break;
+			}
+		}
+	}
+	{
+		Attribute *aRestDirection=findPrivateAttribute(list,0x0013,"SIEMENS CM VA0  CMS",0x0042);		// Patient Rest Direction (Siemens SPI modified)
+		if (!aRestDirection) aRestDirection=findPrivateAttribute(list,0x0021,"SIEMENS CM VA0  CMS",0x0032);	// Patient Rest Direction (Siemens SPI original)
+
+		char *vRestDirection=0;
+		if (aRestDirection) aRestDirection->getValue(0,vRestDirection);
+
+		if (!headfirst) headfirst = vRestDirection && strcmp(vRestDirection,"HEAD") == 0;
+		if (!feetfirst) feetfirst = vRestDirection && strcmp(vRestDirection,"FEET") == 0;
+	}
+
+	{
+		// The view direction is the old "look from top down or bottom up"
+		// issue that applied to EMI head vs. body scans
+
+		// SPI generalizes it to cover sagittals ( "RtoL" or "LtoR") and
+		// coronals ("AtoP" and "PtoA") as well ...
+
+		Attribute *aViewDirection=findPrivateAttribute(list,0x0013,"SIEMENS CM VA0  CMS",0x0046);		// View Direction (Siemens SPI modified)
+		if (!aViewDirection) aViewDirection=findPrivateAttribute(list,0x0021,"SIEMENS CM VA0  CMS",0x0030);	// View Direction (Siemens SPI original)
+		if (!aViewDirection) aViewDirection=findPrivateAttribute(list,0x0019,"TOSHIBA_MEC_CT_1.0",0x0009);	// View Direction (Toshiba CT)
+
+		char *vViewDirection=0;
+		if (aViewDirection) aViewDirection->getValue(0,vViewDirection);
+//cerr << "Got vViewDirection " << vViewDirection << endl;
+
+		if (!viewcranial) viewcranial = vViewDirection && strcmp(vViewDirection,"HEAD") == 0;
+		if (!viewcranial) viewcranial = vViewDirection && strcmp(vViewDirection,"HFF") == 0;		// Toshiba - guess
+		if (!viewcaudal)  viewcaudal  = vViewDirection && strcmp(vViewDirection,"FEET") == 0;
+		if (!viewcaudal)  viewcaudal  = vViewDirection && strcmp(vViewDirection,"VFF") == 0;		// Toshiba
+		if (!viewleft)    viewleft    = vViewDirection && strcmp(vViewDirection,"LtoR") == 0;
+		if (!viewright)   viewright   = vViewDirection && strcmp(vViewDirection,"RtoL") == 0;
+		if (!viewfront)   viewfront   = vViewDirection && strcmp(vViewDirection,"AtoP") == 0;
+		if (!viewback)    viewback    = vViewDirection && strcmp(vViewDirection,"PtoA") == 0;
+	}
+
+
+	Assert(!(supine && prone && right && left));
+	Assert(!(headfirst && feetfirst));
+	Assert(!(viewcranial && viewcaudal && viewleft && viewright && viewfront && viewback));
+
+	Attribute *aImagePositionPatient=list[TagFromName(ImagePositionPatient)];		// DICOM patient relative
+	Attribute *aImageOrientationPatient=list[TagFromName(ImageOrientationPatient)];		// DICOM patient relative
+
+	if (aImagePositionPatient && aImageOrientationPatient) {
+
+		// The DICOM attributes are present - read and rewrite them ...
+		// (why ? converts scientific to float and makes GE AW voxtool happier)
+
+		if (aImagePositionPatient    && aImagePositionPatient->getVM() == 3
+		 && aImageOrientationPatient && aImageOrientationPatient->getVM() == 6) {
+
+			Float32 position_X; (void)aImagePositionPatient->getValue(0,position_X);
+			Float32 position_Y; (void)aImagePositionPatient->getValue(1,position_Y);
+			Float32 position_Z; (void)aImagePositionPatient->getValue(2,position_Z);
+
+			list-=aImagePositionPatient;
+			aImagePositionPatient=new DecimalStringAttribute(TagFromName(ImagePositionPatient));
+			Assert(aImagePositionPatient);
+			aImagePositionPatient->addValue(position_X);
+			aImagePositionPatient->addValue(position_Y);
+			aImagePositionPatient->addValue(position_Z);
+			list+=aImagePositionPatient;
+
+			Float32 orientation_row_X; (void)aImageOrientationPatient->getValue(0,orientation_row_X);
+			Float32 orientation_row_Y; (void)aImageOrientationPatient->getValue(1,orientation_row_Y);
+			Float32 orientation_row_Z; (void)aImageOrientationPatient->getValue(2,orientation_row_Z);
+			Float32 orientation_col_X; (void)aImageOrientationPatient->getValue(3,orientation_col_X);
+			Float32 orientation_col_Y; (void)aImageOrientationPatient->getValue(4,orientation_col_Y);
+			Float32 orientation_col_Z; (void)aImageOrientationPatient->getValue(5,orientation_col_Z);
+
+			list-=aImageOrientationPatient;
+			aImageOrientationPatient=new DecimalStringAttribute(TagFromName(ImageOrientationPatient));
+			Assert(aImageOrientationPatient);
+			aImageOrientationPatient->addValue(orientation_row_X);
+			aImageOrientationPatient->addValue(orientation_row_Y);
+			aImageOrientationPatient->addValue(orientation_row_Z);
+			aImageOrientationPatient->addValue(orientation_col_X);
+			aImageOrientationPatient->addValue(orientation_col_Y);
+			aImageOrientationPatient->addValue(orientation_col_Z);
+			list+=aImageOrientationPatient;
+		}
+	}
+	else {
+		// The DICOM attributes are not present - make them ...
+
+		Attribute *aImagePosition=list[TagFromName(ImagePosition)];		// ACR-NEMA gantry relative
+		Attribute *aImageOrientation=list[TagFromName(ImageOrientation)];	// ACR-NEMA gantry relative
+
+		if (aImagePosition    && aImagePosition->getVM() == 3
+		 && aImageOrientation && aImageOrientation->getVM() == 6) {
+
+			Float32 position_X; (void)aImagePosition->getValue(0,position_X);
+			Float32 position_Y; (void)aImagePosition->getValue(1,position_Y);
+			Float32 position_Z; (void)aImagePosition->getValue(2,position_Z);
+
+			Float32 orientation_row_X; (void)aImageOrientation->getValue(0,orientation_row_X);
+			Float32 orientation_row_Y; (void)aImageOrientation->getValue(1,orientation_row_Y);
+			Float32 orientation_row_Z; (void)aImageOrientation->getValue(2,orientation_row_Z);
+			Float32 orientation_col_X; (void)aImageOrientation->getValue(3,orientation_col_X);
+			Float32 orientation_col_Y; (void)aImageOrientation->getValue(4,orientation_col_Y);
+			Float32 orientation_col_Z; (void)aImageOrientation->getValue(5,orientation_col_Z);
+			
+			if (prone) {		// swap L/R and A/P
+cerr << "Prone so swapping L/R and A/P" << endl;
+				position_X        = -position_X;
+				orientation_row_X = -orientation_row_X;
+				orientation_col_X = -orientation_col_X;
+
+				position_Y        = -position_Y;
+				orientation_row_Y = -orientation_row_Y;
+				orientation_col_Y = -orientation_col_Y;
+			}
+
+			if (right) {		// swap L is really P, A is really L
+cerr << "Decubitus Right so swapping X and Y and changing sign of new Y" << endl;
+				Float32 temp;
+				temp = position_X; position_X = position_Y; position_Y = -temp;
+				temp = orientation_row_X; orientation_row_X = orientation_row_Y; orientation_row_Y = -temp;
+				temp = orientation_col_X; orientation_col_X = orientation_col_Y; orientation_col_Y = -temp;
+			}
+
+			if (left) {		// swap L is really A, P is really L
+cerr << "Decubitus Left so swapping X and Y and changing sign of new Y" << endl;
+				Float32 temp;
+				temp = position_X; position_X = position_Y; position_Y = -temp;
+				temp = orientation_row_X; orientation_row_X = orientation_row_Y; orientation_row_Y = -temp;
+				temp = orientation_col_X; orientation_col_X = orientation_col_Y; orientation_col_Y = -temp;
+			}
+
+			if (feetfirst) {	// swap L/R and H/F
+cerr << "Feet first so swapping L/R and H/F" << endl;
+				position_X        = -position_X;
+				orientation_row_X = -orientation_row_X;
+				orientation_col_X = -orientation_col_X;
+
+				position_Z        = -position_Z;
+				orientation_row_Z = -orientation_row_Z;
+				orientation_col_Z = -orientation_col_Z;
+			}
+
+			if (orientation_col_Y  < 0 && patientOrientationClaimsColumnsPosterior
+			 || orientation_col_Y  > 0 && patientOrientationClaimsColumnsAnterior) {
+cerr << "Warning - Patient Orientation and generated Image Orientation (Patient) inconsistent in column Y direction - change sign (likely Toshiba CT bug)" << endl;
+				orientation_row_Y=-orientation_row_Y;
+				orientation_col_Y=-orientation_col_Y;
+				position_Y       = -position_Y;
+				
+				// also fix up the original (incorrect) gantry-relative attributes
+				{
+					Attribute *aImageOrientation=list[TagFromName(ImageOrientation)];
+					if (aImageOrientation && aImageOrientation->getVM() == 6) {
+						Float32 orientation_row_X; (void)aImageOrientation->getValue(0,orientation_row_X);
+						Float32 orientation_row_Y; (void)aImageOrientation->getValue(1,orientation_row_Y);
+						Float32 orientation_row_Z; (void)aImageOrientation->getValue(2,orientation_row_Z);
+						Float32 orientation_col_X; (void)aImageOrientation->getValue(3,orientation_col_X);
+						Float32 orientation_col_Y; (void)aImageOrientation->getValue(4,orientation_col_Y);
+						Float32 orientation_col_Z; (void)aImageOrientation->getValue(5,orientation_col_Z);
+			
+						list-=aImageOrientation;
+						delete aImageOrientation;
+
+						aImageOrientation=new DecimalStringAttribute(TagFromName(ImageOrientation));
+						Assert(aImageOrientation);
+
+						aImageOrientation->addValue(orientation_row_X);
+						aImageOrientation->addValue(-orientation_row_Y);
+						aImageOrientation->addValue(orientation_row_Z);
+						aImageOrientation->addValue(orientation_col_X);
+						aImageOrientation->addValue(-orientation_col_Y);
+						aImageOrientation->addValue(orientation_col_Z);
+
+						list+=aImageOrientation;
+					}
+					Attribute *aImagePosition=list[TagFromName(ImagePosition)];
+					if (aImagePosition && aImagePosition->getVM() == 3) {
+						Float32 position_X; (void)aImagePosition->getValue(0,position_X);
+						Float32 position_Y; (void)aImagePosition->getValue(1,position_Y);
+						Float32 position_Z; (void)aImagePosition->getValue(2,position_Z);
+			
+						list-=aImagePosition;
+						delete aImagePosition;
+
+						aImagePosition=new DecimalStringAttribute(TagFromName(ImagePosition));
+						Assert(aImagePosition);
+
+						aImagePosition->addValue(position_X);
+						aImagePosition->addValue(-position_Y);
+						aImagePosition->addValue(position_Z);
+
+						list+=aImagePosition;
+					}
+				}
+			}
+			
+			// For now assume that View Direction has already been accounted for in orientation attributes
+			// ... not known if this assumption is valid or not :(
+
+			Attribute *aImagePositionPatient=new DecimalStringAttribute(TagFromName(ImagePositionPatient));
+			Assert(aImagePositionPatient);
+			aImagePositionPatient->addValue(position_X);
+			aImagePositionPatient->addValue(position_Y);
+			aImagePositionPatient->addValue(position_Z);
+			list+=aImagePositionPatient;
+
+			Attribute *aImageOrientationPatient=new DecimalStringAttribute(TagFromName(ImageOrientationPatient));
+			Assert(aImageOrientationPatient);
+			aImageOrientationPatient->addValue(orientation_row_X);
+			aImageOrientationPatient->addValue(orientation_row_Y);
+			aImageOrientationPatient->addValue(orientation_row_Z);
+			aImageOrientationPatient->addValue(orientation_col_X);
+			aImageOrientationPatient->addValue(orientation_col_Y);
+			aImageOrientationPatient->addValue(orientation_col_Z);
+			list+=aImageOrientationPatient;
+		}
+		else if (isPrivateCreatorPresent(list,0x0019,0x0010,"PHILIPS MR/PART")
+		      && list[Tag(0x0019,0x100A)]	// SliceOrientation
+		      && isPrivateCreatorPresent(list,0x0019,0x0011,"PHILIPS MR/PART")
+		      && list[Tag(0x0019,0x110B)]	// ImageOffcentreLR
+		) {
+cerr << "Warning - Image Position or Orientation absent or incomplete - reconstructing from private MR Philips attributes" << endl;
+
+			// reconstruct ImageOrientationPatient from private SliceOrientation (which is already patient not gantry relative)
+
+			Float32 orientation_row_X=0;
+			Float32 orientation_row_Y=0;
+			Float32 orientation_row_Z=0;
+
+			Float32 orientation_col_X=0;
+			Float32 orientation_col_Y=0;
+			Float32 orientation_col_Z=0;
+
+			Attribute *aSliceOrientation=list[Tag(0x0019,0x100A)];
+			Uint16 vSliceOrientation=0;
+
+			if (aSliceOrientation && aSliceOrientation->getVM() == 1) (void) aSliceOrientation->getValue(0,vSliceOrientation);
+
+			// DICOM is +LPH
+
+			switch (vSliceOrientation) {
+				case 1:		// transverse
+						orientation_row_X=1;	// +L
+						orientation_col_Y=1;	// +P
+						break;
+				case 2:		// sagittal
+						orientation_row_Y=1;	// +P
+						orientation_col_Z=-1;	// -H
+						break;
+				case 3:		// coronal
+						orientation_row_X=1;	// +L
+						orientation_col_Z=-1;	// -H
+						break;
+				default:	// undefined or missing - assume transverse
+						orientation_row_X=1;	// +L
+						orientation_col_Y=1;	// +P
+						break;
+			}
+
+			// should probably also account for private rotation attributes ... not yet implemented
+
+
+
+			// reconstruct ImagePositionPatient from private Image Offcentre (assume is already patient not gantry relative)
+
+			// DICOM is +LPH
+			// Philips is +RAH
+
+			Float32 position_X=0;
+			Float32 position_Y=0;
+			Float32 position_Z=0;
+
+			Attribute *aImageOffcentreLR=list[Tag(0x0019,0x100B)];
+			Float32 vImageOffcentreLR=0;
+
+			if (aImageOffcentreLR && aImageOffcentreLR->getVM() == 1) {
+				(void) aImageOffcentreLR->getValue(0,vImageOffcentreLR);
+				position_X-=vImageOffcentreLR;
+			}
+
+			Attribute *aImageOffcentreCC=list[Tag(0x0019,0x100C)];
+			Float32 vImageOffcentreCC=0;
+
+			if (aImageOffcentreCC && aImageOffcentreCC->getVM() == 1) {
+				(void) aImageOffcentreCC->getValue(0,vImageOffcentreCC);
+				position_Z+=vImageOffcentreCC;
+			}
+
+			Attribute *aImageOffcentreAP=list[Tag(0x0019,0x100D)];
+			Float32 vImageOffcentreAP=0;
+
+			if (aImageOffcentreAP && aImageOffcentreAP->getVM() == 1) {
+				(void) aImageOffcentreAP->getValue(0,vImageOffcentreAP);
+				position_Y-=vImageOffcentreAP;
+			}
+
+			{
+				Attribute *aImagePositionPatient=new DecimalStringAttribute(TagFromName(ImagePositionPatient));
+				Assert(aImagePositionPatient);
+				aImagePositionPatient->addValue(position_X);
+				aImagePositionPatient->addValue(position_Y);
+				aImagePositionPatient->addValue(position_Z);
+				list+=aImagePositionPatient;
+
+				Attribute *aImageOrientationPatient=new DecimalStringAttribute(TagFromName(ImageOrientationPatient));
+				Assert(aImageOrientationPatient);
+				aImageOrientationPatient->addValue(orientation_row_X);
+				aImageOrientationPatient->addValue(orientation_row_Y);
+				aImageOrientationPatient->addValue(orientation_row_Z);
+				aImageOrientationPatient->addValue(orientation_col_X);
+				aImageOrientationPatient->addValue(orientation_col_Y);
+				aImageOrientationPatient->addValue(orientation_col_Z);
+				list+=aImageOrientationPatient;
+			}
+		}
+		else {
+cerr << "Warning - Image Position or Orientation absent or incomplete while making patient relative" << endl;
+cerr << "Warning - Orientation (such as left/right) may be wrong" << endl;
+
+			// Let's be creative and make it up from Patient Orientation and Slice Location...
+			// (which may have been derived from Location earlier in this routine)
+
+			Attribute *aSliceLocation=list[TagFromName(SliceLocation)];
+
+			Float32 vSliceLocation=0;
+			if (aSliceLocation && aSliceLocation->getVM() == 1) aSliceLocation->getValue(0,vSliceLocation);
+
+			Attribute *aPatientOrientation=list[TagFromName(PatientOrientation)];
+			char *row_direction=0;
+			char *col_direction=0;
+
+			// Try this only if row and col directions are orthogonal
+			// to major axes (e.g. P\F) and not obliques (that are
+			// compound, e.g. AL\RF) since:
+			// a) angle can't be determined and
+			// b) sign of Slice Location becomes ambiguous
+
+			if (aPatientOrientation && aPatientOrientation->getVM() == 2
+			 && aPatientOrientation->getValue(0,row_direction) && (row_direction[1] == 0 || row_direction[1] == ' ')
+			 && aPatientOrientation->getValue(1,col_direction) && (col_direction[1] == 0 || col_direction[1] == ' ') ) {
+
+				Float32 orientation_row_X=0;
+				Float32 orientation_row_Y=0;
+				Float32 orientation_row_Z=0;
+
+				Float32 orientation_col_X=0;
+				Float32 orientation_col_Y=0;
+				Float32 orientation_col_Z=0;
+
+				// DICOM plane definitions are:
+				// - Left Pos Superior +ve (aka +HPL)
+
+				switch (row_direction[0]) {
+					case 'R':	orientation_row_X=-1; break;
+					case 'L':	orientation_row_X= 1; break;
+					case 'A':	orientation_row_Y=-1; break;
+					case 'P':	orientation_row_Y= 1; break;
+					case 'F':	orientation_row_Z=-1; break;
+					case 'H':	orientation_row_Z= 1; break;
+				}
+
+				switch (col_direction[0]) {
+					case 'R':	orientation_col_X=-1; break;
+					case 'L':	orientation_col_X= 1; break;
+					case 'A':	orientation_col_Y=-1; break;
+					case 'P':	orientation_col_Y= 1; break;
+					case 'F':	orientation_col_Z=-1; break;
+					case 'H':	orientation_col_Z= 1; break;
+				}
+
+				// compute normal to image plane ...
+				// - cross product of row and column vectors
+				// - points AWAY from viewer
+
+				Float32 normal_X = orientation_row_Y*orientation_col_Z - orientation_row_Z*orientation_col_Y;
+				Float32 normal_Y = orientation_row_Z*orientation_col_X - orientation_row_X*orientation_col_Z;
+				Float32 normal_Z = orientation_row_X*orientation_col_Y - orientation_row_Y*orientation_col_X;
+
+//cerr << "normal_X = " << normal_X << endl;
+//cerr << "normal_Y = " << normal_Y << endl;
+//cerr << "normal_Z = " << normal_Z << endl;
+
+				// - change sign to point TOWARDS viewer
+
+				normal_X = -normal_X;
+				normal_Y = -normal_Y;
+				normal_Z = -normal_Z;
+
+				// Project Slice Location along normal making a lot of assumptions:
+				// - which way the normal points - towards or away from the viewer
+				// - is it consistent for all planes
+				// - what is the sign of Slice Location for each plane for Siemens and Philips
+				// - does the patient insertion in the gantry matter
+				//
+				// this needs serious work :)
+
+				// assume patient relative and +FAL (typical late model Siemens)
+
+//cerr << "vSliceLocation = " << vSliceLocation << endl;
+
+				Float32 position_X=normal_X*vSliceLocation;		// sagittal viewed from L, DICOM is +L, location is +L
+				Float32 position_Y=normal_Y*vSliceLocation * -1;	// coronal  viewed from A, DICOM is +P, location is +A
+				Float32 position_Z=normal_Z*vSliceLocation * -1;	// axial    viewed from F, DICOM is +H, location is +F
+
+				Attribute *aImagePositionPatient=new DecimalStringAttribute(TagFromName(ImagePositionPatient));
+				Assert(aImagePositionPatient);
+				aImagePositionPatient->addValue(position_X);
+				aImagePositionPatient->addValue(position_Y);
+				aImagePositionPatient->addValue(position_Z);
+				list+=aImagePositionPatient;
+
+				Attribute *aImageOrientationPatient=new DecimalStringAttribute(TagFromName(ImageOrientationPatient));
+				Assert(aImageOrientationPatient);
+				aImageOrientationPatient->addValue(orientation_row_X);
+				aImageOrientationPatient->addValue(orientation_row_Y);
+				aImageOrientationPatient->addValue(orientation_row_Z);
+				aImageOrientationPatient->addValue(orientation_col_X);
+				aImageOrientationPatient->addValue(orientation_col_Y);
+				aImageOrientationPatient->addValue(orientation_col_Z);
+				list+=aImageOrientationPatient;
+			}
+
+		}
+
+	}
+
+//cerr << "AcrNEMA_FixImagePlaneModule: PatientPosition" << endl;
+
+//cerr << "supine = " << (supine ? "true" : "false") << endl;
+//cerr << "prone = "  << (prone  ? "true" : "false") << endl;
+//cerr << "right = "  << (right  ? "true" : "false") << endl;
+//cerr << "left = "   << (left   ? "true" : "false") << endl;
+
+//cerr << "headfirst = "   << (headfirst   ? "true" : "false") << endl;
+//cerr << "feetfirst = "   << (feetfirst   ? "true" : "false") << endl;
+
+	if (!supine && !prone && !right && !left) {
+		supine=true;
+cerr << "Warning - Can't determine supine or prone - assuming supine" << endl;
+	}
+
+	if (!headfirst && !feetfirst) {
+		headfirst=true;
+cerr << "Warning - Can't determine head or feet first - assuming head first" << endl;
+	}
+
+	const char *vPatientPosition=0;
+	if      (supine && headfirst) vPatientPosition="HFS";
+	else if (supine && feetfirst) vPatientPosition="FFS";
+	else if (prone  && headfirst) vPatientPosition="HFP";
+	else if (prone  && feetfirst) vPatientPosition="FFP";
+
+//cerr << "AcrNEMA_FixImagePlaneModule: new PatientPosition = " << vPatientPosition << endl;
+
+	// add zero length even if no information - is a Type 2 attribute ...
+
+	Attribute *aPatientPosition=new CodeStringAttribute(TagFromName(PatientPosition));
+	Assert(aPatientPosition);
+	if (vPatientPosition) aPatientPosition->addValue(vPatientPosition);
+	list+=aPatientPosition;
+
+//cerr << "AcrNEMA_FixImagePlaneModule: Done" << endl;
+}
+
+
+static void
+AcrNEMA_FixLaterality(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixLaterality:" << endl;
+	bool right = false;
+	bool left = false;
+
+	{
+		Attribute *aLaterality=list[TagFromName(Laterality)];		// ACR-NEMA and Siemens SPI
+										// Value of "NO" is ignored
+
+		char *vLaterality=0;
+		if (aLaterality) {
+			aLaterality->getValue(0,vLaterality);
+			list-=TagFromName(Laterality);				// Replaced later
+		}
+
+		if (!right) right = vLaterality && strcmp(vLaterality,"RIGHT") == 0;
+		if (!right) right = vLaterality && strcmp(vLaterality,"R") == 0;
+		if (!left)  left  = vLaterality && strcmp(vLaterality,"LEFT") == 0;
+		if (!left)  left  = vLaterality && strcmp(vLaterality,"L") == 0;
+	}
+
+	const char *vLaterality=0;
+	if      (right) vLaterality="R";
+	else if (left)  vLaterality="L";
+	Attribute *aLaterality=new CodeStringAttribute(TagFromName(Laterality));
+	Assert(aLaterality);
+	if (vLaterality) aLaterality->addValue(vLaterality);
+	list+=aLaterality;
+}
+
+static void
+AcrNEMA_FixImagePixelModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixImagePixelModule:" << endl;
+	{
+		Attribute *aSamplesPerPixel=list[TagFromName(SamplesPerPixel)];
+		if (!aSamplesPerPixel) {
+			aSamplesPerPixel=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),1);
+			Assert(aSamplesPerPixel);
+			list+=aSamplesPerPixel;
+		}
+	}
+	{
+		Attribute *aPhotometricInterpretation=list[TagFromName(PhotometricInterpretation)];
+		if (!aPhotometricInterpretation) {
+			aPhotometricInterpretation=new CodeStringAttribute(TagFromName(PhotometricInterpretation),"MONOCHROME2");
+			Assert(aPhotometricInterpretation);
+			list+=aPhotometricInterpretation;
+		}
+	}
+
+	// If Bits Allocated is absent or has no value use next byte boundary >= Bits Stored
+	// (eg. Siemens Somatom CT)
+
+	{
+		Attribute *aBitsAllocated=list[TagFromName(BitsAllocated)];
+
+		if (!aBitsAllocated || aBitsAllocated->getVL() == 0) {
+			Attribute *aBitsStored=list[TagFromName(BitsStored)];
+			Uint16 vBitsStored;
+			if (aBitsStored && aBitsStored->getValue(0,vBitsStored) && vBitsStored) {
+				if (aBitsAllocated) {
+					list-=TagFromName(BitsAllocated); 
+				}
+
+				aBitsAllocated=new UnsignedShortAttribute(TagFromName(BitsAllocated),Uint16(((vBitsStored-1)/8+1)*8));
+				Assert(aBitsAllocated);
+				list+=aBitsAllocated;
+			}
+		}
+	}
+	// If High Bit is absent or has no value use one less than Bits Stored
+	// (eg. Toshiba Xpress CT)
+
+	{
+		Attribute *aHighBit=list[TagFromName(HighBit)];
+
+		if (!aHighBit || aHighBit->getVL() == 0) {
+			Attribute *aBitsStored=list[TagFromName(BitsStored)];
+			Uint16 vBitsStored;
+			if (aBitsStored && aBitsStored->getValue(0,vBitsStored) && vBitsStored) {
+				if (aHighBit) {
+					list-=TagFromName(HighBit); 
+				}
+
+				aHighBit=new UnsignedShortAttribute(TagFromName(HighBit),Uint16(vBitsStored-1));
+				Assert(aHighBit);
+				list+=aHighBit;
+			}
+		}
+	}
+}
+
+static void
+AcrNEMA_FixFrameOfReferenceModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixFrameOfReferenceModule:" << endl;
+	// Frame of reference UID is taken care of in general dicom mx list stuff
+
+	{
+		Attribute *aPositionReferenceIndicator=list[TagFromName(PositionReferenceIndicator)];
+		if (!aPositionReferenceIndicator) {
+			aPositionReferenceIndicator=new LongStringAttribute(TagFromName(PositionReferenceIndicator));
+			Assert(aPositionReferenceIndicator);
+			list+=aPositionReferenceIndicator;
+		}
+	}
+}
+
+static void
+AcrNEMA_FixMRImageModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixMRImageModule:" << endl;
+	// Send dummy values for Type 1s and 2s ...
+
+	{
+		// Type 1
+		Attribute *aScanningSequence=list[TagFromName(ScanningSequence)];
+		if (!aScanningSequence) {
+			aScanningSequence=new CodeStringAttribute(TagFromName(ScanningSequence),"NONE");	// invalid enum :(
+			Assert(aScanningSequence);
+			list+=aScanningSequence;
+		}
+	}
+
+	{
+		// Type 1
+		Attribute *aSequenceVariant=list[TagFromName(SequenceVariant)];
+		if (!aSequenceVariant) {
+			aSequenceVariant=new CodeStringAttribute(TagFromName(SequenceVariant),"NONE");
+			Assert(aSequenceVariant);
+			list+=aSequenceVariant;
+		}
+	}
+
+	{
+		// Type 2
+		Attribute *aScanOptions=list[TagFromName(ScanOptions)];
+		if (!aScanOptions) {
+			aScanOptions=new CodeStringAttribute(TagFromName(ScanOptions));
+			Assert(aScanOptions);
+			list+=aScanOptions;
+		}
+	}
+
+	{
+		// Type 2
+		Attribute *aMRAcquisitionType=list[TagFromName(MRAcquisitionType)];
+		if (!aMRAcquisitionType) {
+			Attribute *aNumberOf3DRawPartitionsNominal=findPrivateAttribute(list,0x0021,"SIEMENS MR VA0  GEN",0x0030);
+
+			aMRAcquisitionType=new CodeStringAttribute(TagFromName(MRAcquisitionType));
+			Assert(aMRAcquisitionType);
+
+			if (aNumberOf3DRawPartitionsNominal) {
+				Uint16 vNumberOf3DRawPartitionsNominal = AttributeValue(aNumberOf3DRawPartitionsNominal);
+				aMRAcquisitionType->addValue(vNumberOf3DRawPartitionsNominal ? "3D" : "2D");
+			}
+			list+=aMRAcquisitionType;
+		}
+	}
+
+	{
+		// Type 2
+		Attribute *aEchoTrainLength=list[TagFromName(EchoTrainLength)];
+		if (!aEchoTrainLength) {
+			Attribute *aNumberOfEchoes=findPrivateAttribute(list,0x0021,"SIEMENS MR VA0  GEN",0x0070);
+			Uint16 vNumberOfEchoes = aNumberOfEchoes ? Uint16(AttributeValue(aNumberOfEchoes)) : 0;
+
+			// send 0 rather than zero length else AW gets upset
+
+			aEchoTrainLength=new IntegerStringAttribute(TagFromName(EchoTrainLength),vNumberOfEchoes);
+			Assert(aEchoTrainLength);
+			list+=aEchoTrainLength;
+		}
+	}
+
+	// Map some key optional values ...
+
+	{
+		Attribute *aFlipAngle=list[TagFromName(FlipAngle)];		// the DICOM attribute
+		if (aFlipAngle) {
+			list-=aFlipAngle;	// replace it to get rid of exponential notation (screws up AW)
+		}
+		else {
+			if (isPrivateCreatorPresent(list,0x0019,0x0010,"PHILIPS MR/PART"))
+				aFlipAngle=list[Tag(0x0019,0x101a)];			// Philips SPI MR - FFE Flip Angle
+			else
+				aFlipAngle=findPrivateAttribute(list,0x0019,"SIEMENS MR VA0  GEN",0x0060);
+		}
+
+		if (aFlipAngle) {
+			double vFlipAngle=AttributeValue(aFlipAngle);
+			aFlipAngle=new DecimalStringAttribute(TagFromName(FlipAngle),vFlipAngle);
+			Assert(aFlipAngle);
+			list+=aFlipAngle;
+		}
+	}
+
+	{
+		Attribute *aEchoTime=list[TagFromName(EchoTime)];		// the DICOM attribute
+		double vEchoTime;
+		if (aEchoTime) {
+			list-=aEchoTime;	// replace it to get rid of exponential notation (screws up AW)
+			double vEchoTime=AttributeValue(aEchoTime);
+			aEchoTime=new DecimalStringAttribute(TagFromName(EchoTime),vEchoTime);
+			Assert(aEchoTime);
+			list+=aEchoTime;
+		}
+	}
+
+	{
+		Attribute *aRepetitionTime=list[TagFromName(RepetitionTime)];		// the DICOM attribute
+		double vRepetitionTime;
+		if (aRepetitionTime) {
+			list-=aRepetitionTime;	// replace it to get rid of exponential notation (screws up AW)
+			double vRepetitionTime=AttributeValue(aRepetitionTime);
+			aRepetitionTime=new DecimalStringAttribute(TagFromName(RepetitionTime),vRepetitionTime);
+			Assert(aRepetitionTime);
+			list+=aRepetitionTime;
+		}
+	}
+
+	{
+		Attribute *aInversionTime=list[TagFromName(InversionTime)];		// the DICOM attribute
+		double vInversionTime;
+		if (aInversionTime) {
+			list-=aInversionTime;	// replace it to get rid of exponential notation (screws up AW)
+			double vInversionTime=AttributeValue(aInversionTime);
+			aInversionTime=new DecimalStringAttribute(TagFromName(InversionTime),vInversionTime);
+			Assert(aInversionTime);
+			list+=aInversionTime;
+		}
+	}
+
+	{
+		Attribute *aMagneticFieldStrength=list[TagFromName(MagneticFieldStrength)];		// the DICOM attribute
+		if (!aMagneticFieldStrength) {
+			aMagneticFieldStrength=findPrivateAttribute(list,0x0019,"SIEMENS MR VA0  COAD",0x0012);	// Siemens SPI MR is in Tesla
+			if (aMagneticFieldStrength) {
+				double vMagneticFieldStrength=AttributeValue(aMagneticFieldStrength);
+				aMagneticFieldStrength=new DecimalStringAttribute(TagFromName(MagneticFieldStrength),vMagneticFieldStrength);
+				Assert(aMagneticFieldStrength);
+				list+=aMagneticFieldStrength;
+			}
+		}
+	}
+
+	{
+		Attribute *aReconstructionDiameter=list[TagFromName(ReconstructionDiameter)];		// the DICOM attribute
+		if (!aReconstructionDiameter) {
+
+			Attribute *aPixelSpacing=list[TagFromName(PixelSpacing)];
+			Attribute *aRows=list[TagFromName(Rows)];
+			Attribute *aColumns=list[TagFromName(Columns)];
+
+			Uint16 vRows;
+			Uint16 vColumns;
+			unsigned vmPixelSpacing;
+			double vPixelSpacing_Row;
+			double vPixelSpacing_Column;
+
+			bool havespacingattributes = false;
+
+			if (aRows && aRows->getValue(0,vRows)
+			 && aColumns && aColumns->getValue(0,vColumns)
+			 && aPixelSpacing && (vmPixelSpacing=aPixelSpacing->getVM()) >= 1 && vmPixelSpacing <= 2) {
+				if (vmPixelSpacing == 1) {	// potentially common error
+cerr << "Warning - using single PixelSpacing value since two values not present" << endl;
+					(void)aPixelSpacing->getValue(0,vPixelSpacing_Row);
+					vPixelSpacing_Column=vPixelSpacing_Row;
+				}
+				else {
+					(void)aPixelSpacing->getValue(0,vPixelSpacing_Row);
+					(void)aPixelSpacing->getValue(1,vPixelSpacing_Column);
+				}
+				havespacingattributes=true;
+			}
+
+			// try to derive Reconstruction Diameter from Philips MR Private ...
+
+			Attribute *aFieldOfView=
+				isPrivateCreatorPresent(list,0x0019,0x0010,"PHILIPS MR/PART")
+				? list[Tag(0x0019,0x1000)] : 0;
+
+			if (aFieldOfView && aFieldOfView->getVM() == 1) {
+				//
+				// NB. Do not use when two values specifying
+				// rectangular FoV presumably.
+				//
+				double vReconstructionDiameter=AttributeValue(aFieldOfView);
+				aReconstructionDiameter=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),vReconstructionDiameter);
+				Assert(aReconstructionDiameter);
+				list+=aReconstructionDiameter;
+
+				// check for T5 Pixel Spacing bug (different values when should be the same) ...
+
+				if (havespacingattributes && vmPixelSpacing == 2
+				    && fabs(vPixelSpacing_Row-vPixelSpacing_Column) > .001		// two values different
+				    && fabs(vPixelSpacing_Row-vReconstructionDiameter/vColumns) < .001	// first value ==  FoV/columns
+				) {
+cerr << "Warning - PixelSpacing values different - replacing incorrect column dimension" << endl;
+					vPixelSpacing_Column=vPixelSpacing_Row;
+					list-=aPixelSpacing;
+					aPixelSpacing=new DecimalStringAttribute(TagFromName(PixelSpacing),vPixelSpacing_Row,vPixelSpacing_Column);
+					Assert(aPixelSpacing);
+					list+=aPixelSpacing;
+				}
+			}
+			else {
+				// derive Reconstruction Diameter from the Type 1 attributes, if they were present ...
+
+				if (havespacingattributes) {
+
+					// use average. though probably both row and col values identical ...
+
+					double vReconstructionDiameter=(vRows*vPixelSpacing_Row+vColumns*vPixelSpacing_Column)/2;
+
+					aReconstructionDiameter=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),vReconstructionDiameter);
+					Assert(aReconstructionDiameter);
+					list+=aReconstructionDiameter;
+				}
+			}
+		}
+	}
+	{
+		Attribute *aAcquisitionMatrix=list[TagFromName(AcquisitionMatrix)];
+		Attribute *aNumberOfPhaseEncodingSteps=list[TagFromName(NumberOfPhaseEncodingSteps)];
+		Attribute *aInPlanePhaseEncodingDirection=list[TagFromName(InPlanePhaseEncodingDirection)];
+		if (!aAcquisitionMatrix || !aNumberOfPhaseEncodingSteps || !aInPlanePhaseEncodingDirection) {
+			// derive from SPI Siemens MR Private ...
+
+			Attribute *aNumberOfFourierLinesNominal=
+				findPrivateAttribute(list,0x0019,"SIEMENS MR VA0  GEN",0x0020);
+			//Attribute *aAcquisitionColumns=
+			//	findPrivateAttribute(list,0x0019,"SIEMENS MR VA0  GEN",0x0030);
+			Attribute *aBaseRawMatrixSize=
+				findPrivateAttribute(list,0x0019,"SIEMENS MR VA0  COAD",0x00d4);
+			Attribute *aPhaseCodingDirection=
+				findPrivateAttribute(list,0x0019,"SIEMENS MR VA0  COAD",0x00da);
+			/* if (aNumberOfFourierLinesNominal && aAcquisitionColumns && aPhaseCodingDirection) { */
+			if (aNumberOfFourierLinesNominal && aBaseRawMatrixSize && aPhaseCodingDirection) {
+				char *vPhaseCodingDirection=AttributeValue(aPhaseCodingDirection);
+				Uint16 vNumberOfFourierLinesNominal=AttributeValue(aNumberOfFourierLinesNominal);
+				/* Uint16 vAcquisitionColumns=AttributeValue(aAcquisitionColumns); */
+				Uint16 vBaseRawMatrixSize=AttributeValue(aBaseRawMatrixSize);
+
+				Uint16 frequency_rows=0;					
+				Uint16 frequency_columns=0;
+				Uint16 phase_rows=0;
+				Uint16 phase_columns=0;
+				const char *phase_encoding_direction=0;
+
+				if (strcmp(vPhaseCodingDirection,"plusX") == 0 || strcmp(vPhaseCodingDirection,"minusX") == 0
+				 || strcmp(vPhaseCodingDirection,"PLUSX") == 0 || strcmp(vPhaseCodingDirection,"MINUSX") == 0) {
+					phase_encoding_direction="ROW";
+					frequency_columns=vNumberOfFourierLinesNominal;
+					/* phase_rows=vAcquisitionColumns; */
+					phase_rows=vBaseRawMatrixSize;
+				}
+				else if (strcmp(vPhaseCodingDirection,"plusY") == 0 || strcmp(vPhaseCodingDirection,"minusY") == 0
+				      || strcmp(vPhaseCodingDirection,"PLUSY") == 0 || strcmp(vPhaseCodingDirection,"MINUSY") == 0) {
+					phase_encoding_direction="COL";
+					frequency_rows=vNumberOfFourierLinesNominal;					
+					/* phase_columns=vAcquisitionColumns; */
+					phase_columns=vBaseRawMatrixSize;
+				}
+
+				if (!aAcquisitionMatrix && (frequency_rows || frequency_columns || phase_rows || phase_columns)) {
+					aAcquisitionMatrix=new UnsignedShortAttribute(TagFromName(AcquisitionMatrix));
+					Assert(aAcquisitionMatrix);
+					aAcquisitionMatrix->addValue(frequency_rows);
+					aAcquisitionMatrix->addValue(frequency_columns);
+					aAcquisitionMatrix->addValue(phase_rows);
+					aAcquisitionMatrix->addValue(phase_columns);
+					list+=aAcquisitionMatrix;
+				}
+
+				if (!aNumberOfPhaseEncodingSteps && vBaseRawMatrixSize)
+					list+=new IntegerStringAttribute(TagFromName(NumberOfPhaseEncodingSteps),vBaseRawMatrixSize);
+
+				if (!aInPlanePhaseEncodingDirection && phase_encoding_direction)
+					list+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),phase_encoding_direction);
+			}
+		}
+	}
+
+	{
+		Attribute *aTriggerTime=list[TagFromName(TriggerTime)];
+		if (!aTriggerTime && isPrivateCreatorPresent(list,0x0019,0x0010,"PHILIPS MR/PART")) {
+			aTriggerTime=list[Tag(0x0019,0x106e)];			// Philips SPI MR - Trigger Delay Time
+			if (aTriggerTime) {
+				double vTriggerTime=AttributeValue(aTriggerTime);
+				aTriggerTime=new DecimalStringAttribute(TagFromName(TriggerTime),vTriggerTime);
+				Assert(aTriggerTime);
+				list+=aTriggerTime;
+			}
+		}
+	}
+
+	{
+		Attribute *aAcquisitionDuration=list[TagFromName(AcquisitionDuration)];
+		if (!aAcquisitionDuration) {
+			if (isPrivateCreatorPresent(list,0x2005,0x0010,"Philips MR Imaging DD 001")) {
+				aAcquisitionDuration=list[Tag(0x2005,0x1033)];
+				if (aAcquisitionDuration) {
+					double vAcquisitionDuration=AttributeValue(aAcquisitionDuration);
+					aAcquisitionDuration=new FloatDoubleAttribute(TagFromName(AcquisitionDuration),vAcquisitionDuration);
+					Assert(aAcquisitionDuration);
+					list+=aAcquisitionDuration;
+				}
+			}
+			else if (isPrivateCreatorPresent(list,0x0019,0x0010,"GEMS_ACQU_01")) {
+				aAcquisitionDuration=list[Tag(0x0019,0x105a)];
+				if (aAcquisitionDuration) {
+					double vAcquisitionDuration=double(AttributeValue(aAcquisitionDuration))/1000000.0;		// seems to be in microseconds and we need seconds
+					if (vAcquisitionDuration >= 0) {		// sometimes observed to be -ve and hence presumably meaningless
+						aAcquisitionDuration=new FloatDoubleAttribute(TagFromName(AcquisitionDuration),vAcquisitionDuration);
+						Assert(aAcquisitionDuration);
+						list+=aAcquisitionDuration;
+					}
+				}
+			}
+		}
+	}
+
+#ifdef CRAP
+		Element <SequenceName> not present
+		Element <AngioFlag> not present
+		Element <MagneticFieldStrength> not present
+		Element <SpacingBetweenSlices> not present
+		Element <NumberOfPhaseEncodingSteps> not present
+		Element <PercentSampling> not present
+		Element <PercentPhaseFieldOfView> not present
+		Element <PixelBandwidth> not present
+		Element <NominalInterval> not present
+		Element <BeatRejectionFlag> not present
+		Element <LowRRValue> not present
+		Element <HighRRValue> not present
+		Element <IntervalsAcquired> not present
+		Element <IntervalsRejected> not present
+		Element <PVCRejection> not present
+		Element <SkipBeats> not present
+		Element <HeartRate> not present
+		Element <CardiacNumberOfImages> not present
+		Element <TriggerWindow> not present
+		Element <ReconstructionDiameter> not present
+		Element <TransmittingCoil> not present
+		Element <AcquisitionMatrix> not present
+		Element <InPlanePhaseEncodingDirection> not present
+		Element <SAR> not present
+		Element <VariableFlipAngleFlag> not present
+		Element <dBdt> not present
+		Element <TemporalPositionIdentifier> not present
+		Element <NumberOfTemporalPositions> not present
+		Element <TemporalResolution> not present
+#endif
+}
+
+static void
+AcrNEMA_FixCTImageModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixCTImageModule:" << endl;
+
+	{
+		Attribute *aExposure=list[TagFromName(Exposure)];
+		Uint32 vExposure=AttributeValue(aExposure);
+		Attribute *aExposureInuAs=list[TagFromName(ExposureInuAs)];
+		Uint32 vExposureInuAs=AttributeValue(aExposureInuAs);
+		Attribute *aExposureTime=list[TagFromName(ExposureTime)];
+		Uint32 vExposureTime=AttributeValue(aExposureTime);
+		Attribute *aXRayTubeCurrent=list[TagFromName(XRayTubeCurrent)];
+		Uint32 vXRayTubeCurrent=AttributeValue(aXRayTubeCurrent);
+
+		if (aExposure && !aExposureInuAs) {
+			vExposureInuAs=vExposure*1000;
+			aExposureInuAs=new IntegerStringAttribute(TagFromName(ExposureInuAs),vExposureInuAs);
+			Assert(aExposureInuAs);
+			list+=aExposureInuAs;
+		}
+		else if (aExposureInuAs && !aExposure) {
+			vExposure=vExposureInuAs/1000;
+			aExposure=new IntegerStringAttribute(TagFromName(Exposure),vExposure);
+			Assert(aExposure);
+			list+=aExposure;
+		}
+
+		if (aExposureInuAs && aExposureTime && !aXRayTubeCurrent) {
+			vXRayTubeCurrent=vExposureInuAs/vExposureTime;
+			aXRayTubeCurrent=new IntegerStringAttribute(TagFromName(XRayTubeCurrent),vXRayTubeCurrent);
+			Assert(aXRayTubeCurrent);
+			list+=aXRayTubeCurrent;
+		}
+		else if (aExposureInuAs && !aExposureTime && aXRayTubeCurrent) {
+			vExposureTime=vExposureInuAs/vXRayTubeCurrent;
+			aExposureTime=new IntegerStringAttribute(TagFromName(ExposureTime),vExposureTime);
+			Assert(aExposureTime);
+			list+=aExposureTime;
+		}
+		else if (!aExposureInuAs && aExposureTime && aXRayTubeCurrent) {
+			vExposureInuAs=vExposureTime*vXRayTubeCurrent;
+			aExposureInuAs=new IntegerStringAttribute(TagFromName(ExposureInuAs),vExposureInuAs);
+			Assert(aExposureInuAs);
+			list+=aExposureInuAs;
+
+			vExposure=vExposureInuAs/1000;
+			aExposure=new IntegerStringAttribute(TagFromName(Exposure),vExposure);
+			Assert(aExposure);
+			list+=aExposure;
+		}
+	}
+
+	// fix some Somatom files that have rescale slope/intercept
+	// values padded to more than allowed 16 characters for VR ...
+
+	{
+		Attribute *aRescaleSlope=list[TagFromName(RescaleSlope)];
+		if (aRescaleSlope && aRescaleSlope->getVM() > 0) {
+			double vRescaleSlope=AttributeValue(aRescaleSlope);
+			list-=aRescaleSlope;
+			aRescaleSlope=new DecimalStringAttribute(TagFromName(RescaleSlope),vRescaleSlope);
+			Assert(aRescaleSlope);
+			list+=aRescaleSlope;
+		}
+	}
+	{
+		Attribute *aRescaleIntercept=list[TagFromName(RescaleIntercept)];
+		if (aRescaleIntercept && aRescaleIntercept->getVM() > 0) {
+			double vRescaleIntercept=AttributeValue(aRescaleIntercept);
+			list-=aRescaleIntercept;
+			aRescaleIntercept=new DecimalStringAttribute(TagFromName(RescaleIntercept),vRescaleIntercept);
+			Assert(aRescaleIntercept);
+			list+=aRescaleIntercept;
+		}
+	}
+	
+	// Extract additional attributes for helical scanners
+	
+	{
+
+		Attribute *aRevolutionTime=list[TagFromName(RevolutionTime)];
+		if (!aRevolutionTime) {
+			aRevolutionTime=findPrivateAttribute(list,0x0019,"GEMS_ACQU_01",0x1027);	// GEMS - RotationSpeed
+			if (aRevolutionTime) {
+				double vRevolutionTime=AttributeValue(aRevolutionTime);
+				if (vRevolutionTime > 10 ) {						// DICOM value is seconds, GE's is (supposedly) msec
+					vRevolutionTime/=1000.0;					// but GE seems to actually encode as seconds
+				}
+//cerr << "vRevolutionTime=" << vRevolutionTime << endl;
+				aRevolutionTime=new FloatDoubleAttribute(TagFromName(RevolutionTime),vRevolutionTime);
+				Assert(aRevolutionTime);
+				list+=aRevolutionTime;
+			}
+			else {
+				aRevolutionTime=findPrivateAttribute(list,0x01f1,"ELSCINT1",0x1027);	// Elscint - Rotation Time
+				double vRevolutionTime=AttributeValue(aRevolutionTime);
+				aRevolutionTime=new FloatDoubleAttribute(TagFromName(RevolutionTime),vRevolutionTime);
+				Assert(aRevolutionTime);
+				list+=aRevolutionTime;
+			}
+		}
+	
+		Attribute *aTableFeedPerRotation=list[TagFromName(TableFeedPerRotation)];
+		if (!aTableFeedPerRotation) {
+			aTableFeedPerRotation=findPrivateAttribute(list,0x0019,"GEMS_ACQU_01",0x1023);	// GEMS - Table Speed [mm/rotation]
+			if (!aTableFeedPerRotation) {
+				aTableFeedPerRotation=findPrivateAttribute(list,0x0019,"SIEMENS CT VA0  COAD",0x10b0);	// Siemens - Feed per Rotation [mm/rotation]
+			}
+			if (aTableFeedPerRotation) {
+				double vTableFeedPerRotation=AttributeValue(aTableFeedPerRotation);
+//cerr << "vTableFeedPerRotation=" << vTableFeedPerRotation << endl;
+				aTableFeedPerRotation=new FloatDoubleAttribute(TagFromName(TableFeedPerRotation),vTableFeedPerRotation);
+				Assert(aTableFeedPerRotation);
+				list+=aTableFeedPerRotation;
+			}
+		}
+		
+		Attribute *aTableSpeed=list[TagFromName(TableSpeed)];
+		if (!aTableSpeed && aRevolutionTime && aTableFeedPerRotation) {
+			double vRevolutionTime=AttributeValue(aRevolutionTime);				// seconds/rotation
+			if (vRevolutionTime > 0) {
+				double vTableFeedPerRotation=AttributeValue(aTableFeedPerRotation);	// mm/rotation
+				double vTableSpeed = vTableFeedPerRotation/vRevolutionTime;		// mm/second
+//cerr << "vTableSpeed=" << vTableSpeed << endl;
+				aTableSpeed=new FloatDoubleAttribute(TagFromName(TableSpeed),vTableSpeed);
+				Assert(aTableSpeed);
+				list+=aTableSpeed;
+			}
+		}
+		
+		Attribute *aSpiralPitchFactor=list[TagFromName(SpiralPitchFactor)];
+		if (!aSpiralPitchFactor) {
+			aSpiralPitchFactor=findPrivateAttribute(list,0x0043,"GEMS_PARM_01",0x1027);	// GEMS - Scan Pitch Ratio, e.g. "0.562:1"
+			char *sSpiralPitchFactor=AttributeValue(aSpiralPitchFactor);
+			if (sSpiralPitchFactor && strlen(sSpiralPitchFactor) > 0) {
+//cerr << "sSpiralPitchFactor=" << sSpiralPitchFactor << endl;
+				double vSpiralPitchFactor=0;
+				if (strcmp(sSpiralPitchFactor,"HQ") == 0) {
+					vSpiralPitchFactor=3;				// High quality
+				}
+				else if (strcmp(sSpiralPitchFactor,"HS") == 0) {
+					vSpiralPitchFactor=6;				// High speed
+				}
+				else {
+					if (*sSpiralPitchFactor == '/') {
+						++sSpiralPitchFactor;			// e.g. skip the slash in "/1.4:1"
+					}
+					char *colonIndex = strchr(sSpiralPitchFactor,':');
+					if (colonIndex) {
+						*colonIndex=0;
+					}
+					vSpiralPitchFactor=strtod(sSpiralPitchFactor,NULL);
+				}
+//cerr << "vSpiralPitchFactor=" << vSpiralPitchFactor << endl;
+				aSpiralPitchFactor=new FloatDoubleAttribute(TagFromName(SpiralPitchFactor),vSpiralPitchFactor);
+				Assert(aSpiralPitchFactor);
+				list+=aSpiralPitchFactor;
+			}
+			else {
+				aSpiralPitchFactor=NULL;
+			}
+		}
+		
+		Attribute *aTotalCollimationWidth=list[TagFromName(TotalCollimationWidth)];
+		if (!aTotalCollimationWidth && aTableFeedPerRotation && aSpiralPitchFactor) {
+			double vTableFeedPerRotation=AttributeValue(aTableFeedPerRotation);		// mm/rotation
+			double vSpiralPitchFactor=AttributeValue(aSpiralPitchFactor);			// 1/rotation
+			double vTotalCollimationWidth = vTableFeedPerRotation/vSpiralPitchFactor;	// mm
+//cerr << "vTotalCollimationWidth=" << vTotalCollimationWidth << endl;
+			aTotalCollimationWidth=new FloatDoubleAttribute(TagFromName(TotalCollimationWidth),vTotalCollimationWidth);
+			Assert(aTotalCollimationWidth);
+			list+=aTotalCollimationWidth;
+		}
+		
+		Attribute *aSingleCollimationWidth=list[TagFromName(SingleCollimationWidth)];
+		if (!aSingleCollimationWidth && aTotalCollimationWidth) {
+			Attribute *aNumberOfDetectors=findPrivateAttribute(list,0x0045,"GEMS_HELIOS_01",0x1001);	// GEMS - Number of Macro Rows in Detector
+			if (aNumberOfDetectors) {
+				double vNumberOfDetectors=AttributeValue(aNumberOfDetectors);
+//cerr << "vNumberOfDetectors=" << vNumberOfDetectors << endl;
+				if (vNumberOfDetectors > 0) {
+					double vTotalCollimationWidth = AttributeValue(aTotalCollimationWidth);		// mm
+					double vSingleCollimationWidth = vTotalCollimationWidth/vNumberOfDetectors;	// mm
+//cerr << "vSingleCollimationWidth=" << vSingleCollimationWidth << endl;
+					aSingleCollimationWidth=new FloatDoubleAttribute(TagFromName(SingleCollimationWidth),vSingleCollimationWidth);
+					Assert(aSingleCollimationWidth);
+					list+=aSingleCollimationWidth;
+				}
+			}
+		}
+		
+		Attribute *aReconstructionAngle=list[TagFromName(ReconstructionAngle)];
+		if (!aReconstructionAngle) {
+			Attribute *aScanArc=list[TagFromName(ScanArc)];			// a nuclear medicine tomo attribute used by Elscint CT
+			if (aScanArc) {
+				double vScanArc=AttributeValue(aScanArc);
+				aReconstructionAngle=new FloatDoubleAttribute(TagFromName(ReconstructionAngle),vScanArc);
+				Assert(aReconstructionAngle);
+				list+=aReconstructionAngle;
+			}
+		}
+		
+	}
+}
+
+static void
+AcrNEMA_FixPatientModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixPatientModule:" << endl;
+	{
+		Attribute *aPatientBirthDate=list[TagFromName(PatientBirthDate)];	// Type 2, may be old date format
+
+		char *vPatientBirthDate=0;
+		if (aPatientBirthDate) {
+			aPatientBirthDate->getValue(0,vPatientBirthDate);
+			list-=TagFromName(PatientBirthDate);				// Replaced later
+		}
+
+		if (vPatientBirthDate)
+			aPatientBirthDate=new DateStringAttribute(TagFromName(PatientBirthDate),Date(vPatientBirthDate,DateOrderMonthMiddleYearFirst));
+		else
+			aPatientBirthDate=new DateStringAttribute(TagFromName(PatientBirthDate));
+		Assert(aPatientBirthDate);
+		list+=aPatientBirthDate;
+	}
+}
+
+static void
+AcrNEMA_FixGeneralStudyModuleAfterGeneralSeriesModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixGeneralStudyModuleAfterGeneralSeriesModule:" << endl;
+
+	// If study id is absent, there is a risk that two studies
+	// that are actually different will collide (and get the
+	// same UID if using the same -stamp in the same translation
+	// session). Use date/time to try to avoid this.
+
+	{
+		Attribute *aStudyID=list[TagFromName(StudyID)];
+
+		if (!aStudyID || aStudyID->getVL() == 0) {
+
+			if (aStudyID) {
+				list-=TagFromName(StudyID); 
+			}
+
+			char *vStudyDate=0;
+			Attribute *aStudyDate=list[TagFromName(StudyDate)];
+			if (aStudyDate && aStudyDate->getVL() != 0) {
+				aStudyDate->getValue(0,vStudyDate);
+			}
+			char *vStudyTime=0;
+			Attribute *aStudyTime=list[TagFromName(StudyTime)];
+			if (aStudyTime && aStudyTime->getVL() != 0) {
+				aStudyTime->getValue(0,vStudyTime);
+			}
+			ostrstream oStudyID;
+			oStudyID << (vStudyDate ? vStudyDate : "") << (vStudyTime ? vStudyTime : "") << ends;
+			char *vStudyID = oStudyID.str();
+
+			// clean out any punctuation ...
+
+			char *src,*dst;
+			for (src=vStudyID,dst=vStudyID; *src; ++src) if (isalnum(*src)) *dst++=*src;
+			*dst=0;
+
+			// limit to 16 characters max ... (not including trailing \0)
+
+			if (strlen(vStudyID) > 16) vStudyID[16]=0;
+
+			aStudyID=new ShortStringAttribute(TagFromName(StudyID),vStudyID);
+			Assert(aStudyID);
+			list+=aStudyID;
+		}
+	}
+}
+
+static void
+AcrNEMA_FixGeneralSeriesModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixGeneralSeriesModule:" << endl;
+
+	// If series number is absent, use:
+	// - the leading numeric part of the study ID, for Siemens images of all modalities
+	// - the acquisition number, for Philips MR images (also in the case of Series Number == 1)
+	// - else zero
+
+	{
+		bool useStudyID=false;
+		bool useAcquisitionNumber=false;
+
+		Attribute *aSeriesNumber=list[TagFromName(SeriesNumber)];
+		Uint32 vSeriesNumber=0;					// 0 is flag that none was found or was zero length
+		if (aSeriesNumber) {
+			if (aSeriesNumber->getVL() > 0)
+				aSeriesNumber->getValue(0,vSeriesNumber);
+			list-=TagFromName(SeriesNumber); 
+		}
+
+		Attribute *aModality=list[TagFromName(Modality)];
+		char *vModality=0;
+		if (aModality && aModality->getVL() > 0)
+			(void)aModality->getValue(0,vModality);
+
+		Attribute *aManufacturer=list[TagFromName(Manufacturer)];
+		char *vManufacturer=0;
+		if (aManufacturer && aManufacturer->getVL() > 0)
+			(void)aManufacturer->getValue(0,vManufacturer);
+
+		Attribute *aAcquisitionNumber=list[TagFromName(AcquisitionNumber)];
+		char *vAcquisitionNumber=0;
+		Uint32 nAcquisitionNumber=0;
+		if (aAcquisitionNumber && aAcquisitionNumber->getVL() > 0) {
+			(void)aAcquisitionNumber->getValue(0,vAcquisitionNumber);
+			if (vAcquisitionNumber && *vAcquisitionNumber && isdigit(*vAcquisitionNumber)) {
+				//istrstream istrAcquisitionNumber(vAcquisitionNumber);
+				//istrAcquisitionNumber >> nAcquisitionNumber;
+				nAcquisitionNumber=atol(vAcquisitionNumber);
+//cerr << "AcquisitionNumber leading numeric part=" << nAcquisitionNumber << endl;
+			}
+		}
+
+		Attribute *aStudyID=list[TagFromName(StudyID)];
+		char *vStudyID=0;
+		Uint32 nStudyID=0;
+		if (aStudyID && aStudyID->getVL() > 0) {
+			(void)aStudyID->getValue(0,vStudyID);
+			if (vStudyID && *vStudyID && isdigit(*vStudyID)) {
+				//istrstream istrStudyID(vStudyID);
+				//istrStudyID >> nStudyID;
+				nStudyID=atol(vStudyID);
+//cerr << "StudyID leading numeric part=" << nStudyID << endl;
+			}
+		}
+
+		// use Study ID for all Siemens MR if no Series Number
+
+		if (vStudyID && *vStudyID && isdigit(*vStudyID)
+		 && !vSeriesNumber
+		 && vManufacturer && *vManufacturer && strcmp(vManufacturer,"SIEMENS") == 0
+		 && vModality && *vModality && strcmp(vModality,"MR") == 0) {
+			useStudyID=true;
+		}
+
+		// use Acquisition Number for all Siemens CT if no Series Number,
+		// or is 1 and Acquisition Number is "reasonably" low
+
+		if (vAcquisitionNumber && *vAcquisitionNumber
+		 && (!vSeriesNumber || (vSeriesNumber == 1 && nAcquisitionNumber < 100))
+		 && vManufacturer && *vManufacturer && strcmp(vManufacturer,"SIEMENS") == 0
+		 && vModality && *vModality && strcmp(vModality,"CT") == 0) {
+			useAcquisitionNumber=true;
+		}
+
+		// use Acquisition Number for all Philips MR if no Series Number or is 1
+
+		if (vAcquisitionNumber && *vAcquisitionNumber
+		 && (!vSeriesNumber || vSeriesNumber == 1)
+		 && vManufacturer && *vManufacturer && strcmp(vManufacturer,"Philips Medical Systems") == 0
+		 && vModality && *vModality && strcmp(vModality,"MR") == 0) {
+			useAcquisitionNumber=true;
+		}
+
+		// getting desperate ... using anything we can find ...
+
+		if (!useStudyID && !useAcquisitionNumber && !vSeriesNumber) {
+			if (vAcquisitionNumber && *vAcquisitionNumber) {
+				useAcquisitionNumber=true;
+			}
+			else if (vStudyID && *vStudyID && isdigit(*vStudyID)) {
+				useStudyID=true;
+			}
+		}
+				
+		Assert(!(useStudyID && useAcquisitionNumber));
+
+		if (useStudyID) {
+			vSeriesNumber=nStudyID;
+//cerr << "Using StudyID vSeriesNumber" << vSeriesNumber << endl;
+		}
+		else if (useAcquisitionNumber) {
+			vSeriesNumber=nAcquisitionNumber;
+//cerr << "Using AcquisitionNumber vSeriesNumber" << vSeriesNumber << endl;
+		}
+
+		{
+			// Philips MR mixes multiple dynamic scans with same Slice Number
+			// in single Acquisition Number ... make into separate series 
+
+			Attribute *aDynamicScanNumber=
+				isPrivateCreatorPresent(list,0x0021,0x0010,"PHILIPS MR/PART")
+				? list[Tag(0x0021,0x1050)] : 0;
+
+			Uint16 nDynamicScanNumber;
+
+			Attribute *aNumberOfScans=
+				isPrivateCreatorPresent(list,0x0019,0x0010,"PHILIPS MR/PART")
+				? list[Tag(0x0019,0x101b)] : 0;
+			
+			Uint16 nNumberOfScans;
+
+			if (aDynamicScanNumber && aDynamicScanNumber->getValue(0,nDynamicScanNumber) && nDynamicScanNumber
+			 && aNumberOfScans && aNumberOfScans->getValue(0,nNumberOfScans) && nNumberOfScans > 1
+			) {
+				vSeriesNumber=vSeriesNumber*1000+nDynamicScanNumber;
+			}
+		}
+
+		aSeriesNumber=new IntegerStringAttribute(TagFromName(SeriesNumber),vSeriesNumber);
+		Assert(aSeriesNumber);
+		list+=aSeriesNumber;
+	}
+
+	// copy study into series date/time/description if series level absent
+
+	{
+		Attribute *aSeriesDate=list[TagFromName(SeriesDate)];
+
+		if (!aSeriesDate || aSeriesDate->getVL() == 0) {
+			
+			Attribute *aStudyDate=list[TagFromName(StudyDate)];
+
+			if (aStudyDate && aStudyDate->getVL() != 0) {
+				char *vStudyDate=0;
+				aStudyDate->getValue(0,vStudyDate);
+
+				if (aSeriesDate) {
+					list-=TagFromName(SeriesDate); 
+				}
+
+				aSeriesDate=new DateStringAttribute(TagFromName(SeriesDate),vStudyDate);
+				Assert(aSeriesDate);
+				list+=aSeriesDate;
+			}
+
+		}
+	}
+
+	{
+		Attribute *aSeriesTime=list[TagFromName(SeriesTime)];
+
+		if (!aSeriesTime || aSeriesTime->getVL() == 0) {
+			
+			Attribute *aStudyTime=list[TagFromName(StudyTime)];
+
+			if (aStudyTime && aStudyTime->getVL() != 0) {
+				char *vStudyTime=0;
+				aStudyTime->getValue(0,vStudyTime);
+
+				if (aSeriesTime) {
+					list-=TagFromName(SeriesTime); 
+				}
+
+				aSeriesTime=new TimeStringAttribute(TagFromName(SeriesTime),vStudyTime);
+				Assert(aSeriesTime);
+				list+=aSeriesTime;
+			}
+
+		}
+	}
+
+	{
+		Attribute *aSeriesDescription=list[TagFromName(SeriesDescription)];
+
+		if (!aSeriesDescription || aSeriesDescription->getVL() == 0) {
+			
+			Attribute *aStudyDescription=list[TagFromName(StudyDescription)];
+
+			if (aStudyDescription && aStudyDescription->getVL() != 0) {
+				char *vStudyDescription=0;
+				aStudyDescription->getValue(0,vStudyDescription);
+
+				if (aSeriesDescription) {
+					list-=TagFromName(SeriesDescription); 
+				}
+
+				aSeriesDescription=new LongStringAttribute(TagFromName(SeriesDescription),vStudyDescription);
+				Assert(aSeriesDescription);
+				list+=aSeriesDescription;
+			}
+
+		}
+	}
+
+}
+
+static void
+AcrNEMA_FixGeneralImageModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixGeneralImageModule:" << endl;
+	// If image (instance) number is absent, try and find a private attribute
+	// to use
+
+	{
+		Attribute *aInstanceNumber=list[TagFromName(InstanceNumber)];
+
+		// Always read Instance Number and rewrite ...
+		// (in case non-numeric trailing in some old Philips MR)
+
+		Uint32 vInstanceNumber = 0;						// Defaults to zero rather than absent or zero length
+
+		if (aInstanceNumber) {
+			if (aInstanceNumber->getVL() > 0) {
+				char  *sInstanceNumber = 0;
+				if (aInstanceNumber->getValue(0,sInstanceNumber)) {
+					Assert(sInstanceNumber);
+					vInstanceNumber=atoi(sInstanceNumber);		// extracts leading numeric part
+					if (sInstanceNumber) delete[] sInstanceNumber;	// was a copy
+				}
+			}
+			list-=TagFromName(InstanceNumber);
+		}
+
+		// Always replace Instance Number with Philips MR Slice Number if present ...
+
+		Attribute *aSliceNumber=
+				isPrivateCreatorPresent(list,0x0021,0x0010,"PHILIPS MR/PART")
+				? list[Tag(0x0021,0x1020)] : 0;
+
+		Uint32 vSliceNumber;
+			
+		if (aSliceNumber && aSliceNumber->getValue(0,vSliceNumber)) {
+			vInstanceNumber=vSliceNumber;
+		}
+
+		aInstanceNumber=new IntegerStringAttribute(TagFromName(InstanceNumber),vInstanceNumber);	// may be zero
+		Assert(aInstanceNumber);
+		list+=aInstanceNumber;
+	}
+
+	{
+		Attribute *aImageType=list[TagFromName(ImageType)];
+		if (!aImageType) {
+			aImageType=new CodeStringAttribute(TagFromName(ImageType));
+			Assert(aImageType);
+			aImageType->addValue("ORIGINAL");
+			aImageType->addValue("PRIMARY");
+			aImageType->addValue("UNKNOWN");
+			list+=aImageType;
+		}
+	}
+	
+	{
+		// if GE CT Delta Start Time is present, add it to Acquisition Time (which is constant for all images in acquisition)
+		
+		Attribute *aDeltaStartTime=
+			isPrivateCreatorPresent(list,0x0043,0x0010,"GEMS_PARM_01")
+			? list[Tag(0x0043,0x101e)] : 0;
+		double vDeltaStartTime=0;
+		if (aDeltaStartTime && aDeltaStartTime->getValue(0,vDeltaStartTime)) {
+			vDeltaStartTime*=1000;		// delta start time is in seconds (confirmed by GE, though some conformance statements erroneously claim milliseconds)
+			Attribute *aAcquisitionTime=list[TagFromName(AcquisitionTime)];
+			char *vAcquisitionTime=0;
+			if (aAcquisitionTime && aAcquisitionTime->getVL() != 0 && aAcquisitionTime->getValue(0,vAcquisitionTime) && vAcquisitionTime && strlen(vAcquisitionTime)) {
+				Uint32 uAcquisitionTime=Uint32(Time(vAcquisitionTime)) + Uint32(vDeltaStartTime);	// all in milliseconds
+				list-=TagFromName(AcquisitionTime);
+				list+=new TimeStringAttribute(TagFromName(AcquisitionTime),Time(uAcquisitionTime));
+			}
+		}
+	}
+}
+
+static void
+AcrNEMA_FixVOILUTModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixVOILUTModule:" << endl;
+
+	// If Window Center or Width are zero length, remove them
+
+	Attribute *aWindowCenter=list[TagFromName(WindowCenter)];
+	if (aWindowCenter && aWindowCenter->getVL() == 0) list-=aWindowCenter;
+
+	Attribute *aWindowWidth=list[TagFromName(WindowWidth)];
+	if (aWindowWidth && aWindowWidth->getVL() == 0) list-=aWindowWidth;
+}
+
+static void
+AcrNEMA_FixOverlayModule(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixOverlayModule:" << endl;
+
+	Uint16 group;
+	for (group=0x6000; group <= 0x601e; group+=2) {
+		Tag tOverlayRows=Tag(group,0x0010);
+		Tag tOverlayColumns=Tag(group,0x0011);
+		Tag tOverlayType=Tag(group,0x0040);
+		Tag tOverlayOrigin=Tag(group,0x0050);
+		Tag tOverlayBitsAllocated=Tag(group,0x0100);
+		Tag tOverlayBitPosition=Tag(group,0x0102);
+		Tag tOverlayLocation=Tag(group,0x0200);
+		Tag tOverlayData=Tag(group,0x3000);
+
+		Attribute *aOverlayRows=list[tOverlayRows];
+		Attribute *aOverlayColumns=list[tOverlayColumns];
+		Attribute *aOverlayType=list[tOverlayType];
+		Attribute *aOverlayOrigin=list[tOverlayOrigin];
+		Attribute *aOverlayBitsAllocated=list[tOverlayBitsAllocated];
+		Attribute *aOverlayBitPosition=list[tOverlayBitPosition];
+		Attribute *aOverlayLocation=list[tOverlayLocation];		// not in DICOM
+		Attribute *aOverlayData=list[tOverlayData];
+
+		if (aOverlayRows || aOverlayColumns || aOverlayType || aOverlayOrigin
+		 || aOverlayBitsAllocated || aOverlayBitPosition || aOverlayLocation
+		 || aOverlayData) {
+
+			// we have an overlay
+
+			if (!aOverlayRows) {
+				Attribute *aRows=list[TagFromName(Rows)];
+				Uint16 vRows;
+				if (aRows && aRows->getValue(0,vRows)) {
+					aOverlayRows=new UnsignedShortAttribute(tOverlayRows,vRows);
+					list+=aOverlayRows;
+				}
+			}
+			if (!aOverlayColumns) {
+				Attribute *aColumns=list[TagFromName(Columns)];
+				Uint16 vColumns;
+				if (aColumns && aColumns->getValue(0,vColumns)) {
+					aOverlayColumns=new UnsignedShortAttribute(tOverlayColumns,vColumns);
+					list+=aOverlayColumns;
+				}
+			}
+			if (!aOverlayBitsAllocated) {
+				if (!aOverlayData) {
+					Attribute *aBitsAllocated=list[TagFromName(BitsAllocated)];
+					Uint16 vBitsAllocated;
+					if (aBitsAllocated && aBitsAllocated->getValue(0,vBitsAllocated)) {
+						aOverlayBitsAllocated=new UnsignedShortAttribute(tOverlayBitsAllocated,vBitsAllocated);
+						list+=aOverlayBitsAllocated;
+					}
+				}
+				// else don't really know what to do ... use 1 ?
+			}
+			if (!aOverlayOrigin) {
+				aOverlayOrigin=new SignedShortAttribute(tOverlayOrigin);
+				aOverlayOrigin->addValue(Uint16(1));
+				aOverlayOrigin->addValue(Uint16(1));
+				list+=aOverlayOrigin;
+			}
+		}
+	}
+}
+
+static void
+AcrNEMA_FixAllTimes(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMA_FixAllTimes:" << endl;
+
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+
+		Tag tag=a->getTag();
+
+		const char *vr=a->getVR();
+		Assert(vr);
+
+		if (strcmp(vr,"TM") == 0) {
+			char *v=0;
+			if (a && a->getValue(0,v) && v) {
+
+//cerr << "AcrNEMA_FixAllTimes: old string " << v << endl;
+
+				Time t(v);
+
+//cerr << "AcrNEMA_FixAllTimes: time isgood " << (t.isgood() ? "t" : "f") << endl;
+
+				// following is from attrtypd.cc (should really be method in Time class :( )
+
+				ostrstream ost;
+				ost << dec << setfill('0');
+				if (t.isgood()) {
+					ost << setw(2) << t.getHour()
+					    << setw(2) << t.getMinute()
+					    << setw(2) << t.getSecond();
+					if (t.getMilliSecond())
+						ost << '.' << setw(3) << t.getMilliSecond();
+				}
+				ost << ends;
+				char *s = ost.str();
+
+//cerr << "AcrNEMA_FixAllTimes: new string " << s << endl;
+
+				a->setValue(0,s);
+				if (s) delete[] s;
+			}
+			if (v) delete[] v;
+		}
+
+		++listi;
+	}
+}
+
+
+
+static void
+AcrNEMAorSPItoDICOM(ManagedAttributeList &list)
+{
+//cerr << "AcrNEMAorSPItoDICOM:" << endl;
+	AcrNEMA_FixPatientModule(list);
+	AcrNEMA_FixGeneralSeriesModule(list);
+	AcrNEMA_FixGeneralStudyModuleAfterGeneralSeriesModule(list);
+	AcrNEMA_FixGeneralImageModule(list);
+	AcrNEMA_FixImagePixelModule(list);
+
+	char *vModality=AttributeValue(list[TagFromName(Modality)]);
+
+	if (vModality && (strcmp(vModality,"MR") == 0 || strcmp(vModality,"CT") == 0)) {
+		AcrNEMA_FixImagePlaneModule(list);
+		AcrNEMA_FixFrameOfReferenceModule(list);
+	}
+	if (vModality && strcmp(vModality,"MR") == 0) {
+		AcrNEMA_FixMRImageModule(list);
+	}
+	if (vModality && strcmp(vModality,"CT") == 0) {
+		AcrNEMA_FixCTImageModule(list);
+	}
+
+	AcrNEMA_FixLaterality(list);
+	AcrNEMA_FixVOILUTModule(list);
+	AcrNEMA_FixOverlayModule(list);
+
+	AcrNEMA_FixAllTimes(list);
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		log << list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		AcrNEMAorSPItoDICOM(list);
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/antodc.man b/appsrc/dcfile/antodc.man
new file mode 100755
index 0000000..23ed273
--- /dev/null
+++ b/appsrc/dcfile/antodc.man
@@ -0,0 +1,78 @@
+.TH ANTODC 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Convert ACR-NEMA to DICOM"
+.SH NAME
+antodc \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Convert ACR-NEMA to DICOM
+.SH SYNOPSIS
+.HP 10
+.B antodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B antodc
+reads the named acr-nema input file and copies the information and
+pixel data to a new dicom file, converting as many attributes as
+possible to make valid dicom information objects.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The encoding of the file will be changed to the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options. This provides a means of converting between different transfer
+syntaxes, and adding or removing Part 10 style meta-information headers
+to or from "true" DICOM files, DICOM messages captured from network
+exchanges such as with the Mallinckrodt or Oldenburg central test node
+software, or converting old ACR/NEMA or SPI files.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows pre-DICOM
+ACR-NEMA or SPI files to be converted to DICOM files containing
+conforming instances of SOP classes in a semi-automated manner. If the
+SOP Class can be automatically determined, such as for CT or MR images,
+specific SOP Class instances will be created, otherwise SC will be used.
+Unique study, series and instance identifiers will be generated from a
+time stamp, but can be overridden by command line options to allow for
+shared identifiers between files of a series.
+.LP
+A special effort is made to find a useful value for Instance Number
+(formerly Image Number), by looking for private attributes (e.g. Philips
+MR). Similarly, if Series Number is absent, then StudyID is copied to
+it (Siemens MR), and the same for other series level attributes.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1),
+.BR dccp(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+If there are no gantry relative image orientation and position values in
+the input, antodc will try to use patient orientation and slice location
+to guess suitable values ... this works OK for orientation but very
+likely the direction of the position value will have the wrong sign.
+.LP
+Invalid enumerated values for scanning sequence may be created or left
+alone.
diff --git a/appsrc/dcfile/dcacqmap.man b/appsrc/dcfile/dcacqmap.man
new file mode 100644
index 0000000..8878d52
--- /dev/null
+++ b/appsrc/dcfile/dcacqmap.man
@@ -0,0 +1,140 @@
+.TH dcacqmap 1 "18 May 2010" "DICOM PS3" "Create visual map of acquisition pattern"
+.SH NAME
+dcacqmap \- ACR/NEMA DICOM PS3 ... Create visual map of acquisition pattern
+.SH SYNOPSIS
+.HP 10
+.B dcacqmap
+[
+.B \-byacqnumber
+]
+[
+.B \-byslicelocation
+]
+[
+.B \-byscanoptions
+]
+[
+.B \-byorientation
+]
+[
+.B \-locationtolerance n
+]
+[
+.B \-iconsize n
+]
+[
+.B \-nodump
+]
+[
+.B \-xhtml
+]
+[
+.B \-isonames
+]
+[
+.B \-nostyle
+]
+.B filenamesfile resultfolder
+.SH DESCRIPTION
+.LP
+.B dcacqmap
+reads a list of DICOM filenames from a file, and creates an HTML page containing
+icon images (and optionally reports) that visualize the pattern of acquisition in terms of dimensions
+of space and time and other potential dimensions.
+.LP
+Position is derived from Image Position (Patient) and sorted along the normal to
+the Image Orientation (Patient). It is assumed (but not checked) that all the images
+have the same orientation (unless separated by using -byorientation) and the same Frame of Reference UID.
+.LP
+After partitioning by position, the Acqusition Time (or Number or Scan Options), Convolution Kernel and Slice Thickness
+are then used to distinguish images acquired at the same spatial position.
+.LP
+An index.html will be created in the result folder, which will also contain sub-folders for
+iconic representations of the DICOM image files and reports. Within the html page each image
+icon may be hyperlinked to either a dump of the DICOM contents for the first file for each
+position or the difference between dumps for subsequent files.
+.SH OPTIONS
+.LP
+.TP
+.B \-byacqnumber
+.RS
+Use the Acquisition Number rather than the Acquisition Time to separate blocks of slices acquired
+at the same time; may be useful when every slice has its own different acquisition time.
+.RE
+.TP
+.B \-byslicelocation
+.RS
+Use the Slice Location for position and sorting, rather than deriving distance along the normal
+to Image Orientation (Patient) from Image Position (Patient).
+.RE
+.TP
+.B \-byscanoption
+.RS
+Use the Scan Option value rather than the Acquisition Time to separate blocks of slices acquired
+at the same time; may be useful when cardiac % RR interval is encoded in this attribute.
+.RE
+.TP
+.B \-byorientation
+.RS
+Use the ImageOrientation (Patient) rather than the Acquisition Time to separate blocks of slices; may be useful if
+there are different angulation in the same series.
+.RE
+.TP
+.B \-locationtolerance n
+.RS
+Since calculated or specified positions may differ only by a small distance, even though they
+are perhaps intended to be at the saem location, allow a fudge factor by specify rounding to
+the nearest whole millimeter (1), tenth (10), hundredth (100), etc.
+.RE
+.TP
+.B \-iconsize n
+.RS
+Specify a different size for icons from the default 128x128 pixels.
+.RE
+.TP
+.B \-nodump
+.RS
+Supress the default inclusion of dump or diff files hyperlinked from icons.
+.RE
+.TP
+.B \-xhtml
+.RS
+Create XHTML rather than HTML output.
+.RE
+.TP
+.B \-nostyle
+.RS
+Do not use a CSS stylesheet, but embed style information in the HTML output, either in an HTML or XHTML form depending on whether the -xhtml flag is set.
+.RE
+.TP
+.B \-isonames
+.RS
+Use short names without special characters for all files created, e.g., for recording on ISO 9660 Level 1 compliant media.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcsort(1) ,
+.BR dctable(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+Currently only single-frame CT images have been tested. A different set of sub-keys below position would
+be needed for other modalities.
+.LP
+When Acquisition Time is encoded by the vendor as a single value for all slices in an
+acquisition step, then the strategy adopted for display works well to group steps into
+columns; however, then each slice has a different acquisition time, a (very) large
+number of columns may result, with the slices staggered diagonally as one would
+expect. It is not clear where to look other than Acquisition Time for a single value
+that spans slices in a step in such cases.
+.LP
+The script is intolerant of spaces in file name paths.
diff --git a/appsrc/dcfile/dcacqmap.script b/appsrc/dcfile/dcacqmap.script
new file mode 100755
index 0000000..93a6243
--- /dev/null
+++ b/appsrc/dcfile/dcacqmap.script
@@ -0,0 +1,338 @@
+#!/bin/sh
+#
+# not tolerant of spaces in file names
+#
+
+usage() {
+	echo 1>&2 "Usage: $1 [-byacqnumber] [-byslicelocation] [-byscanoptions] [-bytemporalpositionidentifier] [-locationtolerance n] [-iconsize n] [-nodump] [-xhtml] [-isonames] [-nostyle] filenamesfile resultfolder"
+}
+
+ACQUISITIONPARAMETER=AcquisitionTime
+POSITIONPARAMETER=ImagePositionPatient
+LOCATIONTOLERANCE=""
+ICONSIZE=128
+INCLUDEREPORT="yes"
+MAKEXHTML="no"
+USEUIDFORFILENAME="yes"
+USESTYLESHEET="yes"
+SHORTAGTERMINATOR=""
+
+while [ $# -gt 2 ]
+do
+	if [ "$1" = "-byacqnumber" ]
+	then
+		ACQUISITIONPARAMETER=AcquisitionNumber
+	elif [ "$1" = "-byorientation" ]
+	then
+		# useful for series with different angulations
+		ACQUISITIONPARAMETER=ImageOrientationPatient
+	elif [ "$1" = "-byscanoptions" ]
+	then
+		# useful for Siemens Cardiac acquisitions where %RR is embedded in this attribute
+		ACQUISITIONPARAMETER=ScanOptions
+	elif [ "$1" = "-bytemporalpositionidentifier" ]
+	then
+		# useful for Philips perfusion acquisitions, within set of images all with the same AcquisitionNumber
+		ACQUISITIONPARAMETER=TemporalPositionIdentifier
+	elif [ "$1" = "-byslicelocation" ]
+	then
+		POSITIONPARAMETER=SliceLocation
+	elif [ "$1" = "-nodump" ]
+	then
+		INCLUDEREPORT="no"
+	elif [ "$1" = "-xhtml" ]
+	then
+		MAKEXHTML="yes"
+		SHORTAGTERMINATOR="/"
+	elif [ "$1" = "-isonames" ]
+	then
+		USEUIDFORFILENAME="no"
+	elif [ "$1" = "-nostyle" ]
+	then
+		USESTYLESHEET="no"
+	elif [ "$1" = "-locationtolerance" ]
+	then
+		shift
+		LOCATIONTOLERANCE="$1"
+	elif [ "$1" = "-iconsize" ]
+	then
+		shift
+		ICONSIZE="$1"
+	else
+		usage `basename $0`
+		exit 1
+	fi
+	shift
+done
+
+FILENAMESFILE="$1"
+RESULTFOLDERNAME="$2"
+
+if [ $# -ne 2 -o ! -f "${FILENAMESFILE}" ]
+then
+	usage `basename $0`
+	exit 1
+fi
+
+HTMLFILE="index.html"
+ICONSDIR="icons"
+REPORTSDIR="reports"
+STYLESHEET="style.css"
+
+mkdir -p "${RESULTFOLDERNAME}"
+
+FQHTMLFILE="${RESULTFOLDERNAME}/${HTMLFILE}"
+FQICONSDIR="${RESULTFOLDERNAME}/${ICONSDIR}"
+FQSTYLESHEET="${RESULTFOLDERNAME}/${STYLESHEET}"
+FQREPORTSDIR="${RESULTFOLDERNAME}/${REPORTSDIR}"
+
+mkdir -p "${FQICONSDIR}"
+if [ "${INCLUDEREPORT}" = "yes" ]
+then
+	mkdir -p "${FQREPORTSDIR}"
+fi
+
+TMPROOT=/tmp/`basename $0`.$$.
+
+SORTEDBYPOSITION="${TMPROOT}sortedbyposition.dat"
+POSITIONLIST="${TMPROOT}positionlist.dat"
+SUBKEYS="${TMPROOT}subkeys.dat"
+UNIQUESUBKEYS="${TMPROOT}uniquesubkeys.dat"
+PARAMETERSBYFILE="${TMPROOT}parametersbyfile.dat"
+
+CURRENTPOSITIONFILES="${TMPROOT}currentpositionfiles.dat"
+SORTEDWITHINPOSITION="${TMPROOT}sortedwithinposition.dat"
+ROWFILE="${TMPROOT}rowfile.dat"
+
+useTitle=""
+
+echo 1>&2 "Stage 1: identifying unique values of position and sorting"
+if [ -z "${LOCATIONTOLERANCE}" ]
+then
+	dcsort -index -show -k "${POSITIONPARAMETER}" `cat "${FILENAMESFILE}"` >"${SORTEDBYPOSITION}" 2>&1
+else
+	dcsort -index -show -k "${POSITIONPARAMETER}" `cat "${FILENAMESFILE}"` 2>&1 | awk -v locationtolerance="${LOCATIONTOLERANCE}" '{print $1 "\t" $2 "\t" (int($3*locationtolerance+0.5)/locationtolerance)}' >"${SORTEDBYPOSITION}"
+fi
+#cat 1>&2 "${SORTEDBYPOSITION}"
+awk < "${SORTEDBYPOSITION}" '{print $3}' | sort -u -n -r > "${POSITIONLIST}"	# -r here makes head to toe, rather than -descending in dcsort
+#cat 1>&2 "${POSITIONLIST}"
+
+echo 1>&2 "Stage 2: making icons, extracting other key values than position and identifying unique combinations of those keys"
+rm -f "${UNIQUESUBKEYS}"
+rm -f "${PARAMETERSBYFILE}"
+for i in `cat "${FILENAMESFILE}"`
+do
+	if [ -z "${useTitle}" ]
+	then
+		useTitle=`dckey -noerror -k PatientName "$i" 2>&1 | egrep -iv '(error|warning)' | head -1`
+	fi
+	
+	dckey -brief -k SliceThickness -k ConvolutionKernel -k "${ACQUISITIONPARAMETER}" -k SOPInstanceUID "$i" >"${SUBKEYS}" 2>&1
+#cat "${SUBKEYS}"
+	sopInstanceUID=`grep SOPInstanceUID "${SUBKEYS}"| sed -e 's/^SOPInstanceUID=//'`
+	if [ ! -f "${FQICONSDIR}/${sopInstanceUID}.jpg" ]
+	then
+		dctopgm8 -quiet "$i" 2>/dev/null | pamscale -xsize "${ICONSIZE}" -ysize "${ICONSIZE}" | cjpeg >"${FQICONSDIR}/${sopInstanceUID}.jpg"
+	fi
+	
+	sliceThickness=`grep SliceThickness "${SUBKEYS}"| sed -e 's/^SliceThickness=//'`
+	if [ -z "${sliceThickness}" ]; then sliceThickness="0.0"; fi
+	convolutionKernel=`grep ConvolutionKernel "${SUBKEYS}"| sed -e 's/^ConvolutionKernel=//' -e 's/[^A-Za-z0-9_]/_/g'`
+	if [ -z "${convolutionKernel}" ]; then convolutionKernel="NONE"; fi
+	acquisitionParameter=`grep "${ACQUISITIONPARAMETER}" "${SUBKEYS}"| sed -e "s/^${ACQUISITIONPARAMETER}=//" -e 's/ $//g' -e 's/^ //g' -e 's/[^0-9a-zA-Z+-]/_/g'`
+#echo "${acquisitionParameter}"
+	if [ -z "${acquisitionParameter}" ]; then acquisitionParameter="999999"; fi
+	echo "${acquisitionParameter} ${convolutionKernel} ${sliceThickness}" | awk '{print $1 " " $2 " " $3}' >>"${UNIQUESUBKEYS}"	# awk is to get spaces same as later
+	echo "${acquisitionParameter} ${convolutionKernel} ${sliceThickness} ${sopInstanceUID} $i" >>"${PARAMETERSBYFILE}"
+
+	rm -f "${SUBKEYS}"
+done
+mv "${UNIQUESUBKEYS}" "${UNIQUESUBKEYS}.bak"
+sort -u  <"${UNIQUESUBKEYS}.bak" | sort -n -k1,1 -d -k2,2 -n -k3,3 >"${UNIQUESUBKEYS}"	# why twice ? in case different alphas interpreted as same numeric
+rm -f "${UNIQUESUBKEYS}.bak"
+
+#cat 1>&2 "${PARAMETERSBYFILE}"
+#cat 1>&2 "${UNIQUESUBKEYS}"
+numberofuniquekeys=`wc -l "${UNIQUESUBKEYS}" | awk '{print $1}'`	# is the number of html columns we will need
+#echo 1>&2 "numberofuniquekeys = ${numberofuniquekeys}"
+
+echo 1>&2 "Stage 3: building HTML file"
+if [ "${MAKEXHTML}" = "yes" ]
+then
+	echo > "${FQHTMLFILE}" '<?xml version="1.0" encoding="utf-8" ?>'
+	echo >>"${FQHTMLFILE}" '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">'
+	echo >>"${FQHTMLFILE}" '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'
+else
+	echo >"${FQHTMLFILE}" "<html>"
+fi
+echo >>"${FQHTMLFILE}" "<head>"
+echo >>"${FQHTMLFILE}" "<title>${useTitle}</title>"
+if [ "${USESTYLESHEET}" = "yes" ]
+then
+	echo >>"${FQHTMLFILE}" "<link rel=\"stylesheet\" type=\"text/css\" href=\"${STYLESHEET}\"${SHORTAGTERMINATOR}>"
+fi
+echo >>"${FQHTMLFILE}" "</head>"
+if [ "${USESTYLESHEET}" = "yes" ]
+then
+	echo >>"${FQHTMLFILE}" "<body>"
+else
+	if [ "${MAKEXHTML}" = "yes" ]
+	then
+		echo >>"${FQHTMLFILE}" '<body style="color: lavender; background-color : black; font-family: Arial, sans-serif;">'
+	else
+		echo >>"${FQHTMLFILE}" "<body bgcolor=\"black\" text=\"lavender\">"
+		# note that the face attribute is only supported by IE (see "http://www.blooberry.com/indexdot/html/tagpages/b/basefont.htm"); size of 3 is default
+		echo >>"${FQHTMLFILE}" "<basefont size=\"3\" face=\"Arial, sans-serif\"${SHORTAGTERMINATOR}>"
+	fi
+fi
+echo >>"${FQHTMLFILE}" "<table>"
+echo >>"${FQHTMLFILE}" "<tr><th>Position</th>"
+xargs <"${UNIQUESUBKEYS}" -L1 -J% echo '<th align="center">' % '</th>' >>"${FQHTMLFILE}"
+echo >>"${FQHTMLFILE}" "</tr>"
+
+countForFileName=0
+for position in `cat "${POSITIONLIST}"`
+do
+#echo 1>&2 "Position = ${position}"
+	echo >>"${FQHTMLFILE}" "<tr><td>${position}</td>"
+	positionWithPeriodEscaped=`echo "${position}" | sed -e 's/[.]/[.]/'`
+	grepstring="[^0-9-.]${positionWithPeriodEscaped}\$"
+	egrep "${grepstring}" "${SORTEDBYPOSITION}" | awk '{print $2}' >"${CURRENTPOSITIONFILES}"
+#cat 1>&2 <"${CURRENTPOSITIONFILES}"
+	rm -f "${ROWFILE}"
+	for i in `cat "${CURRENTPOSITIONFILES}"`
+	do
+#echo 1>&2 "i = $i"
+		whichfileentry=`grep "$i" "${PARAMETERSBYFILE}" | head -1`
+#echo 1>&2 "whichfileentry = ${whichfileentry}"
+		parameters=`echo "${whichfileentry}" | awk '{print $1 " " $2 " " $3}'`	# awk is to get spaces same as in UNIQUESUBKEYS (see grep later)
+#echo 1>&2 "parameters = ${parameters}"
+		sopInstanceUID=`echo "${whichfileentry}" | awk '{print $4}'`
+#echo 1>&2 "sopInstanceUID = ${sopInstanceUID}"
+		whichuniquesubkey=`grep -n "${parameters}" "${UNIQUESUBKEYS}" | sed -e 's/:.*$//'`
+#echo 1>&2 "whichuniquesubkey = ${whichuniquesubkey}"
+		echo "${whichuniquesubkey}: ${sopInstanceUID} $i" >>"${ROWFILE}"
+	done
+	firstfile=""
+	count=1
+	while [ ${count} -le ${numberofuniquekeys} ]
+	do
+		row=`egrep "^$count: " "${ROWFILE}" | head -1 | sed -e 's/^[0-9]*:[ ]*//'`
+		if [ -z "${row}" ]
+		then
+			echo >>"${FQHTMLFILE}" "<td></td>"
+		else
+#echo 1>&2 "Got row = ${row}"
+			sopInstanceUID=`echo "${row}" | sed -e 's/^\([0-9][0-9.]*\).*$/\1/'`
+#echo 1>&2 "Got sopInstanceUID = ${sopInstanceUID}"
+			if [ "${USEUIDFORFILENAME}" = "yes" ]
+			then
+				baseForFileName="${sopInstanceUID}"
+			else
+				baseForFileName="${countForFileName}"
+				mv "${FQICONSDIR}/${sopInstanceUID}.jpg"  "${FQICONSDIR}/${baseForFileName}.jpg"
+			fi
+			if [ "${INCLUDEREPORT}" = "no" ]
+			then
+				echo "<td align=\"center\"><img src=\"${ICONSDIR}/${baseForFileName}.jpg\" alt=\"NONE\"${SHORTAGTERMINATOR}></td>" >>"${FQHTMLFILE}"
+			else
+				fileName=`echo "${row}" | sed -e 's/^[^ ]*[ ]*\(.*\)$/\1/'`
+#echo 1>&2 "Got fileName = ${fileName}"
+				report="${baseForFileName}.txt"
+				if [ -z "${firstfile}" ]
+				then
+					dcdump "$fileName" 2>&1 | grep -v 'Warning - Overriding UN With Dictionary VR' >"${FQREPORTSDIR}/${report}"
+					firstfile="$fileName"
+				else
+					dcdiff "${firstfile}" "$fileName" >"${FQREPORTSDIR}/${report}" 2>&1
+				fi
+				#echo "${whichuniquesubkey}: <td align=\"center\"><a href=\"${REPORTSDIR}/${report}\"><img src=\"${ICONSDIR}/${baseForFileName}.jpg\"${SHORTAGTERMINATOR}></a></td>" >>"${FQHTMLFILE}"
+				echo "<td align=\"center\"><a href=\"javascript:void(0)\" onclick=\"window.open('${REPORTSDIR}/${report}')\"><img src=\"${ICONSDIR}/${baseForFileName}.jpg\" alt=\"NONE\"${SHORTAGTERMINATOR}></a></td>" >>"${FQHTMLFILE}"
+			fi
+		fi
+		count=`expr ${count} + 1`
+		countForFileName=`expr ${countForFileName} + 1`
+	done
+	echo >>"${FQHTMLFILE}" "</tr>"
+	rm -f "${CURRENTPOSITIONFILES}"
+	rm -f "${ROWFILE}"
+done
+echo >>"${FQHTMLFILE}" "</table></body></html>"
+
+rm -f "${UNIQUESUBKEYS}"
+rm -f "${PARAMETERSBYFILE}"
+rm -f "${SORTEDBYPOSITION}"
+rm -f "${POSITIONLIST}"
+
+if [ "${USESTYLESHEET}" = "yes" ]
+then
+	cat <<EOF >"${FQSTYLESHEET}"
+body {
+	color: lavender;
+	background-color: #000000;
+	text-decoration:  none;
+	font-family: Arial, sans-serif;
+	font-size: 100%;
+}
+
+frame {
+	color: lavender;
+	background-color: #000000;
+	text-decoration:  none;
+	font-family: Arial, sans-serif;
+	font-size: 100%;
+}
+
+p {
+}
+
+table {
+	border: 0px solid;
+	border-color: lavender;
+}
+
+th {
+	border: 1px solid;
+	padding-left: 2px;
+	padding-right: 2px;
+	border-color: feldspar;
+}
+
+td {
+	border: 1px solid;
+	padding-left: 0px;
+	padding-right: 0px;
+	border-color: feldspar;
+}
+
+a:link {
+	/* Applies to all unvisited links */
+	text-decoration:  none;
+	color:            black;
+}
+
+a:visited {
+	/* Applies to all visited links */
+	text-decoration:  none;
+	color:            black;
+}
+
+a:hover {
+	/* Applies to links under the pointer */
+	text-decoration:  none;
+	background-color: lavender;
+	color:            dimgray;
+} 
+
+a:active  {
+	/* Applies to activated links */
+	text-decoration:  none;
+	color:            black;
+} 
+  
+.centered {
+	text-align: center;
+}
+EOF
+fi
+
diff --git a/appsrc/dcfile/dcanon.man b/appsrc/dcfile/dcanon.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcanon.script b/appsrc/dcfile/dcanon.script
new file mode 100755
index 0000000..46ef2e6
--- /dev/null
+++ b/appsrc/dcfile/dcanon.script
@@ -0,0 +1,604 @@
+#!/bin/sh
+#
+# Usage: $0 srcdir dstdir [options [newpatientname newpatientid]]
+#
+# where options is a SINGLE string, either empty or possibly containing:
+#
+#	nodesc - remove descriptions (equals nopatientdesc,nostudydesc,noseriesdesc,noimagedesc)
+#	nopatientdesc - remove descriptions at patient level
+#	nostudydesc - remove descriptions at study/procedure level
+#	noseriesdesc - remove descriptions at series and procedure step level
+#	noimagedesc - remove descriptions at image level
+#	nomanuf - remove manufacturer
+#	noretired - remove retired ACR-NEMA elements or other elements that are undesirable
+#	noclinicaltrial - remove clinical trial related attributes
+#	keepprivate - do not remove private elements
+#	keepsafeprivate - keep safe private attributes only, e.g. Philips private PET SUV factor
+#	keepuids - do not replace UIDs
+#	keeppet - keep parameters for PET SUV calculation (age,sex,size,weight)
+#	verify - verify afterwards
+#	diff - show difference afterwards
+#	mvdatedesc - more results to descriptive hierarchy (default)
+#	mvid - more results to hierarchy based on IDs
+#	mv8only - more results to 8 character A-Z0-9_ component names
+#	nomove - do not move into hierarchy
+#	none - dummy option to allow specification of name and id arguments when no options
+#
+# e.g. dcanon src dst nodesc,nomanuf Smith^Mary 1234
+
+DCDIFF=dcdiff
+DCIODVFY=dciodvfy
+DCCP=dccp
+DCKEY=dckey
+DCSMPTE=dcsmpte
+DCMVHIERDATEDESC=dcmvhier.datedesc
+DCMVHIER8ONLY=dcmvhier.8only
+DCMVHIERID=dcmvhier
+
+if [ $# = 2 ]
+then
+	"$0" "$1" "$2" " " "Doe^J" "000000"
+elif [ $# = 3 ]
+then
+	"$0" "$1" "$2" "$3" "Doe^J" "000000"
+elif [ $# = 5 ]
+then
+	srcdir=$1
+	dstdir=$2
+	options="$3"
+	newpatientname="$4"
+	newpatientid="$5"
+	TMPROOT=/tmp/`basename $0`.$$
+	uidmapfile="$TMPROOT.uids.tmp"
+	touch "$uidmapfile"
+	counterfile="$TMPROOT.counter.tmp"
+	$DCSMPTE "$TMPROOT.tmp"
+	newuidbase=`$DCKEY -noerror -k SOPInstanceUID "$TMPROOT.tmp" 2>&1 | egrep -v 'Error|Warning'`
+	rm "$TMPROOT.tmp"
+	echo 1 >"$counterfile"
+	find "$srcdir" -follow -type f -a ! -name '.DS_Store' -exec "$0" "$counterfile" "$uidmapfile" "$newuidbase" "$dstdir" "$newpatientname" "$newpatientid" "$options" '{}' ';'
+
+	nomove=`echo "$options" | grep -i nomove`
+	if [ -z "$nomove" ]
+	then
+		mv8only=`echo "$options" | grep -i mv8only`
+		mvid=`echo "$options" | grep -i mvid`
+		mvdatedesc=`echo "$options" | grep -i mvdatedesc`
+		if [ ! -z "$mv8only" ]
+		then
+			usemvhier="$DCMVHIER8ONLY"
+		elif [ ! -z "$mvid" ]
+		then
+			usemvhier="$DCMVHIERID"
+		elif [ ! -z "$mvdatedesc" ]
+		then
+			usemvhier="$DCMVHIERDATEDESC"
+		else
+			usemvhier="$DCMVHIERDATEDESC"
+		fi
+		cd "$dstdir"
+		# take care not to try to move files already nested in hierarchy ...
+		find . -name '*.dcm' | egrep -v '/.*/' | xargs -L1 -I% "$usemvhier" "%"
+		cd ..
+	fi
+	
+	rm "$uidmapfile"
+	rm "$counterfile"
+	
+elif [ $# = 8 ]
+then
+	counterfile=$1
+	uidmapfile=$2
+	newuidbase=$3
+	dstdir=$4
+	newpatientname="$5"
+	newpatientid="$6"
+	options=$7
+	srcfile=$8
+	
+	#echo "$srcfile"
+	#echo "$newpatientname"
+	#echo "$newpatientid"
+	
+	nodescriptions=`echo "$options" | grep -i nodesc`
+	nopatientdesc=`echo "$options" | grep -i nopatientdesc`
+	nostudydesc=`echo "$options" | grep -i nostudydesc`
+	noseriesdesc=`echo "$options" | grep -i noseriesdesc`
+	noimagedesc=`echo "$options" | grep -i noimagedesc`
+	
+	nomanufacturer=`echo "$options" | grep -i nomanuf`
+	noretired=`echo "$options" | grep -i noretired`
+	noclinicaltrial=`echo "$options" | grep -i noclinicaltrial`
+	keepprivate=`echo "$options" | grep -i keepprivate`
+	keepuids=`echo "$options" | grep -i keepuids`
+	keeppet=`echo "$options" | grep -i keeppet`
+	keepsafeprivate=`echo "$options" | grep -i keepsafeprivate`
+	verify=`echo "$options" | grep -i verify`
+	diff=`echo "$options" | grep -i diff`
+
+	deidMethod=`basename "$0"`
+	deidMethod="${deidMethod}\\no identifiers"
+	if [ -z "${nodescriptions}" -a -z "${nopatientdesc}" -a -z "${nostudydesc}" -a -z "${noseriesdesc}" -a -z "${noimagedesc}" ]
+	then
+		deidMethod="${deidMethod}\\keep descriptions"
+	else
+		if [ ! -z "${nodescriptions}" ]
+		then
+			deidMethod="${deidMethod}\\no descriptions"
+		else
+			deidMethod="${deidMethod}\\no"
+			if [ ! -z "${nopatientdesc}" ]
+			then
+				deidMethod="${deidMethod} patient"
+			fi
+			if [ ! -z "${nostudydesc}" ]
+			then
+				deidMethod="${deidMethod} study"
+			fi
+			if [ ! -z "${noseriesdesc}" ]
+			then
+				deidMethod="${deidMethod} series"
+			fi
+			if [ ! -z "${noimagedesc}" ]
+			then
+				deidMethod="${deidMethod} image"
+			fi
+			deidMethod="${deidMethod} descriptions"
+		fi
+	fi	
+	if [ -z "${nomanufacturer}" ]
+	then
+		deidMethod="${deidMethod}\\keep manufacturer"
+	else
+		deidMethod="${deidMethod}\\no manufacturer"
+	fi
+	if [ -z "${noretired}" ]
+	then
+		deidMethod="${deidMethod}\\keep retired"
+	else
+		deidMethod="${deidMethod}\\no retired"
+	fi
+	if [ -z "${noclinicaltrial}" ]
+	then
+		deidMethod="${deidMethod}\\keep clinical trial"
+	else
+		deidMethod="${deidMethod}\\no clinical trial"
+	fi
+	if [ -z "${keepprivate}" ]
+	then
+		if [ -z "${keepsafeprivate}" ]
+		then
+			deidMethod="${deidMethod}\\no private"
+		else
+			deidMethod="${deidMethod}\\no unsafe private"
+		fi
+	else
+		deidMethod="${deidMethod}\\keep private"
+	fi
+	if [ -z "${keepuids}" ]
+	then
+		deidMethod="${deidMethod}\\no uids"
+	else
+		deidMethod="${deidMethod}\\keep uids"
+	fi
+	if [ -z "${keeppet}" ]
+	then
+		deidMethod="${deidMethod}\\no pet demographics"
+	else
+		deidMethod="${deidMethod}\\keep pet demographics"
+	fi
+	deidMethod="${deidMethod}\\keep dates"
+	
+	srcstudyinstanceuid=`$DCKEY -noerror -k StudyInstanceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+	srcseriesinstanceuid=`$DCKEY -noerror -k SeriesInstanceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+	srcsopinstanceuid=`$DCKEY -noerror -k SOPInstanceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+	srcframeofreferenceuid=`$DCKEY -noerror -k FrameOfReferenceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+	srcsyncframeofreferenceuid=`$DCKEY -noerror -k SynchronizationFrameOfReferenceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+	
+	if [ -z "$srcstudyinstanceuid" -o  -z "$srcseriesinstanceuid" -o  -z "$srcsopinstanceuid" ]
+	then
+		echo 1>&2 "Warning: Missing UIDs; ignoring $srcfile"
+	else
+		countervalue=`head -1 "$counterfile" | awk '{print $1}'`	# safer than just cat ?
+		counterfiledirty=0
+		
+		sedstring='^'"$srcstudyinstanceuid"'[^0-9.]'
+		newstudyinstanceuid=`egrep "$sedstring" "$uidmapfile" | awk '{print $2}'`
+		if [ -z "$newstudyinstanceuid" ]
+		then
+			newstudyinstanceuid="$newuidbase.$countervalue"
+			countervalue=`expr $countervalue + 1`
+			counterfiledirty=1
+			echo "$srcstudyinstanceuid $newstudyinstanceuid $countervalue" >>"$uidmapfile"
+		fi
+		#echo "Replacing StudyInstanceUID $srcstudyinstanceuid with $newstudyinstanceuid"
+		sedstring='^'"$srcstudyinstanceuid"'[^0-9.]'
+		newstudyid=`egrep "$sedstring" "$uidmapfile" | awk '{print $3}'`	# use counter value for new Study ID
+		#echo "Replacing StudyID with $newstudyid"
+				
+		sedstring='^'"$srcseriesinstanceuid"'[^0-9.]'
+		newseriesinstanceuid=`egrep "$sedstring" "$uidmapfile" | awk '{print $2}'`
+		if [ -z "$newseriesinstanceuid" ]
+		then
+			newseriesinstanceuid="$newuidbase.$countervalue"
+			countervalue=`expr $countervalue + 1`
+			counterfiledirty=1
+			echo "$srcseriesinstanceuid $newseriesinstanceuid $countervalue" >>"$uidmapfile"
+		fi
+		#echo "Replacing SeriesInstanceUID $srcseriesinstanceuid with $newseriesinstanceuid"
+				
+		sedstring='^'"$srcsopinstanceuid"'[^0-9.]'
+		newsopinstanceuid=`egrep "$sedstring" "$uidmapfile" | awk '{print $2}'`
+		if [ -z "$newsopinstanceuid" ]
+		then
+			newsopinstanceuid="$newuidbase.$countervalue"
+			countervalue=`expr $countervalue + 1`
+			counterfiledirty=1
+			echo "$srcsopinstanceuid $newsopinstanceuid $countervalue" >>"$uidmapfile"
+		fi
+		#echo "Replacing SOPInstanceUID $srcsopinstanceuid with $newsopinstanceuid"
+		
+		if [ ! -z "$srcframeofreferenceuid" ]
+		then
+			sedstring='^'"$srcframeofreferenceuid"'[^0-9.]'
+			newframeofreferenceuid=`egrep "$sedstring" "$uidmapfile" | awk '{print $2}'`
+			if [ -z "$newframeofreferenceuid" ]
+			then
+				newframeofreferenceuid="$newuidbase.$countervalue"
+				countervalue=`expr $countervalue + 1`
+				counterfiledirty=1
+				echo "$srcframeofreferenceuid $newframeofreferenceuid $countervalue" >>"$uidmapfile"
+			fi
+			#echo "Replacing FrameOfReferenceUID $srcframeofreferenceuid with $newframeofreferenceuid"
+		else
+			newframeofreferenceuid=""
+		fi
+		
+		if [ ! -z "$srcsyncframeofreferenceuid" ]
+		then
+			sedstring='^'"$srcsyncframeofreferenceuid"'[^0-9.]'
+			newsyncframeofreferenceuid=`egrep "$sedstring" "$uidmapfile" | awk '{print $2}'`
+			if [ -z "$newsyncframeofreferenceuid" ]
+			then
+				newsyncframeofreferenceuid="$newuidbase.$countervalue"
+				countervalue=`expr $countervalue + 1`
+				counterfiledirty=1
+				echo "$srcsyncframeofreferenceuid $newsyncframeofreferenceuid $countervalue" >>"$uidmapfile"
+			fi
+			#echo "Replacing SynchronizationFrameOfReferenceUID $srcsyncframeofreferenceuid with $newsyncframeofreferenceuid"
+		else
+			newsyncframeofreferenceuid=""
+		fi
+
+		if [ $counterfiledirty != 0 ]
+		then
+			echo $countervalue >"$counterfile"
+		fi
+		
+		dccpoptions="-nodisclaimer"
+		if [ -z "$keepprivate" ]
+		then
+			dccpoptions="$dccpoptions -removeprivate"
+		fi
+
+		if [ -z "$keepuids" ]
+		then
+			dccpoptions="$dccpoptions -removeinstanceuid"
+			dccpoptions="$dccpoptions -r StudyInstanceUID $newstudyinstanceuid -r SeriesInstanceUID $newseriesinstanceuid -r SOPInstanceUID $newsopinstanceuid"
+			dccpoptions="$dccpoptions -d AffectedSOPInstanceUID"
+			dccpoptions="$dccpoptions -d ConcatenationUID"
+			dccpoptions="$dccpoptions -d ContextGroupExtensionCreatorUID"
+			dccpoptions="$dccpoptions -d CreatorVersionUID"
+			dccpoptions="$dccpoptions -d DeviceUID"
+			dccpoptions="$dccpoptions -d DigitalSignatureUID"
+			dccpoptions="$dccpoptions -d DimensionOrganizationUID"
+			dccpoptions="$dccpoptions -d DoseReferenceUID"
+			dccpoptions="$dccpoptions -d FailedSOPInstanceUIDList"
+			dccpoptions="$dccpoptions -d FiducialUID"
+			dccpoptions="$dccpoptions -d ImplementationClassUID"
+			dccpoptions="$dccpoptions -d InstanceCreatorUID"
+			dccpoptions="$dccpoptions -d IrradiationEventUID"
+			dccpoptions="$dccpoptions -d LargePaletteColorLookupTableUID"
+			dccpoptions="$dccpoptions -d MediaStorageSOPInstanceUID"
+			dccpoptions="$dccpoptions -d PaletteColorLookupTableUID"
+			dccpoptions="$dccpoptions -d ReferencedFrameOfReferenceUID"
+			dccpoptions="$dccpoptions -d ReferencedGeneralPurposeScheduledProcedureStepTransactionUID"
+			dccpoptions="$dccpoptions -d ReferencedSOPInstanceUID"
+			dccpoptions="$dccpoptions -d ReferencedSOPInstanceUIDInFile"
+			dccpoptions="$dccpoptions -d RelatedFrameOfReferenceUID"
+			dccpoptions="$dccpoptions -d RequestedSOPInstanceUID"
+			dccpoptions="$dccpoptions -d StorageMediaFileSetUID"
+			dccpoptions="$dccpoptions -d TemplateExtensionCreatorUID"
+			dccpoptions="$dccpoptions -d TemplateExtensionOrganizationUID"
+			dccpoptions="$dccpoptions -d TransactionUID"
+			dccpoptions="$dccpoptions -d UID"
+
+			dccpoptions="$dccpoptions -d SourceImageSequence -d ReferencedImageSequence"
+			
+			if [ ! -z "$newframeofreferenceuid" ]
+			then
+				dccpoptions="$dccpoptions -r FrameOfReferenceUID $newframeofreferenceuid"
+			else
+				dccpoptions="$dccpoptions -d FrameOfReferenceUID"
+			fi
+			if [ ! -z "$newsyncframeofreferenceuid" ]
+			then
+				dccpoptions="$dccpoptions -r SynchronizationFrameOfReferenceUID $newsyncframeofreferenceuid"
+			else
+				dccpoptions="$dccpoptions -d SynchronizationFrameOfReferenceUID"
+			fi
+		fi
+
+		if [ ! -d "$dstdir" ]
+		then
+			mkdir -p "$dstdir"
+		fi
+
+		dstfile="$dstdir/$newsopinstanceuid.dcm"
+		
+		echo "$srcfile -> $dstfile"
+
+		"$DCCP" "$srcfile" "$dstfile" \
+			$dccpoptions \
+			-r PatientIdentityRemoved "YES" \
+			-r DeidentificationMethod "${deidMethod}" \
+			-r StudyID           "$newstudyid" \
+			-r AccessionNumber   "$newstudyid" \
+			-r PatientName       "$newpatientname" \
+			-r PatientID         "$newpatientid" \
+			-d InstitutionName \
+			-d InstitutionAddress \
+			-d RequestingPhysician \
+			-r ReferringPhysicianName " " \
+			-d ReferringPhysicianAddress \
+			-d ReferringPhysicianTelephoneNumbers \
+			-d StationName \
+			-d InstitutionalDepartmentName \
+			-d PhysiciansOfRecord \
+			-d PerformingPhysicianName \
+			-d NameOfPhysiciansReadingStudy \
+			-d OperatorsName \
+			-r PatientBirthDate " " \
+			-d PatientBirthTime \
+			-d OtherPatientIDs \
+			-d OtherPatientNames \
+			-d OtherStudyNumbers \
+			-d MedicalRecordLocator \
+			-d EthnicGroup \
+			-d Occupation \
+			-d DeviceSerialNumber \
+			-d PlateID \
+			-d GantryID \
+			-d CassetteID \
+			-d GeneratorID \
+			-d DetectorID \
+			-d RequestAttributesSequence \
+			-d ReferencedPatientSequence \
+			-d ReferringPhysicianIdentificationSequence \
+			-d PhysiciansOfRecordIdentificationSequence \
+			-d PhysiciansReadingStudyIdentificationSequence \
+			-d ReferencedStudySequence \
+			-d AdmittingDiagnosesCodeSequence \
+			-d PerformingPhysicianIdentificationSequence \
+			-d RequestingPhysicianIdentificationSequence \
+			-d OperatorIdentificationSequence \
+			-d ReferencedPerformedProcedureStepSequence \
+			-d PerformedProcedureStepID \
+			-d IssuerOfAccessionNumberSequence \
+			-d IssuerOfPatientID \
+			-d IssuerOfPatientIDQualifiersSequence \
+			-d StudyIDIssuer \
+			-d IssuerOfAdmissionID \
+			-d IssuerOfAdmissionIDSequence \
+			-d IssuerOfServiceEpisodeID \
+			-d IssuerOfServiceEpisodeIDSequence \
+			-d ResultsIDIssuer \
+			-d InterpretationIDIssuer \
+			-d PatientBirthName \
+			-d PatientMotherBirthName \
+			-d ConfidentialityConstraintOnPatientDataDescription \
+			-d PatientInsurancePlanCodeSequence \
+			-d PatientPrimaryLanguageCodeSequence \
+			-d PatientAddress \
+			-d MilitaryRank \
+			-d BranchOfService \
+			-d CountryOfResidence \
+			-d RegionOfResidence \
+			-d PatientTelephoneNumbers \
+			-d PatientReligiousPreference \
+			-d MedicalAlerts \
+			-d Allergies \
+			-d SmokingStatus \
+			-d PregnancyStatus \
+			-d LastMenstrualDate \
+			-d SpecialNeeds \
+			-d PatientState \
+			-d AdmissionID \
+			-d AdmittingDate \
+			-d AdmittingTime \
+			-d DataSetTrailingPadding \
+			-d OriginalAttributesSequence \
+			-d ModifiedAttributesSequence \
+			-d RequestedProcedureID \
+			2>&1 | grep -v Warning
+
+		if [ -z "$keepprivate" -a ! -z "$keepsafeprivate" ]
+		then
+			philipsPETPrivateCreator=`$DCKEY -noerror -k '(0x7053,0x0010)' "$srcfile" 2>&1 | egrep -v 'Error|Warning' | grep 'Philips PET Private Group'`
+			philipsPETSUVFactor=`$DCKEY -noerror -k '(0x7053,0x1000)' "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+			philipsPETActivityConcentrationFactor=`$DCKEY -noerror -k '(0x7053,0x1009)' "$srcfile" 2>&1 | egrep -v 'Error|Warning'`
+			if [ ! -z "${philipsPETSUVFactor}" -a ! -z "${philipsPETPrivateCreator}" ]
+			then
+				mv "$dstfile" "$dstfile.bak"
+				if [ -z "${philipsPETActivityConcentrationFactor}" ]
+				then
+					"$DCCP" "$dstfile.bak" "$dstfile" \
+						-r '(0x7053,0x0010)' "${philipsPETPrivateCreator}" \
+						-r '(0x7053,0x1000)' "${philipsPETSUVFactor}" \
+						2>&1 | grep -v Warning
+				else
+					"$DCCP" "$dstfile.bak" "$dstfile" \
+						-r '(0x7053,0x0010)' "${philipsPETPrivateCreator}" \
+						-r '(0x7053,0x1000)' "${philipsPETSUVFactor}" \
+						-r '(0x7053,0x1009)' "${philipsPETActivityConcentrationFactor}" \
+						2>&1 | grep -v Warning
+				fi
+				rm "$dstfile.bak"
+			fi
+		fi
+
+		if [ -z "$keeppet" ]
+		then
+			mv "$dstfile" "$dstfile.bak"
+			"$DCCP" "$dstfile.bak" "$dstfile" \
+				-nodisclaimer \
+				-r PatientSex " " \
+				-d PatientAge \
+				-d PatientSize \
+				-d PatientWeight \
+				2>&1 | grep -v Warning
+			rm "$dstfile.bak"
+		fi
+			
+		if [ ! -z "$nodescriptions" ]
+		then
+			mv "$dstfile" "$dstfile.bak"
+			"$DCCP" "$dstfile.bak" "$dstfile" \
+				-nodisclaimer \
+				-d StudyDescription \
+				-d SeriesDescription \
+				-d ImageComments \
+				-d AdmittingDiagnosesDescription \
+				-d AdditionalPatientHistory \
+				-d PatientComments \
+				-d DerivationDescription \
+				-d RequestedProcedureDescription \
+				-d PerformedProcedureStepDescription \
+				-d CommentsOnThePerformedProcedureStep \
+				-d AcquisitionComments \
+				-d ReasonForStudy \
+				-d ProtocolName \
+				2>&1 | grep -v Warning
+			rm "$dstfile.bak"
+		else
+			if [ ! -z "${nopatientdesc}" ]
+			then
+				mv "$dstfile" "$dstfile.bak"
+				"$DCCP" "$dstfile.bak" "$dstfile" \
+					-nodisclaimer \
+					-d AdmittingDiagnosesDescription \
+					-d AdditionalPatientHistory \
+					-d PatientComments \
+					2>&1 | grep -v Warning
+				rm "$dstfile.bak"
+			fi
+			if [ ! -z "${nostudydesc}" ]
+			then
+				mv "$dstfile" "$dstfile.bak"
+				"$DCCP" "$dstfile.bak" "$dstfile" \
+					-nodisclaimer \
+					-d StudyDescription \
+					-d RequestedProcedureDescription \
+					-d ReasonForStudy \
+					2>&1 | grep -v Warning
+				rm "$dstfile.bak"
+			fi
+			if [ ! -z "${noseriesdesc}" ]
+			then
+				mv "$dstfile" "$dstfile.bak"
+				"$DCCP" "$dstfile.bak" "$dstfile" \
+					-nodisclaimer \
+					-d SeriesDescription \
+					-d PerformedProcedureStepDescription \
+					-d CommentsOnThePerformedProcedureStep \
+					-d ProtocolName \
+					2>&1 | grep -v Warning
+				rm "$dstfile.bak"
+			fi
+			if [ ! -z "${noimagedesc}" ]
+			then
+				mv "$dstfile" "$dstfile.bak"
+				"$DCCP" "$dstfile.bak" "$dstfile" \
+					-nodisclaimer \
+					-d ImageComments \
+					-d AcquisitionComments \
+					-d DerivationDescription \
+					2>&1 | grep -v Warning
+				rm "$dstfile.bak"
+			fi
+		fi
+			
+		if [ ! -z "$nomanufacturer" ]
+		then
+			mv "$dstfile" "$dstfile.bak"
+			"$DCCP" "$dstfile.bak" "$dstfile" \
+				-nodisclaimer \
+				-r Manufacturer " " \
+				-d ManufacturerModelName \
+				-d SoftwareVersions \
+				2>&1 | grep -v Warning
+			rm "$dstfile.bak"
+		fi
+			
+		if [ ! -z "$noretired" ]
+		then
+			mv "$dstfile" "$dstfile.bak"
+			"$DCCP" "$dstfile.bak" "$dstfile" \
+				-nodisclaimer \
+				-d DataSetType \
+				-d DataSetSubtype \
+				-d ImagePosition \
+				-d ImageOrientation \
+				-d Location \
+				-d ImageGeometryType \
+				-d AcquisitionsInSeries \
+				-d ImagesInAcquisition \
+				-d ImageDimensions \
+				-d ImageFormat \
+				-d CompressionCode \
+				-d ImageLocation \
+				-d ImageDisplayFormat \
+				-d AnnotationDisplayFormatID \
+				-d FilmOrientation \
+				-d BorderDensity \
+				-d Trim \
+				-d ImageBoxPosition \
+				-d ManipulatedImage \
+				2>&1 | grep -v Warning
+			rm "$dstfile.bak"
+		fi
+
+		if [ ! -z "$noclinicaltrial" ]
+		then
+			mv "$dstfile" "$dstfile.bak"
+			"$DCCP" "$dstfile.bak" "$dstfile" \
+				-nodisclaimer \
+				-d ClinicalTrialSponsorName \
+				-d ClinicalTrialProtocolID \
+				-d ClinicalTrialProtocolName \
+				-d ClinicalTrialSiteID \
+				-d ClinicalTrialSiteName \
+				-d ClinicalTrialSubjectID \
+				-d ClinicalTrialSubjectReadingID \
+				-d ClinicalTrialTimePointID \
+				-d ClinicalTrialTimePointDescription \
+				-d ClinicalTrialCoordinatingCenterName \
+				-d ClinicalTrialSeriesID \
+				-d ClinicalTrialSeriesDescription \
+				2>&1 | grep -v Warning
+			rm "$dstfile.bak"
+		fi
+
+		if [ ! -z "$diff" ]
+		then
+			"$DCDIFF" "$srcfile" "$dstfile"
+		fi
+
+		if [ ! -z "$verify" ]
+		then
+			"$DCIODVFY" "$dstfile"
+		fi
+	fi
+else
+	echo 1>&2 "Error: wrong number of arguments $#"
+fi
diff --git a/appsrc/dcfile/dcarith.cc b/appsrc/dcfile/dcarith.cc
new file mode 100644
index 0000000..b671575
--- /dev/null
+++ b/appsrc/dcfile/dcarith.cc
@@ -0,0 +1,372 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcarith.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "attrtype.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+class MaskHighBitFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	Uint16 mask;
+public:
+	MaskHighBitFilter(unsigned lowbitstokeep)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			Assert(lowbitstokeep > 0);
+			Assert(lowbitstokeep <= 16);
+			mask = Uint16((Uint32(1)<<lowbitstokeep)-1u);
+//cerr << "MaskHighBitFilter::MaskHighBitFilter(): lowbitstokeep=" << dec << lowbitstokeep << endl;
+//cerr << "MaskHighBitFilter::MaskHighBitFilter(): mask=0x" << hex << mask << dec << endl;
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			return value&mask;
+		}
+};
+
+class AddValueOffsetFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	int offset;
+public:
+	AddValueOffsetFilter(int o)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			offset=o;
+//cerr << "AddValueOffsetFilter::AddValueOffsetFilter(): offset=" << dec << offset << endl;
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			return (Uint16(value+offset));
+		}
+};
+
+class ZeroValueFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	Uint16 valuetozero;
+public:
+	ZeroValueFilter(int v)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			valuetozero=Uint16(v);
+//cerr << "ZeroValueFilter::ZeroValueFilter(): v=" << dec << v << endl;
+//cerr << "ZeroValueFilter::ZeroValueFilter(): valuetozero=0x" << hex << valuetozero << dec << endl;
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			return value==valuetozero ? Uint16(0) : value;
+		}
+};
+
+class ReplaceValueFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	Uint16 valuetostartreplace;
+	Uint16 valuetoendreplace;
+	Uint16 replacementvalue;
+public:
+	ReplaceValueFilter(int rs,int re,int v)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			valuetostartreplace=Uint16(rs);
+			valuetoendreplace=Uint16(re);
+			replacementvalue=Uint16(v);
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			return (value >= valuetostartreplace && value <= valuetoendreplace) ? replacementvalue : value;
+		}
+};
+
+class ScaleValueFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	float scalefactor;
+public:
+	ScaleValueFilter(float s)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			scalefactor=s;
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			return value=(Uint16)(scalefactor*(float)value);
+		}
+};
+
+class MakeIdentityRescaleFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	Uint16 maskInput;
+	Uint16 maskOutput;
+	float slope;
+	float intercept;
+public:
+	MakeIdentityRescaleFilter(float rescaleslope,float rescaleintercept,unsigned inputBits,unsigned outputBits)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			Assert(inputBits > 8);
+			Assert(inputBits <= 16);
+			maskInput = Uint16((Uint32(1)<<inputBits)-1u);
+			Assert(outputBits > 8);
+			Assert(outputBits <= 16);
+			maskOutput = Uint16((Uint32(1)<<outputBits)-1u);
+			
+			slope = rescaleslope;
+			intercept = rescaleintercept;
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			// assumes input is always unsigned (doesn't sign extend beyond mask)
+			float hu = (slope*(float)(value&maskInput)) + intercept;
+			return value=(Uint16)(hu)&maskOutput;
+		}
+};
+
+
+class InvertGrayscaleFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	Uint16 mask;
+public:
+	InvertGrayscaleFilter(Uint16 inputBits)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			Assert(inputBits > 0);
+			Assert(inputBits <= 16);
+			mask = Uint16((Uint32(1)<<inputBits)-1u);
+			
+		}
+
+	Uint16 filter(Uint16 value)
+		{
+			return value=(Uint16)(mask - (value&mask));
+		}
+};
+
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool bad = false;
+	
+	unsigned bits=0;
+	bool operation_maskhighbits=options.get("maskhighbits",bits);
+
+	int offset=0;
+	bool operation_addvalueoffset=options.get("addvalueoffset",offset);
+
+	int valuetozero=0;
+	bool operation_zerovalue=options.get("zerovalue",valuetozero);
+
+	int valuetostartreplace = 0;
+	int valuetoendreplace = 0;
+	int replacementvalue = 0;
+	bool operation_replacevalue=false;
+	{
+		int replacevalueArgs[3];
+		int n = options.get("replacevalue",replacevalueArgs,3);
+		if (n > 0) {
+			if (n == 3) {
+				operation_replacevalue=true;
+				valuetostartreplace = replacevalueArgs[0];
+				valuetoendreplace = replacevalueArgs[1];
+				replacementvalue = replacevalueArgs[2];
+			}
+			else {
+				cerr << "replacevalue needs 3 arguments, not " << dec << n << endl;
+				bad=true;
+			}
+		}
+	}
+
+	float scalefactor=1.0;
+	bool operation_scale=options.get("scale",scalefactor);
+
+	bool operation_makeidentityrescale=options.get("makeidentityrescale");
+	
+	bool operation_invertgrayscale=options.get("invertgrayscale");
+
+	int operation_count = 
+		  (operation_maskhighbits ? 1 : 0)
+		+ (operation_addvalueoffset ? 1 : 0)
+		+ (operation_zerovalue ? 1 : 0)
+		+ (operation_replacevalue ? 1 : 0)
+		+ (operation_scale ? 1 : 0)
+		+ (operation_makeidentityrescale ? 1 : 0)
+		+ (operation_invertgrayscale? 1 : 0)
+		;
+
+	if (operation_count > 1) {
+		cerr << "Error: Can only request one operation" << endl;
+		bad = true;
+	}
+	
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	bool pixelpaddingvalue=options.get("pixelpaddingvalue");
+	if (operation_makeidentityrescale) {
+		pixelpaddingvalue = true;
+	}
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [-pixelpaddingvalue]"
+			<< " [-maskhighbits bits]"
+			<< " [-addvalueoffset offset]"
+			<< " [-zerovalue value]"
+			<< " [-replacevalue startvalue endvalue newvalue]"
+			<< " [-scale scalefactor]"
+			<< " [-makeidentityrescale]"
+			<< " [-invertgrayscale]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+
+	if (success) {
+		PointFilterIndependentOfOffset<Uint16,Uint16> *filter = 0;
+		if (operation_maskhighbits) {
+			filter = new MaskHighBitFilter(bits);
+		}
+		else if (operation_addvalueoffset) {
+			filter = new AddValueOffsetFilter(offset);
+		}
+		else if (operation_zerovalue) {
+			filter = new ZeroValueFilter(valuetozero);
+		}
+		else if (operation_replacevalue) {
+			filter = new ReplaceValueFilter(valuetostartreplace,valuetoendreplace,replacementvalue);
+		}
+		else if (operation_scale) {
+			filter = new ScaleValueFilter(scalefactor);
+		}
+		else if (operation_makeidentityrescale) {
+			Uint16 vBitsStored = AttributeValue(list[TagFromName(BitsStored)]);
+			float vRescaleSlope = AttributeValue(list[TagFromName(RescaleSlope)]);
+			float vRescaleIntercept = AttributeValue(list[TagFromName(RescaleIntercept)]);
+			Uint16 newBitsStored = 16;
+			filter = new MakeIdentityRescaleFilter(vRescaleSlope,vRescaleIntercept,vBitsStored,newBitsStored);
+			list -= TagFromName(RescaleSlope);
+			list -= TagFromName(RescaleIntercept);
+			list -= TagFromName(PixelRepresentation);
+			list -= TagFromName(BitsStored);
+			list -= TagFromName(HighBit);
+			list += new DecimalStringAttribute(TagFromName(RescaleSlope),1.0);
+			list += new DecimalStringAttribute(TagFromName(RescaleIntercept),0.0);
+			list += new UnsignedShortAttribute(TagFromName(PixelRepresentation),1);
+			list += new UnsignedShortAttribute(TagFromName(BitsStored),newBitsStored);
+			list += new UnsignedShortAttribute(TagFromName(HighBit),newBitsStored-1);
+			// NB. do not forget to setSuppressScalingOnBitDepthConversion() later, else any switch in bit depth will cause undesirable scaling
+		}
+		else if (operation_invertgrayscale) {
+			Attribute *aBitsStored = list[TagFromName(BitsStored)];
+			Assert(aBitsStored);
+			Uint16 vBitsStored = AttributeValue(aBitsStored);
+			filter = new InvertGrayscaleFilter(vBitsStored);
+		}
+		Assert(filter);
+		
+		if (pixelpaddingvalue) {
+			Attribute *aPixelPaddingValue = list[TagFromName(PixelPaddingValue)];
+			if (aPixelPaddingValue) {
+				Uint16 vPixelPaddingValue = AttributeValue(aPixelPaddingValue);
+				vPixelPaddingValue = filter->filter(vPixelPaddingValue);
+				list -= TagFromName(PixelPaddingValue);
+				list += new UnspecifiedShortAttribute(TagFromName(PixelPaddingValue),vPixelPaddingValue);
+			}
+		}
+
+		Attribute *aPixelData = list[TagFromName(PixelData)];
+
+		if (aPixelData) {
+			OtherUnspecifiedLargeAttributeBase *oPixelData = 0;
+
+			if (!aPixelData->isOtherData()) {
+				log << EMsgDC(PixelDataIncorrectVR) << endl;
+				success=false;
+			}
+			else {
+				oPixelData = aPixelData->castToOtherData();
+				Assert(oPixelData);
+				oPixelData->insertPixelPointTransform(filter);
+				oPixelData->setSuppressScalingOnBitDepthConversion(operation_makeidentityrescale);
+			}
+		}
+		else {
+			log << EMsgDC(MissingAttribute)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcarith.man b/appsrc/dcfile/dcarith.man
new file mode 100755
index 0000000..5571558
--- /dev/null
+++ b/appsrc/dcfile/dcarith.man
@@ -0,0 +1,121 @@
+.TH DCARITH 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Arithmetic on DICOM pixels"
+.SH NAME
+dcarith \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Arithmetic on DICOM pixels
+.SH SYNOPSIS
+.HP 10
+.B dcarith
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-ignorereaderrors
+]
+[
+.B \-maskhighbits bits
+]
+[
+.B \-addvalueoffset offset
+]
+[
+.B \-zerovalue value
+]
+[
+.B \-replacevalue startvalue endvalue newvalue
+]
+[
+.B \-scale scalefactor
+]
+[
+.B \-makeidentityrescale
+]
+[
+.B \-invertgrayscale
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcarith
+reads the named dicom or acr-nema input file and copies the information and
+pixel data to a new dicom file, performing the same arithmetic computation on
+all of the pixel data values (i.e., a point operation).
+.LP
+Note that the command only changes the stored pixel values in PixelData, and does not
+affect any other attributes, including PixelPaddingValue, except as described
+below for specific options. This means that other attributes that describe the
+pixel data may need to be changed manually (using, for example, the \-r option).
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.TP
+.B \-ignorereaderrors
+.RS
+Normally dccp stops if read errors are encountered, but if this option is
+turned on, it will try to write what it can. This may be useful to remove
+trailing garbage after a valid dicom set that has been padded past the
+pixel data (e.g. to a blocksize) or similar.
+.RE
+.TP
+.B \-pixelpaddingvalue
+.RS
+Apply the same operation to PixelPaddingValue as well as the stored pixel values. Implied by \-makeidentityrescale.
+.RE
+.TP
+.B \-maskhighbits bits
+.RS
+Set to zero all bits above (to the left of) the specified bit.
+.RE
+.TP
+.B \-addvalueoffset offset
+.RS
+Add a fixed offset value to all pixels.
+.RE
+.TP
+.B \-zerovalue value
+.RS
+Sets all stored pixel values with the specified value to a new value of zero.
+.RE
+.TP
+.B \-replacevalue startvalue endvalue newvalue
+.RS
+Sets all stored pixel values greater than or equal to the start value and less than or equal to the end value to the specified new value.
+.RE
+.TP
+.B \-scale scalefactor
+.RS
+Multiply all stored pixel values by the specified scale factor (which may be a floating point value).
+.RE
+.TP
+.B \-makeidentityrescale
+.RS
+Determine from the existing RescaleSlope and RescaleIntercept values what computation to apply to the stored
+pixel values to make RescaleSlope 1 and RescaleIntercept 0, and apply that
+computation to the stored pixel values, setting PixelRepresentation to 1 (signed) and BitsStored to 16, regardless of their previous
+values. Also applies the same computation to PixelPaddingValue (i.e., implies \-pixelpaddingvalue).
+.RE
+.TP
+.B \-invertgrayscale
+.RS
+Invert the grayscale of the pixel values, using the BitsStored value to establish the range (i.e. a value of 0 is replaced by (2^BitsStored)-1 and vice versa).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcbriggs.cc b/appsrc/dcfile/dcbriggs.cc
new file mode 100644
index 0000000..ba7aa6a
--- /dev/null
+++ b/appsrc/dcfile/dcbriggs.cc
@@ -0,0 +1,160 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcbriggs.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+//#include "ioopt.h"
+#include "dcopt.h"
+
+#include "briggsrc.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	unsigned rows=512;
+	(void)(options.get("rows",rows) || options.get("x",rows));
+
+	unsigned cols=512;
+	(void)(options.get("cols",cols) || options.get("columns",cols) || options.get("y",cols));
+
+	unsigned bits=8;
+	(void)(options.get("bits",bits) || options.get("depth",bits) || options.get("d",bits));
+
+	if (bits < 1 || bits > 16) {
+		cerr << EMsgDC(OptionUnsupported) << " - bits = " << dec << bits << endl;
+		bad=true;
+	}
+
+	int minval=0;
+	(void)options.get("minval",minval);
+
+	int maxval=(int)(((long)(0x0001l)<<bits)-1);
+	(void)options.get("maxval",maxval);
+
+	bool wantsigned=options.get("signed");
+
+	bool wantinverted=options.get("invert") || options.get("inverted") || options.get("monochrome1");
+
+	unsigned contrast=7;
+	(void)options.get("contrast",contrast);
+	Assert(maxval-minval >= contrast);
+
+	unsigned surround=70;
+	(void)options.get("surround",surround);
+	Assert(surround <= 100);
+
+	unsigned background=30;
+	(void)options.get("background",background);
+	Assert(background <= 100);
+
+	dicom_output_options.done();
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_output_options.usage()
+			<< " [-rows|-y rows]"
+			<< " [-cols|-columns|-x columns]"
+			<< " [-bits|-depth|-d bits]"
+			<< " [-minval i]"
+			<< " [-mavxal i]"
+			<< " [-signed]"
+			<< " [-inverted|-invert|-monochrome1]"
+			<< " [-contrast value]"
+			<< " [-surround percent]"
+			<< " [-background percent]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(OutputFile) << "]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log(cerr);
+
+	Uint16 bitsAllocated=((bits-1)/8+1)*8;
+	Uint16 bitsStored=bits;
+	Uint16 highBit=bits-1;
+
+	list+=new UnsignedShortAttribute(TagFromName(BitsAllocated),bitsAllocated);
+	list+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsStored);
+	list+=new UnsignedShortAttribute(TagFromName(HighBit),highBit);
+	list+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	list+=new UnsignedShortAttribute(TagFromName(Columns),cols);
+	list+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),1u);
+	list+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),wantsigned?1u:0u);
+	list+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),wantinverted ? "MONOCHROME1":"MONOCHROME2");
+
+	// various Type 1 and Type 2 attributes for mandatory SC modules ...
+
+	list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+	list+=new LongStringAttribute(TagFromName(PatientID));
+	list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+	list+=new CodeStringAttribute(TagFromName(PatientSex));
+	list+=new ShortStringAttribute(TagFromName(StudyID));
+	list+=new DateStringAttribute(TagFromName(StudyDate));
+	list+=new TimeStringAttribute(TagFromName(StudyTime));
+	list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+	list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+	list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+	list+=new IntegerStringAttribute(TagFromName(InstanceNumber));
+
+	list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+	list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+
+	list+=new LongStringAttribute(TagFromName(Manufacturer));
+	list+=new CodeStringAttribute(TagFromName(PatientOrientation));
+
+	Briggs_PixelDataSource *pixeldatasrc=new Briggs_PixelDataSource(rows,cols,wantsigned,wantinverted,(Uint16)minval,(Uint16)maxval,
+						contrast,surround,background);
+	Assert(pixeldatasrc);
+
+	list+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1,
+		1,
+		&transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/dcbriggs.man b/appsrc/dcfile/dcbriggs.man
new file mode 100755
index 0000000..71cb451
--- /dev/null
+++ b/appsrc/dcfile/dcbriggs.man
@@ -0,0 +1,161 @@
+.TH DCBRIGGS 1 "6 March 2014" "DICOM PS3" "Create DICOM Briggs pattern"
+.SH NAME
+dcbriggs \- ACR/NEMA DICOM PS3 ... Create DICOM Briggs pattern
+.SH SYNOPSIS
+.HP 10
+.B dcbriggs
+.so man1/gen.so
+[
+.B \-columns|\-cols|\-x " columns"
+]
+[
+.B \-rows|\-y " rows"
+]
+[
+.B \-bits|\-depth|\-d " bits"
+]
+[
+.B \-minval " i"
+]
+[
+.B \-maxval " i"
+]
+[
+.B \-signed
+]
+[
+.B \-inverted|\-invert|\-monochrome1
+]
+[
+.B \-contrast " value"
+]
+[
+.B \-surround " percent"
+]
+[
+.B \-background " percent"
+]
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcbriggs
+writes a grayscale MONOCHROME2 or MONOCHROME1 Briggs 8-target pattern (BPT#4)
+as a DICOM
+Secondary Capture Image Storage SOP Class instance stored in a DICOM file. The
+format, rationale, use and scoring of a Briggs pattern are described in Boeing Technical
+Report D180-25066-1 by S.J. Briggs, January 1979. Basically a set of checkerboard
+patterns of varying spatial and contrast resolution are created in order to visually
+evaluate the quality of the system displaying the pattern.
+.LP
+During the creation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+.PP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.BI \-columns|\-cols|\-x " columns"
+.RS
+Defaults to 512.
+.RE
+.TP
+.BI \-rows|\-y " rows"
+.RS
+Defaults to 512.
+.RE
+.TP
+.BI \-bits|\-depth|\-d " bits"
+.RS
+Defaults to 8.
+.RE
+.TP
+.BI \-minval " i"
+.RS
+Defaults to 0. Specifies the pixel value to store for the 0% gray value in the Briggs pattern.
+.RE
+.TP
+.BI \-maxval " i"
+.RS
+Defaults to (2^bits)-1. Specifies the pixel value to store for the 100% gray value in the Briggs pattern.
+(Note this does not have to be (2^bits)-1).
+.RE
+.TP
+.BI \-signed
+.RS
+Treat the minval and maxval as signed and set the Pixel Representation
+in the DICOM image to signed.
+.RE
+.TP
+.BI \-inverted|\-invert|\-monochrome1
+.RS
+Invert the grayscale range and set the Photometric Interpretation
+to MONOCHROME1 (zero is white) rather than the default MONOCHROME2 (zero
+is black). The image should display the same in a DICOM viewer that
+correctly handles Photometric Interpretation.
+.RE
+.TP
+.BI \-contrast " value"
+.RS
+Optional. Specifies the target command contrast between light and dark checkers. Defaults
+to a value of 7. This corresponds to Briggs' C value.
+.RE
+.TP
+.BI \-surround " percent"
+.RS
+Optional. Specifies percent of maxval-minval used for the target surround. Should be an
+integer. Divided by 100, this corresponds to Briggs' S value. Defaults to 70%.
+.RE
+.TP
+.BI \-background " percent"
+.RS
+Optional. Specifies percent of maxval-minval used for the background and spacing
+between targets. Should be an
+integer. Defaults to 30%.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+# Create an 8 bit pattern from 0 to 255, ie. BPT#4(7,.7,256)
+.RE
+# and make a PGM and a GIF file from it using netpbm tools  ...
+.RE
+% dcbriggs -bits 8 -minval 0 -maxval 255 briggs.dc3
+.RE
+% dctopnm  briggs.dc3 briggs.pgm
+.RE
+% ppmtogif briggs.pgm > briggs.gif
+.RE
+\ 
+.RE
+# Create a 12 bit pattern from 0 to 4095 with a C of 112 and S of .55, ie. BPT#4(13,.55,4096) ...
+.RE
+% dcbriggs -bits 12 -minval 0 -maxval 4095 -contrast 112
+.RE
+\ 
+.RE
+# Create a 16 bit pattern from -1024 to 3071 with a C of 112 and S of .55 ...
+.RE
+% dcbriggs -bits 16 -minval ' -1024' -maxval 3071 -signed -contrast 112 -surround 55
+.RE
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dciodvfy(1) ,
+.BR dcsmpte(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcburn.cc b/appsrc/dcfile/dcburn.cc
new file mode 100644
index 0000000..3c36e50
--- /dev/null
+++ b/appsrc/dcfile/dcburn.cc
@@ -0,0 +1,161 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcburn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+class BurnInOverlaysFilter : public PointFilterDependentOnOffset<Uint16,Uint16> {
+private:
+	Uint16 valuetoburnin;
+	const Uint16 *graphics_buffer;
+	unsigned long graphics_buffer_size;
+public:
+	BurnInOverlaysFilter(int v,const Uint16 *b,unsigned long s)
+			: PointFilterDependentOnOffset<Uint16,Uint16>()
+		{
+			valuetoburnin=Uint16(v);
+			graphics_buffer=b;
+			graphics_buffer_size=s;
+//cerr << "BurnInOverlaysFilter::BurnInOverlaysFilter(): v=" << dec << v << endl;
+//cerr << "BurnInOverlaysFilter::BurnInOverlaysFilter(): value=0x" << hex << value << dec << endl;
+		}
+
+	Uint16 filter(Uint16 originalvalue,size_t offset)
+		{
+			unsigned long wordOffset = offset/16;
+			Assert(wordOffset < graphics_buffer_size);
+			Uint16 bit = (graphics_buffer[wordOffset] >> (offset%16)) & 0x0001;
+		
+			return bit ? valuetoburnin : originalvalue;
+		}
+};
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	int valuetoburnin=0xffff;
+	options.get("value",valuetoburnin);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [-value value]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+
+	if (success) {
+	
+		PointFilterDependentOnOffset<Uint16,Uint16> *filter = 0;
+
+		// should check Tag(OverlayRows_GROUP+u,OverlayRows_ELEMENT) = Rows
+		// should check Tag(OverlayColumns_GROUP+u,OverlayColumns_ELEMENT) = Rows
+		// should check Tag(OverlayType_GROUP+u,OverlayType_ELEMENT) = "G"
+		// should check Tag(OverlayBitsAllocated_GROUP+u,OverlayBitsAllocated_ELEMENT) = 1
+		// should check Tag(OverlayBitPosition_GROUP+u,OverlayBitPosition_ELEMENT) = 0
+		// should check Tag(OverlayOrigin_GROUP+u,OverlayOrigin_ELEMENT) = 1\1
+	
+		unsigned u=0x0000;	// Burn in only Overlay Group 0x6000 for now
+		Attribute *aOverlayData = list[Tag(OverlayData_GROUP+u,OverlayData_ELEMENT)];
+		if (aOverlayData) {
+			unsigned long graphics_buffer_size;
+			const Uint16 *graphics_buffer;
+			aOverlayData->getValue(graphics_buffer,graphics_buffer_size);
+			Assert(graphics_buffer);
+			
+			filter = new BurnInOverlaysFilter(valuetoburnin,graphics_buffer,graphics_buffer_size);
+			Assert(filter);
+		}
+	
+		Attribute *aPixelData = list[TagFromName(PixelData)];
+
+		if (aPixelData) {
+			OtherUnspecifiedLargeAttributeBase *oPixelData = 0;
+
+			if (!aPixelData->isOtherData()) {
+				log << EMsgDC(PixelDataIncorrectVR) << endl;
+				success=false;
+			}
+			else {
+				oPixelData = aPixelData->castToOtherData();
+				Assert(oPixelData);
+				if (filter) oPixelData->insertPixelPointTransform(filter);
+			}
+		}
+		else {
+			log << EMsgDC(MissingAttribute)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcburn.man b/appsrc/dcfile/dcburn.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcbzip2.man b/appsrc/dcfile/dcbzip2.man
new file mode 100755
index 0000000..7379e0b
--- /dev/null
+++ b/appsrc/dcfile/dcbzip2.man
@@ -0,0 +1,30 @@
+.TH dcbzip2 1 "23 Feb 2003" "DICOM PS3" "DICOM PS3 - Create bzip2 DICOM file"
+.SH NAME
+dcbzip2 \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create bzip2 DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcbzip2 "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcbzip2
+reads the named dicom or acr-nema input file and copies the information and
+pixel data to a new dicom file, with the dataset compressed using the bzip2
+transfer syntax, and a meta information header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcunbzip2(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcbzip2.script b/appsrc/dcfile/dcbzip2.script
new file mode 100755
index 0000000..37ae59c
--- /dev/null
+++ b/appsrc/dcfile/dcbzip2.script
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# usage: dcbzip2 infile outfile
+#
+#
+TMPROOT=/tmp/`basename $0`.$$
+
+DCCP=dccp
+BZIP2=bzip2
+
+$DCCP $1 -justmeta -ra TransferSyntaxUID "1.3.6.1.4.1.5962.300.1" >$2
+$DCCP $1 -nometa -output-vr explicit -output-endian little | $BZIP2 >$TMPROOT.1.tmp
+dd if=$TMPROOT.1.tmp ibs=2 skip=1 of=$TMPROOT.2.tmp 2>/dev/null
+rm $TMPROOT.1.tmp
+cat $TMPROOT.2.tmp >>$2
+rm $TMPROOT.2.tmp
diff --git a/appsrc/dcfile/dcckovly.man b/appsrc/dcfile/dcckovly.man
new file mode 100755
index 0000000..2c15dcf
--- /dev/null
+++ b/appsrc/dcfile/dcckovly.man
@@ -0,0 +1,36 @@
+.TH dcckovly 1 "26 October 2010" "DICOM PS3" "DICOM PS3 - Check for overlays, curves, graphics"
+.SH NAME
+dcckovly \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Check for overlays, curves and graphic annotations
+.SH SYNOPSIS
+.HP 10
+.B dcckovly "infile"
+.SH DESCRIPTION
+.LP
+.B dcckovly
+reads the named dicom and looks for evidence of overlays, curves or graphic annotation sequences (which,
+though non-standard in images, some vendors add as standard extended sop classes, as well as
+some known private annotation elements
+checking the high bits above Bits Stored for non-zero values (since these might be remnants
+of overlays), and checking the Overlay Data for non-zero or only zero bits.
+The output consists of a dump of related attributes if present, a specific message if
+non-zero high bits, and a specific message if non-zero overlay data bits are found,
+and a warning if the file is encapuslated.
+.SH OPTIONS
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+\ 
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Cannot detect non-zero high bits in encapsulated images.
diff --git a/appsrc/dcfile/dcckovly.script b/appsrc/dcfile/dcckovly.script
new file mode 100755
index 0000000..410aa66
--- /dev/null
+++ b/appsrc/dcfile/dcckovly.script
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# check for (60xx,xxxx), (50xx,xxxx) or (0070,xxxx)
+# check for any private annotation data elements (e.g. Agfa/Mitra)
+# check for any non-zero high bits above BitsStored that might be overlays
+# check for any non-zero bits in OverlayData
+
+TMPFILE="/tmp/`basename $0`.$$.tmp"
+
+echo "$1"
+dcdump -ignoreoutofordertags "$1" 2>&1 | egrep -iv '(warning|error)' | egrep '^[(]0x([5-6]0[0-9a-fA-F][0-9a-fA-F]|0070)'
+dcdump -ignoreoutofordertags "$1" 2>&1 | egrep -iv '(warning|error)' | grep 'MITRA MARKUP 1.0'
+
+isEncapsulated=`dcfile "$1" 2>&1 | grep 'Data: Encapsulated' | awk '{print $3}'`
+if [ -z "${isEncapsulated}" -o "${isEncapsulated}" = "No" ]
+then
+	bitsStored=`dckey -noerror -decimal -k BitsStored "$1" 2>&1 | egrep -iv '(warning|error)'`
+	bitsAllocated=`dckey -noerror -decimal -k BitsAllocated "$1" 2>&1 | egrep -iv '(warning|error)'`
+	#echo "bitsStored    = <${bitsStored}>"
+	#echo "bitsAllocated = <${bitsAllocated}>"
+	if [ ! -z "${bitsStored}" -a ! -z "${bitsAllocated}" ]
+	then
+		if [ "${bitsStored}" -ne "${bitsAllocated}" ]
+		then
+			#echo "Checking for non-zero high bits"
+			rm -f "${TMPFILE}"
+			dcarith -maskhighbits "${bitsStored}" "$1" "${TMPFILE}" 2>&1 | egrep -iv '(warning|error)'
+			comparison=`dccmp "$1" "${TMPFILE}" 2>&1`
+			if [ ! -z "${comparison}" ]
+			then
+				echo "######### Contains non-zero high bits"
+			fi
+			rm -f "${TMPFILE}"
+		fi
+	#else
+	#	echo "Warning: not a (valid) DICOM image file, so not checking high bits"
+	fi
+else
+	echo "Warning: An encapsulated (compressed) file, so not checking high bits"
+fi
+
+overlaydataattributesarepresent=`dcdump -ignoreoutofordertags "$1" 2>&1 | egrep -iv '(warning|error)' | egrep '^[(]0x60[0-9a-fA-F][0-9a-fA-F],0x3000[)]'`
+if [ ! -z "${overlaydataattributesarepresent}" ]
+then
+	nonzerooverlaydata=`dckey -noerror \
+		-k '(0x6000,0x3000)' \
+		-k '(0x6002,0x3000)' \
+		-k '(0x6004,0x3000)' \
+		-k '(0x6006,0x3000)' \
+		-k '(0x6008,0x3000)' \
+		-k '(0x600A,0x3000)' \
+		-k '(0x600C,0x3000)' \
+		-k '(0x600E,0x3000)' "$1" 2>&1 \
+		| grep -v '0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000' | egrep -v '^[ ]*$'`
+	if [ ! -z "${nonzerooverlaydata}" ]
+	then
+		echo "######### Overlay Data contains non-zero bits"
+	else
+		echo "######### Overlay Data contains only zero bits"
+	fi
+fi
+
diff --git a/appsrc/dcfile/dccmp.man b/appsrc/dcfile/dccmp.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dccmp.script b/appsrc/dcfile/dccmp.script
new file mode 100755
index 0000000..1ea05bf
--- /dev/null
+++ b/appsrc/dcfile/dccmp.script
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# compare the binary pixel data of two dicom files
+
+if [ $# != 2 ]
+then
+	echo "usage: `basename $0` file1 file2"
+	exit 1
+fi
+
+TMPFILE1=/tmp/`basename $0`.$$.tmp1
+TMPFILE2=/tmp/`basename $0`.$$.tmp2
+
+dctoraw -ignoreoutofordertags "$1" >"$TMPFILE1" 2>/dev/null
+dctoraw -ignoreoutofordertags "$2" >"$TMPFILE2" 2>/dev/null
+cmp "$TMPFILE1" "$TMPFILE2"
+
+rm "$TMPFILE1" "$TMPFILE2"
+
+exit 0
+
diff --git a/appsrc/dcfile/dccomb.cc b/appsrc/dcfile/dccomb.cc
new file mode 100644
index 0000000..78fbee9
--- /dev/null
+++ b/appsrc/dcfile/dccomb.cc
@@ -0,0 +1,324 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dccomb.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "srcsink.h"
+#include "elmconst.h"
+
+template<class Tin1,class Tin2,class Tout>
+class FilterTwoSourcesToSinkBufferedBase : public SourceBuffered<Tout> {
+protected:
+	SourceBase<Tin1> *src1;
+	SourceBase<Tin2> *src2;
+public:
+	FilterTwoSourcesToSinkBufferedBase(SourceBase<Tin1>& i1,SourceBase<Tin2>& i2): SourceBuffered<Tout>() {
+//cerr << "FilterTwoSourcesToSinkBufferedBase::FilterTwoSourcesToSinkBufferedBase()\n" << flush;
+		src1=&i1;
+		src2=&i2;
+	}
+};
+
+template<class Tin1,class Tin2,class Tout>
+class CombineFilter {
+public:
+	CombineFilter() {}
+	virtual Tout filter(Tin1,Tin2) = 0;
+};
+
+
+template<class Tin1,class Tin2,class Tout>
+class ConvertTwoSourcesToSinkWithFilter : public FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout> {
+private:
+	CombineFilter<Tin1,Tin2,Tout> *filter;
+public:
+	ConvertTwoSourcesToSinkWithFilter(SourceBase<Tin1>& i1,SourceBase<Tin2>& i2,CombineFilter<Tin1,Tin2,Tout> *f)
+			: FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>(i1,i2)
+		{
+//cerr << "ConvertTwoSourcesToSinkWithFilter::ConvertTwoSourcesToSinkWithFilter\n" << flush;
+			Assert(f);
+			filter=f;
+		}
+
+	size_t read(void)
+		{
+//cerr << "ConvertTwoSourcesToSinkWithFilter::read(void)\n" << flush;
+			FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::buffer.clear();
+			//Assert(FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src1);
+			//Assert(FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src2);
+			if (FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src1->read() && FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src2->read()) {
+//cerr << "ConvertTwoSourcesToSinkWithFilter::read(void) success\n" << flush;
+				size_t n1=FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src1->getBufferCount();
+//cerr << "ConvertTwoSourcesToSinkWithFilter::read(void) source 1: " << n1 << " values\n" << flush;
+				const Tin1 *inptr1=FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src1->getBuffer();
+				size_t n2=FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src2->getBufferCount();
+//cerr << "ConvertTwoSourcesToSinkWithFilter::read(void) source 2: " << n2 << " values\n" << flush;
+				const Tin2 *inptr2=FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src2->getBuffer();
+				while (n1-- && n2--) FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::buffer.add((Tout)(filter->filter(*inptr1++,*inptr2++)));
+			}
+//cerr << "ConvertTwoSourcesToSinkWithFilter::read(void) return " << getBufferCount() << " values\n" << flush;
+			return FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::getBufferCount();
+		}
+
+	int good(void) const	{
+//cerr << "ConvertTwoSourcesToSinkWithFilter::good(void)\n" << flush;
+		//Assert(FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src1);
+		//Assert(FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src2);
+		return FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src1->good() && FilterTwoSourcesToSinkBufferedBase<Tin1,Tin2,Tout>::src2->good();
+	}
+};
+
+// our versions of filter ...
+
+class OurCombineFilter : public CombineFilter<Uint16,Uint16,Uint16> {
+private:
+	double firstMultiplier;
+	double secondMultiplier;
+	Uint16 secondOffset;
+	Uint16 thresholdSecond;
+public:
+	OurCombineFilter(Uint16 useBitsFirst,Uint16 useBitsSecond,Uint16 thresholdSecond,Uint16 newFirstHighestValue,Uint16 newBits)
+			: CombineFilter<Uint16,Uint16,Uint16>()
+		{
+			Assert(useBitsFirst > 0);
+			Assert(useBitsSecond > 0);
+			Assert(newFirstHighestValue > 0);
+			Assert(newBits > 0);
+			Assert(useBitsFirst <= 16);
+			Assert(useBitsSecond <= 16);
+			Assert(newFirstHighestValue <= 0xffff);
+			Assert(newBits <= 16);
+			
+			Assert(newFirstHighestValue < 1l<<newBits);
+			
+			Assert(thresholdSecond < 1l<<useBitsSecond);
+			this->thresholdSecond=thresholdSecond;
+
+			firstMultiplier=double(newFirstHighestValue)/(1l<<useBitsFirst);
+			secondMultiplier=(double(1l<<newBits) - 1 - newFirstHighestValue)/(1l<<useBitsSecond);
+			secondOffset=newFirstHighestValue+1;
+//cerr << "OurCombineFilter::OurCombineFilter() firstMultiplier = " << dec << firstMultiplier << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() secondMultiplier = " << dec << secondMultiplier << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() secondOffset = " << dec << secondOffset << endl;
+
+//cerr << "OurCombineFilter::OurCombineFilter() lowest first = " << dec << filter(0,0) << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() highest first = " << dec << filter(Uint16(1l<<useBitsFirst)-1,0) << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() lowest second = " << dec << filter(0,thresholdSecond) << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() highest second = " << dec << filter(0,Uint16(1l<<useBitsSecond)-1) << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() count of possible second values after offset = " << dec << (filter(0,Uint16(1l<<useBitsSecond)-1) - secondOffset + 1) << endl;
+//cerr << "OurCombineFilter::OurCombineFilter() count of possible second values after threshold = " << dec << (filter(0,Uint16(1l<<useBitsSecond)-1) - filter(0,thresholdSecond) + 1) << endl;
+		}
+
+	Uint16 filter(Uint16 value1,Uint16 value2)
+		{
+			return Uint16(value2 >= thresholdSecond ? value2*secondMultiplier+secondOffset : value1*firstMultiplier);
+		}
+};
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static const char *
+getStringValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	const char *value=AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	return a ? value : "";
+}
+
+static Uint16
+getIntegerValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	Uint16 value=AttributeValue(a);
+	return value;
+}
+
+static Uint16
+getMatchingIntegerValueElseError(AttributeList &list1,AttributeList &list2,Tag tag,const char *label,const char *filename1,const char *filename2,TextOutputStream &log) {
+	Uint16 v1 = getIntegerValueElseError(list1,tag,label,filename1,log);
+	Uint16 v2 = getIntegerValueElseError(list2,tag,label,filename2,log);
+	if (v1 != v2) {
+		log << EMsgDC(DifferentValues)
+		    << " - " << label
+		    << " (" << dec << v1 << "," << v2 << ")"
+		    << endl;
+		return 0;
+	}
+	else {
+		return v1;
+	}
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	bool bad = false;
+	
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options1(options);
+	DicomInputOptions 	dicom_input_options2(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	int useBitsFirst;
+	int useBitsSecond;
+	int thresholdSecond;
+	int newFirstHighestValue;
+	int newBits;
+
+	bad = bad || !options.get("usebitsfirst",useBitsFirst);
+	bad = bad || !options.get("usebitssecond",useBitsSecond);
+	bad = bad || !options.get("thresholdsecond",thresholdSecond);
+	bad = bad || !options.get("newfirsthighestvalue",newFirstHighestValue);
+	bad = bad || !options.get("newbits",newBits);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	dicom_input_options1.done();
+	dicom_input_options2.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener1(
+		options,dicom_input_options1.filename);
+	DicomInputOpenerFromOptions input_opener2(
+		options,dicom_input_options2.filename);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options1.errors();
+	cerr << dicom_input_options2.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener1.errors();
+	cerr << input_opener2.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options1.good()
+	 || !dicom_input_options2.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener1.good()
+	 || !input_opener2.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options1.usage()
+			<< dicom_input_options2.usage()
+			<< dicom_output_options.usage()
+			<< " -usebitsfirst n"
+			<< " -usebitssecond n"
+			<< " -thresholdsecond n"
+			<< " -newfirsthighestvalue n"
+			<< " -newbits n"
+			<< " [-v|-verbose]"
+			<< MMsgDC(InputFile) << " " << MMsgDC(InputFile)
+			<< "[" << MMsgDC(OutputFile) << "]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din1(*(istream *)input_opener1,
+		dicom_input_options1.transfersyntaxuid,
+		dicom_input_options1.usemetaheader);
+	DicomInputStream din2(*(istream *)input_opener2,
+		dicom_input_options2.transfersyntaxuid,
+		dicom_input_options2.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+		
+	const char *file1 = dicom_input_options1.filename ? dicom_input_options1.filename : "1st file";
+	const char *file2 = dicom_input_options2.filename ? dicom_input_options2.filename : "2nd file";
+
+	ManagedAttributeList list1;
+	ManagedAttributeList list2;
+	
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading 1st dataset ... ********" << endl; 
+	list1.read(din1,&log,verbose,0xffffffff,true,dicom_input_options1.uselengthtoend,dicom_input_options1.ignoreoutofordertags);
+	if (verbose) log << "******** While reading 2nd dataset ... ********" << endl; 
+	list2.read(din2,&log,verbose,0xffffffff,true,dicom_input_options2.uselengthtoend,dicom_input_options2.ignoreoutofordertags);
+
+	if (!list1.good()) {
+		log << list1.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	if (!list2.good()) {
+		log << list2.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	Uint16 rows;
+	Uint16 cols;
+	if (success) {
+		rows = getMatchingIntegerValueElseError(list1,list2,TagFromName(Rows),"Rows",file1,file2,log);
+		cols = getMatchingIntegerValueElseError(list1,list2,TagFromName(Columns),"Columns",file1,file2,log);
+		if (!rows || !cols) success=false;
+	}
+	if (success) {
+		Uint16 frames = 1;
+		Uint16 samples = 1;
+		Uint16 bitsAllocated = 16;
+		Uint16 bitsStored = 16;
+		Uint16 highBit = 15;
+
+		Attribute *aPixelData1 = list1[TagFromName(PixelData)];
+		Attribute *aPixelData2 = list2[TagFromName(PixelData)];
+	
+		aPixelData1->castToOtherData()->activateSource();
+		class SourceBase<Uint16> *srcpixeldata1 = aPixelData1->castToOtherData()->get16BitSource();
+		Assert(srcpixeldata1);
+		aPixelData2->castToOtherData()->activateSource();
+		class SourceBase<Uint16> *srcpixeldata2 = aPixelData2->castToOtherData()->get16BitSource();
+		Assert(srcpixeldata2);
+
+		CombineFilter<Uint16,Uint16,Uint16> *filter = new OurCombineFilter(useBitsFirst,useBitsSecond,thresholdSecond,newFirstHighestValue,newBits);
+	
+		class SourceBase<Uint16> *srcpixeldatatouse = new ConvertTwoSourcesToSinkWithFilter<Uint16,Uint16,Uint16>(*srcpixeldata1,*srcpixeldata2,filter);
+		TransferSyntax transfersyntax(
+			dicom_output_options.transfersyntaxuid
+			? dicom_output_options.transfersyntaxuid
+			: DefaultTransferSyntaxUID);
+
+		list1-=TagFromName(PixelData);
+		list1+=new OtherUnspecifiedLargeAttribute(
+			TagFromName(PixelData),
+			srcpixeldatatouse,
+			rows,
+			cols,
+			frames,
+			samples,
+			&transfersyntax,
+			0,bitsAllocated,bitsStored,highBit);
+
+		if (!usualManagedAttributeListWrite(list1,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dccomb.man b/appsrc/dcfile/dccomb.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dccp.cc b/appsrc/dcfile/dccp.cc
new file mode 100644
index 0000000..695dc02
--- /dev/null
+++ b/appsrc/dcfile/dccp.cc
@@ -0,0 +1,210 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dccp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+void
+keepOnlySelectedLUTSequenceItem(AttributeList &list,Tag lutSequenceTag,int whichLUTItemToKeep,TextOutputStream &log) {
+	Attribute *aLUTSequence = list[lutSequenceTag];
+	if (aLUTSequence) {
+		AttributeList **items;
+		int nLUTItems=aLUTSequence->getLists(&items);
+		if (whichLUTItemToKeep >= 0 && whichLUTItemToKeep < nLUTItems) {
+			AttributeList *itemToKeep = items[whichLUTItemToKeep];
+			SequenceAttribute *newLUTSequence = new SequenceAttribute(lutSequenceTag);
+			Assert(newLUTSequence);
+			(*newLUTSequence)+=itemToKeep;
+			list-=lutSequenceTag;
+			list+=newLUTSequence;
+		}
+		else {
+			log << WMsgDC("Missing LUT Sequence Item") << " - " << lutSequenceTag << " # " << whichLUTItemToKeep << endl;
+		}
+	}
+	else {
+		log << WMsgDC("Missing LUT Sequence") << " - " << lutSequenceTag << endl;
+	}
+}
+
+// writeTagNumberAndNameToLog is copied from appsrc/dcfile/dciodvfy.cc
+// Similar to TextOutputStream& Tag::write(TextOutputStream& stream,ElementDictionary *dict) in libsrc/src/dctool/attrtag.cc
+// but without the VR
+
+static void writeTagNumberAndNameToLog(Tag tag,ElementDictionary *dict,TextOutputStream &log) {
+	log << "(";
+	writeZeroPaddedHexNumber(log,tag.getGroup(),4);
+	log << ",";
+	writeZeroPaddedHexNumber(log,tag.getElement(),4);
+	log << ")";
+	const char *desc = NULL;
+	if (dict) {
+		desc = dict->getDescription(tag);
+	}
+	if (desc && strlen(desc) > 0 && strcmp(desc,"?") != 0) {
+		log << " " << desc;
+	}
+}
+
+static void writeTagNumberAndNameToLog(Attribute *a,ElementDictionary *dict,TextOutputStream &log) {
+	writeTagNumberAndNameToLog(a->getTag(),dict,log);
+}
+
+// loopOverListsInSequencesWithLog is copied from libsrc/src/dctool/attrmxls.cc
+
+static bool
+loopOverListsInSequencesWithLog(Attribute *a,TextOutputStream &log,
+		bool (*func)(AttributeList &,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+fixBadDecimalSeparator(AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (strcmp(a->getVR(),"DS") == 0) {
+			int vm = a->getVM();
+			int i;
+			for (i=0; i<vm; ++i) {
+				char *value;
+				a->getValue(i,value);
+				bool changedsomething=false;
+				char *p = value;
+				while (*p != 0) {
+					if (*p == ',') {
+						*p='.';
+						changedsomething=true;
+					}
+					++p;
+				}
+				if (changedsomething) {
+					log << WMsgDC(FixingBadDecimalSeparator) << " in DS VR - ";
+					writeTagNumberAndNameToLog(a,list.getDictionary(),log);
+					log << " - new value " << (i+1) << " is \"" << value << "\"" << endl;
+					a->setValue(i,value);
+				}
+			}
+		}
+		if (!::loopOverListsInSequencesWithLog(a,log,&::fixBadDecimalSeparator)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	bool removecommandgroup=options.get("removecommandgroup");
+	bool fixbaddecimalseparator=options.get("fixbaddecimalseparator");
+
+	int whichVOILUTitem=0;
+	bool selectVOILUTitem=options.get("selectvoilutitem",whichVOILUTitem);
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [-removecommandgroup]"
+			<< " [-selectvoilutitem 0..n-1]"
+			<< " [-fixbaddecimalseparator]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+
+	if (success) {
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+		
+		if (removecommandgroup) {
+			list.removeCommandGroup();
+		}
+		
+		if (selectVOILUTitem) {
+			keepOnlySelectedLUTSequenceItem(list,TagFromName(VOILUTSequence),whichVOILUTitem,log);
+		}
+		
+		if (fixbaddecimalseparator) {
+			fixBadDecimalSeparator(list,log);
+		}
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
diff --git a/appsrc/dcfile/dccp.man b/appsrc/dcfile/dccp.man
new file mode 100755
index 0000000..762527a
--- /dev/null
+++ b/appsrc/dcfile/dccp.man
@@ -0,0 +1,195 @@
+.TH DCCP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Copy DICOM file"
+.SH NAME
+dccp \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Copy DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dccp
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-ignorereaderrors
+]
+[
+.B \-removecommandgroup
+]
+[
+.B \-fixbaddecimalseparator
+]
+[
+.B \-selectvoilutitem 0..n\-1
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dccp
+reads the named dicom or acr-nema input file and copies the information and
+pixel data to a new dicom file.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The encoding of the file will be changed to the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options. This provides a means of converting between different transfer
+syntaxes, and adding or removing Part 10 style meta-information headers
+to or from "true" DICOM files, DICOM messages captured from network
+exchanges such as with the Mallinckrodt or Oldenburg central test node
+software, or converting old ACR/NEMA or SPI files.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows pre-DICOM
+ACR-NEMA or SPI files to be converted to DICOM files containing
+conforming instances of SOP classes in a semi-automated manner. If patient and study information is present (indicating a composite IOD), and the
+SOP Class can be automatically determined, such as for CT or MR images,
+specific SOP Class instances will be created, otherwise SC will be used.
+Unique study, series and instance identifiers will be generated from a
+time stamp, but can be overridden by command line options to allow for
+shared identifiers between files of a series.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.TP
+.B \-ignorereaderrors
+.RS
+Normally dccp stops if read errors are encountered, but if this option is
+turned on, it will try to write what it can. This may be useful to remove
+trailing garbage after a valid dicom set that has been padded past the
+pixel data (e.g. to a blocksize) or similar.
+.RE
+.TP
+.B \-removecommandgroup
+.RS
+Normally dccp will created an invalid copy if the input is in implicit VR and erroneously has
+command group (0x0000) elements at the head of the dataset (e.g. if the both the command
+and dataset network PDUs were saved to a file), since the command group elements will get
+inserted in fromt of the meta information header. Use this option to remove command group
+elements (whether or not a meta information header is added).
+.RE
+.TP
+.B \-fixbaddecimalseparator
+.RS
+Sometimes illegal DS VR values are encountered that use a Locale-specific decimal separator of "," (such as might be displayed in France, Italy, Brazil, etc.) rather
+than the period "." required by the standard; this option can be used to fix these.
+.RE
+.TP
+.B \-selectvoilutitem 0..n\-1
+.RS
+Keep only the selected VOI LUT Sequence Item, where the items are numbered from 0.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% echo Adds meta-information header by default
+.RE
+% dccp -v NM.dc3 NM2.dc3
+.RE
+******** While reading ... ********
+.RE
+ at 0x00000000,0x00000000 of 0xffffffff: (0x0008,0x0000) ...
+.RE
+...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0000) UL Group Length VR=<UL> ...
+.RE
+...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0000) UL Meta Element Group Length ...
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+...
+.RE
+(0x0008,0x0008) CS Image Type VR=<CS> VL=<24> <...>
+.RE
+...
+.RE
+\ 
+.RE
+% echo Make explicit big endian, with stamp & replacement,
+.RE
+       and removal of private attributes
+.RE
+\ 
+.RE
+% dccp \-v \-ts 1.2.840.10008.1.2.2 \-stamp "9999" 
+.RE
+       \-r PatientSex F \-removeprivate
+.RE
+       test.dc3 test.big
+.RE
+******** While reading ... ********
+.RE
+ at 0x00000000,0x00000000 of 0xffffffff: (0x0008,0x0000) ...
+.RE
+...
+.RE
+******** As read ... ********
+.RE
+...
+.RE
+(0x0010,0x0040) CS PatientSex VR=<CS> VL=<2> <M > 
+.RE
+...
+.RE
+(0x0028,0x0010) US Rows       VR=<US> VL=<2> [100]
+.RE
+...
+.RE
+(0x0029,0x0010) LO Private Creator ... [ACME CO ]
+.RE
+(0x0029,0x1010) DS Zoom       VR=<DS> VL=<0> <>
+.RE
+...
+.RE
+******** After replace before... ********
+.RE
+...
+.RE
+(0x0010,0x0040) CS PatientSex VR=<CS> VL=<2> <F> 
+.RE
+...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0000) UL Meta Element Group Length ...
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+...
+.RE
+(0x0010,0x0040) CS PatientSex VR=<CS> VL=<2> <F> 
+.RE
+...
+.RE
+(0x0028,0x0010) US Rows       VR=<US> VL=<2> [100]
+.RE
+...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1),dccreate(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dccreate.cc b/appsrc/dcfile/dccreate.cc
new file mode 100644
index 0000000..bc6dea9
--- /dev/null
+++ b/appsrc/dcfile/dccreate.cc
@@ -0,0 +1,58 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dccreate.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	dicom_output_options.done();
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(OutputFile) << "]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+
+	{
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
diff --git a/appsrc/dcfile/dccreate.man b/appsrc/dcfile/dccreate.man
new file mode 100755
index 0000000..f03081e
--- /dev/null
+++ b/appsrc/dcfile/dccreate.man
@@ -0,0 +1,92 @@
+.TH DCCP 1 "06 March 2014" "DICOM PS3" "DICOM PS3 - Create DICOM file"
+.SH NAME
+dccreate \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dccreate
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dccreate
+creates a new dicom file with no pixel data using whatever command line option
+values to populate the attributes.
+.LP
+The encoding of the file will be the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options.
+.LP
+During the creation, specific attributes may be added, class and instance unique identifiers generated,
+group lengths added, as specified by
+the replacement options described in dcintro(1). If patient and study information is present (indicating a composite IOD), and the
+SOP Class can be automatically determined, such as for CT or MR images,
+specific SOP Class instances will be created, otherwise SC will be used.
+Unique study, series and instance identifiers will be generated from a
+time stamp, but can be overridden by command line options to allow for
+shared identifiers between files of a series.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+% dccreate test.dcm \-r PatientID 123 \-r StudyID 456 \-nodisclaimer
+.RE
+% dcdump test.dcm
+.RE
+(0x0002,0x0000) UL File Meta Information Group Length 	 VR=<UL>   VL=<0x0004>  [0x000000c0] 
+.RE
+(0x0002,0x0001) OB File Meta Information Version 	 VR=<OB>   VL=<0x0002>  [0x00,0x01] 
+.RE
+(0x0002,0x0002) UI Media Storage SOP Class UID 	 VR=<UI>   VL=<0x001a>  <1.2.840.10008.5.1.4.1.1.7> 
+.RE
+(0x0002,0x0003) UI Media Storage SOP Instance UID 	 VR=<UI>   VL=<0x0030>  <1.3.6.1.4.1.5962.1.1.456.0.0.1357662469.73993.0> 
+.RE
+(0x0002,0x0010) UI Transfer Syntax UID 	 VR=<UI>   VL=<0x0014>  <1.2.840.10008.1.2.1> 
+.RE
+(0x0002,0x0012) UI Implementation Class UID 	 VR=<UI>   VL=<0x0012>  <1.3.6.1.4.1.5962.2> 
+.RE
+(0x0002,0x0013) SH Implementation Version Name 	 VR=<SH>   VL=<0x000a>  <DCTOOL100 > 
+.RE
+(0x0002,0x0016) AE Source Application Entity Title 	 VR=<AE>   VL=<0x0008>  <CLUNIE1 > 
+.RE
+(0x0008,0x0012) DA Instance Creation Date 	 VR=<DA>   VL=<0x0008>  <20130108> 
+.RE
+(0x0008,0x0013) TM Instance Creation Time 	 VR=<TM>   VL=<0x0006>  <112749> 
+.RE
+(0x0008,0x0014) UI Instance Creator UID 	 VR=<UI>   VL=<0x0012>  <1.3.6.1.4.1.5962.3> 
+.RE
+(0x0008,0x0016) UI SOP Class UID 	 VR=<UI>   VL=<0x001a>  <1.2.840.10008.5.1.4.1.1.7> 
+.RE
+(0x0008,0x0018) UI SOP Instance UID 	 VR=<UI>   VL=<0x0030>  <1.3.6.1.4.1.5962.1.1.456.0.0.1357662469.73993.0> 
+.RE
+(0x0008,0x0050) SH Accession Number 	 VR=<SH>   VL=<0x0000>  <> 
+.RE
+(0x0008,0x0201) SH Timezone Offset From UTC 	 VR=<SH>   VL=<0x0006>  <-0500 > 
+.RE
+(0x0010,0x0020) LO Patient ID 	 VR=<LO>   VL=<0x0004>  <123 > 
+.RE
+(0x0020,0x000d) UI Study Instance UID 	 VR=<UI>   VL=<0x002c>  <1.3.6.1.4.1.5962.1.2.456.1357662469.73993.0> 
+.RE
+(0x0020,0x0010) SH Study ID 	 VR=<SH>   VL=<0x0004>  <456 > 
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1),dccp(1),ancreate(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcdecmpr.cc b/appsrc/dcfile/dcdecmpr.cc
new file mode 100644
index 0000000..901c6ab
--- /dev/null
+++ b/appsrc/dcfile/dcdecmpr.cc
@@ -0,0 +1,1029 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdecmpr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+//#define ZEROATSTARTOFROW
+//#define OVERRIDE_ESCAPELENGTH	16
+
+// pick one ...
+//#define READBITFROMLSBOFBYTE
+//#define READBITFROMMSBOFBYTE
+#define READBITFROMMSBOF16LE
+//#define READBITFROMLSBOF16LE
+//#define READBITFROMMSBOF16BE
+//#define READBITFROMLSBOF16BE
+
+//#define READBITFROMMSBOF32LE
+//#define READBITFROMLSBOF32LE
+
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+#include "transyn.h"
+
+static void
+writeTheValue(ostream &out,Uint16 accumulatedvalue)
+{
+	// little endian;
+	out.put((unsigned char)(accumulatedvalue&0xff));
+	out.put((unsigned char)((accumulatedvalue&0xff00)>>8));
+}
+
+
+static Uint16			actualVariableDataGroup;
+static const unsigned char *	vVariablePixelData;
+static Uint32			lVariablePixelData;
+static unsigned 		readBitByteCount;
+static short			readBitCount;
+static Uint32			readBitValue;
+
+static void
+initializeReadBit(void)
+{
+	readBitByteCount=0;
+	readBitCount=0;
+	readBitValue=0;
+}
+
+static void
+setVariableDataLocation(Uint16 vImageLocation)
+{
+	actualVariableDataGroup=vImageLocation;
+	vVariablePixelData=0;
+	lVariablePixelData=0;
+}
+
+static bool
+getMoreVariableData(AttributeList &list,TextOutputStream &log)
+{
+	if (actualVariableDataGroup == 0) return false;
+
+	Tag tVariablePixelDataGroupLength(actualVariableDataGroup,0x0000);
+	Tag tVariablePixelData(actualVariableDataGroup,0x0010);
+	Tag tVariableNextDataGroup(actualVariableDataGroup,0x0011);
+
+	Uint32 vVariablePixelDataGroupLength = 0;
+	Attribute *aVariablePixelDataGroupLength = list[tVariablePixelDataGroupLength];
+	if (!aVariablePixelDataGroupLength)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"VariablePixelDataGroupLength\""
+		    << endl;
+	else {
+		vVariablePixelDataGroupLength=AttributeValue(aVariablePixelDataGroupLength);
+//cerr << "VariablePixelDataGroupLength = <0x" << hex << vVariablePixelDataGroupLength << dec << ">" << endl;
+	}
+
+	Uint16 vVariableNextDataGroup = 0;
+	Attribute *aVariableNextDataGroup = list[tVariableNextDataGroup];
+	if (!aVariableNextDataGroup)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"VariableNextDataGroup\""
+		    << endl;
+	else {
+		vVariableNextDataGroup=AttributeValue(aVariableNextDataGroup);
+//cerr << "VariableNextDataGroup = <0x" << hex << vVariableNextDataGroup << dec << ">" << endl;
+	}
+
+	Attribute *aVariablePixelData = list[tVariablePixelData];
+	if (!aVariablePixelData)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"VariablePixelData\""
+		    << endl;
+	else {
+		Uint32 length = aVariablePixelData->getVL();
+		if (vVariablePixelData) delete[] vVariablePixelData;
+		//vVariablePixelData=new unsigned char[length];
+		//Assert(vVariablePixelData);
+		//lVariablePixelData=length;
+
+		if (!aVariablePixelData->getValue(vVariablePixelData,lVariablePixelData)) Assert(0);
+//cerr << "lVariablePixelData = <0x" << hex << lVariablePixelData << dec << ">" << endl;
+	}
+
+	actualVariableDataGroup=vVariableNextDataGroup;		// for next pass
+
+	return true;
+}
+
+#ifdef READBITFROMMSBOF32LE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			Assert(lVariablePixelData >= 4);
+			Assert(lVariablePixelData%4 == 0);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		// little endian word ...
+		readBitValue=((Uint32)(vVariablePixelData[readBitByteCount+3])<<24)
+			    |((Uint32)(vVariablePixelData[readBitByteCount+2])<<16)
+			    |((Uint32)(vVariablePixelData[readBitByteCount+1])<<8)
+			    |         vVariablePixelData[readBitByteCount];
+//cerr << "readBitByteCount =" << readBitByteCount << endl;
+//cerr << "readBitValue =0x" << hex << readBitValue << dec << endl;
+		readBitByteCount+=2;
+		readBitCount=32;
+	}
+	bit=(readBitValue>>(--readBitCount)) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMLSBOF32LE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			Assert(lVariablePixelData >= 4);
+			Assert(lVariablePixelData%4 == 0);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		// little endian word ...
+		readBitValue=((Uint32)(vVariablePixelData[readBitByteCount+3])<<24)
+			    |((Uint32)(vVariablePixelData[readBitByteCount+2])<<16)
+			    |((Uint32)(vVariablePixelData[readBitByteCount+1])<<8)
+			    |         vVariablePixelData[readBitByteCount];
+	}
+	bit=(readBitValue>>(15-(--readBitCount))) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMMSBOF16LE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			Assert(lVariablePixelData >= 2);
+			Assert(lVariablePixelData%2 == 0);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		// little endian word ...
+		readBitValue=((Uint16)(vVariablePixelData[readBitByteCount+1])<<8)|vVariablePixelData[readBitByteCount];
+//cerr << "readBitByteCount =" << readBitByteCount << endl;
+//cerr << "readBitValue =0x" << hex << readBitValue << dec << endl;
+		readBitByteCount+=2;
+		readBitCount=16;
+	}
+	bit=(readBitValue>>(--readBitCount)) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMLSBOF16LE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			Assert(lVariablePixelData >= 2);
+			Assert(lVariablePixelData%2 == 0);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		// little endian word ...
+		readBitValue=((Uint16)(vVariablePixelData[readBitByteCount+1])<<8)|vVariablePixelData[readBitByteCount];
+		readBitByteCount+=2;
+		readBitCount=16;
+	}
+	bit=(readBitValue>>(15-(--readBitCount))) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMMSBOF16BE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			Assert(lVariablePixelData >= 2);
+			Assert(lVariablePixelData%2 == 0);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		// little endian word ...
+		readBitValue=((Uint16)(vVariablePixelData[readBitByteCount])<<8)|vVariablePixelData[readBitByteCount+1];
+//cerr << "readBitByteCount =" << readBitByteCount << endl;
+//cerr << "readBitValue =0x" << hex << readBitValue << dec << endl;
+		readBitByteCount+=2;
+		readBitCount=16;
+	}
+	bit=(readBitValue>>(--readBitCount)) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMLSBOF16BE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			Assert(lVariablePixelData >= 2);
+			Assert(lVariablePixelData%2 == 0);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		// little endian word ...
+		readBitValue=((Uint16)(vVariablePixelData[readBitByteCount])<<8)|vVariablePixelData[readBitByteCount+1];
+		readBitByteCount+=2;
+		readBitCount=16;
+	}
+	bit=(readBitValue>>(15-(--readBitCount))) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMMSBOFBYTE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		readBitValue=vVariablePixelData[readBitByteCount++];
+		readBitCount=8;
+	}
+	bit=(readBitValue>>(--readBitCount)) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+#ifdef READBITFROMLSBOFBYTE
+static bool
+readBit(Uint32 &bit,AttributeList &list,TextOutputStream &log)
+{
+//cerr << "readBit():readBitByteCount = " << readBitByteCount << endl;
+//cerr << "readBit():lVariablePixelData = " << lVariablePixelData << endl;
+
+	// first bits are read from lsb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		if (readBitByteCount >= lVariablePixelData) {
+			if (!getMoreVariableData(list,log)) return false;
+			Assert(lVariablePixelData);
+			readBitByteCount=0;
+		}
+		Assert(vVariablePixelData);
+		readBitValue=vVariablePixelData[readBitByteCount++];
+		readBitCount=8;
+	}
+	bit=(readBitValue>>(7-(--readBitCount))) & 1;
+//cerr << (bit ? "1" : "0");
+	return true;
+}
+#endif
+
+static void
+getValuesOfAttributes(AttributeList &list,ostream &out,TextOutputStream &log,bool quiet)
+{
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else {
+		vBitsStored=AttributeValue(aBitsStored);
+cerr << "BitsStored = <" << vBitsStored << ">" << endl;
+	}
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else {
+		vColumns=AttributeValue(aColumns);
+cerr << "Columns = <" << vColumns << ">" << endl;
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else {
+		vRows=AttributeValue(aRows);
+cerr << "Rows = <" << vRows << ">" << endl;
+	}
+
+	char *vCompressionRecognitionCode = 0;
+	Attribute *aCompressionRecognitionCode = list[TagFromName(CompressionRecognitionCode)];
+	if (!aCompressionRecognitionCode)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CompressionRecognitionCode\""
+		    << endl;
+	else {
+		vCompressionRecognitionCode=AttributeValue(aCompressionRecognitionCode);
+cerr << "CompressionRecognitionCode = <" << vCompressionRecognitionCode << ">" << endl;
+	}
+
+	char *vCompressionCode = 0;
+	Attribute *aCompressionCode = list[TagFromName(CompressionCode)];
+	if (!aCompressionCode)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CompressionCode\""
+		    << endl;
+	else {
+		vCompressionCode=AttributeValue(aCompressionCode);
+cerr << "CompressionCode = <" << vCompressionCode << ">" << endl;
+	}
+
+	char *vCompressionOriginator = 0;
+	Attribute *aCompressionOriginator = list[TagFromName(CompressionOriginator)];
+	if (!aCompressionOriginator)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CompressionOriginator\""
+		    << endl;
+	else {
+		vCompressionOriginator=AttributeValue(aCompressionOriginator);
+cerr << "CompressionOriginator = <" << vCompressionOriginator << ">" << endl;
+	}
+
+	char *vCompressionLabel = 0;
+	Attribute *aCompressionLabel = list[TagFromName(CompressionLabel)];
+	if (!aCompressionLabel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CompressionLabel\""
+		    << endl;
+	else {
+		vCompressionLabel=AttributeValue(aCompressionLabel);
+cerr << "CompressionLabel = <" << vCompressionLabel << ">" << endl;
+	}
+
+	int nCompressionSequence = 0;
+	char ** vCompressionSequence = 0;
+	Attribute *aCompressionSequence = list[TagFromName(CompressionSequence)];
+	if (!aCompressionSequence)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CompressionSequence\""
+		    << endl;
+	else {
+		nCompressionSequence=aCompressionSequence->getVM();
+		if (nCompressionSequence) {
+			vCompressionSequence=new char *[nCompressionSequence];
+			Assert(vCompressionSequence);
+			int i;
+			for (i=0; i<nCompressionSequence; ++i) {
+				bool success=aCompressionSequence->getValue(i,vCompressionSequence[i]);
+				Assert(success);
+cerr << "CompressionSequence[" << i << "] = <" << vCompressionSequence[i] << ">" << endl;
+			}
+		}
+	}
+
+	int nCompressionStepPointers = 0;
+	Uint32 *vCompressionStepPointers = 0;
+	Attribute *aCompressionStepPointers = list[TagFromName(CompressionStepPointers)];
+	if (!aCompressionStepPointers)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CompressionStepPointers\""
+		    << endl;
+	else {
+		nCompressionStepPointers=aCompressionStepPointers->getVM();
+		if (nCompressionStepPointers) {
+			vCompressionStepPointers=new Uint32[nCompressionStepPointers];
+			Assert(vCompressionStepPointers);
+			int i;
+			for (i=0; i<nCompressionStepPointers; ++i) {
+				bool success=aCompressionStepPointers->getValue(i,vCompressionStepPointers[i]);
+				Assert(success);
+cerr << "CompressionStepPointers[" << i << "] = <0x" << hex << vCompressionStepPointers[i] << dec << ">" << endl;
+			}
+		}
+	}
+
+	Uint16 vPerimeterValue = 0;
+	Attribute *aPerimeterValue = list[TagFromName(PerimeterValue)];
+	if (!aPerimeterValue)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PerimeterValue\""
+		    << endl;
+	else {
+		vPerimeterValue=AttributeValue(aPerimeterValue);
+cerr << "PerimeterValue = <0x" << hex << vPerimeterValue << dec << ">" << endl;
+	}
+
+	Uint16 vPredictorRows = 0;
+	Attribute *aPredictorRows = list[TagFromName(PredictorRows)];
+	if (!aPredictorRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PredictorRows\""
+		    << endl;
+	else {
+		vPredictorRows=AttributeValue(aPredictorRows);
+cerr << "PredictorRows = <" << vPredictorRows << ">" << endl;
+	}
+
+	Uint16 vPredictorColumns = 0;
+	Attribute *aPredictorColumns = list[TagFromName(PredictorColumns)];
+	if (!aPredictorColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PredictorColumns\""
+		    << endl;
+	else {
+		vPredictorColumns=AttributeValue(aPredictorColumns);
+cerr << "PredictorColumns = <" << vPredictorColumns << ">" << endl;
+	}
+
+	int nPredictorConstants = 0;
+	Uint16 *vPredictorConstants = 0;
+	Attribute *aPredictorConstants = list[TagFromName(PredictorConstants)];
+	if (!aPredictorConstants)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PredictorConstants\""
+		    << endl;
+	else {
+		nPredictorConstants=aPredictorConstants->getVM();
+		if (nPredictorConstants) {
+			vPredictorConstants=new Uint16[nPredictorConstants];
+			Assert(vPredictorConstants);
+			int i;
+			for (i=0; i<nPredictorConstants; ++i) {
+				bool success=aPredictorConstants->getValue(i,vPredictorConstants[i]);
+				Assert(success);
+cerr << "nPredictorConstants[" << i << "] = <" << hex << vPredictorConstants[i] << dec << ">" << endl;
+			}
+		}
+	}
+
+	Uint16 vImageLocation = 0;
+	Attribute *aImageLocation = list[TagFromName(ImageLocation)];
+	if (!aImageLocation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"ImageLocation\""
+		    << endl;
+	else {
+		vImageLocation=AttributeValue(aImageLocation);
+cerr << "ImageLocation = <0x" << hex << vImageLocation << dec << ">" << endl;
+	}
+
+cerr << "Ignoring ImageLocation and using <0x7f00>" << endl;
+
+	setVariableDataLocation(0x7f00);
+
+
+
+
+
+
+
+	int nCodeLabel = 0;
+	char ** vCodeLabel = 0;
+	Attribute *aCodeLabel = list[TagFromName(CodeLabel)];
+	if (!aCodeLabel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CodeLabel\""
+		    << endl;
+	else {
+		nCodeLabel=aCodeLabel->getVM();
+		if (nCodeLabel) {
+			vCodeLabel=new char *[nCodeLabel];
+			Assert(vCodeLabel);
+			int i;
+			for (i=0; i<nCodeLabel; ++i) {
+				bool success=aCodeLabel->getValue(i,vCodeLabel[i]);
+				Assert(success);
+cerr << "CodeLabel[" << i << "] = <" << vCodeLabel[i] << ">" << endl;
+			}
+		}
+	}
+
+	Uint16 vNumberOfTables = 0;
+	Attribute *aNumberOfTables = list[TagFromName(NumberOfTables)];
+	if (!aNumberOfTables)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"NumberOfTables\""
+		    << endl;
+	else {
+		vNumberOfTables=AttributeValue(aNumberOfTables);
+cerr << "NumberOfTables = <" << vNumberOfTables << ">" << endl;
+	}
+
+
+	Uint32 vCodeTableLocation = 0;
+	Attribute *aCodeTableLocation = list[TagFromName(CodeTableLocation)];
+	if (!aCodeTableLocation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"CodeTableLocation\""
+		    << endl;
+	else {
+		/* vCodeTableLocation=AttributeValue(aCodeTableLocation); */ // Doesn`t work
+		bool success=aCodeTableLocation->getValue(0,vCodeTableLocation);
+		Assert(success);
+cerr << "CodeTableLocation = <0x" << hex << vCodeTableLocation << dec << ">" << endl;
+	}
+
+	struct huffmantableindexentry {
+		unsigned short bits;
+		struct huffmantableentry *ptr;
+	};
+
+	unsigned huffmantableindexsize=0;
+	struct huffmantableindexentry *huffmantableindex = 0;
+
+	if (vNumberOfTables) {
+		Assert(vCodeTableLocation);
+		int i;
+		Uint16 g;
+		Uint16 e;
+
+		for (i=0,g=Uint16((vCodeTableLocation&0xffff0000)>>16),
+		     e=Uint16(e=vCodeTableLocation&0xffff); i < vNumberOfTables; ++i,e+=0x0010) {
+
+			Uint16 vEscapeTripletNumberOfActualValueBits = 0;
+			Uint16 vEscapeTripletNumberOfEscapeCodeBits = 0;
+			Uint16 vEscapeTripletEscapeCode = 0;
+			Attribute *aEscapeTriplet=list[Tag(g,e)];
+			if (!aEscapeTriplet)
+				log << WMsgDC(MissingAttribute)
+				    << " - \"EscapeTriplet\""
+				    << endl;
+			else {
+				Assert(aEscapeTriplet->getVM() == 3);
+				bool success=aEscapeTriplet->getValue(0,vEscapeTripletNumberOfActualValueBits);
+				Assert(success);
+				success=aEscapeTriplet->getValue(1,vEscapeTripletNumberOfEscapeCodeBits);
+				Assert(success);
+				success=aEscapeTriplet->getValue(2,vEscapeTripletEscapeCode);
+				Assert(success);
+cerr << "EscapeTripletNumberOfActualValueBits[" << i << "] = <" << vEscapeTripletNumberOfActualValueBits << ">" << endl;
+cerr << "EscapeTripletNumberOfEscapeCodeBits[" << i << "] = <" << vEscapeTripletNumberOfEscapeCodeBits << ">" << endl;
+cerr << "EscapeTripletEscapeCode[" << i << "] = <0x" << hex << vEscapeTripletEscapeCode << dec << ">" << endl;
+			}
+
+			Uint16 useEscapeTripletNumberOfActualValueBits=vEscapeTripletNumberOfActualValueBits;
+#ifdef OVERRIDE_ESCAPELENGTH
+			useEscapeTripletNumberOfActualValueBits=OVERRIDE_ESCAPELENGTH;
+#endif
+cerr << "use EscapeTripletNumberOfActualValueBits[" << i << "] = <" << useEscapeTripletNumberOfActualValueBits << ">" << endl;
+
+			Uint16 vHuffmanTableSize = 0;
+			Attribute *aHuffmanTableSize=list[Tag(g,e+2)];
+			if (!aHuffmanTableSize)
+				log << WMsgDC(MissingAttribute)
+				    << " - \"HuffmanTableSize\""
+				    << endl;
+			else {
+				vHuffmanTableSize=AttributeValue(aHuffmanTableSize);
+cerr << "HuffmanTableSize = <" << vHuffmanTableSize << ">" << endl;
+			}
+
+			Assert(sizeof(Int16) == 2);	// else would need to sign extend
+
+			Int16 *vHuffmanTableTripletValue = 0;
+			Uint16 *vHuffmanTableTripletNumberOfCodeBits = 0;
+			Uint16 *vHuffmanTableTripletCode = 0;
+
+			Attribute *aHuffmanTableTriplet=list[Tag(g,e+3)];
+			if (!aHuffmanTableTriplet)
+				log << WMsgDC(MissingAttribute)
+				    << " - \"HuffmanTableTriplet\""
+				    << endl;
+			else {
+				Assert(vHuffmanTableSize*6 == aHuffmanTableTriplet->getVL());
+				vHuffmanTableTripletValue = new Int16[vHuffmanTableSize];
+				vHuffmanTableTripletNumberOfCodeBits = new Uint16[vHuffmanTableSize];
+				vHuffmanTableTripletCode = new Uint16[vHuffmanTableSize];
+				Assert(vHuffmanTableTripletValue);
+				Assert(vHuffmanTableTripletNumberOfCodeBits);
+				Assert(vHuffmanTableTripletCode);
+				int j,k;
+				for (j=0,k=0; j<vHuffmanTableSize; ++j,k+=3) {
+					bool success=aHuffmanTableTriplet->getValue(k,vHuffmanTableTripletValue[j]);
+					Assert(success);
+					success=aHuffmanTableTriplet->getValue(k+1,vHuffmanTableTripletNumberOfCodeBits[j]);
+					Assert(success);
+					success=aHuffmanTableTriplet->getValue(k+2,vHuffmanTableTripletCode[j]);
+					Assert(success);
+cerr << "HuffmanTableTripletValue[" << i << "," << j << "] = <0x" << hex << vHuffmanTableTripletValue[j] << dec << ">" << endl;
+cerr << "HuffmanTableTripletNumberOfCodeBits[" << i << "," << j << "] = <" << vHuffmanTableTripletNumberOfCodeBits[j] << ">" << endl;
+cerr << "HuffmanTableTripletCode[" << i << "," << j << "] = <0x" << hex << vHuffmanTableTripletCode[j] << dec << ">" << endl;
+				}
+			}
+
+			// Build a set of huffman decoder tables ...
+
+			unsigned maxcodelength = 0;
+			unsigned j;
+			for (j=0; j<vHuffmanTableSize; ++j)
+				if (maxcodelength < vHuffmanTableTripletNumberOfCodeBits[j])
+					maxcodelength=vHuffmanTableTripletNumberOfCodeBits[j];
+			Assert(maxcodelength > 0);
+cerr << "maxcodelength = " << maxcodelength << endl;
+
+			// Find out which code lengths are in use ...
+			
+			unsigned *codelengthsused = new unsigned [maxcodelength+1];
+			Assert(codelengthsused);
+			for (j=1; j<=maxcodelength; ++j) codelengthsused[j]=0;
+			for (j=0; j<vHuffmanTableSize; ++j) codelengthsused[vHuffmanTableTripletNumberOfCodeBits[j]]++;
+			codelengthsused[vEscapeTripletNumberOfEscapeCodeBits]++;
+
+for (j=1; j<=maxcodelength; ++j) cerr << "codelengthsused [ " << j << "] = " << codelengthsused[j] << endl;
+			
+			// How many code lengths are in use ?
+			
+			unsigned numberofcodelengthsused=0;
+			for (j=1; j<=maxcodelength; ++j) if (codelengthsused[j]) ++numberofcodelengthsused;
+cerr << "numberofcodelengthsused = " << numberofcodelengthsused << endl;
+
+			// create a table for use during decoding with code lengths for only those in use ...
+
+			unsigned *codelengthtable = new unsigned [numberofcodelengthsused];
+			Assert(codelengthtable);
+			unsigned k;
+			for (j=1,k=0; j<=maxcodelength; ++j) if (codelengthsused[j]) codelengthtable[k++]=j;
+
+for (k=0; k<numberofcodelengthsused; ++k) cerr << "codelengthtable [ " << k << "] = " << codelengthtable[k] << endl;
+
+			// create a table of tables of actions and values (sparse)
+
+			struct huffmandecodetableentry {
+#define action_VALUE 1
+#define action_ESCAPE 2
+#define action_NEXTLENGTH 3
+				unsigned action;
+				Int16 value;
+			};
+
+			struct huffmandecodetableentry **huffmandecodetable = new struct huffmandecodetableentry *[numberofcodelengthsused];
+			Assert(huffmandecodetable);
+			
+			for (k=0; k<numberofcodelengthsused; ++k) {
+				unsigned numberofentries = 1<<codelengthtable[k];
+				Assert(numberofentries);
+cerr << "numberofentries[" << k << "] = " << numberofentries << endl;
+				huffmandecodetable[k]=new struct huffmandecodetableentry[numberofentries];
+				Assert(huffmandecodetable[k]);
+
+				// default action is go to next length ...
+				
+				for (j=0; j<numberofentries; ++j) {
+					huffmandecodetable[k][j].action=action_NEXTLENGTH;
+					huffmandecodetable[k][j].value=0;       // not used
+				}
+								
+				// search tables for codes of this length and values ...
+				
+				for (j=0; j<vHuffmanTableSize; ++j) {
+					if (vHuffmanTableTripletNumberOfCodeBits[j] == codelengthtable[k]) {
+						Uint16 code=vHuffmanTableTripletCode[j];
+						Assert(code < numberofentries);
+						Assert(huffmandecodetable[k][code].action == action_NEXTLENGTH);
+						huffmandecodetable[k][code].action=action_VALUE;
+						huffmandecodetable[k][code].value=vHuffmanTableTripletValue[j];
+					}
+				}
+				
+				// fill in table with escape value ...
+				
+				if (vEscapeTripletNumberOfEscapeCodeBits == codelengthtable[k]) {
+					Uint16 code=vEscapeTripletEscapeCode;
+					Assert(code < numberofentries);
+					Assert(huffmandecodetable[k][code].action == action_NEXTLENGTH);
+					huffmandecodetable[k][code].action=action_ESCAPE;
+cerr << "setting escape huffmandecodetable[" << k << "][" << code << " ] action = " << huffmandecodetable[k][code].action << endl;
+				}
+
+			}
+//#ifdef CRAP
+			// dump table ...       
+				
+			for (k=0; k<numberofcodelengthsused; ++k) {
+				unsigned numberofentries = 1<<codelengthtable[k];
+				for (j=0; j<numberofentries; ++j) {
+					cerr << "huffmandecodetable[" << k << "][" << j << " ] action = "
+						<< huffmandecodetable[k][j].action 
+						<< " value = " << huffmandecodetable[k][j].value
+						<< endl;
+				}
+			}
+//#endif
+			// now let's try it ...
+cerr << "Now let's try it ..." << endl;
+			
+			{
+				initializeReadBit();
+
+				Uint16 escapeValueSignBitMask = 1<<(useEscapeTripletNumberOfActualValueBits-1);
+				Uint16 escapeValueSignExtendMask = (0xffff>>useEscapeTripletNumberOfActualValueBits)<<useEscapeTripletNumberOfActualValueBits;
+cerr << "escapeValueSignBitMask = 0x" << hex << escapeValueSignBitMask << dec << endl;
+cerr << "escapeValueSignExtendMask = 0x" << hex << escapeValueSignExtendMask << dec << endl;
+
+				Uint16 valueMask = ~((0xffff>>vBitsStored)<<vBitsStored);
+cerr << "valueMask = 0x" << hex << valueMask << dec << endl;
+
+				Uint16 accumulatedvalue=0;
+				Uint16 count_columns=0;
+				Uint16 count_rows=0;
+
+				Uint32 bits=0;
+				unsigned index=0;
+				Assert(index < numberofcodelengthsused);
+				int needbits=codelengthtable[index];
+				while (count_rows < vRows) {
+				//while (true) {
+//cerr << "index = " << index << endl;
+					Assert(index < numberofcodelengthsused);
+//cerr << "needbits = " << needbits << endl;
+					Assert(needbits < sizeof(Uint32)*8);
+					Uint32 nextbit;
+					while (needbits-- > 0 && readBit(nextbit,list,log)) bits=(bits<<1) | nextbit;
+					if (needbits != -1) break;
+					
+					Uint16 action=huffmandecodetable[index][bits].action;
+					
+//cerr << "huffmandecodetable[" << index << "][" << bits << " ] action = " << action << endl;
+						
+					if (action == action_NEXTLENGTH) {
+						needbits=codelengthtable[index];			// what we already have
+						++index;
+						Assert(index < numberofcodelengthsused);
+						needbits=codelengthtable[index]-needbits;       // what more we need (not total)
+					}
+					else if (action == action_ESCAPE) {
+cerr << "escape" << endl;
+						int bitsinescapevalue=useEscapeTripletNumberOfActualValueBits;
+						Int16 escapevalue=0;
+						while (bitsinescapevalue-- > 0 && readBit(nextbit,list,log)) escapevalue=(escapevalue<<1) | nextbit;
+						Assert(bitsinescapevalue == -1);	// can't run out here
+						
+cerr << "[" << count_rows << "," << count_columns << "] before = " << accumulatedvalue << endl;
+cerr << "escapevalue before sign extend = 0x" << hex << escapevalue << dec << "(" << escapevalue << ")" << endl;
+//#define TWOSCOMPLEMENTESCAPE
+#ifdef TWOSCOMPLEMENTESCAPE
+						// need to sign extend escape value ...
+						if (escapevalue & escapeValueSignBitMask) escapevalue|=escapeValueSignExtendMask;
+cerr << "escapevalue after  sign extend = 0x" << hex << escapevalue << dec << "(" << escapevalue << ")" << endl;
+						accumulatedvalue+=escapevalue;
+						//accumulatedvalue=escapevalue;
+#else
+						if (escapevalue & escapeValueSignBitMask) {
+cerr << "escapevalue after  sign removal = 0x" << hex << (escapevalue-escapeValueSignBitMask) << dec << "(" << (escapevalue-escapeValueSignBitMask) << ")" << endl;
+							accumulatedvalue-=(escapevalue-escapeValueSignBitMask);
+						}
+						else
+							accumulatedvalue+=escapevalue;
+#endif						
+
+cerr << "[" << count_rows << "," << count_columns << "] after = " << accumulatedvalue << endl;
+						accumulatedvalue&=valueMask;
+//cerr << "escapevalue = " << escapevalue << endl;
+cerr << "[" << count_rows << "," << count_columns << "] masked = " << accumulatedvalue << endl;
+						writeTheValue(out,accumulatedvalue);
+
+						++count_columns;
+
+						index=0;
+						needbits=codelengthtable[index];
+						bits=0;
+					}
+					else if (action == action_VALUE) {
+//cerr << "bits = 0x" << hex << bits << dec << endl;
+						accumulatedvalue+=huffmandecodetable[index][bits].value;
+						//accumulatedvalue=huffmandecodetable[index][bits].value;
+						accumulatedvalue&=valueMask;
+//cerr << "value = " << huffmandecodetable[index][bits].value << endl;
+cerr << "[" << count_rows << "," << count_columns << "] = " << accumulatedvalue << endl;
+						writeTheValue(out,accumulatedvalue);
+
+						++count_columns;
+
+						index=0;
+						needbits=codelengthtable[index];
+						bits=0;
+					}
+					else {
+						Assert(0);
+					}
+
+					if (count_columns >= vColumns) {
+						count_columns=0;
+						++count_rows;
+#ifdef ZEROATSTARTOFROW
+						accumulatedvalue=0;
+#endif
+					}
+				}
+			}
+cerr << "Normal exit from loop" << endl;
+		}
+	}
+	out.flush();
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 			options(argc,argv);
+	DicomInputOptions 			dicom_input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	getValuesOfAttributes(list,out,log,quiet);
+
+#ifdef CRAP
+	if (vNumberOfFrames > 1) {
+		log << "Multiple frames not supported" << endl;
+		success=false;
+	}
+
+	if (din.getTransferSyntaxToReadDataSet()->isEncapsulated()) {
+		log << "Encapsulated (compressed) input data not supported" << endl;
+		success=false;
+	}
+
+	if (vBitsAllocated > 8) {
+		if (output_options.byteorder == ByteEndian || output_options.byteorder == NoEndian) {
+			log << "Need to specify output byte order for > 8 bit data" << endl;
+			success=false;
+		}
+		else if (din.getEndian() != output_options.byteorder) {
+			log << "Need to specify same byte order as input for > 8 bit data" << endl;
+			success=false;
+		}
+	}
+
+	const char *pnmstring=0;
+
+	if (vSamplesPerPixel == 1
+	 && vPhotometricInterpretation
+	 && (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0
+	  || strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0) ) {
+		pnmstring="P5";
+	}
+	else if (vSamplesPerPixel == 3
+		&& vPhotometricInterpretation && strcmp(vPhotometricInterpretation,"RGB") == 0
+		&& vPlanarConfiguration == 0) {
+		pnmstring="P6";
+	}
+	else {
+		log << "Only greyscale and RGB interleaved images supported" << endl;
+		success=false;
+	}
+
+	if (success) {
+		Assert(pnmstring);
+		out << pnmstring << "\n";
+		out << vColumns << " " << vRows << "\n";
+		out << ((vBitsAllocated > 8 && vBitsStored < 8) ? 256 : (1<<vBitsStored)-1) << "\n";
+	}
+
+
+	Attribute *apixeldata=list[TagFromName(PixelData)];
+	if (!apixeldata) {
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+		success=false;
+	}
+	else if (!apixeldata->isOtherData()) {
+		log << EMsgDC(PixelDataIncorrectVR) << endl;
+		success=false;
+	}
+
+	if (success) {
+		OtherUnspecifiedLargeAttributeBase *
+			opixeldata = apixeldata->castToOtherData();
+		Assert(opixeldata);
+
+		if (!quiet) log << "Writing ..." << endl;
+
+		opixeldata->writeRaw(out);
+
+		if (!out.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+#endif
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcdecmpr.man b/appsrc/dcfile/dcdecmpr.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcdecmpr.test.dcm b/appsrc/dcfile/dcdecmpr.test.dcm
new file mode 100755
index 0000000..bb77eb5
Binary files /dev/null and b/appsrc/dcfile/dcdecmpr.test.dcm differ
diff --git a/appsrc/dcfile/dcdeflate.man b/appsrc/dcfile/dcdeflate.man
new file mode 100755
index 0000000..2a4833b
--- /dev/null
+++ b/appsrc/dcfile/dcdeflate.man
@@ -0,0 +1,30 @@
+.TH DCDEFLATE 1 "17 Dec 2000" "DICOM PS3" "DICOM PS3 - Create deflated DICOM file"
+.SH NAME
+dcdeflate \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create deflated DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcdeflate "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcdeflate
+reads the named dicom or acr-nema input file and copies the information and
+pixel data to a new dicom file, with the dataset compressed using the deflate
+transfer syntax, and a meta information header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcinflate(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcdeflate.script b/appsrc/dcfile/dcdeflate.script
new file mode 100755
index 0000000..241fdf6
--- /dev/null
+++ b/appsrc/dcfile/dcdeflate.script
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# usage: dcdeflate infile outfile
+#
+#
+DCCP=dccp
+GZIP=gzip
+
+$DCCP $1 -justmeta -ra TransferSyntaxUID "1.2.840.10008.1.2.1.99" >$2
+$DCCP $1 -nometa -output-vr explicit -output-endian little | $GZIP -x --best >>$2
+
diff --git a/appsrc/dcfile/dcdict.cc b/appsrc/dcfile/dcdict.cc
new file mode 100644
index 0000000..ce09a69
--- /dev/null
+++ b/appsrc/dcfile/dcdict.cc
@@ -0,0 +1,89 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdict.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtag.h"
+#include "elmdict.h"
+#include "mesgtext.h"
+#include "getoptns.h"
+
+static const char *options_output_key[] = {
+	"key",
+	"k",
+	0
+};
+
+static const char *options_output_tag[] = {
+	"tag",
+	"t",
+	0
+};
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+
+	bool bad=false;
+
+	ElementDictionary optdict;
+	TextOutputStream  log(cerr);
+
+	const char *keyarg;
+	while (options.get(options_output_key,keyarg)) {
+		Assert(keyarg);
+		Tag tag;
+		if (optdict.getTag(keyarg,tag)) {
+			tag.write(log,&optdict);
+			log << endl;
+		}
+		else {
+			log << "-" << options_output_key[0] << ": "
+			    << EMsgDC(UnrecognizedElement)
+			    << " - \"" << keyarg << "\""
+			    << endl;
+			bad=true;
+		}
+	}
+
+	unsigned tagargs[2];
+	int n;
+	while ((n=options.get(options_output_tag,tagargs,2)) != -1) {
+		if (n == 2) {
+			Tag tag=Tag(Uint16(tagargs[0]),Uint16(tagargs[1]));
+			const char *keyword=optdict.getKeyword(tag);
+			if (keyword) {
+				tag.write(log,&optdict);
+				log << endl;
+			}
+			else {
+				log << "-" << options_output_tag[0] << ": "
+				    << EMsgDC(UnrecognizedElement)
+				    << " - ";
+				tag.write(log);
+				log << endl;
+				bad=true;
+			}
+		}
+		else {
+			log << "-" << options_output_tag[0] << ": "
+			    << EMsgDC(WrongNumberOfArguments)
+			    << endl;
+			bad=true;
+		}
+	}
+
+	options.done();
+
+	cerr << options.errors();
+
+	if (!options.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< " [-key|k attributename]"
+			<< " [-tag|t group element]"
+			<< endl;
+		return 1;
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/dcdict.man b/appsrc/dcfile/dcdict.man
new file mode 100755
index 0000000..e34c013
--- /dev/null
+++ b/appsrc/dcfile/dcdict.man
@@ -0,0 +1,59 @@
+.TH DCDICT 1 "06 March 2014" "DICOM PS3" "DICOM PS3 - Extract dictionary elements"
+.SH NAME
+dcdict \- ACR/NEMA DICOM PS3 ... Extract dictionary elements
+.SH SYNOPSIS
+.HP 10
+.B dcdict
+.so man1/gen.so
+[
+.B \-key|k " attributename ]"
+[
+.B \-tag|t " group element ]"
+.SH DESCRIPTION
+.LP
+.B dcdict
+reads the attribute name or group/element numbers from the command line, looks up the corresponding attribute in the DICOM data dictionary, and describes it.
+.SH OPTIONS
+The description of the element goes to standard error.
+.PP
+Options specific to this program are:
+.TP
+.B \-k|key " attributename"
+.RS
+Extract attributename from the dictionary.
+.RE
+.TP
+.B \-tag|t " group element"
+.RS
+Extract (group,element) from the dictionary. Note that group and element
+are assumed to be decimal unless preceded by 0x (hexadecimal) or 0 (octal).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcdict -k Rows -k Columns
+.RE
+(0x0028,0x0010) US Rows 
+.RE
+(0x0028,0x0011) US Columns
+.RE
+\ 
+.RE
+% dcdict -t 0x28 0x10
+.RE
+(0x0028,0x0010) US Rows 
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+\ 
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcdiff.man b/appsrc/dcfile/dcdiff.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcdiff.script b/appsrc/dcfile/dcdiff.script
new file mode 100755
index 0000000..22e0883
--- /dev/null
+++ b/appsrc/dcfile/dcdiff.script
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# compare the dumps of two dicom files
+
+if [ $# != 2 ]
+then
+	echo "usage: `basename $0` file1 file2"
+	exit 1
+fi
+
+TMPFILE1=/tmp/`basename $0`.$$.tmp1
+TMPFILE2=/tmp/`basename $0`.$$.tmp2
+
+dcdump -ignoreoutofordertags "$1" >"$TMPFILE1" 2>&1
+dcdump -ignoreoutofordertags "$2" >"$TMPFILE2" 2>&1
+diff "$TMPFILE1" "$TMPFILE2"
+
+rm "$TMPFILE1" "$TMPFILE2"
+
+exit 0
+
diff --git a/appsrc/dcfile/dcdirdmp.cc b/appsrc/dcfile/dcdirdmp.cc
new file mode 100644
index 0000000..49a10f5
--- /dev/null
+++ b/appsrc/dcfile/dcdirdmp.cc
@@ -0,0 +1,83 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdirdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "dicomdir.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool verbose=options.get("verbose") || options.get("v") || veryverbose;
+	bool showrecordinfo=options.get("showrecordinfo");
+	bool showdescription=options.get("description");
+	bool showpaths=options.get("paths") || options.get("p");
+	bool showabstract = !showpaths;
+	bool showfilename=options.get("filename");
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose]"
+			<< " [-showrecordinfo]"
+			<< " [-description]"
+			<< " [-p|-paths]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (veryverbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,veryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	//if (veryverbose) log << "******** As read ... ********" << endl; 
+	//log << list;
+	//list.write(log,veryverbose);
+
+	{
+		bool parseSuccess = parseDicomdir(list,log,verbose,veryverbose,showrecordinfo,showabstract,showpaths,showdescription);		// parse regardless of read success or failure
+		success=success&&parseSuccess;
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcdirdmp.man b/appsrc/dcfile/dcdirdmp.man
new file mode 100755
index 0000000..242e458
--- /dev/null
+++ b/appsrc/dcfile/dcdirdmp.man
@@ -0,0 +1,198 @@
+.TH DCDIRDMP 1 "06 March 2014" "DICOM PS3" "DICOM PS3 - Describe DICOMDIR content"
+.SH NAME
+dcdirdmp \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Describe DICOMDIR content
+.SH SYNOPSIS
+.HP 10
+.B dcdirdmp
+.so man1/gen.so
+[
+.B \-v|verbose|vv|veryverbose
+]
+[
+.B \-showrecordinfo
+]
+[
+.B \-description
+]
+[
+.B \-p|paths
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcdirdmp
+reads the named dicom input file and interprets it as a DICOMDIR file, that
+is a DICOM file containing an instance of the Basic Directory IOD.
+.LP
+If the file contains a valid instance of the directory, the hierarchical
+record structure is traversed and displayed in a depth first manner. The
+default output displays selected attribute values for recognized types
+of directory record, including the Referenced File ID. The verbose options
+increase the amount of information dumped.
+.LP
+Note that directory record offset values within attributes are in bytes
+from the start of the file (including meta-information header and
+pre-amble) and these point to the beginning of the Item delimiter that
+introduces each item in the directory record sequence. The offset values
+displayed in the verbose output for the first attribute of each sequence
+item will therefore be 8 bytes greater, as the Item delimiter itself
+is not displayed.
+.SH OPTIONS
+The description and verbose output go to standard error.
+.LP
+Binary attributes are written in hexadecimal with a preceding
+"0x". Numeric string attributes are written in decimal. Attribute values
+are displayed in hexadecimal or string format as determined by the value representation.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-v|verbose
+.RS
+Display all attributes in each directory record.
+.RE
+.TP
+.B \-vv|veryverbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read.
+.RE
+.TP
+.B \-showrecordinfo
+.RS
+Display byte offset with each directory record entry, in hexadecimal.
+.RE
+.TP
+.B \-description
+.RS
+Display the Study and Series Description attribute values.
+.RE
+.TP
+.B \-p|paths
+.RS
+Show Unix style path information for each referenced file only (suppresses normal output).
+Used, for example, to feed paths as command line arguments to some other utility.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcdirdmp DICOMDIR
+.RE
+PATIENT SMITH^^^^ 1634-94
+.RE
+        STUDY 1  19960101 113013 
+.RE
+                VISIT
+.RE
+                STUDY COMPONENT XA ?
+.RE
+                SERIES 1 XA
+.RE
+                        IMAGE 2
+.RE
+                         -> XA000002
+.RE
+
+.RE
+% dcdirdmp -description DICOMDIR
+.RE
+PATIENT Jones^Thomas 3648263
+.RE
+        STUDY 1  20110101 103425 CT Chest/Abdo/Pelvis 
+.RE
+                SERIES 1 CT Portal Venous Phase
+.RE
+                        IMAGE 1
+.RE
+                         -> DICOM\\IM1
+.RE
+
+.RE
+% dcdirdmp -v DICOMDIR
+.RE
+PATIENT SMITH^^^^ 1634-94
+.RE
+(0x0004,0x1400) UL Next Directory Record Offset ...
+.RE
+ ...
+.RE
+(0x0010,0x0010) PN Patient's Name VR=<PN> ... 
+.RE
+ ...
+.RE
+(0x0010,0x0020) LO Patient's ID ... 
+.RE
+(0x0010,0x0030) DA Patient's Birth Date ...
+.RE
+(0x0010,0x0040) CS Patient's Sex  ...
+.RE
+        STUDY 1  19960101 113013 
+.RE
+        (0x0004,0x1400) UL Next Directory Record Offset ...
+.RE
+ ...
+.RE
+        (0x0008,0x0050) SH Accession Number ...
+.RE
+...
+.RE
+\ 
+.RE
+% dcdirdmp -vv dicomdir.
+.RE
+******** While reading ... ********
+.RE
+ at 0x00000084,0x00000000 of 0xffffffff: (0x0002,0x0000) ...
+.RE
+ ...
+.RE
+RootDirectoryFirstRecord = 0x190
+.RE
+RootDirectoryLastRecord = 0x190
+.RE
+Number of records = 7
+.RE
+Offset = 0x190
+.RE
+        @0x00000198: (0x0004,0x1400) UL Next Dir Record ... 
+.RE
+...
+.RE
+Offset = 0x2a4
+.RE
+        @0x000002ac: (0x0004,0x1400) UL Next Dir Record ...
+.RE
+ ...
+.RE
+PATIENT 1634-94-1 1634-94
+.RE
+ at 0x00000198: (0x0004,0x1400) UL Next Dir Record Offset ...
+.RE
+ ...
+.RE
+ at 0x00000268: (0x0010,0x0010) PN Patient's Name ...
+.RE
+ ...
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcdump(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+MRDR not yet handled properly.
diff --git a/appsrc/dcfile/dcdirmk.cc b/appsrc/dcfile/dcdirmk.cc
new file mode 100644
index 0000000..dcd63fe
--- /dev/null
+++ b/appsrc/dcfile/dcdirmk.cc
@@ -0,0 +1,2176 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdirmk.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#include <cctype>
+#else
+#include <fstream.h>
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+
+#include "attrmxls.h"
+#include "attrlsln.h"
+#include "attrtype.h"
+#include "attrseq.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "sopcli.h"
+#include "transynu.h"
+#include "uidgen.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+// In a lot of places, there is an assumption that sequences and items will
+// be written delimited, ie. with undefined lengths ... this will break if
+// this changes (write() in attrseq.cc) :(
+
+// The icon image stuff uses a non-pixel data OB, and hence there is no
+// means of taking into account CP 14 setOutputEncoding stuff ... this
+// shouldn't be a problem as the TS is supposed to be explicit, but it
+// does mean a loss of generality :(
+
+// Writing this highlighted the fact the getVL() for sequences is not
+// working and reviseVL() was never implemented :(
+
+// The approach to making the icon image is make everything 8 bit, and
+// use the first "plane" as is regardless of whether it is color or indexed
+// (or even worse, interleaved) :( ... this will work really well for
+// MONOCHROME2 images where BitsStored is not much bigger than the real
+// maximum and the PixelRepresentaion is unsigned !
+
+static ElementDictionary staticDictionary;
+
+static bool
+errorIfStringValuesDontMatch(const char *dirValue,
+	AttributeList &list,Tag valueTag,
+	const char *valueDescription,
+	const char *uniqueKeyDescription,
+	const char *uniqueKeyValue,
+	const char *filename,TextOutputStream &log)
+{	Assert(filename);
+	Assert(dirValue);
+	Assert(valueDescription);
+	Assert(uniqueKeyDescription);
+	char *listValue=AttributeValue(list[valueTag],"");
+	Assert(listValue);
+
+	bool result;
+	if (strcmp(dirValue,listValue) != 0) {
+		log << filename << ": "<< "Error - Different " << valueDescription << " in instance <"
+		    << (listValue ? listValue : "")
+		    << "> for existing " << uniqueKeyDescription << " <"
+		    << (uniqueKeyValue ? uniqueKeyValue : "")
+		    << "> already entered in directory as " << valueDescription << " <"
+		    << (dirValue ? dirValue : "")
+		    << "> - using original value and assuming they are the same entity"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	if (listValue) delete[] listValue;
+	return result;
+}
+
+static Attribute *
+isAttributePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a)
+		return a;
+	else {
+		log << filename << ": "
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static Attribute *
+isAttributePresentElseNull(AttributeList &list,Tag tag)
+{
+	return list[tag];
+}
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static const char *
+getStringValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	if (a) {
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		return "";
+	}
+}
+
+static const char *
+getStringValueElseWarningAndDefault(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log,const char *def)
+{
+	Attribute *a=list[tag];
+	if (a && a->getVM() > 0) {
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		log << filename << ": " 
+		    << WMsgDC(MissingAttribute)
+		    << " - " << label << " - using default value <" << def << ">"
+		    << endl;
+		return def;
+	}
+}
+
+static const char *
+getStringValueElseZeroLength(AttributeList &list,Tag tag)
+{
+	Attribute *a=list[tag];
+	if (a && a->getVM() > 0) {
+		const char *s = AttributeValue(a);
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		return "";
+	}
+}
+
+static const char *
+getStringValueElseNull(AttributeList &list,Tag tag)
+{
+	Attribute *a=list[tag];
+	if (a && a->getVM() > 0) {
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		return 0;
+	}
+}
+
+static Attribute *
+getCopyOfMultiValuedCodeStringAttributeElseNull(AttributeList &list,Tag tag)
+{
+	Attribute *attr=isAttributePresentElseNull(list,tag);
+        CodeStringAttribute *newAttr = 0;
+
+        if (attr) {
+                newAttr=new CodeStringAttribute(tag);
+                Assert(newAttr);
+                unsigned count = attr->getVM();
+                unsigned i;
+                for (i=0; i < count; ++i) {
+                        char *s;
+                        bool gotit=attr->getValue(i,s);
+                        Assert(gotit);
+                        Assert(s);      // should be "" rather than 0 if zero length
+                        newAttr->addValue(s);
+                        // should we now free s ???? :(
+                }
+        }
+        return newAttr;
+}
+
+static Attribute *
+getCopyOfMultiValuedDecimalStringAttributeElseNull(AttributeList &list,Tag tag)
+{
+	Attribute *attr=isAttributePresentElseNull(list,tag);
+        DecimalStringAttribute *newAttr = 0;
+
+        if (attr) {
+                newAttr=new DecimalStringAttribute(tag);
+                Assert(newAttr);
+                unsigned count = attr->getVM();
+                unsigned i;
+                for (i=0; i < count; ++i) {
+                        double v;							// NOT string ... want to fix any illegal too long decimal strings in source
+                        bool gotit=attr->getValue(i,v);
+                        Assert(gotit);
+                        newAttr->addValue(v);
+                }
+        }
+        return newAttr;
+}
+
+
+static Attribute *
+getCopyOfCodeSequenceAttributeElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *codeValue=getStringValueElseError((*item),TagFromName(CodeValue),"Code Value",filename,log);
+			Assert(codeValue);
+			(*newItem)+=new ShortStringAttribute(TagFromName(CodeValue),codeValue);
+
+			const char *codingSchemeDesignator=getStringValueElseError((*item),TagFromName(CodingSchemeDesignator),"Coding Scheme Designator",filename,log);
+			Assert(codingSchemeDesignator);
+			(*newItem)+=new ShortStringAttribute(TagFromName(CodingSchemeDesignator),codingSchemeDesignator);
+
+			const char *codeMeaning=getStringValueElseError((*item),TagFromName(CodeMeaning),"Code Meaning",filename,log);
+			Assert(codeMeaning);
+			(*newItem)+=new LongStringAttribute(TagFromName(CodeMeaning),codeMeaning);
+		}
+	}
+	return newAttr;
+}
+
+
+static Attribute *
+getCopyOfCodeSequenceAttributeElseEmpty(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseNull(list,tag);
+	SequenceAttribute *newAttr = new SequenceAttribute(tag);
+	Assert(newAttr);
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *codeValue=getStringValueElseError((*item),TagFromName(CodeValue),"Code Value",filename,log);
+			Assert(codeValue);
+			(*newItem)+=new ShortStringAttribute(TagFromName(CodeValue),codeValue);
+
+			const char *codingSchemeDesignator=getStringValueElseError((*item),TagFromName(CodingSchemeDesignator),"Coding Scheme Designator",filename,log);
+			Assert(codingSchemeDesignator);
+			(*newItem)+=new ShortStringAttribute(TagFromName(CodingSchemeDesignator),codingSchemeDesignator);
+
+			const char *codeMeaning=getStringValueElseError((*item),TagFromName(CodeMeaning),"Code Meaning",filename,log);
+			Assert(codeMeaning);
+			(*newItem)+=new LongStringAttribute(TagFromName(CodeMeaning),codeMeaning);
+		}
+	}
+	return newAttr;
+}
+
+static Attribute *
+getCopyOfReferencedImageSequenceAttribute(Attribute *attr,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *referencedSOPClassUID=getStringValueElseError((*item),TagFromName(ReferencedSOPClassUID),"Referenced SOP Class UID",filename,log);
+			Assert(referencedSOPClassUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(ReferencedSOPClassUID),referencedSOPClassUID);
+
+			const char *referencedSOPInstanceUID=getStringValueElseError((*item),TagFromName(ReferencedSOPInstanceUID),"Referenced SOP Instance UID",filename,log);
+			Assert(referencedSOPInstanceUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),referencedSOPInstanceUID);
+		}
+	}
+	return newAttr;
+}
+
+
+static Attribute *
+getCopyOfReferencedImageSequenceAttributeElseNull(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseNull(list,tag);
+	return getCopyOfReferencedImageSequenceAttribute(attr,tag,label,filename,log);
+}
+
+
+static Attribute *
+getCopyOfReferencedImageSequenceAttributeElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	return getCopyOfReferencedImageSequenceAttribute(attr,tag,label,filename,log);
+}
+
+
+static Attribute *
+getCopyOfReferencedSeriesSequenceAttributeElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *seriesInstanceUID=getStringValueElseError((*item),TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+			Assert(seriesInstanceUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(SeriesInstanceUID),seriesInstanceUID);
+
+			Attribute *referencedImageSequence=getCopyOfReferencedImageSequenceAttributeElseError((*item),TagFromName(ReferencedImageSequence),"Referenced Image Sequence",filename,log);
+			Assert(referencedImageSequence);
+			(*newItem)+=referencedImageSequence;
+		}
+	}
+	return newAttr;
+}
+
+static Attribute *
+getCopyOfSequenceContainingStudySeriesImageReferenceElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but actually want to be selective and not copy every attribute anyway (e.g., Blending Sequence)
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *studyInstanceUID=getStringValueElseError((*item),TagFromName(StudyInstanceUID),"Study Instance UID",filename,log);
+			Assert(studyInstanceUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(StudyInstanceUID),studyInstanceUID);
+
+			Attribute *referencedSeriesSequence=getCopyOfReferencedSeriesSequenceAttributeElseError((*item),TagFromName(ReferencedSeriesSequence),"Referenced Series Sequence",filename,log);
+			Assert(referencedSeriesSequence);
+			(*newItem)+=referencedSeriesSequence;
+		}
+	}
+	return newAttr;
+}
+
+
+static SequenceAttribute *
+makeIconImageSequence(AttributeList *srclist,const TransferSyntax *transfersyntax,Uint16 iRows=64,Uint16 iColumns=64)
+{
+	SequenceAttribute *aIconImageSequence = 0;
+
+	Assert(srclist);
+	Assert(transfersyntax);
+	Assert(!transfersyntax->isImplicitVR());	// don't support CP 14 or length calculation here
+
+	Uint16 vRows 				= AttributeValue((*srclist)[TagFromName(Rows)]);
+	Uint16 vColumns 			= AttributeValue((*srclist)[TagFromName(Columns)]);
+	Uint16 vNumberOfFrames 			= AttributeValue((*srclist)[TagFromName(NumberOfFrames)]);
+	char * vPhotometricInterpretation 	= AttributeValue((*srclist)[TagFromName(PhotometricInterpretation)]);
+	Uint16 vSamplesPerPixel 		= AttributeValue((*srclist)[TagFromName(SamplesPerPixel)]);
+	Uint16 vBitsAllocated 			= AttributeValue((*srclist)[TagFromName(BitsAllocated)]);
+	Uint16 vBitsStored 			= AttributeValue((*srclist)[TagFromName(BitsStored)]);
+	Uint16 vHighBit 			= AttributeValue((*srclist)[TagFromName(HighBit)]);
+	Uint16 vPixelRepresentation 		= AttributeValue((*srclist)[TagFromName(PixelRepresentation)],0xffff);
+	Uint16 vPlanarConfiguration 		= AttributeValue((*srclist)[TagFromName(PlanarConfiguration)],0xffff);
+
+	Attribute *aPixelData = (*srclist)[TagFromName(PixelData)];
+
+	if (vRows && vColumns && vPhotometricInterpretation
+	 && vSamplesPerPixel && vBitsAllocated && vBitsStored && vHighBit
+	 && vPixelRepresentation != 0xffff
+	 && (vSamplesPerPixel <= 1 || vPlanarConfiguration != 0xffff)
+	 && vRows >= iRows && vColumns >= iColumns	// upsampling not supported
+	) {
+
+		Uint16 downRows=vRows/iRows;
+		Uint16 downColumns=vColumns/iColumns;
+
+		Assert(downRows);	// < icon size not yet supported
+		Assert(downColumns);
+
+		SourceBase<Uint16> *source=SupplySourceFromAttribute(aPixelData).getSource();
+		Assert(source);
+
+		unsigned char *iconPixelData=new unsigned char[iRows*iColumns];
+		Assert(iconPixelData);
+
+		unsigned row=0;
+		unsigned column=0;
+		unsigned irow=0;
+		unsigned icolumn=0;
+		unsigned char *p=iconPixelData;
+		while (row < vRows && source->read()) {
+			size_t n=source->getBufferCount();
+			Assert(n);
+			const Uint16 *buffer=source->getBuffer();
+			Assert(buffer);
+			while (n-- && row < vRows) {
+				if (row%downRows == 0 && column%downColumns == 0 && irow < iRows && icolumn < iColumns) {
+					Assert(p-iconPixelData < iRows*iColumns);
+					*p++=*buffer>>(vBitsStored-8);
+					if (++icolumn >= iColumns) {
+						icolumn=0;
+						++irow;
+					}
+				}
+				buffer++;
+				if (++column >= vColumns) {
+					column=0;
+					++row;
+				}
+			}
+		}
+		Assert(p-iconPixelData == iRows*iColumns);
+		//Assert(column == 0 && row == vRows*vNumberOfFrames);
+		aIconImageSequence=new SequenceAttribute(TagFromName(IconImageSequence));
+		AttributeList *iconlist = new AttributeList;
+		Assert(iconlist);
+
+		Attribute *aIconPixelData=new OtherByteSmallNonPixelAttribute(TagFromName(PixelData));
+		Assert(aIconPixelData);
+		aIconPixelData->setValue(iconPixelData,Uint32(iRows*iColumns));
+		(*iconlist)+=aIconPixelData;
+
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),1);
+		(*iconlist)+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),"MONOCHROME2");
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(Rows),iRows);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(Columns),iColumns);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(BitsAllocated),8);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(BitsStored),8);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(HighBit),7);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),0);
+
+		(*aIconImageSequence)+=iconlist;
+		// aIconImageSequence->reviseVL();	// Not yet implemented :(
+	}
+	
+	return aIconImageSequence;
+}
+
+
+static bool
+addLengths(AttributeList &list,const TransferSyntax *metats,const TransferSyntax *datats)		// Derived from attrmxls.cc
+{
+	// Fixup and/or insert group lengths
+
+	// each (nnnn,0000) group length element
+	// contains the length in bytes of the rest of the group
+	// not including the length element itself
+
+	bool metaseen=false;
+	bool dothisgroup=true;
+	Uint16 doinggroup=0;
+	Uint32 length=0;
+	AttributeList lengthlist;
+	AttributeListIterator listi(list);
+	while (1) {
+		Attribute *a;
+		Tag tag;
+		if (!listi) {
+			a=listi();
+			Assert(a);
+			tag=a->getTag();
+		}
+		if (!!listi || tag.getGroup() > doinggroup) {
+			if (length && dothisgroup && doinggroup == 0x0002) {
+				lengthlist+=new UnsignedLongAttribute(Tag(doinggroup,0),length);
+			}
+			if (!!listi)
+				break;
+			else {
+				doinggroup=tag.getGroup();
+				dothisgroup=true;
+				length=0;
+			}
+		}
+		else if (tag.getGroup() == doinggroup) {
+                        Uint32 add=lengthOfEntireAttribute(metats,datats,a);
+			if (add == 0xffffffff)
+				dothisgroup=false;
+			else
+				length+=add;
+			++listi;
+		}
+		else
+			++listi;
+
+		if (tag.isMetaheaderGroup())
+			metaseen=true;
+		else
+			if (metaseen) break;
+	}
+
+	list+=(lengthlist);
+
+	return true;
+}
+
+class DirectoryRecordWriteOrder {
+	int order;
+public:
+	static const int ParentChildSibling = 1;
+	static const int ParentSiblingChild = 2;
+	static const int SiblingChildParent = 3;
+	static const int SiblingParentChild = 4;
+	static const int ChildSiblingParent = 5;
+	static const int ChildParentSibling = 6;
+
+	DirectoryRecordWriteOrder(int i) { order = i; }
+
+	int getOrder(void) { return order; }
+};
+
+class DirectoryRecordBase {
+protected:
+	DirectoryRecordBase *sibling;
+	DirectoryRecordBase *child;
+
+	AttributeList *list;
+
+	Uint32 selfoffset;
+
+	virtual TextOutputStream& writeSpecific(TextOutputStream &log) = 0;
+	virtual TextOutputStream& indentSpecific(TextOutputStream &log) = 0;
+
+public:
+	DirectoryRecordBase(DirectoryRecordBase *nextsib,AttributeList *srclist)
+		{
+			child=0;
+			sibling=nextsib;
+
+			list=new AttributeList();
+			(*list)+=new UnsignedLongAttribute(TagFromName(OffsetOfTheNextDirectoryRecord),0);
+			(*list)+=new UnsignedShortAttribute(TagFromName(RecordInUseFlag),0xffff);
+			(*list)+=new UnsignedLongAttribute(TagFromName(OffsetOfReferencedLowerLevelDirectoryEntity),0);
+
+			selfoffset=0;
+
+			Attribute *specificCharacterSet=getCopyOfMultiValuedCodeStringAttributeElseNull((*srclist),TagFromName(SpecificCharacterSet));
+			if (specificCharacterSet) (*list)+=specificCharacterSet;
+		}
+
+	virtual ~DirectoryRecordBase()
+		{
+			if (child) delete child;
+			if (sibling) delete sibling;
+		}
+
+	void setChild(DirectoryRecordBase *newchild)
+		{
+			child=newchild;
+		}
+
+	TextOutputStream& write(TextOutputStream &log,const TransferSyntax *ts)
+		{
+			writeSpecific(log);
+			indentSpecific(log);
+			log << "Length = " << getLength(ts) << endl;
+			if (list) {
+				AttributeListIterator i(*list);
+				while (!i) {
+					Attribute *a=i();
+					Assert(a);
+					indentSpecific(log);
+					a->write(log,&staticDictionary,false);
+					log << endl;
+					++i;
+				}
+			}
+
+			if (child)     child->write(log,ts);
+			if (sibling) sibling->write(log,ts);
+			return log;
+		}
+
+	Uint32 getLength(const TransferSyntax *ts)	// NOT including leading Item (8) and possible trailing Item Delimitation Item (8)
+		{
+			Uint32 length=0;
+			if (list) {
+				AttributeListIterator i(*list);
+				while (!i) {
+					Attribute *a=i();
+					Assert(a);
+                                        Uint32 add=lengthOfEntireAttribute(ts,a);
+                                        if (add == 0xffffffff) {
+                                                Assert(0);              // no unsupported undefined length attributes allowed
+                                        }
+                                        else {
+                                                length+=add;
+                                        }
+					++i;
+				}
+			}
+			return length;
+		}
+
+	void linkOffsetChild(void)
+		{
+			Attribute *aLowerLevelDirectoryOffset=(*list)[TagFromName(OffsetOfReferencedLowerLevelDirectoryEntity)];
+			if (child) {
+				Assert(aLowerLevelDirectoryOffset);
+				aLowerLevelDirectoryOffset->setValue(0u,(unsigned long)child->getOffset());
+				child->linkOffset();
+			}
+			else if (aLowerLevelDirectoryOffset) {
+				aLowerLevelDirectoryOffset->setValue(0u,(unsigned long)0);
+			}
+			// else must be testing with doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel option ... standard requires LowerLevelDirectoryOffset
+		}
+
+	void linkOffsetSibling(void)
+		{
+			Attribute *aNextDirectoryRecordOffset=(*list)[TagFromName(OffsetOfTheNextDirectoryRecord)];
+			Assert(aNextDirectoryRecordOffset);
+			if (sibling) {
+				aNextDirectoryRecordOffset->setValue(0u,(unsigned long)sibling->getOffset());
+				sibling->linkOffset();
+			}
+			else {
+				aNextDirectoryRecordOffset->setValue(0u,(unsigned long)0);
+			}
+		}
+
+	void linkOffset(void)
+		{
+			linkOffsetChild();
+			linkOffsetSibling();
+		}
+
+	Uint32 setOffsetSelf(const TransferSyntax *ts,Uint32 startoffset,Uint32 &lastoffset)
+		{
+			selfoffset=startoffset;		// save this ... will be needed at top level to locate 1st directory record
+
+			lastoffset=startoffset;
+
+			startoffset+=8;			// Item tag and length
+			startoffset+=getLength(ts);	// Ourself
+			startoffset+=8;			// Item delimiter tag and length
+
+			return startoffset;
+		}
+
+	Uint32 setOffsetChild(const TransferSyntax *ts,Uint32 startoffset,TextOutputStream &log,bool verbose,Uint32 &lastoffset,DirectoryRecordWriteOrder order)
+		{
+			if (child) {
+				startoffset=child->setOffset(ts,startoffset,log,verbose,lastoffset,order);
+			}
+
+			return startoffset;
+		}
+
+	Uint32 setOffsetSibling(const TransferSyntax *ts,Uint32 startoffset,TextOutputStream &log,bool verbose,Uint32 &lastoffset,DirectoryRecordWriteOrder order)
+		{
+			if (sibling) {
+				startoffset=sibling->setOffset(ts,startoffset,log,verbose,lastoffset,order);
+			}
+
+			return startoffset;
+		}
+
+	Uint32 setOffset(const TransferSyntax *ts,Uint32 startoffset,TextOutputStream &log,bool verbose,Uint32 &lastoffset,DirectoryRecordWriteOrder order)
+		{
+			if (verbose) {
+				writeSpecific(log);
+				indentSpecific(log);
+				log << "Start offset = " << startoffset << endl;
+			}
+
+			if (order.getOrder() == DirectoryRecordWriteOrder::ParentChildSibling) {
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ParentSiblingChild) {
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingChildParent) {
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingParentChild) {
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildSiblingParent) {
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildParentSibling) {
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else {
+				Assert(0);
+			}
+
+			return startoffset;
+		}
+
+	Uint32 getOffset(void) { return selfoffset; }
+
+	void flatten(SequenceAttribute *aDirectoryRecordSequence,DirectoryRecordWriteOrder order)
+		{
+			if (order.getOrder() == DirectoryRecordWriteOrder::ParentChildSibling) {
+				(*aDirectoryRecordSequence)+=list;
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ParentSiblingChild) {
+				(*aDirectoryRecordSequence)+=list;
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingChildParent) {
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingParentChild) {
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildSiblingParent) {
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildParentSibling) {
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+			}
+			else {
+				Assert(0);
+			}
+		}
+};
+
+class InstanceDirectoryRecord : public DirectoryRecordBase {
+	const char *sopInstanceUID;
+	const char *sopClassUID;
+	const char *instanceNumber;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			log << "\t\t\t";
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Instance "
+			    << (sopInstanceUID ? sopInstanceUID : "") << " "
+			    << (instanceNumber ? instanceNumber : "")
+			    << endl;
+			return log;
+		}
+public:
+	InstanceDirectoryRecord(const char *uid,AttributeList *srclist,InstanceDirectoryRecord *nextsib,
+			const char *filename,const char *inputTransferSyntaxUID,
+			const TransferSyntax *outputTransferSyntax,
+			bool doicon,bool doposition,bool validatefilenamevr,bool doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib,srclist)
+		{
+			if (!doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel) {
+				(*list)-=TagFromName(OffsetOfReferencedLowerLevelDirectoryEntity);		// do not send it rather than sending 0 as per standard (for creating tests to simulate Kodak Algotec bug)
+			}
+		
+			sopInstanceUID=uid;
+			Assert(sopInstanceUID);
+			(*list)+=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUIDInFile),sopInstanceUID);
+
+			sopClassUID=getStringValueElseError((*srclist),TagFromName(SOPClassUID),"SOP Class UID",filename,log);
+			Assert(sopClassUID);
+			(*list)+=new UIStringAttribute(TagFromName(ReferencedSOPClassUIDInFile),sopClassUID);
+
+			Assert(inputTransferSyntaxUID);
+			(*list)+=new UIStringAttribute(TagFromName(ReferencedTransferSyntaxUIDInFile),inputTransferSyntaxUID);
+
+			const char *directoryRecordType = getDirectoryRecordTypeFromUID(sopClassUID);
+			if (!directoryRecordType) directoryRecordType="IMAGE";	// Assume image if unrecognzied SOP Class
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),directoryRecordType);
+
+			{
+				Assert(filename);
+				Attribute *a=new CodeStringFileComponentAttribute(TagFromName(ReferencedFileID),filename);
+				(*list)+=a;
+				Assert(a);
+				if (validatefilenamevr) a->validateVR(log,NULL,&staticDictionary);
+			}
+
+			if (strcmp(directoryRecordType,"IMAGE") == 0) {
+				instanceNumber=getStringValueElseWarningAndDefault((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log,"0");
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				if (doicon) {
+					Attribute *aIconImageSequence = makeIconImageSequence(srclist,outputTransferSyntax);
+					if (aIconImageSequence) (*list)+=aIconImageSequence;
+				}
+
+                                // The following are not required in the IOD, but some profiles ...
+
+                                // ImageType (XABC-CD,XA1K-CD:1)
+
+			        Attribute *imageType=getCopyOfMultiValuedCodeStringAttributeElseNull((*srclist),TagFromName(ImageType));
+			        if (imageType) (*list)+=imageType;
+
+                                // CalibrationImage (XABC-CD,XA1K-CD:2)
+
+				const char *calibrationImage=getStringValueElseZeroLength((*srclist),TagFromName(CalibrationImage));
+				Assert(calibrationImage);
+				(*list)+=new CodeStringAttribute(TagFromName(CalibrationImage),calibrationImage);
+
+                                // ReferencedImageSequence (XABC-CD,XA1K-CD:1C if ImageType value 3 is BIPLANE A or B)
+                                // ReferencedImageSequence (CTMR:1C if present in image)
+
+			        Attribute *referencedImageSequence=getCopyOfReferencedImageSequenceAttributeElseNull((*srclist),TagFromName(ReferencedImageSequence),"Referenced Image Sequence",filename,log);
+			        if (referencedImageSequence) (*list)+=referencedImageSequence;
+
+                                // The Image Plane Module attributes are all (CTMR:1C if present in image)
+                                // (Rows and Columns are actually 1 since always present)
+				if (doposition) {
+					// ReferencedImageSequence already included above
+					
+					Attribute *a;
+					
+					a=getCopyOfMultiValuedDecimalStringAttributeElseNull((*srclist),TagFromName(ImagePositionPatient));
+					if (a) { (*list)+=a; }
+
+					a=getCopyOfMultiValuedDecimalStringAttributeElseNull((*srclist),TagFromName(ImageOrientationPatient));
+					if (a) { (*list)+=a; }	
+
+					a=(*srclist)[TagFromName(FrameOfReferenceUID)];
+					if (a) { (*srclist)-=a; (*list)+=a; }			// Do it safely safe in the absence of reference counting ...
+
+					a=(*srclist)[TagFromName(TableHeight)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(Rows)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(Columns)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=getCopyOfMultiValuedDecimalStringAttributeElseNull((*srclist),TagFromName(PixelSpacing));
+					if (a) { (*list)+=a; }
+				}
+                                // The following might hypothetically be required in a future enhanced CT/MR object profile ...
+
+				if (sopClassUID && (strcmp(sopClassUID,EnhancedMRImageStorageSOPClassUID) == 0 || strcmp(sopClassUID,EnhancedCTImageStorageSOPClassUID) == 0)) {
+					const char *acquisitionDateTime=getStringValueElseNull((*srclist),TagFromName(AcquisitionDateTime));
+					if (acquisitionDateTime)
+						(*list)+=new DateTimeStringAttribute(TagFromName(AcquisitionDateTime),acquisitionDateTime);
+
+					const char *volumetricProperties=getStringValueElseNull((*srclist),TagFromName(VolumetricProperties));
+					if (volumetricProperties)
+						(*list)+=new CodeStringAttribute(TagFromName(VolumetricProperties),volumetricProperties);
+
+					const char *volumeBasedCalculationTechnique=getStringValueElseNull((*srclist),TagFromName(VolumeBasedCalculationTechnique));
+					if (volumeBasedCalculationTechnique)
+						(*list)+=new CodeStringAttribute(TagFromName(VolumeBasedCalculationTechnique),volumeBasedCalculationTechnique);
+
+					const char *complexImageComponent=getStringValueElseNull((*srclist),TagFromName(ComplexImageComponent));
+					if (complexImageComponent)
+						(*list)+=new CodeStringAttribute(TagFromName(ComplexImageComponent),complexImageComponent);
+
+					const char *acquisitionContrast=getStringValueElseNull((*srclist),TagFromName(AcquisitionContrast));
+					if (acquisitionContrast)
+						(*list)+=new CodeStringAttribute(TagFromName(AcquisitionContrast),acquisitionContrast);
+
+					const char *pixelPresentation=getStringValueElseNull((*srclist),TagFromName(PixelPresentation));
+					if (pixelPresentation)
+						(*list)+=new CodeStringAttribute(TagFromName(PixelPresentation),pixelPresentation);
+					
+					if (doposition) {
+						// check and see if ImageOrientationPatient is shared and if so include it
+						SequenceAttribute *aSharedFunctionalGroupsSequence=(SequenceAttribute *)((*srclist)[TagFromName(SharedFunctionalGroupsSequence)]);
+						if (aSharedFunctionalGroupsSequence) {
+							AttributeList **lSharedFunctionalGroupsSequence;
+							int countSharedFunctionalGroupsSequenceItems = aSharedFunctionalGroupsSequence->getLists(&lSharedFunctionalGroupsSequence);
+							if (lSharedFunctionalGroupsSequence && countSharedFunctionalGroupsSequenceItems == 1) {
+								AttributeList *iSharedFunctionalGroupsSequence = lSharedFunctionalGroupsSequence[0];
+								if (iSharedFunctionalGroupsSequence) {
+									SequenceAttribute *aPlaneOrientationSequence=(SequenceAttribute *)
+										((*iSharedFunctionalGroupsSequence)[TagFromName(PlaneOrientationSequence)]);
+									if (aPlaneOrientationSequence) {
+										AttributeList **lPlaneOrientationSequence;
+										int countPlaneOrientationSequenceItems = aPlaneOrientationSequence->getLists(&lPlaneOrientationSequence);
+										if (lPlaneOrientationSequence && countPlaneOrientationSequenceItems == 1) {
+											AttributeList *iPlaneOrientationSequence = lPlaneOrientationSequence[0];
+											if (iPlaneOrientationSequence) {
+												Attribute *aImageOrientationPatient=(*iPlaneOrientationSequence)[TagFromName(ImageOrientationPatient)];
+												if (aImageOrientationPatient) {
+													(*iPlaneOrientationSequence)-=aImageOrientationPatient; (*list)+=aImageOrientationPatient;
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+				
+				// regardless of SOP Class, if concatenation stuff is present, include it ...
+				{
+					const char *concatenationUID=getStringValueElseNull((*srclist),TagFromName(ConcatenationUID));
+					Uint16 inConcatenationNumber=AttributeValue((*srclist)[TagFromName(InConcatenationNumber)]);
+					Uint32 concatenationFrameOffsetNumber=AttributeValue((*srclist)[TagFromName(ConcatenationFrameOffsetNumber)]);
+					if (concatenationUID) {
+						(*list)+=new UIStringAttribute(TagFromName(ConcatenationUID),concatenationUID);
+						(*list)+=new UnsignedShortAttribute(TagFromName(InConcatenationNumber),inConcatenationNumber);
+						(*list)+=new UnsignedLongAttribute(TagFromName(ConcatenationFrameOffsetNumber),concatenationFrameOffsetNumber);
+					}
+				}
+				
+				// regardless of SOP Class, add number of frames only if present in source ...
+				{
+					Attribute *aNumberOfFrames = (*srclist)[TagFromName(NumberOfFrames)];
+					if (aNumberOfFrames) {
+						Uint16 vNumberOfFrames = AttributeValue(aNumberOfFrames);
+						(*list)+=new IntegerStringAttribute(TagFromName(NumberOfFrames),vNumberOfFrames);
+					}
+				}
+				
+				// Optional but potentially useful ...
+			
+				const char *imageComments=getStringValueElseNull((*srclist),TagFromName(ImageComments));
+				if (imageComments && strlen(imageComments) > 0)
+					(*list)+=new LongTextAttribute(TagFromName(ImageComments),imageComments);
+
+				const char *photometricInterpretation=getStringValueElseNull((*srclist),TagFromName(PhotometricInterpretation));
+				if (photometricInterpretation)
+					(*list)+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),photometricInterpretation);
+				
+			}
+			else if (strcmp(directoryRecordType,"SR DOCUMENT") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *completionFlag=getStringValueElseError((*srclist),TagFromName(CompletionFlag),"Completion Flag",filename,log);
+				Assert(completionFlag);
+				(*list)+=new CodeStringAttribute(TagFromName(CompletionFlag),completionFlag);
+
+				const char *verificationFlag=getStringValueElseError((*srclist),TagFromName(VerificationFlag),"Verification Flag",filename,log);
+				Assert(verificationFlag);
+				(*list)+=new CodeStringAttribute(TagFromName(VerificationFlag),verificationFlag);
+
+				if (strcmp(verificationFlag,"VERIFIED") == 0) {
+					Attribute *aVerifyingObserverSequence = (*srclist)[TagFromName(VerifyingObserverSequence)];
+					if (aVerifyingObserverSequence->isSequence()) {
+						AttributeList **items;
+						int itemCount = aVerifyingObserverSequence->getLists(&items);
+						if (itemCount && items) {
+							AttributeList *itemList=*items;
+							const char *verificationDateTime=getStringValueElseError((*itemList),TagFromName(VerificationDateTime),"Verification DateTime",filename,log);
+							Assert(verificationDateTime);
+							(*list)+=new DateTimeStringAttribute(TagFromName(VerificationDateTime),verificationDateTime);
+						}
+						else {
+							log << filename << ": " << EMsgDC(EmptyAttribute) << " - " << "Verifying Observer Sequence (for Verification DateTime)" << endl;
+						}
+					}
+					else {
+						log << filename << ": " << EMsgDC(MissingAttribute) << " - " << "Verifying Observer Sequence (for Verification DateTime)" << endl;
+					}
+				}
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+
+				Attribute *conceptNameCodeSequence=getCopyOfCodeSequenceAttributeElseError((*srclist),TagFromName(ConceptNameCodeSequence),"Concept Name Code Sequence",filename,log);
+				if (conceptNameCodeSequence) {
+					(*list)+=conceptNameCodeSequence;
+				}
+				// Should also do Content Sequence with HAS CONCEPT MOD Relationship Type :(
+			}
+			else if (strcmp(directoryRecordType,"KEY OBJECT DOC") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+
+				Attribute *conceptNameCodeSequence=getCopyOfCodeSequenceAttributeElseError((*srclist),TagFromName(ConceptNameCodeSequence),"Concept Name Code Sequence",filename,log);
+				Assert(conceptNameCodeSequence);
+				(*list)+=conceptNameCodeSequence;
+
+				// Should also do Content Sequence with HAS CONCEPT MOD Relationship Type :(
+			}
+			else if (strcmp(directoryRecordType,"ENCAP DOC") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentDate=getStringValueElseZeroLength((*srclist),TagFromName(ContentDate));
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseZeroLength((*srclist),TagFromName(ContentTime));
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+
+				const char *documentTitle=getStringValueElseZeroLength((*srclist),TagFromName(DocumentTitle));
+				Assert(documentTitle);
+				(*list)+=new ShortTextAttribute(TagFromName(DocumentTitle),documentTitle);
+				
+				const char *hl7InstanceIdentifier=getStringValueElseNull((*srclist),TagFromName(HL7InstanceIdentifier));
+				if (hl7InstanceIdentifier) {
+					(*list)+=new ShortTextAttribute(TagFromName(HL7InstanceIdentifier),hl7InstanceIdentifier);
+				}
+				
+				const char *mimeTypeOfEncapsulatedDocument=getStringValueElseError((*srclist),TagFromName(MIMETypeOfEncapsulatedDocument),"MIME Type of Encapsulated Document",filename,log);
+				Assert(mimeTypeOfEncapsulatedDocument);
+				(*list)+=new LongStringAttribute(TagFromName(MIMETypeOfEncapsulatedDocument),mimeTypeOfEncapsulatedDocument);
+
+				Attribute *conceptNameCodeSequence=getCopyOfCodeSequenceAttributeElseEmpty((*srclist),TagFromName(ConceptNameCodeSequence),"Concept Name Code Sequence",filename,log);
+				Assert(conceptNameCodeSequence);
+				(*list)+=conceptNameCodeSequence;
+			}
+			else if (strcmp(directoryRecordType,"PRESENTATION") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentLabel=getStringValueElseError((*srclist),TagFromName(ContentLabel),"Content Label",filename,log);
+				Assert(contentLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(ContentLabel),contentLabel);
+
+				const char *contentDescription=getStringValueElseZeroLength((*srclist),TagFromName(ContentDescription));
+				Assert(contentDescription);
+				(*list)+=new LongStringAttribute(TagFromName(ContentDescription),contentDescription);
+
+				const char *presentationCreationDate=getStringValueElseError((*srclist),TagFromName(PresentationCreationDate),"Presentation Creation Date",filename,log);
+				Assert(presentationCreationDate);
+				(*list)+=new DateStringAttribute(TagFromName(PresentationCreationDate),presentationCreationDate);
+
+				const char *presentationCreationTime=getStringValueElseError((*srclist),TagFromName(PresentationCreationTime),"Presentation Creation Time",filename,log);
+				Assert(presentationCreationTime);
+				(*list)+=new TimeStringAttribute(TagFromName(PresentationCreationTime),presentationCreationTime);
+
+				const char *contentCreatorName=getStringValueElseZeroLength((*srclist),TagFromName(ContentCreatorName));
+				Assert(contentCreatorName);
+				(*list)+=new PersonNameAttribute(TagFromName(ContentCreatorName),contentCreatorName);
+
+				if (isAttributePresentElseNull((*srclist),TagFromName(ReferencedSeriesSequence))) {
+					Attribute *referencedSeriesSequence=getCopyOfReferencedSeriesSequenceAttributeElseError((*srclist),TagFromName(ReferencedSeriesSequence),"Referenced Series Sequence",filename,log);
+					Assert(referencedSeriesSequence);
+					(*list)+=referencedSeriesSequence;
+				}
+				
+				if (isAttributePresentElseNull((*srclist),TagFromName(BlendingSequence))) {
+					Attribute *blendingSequence=getCopyOfSequenceContainingStudySeriesImageReferenceElseError((*srclist),TagFromName(BlendingSequence),"Blending Sequence",filename,log);
+					Assert(blendingSequence);
+					(*list)+=blendingSequence;
+				}
+			}
+			else if (strcmp(directoryRecordType,"REGISTRATION") == 0
+			      || strcmp(directoryRecordType,"FIDUCIAL") == 0
+				  || strcmp(directoryRecordType,"VALUE MAP") == 0
+				  || strcmp(directoryRecordType,"MEASUREMENT") == 0
+				  || strcmp(directoryRecordType,"SURFACE") == 0
+				  ) {
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentLabel=getStringValueElseError((*srclist),TagFromName(ContentLabel),"Content Label",filename,log);
+				Assert(contentLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(ContentLabel),contentLabel);
+
+				const char *contentDescription=getStringValueElseZeroLength((*srclist),TagFromName(ContentDescription));
+				Assert(contentDescription);
+				(*list)+=new LongStringAttribute(TagFromName(ContentDescription),contentDescription);
+
+				const char *contentCreatorName=getStringValueElseZeroLength((*srclist),TagFromName(ContentCreatorName));
+				Assert(contentCreatorName);
+				(*list)+=new PersonNameAttribute(TagFromName(ContentCreatorName),contentCreatorName);
+			}
+			else if (strcmp(directoryRecordType,"STEREOMETRIC") == 0) {
+				// nothing actually required
+			}
+			else if (strcmp(directoryRecordType,"SPECTROSCOPY") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+
+			        Attribute *imageType=getCopyOfMultiValuedCodeStringAttributeElseNull((*srclist),TagFromName(ImageType));
+			        if (imageType) (*list)+=imageType;
+
+				{
+					Attribute *a;
+					a=(*srclist)[TagFromName(Rows)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(Columns)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+					
+					a=(*srclist)[TagFromName(DataPointRows)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(DataPointColumns)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+				}
+				
+				// add number of frames only if present in source (should always be) ...
+				{
+					Attribute *aNumberOfFrames = (*srclist)[TagFromName(NumberOfFrames)];
+					if (aNumberOfFrames) {
+						Uint16 vNumberOfFrames = AttributeValue(aNumberOfFrames);
+						(*list)+=new IntegerStringAttribute(TagFromName(NumberOfFrames),vNumberOfFrames);
+					}
+				}
+				
+				// Optional but potentially useful ...
+			
+				const char *imageComments=getStringValueElseNull((*srclist),TagFromName(ImageComments));
+				if (imageComments && strlen(imageComments) > 0)
+					(*list)+=new LongTextAttribute(TagFromName(ImageComments),imageComments);
+				
+                        }
+			else if (strcmp(directoryRecordType,"RAW DATA") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+                        }
+			else if (strcmp(directoryRecordType,"WAVEFORM") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+                        }
+			else if (strcmp(directoryRecordType,"OVERLAY") == 0) {
+				const char *overlayNumber=getStringValueElseError((*srclist),TagFromName(OverlayNumber),"Overlay Number",filename,log);
+				Assert(overlayNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(OverlayNumber),overlayNumber);
+                        }
+			else if (strcmp(directoryRecordType,"MODALITY LUT") == 0 || strcmp(directoryRecordType,"MODALITY LUT") == 0) {
+				const char *lutNumber=getStringValueElseError((*srclist),TagFromName(LUTNumber),"LUT Number",filename,log);
+				Assert(lutNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(LUTNumber),lutNumber);
+                        }
+			else if (strcmp(directoryRecordType,"CURVE") == 0) {
+				const char *curveNumber=getStringValueElseError((*srclist),TagFromName(CurveNumber),"Curve Number",filename,log);
+				Assert(curveNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(CurveNumber),curveNumber);
+                        }
+			else if (strcmp(directoryRecordType,"STORED PRINT") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+                        }
+			else if (strcmp(directoryRecordType,"RT DOSE") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *doseSummationType=getStringValueElseError((*srclist),TagFromName(DoseSummationType),"Dose Summation Type",filename,log);
+				Assert(doseSummationType);
+				(*list)+=new CodeStringAttribute(TagFromName(DoseSummationType),doseSummationType);
+
+                                const char *doseComment=getStringValueElseNull((*srclist),TagFromName(DoseComment));
+                                if (doseComment) (*list)+=new LongStringAttribute(TagFromName(DoseComment),doseComment);
+			}
+			else if (strcmp(directoryRecordType,"RT STRUCTURE SET") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *structureSetLabel=getStringValueElseError((*srclist),TagFromName(StructureSetLabel),"Structure Set Label",filename,log);
+				Assert(structureSetLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(StructureSetLabel),structureSetLabel);
+
+				const char *structureSetDate=getStringValueElseZeroLength((*srclist),TagFromName(StructureSetDate));
+				Assert(structureSetDate);
+				(*list)+=new DateStringAttribute(TagFromName(StructureSetDate),structureSetDate);
+
+				const char *structureSetTime=getStringValueElseZeroLength((*srclist),TagFromName(StructureSetTime));
+				Assert(structureSetTime);
+				(*list)+=new TimeStringAttribute(TagFromName(StructureSetTime),structureSetTime);
+			}
+			else if (strcmp(directoryRecordType,"RT PLAN") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *rtPlanLabel=getStringValueElseError((*srclist),TagFromName(RTPlanLabel),"RT Plan Label",filename,log);
+				Assert(rtPlanLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(RTPlanLabel),rtPlanLabel);
+
+				const char *rtPlanDate=getStringValueElseZeroLength((*srclist),TagFromName(RTPlanDate));
+				Assert(rtPlanDate);
+				(*list)+=new DateStringAttribute(TagFromName(RTPlanDate),rtPlanDate);
+
+				const char *rtPlanTime=getStringValueElseZeroLength((*srclist),TagFromName(RTPlanTime));
+				Assert(rtPlanTime);
+				(*list)+=new TimeStringAttribute(TagFromName(RTPlanTime),rtPlanTime);
+			}
+			else if (strcmp(directoryRecordType,"RT TREAT RECORD") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *treatmentDate=getStringValueElseZeroLength((*srclist),TagFromName(TreatmentDate));
+				Assert(treatmentDate);
+				(*list)+=new DateStringAttribute(TagFromName(TreatmentDate),treatmentDate);
+
+				const char *treatmentTime=getStringValueElseZeroLength((*srclist),TagFromName(TreatmentTime));
+				Assert(treatmentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(TreatmentTime),treatmentTime);
+			}
+		}
+
+	~InstanceDirectoryRecord()
+		{
+			if (sopInstanceUID) delete[] sopInstanceUID;
+			if (instanceNumber)    delete[] instanceNumber;
+		}
+
+	InstanceDirectoryRecord *getSibling()	{ return (InstanceDirectoryRecord *)sibling; }
+
+	const char *getSOPInstanceUID()		{ return sopInstanceUID; }
+	const char *getInstanceNumber()		{ return instanceNumber; }
+
+	bool matches(const char *uid)
+		{
+			Assert(uid);
+			Assert(sopInstanceUID);
+			return strcmp(uid,sopInstanceUID) == 0 ? true : false;
+		}
+};
+
+class SeriesDirectoryRecord : public DirectoryRecordBase {
+	const char *seriesInstanceUID;
+	const char *seriesNumber;
+	const char *modality;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			log << "\t\t";
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Series "
+			    << (seriesInstanceUID ? seriesInstanceUID : "") << " "
+			    << (seriesNumber ? seriesNumber : "")
+			    << endl;
+			return log;
+		}
+public:
+	SeriesDirectoryRecord(const char *uid,AttributeList *srclist,SeriesDirectoryRecord *nextsib,const char *filename,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib,srclist)
+		{
+			// the following are Type 1 in directory record ...
+
+			seriesInstanceUID=uid;
+			Assert(seriesInstanceUID);
+			(*list)+=new UIStringAttribute(TagFromName(SeriesInstanceUID),seriesInstanceUID);
+
+			seriesNumber=getStringValueElseWarningAndDefault((*srclist),TagFromName(SeriesNumber),"Series Number",filename,log,"0");
+			Assert(seriesNumber);
+			(*list)+=new IntegerStringAttribute(TagFromName(SeriesNumber),seriesNumber);
+
+			modality=getStringValueElseWarningAndDefault((*srclist),TagFromName(Modality),"Modality",filename,log,"OT");
+			Assert(modality);
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),modality);
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),"SERIES");
+
+                        // The following are not required in the IOD, but some profiles ...
+
+                        // InstitutionName (XABC-CD,XA1K-CD:2)
+
+			const char *institutionName=getStringValueElseZeroLength((*srclist),TagFromName(InstitutionName));
+			Assert(institutionName);
+			(*list)+=new LongStringAttribute(TagFromName(InstitutionName),institutionName);
+
+                        // InstitutionAddress (XABC-CD,XA1K-CD:2)
+
+			const char *institutionAddress=getStringValueElseZeroLength((*srclist),TagFromName(InstitutionAddress));
+			Assert(institutionAddress);
+			(*list)+=new ShortTextAttribute(TagFromName(InstitutionAddress),institutionAddress);
+
+                        // PerformingPhysicianName (XABC-CD,XA1K-CD:2)
+                        // should really check for and copy multiple values :(
+
+			const char *performingPhysicianName=getStringValueElseZeroLength((*srclist),TagFromName(PerformingPhysicianName));
+			Assert(performingPhysicianName);
+			(*list)+=new PersonNameAttribute(TagFromName(PerformingPhysicianName),performingPhysicianName);
+			
+			// Optional but potentially useful ...
+			
+			const char *seriesDescription=getStringValueElseNull((*srclist),TagFromName(SeriesDescription));
+			if (seriesDescription && strlen(seriesDescription) > 0)
+				(*list)+=new LongStringAttribute(TagFromName(SeriesDescription),seriesDescription);
+				
+			const char *bodyPartExamined=getStringValueElseNull((*srclist),TagFromName(BodyPartExamined));
+			if (bodyPartExamined && strlen(bodyPartExamined) > 0)
+				(*list)+=new CodeStringAttribute(TagFromName(BodyPartExamined),bodyPartExamined);
+				
+			const char *laterality=getStringValueElseNull((*srclist),TagFromName(Laterality));
+			if (laterality && strlen(laterality) > 0)
+				(*list)+=new CodeStringAttribute(TagFromName(Laterality),laterality);
+			
+			const char *manufacturer=getStringValueElseNull((*srclist),TagFromName(Manufacturer));
+			if (manufacturer && strlen(manufacturer) > 0)
+				(*list)+=new LongStringAttribute(TagFromName(Manufacturer),manufacturer);
+			
+			const char *manufacturerModelName=getStringValueElseNull((*srclist),TagFromName(ManufacturerModelName));
+			if (manufacturerModelName && strlen(manufacturerModelName) > 0)
+				(*list)+=new LongStringAttribute(TagFromName(ManufacturerModelName),manufacturerModelName);
+		}
+
+	~SeriesDirectoryRecord()
+		{
+			if (seriesInstanceUID) delete[] seriesInstanceUID;
+			if (seriesNumber)      delete[] seriesNumber;
+			if (modality)          delete[] modality;
+		}
+
+	SeriesDirectoryRecord *getSibling()	{ return (SeriesDirectoryRecord *)sibling; }
+	InstanceDirectoryRecord   *getChild()	{ return (InstanceDirectoryRecord *)child; }
+
+	const char *getSeriesInstanceUID()	{ return seriesInstanceUID; }
+	const char *getSeriesNumber()		{ return seriesNumber; }
+
+	bool matches(const char *uid)
+		{
+			Assert(uid);
+			Assert(seriesInstanceUID);
+			return strcmp(uid,seriesInstanceUID) == 0 ? true : false;
+		}
+
+	bool checkMatch(AttributeList *srclist,const char *filename,TextOutputStream &log,bool verbose)
+		{
+			Assert(seriesInstanceUID);
+			Assert(seriesNumber);
+			Assert(modality);
+
+			if (verbose) log << filename << " matches "
+					     << seriesInstanceUID
+					     << " "
+					     << seriesNumber
+					     << endl;
+
+			(void)errorIfStringValuesDontMatch(seriesNumber,*srclist,
+				TagFromName(SeriesNumber),"Series Number",
+				"Series Instance UID",seriesInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(modality,*srclist,
+				TagFromName(Modality),"Modality",
+				"Series Instance UID",seriesInstanceUID,filename,log);
+		}
+};
+
+class StudyDirectoryRecord : public DirectoryRecordBase {
+	const char *studyInstanceUID;
+	const char *studyID;
+	const char *studyDate;
+	const char *studyTime;
+	const char *studyDescription;
+	const char *accessionNumber;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			log << "\t";
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Study "
+			    << (studyInstanceUID ? studyInstanceUID : "") << " "
+			    << (studyID ? studyID : "")
+			    << endl;
+			return log;
+		}
+public:
+	StudyDirectoryRecord(const char *uid,AttributeList *srclist,StudyDirectoryRecord *nextsib,const char *filename,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib,srclist)
+		{
+			// the following are Type 1 in directory record ...
+
+			studyInstanceUID=uid;
+			Assert(studyInstanceUID);
+			(*list)+=new UIStringAttribute(TagFromName(StudyInstanceUID),studyInstanceUID);
+
+			Attribute *a;
+
+			studyDate=getStringValueElseWarningAndDefault((*srclist),TagFromName(StudyDate),"Study Date",filename,log,"19000101");
+			Assert(studyDate);
+			(*list)+=new DateStringAttribute(TagFromName(StudyDate),studyDate);
+
+			studyTime=getStringValueElseWarningAndDefault((*srclist),TagFromName(StudyTime),"Study Time",filename,log,"000000");
+			Assert(studyTime);
+			(*list)+=new TimeStringAttribute(TagFromName(StudyTime),studyTime);
+
+			studyID=getStringValueElseWarningAndDefault((*srclist),TagFromName(StudyID),"Study ID",filename,log,studyDate);
+			Assert(studyID);
+			(*list)+=new ShortStringAttribute(TagFromName(StudyID),studyID);
+
+			// the following are Type 2 in directory record ...
+
+			studyDescription=AttributeValue((*srclist)[TagFromName(StudyDescription)],"");
+			Assert(studyDescription);
+			(*list)+=new LongStringAttribute(TagFromName(StudyDescription),studyDescription);
+
+			accessionNumber=AttributeValue((*srclist)[TagFromName(AccessionNumber)],"");
+			Assert(accessionNumber);
+			(*list)+=new ShortStringAttribute(TagFromName(AccessionNumber),accessionNumber);
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),"STUDY");
+		}
+
+	~StudyDirectoryRecord()
+		{
+			if (studyInstanceUID) delete[] studyInstanceUID;
+			if (studyID)          delete[] studyID;
+			if (studyDate)        delete[] studyDate;
+			if (studyTime)        delete[] studyTime;
+			if (studyDescription) delete[] studyDescription;
+			if (accessionNumber)  delete[] accessionNumber;
+		}
+
+	StudyDirectoryRecord *getSibling()	{ return (StudyDirectoryRecord *)sibling; }
+	SeriesDirectoryRecord   *getChild()	{ return (SeriesDirectoryRecord *)child; }
+
+	const char *getStudyInstanceUID()	{ return studyInstanceUID; }
+	const char *getStudyID()		{ return studyID; }
+
+	bool matches(const char *uid)
+		{
+			Assert(uid);
+			Assert(studyInstanceUID);
+			return strcmp(uid,studyInstanceUID) == 0 ? true : false;
+		}
+
+	bool checkMatch(AttributeList *srclist,const char *filename,TextOutputStream &log,bool verbose)
+		{
+			Assert(studyInstanceUID);
+			Assert(studyID);
+			Assert(studyDate);
+			Assert(studyTime);
+			Assert(studyDescription);
+			Assert(accessionNumber);
+
+			if (verbose) log << filename << " matches "
+					     << studyInstanceUID
+					     << " "
+					     << studyID
+					     << endl;
+
+			(void)errorIfStringValuesDontMatch(studyID,*srclist,
+				TagFromName(StudyID),"Study ID",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(studyDate,*srclist,
+				TagFromName(StudyDate),"Study Date",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(studyTime,*srclist,
+				TagFromName(StudyTime),"Study Time",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(studyDescription,*srclist,
+				TagFromName(StudyDescription),"Study Description",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(accessionNumber,*srclist,
+				TagFromName(AccessionNumber),"Accession Number",
+				"Study Instance UID",studyInstanceUID,filename,log);
+		}
+};
+
+class PatientDirectoryRecord : public DirectoryRecordBase {
+	const char *patientID;
+	const char *patientName;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Patient "
+			    << (patientID ? patientID : "") << " "
+			    << (patientName ? patientName : "")
+			    << endl;
+			return log;
+		}
+public:
+	PatientDirectoryRecord(const char *id,const char *name,AttributeList *srclist,PatientDirectoryRecord *nextsib,const char *filename,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib,srclist)
+		{
+			patientID=id;
+			Assert(patientID);
+			(*list)+=new LongStringAttribute(TagFromName(PatientID),patientID);
+
+			patientName=name;
+			Assert(patientName);
+			(*list)+=new PersonNameAttribute(TagFromName(PatientName),patientName);
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),"PATIENT");
+
+                        // The following are not required in the IOD, but some profiles ...
+
+                        // PatientBirthDate (XABC-CD,XA1K-CD:2)
+
+			const char *patientBirthDate=getStringValueElseZeroLength((*srclist),TagFromName(PatientBirthDate));
+			Assert(patientBirthDate);
+			(*list)+=new DateStringAttribute(TagFromName(PatientBirthDate),patientBirthDate);
+
+                        // PatientSex (XABC-CD,XA1K-CD:2)
+
+			const char *patientSex=getStringValueElseZeroLength((*srclist),TagFromName(PatientSex));
+			Assert(patientSex);
+			(*list)+=new CodeStringAttribute(TagFromName(PatientSex),patientSex);
+		}
+
+	~PatientDirectoryRecord()
+		{
+			if (patientID)   delete[] patientID;
+			if (patientName) delete[] patientName;
+		}
+
+	PatientDirectoryRecord *getSibling()	{ return (PatientDirectoryRecord *)sibling; }
+	StudyDirectoryRecord   *getChild()	{ return (StudyDirectoryRecord *)child; }
+
+	const char *getPatientID()	{ return patientID; }
+	const char *getPatientName()	{ return patientName; }
+	
+	static int indexOfLastSignificantPartOfPersonName(const char *name) {
+		int index = 0;
+		if (name != NULL) {
+			int length = strlen(name);
+			if (length > 0) {
+				const char *endptr = name + length - 1;
+				while (endptr >= name && *endptr && (*endptr == 0 || isspace(*endptr) || *endptr == '^')) --endptr;
+				index = endptr - name + 1;	// i.e. if empty, then index will be 0
+			}
+		}
+		return index;
+	}
+	
+	static bool compareOnlySignificantPartsOfPersonName(const char *name1,const char *name2) {
+//cerr << "PatientDirectoryRecord.compareOnlySignificantPartsOfPersonName(): name1 " << name1 << endl;
+//cerr << "PatientDirectoryRecord.compareOnlySignificantPartsOfPersonName(): name2 " << name2 << endl;
+		int n = indexOfLastSignificantPartOfPersonName(name1);
+//cerr << "PatientDirectoryRecord.compareOnlySignificantPartsOfPersonName(): name1 index " << n << endl;
+		int index2 = indexOfLastSignificantPartOfPersonName(name2);
+//cerr << "PatientDirectoryRecord.compareOnlySignificantPartsOfPersonName(): name2 index " << index2 << endl;
+		if (index2 > n) {
+			n=index2;
+		}
+		return strncmp(name1,name2,n) == 0;	// "compares not more than n characters"
+	}
+
+	bool matches(const char *id,const char *name)
+		{
+			Assert(id);
+			Assert(patientID);
+			Assert(name);
+			Assert(patientName);
+			//return strcmp(id,patientID) == 0 && strcmp(name,patientName) == 0 ? true : false;
+			return strcmp(id,patientID) == 0 && compareOnlySignificantPartsOfPersonName(name,patientName);
+		}
+
+	bool checkMatch(AttributeList *srclist,const char *filename,TextOutputStream &log,bool verbose)
+		{
+			Assert(patientID);
+			Assert(patientName);
+
+			(void)errorIfStringValuesDontMatch(patientName,*srclist,
+				TagFromName(PatientName),"Patient Name",
+				"Patient ID",patientID,filename,log);
+
+			if (verbose) log << filename << " matches "
+					     << patientID
+					     << " "
+					     << patientName
+					     << endl;
+		}
+};
+
+// Derived from attrmxls.cc ...
+
+static bool
+addMetaHeader(AttributeList &list,const TransferSyntax *ts,const char *uidstamp)
+{
+//cerr << "addMetaHeader" << endl;
+	Attribute *a;
+
+	{
+		Assert(ts);
+		const char *tsuid=ts->getUID();
+		Assert(tsuid);
+		a=new UIStringAttribute(TagFromName(TransferSyntaxUID),tsuid);
+		Assert(a);
+		list+=(a);
+	}
+
+	{
+		a=new OtherByteSmallNonPixelAttribute(TagFromName(FileMetaInformationVersion));
+		Assert(a);
+		unsigned char values[2];
+		values[0]=0x00;
+		values[1]=0x01;
+		a->setValue(values,2);
+		list+=(a);
+	}
+
+	{
+		a=new UIStringAttribute(TagFromName(MediaStorageSOPClassUID),MediaStorageDirectoryStorageSOPClassUID);
+		Assert(a);
+		list+=(a);
+	}
+
+	{
+		a=new UIStringAttribute(TagFromName(MediaStorageSOPInstanceUID),GeneratedDirInstanceUID(uidstamp));
+		Assert(a);
+		list+=(a);
+	}
+
+#ifndef DEFAULTIMPLEMENTATIONCLASSUID
+#define DEFAULTIMPLEMENTATIONCLASSUID "0.0.0.0"
+#endif
+	{
+		a=new UIStringAttribute(TagFromName(ImplementationClassUID));
+		Assert(a);
+		a->addValue(DEFAULTIMPLEMENTATIONCLASSUID);
+		list+=(a);
+	}
+
+#ifndef DEFAULTIMPLEMENTATIONVERSIONNAME
+#define DEFAULTIMPLEMENTATIONVERSIONNAME "NOTSPECIFIED"
+#endif
+	{
+		a=new ShortStringAttribute(TagFromName(ImplementationVersionName));
+		Assert(a);
+		a->addValue(DEFAULTIMPLEMENTATIONVERSIONNAME);
+		list+=(a);
+	}
+
+#ifndef DEFAULTSOURCEAPPLICATIONENTITYTITLE
+#define DEFAULTSOURCEAPPLICATIONENTITYTITLE "NOTSPECIFIED"
+#endif
+	{
+		a=new ApplicationEntityAttribute(TagFromName(SourceApplicationEntityTitle));
+		Assert(a);
+		a->addValue(DEFAULTSOURCEAPPLICATIONENTITYTITLE);
+		list+=(a);
+	}
+
+	return true;
+}
+
+static void handleOneFile(const char *filename,
+			PatientDirectoryRecord *&headPatient,
+			DicomInputOptions &dicom_input_options,
+			DicomOutputOptions &dicom_output_options,
+			bool listnames,bool success,bool veryverbose,bool veryveryverbose,
+			bool doicon,bool doposition,bool dovalidatename,bool doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel,
+			TextOutputStream &log) {
+
+		Assert(filename);
+		if (listnames) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			success=false;
+			return;
+		}
+
+		DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+
+		if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl;
+		list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			return;
+		}
+
+		const char *patientID=getStringValueElseWarningAndDefault(list,TagFromName(PatientID),"Patient ID",filename,log,"NOPATIENTID");
+		Assert(patientID);
+
+		const char *patientName=getStringValueElseWarningAndDefault(list,TagFromName(PatientName),"Patient Name",filename,log,"Nobody^");
+		Assert(patientName);
+
+		PatientDirectoryRecord *ptrPatient=headPatient;
+		while (ptrPatient && !ptrPatient->matches(patientID,patientName)) ptrPatient=ptrPatient->getSibling();
+
+		StudyDirectoryRecord *headStudy,*ptrStudy;
+		if (ptrPatient) {
+			ptrPatient->checkMatch(&list,filename,log,veryverbose);
+
+			ptrStudy=headStudy=ptrPatient->getChild();
+		}
+		else {
+			if (veryverbose) log << filename << " no match for ID <" << patientID << "> and Name <" << patientName << ">" << endl;
+
+			ptrPatient=headPatient=new PatientDirectoryRecord(patientID,patientName,&list,headPatient,filename,log);
+			ptrStudy=headStudy=0;
+		}
+
+		const char *studyInstanceUID=getStringValueElseError(list,TagFromName(StudyInstanceUID),"Study Instance UID",filename,log);
+		Assert(studyInstanceUID);
+
+		while (ptrStudy && !ptrStudy->matches(studyInstanceUID)) ptrStudy=ptrStudy->getSibling();
+
+		SeriesDirectoryRecord *headSeries,*ptrSeries;
+		if (ptrStudy) {
+			ptrStudy->checkMatch(&list,filename,log,veryverbose);
+
+			ptrSeries=headSeries=ptrStudy->getChild();
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << studyInstanceUID << endl;
+
+			ptrStudy=headStudy=new StudyDirectoryRecord(studyInstanceUID,&list,headStudy,filename,log);
+			Assert(ptrPatient);
+			ptrPatient->setChild(headStudy);
+			ptrSeries=headSeries=0;
+		}
+
+		const char *seriesInstanceUID=getStringValueElseError(list,TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+		Assert(seriesInstanceUID);
+
+		while (ptrSeries && !ptrSeries->matches(seriesInstanceUID)) ptrSeries=ptrSeries->getSibling();
+
+		InstanceDirectoryRecord *headInstance,*ptrInstance;
+		if (ptrSeries) {
+			ptrSeries->checkMatch(&list,filename,log,veryverbose);
+
+			ptrInstance=headInstance=ptrSeries->getChild();
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << seriesInstanceUID << endl;
+
+			ptrSeries=headSeries=new SeriesDirectoryRecord(seriesInstanceUID,&list,headSeries,filename,log);
+			Assert(ptrStudy);
+			ptrStudy->setChild(headSeries);
+			ptrInstance=headInstance=0;
+		}
+
+		const char *sopInstanceUID=getStringValueElseError(list,TagFromName(SOPInstanceUID),"SOP Instance UID",filename,log);
+		Assert(sopInstanceUID);
+
+		while (ptrInstance && !ptrInstance->matches(sopInstanceUID)) ptrInstance=ptrInstance->getSibling();
+
+		if (ptrInstance) {
+			log << "Error - duplicate SOP instance within Series for file " << filename << " matches "
+			    << ptrInstance-> getSOPInstanceUID()
+			    << " Instance Number "
+			    << (ptrInstance-> getInstanceNumber() ? ptrInstance-> getInstanceNumber() : "")
+			    << endl;
+
+			return; // because of error
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << sopInstanceUID << endl;
+
+			TransferSyntax outts(dicom_output_options.transfersyntaxuid);	// SGI CC doesn't like this inline :(
+			ptrInstance=headInstance=new InstanceDirectoryRecord(sopInstanceUID,&list,headInstance,
+				filename,
+				din.getTransferSyntaxToReadDataSet()->getUID(),
+				&outts,
+				doicon,doposition,dovalidatename,doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel,log);
+			Assert(ptrSeries);
+			ptrSeries->setChild(headInstance);
+		}
+
+		if (fstr) {
+			fstr->close();
+			delete fstr;
+		}
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool veryveryverbose=options.get("veryveryverbose") || options.get("vvv");
+	if (veryveryverbose) veryverbose=true;
+	if (veryverbose) verbose=true;
+	bool listnames=options.get("l");
+
+	const char *descriptor=0;
+	(void)(options.get("descriptor",descriptor) || options.get("readme",descriptor));
+
+	const char *identifier=0;
+	(void)(options.get("identifier",identifier) || options.get("id",identifier));
+
+	bool doicon=!options.get("noicons");
+	bool doposition=options.get("position");
+	bool dovalidatename=!options.get("novalidatename");
+	bool doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel=!options.get("noinstancechildoffset");
+
+	DirectoryRecordWriteOrder order(DirectoryRecordWriteOrder::ParentChildSibling);
+	{
+		const char *order_arg=0;
+		if (options.get("dirrecorder",order_arg)) {
+			if (!order_arg || !*order_arg) bad=true;
+			else if (strcmp(order_arg,"pcs") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ParentChildSibling);
+			else if (strcmp(order_arg,"psc") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ParentSiblingChild);
+			else if (strcmp(order_arg,"scp") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::SiblingChildParent);
+			else if (strcmp(order_arg,"spc") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::SiblingParentChild);
+			else if (strcmp(order_arg,"csp") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ChildSiblingParent);
+			else if (strcmp(order_arg,"cps") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ChildParentSibling);
+			else bad=true;
+		}
+	}
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	const char *filelistfile=0;
+	(void)(options.get("filelist",filelistfile) || options.get("f",filelistfile));
+
+	int numberofinputfiles=!options;
+
+
+	const char **listoffilenames = new const char * [numberofinputfiles];
+	const char **ptr = listoffilenames;
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		*ptr++=filename;
+	}
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose|-vvv|-veryveryverbose]"
+			<< " [-descriptor|-readme filename]"
+			<< " [-identifier|-id filesetid]"
+			<< " [-noicons]"
+			<< " [-position]"
+			<< " [-novalidatename]"
+			<< " [-dirrecorder pcs|psc|scp|spc|csp|cps]"
+			<< " [-noinstancechildoffset]"
+			<< " [-f|-filelist filename]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	PatientDirectoryRecord *headPatient=0;
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		handleOneFile(listoffilenames[i],headPatient,dicom_input_options,dicom_output_options,
+			listnames,success,veryverbose,veryveryverbose,doicon,doposition,dovalidatename,doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel,
+			log);
+	}
+
+	if (filelistfile) {
+		ifstream *flfstr=new ifstream(filelistfile);
+		if (!flfstr || !*flfstr || !flfstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filelistfile) cerr <<" - \"" << filename << "\"";
+			cerr << endl;
+			bad=true;
+		}
+		else {
+			while (flfstr->peek() != istream::traits_type::eof()) {
+				const int lineBufferSize=2048;
+				char lineBuffer[lineBufferSize];
+				flfstr->getline(lineBuffer,2048);
+				if (strlen(lineBuffer))
+					handleOneFile(lineBuffer,headPatient,dicom_input_options,dicom_output_options,
+						listnames,success,veryverbose,veryveryverbose,doicon,doposition,dovalidatename,doNotIncludeLowerLevelDirectoryOffsetForInstanceLevel,
+						log);
+				// else skip blank lines
+			}
+		}
+	}
+
+	if (veryverbose && headPatient) {
+		TransferSyntax outts(dicom_output_options.transfersyntaxuid);	// SGI CC doesn't like this inline :(
+		headPatient->write(log,&outts);
+	}
+
+	if (numberofinputfiles && listoffilenames) delete[] listoffilenames;
+
+	if (success) {
+		AttributeList list;
+
+		DicomOutputStream dout(*(ostream *)output_opener,
+			dicom_output_options.transfersyntaxuid,
+			dicom_output_options.usemetaheader,
+			dicom_output_options.useimplicitmetaheader,
+			dicom_output_options.addtiff);
+
+		if (dicom_output_options.usemetaheader) {
+			addMetaHeader(list,dout.getTransferSyntaxToWriteDataSet(),dicom_output_options.stamp);
+			(void)addLengths(list,dout.getTransferSyntaxToWriteMetaHeader(),dout.getTransferSyntaxToWriteDataSet());
+		}
+
+		if (identifier)
+			list+=new CodeStringAttribute(TagFromName(FileSetID),identifier);
+		else
+			list+=new CodeStringAttribute(TagFromName(FileSetID));
+
+		if (descriptor)
+			list+=new CodeStringFileComponentAttribute(TagFromName(FileSetDescriptorFileID),descriptor);
+
+		list+=new UnsignedShortAttribute(TagFromName(FileSetConsistencyFlag),0x0000);
+
+		Uint32 predictedOffset=0;
+
+		if (dicom_output_options.usemetaheader)
+			predictedOffset+=132;	// preamble
+
+		AttributeListIterator listi(list);
+		while (!listi) {
+			Attribute *a = listi();
+			Assert(a);
+			if (veryverbose) { a->write(log,&staticDictionary); log << endl; }
+			predictedOffset+=lengthOfFixedPartOfAttribute(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),a)
+						+a->getVL();
+			++listi;
+		}
+
+		if (veryverbose) log << "Predicted Offset before Root Directory Entity First Directory Record attribute = " << dec << predictedOffset << endl;
+
+		Attribute *aRootDirectoryFirstRecord=new UnsignedLongAttribute(TagFromName(OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity),0);
+
+		predictedOffset+=lengthOfFixedPartOfAttribute(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),aRootDirectoryFirstRecord)
+						+aRootDirectoryFirstRecord->getVL();
+
+		Attribute *aRootDirectoryLastRecord=new UnsignedLongAttribute(TagFromName(OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity),0);
+
+		predictedOffset+=lengthOfFixedPartOfAttribute(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),aRootDirectoryLastRecord)
+						+aRootDirectoryLastRecord->getVL();
+
+		if (veryverbose) log << "Predicted Offset before Directory Record Sequence = " << dec << predictedOffset << endl;
+
+		SequenceAttribute *aDirectoryRecordSequence=new SequenceAttribute(TagFromName(DirectoryRecordSequence));
+
+		predictedOffset+=lengthOfFixedPartOfAttribute(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),aDirectoryRecordSequence);
+
+		if (veryverbose) log << "Predicted Offset before first item = " << dec << predictedOffset << endl;
+
+		if (headPatient) {
+			Uint32 lastoffset;
+
+			(void)headPatient->setOffset(
+					dout.getTransferSyntaxToWriteDataSet(),predictedOffset,log,veryverbose,lastoffset,order);
+
+			headPatient->linkOffset();
+
+			if (veryverbose) {
+				TransferSyntax outts(dicom_output_options.transfersyntaxuid);	// SGI CC doesn't like this inline :(
+				headPatient->write(log,&outts);
+			}
+
+			aRootDirectoryFirstRecord->setValue(0u,headPatient->getOffset());
+			list+=aRootDirectoryFirstRecord;
+
+			aRootDirectoryLastRecord->setValue(0u,lastoffset);
+			list+=aRootDirectoryLastRecord;
+
+			headPatient->flatten(aDirectoryRecordSequence,order);
+			list+=aDirectoryRecordSequence;
+		}
+
+		listi.first();
+		while (!listi) {
+			Attribute *a = listi();
+			Assert(a);
+			if (a->getTag().isMetaheaderGroup())
+				dout.writingMetaHeader();
+			else
+				dout.writingDataSet();
+			a->write(dout);
+			if (verbose) { a->write(log,&staticDictionary); log << endl; }
+			++listi;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
+
+
+
+
+
diff --git a/appsrc/dcfile/dcdirmk.cc_sqlengths b/appsrc/dcfile/dcdirmk.cc_sqlengths
new file mode 100755
index 0000000..566b824
--- /dev/null
+++ b/appsrc/dcfile/dcdirmk.cc_sqlengths
@@ -0,0 +1,1737 @@
+#include <fstream.h>
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrseq.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "sopcli.h"
+#include "transynu.h"
+#include "uidgen.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+// In a lot of places, there is an assumption that sequences and items will
+// be written delimited, ie. with undefined lengths ... this will break if
+// this changes (write() in attrseq.cc) :(
+
+// The icon image stuff uses a non-pixel data OB, and hence there is no
+// means of taking into account CP 14 setOutputEncoding stuff ... this
+// shouldn't be a problem as the TS is supposed to be explicit, but it
+// does mean a loss of generality :(
+
+// Writing this highlighted the fact the getVL() for sequences is not
+// working and reviseVL() was never implemented :(
+
+// The approach to making the icon image is make everything 8 bit, and
+// use the first "plane" as is regardless of whether it is color or indexed
+// (or even worse, interleaved) :( ... this will work really well for
+// MONOCHROME2 images where BitsStored is not much bigger than the real
+// maximum and the PixelRepresentaion is unsigned !
+
+static ElementDictionary staticDictionary;
+
+static bool
+errorIfStringValuesDontMatch(const char *dirValue,
+	AttributeList &list,Tag valueTag,
+	const char *valueDescription,
+	const char *uniqueKeyDescription,
+	const char *uniqueKeyValue,
+	const char *filename,TextOutputStream &log)
+{
+	Assert(filename);
+	Assert(dirValue);
+	Assert(valueDescription);
+	Assert(uniqueKeyDescription);
+	char *listValue=AttributeValue(list[valueTag],"");
+	Assert(listValue);
+
+	bool result;
+	if (strcmp(dirValue,listValue) != 0) {
+		log << filename << ": "<< "Error - Different " << valueDescription << " in instance <"
+		    << (listValue ? listValue : "")
+		    << "> for existing " << uniqueKeyDescription << " <"
+		    << (uniqueKeyValue ? uniqueKeyValue : "")
+		    << "> already entered in directory as " << valueDescription << " <"
+		    << (dirValue ? dirValue : "")
+		    << "> - using original value and assuming they are the same entity"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	if (listValue) delete[] listValue;
+	return result;
+}
+
+static Attribute *
+isAttributePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a)
+		return a;
+	else {
+		log << filename << ": "
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static Attribute *
+isAttributePresentElseNull(AttributeList &list,Tag tag)
+{
+	return list[tag];
+}
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static const char *
+getStringValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	if (a) {
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		return "";
+	}
+}
+
+static const char *
+getStringValueElseZeroLength(AttributeList &list,Tag tag)
+{
+	Attribute *a=list[tag];
+	if (a && a->getVM() > 0) {
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		return "";
+	}
+}
+
+static const char *
+getStringValueElseNull(AttributeList &list,Tag tag)
+{
+	Attribute *a=list[tag];
+	if (a && a->getVM() > 0) {
+		return AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	}
+	else {
+		return 0;
+	}
+}
+
+static Attribute *
+getCopyOfImageTypeAttributeElseNull(AttributeList &list,Tag tag)
+{
+	Attribute *attr=isAttributePresentElseNull(list,tag);
+        CodeStringAttribute *newAttr = 0;
+
+        if (attr) {
+                newAttr=new CodeStringAttribute(tag);
+                Assert(newAttr);
+                unsigned count = attr->getVM();
+                unsigned i;
+                for (i=0; i < count; ++i) {
+                        char *s;
+                        bool gotit=attr->getValue(i,s);
+                        Assert(gotit);
+                        Assert(s);      // should be "" rather than 0 if zero length
+                        newAttr->addValue(s);
+                        // should we now free s ???? :(
+                }
+        }
+        return newAttr;
+}
+
+
+static Attribute *
+getCopyOfCodeSequenceAttributeElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *codeValue=getStringValueElseError((*item),TagFromName(CodeValue),"Code Value",filename,log);
+			Assert(codeValue);
+			(*newItem)+=new ShortStringAttribute(TagFromName(CodeValue),codeValue);
+
+			const char *codingSchemeDesignator=getStringValueElseError((*item),TagFromName(CodingSchemeDesignator),"Coding Scheme Designator",filename,log);
+			Assert(codingSchemeDesignator);
+			(*newItem)+=new ShortStringAttribute(TagFromName(CodingSchemeDesignator),codingSchemeDesignator);
+
+			const char *codeMeaning=getStringValueElseError((*item),TagFromName(CodeMeaning),"Code Meaning",filename,log);
+			Assert(codeMeaning);
+			(*newItem)+=new LongStringAttribute(TagFromName(CodeMeaning),codeMeaning);
+		}
+	}
+	return newAttr;
+}
+
+
+static Attribute *
+getCopyOfReferencedImageSequenceAttribute(Attribute *attr,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *referencedSOPClassUID=getStringValueElseError((*item),TagFromName(ReferencedSOPClassUID),"Referenced SOP Class UID",filename,log);
+			Assert(referencedSOPClassUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(ReferencedSOPClassUID),referencedSOPClassUID);
+
+			const char *referencedSOPInstanceUID=getStringValueElseError((*item),TagFromName(ReferencedSOPInstanceUID),"Referenced SOP Instance UID",filename,log);
+			Assert(referencedSOPInstanceUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),referencedSOPInstanceUID);
+		}
+	}
+	return newAttr;
+}
+
+
+static Attribute *
+getCopyOfReferencedImageSequenceAttributeElseNull(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseNull(list,tag);
+	return getCopyOfReferencedImageSequenceAttribute(attr,tag,label,filename,log);
+}
+
+
+static Attribute *
+getCopyOfReferencedImageSequenceAttributeElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	return getCopyOfReferencedImageSequenceAttribute(attr,tag,label,filename,log);
+}
+
+
+static Attribute *
+getCopyOfReferencedSeriesSequenceAttributeElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *attr=isAttributePresentElseError(list,tag,label,filename,log);
+	SequenceAttribute *newAttr = 0;
+
+	// really would be nice to have a deep copy (clone) of any sequence attribute and its items, but for now ...
+
+	if (attr) {
+		Assert(attr->isSequence());
+		newAttr = new SequenceAttribute(tag);
+		Assert(newAttr);
+		AttributeList **items;
+		int itemCount = attr->getLists(&items);
+		AttributeList **iptr;
+		int i;
+		for (i=0,iptr=items; i<itemCount; ++i,++iptr) {
+			AttributeList *item=*iptr;
+			Assert(item);
+			AttributeList *newItem = new AttributeList();
+			Assert(newItem);
+			(*newAttr)+=newItem;
+
+			const char *seriesInstanceUID=getStringValueElseError((*item),TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+			Assert(seriesInstanceUID);
+			(*newItem)+=new UIStringAttribute(TagFromName(SeriesInstanceUID),seriesInstanceUID);
+
+			// Need to turn off until nested sequence attribute length calculation feature implemented ...
+
+			//Attribute *referencedImageSequence=getCopyOfReferencedImageSequenceAttributeElseError((*item),TagFromName(ReferencedImageSequence),"Referenced Image Sequence",filename,log);
+			//Assert(referencedImageSequence);
+			//(*newItem)+=referencedImageSequence;
+		}
+	}
+	return newAttr;
+}
+
+
+static SequenceAttribute *
+makeIconImageSequence(AttributeList *srclist,const TransferSyntax *transfersyntax,Uint16 iRows=64,Uint16 iColumns=64)
+{
+	SequenceAttribute *aIconImageSequence = 0;
+
+	Assert(srclist);
+	Assert(transfersyntax);
+	Assert(!transfersyntax->isImplicitVR());	// don't support CP 14 or length calculation here
+
+	Uint16 vRows 				= AttributeValue((*srclist)[TagFromName(Rows)]);
+	Uint16 vColumns 			= AttributeValue((*srclist)[TagFromName(Columns)]);
+	Uint16 vNumberOfFrames 			= AttributeValue((*srclist)[TagFromName(NumberOfFrames)]);
+	char * vPhotometricInterpretation 	= AttributeValue((*srclist)[TagFromName(PhotometricInterpretation)]);
+	Uint16 vSamplesPerPixel 		= AttributeValue((*srclist)[TagFromName(SamplesPerPixel)]);
+	Uint16 vBitsAllocated 			= AttributeValue((*srclist)[TagFromName(BitsAllocated)]);
+	Uint16 vBitsStored 			= AttributeValue((*srclist)[TagFromName(BitsStored)]);
+	Uint16 vHighBit 			= AttributeValue((*srclist)[TagFromName(HighBit)]);
+	Uint16 vPixelRepresentation 		= AttributeValue((*srclist)[TagFromName(PixelRepresentation)],0xffff);
+	Uint16 vPlanarConfiguration 		= AttributeValue((*srclist)[TagFromName(PlanarConfiguration)],0xffff);
+
+	Attribute *aPixelData = (*srclist)[TagFromName(PixelData)];
+
+	if (vRows && vColumns && vPhotometricInterpretation
+	 && vSamplesPerPixel && vBitsAllocated && vBitsStored && vHighBit
+	 && vPixelRepresentation != 0xffff
+	 && (vSamplesPerPixel <= 1 || vPlanarConfiguration != 0xffff)) {
+
+		Uint16 downRows=vRows/iRows;
+		Uint16 downColumns=vColumns/iColumns;
+
+		Assert(downRows);	// < icon size not yet supported
+		Assert(downColumns);
+
+		SourceBase<Uint16> *source=SupplySourceFromAttribute(aPixelData).getSource();
+		Assert(source);
+
+		unsigned char *iconPixelData=new unsigned char[iRows*iColumns];
+		Assert(iconPixelData);
+
+		unsigned row=0;
+		unsigned column=0;
+		unsigned irow=0;
+		unsigned icolumn=0;
+		unsigned char *p=iconPixelData;
+		while (row < vRows && source->read()) {
+			size_t n=source->getBufferCount();
+			Assert(n);
+			const Uint16 *buffer=source->getBuffer();
+			Assert(buffer);
+			while (n-- && row < vRows) {
+				if (row%downRows == 0 && column%downColumns == 0 && irow < iRows && icolumn < iColumns) {
+					Assert(p-iconPixelData < iRows*iColumns);
+					*p++=*buffer>>(vBitsStored-8);
+					if (++icolumn >= iColumns) {
+						icolumn=0;
+						++irow;
+					}
+				}
+				buffer++;
+				if (++column >= vColumns) {
+					column=0;
+					++row;
+				}
+			}
+		}
+		Assert(p-iconPixelData == iRows*iColumns);
+		//Assert(column == 0 && row == vRows*vNumberOfFrames);
+		aIconImageSequence=new SequenceAttribute(TagFromName(IconImageSequence));
+		AttributeList *iconlist = new AttributeList;
+		Assert(iconlist);
+
+		Attribute *aIconPixelData=new OtherByteSmallNonPixelAttribute(TagFromName(PixelData));
+		Assert(aIconPixelData);
+		aIconPixelData->setValue(iconPixelData,Uint32(iRows*iColumns));
+		(*iconlist)+=aIconPixelData;
+
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),1);
+		(*iconlist)+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),"MONOCHROME2");
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(Rows),iRows);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(Columns),iColumns);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(BitsAllocated),8);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(BitsStored),8);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(HighBit),7);
+		(*iconlist)+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),0);
+
+		(*aIconImageSequence)+=iconlist;
+		// aIconImageSequence->reviseVL();	// Not yet implemented :(
+	}
+	
+	return aIconImageSequence;
+}
+
+
+static Uint32		// Taken straight from attrmxls.cc
+fixedlength(
+	const TransferSyntax *metats,const TransferSyntax *datats,Attribute *a)
+{
+	// returned the length in bytes of the fixed part of an element
+	// ie. that part other than that returned by a->getVL()
+	// obviously this is dictated by the Value Representation which
+	// in turn depends on the Transfer Syntax
+
+	Assert(a);
+
+	const TransferSyntax *ts = a->getTag().isMetaheaderGroup()
+		? metats
+		: datats;
+
+	Assert(ts);
+
+	Uint32 length=4;	// length of tag itself
+	// work out length of "value length" field
+	if (ts->isImplicitVR())
+		length+=4;
+	else if (ts->isExplicitVR()) {
+		const char *vru=a->getVR();
+		if (vru) {	// Explicit OB,OW,SQ
+			if (vru[0]=='O' && (vru[1]=='B' || vru[1]=='W')
+			 || vru[0]=='S' &&  vru[1]=='Q')
+				length+=6;
+			else
+				length+=2;
+		}
+		else
+			Assert(0);
+		length+=2;	// add length of explicit VR itself
+	}
+	else
+		Assert(0);
+	return length;
+}
+
+static bool
+addLengths(AttributeList &list,const TransferSyntax *metats,const TransferSyntax *datats)		// Derived from attrmxls.cc
+{
+	// Fixup and/or insert group lengths
+
+	// each (nnnn,0000) group length element
+	// contains the length in bytes of the rest of the group
+	// not including the length element itself
+
+	bool metaseen=false;
+	bool dothisgroup=true;
+	Uint16 doinggroup=0;
+	Uint32 length=0;
+	AttributeList lengthlist;
+	AttributeListIterator listi(list);
+	while (1) {
+		Attribute *a;
+		Tag tag;
+		if (!listi) {
+			a=listi();
+			Assert(a);
+			tag=a->getTag();
+		}
+		if (!!listi || tag.getGroup() > doinggroup) {
+			if (length && dothisgroup && doinggroup == 0x0002) {
+				lengthlist+=new UnsignedLongAttribute(Tag(doinggroup,0),length);
+			}
+			if (!!listi)
+				break;
+			else {
+				doinggroup=tag.getGroup();
+				dothisgroup=true;
+				length=0;
+			}
+		}
+		else if (tag.getGroup() == doinggroup) {
+			if (a->getVL() == 0xffffffff)
+				dothisgroup=false;
+			else
+				length+=fixedlength(metats,datats,a)+a->getVL();
+			++listi;
+		}
+		else
+			++listi;
+
+		if (tag.isMetaheaderGroup())
+			metaseen=true;
+		else
+			if (metaseen) break;
+	}
+
+	list+=(lengthlist);
+
+	return true;
+}
+
+class DirectoryRecordWriteOrder {
+	int order;
+public:
+	static const int ParentChildSibling = 1;
+	static const int ParentSiblingChild = 2;
+	static const int SiblingChildParent = 3;
+	static const int SiblingParentChild = 4;
+	static const int ChildSiblingParent = 5;
+	static const int ChildParentSibling = 6;
+
+	DirectoryRecordWriteOrder(int i) { order = i; }
+
+	int getOrder(void) { return order; }
+};
+
+class DirectoryRecordBase {
+protected:
+	DirectoryRecordBase *sibling;
+	DirectoryRecordBase *child;
+
+	AttributeList *list;
+
+	Uint32 selfoffset;
+
+	virtual TextOutputStream& writeSpecific(TextOutputStream &log) = 0;
+	virtual TextOutputStream& indentSpecific(TextOutputStream &log) = 0;
+
+public:
+	DirectoryRecordBase(DirectoryRecordBase *nextsib)
+		{
+			child=0;
+			sibling=nextsib;
+
+			list=new AttributeList();
+			(*list)+=new UnsignedLongAttribute(TagFromName(NextDirectoryRecordOffset),0);
+			(*list)+=new UnsignedShortAttribute(TagFromName(RecordInUseFlag),0xffff);
+			(*list)+=new UnsignedLongAttribute(TagFromName(LowerLevelDirectoryOffset),0);
+
+			selfoffset=0;
+		}
+
+	virtual ~DirectoryRecordBase()
+		{
+			if (child) delete child;
+			if (sibling) delete sibling;
+		}
+
+	void setChild(DirectoryRecordBase *newchild)
+		{
+			child=newchild;
+		}
+
+	TextOutputStream& write(TextOutputStream &log,const TransferSyntax *ts)
+		{
+			writeSpecific(log);
+			indentSpecific(log);
+			log << "Length = " << getLength(ts) << endl;
+			if (list) {
+				AttributeListIterator i(*list);
+				while (!i) {
+					Attribute *a=i();
+					Assert(a);
+					indentSpecific(log);
+					a->write(log,&staticDictionary,false);
+					log << endl;
+					++i;
+				}
+			}
+
+			if (child)     child->write(log,ts);
+			if (sibling) sibling->write(log,ts);
+			return log;
+		}
+
+	Uint32 getLength(const TransferSyntax *ts)	// NOT including leading Item (8) and possible trailing Item Delimitation Item (8)
+		{
+			Uint32 length=0;
+			if (list) {
+				AttributeListIterator i(*list);
+				while (!i) {
+					Attribute *a=i();
+					Assert(a);
+					length+=fixedlength(0,ts,a);
+					if (strcmp(a->getVR(),"SQ") == 0) {
+						SequenceAttribute *as=(SequenceAttribute *)a;
+						AttributeList **alists;
+						int count=as->getLists(&alists);
+						while (count--) {
+							Assert(*alists);
+							length+=8;	// Item
+							AttributeListIterator i(**alists);
+							while (!i) {
+								Attribute *a=i();
+								Assert(a);
+								Assert(strcmp(a->getVR(),"SQ") != 0);	// No nested sequences here :(
+								length+=fixedlength(0,ts,a)+a->getVL();
+								++i;
+							}
+							length+=8;	// Item Delimiter
+							++alists;
+						}
+						length+=8;		// Sequence Delimiter
+					}
+					else
+						length+=a->getVL();	// this is broken for sequences :(
+					++i;
+				}
+			}
+			return length;
+		}
+
+	void linkOffsetChild(void)
+		{
+			Attribute *aLowerLevelDirectoryOffset=(*list)[TagFromName(LowerLevelDirectoryOffset)];
+			Assert(aLowerLevelDirectoryOffset);
+			if (child) {
+				aLowerLevelDirectoryOffset->setValue(0u,(unsigned long)child->getOffset());
+				child->linkOffset();
+			}
+			else {
+				aLowerLevelDirectoryOffset->setValue(0u,(unsigned long)0);
+			}
+		}
+
+	void linkOffsetSibling(void)
+		{
+			Attribute *aNextDirectoryRecordOffset=(*list)[TagFromName(NextDirectoryRecordOffset)];
+			Assert(aNextDirectoryRecordOffset);
+			if (sibling) {
+				aNextDirectoryRecordOffset->setValue(0u,(unsigned long)sibling->getOffset());
+				sibling->linkOffset();
+			}
+			else {
+				aNextDirectoryRecordOffset->setValue(0u,(unsigned long)0);
+			}
+		}
+
+	void linkOffset(void)
+		{
+			linkOffsetChild();
+			linkOffsetSibling();
+		}
+
+	Uint32 setOffsetSelf(const TransferSyntax *ts,Uint32 startoffset,Uint32 &lastoffset)
+		{
+			selfoffset=startoffset;		// save this ... will be needed at top level to locate 1st directory record
+
+			lastoffset=startoffset;
+
+			startoffset+=8;			// Item tag and length
+			startoffset+=getLength(ts);	// Ourself
+			startoffset+=8;			// Item delimiter tag and length
+
+			return startoffset;
+		}
+
+	Uint32 setOffsetChild(const TransferSyntax *ts,Uint32 startoffset,TextOutputStream &log,bool verbose,Uint32 &lastoffset,DirectoryRecordWriteOrder order)
+		{
+			if (child) {
+				startoffset=child->setOffset(ts,startoffset,log,verbose,lastoffset,order);
+			}
+
+			return startoffset;
+		}
+
+	Uint32 setOffsetSibling(const TransferSyntax *ts,Uint32 startoffset,TextOutputStream &log,bool verbose,Uint32 &lastoffset,DirectoryRecordWriteOrder order)
+		{
+			if (sibling) {
+				startoffset=sibling->setOffset(ts,startoffset,log,verbose,lastoffset,order);
+			}
+
+			return startoffset;
+		}
+
+	Uint32 setOffset(const TransferSyntax *ts,Uint32 startoffset,TextOutputStream &log,bool verbose,Uint32 &lastoffset,DirectoryRecordWriteOrder order)
+		{
+			if (verbose) {
+				writeSpecific(log);
+				indentSpecific(log);
+				log << "Start offset = " << startoffset << endl;
+			}
+
+			if (order.getOrder() == DirectoryRecordWriteOrder::ParentChildSibling) {
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ParentSiblingChild) {
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingChildParent) {
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingParentChild) {
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildSiblingParent) {
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildParentSibling) {
+				startoffset=setOffsetChild  (ts,startoffset,log,verbose,lastoffset,order);
+				startoffset=setOffsetSelf   (ts,startoffset,lastoffset);
+				startoffset=setOffsetSibling(ts,startoffset,log,verbose,lastoffset,order);
+			}
+			else {
+				Assert(0);
+			}
+
+			return startoffset;
+		}
+
+	Uint32 getOffset(void) { return selfoffset; }
+
+	void flatten(SequenceAttribute *aDirectoryRecordSequence,DirectoryRecordWriteOrder order)
+		{
+			if (order.getOrder() == DirectoryRecordWriteOrder::ParentChildSibling) {
+				(*aDirectoryRecordSequence)+=list;
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ParentSiblingChild) {
+				(*aDirectoryRecordSequence)+=list;
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingChildParent) {
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::SiblingParentChild) {
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildSiblingParent) {
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+			}
+			else if (order.getOrder() == DirectoryRecordWriteOrder::ChildParentSibling) {
+				if (child)     child->flatten(aDirectoryRecordSequence,order);
+				(*aDirectoryRecordSequence)+=list;
+				if (sibling) sibling->flatten(aDirectoryRecordSequence,order);
+			}
+			else {
+				Assert(0);
+			}
+		}
+};
+
+class InstanceDirectoryRecord : public DirectoryRecordBase {
+	const char *sopInstanceUID;
+	const char *sopClassUID;
+	const char *instanceNumber;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			log << "\t\t\t";
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Instance "
+			    << (sopInstanceUID ? sopInstanceUID : "") << " "
+			    << (instanceNumber ? instanceNumber : "") 
+			    << endl;
+			return log;
+		}
+public:
+	InstanceDirectoryRecord(const char *uid,AttributeList *srclist,InstanceDirectoryRecord *nextsib,
+			const char *filename,const char *inputTransferSyntaxUID,
+			const TransferSyntax *outputTransferSyntax,
+			bool doicon,bool doposition,bool validatefilenamevr,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib)
+		{
+			sopInstanceUID=uid;
+			Assert(sopInstanceUID);
+			(*list)+=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUIDInFile),sopInstanceUID);
+
+			sopClassUID=getStringValueElseError((*srclist),TagFromName(SOPClassUID),"SOP Class UID",filename,log);
+			Assert(sopClassUID);
+			(*list)+=new UIStringAttribute(TagFromName(ReferencedSOPClassUIDInFile),sopClassUID);
+
+			Assert(inputTransferSyntaxUID);
+			(*list)+=new UIStringAttribute(TagFromName(ReferencedTransferSyntaxUIDInFile),inputTransferSyntaxUID);
+
+			const char *directoryRecordType = getDirectoryRecordTypeFromUID(sopClassUID);
+			if (!directoryRecordType) directoryRecordType="IMAGE";	// Assume image if unrecognzied SOP Class
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),directoryRecordType);
+
+			{
+				Assert(filename);
+				Attribute *a=new CodeStringFileComponentAttribute(TagFromName(ReferencedFileID),filename);
+				(*list)+=a;
+				Assert(a);
+				if (validatefilenamevr) a->validateVR(log,&staticDictionary);
+			}
+
+			if (strcmp(directoryRecordType,"IMAGE") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				if (doicon) {
+					Attribute *aIconImageSequence = makeIconImageSequence(srclist,outputTransferSyntax);
+					if (aIconImageSequence) (*list)+=aIconImageSequence;
+				}
+
+                                // The following are not required in the IOD, but some profiles ...
+
+                                // ImageType (XABC-CD,XA1K-CD:1)
+
+			        Attribute *imageType=getCopyOfImageTypeAttributeElseNull((*srclist),TagFromName(ImageType));
+			        if (imageType) (*list)+=imageType;
+
+                                // CalibrationImage (XABC-CD,XA1K-CD:2)
+
+				const char *calibrationImage=getStringValueElseZeroLength((*srclist),TagFromName(CalibrationImage));
+				Assert(calibrationImage);
+				(*list)+=new CodeStringAttribute(TagFromName(CalibrationImage),calibrationImage);
+
+                                // ReferencedImageSequence (XABC-CD,XA1K-CD:1C if ImageType value 3 is BIPLANE A or B)
+                                // ReferencedImageSequence (CTMR:1C if present in image)
+
+			        Attribute *referencedImageSequence=getCopyOfReferencedImageSequenceAttributeElseNull((*srclist),TagFromName(ReferencedImageSequence),"Referenced Image Sequence",filename,log);
+			        if (referencedImageSequence) (*list)+=referencedImageSequence;
+
+                                // The Image Plane Module attributes are all (CTMR:1C if present in image)
+                                // (Rows and COlumns are actually 1 since always present)
+				if (doposition) {
+					// Do it safely safe in the absence of reference counting ...
+
+					Attribute *a;
+					a=(*srclist)[TagFromName(ReferencedImageSequence)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(ImagePositionPatient)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(ImageOrientationPatient)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(FrameOfReferenceUID)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(TableHeight)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(Rows)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(Columns)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+
+					a=(*srclist)[TagFromName(PixelSpacing)];
+					if (a) { (*srclist)-=a; (*list)+=a; }
+				}
+			}
+			else if (strcmp(directoryRecordType,"SR DOCUMENT") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *completionFlag=getStringValueElseError((*srclist),TagFromName(CompletionFlag),"Completion Flag",filename,log);
+				Assert(completionFlag);
+				(*list)+=new CodeStringAttribute(TagFromName(CompletionFlag),completionFlag);
+
+				const char *verificationFlag=getStringValueElseError((*srclist),TagFromName(VerificationFlag),"Verification Flag",filename,log);
+				Assert(verificationFlag);
+				(*list)+=new CodeStringAttribute(TagFromName(VerificationFlag),verificationFlag);
+
+				if (strcmp(verificationFlag,"VERIFIED") == 0) {
+					const char *verificationDateTime=getStringValueElseError((*srclist),TagFromName(VerificationDateTime),"Verification DateTime",filename,log);
+					Assert(verificationDateTime);
+					(*list)+=new DateTimeStringAttribute(TagFromName(VerificationDateTime),verificationDateTime);
+				}
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+
+				Attribute *conceptNameCodeSequence=getCopyOfCodeSequenceAttributeElseError((*srclist),TagFromName(ConceptNameCodeSequence),"Concept Name Code Sequence",filename,log);
+				Assert(conceptNameCodeSequence);
+				(*list)+=conceptNameCodeSequence;
+
+				// Should do Content Sequence with extracted modifiers but this is hard :(
+			}
+			else if (strcmp(directoryRecordType,"PRESENTATION") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *presentationLabel=getStringValueElseError((*srclist),TagFromName(PresentationLabel),"Presentation Label",filename,log);
+				Assert(presentationLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(PresentationLabel),presentationLabel);
+
+				const char *presentationDescription=getStringValueElseZeroLength((*srclist),TagFromName(PresentationDescription));
+				Assert(presentationDescription);
+				(*list)+=new LongStringAttribute(TagFromName(PresentationDescription),presentationDescription);
+
+				const char *presentationCreationDate=getStringValueElseError((*srclist),TagFromName(PresentationCreationDate),"Presentation Creation Date",filename,log);
+				Assert(presentationCreationDate);
+				(*list)+=new DateStringAttribute(TagFromName(PresentationCreationDate),presentationCreationDate);
+
+				const char *presentationCreationTime=getStringValueElseError((*srclist),TagFromName(PresentationCreationTime),"Presentation Creation Time",filename,log);
+				Assert(presentationCreationTime);
+				(*list)+=new TimeStringAttribute(TagFromName(PresentationCreationTime),presentationCreationTime);
+
+				const char *presentationCreatorsName=getStringValueElseZeroLength((*srclist),TagFromName(PresentationCreatorsName));
+				Assert(presentationCreatorsName);
+				(*list)+=new LongStringAttribute(TagFromName(PresentationCreatorsName),presentationCreatorsName);
+
+				Attribute *referencedSeriesSequence=getCopyOfReferencedSeriesSequenceAttributeElseError((*srclist),TagFromName(ReferencedSeriesSequence),"Referenced Series Sequence",filename,log);
+				Assert(referencedSeriesSequence);
+				(*list)+=referencedSeriesSequence;
+			}
+			else if (strcmp(directoryRecordType,"WAVEFORM") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *contentDate=getStringValueElseError((*srclist),TagFromName(ContentDate),"Content Date",filename,log);
+				Assert(contentDate);
+				(*list)+=new DateStringAttribute(TagFromName(ContentDate),contentDate);
+
+				const char *contentTime=getStringValueElseError((*srclist),TagFromName(ContentTime),"Content Time",filename,log);
+				Assert(contentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(ContentTime),contentTime);
+                        }
+			else if (strcmp(directoryRecordType,"OVERLAY") == 0) {
+				const char *overlayNumber=getStringValueElseError((*srclist),TagFromName(OverlayNumber),"Overlay Number",filename,log);
+				Assert(overlayNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(OverlayNumber),overlayNumber);
+                        }
+			else if (strcmp(directoryRecordType,"MODALITY LUT") == 0 || strcmp(directoryRecordType,"MODALITY LUT") == 0) {
+				const char *lutNumber=getStringValueElseError((*srclist),TagFromName(LUTNumber),"LUT Number",filename,log);
+				Assert(lutNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(LUTNumber),lutNumber);
+                        }
+			else if (strcmp(directoryRecordType,"CURVE") == 0) {
+				const char *curveNumber=getStringValueElseError((*srclist),TagFromName(CurveNumber),"Curve Number",filename,log);
+				Assert(curveNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(CurveNumber),curveNumber);
+                        }
+			else if (strcmp(directoryRecordType,"STORED PRINT") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+                        }
+			else if (strcmp(directoryRecordType,"RT DOSE") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *doseSummationType=getStringValueElseError((*srclist),TagFromName(DoseSummationType),"Dose Summation Type",filename,log);
+				Assert(doseSummationType);
+				(*list)+=new CodeStringAttribute(TagFromName(DoseSummationType),doseSummationType);
+
+                                const char *doseComment=getStringValueElseNull((*srclist),TagFromName(DoseComment));
+                                if (doseComment) (*list)+=new LongStringAttribute(TagFromName(DoseComment),doseComment);
+			}
+			else if (strcmp(directoryRecordType,"RT STRUCTURE SET") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *structureSetLabel=getStringValueElseError((*srclist),TagFromName(StructureSetLabel),"Structure Set Label",filename,log);
+				Assert(structureSetLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(StructureSetLabel),structureSetLabel);
+
+				const char *structureSetDate=getStringValueElseZeroLength((*srclist),TagFromName(StructureSetDate));
+				Assert(structureSetDate);
+				(*list)+=new DateStringAttribute(TagFromName(StructureSetDate),structureSetDate);
+
+				const char *structureSetTime=getStringValueElseZeroLength((*srclist),TagFromName(StructureSetTime));
+				Assert(structureSetTime);
+				(*list)+=new TimeStringAttribute(TagFromName(StructureSetTime),structureSetTime);
+			}
+			else if (strcmp(directoryRecordType,"RT PLAN") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *rtPlanLabel=getStringValueElseError((*srclist),TagFromName(RTPlanLabel),"RT Plan Label",filename,log);
+				Assert(rtPlanLabel);
+				(*list)+=new CodeStringAttribute(TagFromName(RTPlanLabel),rtPlanLabel);
+
+				const char *rtPlanDate=getStringValueElseZeroLength((*srclist),TagFromName(RTPlanDate));
+				Assert(rtPlanDate);
+				(*list)+=new DateStringAttribute(TagFromName(RTPlanDate),rtPlanDate);
+
+				const char *rtPlanTime=getStringValueElseZeroLength((*srclist),TagFromName(RTPlanTime));
+				Assert(rtPlanTime);
+				(*list)+=new TimeStringAttribute(TagFromName(RTPlanTime),rtPlanTime);
+			}
+			else if (strcmp(directoryRecordType,"RT TREAT RECORD") == 0) {
+				instanceNumber=getStringValueElseError((*srclist),TagFromName(InstanceNumber),"Instance Number",filename,log);
+				Assert(instanceNumber);
+				(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),instanceNumber);
+
+				const char *treatmentDate=getStringValueElseZeroLength((*srclist),TagFromName(TreatmentDate));
+				Assert(treatmentDate);
+				(*list)+=new DateStringAttribute(TagFromName(TreatmentDate),treatmentDate);
+
+				const char *treatmentTime=getStringValueElseZeroLength((*srclist),TagFromName(TreatmentTime));
+				Assert(treatmentTime);
+				(*list)+=new TimeStringAttribute(TagFromName(TreatmentTime),treatmentTime);
+			}
+		}
+
+	~InstanceDirectoryRecord()
+		{
+			if (sopInstanceUID) delete[] sopInstanceUID;
+			if (instanceNumber)    delete[] instanceNumber;
+		}
+
+	InstanceDirectoryRecord *getSibling()	{ return (InstanceDirectoryRecord *)sibling; }
+
+	const char *getSOPInstanceUID()		{ return sopInstanceUID; }
+	const char *getInstanceNumber()		{ return instanceNumber; }
+
+	bool matches(const char *uid)
+		{
+			Assert(uid);
+			Assert(sopInstanceUID);
+			return strcmp(uid,sopInstanceUID) == 0 ? true : false;
+		}
+};
+
+class SeriesDirectoryRecord : public DirectoryRecordBase {
+	const char *seriesInstanceUID;
+	const char *seriesNumber;
+	const char *modality;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			log << "\t\t";
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Series "
+			    << (seriesInstanceUID ? seriesInstanceUID : "") << " "
+			    << (seriesNumber ? seriesNumber : "") 
+			    << endl;
+			return log;
+		}
+public:
+	SeriesDirectoryRecord(const char *uid,AttributeList *srclist,SeriesDirectoryRecord *nextsib,const char *filename,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib)
+		{
+			// the following are Type 1 in directory record ...
+
+			seriesInstanceUID=uid;
+			Assert(seriesInstanceUID);
+			(*list)+=new UIStringAttribute(TagFromName(SeriesInstanceUID),seriesInstanceUID);
+
+			seriesNumber=getStringValueElseError((*srclist),TagFromName(SeriesNumber),"Series Number",filename,log);
+			Assert(seriesNumber);
+			(*list)+=new IntegerStringAttribute(TagFromName(SeriesNumber),seriesNumber);
+
+			modality=getStringValueElseError((*srclist),TagFromName(Modality),"Modality",filename,log);
+			Assert(modality);
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),modality);
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),"SERIES");
+
+                        // The following are not required in the IOD, but some profiles ...
+
+                        // InstitutionName (XABC-CD,XA1K-CD:2)
+
+			const char *institutionName=getStringValueElseZeroLength((*srclist),TagFromName(InstitutionName));
+			Assert(institutionName);
+			(*list)+=new LongStringAttribute(TagFromName(InstitutionName),institutionName);
+
+                        // InstitutionAddress (XABC-CD,XA1K-CD:2)
+
+			const char *institutionAddress=getStringValueElseZeroLength((*srclist),TagFromName(InstitutionAddress));
+			Assert(institutionAddress);
+			(*list)+=new ShortTextAttribute(TagFromName(InstitutionAddress),institutionAddress);
+
+                        // PerformingPhysicianName (XABC-CD,XA1K-CD:2)
+                        // should really check for and copy multiple values :(
+
+			const char *performingPhysicianName=getStringValueElseZeroLength((*srclist),TagFromName(PerformingPhysicianName));
+			Assert(performingPhysicianName);
+			(*list)+=new PersonNameAttribute(TagFromName(PerformingPhysicianName),performingPhysicianName);
+		}
+
+	~SeriesDirectoryRecord()
+		{
+			if (seriesInstanceUID) delete[] seriesInstanceUID;
+			if (seriesNumber)      delete[] seriesNumber;
+			if (modality)          delete[] modality;
+		}
+
+	SeriesDirectoryRecord *getSibling()	{ return (SeriesDirectoryRecord *)sibling; }
+	InstanceDirectoryRecord   *getChild()	{ return (InstanceDirectoryRecord *)child; }
+
+	const char *getSeriesInstanceUID()	{ return seriesInstanceUID; }
+	const char *getSeriesNumber()		{ return seriesNumber; }
+
+	bool matches(const char *uid)
+		{
+			Assert(uid);
+			Assert(seriesInstanceUID);
+			return strcmp(uid,seriesInstanceUID) == 0 ? true : false;
+		}
+
+	bool checkMatch(AttributeList *srclist,const char *filename,TextOutputStream &log,bool verbose)
+		{
+			Assert(seriesInstanceUID);
+			Assert(seriesNumber);
+			Assert(modality);
+
+			if (verbose) log << filename << " matches "
+					     << seriesInstanceUID
+					     << " "
+					     << seriesNumber
+					     << endl;
+
+			(void)errorIfStringValuesDontMatch(seriesNumber,*srclist,
+				TagFromName(SeriesNumber),"Series Number",
+				"Series Instance UID",seriesInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(modality,*srclist,
+				TagFromName(Modality),"Modality",
+				"Series Instance UID",seriesInstanceUID,filename,log);
+		}
+};
+
+class StudyDirectoryRecord : public DirectoryRecordBase {
+	const char *studyInstanceUID;
+	const char *studyID;
+	const char *studyDate;
+	const char *studyTime;
+	const char *studyDescription;
+	const char *accessionNumber;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			log << "\t";
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Study "
+			    << (studyInstanceUID ? studyInstanceUID : "") << " "
+			    << (studyID ? studyID : "") 
+			    << endl;
+			return log;
+		}
+public:
+	StudyDirectoryRecord(const char *uid,AttributeList *srclist,StudyDirectoryRecord *nextsib,const char *filename,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib)
+		{
+			// the following are Type 1 in directory record ...
+
+			studyID=getStringValueElseError((*srclist),TagFromName(StudyID),"Study ID",filename,log);
+			Assert(studyID);
+			(*list)+=new ShortStringAttribute(TagFromName(StudyID),studyID);
+
+			studyInstanceUID=uid;
+			Assert(studyInstanceUID);
+			(*list)+=new UIStringAttribute(TagFromName(StudyInstanceUID),studyInstanceUID);
+
+			Attribute *a;
+
+			studyDate=getStringValueElseError((*srclist),TagFromName(StudyDate),"Study Date",filename,log);
+			Assert(studyDate);
+			(*list)+=new DateStringAttribute(TagFromName(StudyDate),studyDate);
+
+			studyTime=getStringValueElseError((*srclist),TagFromName(StudyTime),"Study Time",filename,log);
+			Assert(studyTime);
+			(*list)+=new TimeStringAttribute(TagFromName(StudyTime),studyTime);
+
+			// the following are Type 2 in directory record ...
+
+			studyDescription=AttributeValue((*srclist)[TagFromName(StudyDescription)],"");
+			Assert(studyDescription);
+			(*list)+=new LongStringAttribute(TagFromName(StudyDescription),studyDescription);
+
+			accessionNumber=AttributeValue((*srclist)[TagFromName(AccessionNumber)],"");
+			Assert(accessionNumber);
+			(*list)+=new ShortStringAttribute(TagFromName(AccessionNumber),accessionNumber);
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),"STUDY");
+		}
+
+	~StudyDirectoryRecord()
+		{
+			if (studyInstanceUID) delete[] studyInstanceUID;
+			if (studyID)          delete[] studyID;
+			if (studyDate)        delete[] studyDate;
+			if (studyTime)        delete[] studyTime;
+			if (studyDescription) delete[] studyDescription;
+			if (accessionNumber)  delete[] accessionNumber;
+		}
+
+	StudyDirectoryRecord *getSibling()	{ return (StudyDirectoryRecord *)sibling; }
+	SeriesDirectoryRecord   *getChild()	{ return (SeriesDirectoryRecord *)child; }
+
+	const char *getStudyInstanceUID()	{ return studyInstanceUID; }
+	const char *getStudyID()		{ return studyID; }
+
+	bool matches(const char *uid)
+		{
+			Assert(uid);
+			Assert(studyInstanceUID);
+			return strcmp(uid,studyInstanceUID) == 0 ? true : false;
+		}
+
+	bool checkMatch(AttributeList *srclist,const char *filename,TextOutputStream &log,bool verbose)
+		{
+			Assert(studyInstanceUID);
+			Assert(studyID);
+			Assert(studyDate);
+			Assert(studyTime);
+			Assert(studyDescription);
+			Assert(accessionNumber);
+
+			if (verbose) log << filename << " matches "
+					     << studyInstanceUID
+					     << " "
+					     << studyID
+					     << endl;
+
+			(void)errorIfStringValuesDontMatch(studyID,*srclist,
+				TagFromName(StudyID),"Study ID",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(studyDate,*srclist,
+				TagFromName(StudyDate),"Study Date",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(studyTime,*srclist,
+				TagFromName(StudyTime),"Study Time",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(studyDescription,*srclist,
+				TagFromName(StudyDescription),"Study Description",
+				"Study Instance UID",studyInstanceUID,filename,log);
+
+			(void)errorIfStringValuesDontMatch(accessionNumber,*srclist,
+				TagFromName(AccessionNumber),"Accession Number",
+				"Study Instance UID",studyInstanceUID,filename,log);
+		}
+};
+
+class PatientDirectoryRecord : public DirectoryRecordBase {
+	const char *patientID;
+	const char *patientName;
+
+	TextOutputStream& indentSpecific(TextOutputStream &log)
+		{
+			return log;
+		}
+
+	TextOutputStream& writeSpecific(TextOutputStream &log)
+		{
+			indentSpecific(log);
+			log << "Patient "
+			    << (patientID ? patientID : "") << " "
+			    << (patientName ? patientName : "") 
+			    << endl;
+			return log;
+		}
+public:
+	PatientDirectoryRecord(const char *id,AttributeList *srclist,PatientDirectoryRecord *nextsib,const char *filename,TextOutputStream &log)
+		: DirectoryRecordBase(nextsib)
+		{
+			patientID=id;
+			Assert(patientID);
+			(*list)+=new LongStringAttribute(TagFromName(PatientID),patientID);
+
+			patientName=AttributeValue((*srclist)[TagFromName(PatientName)],"");
+			Assert(patientName);
+			(*list)+=new PersonNameAttribute(TagFromName(PatientName),patientName);
+
+			(*list)+=new CodeStringAttribute(TagFromName(DirectoryRecordType),"PATIENT");
+
+                        // The following are not required in the IOD, but some profiles ...
+
+                        // PatientBirthDate (XABC-CD,XA1K-CD:2)
+
+			const char *patientBirthDate=getStringValueElseZeroLength((*srclist),TagFromName(PatientBirthDate));
+			Assert(patientBirthDate);
+			(*list)+=new DateStringAttribute(TagFromName(PatientBirthDate),patientBirthDate);
+
+                        // PatientSex (XABC-CD,XA1K-CD:2)
+
+			const char *patientSex=getStringValueElseZeroLength((*srclist),TagFromName(PatientSex));
+			Assert(patientSex);
+			(*list)+=new CodeStringAttribute(TagFromName(PatientSex),patientSex);
+		}
+
+	~PatientDirectoryRecord()
+		{
+			if (patientID)   delete[] patientID;
+			if (patientName) delete[] patientName;
+		}
+
+	PatientDirectoryRecord *getSibling()	{ return (PatientDirectoryRecord *)sibling; }
+	StudyDirectoryRecord   *getChild()	{ return (StudyDirectoryRecord *)child; }
+
+	const char *getPatientID()	{ return patientID; }
+	const char *getPatientName()	{ return patientName; }
+
+	bool matches(const char *id)
+		{
+			Assert(id);
+			Assert(patientID);
+			return strcmp(id,patientID) == 0 ? true : false;
+		}
+
+	bool checkMatch(AttributeList *srclist,const char *filename,TextOutputStream &log,bool verbose)
+		{
+			Assert(patientID);
+			Assert(patientName);
+
+			(void)errorIfStringValuesDontMatch(patientName,*srclist,
+				TagFromName(PatientName),"Patient Name",
+				"Patient ID",patientID,filename,log);
+
+			if (verbose) log << filename << " matches "
+					     << patientID
+					     << " "
+					     << patientName
+					     << endl;
+		}
+};
+
+// Derived from attrmxls.cc ...
+
+static bool
+addMetaHeader(AttributeList &list,const TransferSyntax *ts,const char *uidstamp)
+{
+//cerr << "addMetaHeader" << endl;
+	Attribute *a;
+
+	{
+		Assert(ts);
+		const char *tsuid=ts->getUID();
+		Assert(tsuid);
+		a=new UIStringAttribute(TagFromName(TransferSyntaxUID),tsuid);
+		Assert(a);
+		list+=(a);
+	}
+
+	{
+		a=new OtherByteSmallNonPixelAttribute(TagFromName(FileMetaInformationVersion));
+		Assert(a);
+		unsigned char values[2];
+		values[0]=0x00;
+		values[1]=0x01;
+		a->setValue(values,2);
+		list+=(a);
+	}
+
+	{
+		a=new UIStringAttribute(TagFromName(MediaStorageSOPClassUID),MediaStorageDirectoryStorageSOPClassUID);
+		Assert(a);
+		list+=(a);
+	}
+
+	{
+		a=new UIStringAttribute(TagFromName(MediaStorageSOPInstanceUID),GeneratedDirInstanceUID(uidstamp));
+		Assert(a);
+		list+=(a);
+	}
+
+#ifndef DEFAULTIMPLEMENTATIONCLASSUID
+#define DEFAULTIMPLEMENTATIONCLASSUID "0.0.0.0"
+#endif
+	{
+		a=new UIStringAttribute(TagFromName(ImplementationClassUID));
+		Assert(a);
+		a->addValue(DEFAULTIMPLEMENTATIONCLASSUID);
+		list+=(a);
+	}
+
+#ifndef DEFAULTIMPLEMENTATIONVERSIONNAME
+#define DEFAULTIMPLEMENTATIONVERSIONNAME "NOTSPECIFIED"
+#endif
+	{
+		a=new ShortStringAttribute(TagFromName(ImplementationVersionName));
+		Assert(a);
+		a->addValue(DEFAULTIMPLEMENTATIONVERSIONNAME);
+		list+=(a);
+	}
+
+#ifndef DEFAULTSOURCEAPPLICATIONENTITYTITLE
+#define DEFAULTSOURCEAPPLICATIONENTITYTITLE "NOTSPECIFIED"
+#endif
+	{
+		a=new ApplicationEntityAttribute(TagFromName(SourceApplicationEntityTitle));
+		Assert(a);
+		a->addValue(DEFAULTSOURCEAPPLICATIONENTITYTITLE);
+		list+=(a);
+	}
+
+	return true;
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool veryveryverbose=options.get("veryveryverbose") || options.get("vvv");
+	if (veryveryverbose) veryverbose=true;
+	if (veryverbose) verbose=true;
+	bool listnames=options.get("l");
+
+	const char *descriptor=0;
+	(void)(options.get("descriptor",descriptor) || options.get("readme",descriptor));
+
+	bool doicon=!options.get("noicons");
+	bool doposition=options.get("position");
+	bool dovalidatename=!options.get("novalidatename");
+
+	DirectoryRecordWriteOrder order(DirectoryRecordWriteOrder::ParentChildSibling);
+	{
+		const char *order_arg=0;
+		if (options.get("dirrecorder",order_arg)) {
+			if (!order_arg || !*order_arg) bad=true;
+			else if (strcmp(order_arg,"pcs") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ParentChildSibling);
+			else if (strcmp(order_arg,"psc") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ParentSiblingChild);
+			else if (strcmp(order_arg,"scp") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::SiblingChildParent);
+			else if (strcmp(order_arg,"spc") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::SiblingParentChild);
+			else if (strcmp(order_arg,"csp") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ChildSiblingParent);
+			else if (strcmp(order_arg,"cps") == 0) order=DirectoryRecordWriteOrder(DirectoryRecordWriteOrder::ChildParentSibling);
+			else bad=true;
+		}
+	}
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	int numberofinputfiles=!options;
+	const char **listoffilenames = new const char * [numberofinputfiles];
+	const char **ptr = listoffilenames;
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		*ptr++=filename;
+	}
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose|-vvv|-veryveryverbose]"
+			<< " [-descriptor|-readme filename]"
+			<< " [-noicons]"
+			<< " [-position]"
+			<< " [-novalidatename]"
+			<< " [-dirrecorder pcs|psc|scp|spc|csp|cps]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	PatientDirectoryRecord *headPatient=0;
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		const char *filename=listoffilenames[i];
+		Assert(filename);
+		if (listnames) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			success=false;
+			break;
+		}
+
+		DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+
+		if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+		list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			break;
+		}
+
+		const char *patientID=getStringValueElseError(list,TagFromName(PatientID),"Patient ID",filename,log);
+		Assert(patientID);
+
+		PatientDirectoryRecord *ptrPatient=headPatient;
+		while (ptrPatient && !ptrPatient->matches(patientID)) ptrPatient=ptrPatient->getSibling();
+
+		StudyDirectoryRecord *headStudy,*ptrStudy;
+		if (ptrPatient) {
+			ptrPatient->checkMatch(&list,filename,log,veryverbose);
+
+			ptrStudy=headStudy=ptrPatient->getChild();
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << patientID << endl;
+
+			ptrPatient=headPatient=new PatientDirectoryRecord(patientID,&list,headPatient,filename,log);
+			ptrStudy=headStudy=0;
+		}
+
+		const char *studyInstanceUID=getStringValueElseError(list,TagFromName(StudyInstanceUID),"Study Instance UID",filename,log);
+		Assert(studyInstanceUID);
+
+		while (ptrStudy && !ptrStudy->matches(studyInstanceUID)) ptrStudy=ptrStudy->getSibling();
+
+		SeriesDirectoryRecord *headSeries,*ptrSeries;
+		if (ptrStudy) {
+			ptrStudy->checkMatch(&list,filename,log,veryverbose);
+
+			ptrSeries=headSeries=ptrStudy->getChild();
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << studyInstanceUID << endl;
+
+			ptrStudy=headStudy=new StudyDirectoryRecord(studyInstanceUID,&list,headStudy,filename,log);
+			Assert(ptrPatient);
+			ptrPatient->setChild(headStudy);
+			ptrSeries=headSeries=0;
+		}
+
+		const char *seriesInstanceUID=getStringValueElseError(list,TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+		Assert(seriesInstanceUID);
+
+		while (ptrSeries && !ptrSeries->matches(seriesInstanceUID)) ptrSeries=ptrSeries->getSibling();
+
+		InstanceDirectoryRecord *headInstance,*ptrInstance;
+		if (ptrSeries) {
+			ptrSeries->checkMatch(&list,filename,log,veryverbose);
+
+			ptrInstance=headInstance=ptrSeries->getChild();
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << seriesInstanceUID << endl;
+
+			ptrSeries=headSeries=new SeriesDirectoryRecord(seriesInstanceUID,&list,headSeries,filename,log);
+			Assert(ptrStudy);
+			ptrStudy->setChild(headSeries);
+			ptrInstance=headInstance=0;
+		}
+
+		const char *sopInstanceUID=getStringValueElseError(list,TagFromName(SOPInstanceUID),"SOP Instance UID",filename,log);
+		Assert(sopInstanceUID);
+
+		while (ptrInstance && !ptrInstance->matches(sopInstanceUID)) ptrInstance=ptrInstance->getSibling();
+
+		if (ptrInstance) {
+			log << "Error - duplicate SOP instance within Series for file " << filename << " matches "
+			    << ptrInstance-> getSOPInstanceUID()
+			    << " Instance Number "
+			    << (ptrInstance-> getInstanceNumber() ? ptrInstance-> getInstanceNumber() : "")
+			    << endl;
+
+			break; // because of error
+		}
+		else {
+			if (veryverbose) log << filename << " no match for " << sopInstanceUID << endl;
+
+			TransferSyntax outts(dicom_output_options.transfersyntaxuid);	// SGI CC doesn't like this inline :(
+			ptrInstance=headInstance=new InstanceDirectoryRecord(sopInstanceUID,&list,headInstance,
+				filename,
+				din.getTransferSyntaxToReadDataSet()->getUID(),
+				&outts,
+				doicon,doposition,dovalidatename,log);
+			Assert(ptrSeries);
+			ptrSeries->setChild(headInstance);
+		}
+
+		if (fstr) delete fstr;
+	}
+
+	if (veryverbose && headPatient) {
+		TransferSyntax outts(dicom_output_options.transfersyntaxuid);	// SGI CC doesn't like this inline :(
+		headPatient->write(log,&outts);
+	}
+
+	if (numberofinputfiles && listoffilenames) delete[] listoffilenames;
+
+	if (success) {
+		AttributeList list;
+
+		DicomOutputStream dout(*(ostream *)output_opener,
+			dicom_output_options.transfersyntaxuid,
+			dicom_output_options.usemetaheader,
+			dicom_output_options.useimplicitmetaheader,
+			dicom_output_options.addtiff);
+
+		if (dicom_output_options.usemetaheader) {
+			addMetaHeader(list,dout.getTransferSyntaxToWriteDataSet(),dicom_output_options.stamp);
+			(void)addLengths(list,dout.getTransferSyntaxToWriteMetaHeader(),dout.getTransferSyntaxToWriteDataSet());
+		}
+
+		list+=new CodeStringAttribute(TagFromName(FileSetID));
+
+		if (descriptor)
+			list+=new CodeStringFileComponentAttribute(TagFromName(FileSetDescriptorFileID),descriptor);
+
+		list+=new UnsignedShortAttribute(TagFromName(FileSetConsistencyFlag),0x0000);
+
+		Uint32 predictedOffset=0;
+
+		if (dicom_output_options.usemetaheader)
+			predictedOffset+=132;	// preamble
+
+		AttributeListIterator listi(list);
+		while (!listi) {
+			Attribute *a = listi();
+			Assert(a);
+			if (veryverbose) { a->write(log,&staticDictionary); log << endl; }
+			predictedOffset+=fixedlength(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),a)
+						+a->getVL();
+			++listi;
+		}
+
+		if (veryverbose) log << "Predicted Offset before Root Directory Entity First Directory Record attribute = " << dec << predictedOffset << endl;
+
+		Attribute *aRootDirectoryFirstRecord=new UnsignedLongAttribute(TagFromName(RootDirectoryFirstRecord),0);
+
+		predictedOffset+=fixedlength(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),aRootDirectoryFirstRecord)
+						+aRootDirectoryFirstRecord->getVL();
+
+		Attribute *aRootDirectoryLastRecord=new UnsignedLongAttribute(TagFromName(RootDirectoryLastRecord),0);
+
+		predictedOffset+=fixedlength(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),aRootDirectoryLastRecord)
+						+aRootDirectoryLastRecord->getVL();
+
+		if (veryverbose) log << "Predicted Offset before Directory Record Sequence = " << dec << predictedOffset << endl;
+
+		SequenceAttribute *aDirectoryRecordSequence=new SequenceAttribute(TagFromName(DirectoryRecordSequence));
+
+		predictedOffset+=fixedlength(
+					dout.getTransferSyntaxToWriteMetaHeader(),
+					dout.getTransferSyntaxToWriteDataSet(),aDirectoryRecordSequence);
+
+		if (veryverbose) log << "Predicted Offset before first item = " << dec << predictedOffset << endl;
+
+		if (headPatient) {
+			Uint32 lastoffset;
+
+			(void)headPatient->setOffset(
+					dout.getTransferSyntaxToWriteDataSet(),predictedOffset,log,veryverbose,lastoffset,order);
+
+			headPatient->linkOffset();
+
+			if (veryverbose) {
+				TransferSyntax outts(dicom_output_options.transfersyntaxuid);	// SGI CC doesn't like this inline :(
+				headPatient->write(log,&outts);
+			}
+
+			aRootDirectoryFirstRecord->setValue(0u,headPatient->getOffset());
+			list+=aRootDirectoryFirstRecord;
+
+			aRootDirectoryLastRecord->setValue(0u,lastoffset);
+			list+=aRootDirectoryLastRecord;
+
+			headPatient->flatten(aDirectoryRecordSequence,order);
+			list+=aDirectoryRecordSequence;
+		}
+
+		listi.first();
+		while (!listi) {
+			Attribute *a = listi();
+			Assert(a);
+			if (a->getTag().isMetaheaderGroup())
+				dout.writingMetaHeader();
+			else
+				dout.writingDataSet();
+			a->write(dout);
+			if (verbose) { a->write(log,&staticDictionary); log << endl; }
+			++listi;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcdirmk.man b/appsrc/dcfile/dcdirmk.man
new file mode 100755
index 0000000..461f193
--- /dev/null
+++ b/appsrc/dcfile/dcdirmk.man
@@ -0,0 +1,205 @@
+.TH DCDIRMK 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Create DICOMDIR"
+.SH NAME
+dcdirmk \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create DICOMDIR
+.SH SYNOPSIS
+.HP 10
+.B dcdirmk
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+[
+.B \-v|verbose|vv|veryverbose
+]
+[
+.B \-l
+]
+[
+.B \-noicons
+]
+[
+.B \-position
+]
+[
+.B \-novalidatename
+]
+[
+.B \-noinstancechildoffset
+]
+[
+.B \-descriptor|-readme " filename"
+]
+[
+.B \-identifier|-id " filesetid"
+]
+[
+.B \-dirrecorder " pcs|psc|scp|spc|csp|cps"
+]
+[
+.B \-input-nometa
+]
+[
+.B \-input-ts " uid"
+]
+[
+.B \-input-default
+]
+[
+.B \-input-byteorder|-input-endian " big|little"
+]
+[
+.B \-input-vr " implicit|explicit"
+]
+[
+.B \-f|-filelist " filename"
+]
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcdirmk
+reads the named dicom input files (and/or the files listed in the specified
+file), extracts patient, study, series and image
+information, and creates a DICOMDIR file as output.
+.LP
+Note that it is the user's responsibility to ensure that the filenames of
+the input files, which will be written to the output DICOMDIR, comply
+with the limitations specified in PS 3.10, specifically all upper case
+or numbers or underscore, 8 characters per component, and no more than
+8 components.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The output encoding of the file be the default for the DICOMDIR but can
+be overridden, though this is very unlikely to be useful.
+.LP
+Icon images are derived from the image pixel data.
+.LP
+Since some attributes are mandatory in the directory records that may be
+zero-length in image objects, a meagre effort is made to fill them with
+defaults. Specifically, 19000101 will be used for the Study Date if missing, 000000
+will be used for the Study Time if missing, the Study Date (or 19000101) will
+be used for the Study ID if missing, the value 0 will be used for Series Number if missing, the
+value NOPATIENTID will be used for Patient ID if missing and the value Nobody^ will be used for
+Patient Name if missing.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-v|verbose
+.RS
+Display all attributes in each directory record, once the directory is built.
+.RE
+.TP
+.B \-vv|veryverbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read, and various intermediate data structures,
+and calculations as the directory is built.
+.RE
+.TP
+.B \-l
+.RS
+List filenames as they are read.
+.RE
+.TP
+.B \-descriptor|readme filename
+.RS
+Insert a reference to the specified file as the File-set Descriptor File ID.
+.RE
+.TP
+.B \-identifier|id filesetid
+.RS
+Specify a value for the File-set ID which otherwise defaults to null.
+.RE
+.TP
+.B \-noicons
+.RS
+Don't insert icon images. The default is to insert them.
+.RE
+.TP
+.B \-position
+.RS
+Add positioning and referenced image attributes to image directory record
+to facilitate posting of localizer from the directory only.
+.RE
+.TP
+.B \-novalidatename
+.RS
+Don't validate image filenames. The default is to validate them.
+.RE
+.TP
+.B \-noinstancechildoffset
+.RS
+Do not include the Offset of Referenced Lower-Level Directory Entity (0004,1420) for
+instance-level records (which have no children). Use of this option will create illegal
+DICOMDIR files that are useful for testing the defensiveness of DICOMDIR readers in
+this regard. The default is to include the attribute with a value of 0, as the standard
+requires.
+.RE
+.TP
+.B \-dirrecorder pcs|psc|scp|spc|csp|cps
+.RS
+Order directory records in a particular way. Argument is abbreviation for "parent", 
+"child" and "sibling" order. Used for creating DICOMDIRs to exercise various parser's
+implict assumptions about order of offset pointers.
+.RE
+.TP
+.B \-f|filelist filename
+.RS
+A file containing a list of DICOM input files (one filename per line).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcdirmk IMAGES/[0-9]* >DICOMDIR
+.RE
+% dcdirdmp DICOMDIR
+.RE
+PATIENT Patient 3 000003
+.RE
+ STUDY 000003  19940517 112213 BRAIN
+.RE
+  SERIES 3 MR
+.RE
+   IMAGE 3
+.RE
+   -> IMAGES\3333 
+.RE
+   IMAGE 2
+.RE
+   -> IMAGES\3332 
+.RE
+   IMAGE 1
+.RE
+   -> IMAGES\3331 
+.RE
+  SERIES 2 MR
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), 
+.BR dcdirdmp(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+The approach to making the icon image is make everything 8 bit, and
+use the first "plane" as is regardless of whether it is color or indexed
+(or even worse, interleaved). This will work really well for
+MONOCHROME2 images where BitsStored is not much bigger than the real
+maximum and the PixelRepresentaion is unsigned !
+.LP
+Output of icon images in implicit VR will fail.
+.LP
+
+
+
+
diff --git a/appsrc/dcfile/dcdtchg.cc b/appsrc/dcfile/dcdtchg.cc
new file mode 100644
index 0000000..79f8d37
--- /dev/null
+++ b/appsrc/dcfile/dcdtchg.cc
@@ -0,0 +1,844 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdtchg.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+//#include <time.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "attrtype.h"
+
+#include "hash.h"
+#include "datetype.h"
+
+#include "dcdtchg.h"
+
+class EntryString {
+	HashKeyString key;
+	const char *value;
+public:
+	EntryString(void)		{}
+	EntryString(const char *s,const char *v)
+					{ key=HashKeyString(s); value=v; }
+	EntryString(EntryString *e)
+					{ key=e->key; value=e->value; }
+
+	HashKeyString	getKey(void) const	{ return key; }
+	const char *	getValue(void) const	{ return value; }
+
+	bool operator==(EntryString e)
+					{ return key == e.getKey(); }
+};
+
+class EntryStringList : public SimpleList<EntryString>
+{
+public:
+	~EntryStringList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class EntryStringListIterator : public SimpleListIterator<EntryString>
+{
+public:
+	EntryStringListIterator(void)
+		: SimpleListIterator<EntryString>() {}
+	EntryStringListIterator(EntryStringList& list)
+		: SimpleListIterator<EntryString>(list) {}
+};
+
+class HashMap : public OpenHashTable <EntryString,
+					HashKeyString,
+					EntryStringList,
+					EntryStringListIterator>
+{
+public:
+	HashMap(unsigned long size)
+		: OpenHashTable<EntryString,
+				HashKeyString,
+				EntryStringList,
+				EntryStringListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long	hash(const HashKeyString &key,unsigned long size)
+		{
+			const unsigned nchars = 10;
+			const unsigned shift  = 4;
+
+			unsigned n=nchars;
+			unsigned long value=0;
+			const char *s=key.getString();
+			while (n-- && *s) {
+				value=(value<<shift)|*s++;
+			}
+			return value%size; 
+		}
+
+	HashKeyString key(const EntryString &e)	{ return e.getKey(); }
+};
+
+static bool
+isAttributeToBeReplaced(Attribute *a) {
+	//	Tag tag = a->getTag();
+	//	return tag != TagFromName(Date);
+	return true;
+}
+
+HashMap *timeHashMap;
+HashMap *dateTimeHashMap;
+long long dateDelta;
+bool dateDeltaSet;
+long long baseDateOffsetFromEpoch;
+bool forceFirstDay;
+bool forceFirstMonth;
+bool keepZone;
+bool addDeidentificationMethod;
+static unsigned shiftToNoonInSeconds = 12*3600u;
+static unsigned twentyFourHoursInSeconds = 24*3600u;
+
+static bool
+loopOverListsInSequences(Attribute *a,TextOutputStream &log,
+		bool (*func)(AttributeList &,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static unsigned long daysInNonLeapYear = 365;
+static unsigned long daysInLeapYear = 366;
+
+static unsigned long long milliSecondsInSecond = 1000;
+
+static unsigned long long milliSecondsInMinute = 60ul * milliSecondsInSecond;
+static unsigned long long milliSecondsInHour = 60*milliSecondsInMinute;
+static unsigned long long milliSecondsInDay = 24*milliSecondsInHour;
+
+static unsigned long long milliSecondsInNonLeapYear = (unsigned long long)(daysInNonLeapYear) * milliSecondsInDay;
+static unsigned long long milliSecondsInLeapYear = (unsigned long long)(daysInLeapYear) * milliSecondsInDay;
+
+static unsigned long daysPerMonthInNonLeapYear[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static unsigned long daysPerMonthInLeapYear[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+static unsigned long cummulativeDaysInPreviousMonthInNonLeapYear[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned long cummulativeDaysInPreviousMonthInLeapYear[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static unsigned long
+getDaysPerMonth(int mm,bool leapYear) {
+	long day = 0;
+	if (mm <= 12 && mm > 0) {
+		day = (leapYear ?  daysPerMonthInLeapYear : daysPerMonthInNonLeapYear)[mm];
+	}
+	return day;
+}
+
+static unsigned long long
+getMilliSecondsPerMonth(int mm,bool leapYear) {
+	return getDaysPerMonth(mm,leapYear) * milliSecondsInDay;
+}
+
+static void
+populateCummulativeDaysPerMonth() {
+	unsigned long nonLeapTotal=0;
+	unsigned long leapTotal=0;
+	for (int i=1; i<=12; ++i) {
+		nonLeapTotal += daysPerMonthInNonLeapYear[i-1];
+		cummulativeDaysInPreviousMonthInNonLeapYear[i] = nonLeapTotal;
+		leapTotal += daysPerMonthInLeapYear[i-1];
+		cummulativeDaysInPreviousMonthInLeapYear[i] = leapTotal;
+	}
+//cerr << "cummulativeDaysInPreviousMonthInNonLeapYear = {";
+//for (int i=0; i<=12; ++i) {
+//cerr << cummulativeDaysInPreviousMonthInNonLeapYear[i] << ",";
+//}
+//cerr << "}" << endl;
+//cerr << "cummulativeDaysInPreviousMonthInLeapYear = {";
+//for (int i=0; i<=12; ++i) {
+//cerr << cummulativeDaysInPreviousMonthInLeapYear[i] << ",";
+//}
+//cerr << "}" << endl;
+}
+
+static unsigned long
+getCummulativeDaysPerMonth(int mm,bool leapYear) {
+	long day = 0;
+	if (mm <= 12 && mm > 0) {
+		day = (leapYear ?  cummulativeDaysInPreviousMonthInLeapYear : cummulativeDaysInPreviousMonthInNonLeapYear)[mm];
+		if (day == 0 && mm > 1) {
+			// lazy computation of accumulated days
+			populateCummulativeDaysPerMonth();
+			// try again
+			day = (leapYear ?  cummulativeDaysInPreviousMonthInLeapYear : cummulativeDaysInPreviousMonthInNonLeapYear)[mm];
+		}
+	}
+	return day;
+}
+
+static bool isLeapYear(int yyyy) {
+	return (yyyy % 4 == 0) && ((yyyy % 100 != 0) || (yyyy % 400 == 0));
+}
+
+
+static char *
+getDateAsYYYYMMDDString(short yyyy,short mm,short dd) {
+	ostrstream ost;
+	ost << dec << setfill('0');
+	ost << setw(4) << yyyy
+		<< setw(2) << mm
+		<< setw(2) << dd;
+	ost << ends;
+	return ost.str();
+}
+
+static char *
+getTimeAsHHMMSSFFFString(short hour,short minute,short second,short milliSecond=0) {
+	ostrstream ost;
+	ost << dec << setfill('0');
+	ost << setw(2) << hour
+		<< setw(2) << minute
+		<< setw(2) << second;
+	if (milliSecond) {
+		ost << '.' << setw(3) << milliSecond;
+	}
+	ost << ends;
+	return ost.str();
+}
+
+static const char *
+getDateTimeAsYYYYMMDDHHMMSSFFFString(int yyyy,int mm,int dd,short hour,short minute,short second,short milliSecond=0) {
+	ostrstream ost;
+	ost << dec << setfill('0');
+	ost << setw(4) << yyyy
+		<< setw(2) << mm
+		<< setw(2) << dd
+		<< setw(2) << hour
+		<< setw(2) << minute
+		<< setw(2) << second;
+	if (milliSecond) {
+		ost << '.' << setw(3) << milliSecond;
+	}
+	ost << ends;
+	return ost.str();
+}
+
+//static char *getTimeAsHHMMSSFFFString(Time t) {
+//	return getTimeAsHHMMSSFFFString(t.getHour(),t.getMinute(), t.getSecond(),t.getMilliSecond());
+//}
+
+// we use long long, not just long, otherwise for 32 bit long, earliest is 1901/12/13 and latest is 2038/01/19 (see http://en.wikipedia.org/wiki/Unix_time)
+
+static void
+getTimeFromMilliSecondsSinceEpoch(long long milliSecondsSinceEpoch,short &year,short &month,short &day,short &hour,short &min,short &sec,short &millisec) {
+	year=1970;
+	if (milliSecondsSinceEpoch >= 0) {
+		while (true) {
+			unsigned long long milliSecondsInThisYear = isLeapYear(year) ? milliSecondsInLeapYear : milliSecondsInNonLeapYear;
+			if (milliSecondsSinceEpoch < milliSecondsInThisYear) {
+				break;
+			}
+			milliSecondsSinceEpoch -= milliSecondsInThisYear;
+//cerr << "getTimeFromMilliSecondsSinceEpoch(): removed year " << year << " is " << (isLeapYear(year) ? " " : "not ") << "leap, milliSecondsSinceEpoch now = "<< milliSecondsSinceEpoch << endl;
+			++year;
+		}
+	}
+	else {
+		while (true) {
+			--year;
+			unsigned long long milliSecondsInThisYear = isLeapYear(year) ? milliSecondsInLeapYear : milliSecondsInNonLeapYear;
+			milliSecondsSinceEpoch += milliSecondsInThisYear;
+			if (milliSecondsSinceEpoch >= 0) {
+				break;
+			}
+//cerr << "getTimeFromMilliSecondsSinceEpoch(): added year " << year << " is " << (isLeapYear(year) ? " " : "not ") << "leap, milliSecondsSinceEpoch now = "<< milliSecondsSinceEpoch << endl;
+		}
+	}
+	{
+		bool leap = isLeapYear(year);
+		month=1;
+		while (true) {
+			Assert(month <= 12);
+			unsigned long long milliSecondsInMonth = getMilliSecondsPerMonth(month,leap);
+			if (milliSecondsSinceEpoch < milliSecondsInMonth) {
+				break;
+			}
+			milliSecondsSinceEpoch -= milliSecondsInMonth;
+//cerr << "getMilliSecondsSinceEpoch(): removed month " << month << " milliSecondsInMonth = " << milliSecondsInMonth << ", milliSecondsSinceEpoch now = "<< milliSecondsSinceEpoch << endl;
+			++month;
+		}
+		day = (short)(milliSecondsSinceEpoch / milliSecondsInDay) + 1;
+		milliSecondsSinceEpoch = milliSecondsSinceEpoch % milliSecondsInDay;
+		
+		hour = (short)(milliSecondsSinceEpoch / milliSecondsInHour);
+		milliSecondsSinceEpoch = milliSecondsSinceEpoch % milliSecondsInHour;
+		
+		min = (short)(milliSecondsSinceEpoch / milliSecondsInMinute);
+		milliSecondsSinceEpoch = milliSecondsSinceEpoch % milliSecondsInMinute;
+		
+		sec = (short)(milliSecondsSinceEpoch / milliSecondsInSecond);
+		milliSecondsSinceEpoch = milliSecondsSinceEpoch % milliSecondsInSecond;
+		
+		millisec = (short)milliSecondsSinceEpoch;
+		
+		Assert(millisec >= 0 && millisec < 1000);
+		Assert(sec >= 0 && sec < 60);
+		Assert(min >= 0 && min < 60);
+		Assert(hour >= 0 && hour < 24);
+		Assert(day > 0 && day <= 31);
+		Assert(month > 0 && month <= 12);
+	}
+}
+
+static long long
+getMilliSecondsSinceEpoch(short yyyy,short mm,short dd,short h=0,short m=0,short s=0,short ms=0) {
+//cerr << "getMilliSecondsSinceEpoch(): " << getDateAsYYYYMMDDString(yyyy,mm,dd) << getTimeAsHHMMSSFFFString(h,m,s,ms) << endl;
+	long long value = -1;
+	if (mm <= 12 && mm >= 1 && dd <= 31 && dd >= 1) {
+		//if (yyyy < 1900) {
+		//	yyyy+=1900;
+		//}
+		value=0;
+		if (yyyy >= 1970) {
+			// do whole intervening years
+			for (int y=1970; y<yyyy; ++y) {
+				value += isLeapYear(y) ? daysInLeapYear : daysInNonLeapYear;
+//cerr << "getMilliSecondsSinceEpoch(): added year " << y << " is " << (isLeapYear(y) ? " " : "not ") << "leap, value now = "<< value << " days (" << (value*secondsInDay) << " seconds)" << endl;
+			}
+		}
+		else {
+			for (int y=1970; y>yyyy; --y) {
+				value -= isLeapYear(y-1) ? daysInLeapYear : daysInNonLeapYear;
+//cerr << "getMilliSecondsSinceEpoch(): subtracted year " << y << " is " << (isLeapYear(y) ? " " : "not ") << "leap, value now = "<< value << " days (" << (value*secondsInDay) << " seconds)" << endl;
+			}
+		}
+		{
+			unsigned cummulativeDaysInPreviousMonth = getCummulativeDaysPerMonth(mm,isLeapYear(yyyy));
+			value += cummulativeDaysInPreviousMonth;
+//cerr << "getMilliSecondsSinceEpoch(): added month " << mm << " cummulativeDaysInPreviousMonth = " << cummulativeDaysInPreviousMonth << " days (" << (cummulativeDaysInPreviousMonth*secondsInDay) << " seconds)" << ", value now = "<< value << " days (" << (value*secondsInDay) << " seconds)" << endl;
+			value += (dd-1);												// want difference from epoch, which is 1st, so -1
+//cerr << "getMilliSecondsSinceEpoch(): added day - 1 " << (dd-1) << ", value now = "<< value << " days (" << (value*secondsInDay) << " seconds)" << endl;
+			value *= milliSecondsInDay;
+		}
+	}
+	value += h*milliSecondsInHour + m*milliSecondsInMinute + s*milliSecondsInSecond + ms;
+//cerr << "getMilliSecondsSinceEpoch(): value in milliseconds " << value << endl;
+{
+short year,month,day,hour,minute,second,millisec;
+getTimeFromMilliSecondsSinceEpoch(value,year,month,day,hour,minute,second,millisec);
+//cerr << "getMilliSecondsSinceEpoch(): For " << getDateAsYYYYMMDDString(yyyy,mm,dd) << getTimeAsHHMMSSFFFString(h,m,s,ms) << " value in milliseconds is " << value << ", reversed is " << getDateAsYYYYMMDDString(year,month,day) << getTimeAsHHMMSSFFFString(hour,minute,second,millisec) << endl;
+Assert(year == yyyy);
+Assert(month == mm);
+Assert(day == dd);
+Assert(hour == h);
+Assert(minute == m);
+Assert(second == s);
+Assert(millisec == ms);
+}
+	return value;
+}
+
+static long long
+getMilliSecondsSinceEpochFromDateTimeString(const char *dateString,const char *timeString,const char *timezoneString) {
+	short yyyy = 1970;
+	short mm = 1;
+	short dd = 1;
+	short hour = 0;
+	short minute = 0;
+	short second = 0;
+	short millisec = 0;
+	Date *originalDate = new Date(dateString,DateOrderMonthMiddleYearFirst);
+	if (originalDate->isgood()) {
+		yyyy = originalDate->getYYYY();
+		mm = originalDate->getMM();
+		dd = originalDate->getDD();
+	}
+	if (timeString && strlen(timeString) > 0) {
+		Time *originalTime = new Time(timeString);
+		if (originalTime->isgood()) {
+			hour = originalTime->getHour();
+			minute = originalTime->getMinute();
+			second = originalTime->getSecond();
+			millisec = originalTime->getMilliSecond();
+		}
+	}
+	long long milliSecondsSinceEpoch = getMilliSecondsSinceEpoch(yyyy,mm,dd,hour,minute,second,millisec);
+	// should add or subtract timezone offset here :(
+//cerr << "getMilliSecondsSinceEpochFromDateTimeString(): " << dateString << (timeString ? timeString : "" ) << (timezoneString ? timezoneString : "" ) << "  -> " << milliSecondsSinceEpoch << endl;
+	return milliSecondsSinceEpoch;
+}
+
+static long long
+getMilliSecondsSinceEpochFromDateTimeString(const char *s) {
+	// YYYYMMDDHHMMSS[.FFFFFF[&ZZZZ]] where & is + or -
+	size_t dateTimeLength = strlen(s);
+	char *dateString = new char[9];
+	strncpy(dateString,s,8);
+	dateString[8]=0;
+	char *timeString = NULL;
+	char *timezoneString = NULL;
+	if (dateTimeLength > 8) {
+		size_t timeLength = dateTimeLength-8;
+		timeString = new char[timeLength+1];
+		strncpy(timeString,s+8,timeLength);
+		size_t endOfTimeString = timeLength;
+		const char *startOfTimezone = strchr(timeString,'+');
+		if (!startOfTimezone) {
+			startOfTimezone = strchr(timeString,'-');
+		}
+		if (startOfTimezone) {
+			size_t timezoneLength = timeLength-(startOfTimezone-timeString);
+			timezoneString = new char[timezoneLength+1];
+			strcpy(timezoneString,startOfTimezone);
+			timezoneString[timezoneLength]=0;
+			timeLength = startOfTimezone-timeString;
+		}
+		timeString[timeLength]=0;
+	}
+	return getMilliSecondsSinceEpochFromDateTimeString(dateString,timeString,timezoneString);
+}
+
+static const char *
+getReplacementDateTimeUsingCachedDelta(const char *originalString) {
+	long long originalOffsetFromEpoch = getMilliSecondsSinceEpochFromDateTimeString(originalString);
+	if (!dateDeltaSet) {
+		dateDelta = baseDateOffsetFromEpoch - originalOffsetFromEpoch;
+cerr << "delta = " << dateDelta << endl;
+		dateDeltaSet = true;
+	}
+	long long replacementOffsetFromEpoch = originalOffsetFromEpoch + dateDelta;
+	short year,month,day,hour,minute,second,millisec;
+	getTimeFromMilliSecondsSinceEpoch(replacementOffsetFromEpoch,year,month,day,hour,minute,second,millisec);
+	if (forceFirstDay) {
+		day=1;
+	}
+	if (forceFirstMonth) {
+		month=1;
+	}
+	const char *replacementString = getDateTimeAsYYYYMMDDHHMMSSFFFString(year,month,day,hour,minute,second,millisec);
+//cerr << "getReplacementDateTimeUsingCachedDelta(): replacement for datetime " << originalString << " is " << replacementString << endl;
+	return replacementString;
+}
+
+static void
+getReplacementDateTimeUsingCachedDelta(const char *originalDateString,const char *originalTimeString,const char *&replacementDateString,const char *&replacementTimeString) {
+	long long originalOffsetFromEpoch = getMilliSecondsSinceEpochFromDateTimeString(originalDateString,originalTimeString,NULL);
+	if (!dateDeltaSet) {
+		dateDelta = baseDateOffsetFromEpoch - originalOffsetFromEpoch;
+cerr << "delta = " << dateDelta << endl;
+		dateDeltaSet = true;
+	}
+	long long replacementOffsetFromEpoch = originalOffsetFromEpoch + dateDelta;
+	short year,month,day,hour,minute,second,millisec;
+	getTimeFromMilliSecondsSinceEpoch(replacementOffsetFromEpoch,year,month,day,hour,minute,second,millisec);
+	if (forceFirstDay) {
+		day=1;
+	}
+	if (forceFirstMonth) {
+		month=1;
+	}
+	replacementDateString = getDateAsYYYYMMDDString(year,month,day);
+	replacementTimeString = getTimeAsHHMMSSFFFString(hour,minute,second,millisec);
+//cerr << "getReplacementDateTimeUsingCachedDelta(): replacement for date " << originalDateString << " is " << replacementDateString << endl;
+//cerr << "getReplacementDateTimeUsingCachedDelta(): replacement for time " << (originalTimeString ? originalTimeString : "") << " is " << replacementTimeString << endl;
+}
+
+static Tag
+getTagOfTimeAttributeCorrespondingToDateAttribute(Tag dateTag,TextOutputStream &log) {
+	// in map, odd entries are date, succeeding even entry is corresponding time
+	Tag *p = mapDateTagToTimeTag;
+	while (*p && *p != dateTag) {
+		p+=2;
+	}
+	Tag timeTag = *(p+1);
+//log << "getTagOfTimeAttributeCorrespondingToDateAttribute(): for date tag "; dateTag.write(log); log << " time tag is "; timeTag.write(log); log << endl;
+	return timeTag;
+}
+
+static const char *
+getCorrespondingValueOfTimeAttributeCorrespondingToDateAttribute(AttributeList& list,Attribute *aDate,int i,TextOutputStream &log) {
+//log << "getCorrespondingValueOfTimeAttributeCorrespondingToDateAttribute(): For date "; if (aDate) aDate->write(log); log << endl;
+	char *timeString = NULL;
+	Tag dateTag = aDate->getTag();
+	Tag timeTag = getTagOfTimeAttributeCorrespondingToDateAttribute(dateTag,log);
+	if (timeTag) {
+		Attribute *aTime = list[timeTag];
+//log << "getCorrespondingValueOfTimeAttributeCorrespondingToDateAttribute(): Got time "; if (aTime) aTime->write(log); log << endl;
+		if (aTime && i < aTime->getVM()) {
+			aTime->getValue(i,timeString);
+		}
+	}
+	return timeString;
+}
+
+static bool
+changeDatesAndTimes(AttributeList& list,TextOutputStream &log)
+{
+	bool succeeded=true;
+	if (!keepZone) {
+		// will be added with +0000 to root list only; this routine is also called for sequence item lists
+		list-=TagFromName(TimezoneOffsetFromUTC);
+	}
+	if (!dateDeltaSet) {
+		// try and make sure that the Study Date and Time of the first image encountered are the "earliest", so they don't get move to the day before
+		Attribute *a = list[TagFromName(StudyDate)];
+		char *originalDateString;
+		if (a && a->getValue(0,originalDateString) && originalDateString && strlen(originalDateString)) {
+			const char *originalTimeString = getCorrespondingValueOfTimeAttributeCorrespondingToDateAttribute(list,a,0,log);
+			const char *replacementDateString = NULL;
+			const char *replacementTimeString = NULL;
+			// this next will set dateDeltaSet
+			getReplacementDateTimeUsingCachedDelta(originalDateString,originalTimeString,replacementDateString,replacementTimeString);
+			// ignore result ... weill do it for real when iterating through whole attribute list
+		}
+	}
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequences(a,log,&::changeDatesAndTimes)) {
+			succeeded=false;
+		}
+//a->write(log); log << endl;
+		const char *vr = a->getVR();
+		bool isDate = false;
+		bool isTime = false;
+		bool isDateTime = false;
+		if (vr) {
+			if (strcmp(vr,"DA") == 0) {
+				isDate = true;
+			}
+			else if (strcmp(vr,"TM") == 0) {
+				isTime = true;
+			}
+			else if (strcmp(vr,"DT") == 0) {
+				isDateTime = true;
+			}
+		}
+		if (isDate || isTime || isDateTime) {
+//log << "Was: "; a->write(log); log << endl;
+			int n = a->getVM();
+			int i;
+			for (int i=0; i<n; ++i) {
+				char *originalString;
+				if (a->getValue(i,originalString) && originalString && strlen(originalString) && isAttributeToBeReplaced(a)) {
+//cerr << "Original String = " << originalString << endl;
+					const char *replacementString = NULL;
+					{
+						if (isDate) {
+							// regardless of whether there might be a cached value ... do it from scratch in order to pick up corresponding time
+							// since the same date value may be used in different date attributes
+							const char *originalTimeString = getCorrespondingValueOfTimeAttributeCorrespondingToDateAttribute(list,a,i,log);
+							const char *replacementTimeString = NULL;
+							getReplacementDateTimeUsingCachedDelta(originalString,originalTimeString,replacementString,replacementTimeString);
+							// add any replacement time string to the timeHashMap ... will actually be used later
+							if (originalTimeString && strlen(originalTimeString) > 0 && replacementTimeString && strlen(replacementTimeString)) {
+//cerr << "Add time entry = " << originalTimeString << ", " << replacementTimeString << endl;
+								(*timeHashMap)+=new EntryString(StrDup(originalTimeString),replacementTimeString);
+							}
+						}
+						if (isTime) {
+							// Only handle time entries are created as pairs with date entries ... assumes date attributes always encountered before corresponding time
+							EntryString *entry = (*timeHashMap)[originalString];
+							if (entry) {
+//cerr << "Found time entry = " << entry->getKey().getString() << ", " << entry->getValue() << endl;
+								replacementString = entry->getValue();
+							}
+						}
+						else if (isDateTime) {
+							EntryString *entry = (*dateTimeHashMap)[originalString];
+							if (entry) {
+//cerr << "Found datetime entry = " << entry->getKey().getString() << ", " << entry->getValue() << endl;
+								replacementString = entry->getValue();
+							}
+							if (!replacementString) {
+								replacementString = getReplacementDateTimeUsingCachedDelta(originalString);
+//cerr << "Add datetime entry = " << originalString << ", " << replacementString << endl;
+								if (replacementString) {
+									(*dateTimeHashMap)+=new EntryString(StrDup(originalString),replacementString);
+								}
+							}
+						}
+					}
+					if (replacementString) {
+//cerr << "Replace " << originalString << " with " << replacementString << endl;
+						a->setValue(i,replacementString);
+//log << "---> "; a->write(log); log << endl;
+					}
+				}
+			}
+		}
+		//	succeeded=false;
+		++listi;
+	}
+	return succeeded;
+}
+
+static const char *
+makeNewFileName(const char *outdir,const char *filename) {
+//cerr << "makeNewFileName(): outdir " << outdir << endl;
+//cerr << "makeNewFileName(): filename " << filename << endl;
+	Assert(outdir);
+	Assert(filename);
+	size_t outdirLength = strlen(outdir);
+	size_t filenameLength = strlen(filename);
+	const char *filenameLastSeparator = strrchr(filename,'/');
+	if (filenameLastSeparator != NULL) {
+		filename = filenameLastSeparator+1;
+		filenameLength = strlen(filename);
+//cerr << "makeNewFileName(): found last component " << filename << endl;
+	}
+	size_t length = outdirLength + 1 + filenameLength;
+	char *string=new char[length+1];
+	strcpy(string,outdir);
+	strcat(string,"/");
+	strcat(string,filename);
+	string[length]=0;
+//cerr << "makeNewFileName(): returning " << string << endl;
+	return string;
+}
+
+static void handleOneFile(const char *outdir,const char *filename,
+			DicomInputOptions &dicom_input_options,
+			DicomOutputOptions &dicom_output_options,
+			bool listnames,bool success,bool verbose,
+			TextOutputStream &log) {
+
+		Assert(filename);
+		if (listnames) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *ifstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *ifstr=new ifstream(filename);
+#endif
+		if (!ifstr || !*ifstr || !ifstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			cerr << endl;
+			success=false;
+			return;
+		}
+
+		DicomInputStream din(*(istream *)ifstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+
+		if (verbose) log << "******** While reading ... " << filename << " ... ********" << endl;
+		list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			return;
+		}
+
+		// do NOT close input file yet, else deferred pixel data read for write will fail
+		
+		changeDatesAndTimes(list,log);
+		if (!keepZone) {
+			// already removed previously, if present
+			Attribute *a = new ShortStringAttribute(TagFromName(TimezoneOffsetFromUTC),"+0000");
+			list+=a;
+		}
+
+		if (addDeidentificationMethod) {
+			Attribute *a = list[TagFromName(DeidentificationMethod)];
+			if (a) {
+				a->addValue("dcdtchg change dates");
+			}
+			else {
+				a = new LongStringAttribute(TagFromName(DeidentificationMethod),"dcdtchg change dates");
+				list += a;
+			}
+		}
+		
+		const char *outfilename = makeNewFileName(outdir,filename);
+		Assert(outfilename);
+		if (listnames) log << "Writing \"" << outfilename << "\"" << endl;
+		
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+		ofstream *ofstr=new ofstream(outfilename,
+			ios::out|ios::trunc|ios::binary);
+#else
+		ofstream *ofstr=new ofstream(outfilename,ios::out|ios::trunc);
+#endif
+		if (!ofstr || !*ofstr || !ofstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileWriteOpenFailed);
+			if (outfilename) cerr <<" - \"" << outfilename << "\"";
+			cerr << endl;
+			success=false;
+			return;
+		}
+		
+		DicomOutputStream dout(*(ostream *)ofstr,
+			dicom_output_options.transfersyntaxuid,
+			dicom_output_options.usemetaheader,
+			dicom_output_options.useimplicitmetaheader,
+			dicom_output_options.addtiff);
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+		
+		if (ofstr) {
+			ofstr->close();
+			delete ofstr;
+		}
+		if (outfilename) {
+			delete outfilename;
+		}
+		// Now can close input file
+		if (ifstr) {
+			ifstr->close();
+			delete ifstr;
+		}
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool listnames=options.get("l");
+
+	const char *outdir=0;
+	bad = !options.get("outdir",outdir) || bad;
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	const char *filelistfile=0;
+	(void)(options.get("filelist",filelistfile) || options.get("f",filelistfile));
+
+	baseDateOffsetFromEpoch = 0;
+	{
+		const char *baseDateString=0;
+		(void)(options.get("basedate",baseDateString));
+		if (baseDateString == NULL) {
+			baseDateString = "20010101000000+0000";
+		}
+		baseDateOffsetFromEpoch = getMilliSecondsSinceEpochFromDateTimeString(baseDateString);
+	}
+	
+	forceFirstDay=options.get("forcefirstday");
+	forceFirstMonth=options.get("forcefirstmonth");
+
+	keepZone=options.get("keepzone");
+	
+	addDeidentificationMethod=!options.get("nomethod");
+	
+	dateDeltaSet = options.get("delta",dateDelta);	// if not supplied, will be set once first date is encountered
+//cerr << "delta = " << dateDelta << endl;
+
+	int numberofinputfiles=!options;
+
+	const char **listoffilenames = new const char * [numberofinputfiles];
+	const char **ptr = listoffilenames;
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		*ptr++=filename;
+	}
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -outdir dirname"
+			<< " [-v|-verbose]"
+			<< " [-l]"
+			<< " [-f|-filelist filename]"
+			<< " [-delta ms]"
+			<< " [-basedate yyyymmdd]"
+			<< " [-forcefirstday]"
+			<< " [-forcefirstmonth]"
+			<< " [-keepzone]"
+			<< " [-nomethod]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	timeHashMap = new HashMap(1000);
+	dateTimeHashMap = new HashMap(1000);
+	
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		handleOneFile(outdir,listoffilenames[i],dicom_input_options,dicom_output_options,listnames,success,verbose,log);
+	}
+
+	if (filelistfile) {
+		ifstream *flfstr=new ifstream(filelistfile);
+		if (!flfstr || !*flfstr || !flfstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filelistfile) cerr <<" - \"" << filename << "\"";
+			cerr << endl;
+			bad=true;
+		}
+		else {
+			while (flfstr->peek() != istream::traits_type::eof()) {
+				const int lineBufferSize=2048;
+				char lineBuffer[lineBufferSize];
+				flfstr->getline(lineBuffer,2048);
+				if (strlen(lineBuffer)) {
+					handleOneFile(outdir,lineBuffer,dicom_input_options,dicom_output_options,listnames,success,verbose,log);
+				}
+				// else skip blank lines
+			}
+		}
+	}
+
+	if (numberofinputfiles && listoffilenames) delete[] listoffilenames;
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcdtchg.h b/appsrc/dcfile/dcdtchg.h
new file mode 100644
index 0000000..a1a612a
--- /dev/null
+++ b/appsrc/dcfile/dcdtchg.h
@@ -0,0 +1,47 @@
+// Automatically generated from template - EDITS WILL BE LOST
+// Generated by makedcdtchgheader.sh
+static Tag mapDateTagToTimeTag[] = {
+    TagFromName(InstanceCreationDate), TagFromName(InstanceCreationTime),
+    TagFromName(StudyDate), TagFromName(StudyTime),
+    TagFromName(SeriesDate), TagFromName(SeriesTime),
+    TagFromName(AcquisitionDate), TagFromName(AcquisitionTime),
+    TagFromName(ContentDate), TagFromName(ContentTime),
+    TagFromName(OverlayDate), TagFromName(OverlayTime),
+    TagFromName(CurveDate), TagFromName(CurveTime),
+    TagFromName(PatientBirthDate), TagFromName(PatientBirthTime),
+    TagFromName(DateOfSecondaryCapture), TagFromName(TimeOfSecondaryCapture),
+    TagFromName(DateOfLastCalibration), TagFromName(TimeOfLastCalibration),
+    TagFromName(DateOfLastDetectorCalibration), TagFromName(TimeOfLastDetectorCalibration),
+    TagFromName(ModifiedImageDate), TagFromName(ModifiedImageTime),
+    TagFromName(StudyVerifiedDate), TagFromName(StudyVerifiedTime),
+    TagFromName(StudyReadDate), TagFromName(StudyReadTime),
+    TagFromName(ScheduledStudyStartDate), TagFromName(ScheduledStudyStartTime),
+    TagFromName(ScheduledStudyStopDate), TagFromName(ScheduledStudyStopTime),
+    TagFromName(StudyArrivalDate), TagFromName(StudyArrivalTime),
+    TagFromName(StudyCompletionDate), TagFromName(StudyCompletionTime),
+    TagFromName(ScheduledAdmissionDate), TagFromName(ScheduledAdmissionTime),
+    TagFromName(ScheduledDischargeDate), TagFromName(ScheduledDischargeTime),
+    TagFromName(AdmittingDate), TagFromName(AdmittingTime),
+    TagFromName(DischargeDate), TagFromName(DischargeTime),
+    TagFromName(ScheduledProcedureStepStartDate), TagFromName(ScheduledProcedureStepStartTime),
+    TagFromName(ScheduledProcedureStepEndDate), TagFromName(ScheduledProcedureStepEndTime),
+    TagFromName(PerformedProcedureStepStartDate), TagFromName(PerformedProcedureStepStartTime),
+    TagFromName(PerformedProcedureStepEndDate), TagFromName(PerformedProcedureStepEndTime),
+    TagFromName(IssueDateOfImagingServiceRequest), TagFromName(IssueTimeOfImagingServiceRequest),
+    TagFromName(FindingsGroupRecordingDateTrial), TagFromName(FindingsGroupRecordingTimeTrial),
+    TagFromName(Date), TagFromName(Time),
+    TagFromName(ObservationDateTrial), TagFromName(ObservationTimeTrial),
+    TagFromName(PresentationCreationDate), TagFromName(PresentationCreationTime),
+    TagFromName(CreationDate), TagFromName(CreationTime),
+    TagFromName(StructureSetDate), TagFromName(StructureSetTime),
+    TagFromName(TreatmentControlPointDate), TagFromName(TreatmentControlPointTime),
+    TagFromName(SafePositionExitDate), TagFromName(SafePositionExitTime),
+    TagFromName(SafePositionReturnDate), TagFromName(SafePositionReturnTime),
+    TagFromName(TreatmentDate), TagFromName(TreatmentTime),
+    TagFromName(RTPlanDate), TagFromName(RTPlanTime),
+    TagFromName(SourceStrengthReferenceDate), TagFromName(SourceStrengthReferenceTime),
+    TagFromName(ReviewDate), TagFromName(ReviewTime),
+    TagFromName(InterpretationRecordedDate), TagFromName(InterpretationRecordedTime),
+    TagFromName(InterpretationTranscriptionDate), TagFromName(InterpretationTranscriptionTime),
+    TagFromName(InterpretationApprovalDate), TagFromName(InterpretationApprovalTime),
+    0,0 };
diff --git a/appsrc/dcfile/dcdtchg.man b/appsrc/dcfile/dcdtchg.man
new file mode 100755
index 0000000..3959492
--- /dev/null
+++ b/appsrc/dcfile/dcdtchg.man
@@ -0,0 +1,200 @@
+.TH DCDTCHG 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Change UIDs"
+.SH NAME
+dcdtchg \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Change UIDs consistently
+.SH SYNOPSIS
+.HP 10
+.B dcdtchg
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+.B \-outdir " dirname"
+[
+.B \-v|verbose|vv|veryverbose
+]
+[
+.B \-l
+]
+[
+.B \-f|-filelist " filename"
+]
+[
+.B \-basedate " yyyymmdd"
+]
+[
+.B \-delta " ms"
+]
+[
+.B \-forcefirstday
+]
+[
+.B \-forcefirstmonth
+]
+[
+.B \-keepzone
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcdtchg
+reads all the named dicom input files (and/or the files listed in the specified
+file) and copies them to the specified directory, changing all the dates and times
+in a consistent manner throughout the set of files.
+.LP
+The dates and times obtained by two separate invocations of this utility on different files will be different, so
+the action needs to be performed on a set of files simultaneously in order
+to maintain consistency across studies, series and temporal frames of reference.
+.LP
+Normalization of dates and times involves shifting the first date and time pair encountered in the first file to a
+base date, and then maintaining a consistent offset from that base date and time for all subsequent dates and times
+encountered.
+.LP
+Normalization of the times is only performed for DT attributes and for those TM attributes
+that have a known DA corresponding attribute. For example Study Date and Study Time are
+treated as a pair. Any TM attribute that does not have a corresponding known standard DA
+attribute will be left alone, unless it happens to have exactly the same value as another
+TM attribute that does have a matching date and has been normalized.
+.LP
+After date and time normalization, the day of the month and the month of the year may be forced
+to a value of 1 with the appropiate options, though this will potentially invalidate
+time intervals that span 24 hour boundaries
+.LP
+All timezone information is removed and set to UTC, and the TimezoneOffsetFromUTC attribute
+added, unless suppressed with the keepzone option.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-outdir dirname
+.RS
+The directory, which must already exist, to which the copied files are written, using
+the basename of the original filename.
+.RE
+.TP
+.B \-v|verbose
+.RS
+Display attributes as they are read and written.
+.RE
+.TP
+.B \-l
+.RS
+List filenames as they are read and written.
+.RE
+.TP
+.B \-f|filelist filename
+.RS
+.RE
+.TP
+.B \-basedate yyyymmdd[hhmmss]
+.RS
+Use a different date (and time) to which to normalize all dates and times rather than the default 20010101000000.
+.RE
+.TP
+.B \-delta ms
+.RS
+Use a specific delta (such as reported on a previous run of dcdtchg), so as to shift the datetimes of another
+set of instances by the same delta and hence maintain their relative temporal relationship.
+.RE
+.TP
+.B \-forcefirstday
+.RS
+Replace the day of the month with 01 after shifting the date to the base date. This will potentially
+invalidate time intervals that span 24 hour boundaries.
+.RE
+.TP
+.B \-forcefirstmonth
+.RS
+Replace the month of the year with 01 after shifting the date to the base date. This will potentially
+invalidate time intervals that span 24 hour boundaries.
+.RE
+.RE
+.B \-keepzone
+.RS
+Do not change the timezone. Any TimezoneOffsetFromUTC is left unchanged. Any timezone component of
+a DT attribute is copied to the output.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% ls -1 IMAGES/[0-9]*
+.RE
+IMAGES/IM0001
+.RE
+IMAGES/IM0002
+.RE
+% mkdir /tmp/IMAGES
+.RE
+% dcuidchg IMAGES/[0-9]* -outdir /tmp/NEWIMAGES
+.RE
+delta = -200590875000
+.RE
+% ls -1 /tmp/NEWIMAGES
+.RE
+/tmp/NEWIMAGES/IM0001
+.RE
+/tmp/NEWIMAGES/IM0002
+.RE
+% dcdiff IMAGES/IM0001 /tmp/NEWIMAGES/IM0001
+.RE
+9,10c9,10
+.RE
+< (0x0008,0x0012) DA Instance Creation Date      VR=<DA>   VL=<0x0008>  <20071109> 
+.RE
+< (0x0008,0x0013) TM Instance Creation Time      VR=<TM>   VL=<0x0006>  <161536> 
+.RE
+---
+.RE
+> (0x0008,0x0012) DA Instance Creation Date      VR=<DA>   VL=<0x0008>  <20010702> 
+.RE
+> (0x0008,0x0013) TM Instance Creation Time      VR=<TM>   VL=<0x0006>  <003421> 
+.RE
+15c15
+.RE
+< (0x0008,0x002a) DT Acquisition Date Time       VR=<DT>   VL=<0x0014>  <20070511155342-1400 > 
+.RE
+---
+.RE
+> (0x0008,0x002a) DT Acquisition Date Time       VR=<DT>   VL=<0x0014>  <20010101001227+0000 > 
+.RE
+22c22
+.RE
+< (0x0008,0x0201) SH Timezone Offset From UTC    VR=<SH>   VL=<0x0006>  <-0500> 
+.RE
+---
+.RE
+> (0x0008,0x0201) SH Timezone Offset From UTC    VR=<SH>   VL=<0x0006>  <+0000 > 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), 
+.BR dcuidchg(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+There is a fixed length of buffer used for reading each line from the list of filenames file.
+.LP
+Time normalization based on combined date and time values introduces the risk that times
+may wrap around the 24 hour period (in either direction) though any corresponding date
+attribute will be appropriately incremented or decremented. That is, the interval between
+times will be preserved, except when the date day or month values are forced to 1. This
+risk is mitigated by looking for the Study Date and Time (usually the earliest) first.
+.LP
+Timezone replacement does not take into account the possibility of two attributes with the
+different explicit timezones in DT attributes (or different from the value in the
+TimezoneOffsetFromUTC attribute) being present ... all timezone information is simply
+removed and replaced with "+0000" (UTC).
+.LP
+Times and datetimes with a fractional second component are always output to a precision of 3 digits (milliseconds)
+even if greater or lesser precision was present in the input. If a fractional component is present
+but has a value of 0, then the fractional component will not be present in the output; this is
+normally the case when the times in the input are specified to second precision.
+.LP
+
diff --git a/appsrc/dcfile/dcdump.cc b/appsrc/dcfile/dcdump.cc
new file mode 100644
index 0000000..fc5a440
--- /dev/null
+++ b/appsrc/dcfile/dcdump.cc
@@ -0,0 +1,71 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool showfilename=options.get("filename");
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		log << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (verbose) log << "******** While reading ... ********" << endl;
+//clock_t start = clock();
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+//log << "Elapsed time " << (double((clock() - start))/CLOCKS_PER_SEC*1000.0) << " ms" <<endl;
+	
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	if (verbose) log << "******** As read ... ********" << endl; 
+	//log << list;
+	list.write(log,verbose);
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcdump.man b/appsrc/dcfile/dcdump.man
new file mode 100755
index 0000000..04b7520
--- /dev/null
+++ b/appsrc/dcfile/dcdump.man
@@ -0,0 +1,74 @@
+.TH DCDUMP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Describe DICOM file content"
+.SH NAME
+dcdump \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Describe DICOM file content
+.SH SYNOPSIS
+.HP 10
+.B dcdump
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcdump
+reads the named dicom or acr-nema input file and describes the information contained, attempting to interpret the structure of the message, including nested sequences (cf. andump).
+.LP
+The group and element number, dictionary and explicit value representation, description of tag, value length and value of the element are displayed, 
+optionally with an offset byte count from the start of the file.
+.SH OPTIONS
+The attribute values, description and verbose output go to standard error.
+.LP
+Binary attributes are written in hexadecimal with a preceding
+"0x". Numeric string attributes are written in decimal. Attribute values
+are displayed in hexadecimal or string format as determined by the value representation.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcdump NM.dc3
+.RE
+(0x0008,0x0000) UL Group Length  VR=<UL> VL=<0x0004> [0x08] 
+.RE
+(0x0008,0x0008) CS Image Type    VR=<CS> VL=<0x0024> <...> 
+.RE
+ ...
+.RE
+(0x0054,0x0013) SQ ... Sequence  VR=<SQ> VL=<0xffffffff> []
+.RE
+----:
+.RE
+>(0x0054,0x0014) DS Energy Win LL VR=<DS> VL=<0x0006> <1.0> 
+.RE
+>(0x0054,0x0015) DS Energy Win UL VR=<DS> VL=<0x0006> <9.0> 
+.RE
+ ...
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR andump(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcencap.cc b/appsrc/dcfile/dcencap.cc
new file mode 100644
index 0000000..c7097ed
--- /dev/null
+++ b/appsrc/dcfile/dcencap.cc
@@ -0,0 +1,299 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcencap.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "getoptns.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "attrval.h"
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options1(options);
+	InputOptions		input_options2(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	unsigned itemSize=0;
+	(void)options.get("itemsize",itemSize);
+	if (itemSize%2 != 0) {
+		cerr << EMsgDC("Item size must be even length") << endl;
+		bad=true;
+	}
+	
+	bool singleitem = options.get("singleitem");
+	if (singleitem) {
+		if (itemSize != 0) {
+			cerr << EMsgDC("Cannot specify -itemsize if -singleitem") << endl;
+			bad=true;
+		}
+	}
+	
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool verbose=options.get("verbose") || options.get("v") || veryverbose;
+
+	bool writeListPreceedingPixelData = true;
+	bool writePixelDataAttributeBase = true;
+	bool writePixelDataFragments = true;
+	bool writePixelDataAttributeSequenceDelimiter = true;
+
+	dicom_input_options1.done();
+	input_options2.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener1(
+		options,dicom_input_options1.filename);
+	InputOpenerFromOptions input_opener2(
+		options,input_options2.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options1.errors();
+	cerr << input_options2.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener1.errors();
+	cerr << input_opener2.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options1.good()
+	 || !input_options2.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener1.good()
+	 || !input_opener2.good()
+	 || !output_opener.good()
+	 || !options
+	|| bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options1.usage()
+			<< input_options2.usage()
+			<< dicom_output_options.usage()
+			<< " [-itemsize nbytes|-singleitem]"
+			<< " [-v|-verbose|-vv|-veryverbose]"
+			<< MMsgDC(InputFile) << " " << MMsgDC(InputFile)
+			<< "[" << MMsgDC(OutputFile) << "]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din1(*(istream *)input_opener1,
+		dicom_input_options1.transfersyntaxuid,
+		dicom_input_options1.usemetaheader);
+	istream in2(input_opener2);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (veryverbose) log << "******** While reading DICOM dataset ... ********" << endl; 
+	list.read(din1,&log,veryverbose,0xffffffff,true,dicom_input_options1.uselengthtoend,dicom_input_options1.ignoreoutofordertags);
+	
+	if (!list.good()) {
+		log << list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		if (writeListPreceedingPixelData) {
+			if (!usualManagedAttributeListWrite(list,dout,
+				dicom_output_options,log,veryverbose)) success=false;
+		}
+		if (writePixelDataAttributeBase) {
+			// now construct and write an undefined length PixelData attribute "manually"
+		
+			dout << Uint16(0x7fe0);
+			dout << Uint16(0x0010);
+			if (dout.getTransferSyntaxInUse()->isExplicitVR()) {
+				dout << 'O';
+				dout << 'B';
+				dout << Uint16(0);
+			}
+			dout << Uint32(0xffffffffl);	// VL
+		
+			// don't forget the empty item offset table "item" ...
+		
+			dout << Uint16(0xfffe);
+			dout << Uint16(0xe000);
+			dout << Uint32(0);		// VL
+		}
+		if (writePixelDataFragments) {		
+			Uint16 numberOfFrames=1;
+			Uint32 frameSize=0;
+			{
+				Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+				if (aNumberOfFrames) {
+					numberOfFrames=AttributeValue(aNumberOfFrames);
+				}
+			
+				Uint16 vRows = 0;
+				Attribute *aRows = list[TagFromName(Rows)];
+				if (!aRows) {
+					log << WMsgDC(MissingAttribute)
+					<< " - \"Rows\""
+					<< endl;
+				}
+				else {
+					vRows=AttributeValue(aRows);
+				}
+				Uint16 vColumns = 0;
+				Attribute *aColumns = list[TagFromName(Columns)];
+				if (!aColumns) {
+					log << WMsgDC(MissingAttribute)
+					<< " - \"Columns\""
+					<< endl;
+				}
+				else {
+					vColumns=AttributeValue(aColumns);
+				}
+				Uint16 vBitsAllocated = 0;
+				Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+				if (!aBitsAllocated) {
+					log << WMsgDC(MissingAttribute)
+					<< " - \"BitsAllocated\""
+					<< endl;
+				}
+				else {
+					vBitsAllocated=AttributeValue(aBitsAllocated);
+				}
+				Uint16 vSamplesPerPixel = 1;
+				Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+				if (!aSamplesPerPixel) {
+					log << WMsgDC(MissingAttribute)
+					<< " - \"SamplesPerPixel\""
+					<< endl;
+				}
+				else {
+					vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+				}
+				frameSize=((Uint32)vRows)*vColumns*vSamplesPerPixel*((vBitsAllocated-1)/8+1);
+			}
+			if (frameSize == 0) {
+				log << WMsgDC("Cannot compute frame size from Image Pixel Module attributes") << endl;
+				frameSize=0xFFFFFFFE;
+			}
+			{
+				if (verbose) {
+					log << "Using frameSize " << dec << frameSize << endl; 
+				}
+				if (singleitem) {
+					itemSize=numberOfFrames*frameSize;
+					if (itemSize%2 != 0) ++itemSize;
+					if (itemSize > 0xFFFFFFFE) itemSize=0xFFFFFFFE;	// maximum length of defined length item
+				}
+				else {
+					if (itemSize == 0) {
+						itemSize=(unsigned)frameSize;
+						if (itemSize%2 != 0) ++itemSize;
+						if (itemSize > 0xFFFFFFFE) itemSize=0xFFFFFFFE;	// maximum length of defined length item
+					}
+				}
+				if (verbose) {
+					log << "Using itemSize " << dec << itemSize << endl; 
+				}
+				unsigned long total=0;
+				char *buffer = new char[itemSize];
+				Assert(buffer);
+				if (singleitem) {
+					if (verbose) {
+						log << "Doing single item " << endl; 
+					}
+					in2.read(buffer,itemSize);
+					int bytesRead=in2.gcount();
+					if (bytesRead > 0) {
+						int bytesWritten = bytesRead;
+						if (bytesWritten%2 != 0) {
+							if (verbose) {
+								log << "Padding odd length fragment" << endl; 
+							}
+							++bytesWritten;
+							Assert(bytesWritten <= itemSize);
+							buffer[bytesRead]=(char)0xff;	// pad character is 0xff for JPEG etc, after EOI
+						}
+						// write Item
+						dout << Uint16(0xfffe);
+						dout << Uint16(0xe000);
+						dout << Uint32(bytesWritten);		// VL
+						dout.write(buffer,bytesWritten);
+						total+=bytesWritten;
+					}
+				}
+				else {
+					unsigned f;
+					for (f=0; f < numberOfFrames; ++f) {
+						if (verbose) {
+							log << "Doing frame " << dec << f << endl; 
+						}
+						Uint32 bytesLeftInFrame=frameSize; 
+						while (bytesLeftInFrame > 0) {
+							unsigned bytesThisItem = bytesLeftInFrame > itemSize ? itemSize : (unsigned)bytesLeftInFrame;
+							if (in2.eof()) {
+								// This is not an error if data was compressed; we just reached the end of it ...
+								//log << EMsgDC("Premature EOF - giving up") << endl;
+								//success=false;
+								bytesLeftInFrame=0;
+								f=numberOfFrames;
+							}
+							else {
+								in2.read(buffer,bytesThisItem);
+								int bytesRead=in2.gcount();
+								if (verbose) {
+									log << "Wanted " << dec << bytesThisItem << " read " << bytesRead << endl; 
+								}
+								if (bytesRead > 0) {
+									int bytesWritten = bytesRead;
+									if (bytesWritten%2 != 0) {
+										if (verbose) {
+											log << "Padding odd length fragment" << endl; 
+										}
+										++bytesWritten;
+										Assert(bytesWritten <= itemSize);
+										buffer[bytesRead]=(char)0xff;	// pad character is 0xff for JPEG etc, after EOI
+									}
+									// write Item
+									dout << Uint16(0xfffe);
+									dout << Uint16(0xe000);
+									dout << Uint32(bytesWritten);		// VL
+									dout.write(buffer,bytesWritten);
+									bytesLeftInFrame-=bytesRead;
+									Assert(bytesLeftInFrame == 0 || bytesWritten%2 == 0);	// i.e. didn't pad in middle of item
+									total+=bytesWritten;
+								}
+								else {
+									// This is not an error if data was compressed; we just reached the end of it ...
+									//log << EMsgDC("Read returns zero length - giving up") << endl;
+									//success=false;
+									bytesLeftInFrame=0;
+									f=numberOfFrames;
+								}
+							}
+						}
+					}
+				}
+				if (verbose) {
+					log << "Wrote total of " << dec << total << endl; 
+				}
+			}
+			if (writePixelDataAttributeSequenceDelimiter) {
+				dout << Uint16(0xfffe);
+				dout << Uint16(0xe0dd);
+				dout << Uint32(0);	// VL
+			}
+			dout.flush();
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcencap.man b/appsrc/dcfile/dcencap.man
new file mode 100755
index 0000000..166a862
--- /dev/null
+++ b/appsrc/dcfile/dcencap.man
@@ -0,0 +1,82 @@
+.TH DCENCAP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Encapsulate in DICOM file"
+.SH NAME
+dcencap \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Encapsulate compressed stream in a DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcencap
+.so man1/gen.so
+.B dicomheader rawpixeldata
+.B \-transfersyntax " uid"
+[
+.B \-itemsize " nbytes"
+|
+.B \-singleitem
+]
+[
+.B \-v|verbose|vv|veryverbose
+]
+.so man1/optin.so
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcencap
+reads the named dicom header input file and raw pixel data bitstream input file
+and copies the information and pixel data into a new dicom file with the
+pixel data encapsulated and the specified transfer syntax.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1), though the input
+filenames must be explicitly specified, ie. they cannot be redirected from standard input. The transfer syntax
+must be explicitly specifed for the DICOM output file using the usual \-ts option, and it obviously has to
+be one of the encapsulated transfer syntaxes. Options specific to this program are:
+.TP
+.B \-singleitem
+.RS
+Only a single encapsulated item is written, regardless of the number of frames (e.g., for MPEG).
+.RE
+.TP
+.B \-itemsize " nbytes"
+.RS
+The number of bytes to include in each encapsulated item. Defaults to number of rows times number of columns times bytes per pixel in a single frame, unless it exceeds the size of what will fit in a 32 bit length field; obviously this calculation has no meaning if the data stream
+is compressed.
+.RE
+.TP
+.B \-verbose
+.RS
+Describe fragmentation process and number of bytes processed.
+.RE
+.TP
+.B \-veryverbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+% dcencap -v -singleitem video_002.src video_002.mpg -of video_002.dcm -ts 1.2.840.10008.1.2.4.100
+.RE
+Using frameSize 304128
+.RE
+Using itemSize 136857600
+.RE
+Doing single item 
+.RE
+Wrote total of 9072492
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Cannot add further attributes after the encapsulated Pixel Data attribute.
+.LP
+Cannot separate concatenated multi-frame compressed data bitsream into separate fragments (e.g., to build a multi-frame JPEG encapsulated encoding).
+
diff --git a/appsrc/dcfile/dcentvfy.cc b/appsrc/dcfile/dcentvfy.cc
new file mode 100644
index 0000000..d4eeb25
--- /dev/null
+++ b/appsrc/dcfile/dcentvfy.cc
@@ -0,0 +1,863 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcentvfy.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+//#include "sopclu.h"
+#include "elmconst.h"
+#include "attrval.h"
+#include "attrseq.h"
+
+#include "iodcomp.h"
+
+#include "hash.h"
+
+static const char *
+getStringValueElseDefault(AttributeList &list,Tag tag,const char *def)
+{
+	Attribute *a=list[tag];
+	if (a && a->getVM() > 0) {
+		return AttributeValue(a);
+	}
+	else {
+		return def;
+	}
+}
+
+class RecordBase {
+protected:
+	RecordBase *sibling;
+	RecordBase *child;
+	const char *primaryKey;
+public:
+	RecordBase(const char *key,RecordBase *nextsib)
+		{
+			primaryKey=key;
+			Assert(primaryKey);
+			
+			child=0;
+			sibling=nextsib;
+		}
+
+	virtual ~RecordBase()
+		{
+			if (child) delete child;
+			if (sibling) delete sibling;
+			if (primaryKey) delete[] primaryKey;
+		}
+
+	const char *getPrimaryKey() { return primaryKey; }
+
+	RecordBase *getSibling()	{ return sibling; }
+	RecordBase *getChild()	{ return child; }
+	
+	void setChild(RecordBase *newchild)
+		{
+			child=newchild;
+		}
+
+	bool matches(const char *key)
+		{
+			Assert(key);
+			Assert(primaryKey);
+			return strcmp(key,primaryKey) == 0 ? true : false;
+		}
+
+	virtual const char *getInformationEntity() = 0;
+};
+
+class InstanceRecord : public RecordBase {
+	const char *filename;
+	AttributeList *list;
+	CompositeIOD *iod;
+public:
+	InstanceRecord(const char *uid,InstanceRecord *nextsib,AttributeList *srclist,const char *name)
+		: RecordBase(uid,nextsib)
+		{
+			list=srclist;
+			Assert(list);
+			filename=name;
+			Assert(filename);
+			iod = selectCompositeIOD(list,NULL);	// this has the side effect of setting the IE for each attribute
+		}
+
+	const char *getInformationEntity() { return "Instance"; }
+	
+	AttributeList *getAttributeList() { return list; }
+	
+	CompositeIOD *getCompositeIOD() { return iod; }
+	
+	const char *getFileName() { return filename; }
+};
+
+class SeriesRecord : public RecordBase {
+public:
+	SeriesRecord(const char *uid,SeriesRecord *nextsib)
+		: RecordBase(uid,nextsib)
+		{
+		}
+
+	const char *getInformationEntity() { return "Series"; }
+};
+
+class StudyRecord : public RecordBase {
+public:
+	StudyRecord(const char *uid,StudyRecord *nextsib)
+		: RecordBase(uid,nextsib)
+		{
+		}
+
+	const char *getInformationEntity() { return "Study"; }
+};
+
+class PatientRecord : public RecordBase {
+public:
+	PatientRecord(const char *patientID,PatientRecord *nextsib)
+		: RecordBase(patientID,nextsib)
+		{
+		}
+
+	const char *getInformationEntity() { return "Patient"; }
+};
+
+static bool singleNumericAttributeValuesAreEqual(Attribute *attr1,Attribute *attr2,Float64 &value1,Float64 &value2,Uint16 i,bool verbose,TextOutputStream& log) {
+	attr1->getValue(i,value1);
+	attr2->getValue(i,value2);
+	if (verbose) log << "diffAttributes(): attr1 value " << dec << (i+1) << " = " << value1 << endl;
+	if (verbose) log << "diffAttributes(): attr2 value " << dec << (i+1) << " = " << value2 << endl;
+	return value1 == value2;
+}
+
+static bool
+diffAttributes(Attribute *attr1,Attribute *attr2,
+	const char *element,const char *ie,const char *filename1,const char *filename2,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict)
+{
+	bool success = true;
+	if (verbose) log << "diffAttributes():" << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">" << endl;
+	Assert(attr1 != attr2);
+	if (attr1 && attr2) {
+		const char *vr1 = attr1->getVR();
+		const char *vr2 = attr1->getVR();
+		if (!attr1->isUnknown() && !attr2->isUnknown() && strcmp(vr1,vr2) != 0) {
+			log << EMsgDC(DifferentValueRepresentationInOneInstanceComparedToTheOther)
+				<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+				<< " - " << MMsgDC(ValueRepresentation) << " "
+				<< " " << vr1 << " versus " << vr2
+				<< endl;
+			success = false;
+		}
+		int vm1 = attr1->getVM();
+		if (verbose) log << "diffAttributes(): vm1 = " << dec << vm1 << endl;
+		int vm2 = attr2->getVM();
+		if (verbose) log << "diffAttributes(): vm2 = " << dec << vm2 << endl;
+		if (vm1 == vm2) {
+			for (Uint16 i=0; i<vm1; ++i) {
+				if (attr1->isString() && attr2->isString()) {
+					char *value1;
+					char *value2;
+					attr1->getValue(i,value1);
+					attr2->getValue(i,value2);
+					if (verbose) log << "diffAttributes(): attr1 value " << dec << (i+1) << " = " << value1 << endl;
+					if (verbose) log << "diffAttributes(): attr2 value " << dec << (i+1) << " = " << value2 << endl;
+					if (value1 && value2) {
+						if (strcmp(value1,value2) != 0) {
+							if (attr1->isNumeric() && attr2->isNumeric()
+							 || (strcmp(vr1,"TM") == 0 &&  strcmp(vr2,"TM") == 0)) {
+								Float64 fvalue1;
+								Float64 fvalue2;
+								if (singleNumericAttributeValuesAreEqual(attr1,attr2,fvalue1,fvalue2,i,verbose,log)) {
+									log << WMsgDC(NumericStringAttributeHasEqualValueButDifferentEncodingInOneInstanceComparedToTheOther)
+										<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+										<< " " << MMsgDC(Value) << " " << dec << (i+1)
+										<< " <" << value1 << "> [" << fvalue1 << "] versus <" << value2 << "> [" << fvalue2 << "]"
+										<< endl;
+								}
+								else {
+									log << EMsgDC(NumericStringAttributeHasDifferentValueInOneInstanceComparedToTheOther)
+										<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+										<< " " << MMsgDC(Value) << " " << dec << (i+1)
+										<< " <" << value1 << "> versus <" << value2 << ">"
+										<< endl;
+									success = false;
+								}
+							}
+							else {
+								log << EMsgDC(StringAttributeHasDifferentValueInOneInstanceComparedToTheOther)
+									<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+									<< " " << MMsgDC(Value) << " " << dec << (i+1)
+									<< " <" << value1 << "> versus <" << value2 << ">"
+									<< endl;
+								success = false;
+							}
+						}
+					}
+					else if (value1 || value2) {
+						log << WMsgDC(ValuePresentInOneInstanceButNotTheOther)
+							<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+							<< " " << MMsgDC(Value) << " " << dec << (i+1)
+							<< endl;
+					}
+					// else OK ... both null
+				}
+				else if (attr1->isNumeric() && attr2->isNumeric()) {
+					Float64 value1;
+					Float64 value2;
+					if (!singleNumericAttributeValuesAreEqual(attr1,attr2,value1,value2,i,verbose,log)) {
+						log << EMsgDC(NumericAttributeHasDifferentValueInOneInstanceComparedToTheOther)
+							<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+							<< " " << MMsgDC(Value) << " " << dec << (i+1)
+							<< " <" << value1 << "> versus <" << value2 << ">"
+							<< endl;
+						success = false;
+					}
+				}
+				// else do not attempt to compare
+			}
+		}
+		else {
+			if (vm1 == 0 || vm2 == 0) {
+				log << WMsgDC(MissingValueInOneInstanceComparedToTheOtherOKIfType2)
+					<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+					<< endl;
+			}
+			else {
+				log << EMsgDC(AttributeHasDifferentValueMultiplicityInOneInstanceComparedToTheOther)
+					<< " - " << dec << vm1 << " versus " << vm2
+					<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+					<< endl;
+				success = false;
+			}
+		}
+	}
+	else if (attr1 || attr2) {
+		log << WMsgDC(AttributePresentInOneInstanceButNotTheOther) << " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">" << endl;
+	}
+	// else OK ... both empty
+	return success;
+}
+
+const char *getElementName(Tag t,ElementDictionary *dict) {
+	return  (t.isPrivateGroup() ? "--private--" : dict->getKeyword(t));
+}
+
+bool
+compareInformationEntitiesOfAttributeLists(AttributeList *list1,AttributeList *list2,const char *ie,const char *filename1,const char *filename2,bool verbose,TextOutputStream &log,ElementDictionary *dict) {
+	if (verbose) log << "Comparing attribute lists for IE " << ie << endl;
+	bool success = true;
+	Assert(ie);
+	InformationEntity ieWanted = getInformationEntityFromDescription(ie);
+	Assert(ieWanted != UnknownIE);
+	
+	Assert(list1);
+	Assert(list2);
+	Assert(list1 != list2);
+	AttributeListIterator listi1(*list1);
+	AttributeListIterator listi2(*list2);
+	Attribute *a1 = !listi1 ? listi1() : NULL;
+	Attribute *a2 = !listi2 ? listi2() : NULL;
+	while (a1 && a2) {
+		if (verbose) log << "Comparing attribute lists -- looping" << endl;
+		Tag t1 = a1->getTag();
+		Tag t2 = a2->getTag();
+		if (verbose) { log << "("; writeZeroPaddedHexNumber(log,t1.getGroup(),4); log << ","; writeZeroPaddedHexNumber(log,t1.getElement(),4); log << ") " << endl; }
+		if (verbose) { log << "("; writeZeroPaddedHexNumber(log,t2.getGroup(),4); log << ","; writeZeroPaddedHexNumber(log,t2.getElement(),4); log << ") " << endl; }
+		InformationEntity ie1 = a1->getInformationEntity();
+		InformationEntity ie2 = a2->getInformationEntity();
+		if (verbose) log << "IE1=" << describeInformationEntity(ie1) << endl;
+		if (verbose) log << "IE2=" << describeInformationEntity(ie1) << endl;
+		if (t1 == t2) {
+			if (verbose) log << "Checking attribute isPrivateGroup()" << t1.isPrivateGroup() << endl;
+			const char *element = getElementName(t1,dict);
+			if (verbose) log << "Checking attribute " << element << endl;
+			if (verbose) log << "Checking attribute " << element << " -  IE1=" << describeInformationEntity(ie1) << " versus IE2=" << describeInformationEntity(ie2) << endl;
+			if (ie1 == ieWanted || ie2 == ieWanted) {	// do not need to check for private tag, since there would be no IE information
+				if (verbose) log << "Attribute is candidate this IE " << element << endl;
+				if (ie1 != ie2) {
+					log << WMsgDC(DifferentInformationEntitiesForAttributeInOneInstanceComparedToTheOther)
+						<< " - " << MMsgDC(Element) << "=<" << element << "> "
+						<< MMsgDC(IE) << " <" << describeInformationEntity(ie1) << "> versus <" << describeInformationEntity(ie2)
+						<< "> for file <" << filename1 << "> versus <" << filename2 << ">"
+						<< endl;
+				}
+				else {
+					if (a1->isSequence() || a2->isSequence()) {
+						if (verbose) log << "Checking Sequence Attribute " << element << endl;
+						if (a1->isSequence() && a2->isSequence()) {
+							SequenceAttribute *sa1 = (SequenceAttribute *)a1;
+							SequenceAttribute *sa2 = (SequenceAttribute *)a2;
+							AttributeList **sal1;
+							AttributeList **sal2;
+							int n1 = sa1->getLists(&sal1);
+							int n2 = sa2->getLists(&sal2);
+							if (n1 == n2) {
+								if (n1 > 0) {
+									for (int item=0; item <n1; ++item) {
+										if (verbose) log << "Checking Sequence Attribute " << element << " item " << dec << (item+1) << endl;
+										AttributeList *l1 = sal1[item];
+										AttributeList *l2 = sal2[item];
+										bool ourSucess = compareInformationEntitiesOfAttributeLists(l1,l2,ie,filename1,filename2,verbose,log,dict);
+										if (!ourSucess) success = false;
+									}
+								}
+							}
+							else {
+								log << EMsgDC(SequenceHasDifferentNumberOfItemsInOneInstanceComparedToTheOther)
+									<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+									<< " - " << n1 << " versus " << n2
+									<< endl;
+								success = false;
+							}
+						}
+						else {
+							log << EMsgDC(SequenceHasDifferentValueRepresentationInOneInstanceComparedToTheOther)
+								<< " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">"
+								<< " - " << MMsgDC(ValueRepresentation) << " "
+								<< " " << a1->getVR() << " versus " << a2->getVR()
+								<< endl;
+							success = false;
+						}
+					}
+					else {
+						bool ourSucess = diffAttributes(a1,a2,element,ie,filename1,filename2,verbose,log,dict);
+						if (!ourSucess) success = false;
+					}
+				}
+			}
+			else {
+				if (verbose) log << "Ignoring Attribute in both lists but not for wanted IE " << element << endl;
+			}
+			++listi1; a1 = !listi1 ? listi1() : NULL;
+			++listi2; a2 = !listi2 ? listi2() : NULL;
+		}
+		else if (t1 < t2) {
+			const char *element = getElementName(t1,dict);
+			if (ie1 == ieWanted) {	// do not need to check for private tag, since there would be no IE information
+				log << WMsgDC(AttributePresentInOneInstanceButNotTheOther) << " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">" << endl;
+			}
+			else {
+				if (verbose) log << "Ignoring Attribute present only in first list not for wanted IE " << element << endl;
+			}
+			++listi1; a1 = !listi1 ? listi1() : NULL;
+		}
+		else if (t1 > t2) {
+			const char *element = getElementName(t2,dict);
+			if (ie2 == ieWanted) {	// do not need to check for private tag, since there would be no IE information
+				log << WMsgDC(AttributePresentInOneInstanceButNotTheOther) << " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">" << endl;
+			}
+			else {
+				if (verbose) log << "Ignoring Attribute present only in second list not for wanted IE " << element << endl;
+			}
+			++listi2; a2 = !listi2 ? listi2() : NULL;
+		}
+		else {
+			Assert(0);
+		}
+	}
+	while (a1) {
+		if (verbose) log << "Checking residual attributes in first attribute list -- looping" << endl;
+		Tag t1 = a1->getTag();
+		InformationEntity ie1 = a1->getInformationEntity();
+		const char *element = getElementName(t1,dict);
+		if (verbose) log << "Checking residual attributes in first attribute list -- have element " << element << endl;
+		if (ie1 == ieWanted) {
+			log << WMsgDC(AttributePresentInOneInstanceButNotTheOther) << " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">" << endl;
+		}
+		++listi1; a1 = !listi1 ? listi1() : NULL;
+	}
+	while (a2) {
+		if (verbose) log << "Checking residual attributes in second attribute list -- looping" << endl;
+		Tag t2 = a2->getTag();
+		InformationEntity ie2 = a2->getInformationEntity();
+		const char *element = getElementName(t2,dict);
+		if (verbose) log << "Checking residual attributes in second attribute list -- have element " << element << endl;
+		if (ie2 == ieWanted) {
+			log << WMsgDC(AttributePresentInOneInstanceButNotTheOther) << " - " << MMsgDC(Element) << "=<" << element << "> " << MMsgDC(IE) << "=<" << ie << "> for file <" << filename1 << "> versus <" << filename2 << ">" << endl;
+		}
+		++listi2; a2 = !listi2 ? listi2() : NULL;
+	}
+	if (verbose) log << "Done comparing attribute lists for IE " << ie << endl;
+	return success;
+}
+
+bool
+compareAllDeepestChildrenOfCurrentRecord(RecordBase *record,InstanceRecord *&compareWith,const char *ie,bool verbose,bool veryverbose,TextOutputStream &log) {
+	bool success = true;
+	RecordBase *child = record->getChild();
+	if (child) {
+		while (child) {
+			bool ourSucess = compareAllDeepestChildrenOfCurrentRecord(child,compareWith,ie,verbose,veryverbose,log);
+			if (!ourSucess) success = false;
+			child = child->getSibling();
+		}
+	}
+	else {
+		//if (veryverbose) log << "Comparing: record.getInformationEntity() " << record->getInformationEntity() << endl;
+		Assert(strcmp(record->getInformationEntity(),"Instance") == 0);
+		// no child ... we assume all leaves are instances (since they could not be created otherwise)
+		InstanceRecord *testInstance = (InstanceRecord *)record;
+		AttributeList *list = testInstance->getAttributeList();
+		Assert(list);
+		ElementDictionary *dict = list->getDictionary();
+		Assert(dict);
+		if (compareWith) {
+			if (verbose) log << "Comparing " << compareWith->getFileName() << " with " << testInstance->getFileName() << " for IE " << ie << endl;
+			if (verbose) log << "Comparing primary key " << testInstance->getPrimaryKey() << endl;
+			bool ourSucess = compareInformationEntitiesOfAttributeLists(list,compareWith->getAttributeList(),ie,testInstance->getFileName(),compareWith->getFileName(),veryverbose,log,dict);
+			if (!ourSucess) success = false;
+		}
+		else {
+			compareWith = testInstance;
+			if (verbose) log << "Choosing basis for comparison to be " << compareWith->getFileName() << " for IE " << ie << endl;
+			if (verbose) log << "Choosing basis for comparison primary key " << testInstance->getPrimaryKey() << endl;
+		}
+	}
+	return success;
+}
+
+bool checkNonLeafRecordAndChilden(RecordBase *record,bool verbose,bool veryverbose,TextOutputStream &log) {
+	bool success = true;
+	RecordBase *child = record->getChild();
+	if (child) {
+		InstanceRecord *compareWith = NULL;
+		const char *ie = record->getInformationEntity();
+		Assert(ie);
+		const char *key = record->getPrimaryKey();
+		Assert(ie);
+		if (verbose) log << "Checking IE " << ie << " identified by " << key << endl;
+		bool ourSucess = compareAllDeepestChildrenOfCurrentRecord(record,compareWith,ie,verbose,veryverbose,log);
+		if (!ourSucess) success = false;
+		while (child) {
+			bool ourSucess = checkNonLeafRecordAndChilden(child,verbose,veryverbose,log);
+			if (!ourSucess) success = false;
+			child = child->getSibling();
+		}
+	}
+	// else do not check leaf records themselves (i.e., instances)
+	return success;
+}
+
+bool
+checkAllRecords(RecordBase *record,bool verbose,bool veryverbose,TextOutputStream &log) {
+	bool success = true;
+	while (record) {
+		bool ourSucess = checkNonLeafRecordAndChilden(record,verbose,veryverbose,log);
+		if (!ourSucess) success = false;
+		record = record->getSibling();
+	}
+	return success;
+}
+
+// This hash table stuff was based on elmhash.h, but differs in that value is string, not an index number
+//
+// ********************* stuff for StringByString *********************
+
+class StringEntryString {
+	HashKeyString key;
+	const char *value;
+public:
+	StringEntryString(void)		{}
+	StringEntryString(const char *s,const char *v)
+					{ key=HashKeyString(s); value=v; }
+	StringEntryString(StringEntryString *e)
+					{ key=e->key; value=e->value; }
+
+	HashKeyString	getKey(void) const	{ return key; }
+	const char *	getValue(void) const	{ return value; }
+
+	bool operator==(StringEntryString e)
+					{ return key == e.getKey(); }
+};
+
+class StringEntryStringList : public SimpleList<StringEntryString>
+{
+public:
+	~StringEntryStringList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class StringEntryStringListIterator : public SimpleListIterator<StringEntryString>
+{
+public:
+	StringEntryStringListIterator(void)
+		: SimpleListIterator<StringEntryString>() {}
+	StringEntryStringListIterator(StringEntryStringList& list)
+		: SimpleListIterator<StringEntryString>(list) {}
+};
+
+class StringByString : public OpenHashTable <StringEntryString,
+					HashKeyString,
+					StringEntryStringList,
+					StringEntryStringListIterator>
+{
+public:
+	StringByString(unsigned long size)
+		: OpenHashTable<StringEntryString,
+				HashKeyString,
+				StringEntryStringList,
+				StringEntryStringListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long	hash(const HashKeyString &key,unsigned long size)
+		{
+			const unsigned nchars = 10;
+			const unsigned shift  = 4;
+
+			unsigned n=nchars;
+			unsigned long value=0;
+			const char *s=key.getString();
+			while (n-- && *s) {
+				value=(value<<shift)|*s++;
+			}
+			return value%size; 
+		}
+
+	HashKeyString key(const StringEntryString &e)	{ return e.getKey(); }
+	
+	const char * get(const char *key) { StringEntryString *e=operator[](key); return e ? e->getValue() : NULL; }
+};
+
+
+static bool readOneFile(const char *filename,PatientRecord *&headPatient,DicomInputOptions &dicom_input_options,bool success,bool verbose,bool veryverbose,TextOutputStream &log,
+		StringByString &patientIDForSOPInstanceUID,
+		StringByString &studyInstanceUIDForSOPInstanceUID,
+		StringByString &seriesInstanceUIDForSOPInstanceUID,
+		StringByString &patientIDForSeriesInstanceUID,
+		StringByString &studyInstanceUIDForSeriesInstanceUID,
+		StringByString &patientIDForStudyInstanceUID
+	) {
+	Assert(filename);
+	if (verbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+	ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+	ifstream *fstr=new ifstream(filename);
+#endif
+	if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+		cerr << AMsgDC(FileReadOpenFailed);
+		if (filename) cerr <<" - \"" << filename << "\"";
+		return false;
+	}
+
+	DicomInputStream din(*(istream *)fstr,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList *list = new ManagedAttributeList();
+	Assert(list);
+
+	list->read(din,&log,false,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list->good()) {
+		log << list->errors()
+			<< EMsgDC(DatasetReadFailed) << endl;
+		return false;
+	}
+
+	const char *patientID=getStringValueElseDefault(*list,TagFromName(PatientID),"");
+	Assert(patientID);
+
+	PatientRecord *ptrPatient=headPatient;
+	while (ptrPatient && !ptrPatient->matches(patientID)) ptrPatient=(PatientRecord *)ptrPatient->getSibling();
+
+	StudyRecord *headStudy,*ptrStudy;
+	if (ptrPatient) {
+		ptrStudy=headStudy=(StudyRecord *)ptrPatient->getChild();
+	}
+	else {
+		if (verbose) log << filename << " Detected new patient identified by " << patientID << endl;
+		ptrPatient=headPatient=new PatientRecord(patientID,headPatient);
+		ptrStudy=headStudy=0;
+	}
+
+	const char *studyInstanceUID=getStringValueElseDefault(*list,TagFromName(StudyInstanceUID),"");
+	Assert(studyInstanceUID);
+
+	while (ptrStudy && !ptrStudy->matches(studyInstanceUID)) ptrStudy=(StudyRecord *)ptrStudy->getSibling();
+
+	SeriesRecord *headSeries,*ptrSeries;
+	if (ptrStudy) {
+		ptrSeries=headSeries=(SeriesRecord *)ptrStudy->getChild();
+	}
+	else {
+		if (verbose) log << filename << " Detected new study identified by " << studyInstanceUID << endl;
+		ptrStudy=headStudy=new StudyRecord(studyInstanceUID,headStudy);
+		Assert(ptrPatient);
+		ptrPatient->setChild(headStudy);
+		ptrSeries=headSeries=0;
+	}
+
+	const char *seriesInstanceUID=getStringValueElseDefault(*list,TagFromName(SeriesInstanceUID),"");
+	Assert(seriesInstanceUID);
+
+	while (ptrSeries && !ptrSeries->matches(seriesInstanceUID)) ptrSeries=(SeriesRecord *)ptrSeries->getSibling();
+
+	InstanceRecord *headInstance,*ptrInstance;
+	if (ptrSeries) {
+		ptrInstance=headInstance=(InstanceRecord *)ptrSeries->getChild();
+	}
+	else {
+		if (verbose) log << filename << " Detected new series identified by " << seriesInstanceUID << endl;
+		ptrSeries=headSeries=new SeriesRecord(seriesInstanceUID,headSeries);
+		Assert(ptrStudy);
+		ptrStudy->setChild(headSeries);
+		ptrInstance=headInstance=0;
+	}
+
+	const char *sopInstanceUID=getStringValueElseDefault(*list,TagFromName(SOPInstanceUID),"");
+	Assert(sopInstanceUID);
+
+	while (ptrInstance && !ptrInstance->matches(sopInstanceUID)) ptrInstance=(InstanceRecord *)ptrInstance->getSibling();
+
+	if (ptrInstance) {
+		log << EMsgDC(DuplicateSOPInstanceUID) << " - " << sopInstanceUID << " within Series for file <" << filename << "> versus <" << ptrInstance->getFileName() << ">" << endl;
+		success = false;
+	}
+	else {
+		ptrInstance=headInstance=new InstanceRecord(sopInstanceUID,headInstance,list,StrDup(filename));
+		Assert(ptrSeries);
+		ptrSeries->setChild(headInstance);
+
+		if (!ptrInstance->getCompositeIOD()) {
+			const char *sopClassUID=getStringValueElseDefault(*list,TagFromName(SOPClassUID),"");
+			log << WMsgDC(UnrecognizedSOPClass) << " - " << sopClassUID << " - so cannot determine information entity of attributes within file <" << filename << ">" << endl;
+		}
+	}
+
+	{
+		const char *existingPatientID = patientIDForStudyInstanceUID.get(studyInstanceUID);
+		if (existingPatientID) {
+			if (strcmp(existingPatientID,patientID) == 0) {
+				if (verbose) log << "Checked PatientID " << patientID << " for StudyInstanceUID " << studyInstanceUID << " is OK" << endl;
+			}
+			else {
+				log << EMsgDC(DifferentPatientIDForStudyInstanceUID)
+					<< " - " << MMsgDC(StudyInstanceUID) << "=<" << studyInstanceUID << "> " << MMsgDC(PatientID) << "=<" << patientID << "> for file <" << filename << "> versus existing " << MMsgDC(PatientID) << "=<" << existingPatientID << ">"
+					<< endl;
+				success = false;
+			}
+		}
+		else {
+			if (verbose) log << "Set PatientID " << patientID << " for StudyInstanceUID " << studyInstanceUID << endl;
+			patientIDForStudyInstanceUID+=new StringEntryString(studyInstanceUID,patientID);
+		}
+	}
+
+	{
+		const char *existingPatientID = patientIDForSeriesInstanceUID.get(seriesInstanceUID);
+		if (existingPatientID) {
+			if (strcmp(existingPatientID,patientID) == 0) {
+				if (verbose) log << "Checked PatientID " << patientID << " for SeriesInstanceUID " << seriesInstanceUID << " is OK" << endl;
+			}
+			else {
+				log << EMsgDC(DifferentPatientIDForSeriesInstanceUID)
+					<< " - " << MMsgDC(SeriesInstanceUID) << "=<" << seriesInstanceUID << "> " << MMsgDC(PatientID) << "=<" << patientID << "> for file <" << filename << "> versus existing " << MMsgDC(PatientID) << "=<" << existingPatientID << ">"
+					<< endl;
+				success = false;
+			}
+		}
+		else {
+			if (verbose) log << "Set PatientID " << patientID << " for SeriesInstanceUID " << seriesInstanceUID << endl;
+			patientIDForSeriesInstanceUID+=new StringEntryString(seriesInstanceUID,patientID);
+		}
+	}
+	{
+		const char *existingStudyInstanceUID = studyInstanceUIDForSeriesInstanceUID.get(seriesInstanceUID);
+		if (existingStudyInstanceUID) {
+			if (strcmp(existingStudyInstanceUID,studyInstanceUID) == 0) {
+				if (verbose) log << "Checked StudyInstanceUID " << studyInstanceUID << " for SeriesInstanceUID " << seriesInstanceUID << " is OK" << endl;
+			}
+			else {
+				log << EMsgDC(DifferentStudyInstanceUIDForSeriesInstanceUID)
+					<< " - " << MMsgDC(SeriesInstanceUID) << "=<" << seriesInstanceUID << "> " << MMsgDC(StudyInstanceUID) << "=<" << studyInstanceUID << "> for file <" << filename << "> versus existing " << MMsgDC(StudyInstanceUID) << "=<" << existingStudyInstanceUID << ">"
+					<< endl;
+				success = false;
+			}
+		}
+		else {
+			if (verbose) log << "Set StudyInstanceUID " << studyInstanceUID << " for SeriesInstanceUID " << seriesInstanceUID << endl;
+			studyInstanceUIDForSeriesInstanceUID+=new StringEntryString(seriesInstanceUID,studyInstanceUID);
+		}
+	}
+	
+	{
+		const char *existingPatientID = patientIDForSOPInstanceUID.get(sopInstanceUID);
+		if (existingPatientID) {
+			if (strcmp(existingPatientID,patientID) == 0) {
+				if (verbose) log << "Checked PatientID " << patientID << " for SOPInstanceUID " << sopInstanceUID << " is OK" << endl;
+			}
+			else {
+				log << EMsgDC(DifferentPatientIDForSOPInstanceUID)
+					<< " - " << MMsgDC(SOPInstanceUID) << "=<" << sopInstanceUID << "> " << MMsgDC(PatientID) << "=<" << patientID << "> for file <" << filename << "> versus existing " << MMsgDC(PatientID) << "=<" << existingPatientID << ">"
+					<< endl;
+				success = false;
+			}
+		}
+		else {
+			if (verbose) log << "Set PatientID " << patientID << " for SOPInstanceUID " << sopInstanceUID << endl;
+			patientIDForSOPInstanceUID+=new StringEntryString(sopInstanceUID,patientID);
+		}
+	}
+	{
+		const char *existingStudyInstanceUID = studyInstanceUIDForSOPInstanceUID.get(sopInstanceUID);
+		if (existingStudyInstanceUID) {
+			if (strcmp(existingStudyInstanceUID,studyInstanceUID) == 0) {
+				if (verbose) log << "Checked StudyInstanceUID " << studyInstanceUID << " for SOPInstanceUID " << sopInstanceUID << " is OK" << endl;
+			}
+			else {
+				log << EMsgDC(DifferentStudyInstanceUIDForSOPInstanceUID)
+					<< " - " << MMsgDC(SOPInstanceUID) << "=<" << sopInstanceUID << "> " << MMsgDC(StudyInstanceUID) << "=<" << studyInstanceUID << "> for file <" << filename << "> versus existing " << MMsgDC(StudyInstanceUID) << "=<" << existingStudyInstanceUID << ">"
+					<< endl;
+				success = false;
+			}
+		}
+		else {
+			if (verbose) log << "Set StudyInstanceUID " << studyInstanceUID << " for SOPInstanceUID " << sopInstanceUID << endl;
+			studyInstanceUIDForSOPInstanceUID+=new StringEntryString(sopInstanceUID,studyInstanceUID);
+		}
+	}
+	{
+		const char *existingSeriesInstanceUID = seriesInstanceUIDForSOPInstanceUID.get(sopInstanceUID);
+		if (existingSeriesInstanceUID) {
+			if (strcmp(existingSeriesInstanceUID,seriesInstanceUID) == 0) {
+				if (verbose) log << "Checked SeriesInstanceUID " << seriesInstanceUID << " for SOPInstanceUID " << sopInstanceUID << " is OK" << endl;
+			}
+			else {
+				log << EMsgDC(DifferentSeriesInstanceUIDForSOPInstanceUID)
+					<< " - " << MMsgDC(SOPInstanceUID) << "=<" << sopInstanceUID << "> " << MMsgDC(SeriesInstanceUID) << "=<" << seriesInstanceUID << "> for file <" << filename << "> versus existing " << MMsgDC(SeriesInstanceUID) << "=<" << existingSeriesInstanceUID << ">"
+					<< endl;
+				success = false;
+			}
+		}
+		else {
+			if (verbose) log << "Set SeriesInstanceUID " << seriesInstanceUID << " for SOPInstanceUID " << sopInstanceUID << endl;
+			seriesInstanceUIDForSOPInstanceUID+=new StringEntryString(sopInstanceUID,seriesInstanceUID);
+		}
+	}
+
+	if (verbose) log << filename << " Done processing file for SOPInstanceUID " << sopInstanceUID << endl;
+	if (fstr) {
+		fstr->close();
+		delete fstr;
+	}
+	return success;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	if (veryverbose) verbose=true;
+	
+	bool bad=false;
+
+	dicom_input_options.done();
+	
+	const char *filelistfile=0;
+	(void)(options.get("filelist",filelistfile) || options.get("f",filelistfile));
+
+	int numberofinputfiles=!options;
+
+
+	const char **listoffilenames = new const char * [numberofinputfiles];
+	const char **ptr = listoffilenames;
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		*ptr++=filename;
+	}
+
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose]"
+			<< " [-f|-filelist filename]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< endl;
+		return 1;
+	}
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	PatientRecord *headPatient = NULL;
+
+	StringByString patientIDForSOPInstanceUID(1000);
+	StringByString studyInstanceUIDForSOPInstanceUID(1000);
+	StringByString seriesInstanceUIDForSOPInstanceUID(1000);
+
+	StringByString patientIDForSeriesInstanceUID(100);
+	StringByString studyInstanceUIDForSeriesInstanceUID(100);
+
+	StringByString patientIDForStudyInstanceUID(100);
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		bool thisFileSucceeded = readOneFile(listoffilenames[i],headPatient,dicom_input_options,success,verbose,veryverbose,log,
+			patientIDForSOPInstanceUID,studyInstanceUIDForSOPInstanceUID,seriesInstanceUIDForSOPInstanceUID,patientIDForSeriesInstanceUID,studyInstanceUIDForSeriesInstanceUID,patientIDForStudyInstanceUID);
+		if (!thisFileSucceeded) success=false;
+	}
+
+	if (filelistfile) {
+		ifstream *flfstr=new ifstream(filelistfile);
+		if (!flfstr || !*flfstr || !flfstr->rdbuf()->is_open()) {
+			log << AMsgDC(FileReadOpenFailed);
+			if (filelistfile) log <<" - \"" << filename << "\"";
+			log << endl;
+			bad=true;
+		}
+		else {
+			while (flfstr->peek() != istream::traits_type::eof()) {
+				const int lineBufferSize=2048;
+				char lineBuffer[lineBufferSize];
+				flfstr->getline(lineBuffer,2048);
+				if (strlen(lineBuffer)) {
+					bool thisFileSucceeded = readOneFile(lineBuffer,headPatient,dicom_input_options,success,verbose,veryverbose,log,
+						patientIDForSOPInstanceUID,studyInstanceUIDForSOPInstanceUID,seriesInstanceUIDForSOPInstanceUID,patientIDForSeriesInstanceUID,studyInstanceUIDForSeriesInstanceUID,patientIDForStudyInstanceUID);
+					if (!thisFileSucceeded) success=false;
+				}
+				// else skip blank lines
+			}
+		}
+	}
+	
+	//if (success) {
+	{
+		bool successfulCheck = checkAllRecords(headPatient,verbose,veryverbose,log);
+		if (!successfulCheck) success=false;
+	}
+	//}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcentvfy.man b/appsrc/dcfile/dcentvfy.man
new file mode 100644
index 0000000..29e52a9
--- /dev/null
+++ b/appsrc/dcfile/dcentvfy.man
@@ -0,0 +1,58 @@
+.TH DCENTVFY 1 "7 December 2015" "DICOM PS3" "DICOM PS3 - Validate DICOM entities"
+.SH NAME
+dcentvfy \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Validate DICOM entities
+.SH SYNOPSIS
+.HP 10
+.B dcentvfy
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+[
+.B \-v|verbose|vv|veryverbose
+]
+[
+.B \-f|-filelist " filename"
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcentvfy
+reads the named dicom files (and/or the files listed in the specified
+file), extracts patient, study, series and instance entity unique identifiers
+and then validates that the attribute values defined in the standard
+for those entities have consistent values for the same entity, and that
+identifiers of subordinate entries are not reused for different parent
+entities.
+.SH OPTIONS
+The description and verbose output go to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-v|verbose
+.RS
+Describe as files are read and analyzed and the model of entity relationships to instances is built.
+.RE
+.TP
+.B \-vv|veryverbose
+.RS
+Describe the detailed behavior of comparison of each attribute for each entity for each instance.
+.RE
+.TP
+.B \-f|filelist filename
+.RS
+A file containing a list of DICOM input files (one filename per line).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dciodvfy(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcfile.cc b/appsrc/dcfile/dcfile.cc
new file mode 100644
index 0000000..77109b5
--- /dev/null
+++ b/appsrc/dcfile/dcfile.cc
@@ -0,0 +1,198 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcfile.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "dcstream.h"
+#include "attr.h"
+#include "attrnew.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "transynd.h"
+
+static TransferSyntax *
+readMetaHeaderTillTransferSyntax(DicomInputStream &stream)
+{
+	Uint32 n=0;
+	Uint32 length=0xffffffff;
+	while (stream.peek() != istream::traits_type::eof() && (length == 0xffffffff || n < length)) {
+		Tag tag;
+		stream >> tag;
+		if (stream.fail()) {
+			cerr << EMsgDC(TagReadFailed) << endl;
+			return NULL;
+		}
+		n+=4;
+
+		char vr[3];
+		if (stream.getTransferSyntaxInUse()->isExplicitVR()) {
+			stream.read(vr,2);
+			if (stream.fail()) {
+				cerr << EMsgDC(VRReadFailed) << endl;
+				return NULL;
+			}
+			n+=2;
+			vr[2]=0;
+		}
+		else {
+			vr[0]=0;
+		}
+
+		Uint32 vl;
+		if (!stream.getTransferSyntaxInUse()->isExplicitVR()) {
+			stream >> vl;
+			n+=4;
+		}
+		else if (isLongValueLengthInExplicitValueRepresentation(vr)) {
+			(void)stream.read16();	// "Reserved"
+			stream >> vl;
+			n+=6;
+		}
+		else {
+			vl=stream.read16();
+			n+=2;
+		}
+		if (stream.fail()) {
+			cerr << EMsgDC(VLReadFailed) << endl;
+			return NULL;
+		}
+
+		if (tag == TagFromName(FileMetaInformationGroupLength)) {
+			if (vl == 4) {
+				length=stream.read32();
+				n+=vl;
+			}
+			else {
+				cerr << EMsgDC(UnexpectedVL) << endl;
+				return NULL;
+			}
+		}
+		else if (tag == TagFromName(TransferSyntaxUID)) {
+			if (!stream.getTransferSyntaxInUse()->isExplicitVR()) {
+				vr[0]='U'; vr[1]='I'; vr[2]=0;
+			}
+			Attribute *a=newAttribute(vr,tag);
+			if (a) {
+				a->read(stream,vl);
+				if (stream.fail()) {
+					cerr << EMsgDC(VLReadFailed) << endl;
+					return NULL;
+				}
+				else {
+					n+=vl;
+					TransferSyntax *dts=new TransferSyntax(AttributeValue(a));
+					Assert(dts);
+					return dts;
+				}
+			}
+			else {
+				cerr << EMsgDC(UnrecognizedVR) << endl;
+				return NULL;
+			}
+		}
+		else if (!tag.isMetaheaderGroup()) {
+			cerr << EMsgDC(PrematureEndOfMetaHeader) << endl;
+			return NULL;
+		}
+		else if (vl == 0xffffffff) {
+			cerr << EMsgDC(UnexpectedVL) << endl;
+			return NULL;
+		}
+		else {
+			stream.seekg(vl,ios::cur);
+			if (stream.fail()) {
+				cerr << EMsgDC(SeekFailed) << endl;
+				return NULL;
+			}
+			n+=vl;
+		}
+	}
+	cerr << EMsgDC(PrematureEndOfMetaHeader) << endl;
+	return NULL;
+}
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool brief=options.get("brief") || options.get("b");
+	bool showfilename=options.get("filename");
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-b|-brief]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	bool success;
+
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (din.haveMetaHeader()) {
+		TransferSyntax *mts=din.getTransferSyntaxToReadMetaHeader();
+		if (mts) {
+			if (!brief) {
+				dumpTransferSyntax(mts,"Meta: ");
+			}
+			TransferSyntax *dts = readMetaHeaderTillTransferSyntax(din);
+			if (dts) {
+				if (brief) {
+					cerr << "DICOM file, with metaheader, " << dts->getDescription() << endl;	// do not worry if mts is not EVRLE
+				}
+				else {
+					dumpTransferSyntax(dts,"Data: ");
+				}
+				success = true;
+			}
+			else {
+				success=false;
+			}
+		}
+		else
+			success=false;
+	}
+	else {
+		TransferSyntax *dts=din.getTransferSyntaxToReadDataSet();
+		if (dts) {
+			if (brief) {
+				cerr << "DICOM file, no metaheader, " << dts->getDescription() << endl;
+			}
+			else {
+				dumpTransferSyntax(dts,"Data: ");
+			}
+		}
+		if (din.isSwapped32Big() && !brief) {
+			cerr << "Data: Swapped32Big\tYes" << endl;
+		}
+		success=true;
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcfile.man b/appsrc/dcfile/dcfile.man
new file mode 100755
index 0000000..4e6fdd6
--- /dev/null
+++ b/appsrc/dcfile/dcfile.man
@@ -0,0 +1,134 @@
+.TH DCFILE 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Describe DICOM file content"
+.SH NAME
+dcfile \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Describe DICOM file content
+.SH SYNOPSIS
+.HP 10
+.B dcfile
+.so man1/gen.so
+[
+.B \-b|brief
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcfile
+reads the named dicom or acr-nema input file and describes the encoding
+method of the file, ie. what transfer syntax is in use, and whether or
+not a Part 10 style meta-information header is present.
+.SH OPTIONS
+The description goes to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-b|brief
+.RS
+Display a single line brief summary.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcfile dicomdir.
+.RE
+Meta: UID               1.2.840.10008.1.2.1
+.RE
+Meta: Description       "Explicit VR Little Endian"
+.RE
+Meta: ByteOrder Little
+.RE
+Meta: VR                Explicit
+.RE
+Meta: Encapsulated      No
+.RE
+Data: UID               1.2.840.10008.1.2.1
+.RE
+Data: Description       "Explicit VR Little Endian"
+.RE
+Data: ByteOrder Little
+.RE
+Data: VR                Explicit
+.RE
+Data: Encapsulated      No
+.RE
+\ 
+.RE
+% dcfile expmeta.dc3
+.RE
+Meta: UID               1.2.840.10008.1.2.1
+.RE
+Meta: Description       "Explicit VR Little Endian"
+.RE
+Meta: ByteOrder Little
+.RE
+Meta: VR                Explicit
+.RE
+Meta: Encapsulated      No
+.RE
+Data: UID               1.2.840.10008.1.2
+.RE
+Data: Description       "Implicit VR Little Endian"
+.RE
+Data: ByteOrder Little
+.RE
+Data: VR                Implicit
+.RE
+Data: Encapsulated      No
+.RE
+\ 
+.RE
+% dcfile NM.1
+.RE
+Data: UID               1.2.840.10008.1.2
+.RE
+Data: Description       "Implicit VR Little Endian"
+.RE
+Data: ByteOrder Little
+.RE
+Data: VR                Implicit
+.RE
+Data: Encapsulated      No
+.RE
+\ 
+.RE
+% dcfile test.spi
+.RE
+Data: ByteOrder Big
+.RE
+Data: VR                Implicit
+.RE
+Data: Encapsulated      No
+.RE
+\ 
+.RE
+% dcfile -b evrlewm.dcm
+.RE
+DICOM file, with metaheader, Explicit VR Little Endian
+.RE
+\ 
+.RE
+% dcfile -b evrlenom.dcm
+.RE
+DICOM file, no metaheader, Explicit VR Little Endian
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR file(1) ,
+.BR dcdump(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dchist.cc b/appsrc/dcfile/dchist.cc
new file mode 100644
index 0000000..2e7814c
--- /dev/null
+++ b/appsrc/dcfile/dchist.cc
@@ -0,0 +1,228 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dchist.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static unsigned
+howManySignificantBits(Uint16 test)
+{
+	unsigned bits;
+	for (bits=0; test; test=test>>1,++bits);
+	return bits;
+}
+
+static bool
+dumpImageHistogram(ManagedAttributeList& list,TextOutputStream& log,bool showhist,bool showcsv,bool withHighBits,bool highBitsOnly)
+{
+	bool success;
+
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	Uint16 vBitsStored=AttributeValue(aBitsStored);
+
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	Uint16 vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << EMsgDC(MissingAttribute) << " - \"Rows\"" << endl;
+	Uint16 vRows=AttributeValue(aRows);
+
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << EMsgDC(MissingAttribute) << " - \"Columns\"" << endl;
+	Uint16 vColumns=AttributeValue(aColumns);
+
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	Uint16 vNumberOfFrames=AttributeValue(aNumberOfFrames,1);
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+	if (!aPixelData)
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+
+	if (!aPixelData || !aRows || !aColumns) {
+		success=false;
+	}
+	else {
+		SupplySourceFromAttribute sPixelData(aPixelData,withHighBits || highBitsOnly);
+		class SourceBase<Uint16> *source = sPixelData.getSource();
+		if (!source) {
+			log << EMsgDC(BadAttributeValue)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+		else {
+			int bitsUsed;
+			Uint16 maskLowBits = 0;
+			if (withHighBits) {
+				bitsUsed = vBitsAllocated;
+			}
+			else if (highBitsOnly) {
+				bitsUsed = vBitsAllocated;
+				int i;
+				for (i=0; i<vBitsStored; ++i) {
+					maskLowBits = (maskLowBits<<1) | 1;
+				}
+			}
+			else {
+				bitsUsed = vBitsStored;
+			}
+			maskLowBits = (~maskLowBits)&0xffff;
+			Uint32 largestsymbolplusone = ((Uint32)1) << (bitsUsed ? bitsUsed : 16);
+			Uint32 *histogram = new Uint32[largestsymbolplusone];
+			Assert(histogram);
+			{
+				Uint32 i;
+				Uint32 *histptr;
+				for (i=0,histptr=histogram; i<largestsymbolplusone; ++i) *histptr++=0;
+			}
+			Uint32 count=0;
+			Uint16 smallestsymbol=0xffff;
+			Uint16 largestsymbol=0;
+
+			unsigned row=0;
+			unsigned column=0;
+			while (row < vRows*vNumberOfFrames && source->read()) {
+				size_t n=source->getBufferCount();
+				Assert(n);
+				const Uint16 *buffer=source->getBuffer();
+				Assert(buffer);
+				while (n-- && row < vRows*vNumberOfFrames) {
+					Uint16 symbol=*buffer++;
+					symbol = symbol & maskLowBits;
+
+					Assert(symbol<largestsymbolplusone);
+					Assert(histogram[symbol] < 0xffffffff);
+					++histogram[symbol];
+					++count;
+
+					if (symbol < smallestsymbol) smallestsymbol=symbol;
+					if (symbol > largestsymbol) largestsymbol=symbol;
+
+					if (++column >= vColumns) {
+						column=0;
+						++row;
+					}
+				}
+			}
+			//Assert(column == 0 && row == vRows*vNumberOfFrames);
+
+			Assert(count == vColumns*vRows*vNumberOfFrames);
+			Assert(count);
+
+			double entropy;
+			{
+				Uint32 i;
+				Uint32 *histptr;
+				for (i=smallestsymbol,histptr=histogram+smallestsymbol,entropy=0; i<=largestsymbol; ++i,++histptr) {
+					if (*histptr) {
+						double probsymbol=double(*histptr)/count;
+						double contributes=-probsymbol*ourlog2(probsymbol);
+						entropy+=contributes;
+						if (showhist) {
+							log << "[" << hex << i << "]\t"
+							    << dec << *histptr << "\t"
+							    << "p=" << dec << probsymbol << "\t"
+							    << "e=" << dec << contributes << "\t"
+							    << "cum=" << dec << entropy << endl;
+						}
+						if (showcsv) {
+							log << dec << i << "," << *histptr << endl;
+						}
+					}
+				}
+			}
+
+			if (showhist) log << endl;
+
+			if (!showcsv) {
+				log << dec << entropy << "\tZero order entropy (bits per pixel)" << endl;
+				log << hex << smallestsymbol << "\tSmallest symbol value" << endl;
+				log << dec << howManySignificantBits(smallestsymbol) << "\tSmallest symbol length (bits)" << endl;
+				log << hex << largestsymbol << "\tLargest symbol value" << endl;
+				int mostSignificantBits = howManySignificantBits(largestsymbol);
+				log << dec << mostSignificantBits << "\tLargest symbol length (bits)" << endl;
+				if (mostSignificantBits > vBitsStored) {
+					log << "ALERT\tEmbedded overlay bits or sign extension bits present above Bits Stored" << endl;
+				}
+			}
+			
+			success=true;
+		}
+	}
+	return success;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool showfilename=options.get("filename");
+	bool showhist=options.get("histogram") || options.get("h");
+	bool showcsv=options.get("csv");
+	bool withHighBits=options.get("withhighbits");
+	bool highBitsOnly=options.get("highbitsonly");
+	
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-h|-histogram]"
+			<< " [-csv]"
+			<< " [-v|-verbose]"
+			<< " [-withhighbits|-highbitsonly]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		log << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		success=dumpImageHistogram(list,log,showhist,showcsv,withHighBits,highBitsOnly);
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dchist.man b/appsrc/dcfile/dchist.man
new file mode 100755
index 0000000..ae641d6
--- /dev/null
+++ b/appsrc/dcfile/dchist.man
@@ -0,0 +1,117 @@
+.TH DCHIST 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM image statistics"
+.SH NAME
+dchist \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM image statistics
+.SH SYNOPSIS
+.HP 10
+.B dchist
+.so man1/gen.so
+[
+.B \-h|histogram
+]
+[
+.B \-csv
+]
+[
+.B \-withhighbits|highbitsonly
+]
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dchist
+reads the named dicom or acr-nema input file and describes the statistics
+of the image pixel data. The primary intent is to determine the zero
+order entropy of the image.
+.LP
+The description and verbose output go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-h|histogram
+.RS
+Display table of pixel value, frequency, probability, contribution to zero order entropy, and cumulative zero order entropy. May generate a LOT of output !
+.RE
+.TP
+.B \-csv
+.RS
+Display only a comma separated value pair of pixel value and frequency, one line per value, e.g., for import into a statistical program or spreadsheet
+.RE
+.TP
+.B \-withhighbits
+.RS
+Include as well the values that are above Bits Stored and within Bits Allocated, such as might be overlay bits
+(regardless of whether or not there are any 60xx group elements).
+.RE
+.TP
+.B \-highbitsonly
+.RS
+Use instead the values that are above Bits Stored and within Bits Allocated, such as might be overlay bits,
+and treat all valid pixel values below Bits Stored inclusive as zero
+(regardless of whether or not there are any 60xx group elements).
+.RE
+.TP
+.B \-v|verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dchist expmeta.dc3
+.RE
+9.02366 Zero order entropy (bits per pixel)
+.RE
+0x0     Smallest symbol value
+.RE
+0       Smallest symbol length (bits)
+.RE
+0x6e9   Largest symbol value
+.RE
+11      Largest symbol length (bits)
+.RE
+\ 
+.RE
+% dchist -h expmeta.dc3
+.RE
+[0x0]   392 p=0.00598145  e=0.0441747   cum=0.0441747
+.RE
+ ...
+.RE
+[0x6e9] 1   p=1.52588e-05 e=0.000244141 cum=9.02366
+.RE
+\ 
+.RE
+9.02366 Zero order entropy (bits per pixel)
+.RE
+0x0     Smallest symbol value
+.RE
+0       Smallest symbol length (bits)
+.RE
+0x6e9   Largest symbol value
+.RE
+11      Largest symbol length (bits)
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcstats(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcinflate.man b/appsrc/dcfile/dcinflate.man
new file mode 100755
index 0000000..db1352e
--- /dev/null
+++ b/appsrc/dcfile/dcinflate.man
@@ -0,0 +1,31 @@
+.TH DCINFLATE 1 "17 Dec 2000" "DICOM PS3" "DICOM PS3 - Decompress deflated DICOM file"
+.SH NAME
+dcinflate \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Decompress deflated DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcinflate "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcinflate
+reads the named dicom or acr-nema input file that is compressed using the deflate
+transfer syntax, and copies the information and pixel data to a new dicom file,
+in the explicit VR little endian uncompressed transfer syntax with a meta information
+header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcdeflate(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcinflate.script b/appsrc/dcfile/dcinflate.script
new file mode 100755
index 0000000..fc0c6c6
--- /dev/null
+++ b/appsrc/dcfile/dcinflate.script
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# usage: dcinflate infile outfile
+#
+#
+TMPROOT=/tmp/`basename $0`.$$
+
+DCCP=dccp
+DCRMMETA=dcrmmeta
+GZIP=gzip
+
+$DCRMMETA $1 $TMPROOT.1.tmp
+$GZIP -d -x < $TMPROOT.1.tmp > $TMPROOT.2.tmp
+rm -f $TMPROOT.1.tmp
+$DCCP $TMPROOT.2.tmp $2
+rm -f $TMPROOT.2.tmp
+
diff --git a/appsrc/dcfile/dciodvfy.cc b/appsrc/dcfile/dciodvfy.cc
new file mode 100644
index 0000000..0dfc5a3
--- /dev/null
+++ b/appsrc/dcfile/dciodvfy.cc
@@ -0,0 +1,2250 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dciodvfy.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "sopclu.h"
+#include "elmconst.h"
+#include "attrval.h"
+#include "attrseq.h"
+
+#include "iodcomp.h"
+
+// Similar to TextOutputStream& Tag::write(TextOutputStream& stream,ElementDictionary *dict) in libsrc/src/dctool/attrtag.cc
+// but without the VR
+
+static void writeTagNumberAndNameToLog(Tag tag,ElementDictionary *dict,TextOutputStream &log) {
+	log << "(";
+	writeZeroPaddedHexNumber(log,tag.getGroup(),4);
+	log << ",";
+	writeZeroPaddedHexNumber(log,tag.getElement(),4);
+	log << ")";
+	const char *desc = NULL;
+	if (dict) {
+		desc = dict->getDescription(tag);
+	}
+	if (desc && strlen(desc) > 0 && strcmp(desc,"?") != 0) {
+		log << " " << desc;
+	}
+}
+
+static void writeTagNumberAndNameToLog(Attribute *a,ElementDictionary *dict,TextOutputStream &log) {
+	writeTagNumberAndNameToLog(a->getTag(),dict,log);
+}
+
+// loopOverListsInSequencesWithLog is copied from libsrc/src/dctool/attrmxls.cc
+
+static bool
+loopOverListsInSequencesWithLog(Attribute *a,TextOutputStream &log,
+		bool (*func)(AttributeList &,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+loopOverListsInSequencesWithRootListAndLog(AttributeList &rootlist,Attribute *a,TextOutputStream &log,
+		bool (*func)(AttributeList &,AttributeList &,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(rootlist,*al[i],log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool checkScaledNumericValues(Tag coarseTag,const char *coarseName,Tag fineTag,const char *fineName,double scaleFactor,AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	Attribute *aCoarse=list[coarseTag];
+	Attribute *aFine=list[fineTag];
+	if (aCoarse && aFine) {
+		Uint16 coarseValue = 0;
+		Float64 fineValue = 0;		// Uint16 would be OK if was always IS, but sometimes fine values are DS and not IS, and Uint16 may be too small
+		if (aCoarse->getValue(0,coarseValue) && aFine->getValue(0,fineValue)) {
+			if (coarseValue != Uint16(round(fineValue/scaleFactor)) && coarseValue != Uint16(fineValue/scaleFactor)) {		// NB. standard does not specify whether or not to round or truncate, so allow both
+				log << EMsgDC(ScaledNumericValuesForSameConceptAreInconsistent) << " - " << coarseName << " = " << coarseValue << " and " << fineName << " = " << fineValue << endl;
+				success=false;
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkScaledNumericValues(AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	if (!checkScaledNumericValues(TagFromName(Exposure),"Exposure",TagFromName(ExposureInuAs),"ExposureInuAs",1000.0,list,log)) success = false;
+	if (!checkScaledNumericValues(TagFromName(ExposureTime),"ExposureTime",TagFromName(ExposureTimeInuS),"ExposureTimeInuS",1000.0,list,log)) success = false;
+	if (!checkScaledNumericValues(TagFromName(XRayTubeCurrent),"XRayTubeCurrent",TagFromName(XRayTubeCurrentInuA),"XRayTubeCurrentInuA",1000.0,list,log)) success = false;
+
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkScaledNumericValues)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkPatientOrientationValuesForBiped(AttributeList &list,TextOutputStream &log) {
+//log << "checkPatientOrientationValuesForBiped" << endl;
+	bool success=true;
+	Attribute *aPatientOrientation=list[TagFromName(PatientOrientation)];
+	if (aPatientOrientation) {
+		int nValues = aPatientOrientation->getVM();
+		const char *firstValue = NULL;
+		for (int i=0; i<nValues; ++i) {
+			char *value;
+			if (aPatientOrientation->getValue(i,value)) {
+				if (value) {
+					bool haveA = false;
+					bool haveP = false;
+					bool haveH = false;
+					bool haveF = false;
+					bool haveL = false;
+					bool haveR = false;
+					int length=strlen(value);
+					for (int p=0; p<length; ++p) {
+						char c = value[p];
+						switch (c) {
+							case 'A':	haveA = true; break;
+							case 'P':	haveP = true; break;
+							case 'H':	haveH = true; break;
+							case 'F':	haveF = true; break;
+							case 'L':	haveL = true; break;
+							case 'R':	haveR = true; break;
+							default:
+										log << EMsgDC(IllegalCharacterInPatientOrientation) << " - '" << c << "' - only L, R, A, P, H or F permitted" << endl;
+										success = false;
+										break;
+						}
+					}
+					if (haveA && haveP) {
+						log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - A, P " << endl;
+						success = false;
+					}
+					if (haveH && haveF) {
+						log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - H, F " << endl;
+						success = false;
+					}
+					if (haveL && haveR) {
+						log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - L, R " << endl;
+						success = false;
+					}
+					if (i == 0) {
+						firstValue=value;
+					}
+					else if (firstValue && value && strlen(firstValue) > 0 && strcmp(firstValue,value) == 0) {
+						log << EMsgDC(PatientOrientationRowAndColumnDirectionsCannotBeIdentical) << " - \"" << firstValue << "\" and \"" << value << "\"" << endl;
+						success = false;
+					}
+				}
+			}
+		}
+	}
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkPatientOrientationValuesForBiped)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkPatientOrientationValuesForQuadruped(AttributeList &list,TextOutputStream &log) {
+//log << "checkPatientOrientationValuesForQuadruped" << endl;
+	bool success=true;
+	Attribute *aPatientOrientation=list[TagFromName(PatientOrientation)];
+	if (aPatientOrientation) {
+		int nValues = aPatientOrientation->getVM();
+		const char *firstValue = NULL;
+		for (int i=0; i<nValues; ++i) {
+			char *value;
+			if (aPatientOrientation->getValue(i,value)) {
+				if (value) {
+					bool haveCD = false;	// (Cd or Caudal)
+					bool haveCR = false;	// (Cr or Cranial)
+					bool haveD  = false;	// (Dorsal)
+					bool haveDI = false;	// (Di or Distal)
+					bool haveL  = false;	// (Lateral)
+					bool haveLE = false;	// (Le or Left)
+					bool haveM  = false;	// (Medial)
+					bool havePA = false;	// (Pa or Palmar)
+					bool havePL = false;	// (Pl or Plantar
+					bool havePR = false;	// (Pr or Proximal)
+					bool haveR  = false;	// (Rostral)
+					bool haveRT = false;	// (Rt or Right)
+					bool haveV  = false;	// (Ventral)
+					bool badValue = false;
+					int length=strlen(value);
+					char c;
+					for (int p=0; p<length && !badValue; ++p) {
+						c = value[p];
+						switch (c) {
+							case 'C':	if (p<length && value[p+1] == 'D') {
+											++p;
+											haveCD = true;
+										}
+										else if (p<length && value[p+1] == 'R') {
+											++p;
+											haveCR = true;
+										}
+										else {
+											badValue = true;
+										}
+										break;
+							case 'D':	if (p<length && value[p+1] == 'I') {
+											++p;
+											haveDI = true;
+										}
+										else {
+											haveD = true;
+										}
+										break;
+							case 'L':	if (p<length && value[p+1] == 'E') {
+											++p;
+											haveLE = true;
+										}
+										else {
+											haveL = true;
+										}
+										break;
+							case 'M':	haveM = true; break;
+							case 'P':	if (p<length && value[p+1] == 'A') {
+											++p;
+											havePA = true;
+										}
+										else if (p<length && value[p+1] == 'L') {
+											++p;
+											havePL = true;
+										}
+										else if (p<length && value[p+1] == 'R') {
+											++p;
+											havePR = true;
+										}
+										else {
+											badValue = true;
+										}
+										break;
+							case 'R':	if (p<length && value[p+1] == 'T') {
+											++p;
+											haveRT = true;
+										}
+										else {
+											haveR = true;
+										}
+										break;
+							case 'V':	haveV = true; break;
+							default:	badValue = true; break;
+						}
+					}
+					if (badValue) {
+						log << EMsgDC(IllegalCharacterInPatientOrientation) << " - '" << c << "' - only CD, CR, D, DI, L, LE, M, PA, PL, PR, R, RT or V permitted for quadruped" << endl;
+						success = false;
+					}
+					else {
+						if (haveLE && haveRT) {
+							log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - LE, RT " << endl;
+							success = false;
+						}
+						if (haveD && haveV) {
+							log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - D, V " << endl;
+							success = false;
+						}
+						if (haveCR && haveCD || haveR && haveCD || haveR && haveCR) {
+							log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - CR, CD, R " << endl;
+							success = false;
+						}
+						if (haveM && haveL) {
+							log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - M, L " << endl;
+							success = false;
+						}
+						if (havePR && haveDI) {
+							log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - PR, DI " << endl;
+							success = false;
+						}
+						if (havePA && havePL) {
+							log << EMsgDC(ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue) << " - PA, PL " << endl;
+							success = false;
+						}
+						if (i == 0) {
+							firstValue=value;
+						}
+						else if (firstValue && value && strlen(firstValue) > 0 && strcmp(firstValue,value) == 0) {
+							log << EMsgDC(PatientOrientationRowAndColumnDirectionsCannotBeIdentical) << " - \"" << firstValue << "\" and \"" << value << "\"" << endl;
+						success = false;
+						}
+					}
+				}
+			}
+		}
+	}
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkPatientOrientationValuesForQuadruped)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkPatientOrientationValuesForBipedOrQuadruped(AttributeList &list,TextOutputStream &log) {
+	bool quadruped = false;
+	Attribute *aAnatomicalOrientationType=list[TagFromName(AnatomicalOrientationType)];
+	if (aAnatomicalOrientationType) {
+		const char *vAnatomicalOrientationType=AttributeValue(aAnatomicalOrientationType);
+//log << "checkPatientOrientationValuesForBipedOrQuadruped(): vAnatomicalOrientationType = " << vAnatomicalOrientationType << endl;
+		if (vAnatomicalOrientationType && strcmp(vAnatomicalOrientationType,"QUADRUPED") == 0) {
+			quadruped = true;
+		}
+	}
+	return quadruped ? checkPatientOrientationValuesForQuadruped(list,log) : checkPatientOrientationValuesForBiped(list,log);
+}
+
+static bool
+checkUIDs(AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		const char *vr = a->getVR();
+		if (vr && vr[0]=='U' &&  vr[1]=='I') {
+			int nValues = a->getVM();
+			for (int i=0; i<nValues; ++i) {
+				char *value;
+				if (a->getValue(i,value)) {
+					if (value && strlen(value) >= 2) {
+						if (strncmp(value,"1.",2) != 0 && strncmp(value,"2.",2) != 0) {
+							log << EMsgDC(IllegalRootForUID) << " - \"" << value << "\" in ";
+							writeTagNumberAndNameToLog(a,list.getDictionary(),log);
+							log << endl;
+							success = false;
+						}
+					}
+				}
+			}
+		}
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkUIDs)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkNoEmptyReferencedFileIDComponents(AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	Attribute *aReferencedFileID=list[TagFromName(ReferencedFileID)];
+	if (aReferencedFileID && aReferencedFileID->isEmptyOrHasAnyEmptyValue()) {
+		log << EMsgDC(ReferencedFileIDHasEmptyComponents) << endl;
+		success=false;
+	}
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkNoEmptyReferencedFileIDComponents)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkNoIllegalOddNumberedGroups(AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkNoIllegalOddNumberedGroups)) {
+			success=false;
+		}
+		Tag tag=a->getTag();
+		Uint16 group = tag.getGroup();
+		if (group == 0x0001 || group == 0x0003 || group == 0x0005 || group == 0x0007) {
+			log << EMsgDC(BadGroup) << " - (";
+			writeZeroPaddedHexNumber(log,group,4);
+			log << ",";
+			writeZeroPaddedHexNumber(log,tag.getElement(),4);
+			log << ") " << endl;
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkHasStringValueElseWarning(AttributeList &list,Tag tag,const char *label,TextOutputStream &log)
+{
+	Attribute *a=list[tag];
+	if (!a || a->getVM() == 0) {
+		log << WMsgDC(MissingAttributeValueNeededForDirectory)
+		    << " - " << label
+		    << endl;
+		return false;
+	}
+	else {
+		return true;
+	}
+}
+
+static bool
+checkPresentationStateDisplayedAreaSelectionValuesAreValid(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+
+	Uint16 imageRotation = 0;
+	{
+		Attribute *aImageRotation=list[TagFromName(ImageRotation)];
+		if (aImageRotation && aImageRotation->getVM() == 1) {
+			aImageRotation->getValue(0,imageRotation);
+		}
+	}
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): imageRotation=" << dec << imageRotation << endl;
+	
+	bool imageHorizontalFlip = false;
+	{
+		Attribute *aImageHorizontalFlip=list[TagFromName(ImageHorizontalFlip)];
+		char *vImageHorizontalFlip = NULL;
+		if (aImageHorizontalFlip && aImageHorizontalFlip->getValue(0,vImageHorizontalFlip) && strcmp(vImageHorizontalFlip,"Y") == 0) {
+			imageHorizontalFlip = true;
+		}
+	}
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): imageHorizontalFlip=" << imageHorizontalFlip << endl;
+	
+	Attribute *aDisplayedAreaSelectionSequence=list[TagFromName(DisplayedAreaSelectionSequence)];
+	if (aDisplayedAreaSelectionSequence) {
+		if (aDisplayedAreaSelectionSequence->isSequence()) {
+			SequenceAttribute *sDisplayedAreaSelectionSequence = (SequenceAttribute *)aDisplayedAreaSelectionSequence;
+			AttributeList **displayedAreaSelectionSequenceItemLists;
+			int nDisplayedAreaSelectionSequenceItems = sDisplayedAreaSelectionSequence->getLists(&displayedAreaSelectionSequenceItemLists);
+			int i;
+			for (int i=0; i<nDisplayedAreaSelectionSequenceItems; ++i) {
+				AttributeList *displayedAreaSelectionSequenceItemList = displayedAreaSelectionSequenceItemLists[i];
+				if (displayedAreaSelectionSequenceItemList) {
+					Attribute *aDisplayedAreaTopLeftHandCorner=(*displayedAreaSelectionSequenceItemList)[TagFromName(DisplayedAreaTopLeftHandCorner)];
+					Attribute *aDisplayedAreaBottomRightHandCorner=(*displayedAreaSelectionSequenceItemList)[TagFromName(DisplayedAreaBottomRightHandCorner)];
+					if (aDisplayedAreaTopLeftHandCorner && aDisplayedAreaTopLeftHandCorner->getVM() == 2 && aDisplayedAreaBottomRightHandCorner && aDisplayedAreaBottomRightHandCorner->getVM() == 2) {
+						Int32 tlhcX,tlhcY,brhcX,brhcY;
+						if (aDisplayedAreaTopLeftHandCorner->getValue(0,tlhcX) && aDisplayedAreaTopLeftHandCorner->getValue(1,tlhcY)
+						 && aDisplayedAreaBottomRightHandCorner->getValue(0,brhcX) && aDisplayedAreaBottomRightHandCorner->getValue(1,brhcY)) {
+						 
+							// test case PS 3.3 Figure C.10.4-1.b
+							//tlhcX = 1;
+							//tlhcY = 480;
+							//brhcX = 640;
+							//brhcY = 1;
+							//imageRotation = 90;
+							//imageHorizontalFlip = false;
+						 
+							// test case PS 3.3 Figure C.10.4-1.c
+							//tlhcX = 1;
+							//tlhcY = 1;
+							//brhcX = 640;
+							//brhcY = 480;
+							//imageRotation = 90;
+							//imageHorizontalFlip = true;
+						 
+							if (imageRotation != 0 || imageHorizontalFlip) {
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): encoded TLHC = (" << tlhcX << "," << tlhcY << ") and BRHC = (" << brhcX << "," << brhcY << ") " << endl;
+								// check rotation and flip are correct by extracting original coordinates that must be TLHC above and left of BRHC and then simulating rotate and flip
+								// extract unrotated and unflipped original image relative coordinates ...
+								Int32 minX = tlhcX < brhcX ? tlhcX : brhcX;
+								Int32 maxX = tlhcX > brhcX ? tlhcX : brhcX;
+								Int32 minY = tlhcY < brhcY ? tlhcY : brhcY;
+								Int32 maxY = tlhcY > brhcY ? tlhcY : brhcY;
+								// now rotate and flip
+								Int32 x[4];
+								Int32 y[4];
+								x[0] = minX;
+								x[1] = maxX;
+								x[2] = maxX;
+								x[3] = minX;
+								y[0] = minY;
+								y[1] = minY;
+								y[2] = maxY;
+								y[3] = maxY;
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): original corners:\n(" << x[0] << "," << y[0] << ")\t(" << x[1] << "," << y[1] << ")\n(" << x[3] << "," << y[3] << ")\t(" << x[2] << "," << y[2] << ")" << endl;
+								Uint16 useRotation = imageRotation % 360;
+								Uint16 nNinety = useRotation/90;
+								if (nNinety > 0) {
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): performing " << nNinety << " CW unrotations " << endl;
+									for (int r=0; r<nNinety; ++r) {
+										Int32 holdX = x[3];
+										Int32 holdY = y[3];
+										for (int corner=3; corner>0; --corner) {
+											x[corner] = x[corner-1];
+											y[corner] = y[corner-1];
+										}
+										x[0] = holdX;
+										y[0] = holdY;
+									}
+								}
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): rotated corners:\n(" << x[0] << "," << y[0] << ")\t(" << x[1] << "," << y[1] << ")\n(" << x[3] << "," << y[3] << ")\t(" << x[2] << "," << y[2] << ")" << endl;
+								Int32 tlhcXExpected = imageHorizontalFlip ? x[1] : x[0];
+								Int32 tlhcYExpected = imageHorizontalFlip ? y[1] : y[0];
+								Int32 brhcXExpected = imageHorizontalFlip ? x[3] : x[2];
+								Int32 brhcYExpected = imageHorizontalFlip ? y[3] : y[2];
+//log << "checkPresentationStateDisplayedAreaSelectionValuesAreValid(): expected rotated flipped TLHC = (" << tlhcXExpected << "," << tlhcYExpected << ") and BRHC = (" << brhcXExpected << "," << brhcYExpected << ") " << endl;
+								if (tlhcX != tlhcXExpected || tlhcY != tlhcYExpected) {
+									log << EMsgDC(DisplayedAreaSelectionSequenceInternallyInconsistent)
+										<< " - DisplayedAreaTopLeftHandCorner = (" << tlhcX << "," << tlhcY << ") "
+										<< " does not match expected value after rotation of " << imageRotation << " degrees and " << (imageHorizontalFlip ? "" : "no ") << "horizontal flip "
+										<< " (" << tlhcXExpected << "," << tlhcYExpected << ") "
+										<< endl;
+									success=false;
+								}
+								if (brhcX != brhcXExpected || brhcY != brhcYExpected) {
+									log << EMsgDC(DisplayedAreaSelectionSequenceInternallyInconsistent)
+										<< " - DisplayedAreaBottomRightHandCorner = (" << brhcX << "," << brhcY << ") "
+										<< " does not match expected value after rotation of " << imageRotation << " degrees and " << (imageHorizontalFlip ? "" : "no ") << "horizontal flip "
+										<< " (" << brhcXExpected << "," << brhcYExpected << ") "
+										<< endl;
+									success=false;
+								}
+							}
+							else if (tlhcX >= brhcX || tlhcY >= brhcY) {
+								log << EMsgDC(DisplayedAreaSelectionSequenceInternallyInconsistent)
+									<< " - DisplayedAreaTopLeftHandCorner = (" << tlhcX << "," << tlhcY << ") "
+									<< " is not above and to the left of"
+									<< " DisplayedAreaBottomRightHandCorner = (" << brhcX << "," << brhcY << ") "
+									<< endl;
+								success=false;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkValuesNeededToBuildDicomDirectoryArePresentAndNotEmpty(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+
+	Attribute *aSOPClassUID=list[TagFromName(SOPClassUID)];
+	const char *vSOPClassUID=AttributeValue(aSOPClassUID);
+	Attribute *aDirectoryRecordSequence=list[TagFromName(DirectoryRecordSequence)];
+	if (!aDirectoryRecordSequence && (vSOPClassUID == NULL || (strcmp(vSOPClassUID,HangingProtocolStorageSOPClassUID) != 0 && strcmp(vSOPClassUID,ColorPaletteStorageSOPClassUID) != 0))) {
+		success = checkHasStringValueElseWarning(list,TagFromName(PatientID),"Patient ID",log) && success;
+		success = checkHasStringValueElseWarning(list,TagFromName(StudyDate),"Study Date",log) && success;
+		success = checkHasStringValueElseWarning(list,TagFromName(StudyTime),"Study Time",log) && success;
+		success = checkHasStringValueElseWarning(list,TagFromName(StudyID),"Study ID",log) && success;
+		success = checkHasStringValueElseWarning(list,TagFromName(Modality),"Modality",log) && success;
+		success = checkHasStringValueElseWarning(list,TagFromName(SeriesNumber),"Series Number",log) && success;
+		if (list[TagFromName(PixelData)]) {
+			success = checkHasStringValueElseWarning(list,TagFromName(InstanceNumber),"Instance Number",log) && success;
+		}
+		// should do RT, PS, Waveform, SR, Spectroscopy, etc. stuff here as well :(
+	}
+	return success;
+}
+
+static bool
+checkWaveformSequenceIsInternallyConsistent(AttributeList &list,TextOutputStream &log) {
+	bool success=true;
+	Attribute *aWaveformSequence=list[TagFromName(WaveformSequence)];
+	if (aWaveformSequence) {
+		if (aWaveformSequence->isSequence()) {
+			SequenceAttribute *sWaveformSequence = (SequenceAttribute *)aWaveformSequence;
+			AttributeList **multiplexGroupItemLists;
+			int nMultiplexGroups = sWaveformSequence->getLists(&multiplexGroupItemLists);
+			int i;
+			for (int i=0; i<nMultiplexGroups; ++i) {
+				AttributeList *multiplexGroupList = multiplexGroupItemLists[i];
+				if (multiplexGroupList) {
+					Attribute *aNumberOfWaveformChannels = (*multiplexGroupList)[TagFromName(NumberOfWaveformChannels)];
+					Attribute *aChannelDefinitionSequence = (*multiplexGroupList)[TagFromName(ChannelDefinitionSequence)];
+					if (aNumberOfWaveformChannels && aChannelDefinitionSequence && aChannelDefinitionSequence->isSequence()) {
+						Uint16 numberOfWaveformChannels = AttributeValue(aNumberOfWaveformChannels);
+						SequenceAttribute *sChannelDefinitionSequence = (SequenceAttribute *)aChannelDefinitionSequence;
+						AttributeList **channelDefinitionSequenceLists;
+						int numberOfChannelDefinitionSequenceItems = sChannelDefinitionSequence->getLists(&channelDefinitionSequenceLists);
+						if (numberOfWaveformChannels != numberOfChannelDefinitionSequenceItems) {
+							log << EMsgDC(WaveformSequenceInternallyInconsistent)
+							    << " - NumberOfWaveformChannels = " << numberOfWaveformChannels
+							    << " but number of ChannelDefinitionSequence Items = " << numberOfChannelDefinitionSequenceItems
+							    << endl;
+							success=false;
+						}
+					}
+				}
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkPixelDataIsTheCorrectLength(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aPixelData=list[TagFromName(PixelData)];
+	if (aPixelData) {
+		Uint32 vl = aPixelData->getVL();
+		if (vl != 0xffffffff) {
+//log << "vl=" << dec << vl << endl;
+			Uint16 vRows=AttributeValue(list[TagFromName(Rows)]);
+			Uint16 vColumns=AttributeValue(list[TagFromName(Columns)]);
+			Uint16 vBitsAllocated=AttributeValue(list[TagFromName(BitsAllocated)]);
+			Uint16 vBitsStored=AttributeValue(list[TagFromName(BitsStored)]);
+			Uint16 vNumberOfFrames=AttributeValue(list[TagFromName(NumberOfFrames)],1);
+			if (vNumberOfFrames == 0) {	// cannot be -ve since unsigned
+				// do not send an error message, since will always be picked up as unexpected enumerated value of 0 in CheckSingleFramePseudo Module or NotZeroError in Multiframe Module etc.
+				vNumberOfFrames = 1;	// so that pixel data length expected will not be 0 (000393)
+			}
+			Uint16 vSamplesPerPixel=AttributeValue(list[TagFromName(SamplesPerPixel)],1);
+//log << "vRows=" << dec << vRows << endl;
+//log << "vColumns=" << dec << vColumns << endl;
+//log << "vBitsAllocated=" << dec << vBitsAllocated << endl;
+//log << "vBitsStored=" << dec << vBitsStored << endl;
+//log << "vNumberOfFrames=" << dec << vNumberOfFrames << endl;
+//log << "vSamplesPerPixel=" << dec << vSamplesPerPixel << endl;
+			// suppress the error when BitsAllocated is not sent, assuming byte aligned based on BitsStored
+			Uint16 useBits = vBitsAllocated == 0 ? (vBitsStored == 0 ? 16 : ((vBitsStored-1)/8+1)*8 ) : vBitsAllocated;
+//log << "useBits=" << dec << useBits << endl;
+			Uint32 expectedLength;
+			if (useBits % 8 == 0) {
+				Uint16 useBytes = useBits/8;
+//log << "useBytes=" << dec << useBytes << endl;
+				expectedLength = ((Uint32)vRows)*vColumns*useBytes*vNumberOfFrames*vSamplesPerPixel;
+			}
+			else {
+				// account for packed data, as in old ACR-NEMA objects, instead of assuming whole number of bytes
+				// but this may overflow 32 bits if too long :(
+				expectedLength = (((Uint32)vRows)*vColumns*useBits*vNumberOfFrames*vSamplesPerPixel - 1)/8 + 1;
+			}
+//log << "expectedLength=" << dec << expectedLength << endl;
+			if (expectedLength%2 == 1) {
+				++expectedLength;	// odd lengths are always padded by one byte to even ([bugs.dicom3tools] (000113))
+			}
+			if (vl != expectedLength) {
+				log << EMsgDC(PixelDataIncorrectVL)
+					<< " - " << MMsgDC(Expected) << " " << dec << expectedLength << " dec"
+					<< " - " << MMsgDC(Got) << " " << dec << vl << " dec"
+				    << endl;
+				success=false;
+			}
+		}
+		// else do not check if encapsulated
+	}
+	
+	return success;
+}
+
+
+static bool
+checkPixelAspectRatioValidIfPresent(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aPixelAspectRatio=list[TagFromName(PixelAspectRatio)];
+	if (aPixelAspectRatio) {
+		int length = aPixelAspectRatio->getVL();
+		Uint32 value1,value2;
+		if (aPixelAspectRatio->getValue(0,value1) && aPixelAspectRatio->getValue(1,value2)) {
+			if (value1 == value2) {
+				log << EMsgDC(PixelAspectRatioNotPermittedWhenOneToOne) << " - values are " << value1 << "\\" << value2 << endl;
+			}
+		}
+	}
+
+	return success;
+}
+
+static bool
+checkEstimatedRadiographicMagnificationFactorIfPresent(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aEstimatedRadiographicMagnificationFactor=list[TagFromName(EstimatedRadiographicMagnificationFactor)];
+	Attribute *aDistanceSourceToDetector=list[TagFromName(DistanceSourceToDetector)];
+	Attribute *aDistanceSourceToPatient=list[TagFromName(DistanceSourceToPatient)];
+	if (aEstimatedRadiographicMagnificationFactor && aDistanceSourceToDetector && aDistanceSourceToPatient) {
+		Float32 vEstimatedRadiographicMagnificationFactor = 0;
+		Float32 vDistanceSourceToDetector = 0;
+		Float32 vDistanceSourceToPatient = 0;
+		if (aEstimatedRadiographicMagnificationFactor->getValue(0,vEstimatedRadiographicMagnificationFactor)
+		 && aDistanceSourceToDetector->getValue(0,vDistanceSourceToDetector)
+		 && aDistanceSourceToPatient->getValue(0,vDistanceSourceToPatient)) {
+			if (vDistanceSourceToPatient > 0
+			 && fabs(vDistanceSourceToDetector/vDistanceSourceToPatient - vEstimatedRadiographicMagnificationFactor) > 0.0001) {
+				log << WMsgDC(EstimatedRadiographicMagnificationFactorDoesNotMatchRatioOfDistanceSourceToDetectorAndDistanceSourceToPatient)
+					<< " - values are " << vEstimatedRadiographicMagnificationFactor << ", " << vDistanceSourceToDetector << ", " << vDistanceSourceToPatient << endl;
+			}
+		}
+	}
+
+	return success;
+}
+
+static bool checkUnitVector(Attribute *a,int length,int valueOffset,const char *whichVector,const char *tagName,TextOutputStream &log) {
+//cerr << "checkUnitVector(): checking " << whichVector << " of " << tagName << endl;
+	bool success=true;
+	Float32 x,y,z;
+	if (valueOffset+2 < length && a->getValue(valueOffset,x) && a->getValue(valueOffset+1,y) && a->getValue(valueOffset+2,z)) {
+		Float32 sumOfSquares = x*x + y*y + z*z;
+//cerr << "checkUnitVector(): x = " << x << endl;
+//cerr << "checkUnitVector(): y = " << y << endl;
+//cerr << "checkUnitVector(): z = " << z << endl;
+//cerr << "checkUnitVector(): sumOfSquares = " << sumOfSquares << endl;
+		if (fabs(sumOfSquares - 1) > 0.0001) {
+			success=false;
+			log << EMsgDC(OrientationVectorIsNotUnitVector) << " for " << whichVector << " vector of " << tagName << " - values are " << x << "\\" << y << "\\" << z << endl;
+		}
+	}
+	return success;
+}
+
+static bool checkOrthogonal(
+		Attribute *a1,int length1,int valueOffset1,const char *whichVector1,const char *tagName1,
+		Attribute *a2,int length2,int valueOffset2,const char *whichVector2,const char *tagName2,
+		TextOutputStream &log) {
+//cerr << "checkOrthogonal(): checking " << whichVector1 << " of " << tagName1 << " and " << whichVector2 << " of " << tagName2 << endl;
+	bool success=true;
+	Float32 x1,y1,z1;
+	Float32 x2,y2,z2;
+	if (valueOffset1+2 < length1 && a1->getValue(valueOffset1,x1) && a1->getValue(valueOffset1+1,y1) && a1->getValue(valueOffset1+2,z1)
+	 && valueOffset2+2 < length2 && a2->getValue(valueOffset2,x2) && a2->getValue(valueOffset2+1,y2) && a2->getValue(valueOffset2+2,z2)) {
+//cerr << "checkUnitVector(): x1 = " << x1 << endl;
+//cerr << "checkUnitVector(): y1 = " << y1 << endl;
+//cerr << "checkUnitVector(): z1 = " << z1 << endl;
+//cerr << "checkUnitVector(): x2 = " << x2 << endl;
+//cerr << "checkUnitVector(): y2 = " << y2 << endl;
+//cerr << "checkUnitVector(): z2 = " << z2 << endl;
+		Float32 dotProduct = x1*x2 + y1*y2 + z1*z2;
+//cerr << "checkUnitVector(): dotProduct = " << dotProduct << endl;
+		if (fabs(dotProduct) > 0.0001) {
+			success=false;
+			log << EMsgDC(OrientationVectorsAreNotOrthogonal)
+				<< " for " << whichVector1 << " vector of " << tagName1 << " (" << x1 << "\\" << y1 << "\\" << z1 << ")"
+				<< " and " << whichVector2 << " vector of " << tagName2 << " (" << x2 << "\\" << y2 << "\\" << z2 << ")"
+				<< endl;
+		}
+	}
+	return success;
+}
+
+static bool
+checkOrientationsAreOrthogonal(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	{
+		Attribute *aImageOrientationPatient=list[TagFromName(ImageOrientationPatient)];
+		if (aImageOrientationPatient) {
+			int length = aImageOrientationPatient->getVL();
+			if (!checkOrthogonal(aImageOrientationPatient,length,0,"row","ImageOrientationPatient",aImageOrientationPatient,length,3,"column","ImageOrientationPatient",log)) success = false;
+		}
+	}
+	{
+		Attribute *aImageOrientation=list[TagFromName(ImageOrientation)];
+		if (aImageOrientation) {
+			int length = aImageOrientation->getVL();
+			if (!checkOrthogonal(aImageOrientation,length,0,"row","ImageOrientation",aImageOrientation,length,3,"column","ImageOrientation",log)) success = false;
+		}
+	}
+	
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkOrientationsAreOrthogonal)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkOrientationsAreUnitVectors(AttributeList &list,TextOutputStream &log)
+{
+	// call for ImageOrientationPatient and ImageOrientation
+	bool success=true;
+	{
+		Attribute *aImageOrientationPatient=list[TagFromName(ImageOrientationPatient)];
+		if (aImageOrientationPatient) {
+			int length = aImageOrientationPatient->getVL();
+			if (!checkUnitVector(aImageOrientationPatient,length,0,"row","ImageOrientationPatient",log)) success = false;
+			if (!checkUnitVector(aImageOrientationPatient,length,3,"column","ImageOrientationPatient",log)) success = false;
+		}
+	}
+	{
+		Attribute *aImageOrientation=list[TagFromName(ImageOrientation)];
+		if (aImageOrientation) {
+			int length = aImageOrientation->getVL();
+			if (!checkUnitVector(aImageOrientation,length,0,"row","ImageOrientation",log)) success = false;
+			if (!checkUnitVector(aImageOrientation,length,3,"column","ImageOrientation",log)) success = false;
+		}
+	}
+	{
+		Attribute *aImageOrientationSlide=list[TagFromName(ImageOrientationSlide)];
+		if (aImageOrientationSlide) {
+			int length = aImageOrientationSlide->getVL();
+			if (!checkUnitVector(aImageOrientationSlide,length,0,"row","ImageOrientationSlide",log)) success = false;
+			if (!checkUnitVector(aImageOrientationSlide,length,3,"column","ImageOrientationSlide",log)) success = false;
+		}
+	}
+	{
+		Attribute *aControlPointOrientation=list[TagFromName(ControlPointOrientation)];
+		if (aControlPointOrientation) {
+			int length = aControlPointOrientation->getVL();
+			if (!checkUnitVector(aControlPointOrientation,length,0,"","ControlPointOrientation",log)) success = false;
+		}
+	}
+	{
+		Attribute *aSlabOrientation=list[TagFromName(SlabOrientation)];
+		if (aSlabOrientation) {
+			int length = aSlabOrientation->getVL();
+			if (!checkUnitVector(aSlabOrientation,length,0,"","SlabOrientation",log)) success = false;
+		}
+	}
+	{
+		Attribute *aVelocityEncodingDirection=list[TagFromName(VelocityEncodingDirection)];
+		if (aVelocityEncodingDirection) {
+			int length = aVelocityEncodingDirection->getVL();
+			if (!checkUnitVector(aVelocityEncodingDirection,length,0,"","VelocityEncodingDirection",log)) success = false;
+		}
+	}
+	
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkOrientationsAreUnitVectors)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkPixelSpacingCalibration(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aPixelSpacing=list[TagFromName(PixelSpacing)];
+	Attribute *aImagerPixelSpacing=list[TagFromName(ImagerPixelSpacing)];
+	Attribute *aNominalScannedPixelSpacing=list[TagFromName(NominalScannedPixelSpacing)];
+	Attribute *aPixelSpacingCalibrationType=list[TagFromName(PixelSpacingCalibrationType)];
+
+	if (aPixelSpacing && !aPixelSpacingCalibrationType) {
+		Float32 vPixelSpacingRow = 0;
+		Float32 vPixelSpacingCol = 0;
+		if (aPixelSpacing->getValue(0,vPixelSpacingRow) && aPixelSpacing->getValue(1,vPixelSpacingCol)) {
+			if (aImagerPixelSpacing) {
+				Float32 vImagerPixelSpacingRow = 0;
+				Float32 vImagerPixelSpacingCol = 0;
+				if (aImagerPixelSpacing->getValue(0,vImagerPixelSpacingRow) && aImagerPixelSpacing->getValue(1,vImagerPixelSpacingCol)
+				&& (vPixelSpacingRow != vImagerPixelSpacingRow || vPixelSpacingCol != vImagerPixelSpacingCol)) {
+					log << WMsgDC(PixelSpacingDoesNotMatchImagerPixelSpacingButPixelSpacingCalibrationTypeNotPresent)
+					    << " - PixelSpacing = " << vPixelSpacingRow << "\\" << vPixelSpacingCol << " versus ImagerPixelSpacing = "
+						<< vImagerPixelSpacingRow << "\\" << vImagerPixelSpacingCol << endl;
+				}
+			}
+			if (aNominalScannedPixelSpacing) {
+				Float32 vNominalScannedPixelSpacingRow = 0;
+				Float32 vNominalScannedPixelSpacingCol = 0;
+				if (aNominalScannedPixelSpacing->getValue(0,vNominalScannedPixelSpacingRow) && aNominalScannedPixelSpacing->getValue(1,vNominalScannedPixelSpacingCol)
+				&& (vPixelSpacingRow != vNominalScannedPixelSpacingRow || vPixelSpacingCol != vNominalScannedPixelSpacingCol)) {
+					log << WMsgDC(PixelSpacingDoesNotMatchNominalScannedPixelSpacingButPixelSpacingCalibrationTypeNotPresent)
+					    << " - PixelSpacing = " << vPixelSpacingRow << "\\" << vPixelSpacingCol << " versus NominalScannedPixelSpacing = "
+						<< vNominalScannedPixelSpacingRow << "\\" << vNominalScannedPixelSpacingCol << endl;
+				}
+			}
+		}
+	}
+
+	return success;
+}
+
+static bool
+checkSpacingBetweenSlicesIsNotNegative(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aSpacingBetweenSlices=list[TagFromName(SpacingBetweenSlices)];
+
+	if (aSpacingBetweenSlices) {
+		Float32 vSpacingBetweenSlices = 0;
+		if (aSpacingBetweenSlices->getValue(0,vSpacingBetweenSlices)) {
+			if (vSpacingBetweenSlices < 0) {
+				Attribute *aSOPClassUID=list[TagFromName(SOPClassUID)];
+				char *vSOPClassUID;
+				if (!aSOPClassUID || !aSOPClassUID->getValue(0,vSOPClassUID) || strcmp(vSOPClassUID,NuclearMedicineImageStorageSOPClassUID) != 0) {
+					log << EMsgDC(IllegalNegativeValue) << " - SpacingBetweenSlices = " << vSpacingBetweenSlices << endl;
+					success = false;
+				}
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkFrameIncrementPointerValuesValid(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aFrameIncrementPointer=list[TagFromName(FrameIncrementPointer)];
+	if (aFrameIncrementPointer) {
+		int length = aFrameIncrementPointer->getVL();
+		for (int i=0; i<length; ++i) {
+			Uint32 value;
+			if (aFrameIncrementPointer->getValue(i,value)) {
+				Tag *tag = new Tag(value);
+				Attribute *a = list[*tag];
+				if (!a) {
+					log << EMsgDC(FrameIncrementPointerValueNotPresentInDataset)
+					    << " for value " << i << ", which is ";
+					writeTagNumberAndNameToLog(*tag,list.getDictionary(),log);
+					log << endl;
+				}
+				delete tag;
+			}
+		}
+	}
+
+	return success;
+}
+
+static bool
+checkFrameVectorCountsValid(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aNumberOfFrames=list[TagFromName(NumberOfFrames)];
+	Uint32 vNumberOfFrames = 1;
+	if (aNumberOfFrames) {
+		(void)aNumberOfFrames->getValue(0,vNumberOfFrames);
+	}
+	
+	const Tag vectorTags[] = {
+		TagFromName(EnergyWindowVector),
+		TagFromName(DetectorVector),
+		TagFromName(PhaseVector),
+		TagFromName(RotationVector),
+		TagFromName(RRIntervalVector),
+		TagFromName(TimeSlotVector),
+		TagFromName(SliceVector),
+		TagFromName(AngularViewVector)
+	};
+	const Tag numberTags[] = {
+		TagFromName(NumberOfEnergyWindows),
+		TagFromName(NumberOfDetectors),
+		TagFromName(NumberOfPhases),
+		TagFromName(NumberOfRotations),
+		TagFromName(NumberOfRRIntervals),
+		TagFromName(NumberOfTimeSlots),
+		TagFromName(NumberOfSlices),
+		TagFromName(TimeSliceVector)
+	};
+	int nTags = 8;
+
+	for (int i=0; i<nTags; ++i) {
+		Attribute *aVector=list[vectorTags[i]];
+		if (aVector) {
+			int nValues = aVector->getVM();
+			if (nValues != vNumberOfFrames) {
+				log << EMsgDC(NumberOfValuesInVectorDoesNotMatchNumberOfFrames)
+					<< " for Attribute ";
+				writeTagNumberAndNameToLog(aVector,list.getDictionary(),log);
+				log << ", which has " << dec << nValues << " values"
+					<< " though Number of Frames is " << vNumberOfFrames
+					<< endl;
+				success = false;
+			}
+			Attribute *aNumber=list[numberTags[i]];
+			Uint32 vNumber = 0;
+			if (aNumber && aNumber->getValue(0,vNumber) && nValues > 0) {
+				Uint32 lowestValueFound = 0xffffffff;
+				Uint32 highestValueFound = 0;
+				for (int j=0; j<nValues; ++j) {
+					Uint32 value;
+					if (aVector->getValue(j,value)) {
+						if (value > highestValueFound) {
+							highestValueFound = value;
+						}
+						if (value < lowestValueFound) {
+							lowestValueFound = value;
+						}
+					}
+				}
+				if (highestValueFound != vNumber) {
+					log << EMsgDC(SpecifiedNumberOfVectorValuesDoesNotMatchActualValuesInVector)
+						<< " for Attribute ";
+					writeTagNumberAndNameToLog(aNumber,list.getDictionary(),log);
+					log << ", which has value " << dec << vNumber
+						<< ", whereas the highest value found in ";
+					writeTagNumberAndNameToLog(aVector,list.getDictionary(),log);
+					log << " is " << dec << highestValueFound
+						<< endl;
+					success = false;
+				}
+				if (lowestValueFound != 1) {
+					log << EMsgDC(LowestValueInVectorIsNotOne)
+						<< " for Attribute ";
+					writeTagNumberAndNameToLog(aVector,list.getDictionary(),log);
+					log << ", but rather is " << dec << lowestValueFound
+						<< endl;
+					success = false;
+				}
+			}
+		}
+	}
+	return success;
+}
+
+
+static bool
+checkMetaInformationMatchesSOPInstance(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute *aMediaStorageSOPInstanceUID=list[TagFromName(MediaStorageSOPInstanceUID)];
+	Attribute *aMediaStorageSOPClassUID=list[TagFromName(MediaStorageSOPClassUID)];
+	Attribute *aSOPInstanceUID=list[TagFromName(SOPInstanceUID)];
+	Attribute *aSOPClassUID=list[TagFromName(SOPClassUID)];
+	Attribute *aDirectoryRecordSequence=list[TagFromName(DirectoryRecordSequence)];
+		
+	if (aMediaStorageSOPInstanceUID) {
+		if (aSOPInstanceUID) {
+			const char *vMediaStorageSOPInstanceUID=AttributeValue(aMediaStorageSOPInstanceUID);
+			const char *vSOPInstanceUID=AttributeValue(aSOPInstanceUID);
+			if (!vMediaStorageSOPInstanceUID || !vSOPInstanceUID || strcmp(vMediaStorageSOPInstanceUID,vSOPInstanceUID) != 0) {
+				success=false;
+				log << EMsgDC(MediaStorageSOPInstanceUIDDifferentFromSOPInstanceUID)
+				    << endl;
+			}
+		}
+		else if (!aDirectoryRecordSequence) {
+			success=false;
+			log << EMsgDC(MediaStorageSOPInstanceUIDButMissingSOPInstanceUIDAndNotADirectory)
+			    << endl;
+		}
+	}
+
+	if (aMediaStorageSOPClassUID) {
+		const char *vMediaStorageSOPClassUID=AttributeValue(aMediaStorageSOPClassUID);
+		if (aSOPClassUID) {
+			const char *vSOPClassUID=AttributeValue(aSOPClassUID);
+			if (!vMediaStorageSOPClassUID || !vSOPClassUID || strcmp(vMediaStorageSOPClassUID,vSOPClassUID) != 0) {
+				success=false;
+				log << EMsgDC(MediaStorageSOPClassUIDDifferentFromSOPClassUID)
+				    << endl;
+			}
+		}
+		else if (aDirectoryRecordSequence) {
+			if (!vMediaStorageSOPClassUID || strcmp(vMediaStorageSOPClassUID,MediaStorageDirectoryStorageSOPClassUID) != 0) {
+				success=false;
+				log << EMsgDC(MediaStorageSOPClassUIDNotMediaStorageDirectoryStorageSOPClassUID)
+				    << endl;
+			}
+		}
+		else {
+			success=false;
+			log << EMsgDC(MediaStorageSOPClassUIDButMissingSOPClassUIDAndNotADirectory)
+			    << endl;
+		}
+	}
+
+	return success;
+}
+
+static bool
+checkLUTDataValuesMatchSpecifiedRange(AttributeList &list,Tag descriptorTag,Tag dataTag,const char *message,TextOutputStream &log)
+{
+	bool success=true;
+	{
+		Attribute *aLUTDescriptor = list[descriptorTag];
+		Attribute *aLUTData = list[dataTag];
+		if (aLUTDescriptor && aLUTDescriptor->getVM() == 3) {
+			Uint16 numberOfBits = 0;
+			Uint16 numberOfEntries = 0;
+			if (aLUTDescriptor->getValue(0,numberOfEntries)
+			 && aLUTDescriptor->getValue(2,numberOfBits)) {
+				Uint32 actualNumberOfEntries = (numberOfEntries == 0) ? 0x10000 : ((Uint32)numberOfEntries & 0xffff);
+				Uint16 wantMaxValueMax = (Uint16)( ( ((Uint32)1) <<  numberOfBits    ) - 1 );
+				Uint16 wantMaxValueMin = (Uint16)( ( ((Uint32)1) << (numberOfBits-1) )     );
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): wantMaxValueMax = 0x" << hex << wantMaxValueMax << dec << endl;
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): wantMaxValueMin = 0x" << hex << wantMaxValueMin << dec << endl;
+				if (aLUTData) {
+					bool foundValuesToCheck = false;
+					Uint16 maxValue = 0;
+					Uint32 nLUTData = 0;
+					if (numberOfBits > 8) {
+						if (aLUTData->isOtherWordNonPixel()) {
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): checking > 8 bit OW" << endl;
+							const Uint16 *vLUTData = NULL;
+							if (aLUTData->getValue(vLUTData,nLUTData)) {
+								foundValuesToCheck=true;
+								for (int i=0; i<nLUTData; ++i) {
+									Uint16 value = vLUTData[i];
+									if (value > maxValue) maxValue = value;
+								}
+							}
+						}
+						else if (aLUTData->isNumericBinary()) {		// e.g. US VR
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): checking > 8 bit " << aLUTData->getVR() << endl;
+							foundValuesToCheck=true;
+							nLUTData = aLUTData->getVM();
+							for (int i=0; i<nLUTData; ++i) {	// very slow :(
+								Uint16 value;
+								if (aLUTData->getValue(i,value)) {
+									if (value > maxValue) maxValue = value;
+								}
+							}
+						}
+						else {
+							// what have we missed ?
+							log << WMsgDC(NotCheckingLUTDataMaximum)
+							    << " - " << message
+							    << " - 16 bit LUT for VR " << aLUTData->getVR()
+							    << endl;
+						}
+						if (foundValuesToCheck) {
+							if (nLUTData != actualNumberOfEntries) {
+								log << EMsgDC(LUTDataWrongLength)
+								    << " - " << message
+								    << " - LUT Descriptor number of entries = " << actualNumberOfEntries
+								    << " but number of 16 bit values = " << nLUTData
+								    << endl;
+								success=false;
+							}
+						}
+					}
+					else {
+						if (aLUTData->isOtherWordNonPixel()) {
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): checking <= 8 bit OW" << endl;
+							const Uint16 *vLUTData = NULL;
+							if (aLUTData->getValue(vLUTData,nLUTData)) {
+								foundValuesToCheck=true;
+								for (int i=0; i<nLUTData; ++i) {
+									Uint16 value = vLUTData[i];
+									Uint16 lowValue = (value >> 8) & 0xff;
+									if (lowValue > maxValue) maxValue = lowValue;
+									Uint16 highValue = value & 0xff;
+									if (highValue > maxValue) maxValue = highValue;
+								}
+							}
+						}
+						else if (aLUTData->isNumericBinary()) {		// e.g. US VR
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): checking <= 8 bit " << aLUTData->getVR() << endl;
+							foundValuesToCheck=true;
+							nLUTData = aLUTData->getVM();
+							for (int i=0; i<nLUTData; ++i) {	// very slow :(
+								Uint16 value;
+								if (aLUTData->getValue(i,value)) {
+									Uint16 lowValue = (value >> 8) & 0xff;
+									if (lowValue > maxValue) maxValue = lowValue;
+									Uint16 highValue = value & 0xff;
+									if (highValue > maxValue) maxValue = highValue;
+								}
+							}
+						}
+						else {
+							// what have we missed ?
+							log << WMsgDC(NotCheckingLUTDataMaximum)
+							    << " - " << message
+							    << " - 8 bit LUT for VR " << aLUTData->getVR()
+							    << endl;
+						}
+						if (foundValuesToCheck) {
+							if (nLUTData*2 != actualNumberOfEntries) {
+								log << EMsgDC(LUTDataWrongLength)
+								    << " - " << message
+								    << " - LUT Descriptor number of entries = " << actualNumberOfEntries
+								    << " but number of 8 bit values = " << nLUTData*2
+								    << " packed into " << nLUTData << " 16 bit words"
+								    << endl;
+								success=false;
+							}
+						}
+					}
+					if (foundValuesToCheck) {
+//cerr << "checkLUTDataValuesMatchSpecifiedRange(): maxValue = 0x" << hex << maxValue << dec << endl;
+						if (maxValue < wantMaxValueMin || maxValue > wantMaxValueMax) {
+							log << EMsgDC(LUTDataBad)
+							    << " - " << message
+							    << " - LUT Descriptor number of bits = " << numberOfBits
+							    << " but maximum LUT Data value is " << hex << maxValue << dec
+							    << endl;
+							success=false;
+						}
+					}
+				}
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkLUTDataValuesMatchSpecifiedRange(AttributeList &list,Tag sequenceTag,Tag descriptorTag,Tag dataTag,const char *message,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute* a = list[sequenceTag];
+	if (a && a->isSequence()) {
+		SequenceAttribute *sa = (SequenceAttribute *)a;
+		AttributeList **itemLists;
+		int nItems = sa->getLists(&itemLists);
+		int i;
+		for (int i=0; i<nItems; ++i) {
+			AttributeList *itemList = itemLists[i];
+			if (itemList) {
+				if (!checkLUTDataValuesMatchSpecifiedRange(*itemList,descriptorTag,dataTag,message,log)) success = false;
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkLUTDataValuesInIconImageSequenceMatchSpecifiedRange(AttributeList &list,TextOutputStream &log)
+{
+	bool success=true;
+	Attribute* aIconImageSequence = list[TagFromName(IconImageSequence)];
+	if (aIconImageSequence && aIconImageSequence->isSequence()) {
+		SequenceAttribute *sa = (SequenceAttribute *)aIconImageSequence;
+		AttributeList **itemLists;
+		int nItems = sa->getLists(&itemLists);
+		int i;
+		for (int i=0; i<nItems; ++i) {
+			AttributeList *itemList = itemLists[i];
+			if (itemList) {
+				if (!checkLUTDataValuesMatchSpecifiedRange(*itemList,TagFromName(RedPaletteColorLookupTableDescriptor),TagFromName(RedPaletteColorLookupTableData),
+					"Icon Image Sequence - Red Palette Color LUT",log)) success = false;
+				if (!checkLUTDataValuesMatchSpecifiedRange(*itemList,TagFromName(GreenPaletteColorLookupTableDescriptor),TagFromName(GreenPaletteColorLookupTableData),
+					"Icon Image Sequence - Green Palette Color LUT",log)) success = false;
+				if (!checkLUTDataValuesMatchSpecifiedRange(*itemList,TagFromName(BluePaletteColorLookupTableDescriptor),TagFromName(BluePaletteColorLookupTableData),
+					"Icon Image Sequence - Blue Palette Color LUT",log)) success = false;
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkLUTDataValuesMatchSpecifiedRange(AttributeList &list,TextOutputStream &log)
+{
+	bool success = true;
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,TagFromName(ModalityLUTSequence),TagFromName(LUTDescriptor),TagFromName(LUTData),"Modality LUT",log)) success = false;
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,TagFromName(VOILUTSequence),TagFromName(LUTDescriptor),TagFromName(LUTData),"VOI LUT",log)) success = false;
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,TagFromName(PresentationLUTSequence),TagFromName(LUTDescriptor),TagFromName(LUTData),"Presentation LUT",log)) success = false;
+	
+	Attribute* aSoftcopyVOILUTSequence = list[TagFromName(SoftcopyVOILUTSequence)];
+	if (aSoftcopyVOILUTSequence && aSoftcopyVOILUTSequence->isSequence()) {
+		SequenceAttribute *sa = (SequenceAttribute *)aSoftcopyVOILUTSequence;
+		AttributeList **itemLists;
+		int nItems = sa->getLists(&itemLists);
+		int i;
+		for (int i=0; i<nItems; ++i) {
+			AttributeList *itemList = itemLists[i];
+			if (itemList) {
+				if (!checkLUTDataValuesMatchSpecifiedRange(*itemList,TagFromName(VOILUTSequence),TagFromName(LUTDescriptor),TagFromName(LUTData),
+					"Softcopy VOI LUT",log)) success = false;
+			}
+		}
+	}
+
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,TagFromName(RedPaletteColorLookupTableDescriptor),TagFromName(RedPaletteColorLookupTableData),"Red Palette Color LUT",log)) success = false;
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,TagFromName(GreenPaletteColorLookupTableDescriptor),TagFromName(GreenPaletteColorLookupTableData),"Green Palette Color LUT",log)) success = false;
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,TagFromName(BluePaletteColorLookupTableDescriptor),TagFromName(BluePaletteColorLookupTableData),"Blue Palette Color LUT",log)) success = false;
+
+	if (!checkLUTDataValuesInIconImageSequenceMatchSpecifiedRange(list,log)) success = false;
+
+	Attribute* aDirectoryRecordSequence = list[TagFromName(DirectoryRecordSequence)];
+	if (aDirectoryRecordSequence && aDirectoryRecordSequence->isSequence()) {
+		SequenceAttribute *sa = (SequenceAttribute *)aDirectoryRecordSequence;
+		AttributeList **itemLists;
+		int nItems = sa->getLists(&itemLists);
+		int i;
+		for (int i=0; i<nItems; ++i) {
+			AttributeList *itemList = itemLists[i];
+			if (itemList) {
+				if (!checkLUTDataValuesInIconImageSequenceMatchSpecifiedRange(*itemList,log)) success = false;
+			}
+		}
+	}
+	
+	return success;
+}
+
+static bool
+checkCodeValuesDoNotContainInappropriateCharacters(AttributeList &list,TextOutputStream &log) {
+	//cerr << "checkCodeValuesDoNotContainInappropriateCharacters():" << endl;
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		{
+			if (a && a->isSequence() && !a->isEmpty()) {
+				//cerr << "checkCodeValuesDoNotContainInappropriateCharacters(): have Sequence" << endl;
+				AttributeList **al;
+				int n;
+				if ((n=a->getLists(&al)) > 0) {
+					//cerr << "checkCodeValuesDoNotContainInappropriateCharacters(): have " << n << " items" << endl;
+					int i;
+					for (i=0; i<n; ++i) {
+						AttributeList *itemList = al[i];
+						Attribute *aCodeValue=(*itemList)[TagFromName(CodeValue)];
+						Attribute *aCodingSchemeDesignator=(*itemList)[TagFromName(CodingSchemeDesignator)];
+						//cerr << "checkCodeValuesDoNotContainInappropriateCharacters(): have CodeValue" << endl;
+						if (aCodeValue && aCodingSchemeDesignator) {
+							char *vCodingSchemeDesignator = NULL;
+							if (aCodingSchemeDesignator->getVM() > 0) {
+								aCodingSchemeDesignator->getValue(0,vCodingSchemeDesignator);
+							}
+							Uint16 nValues= aCodeValue->getVM();
+							if (nValues > 0 && vCodingSchemeDesignator) {
+								//cerr << "checkCodeValuesDoNotContainInappropriateCharacters(): have CodeValue with " << nValues << " values" << endl;
+								bool isSNOMED = strcmp(vCodingSchemeDesignator,"SRT") == 0|| strcmp(vCodingSchemeDesignator,"SNM3") == 0 || strcmp(vCodingSchemeDesignator,"99SDM") == 0;
+								bool isDICOM  = strcmp(vCodingSchemeDesignator,"DCM") == 0;
+								if (isSNOMED | isDICOM) {
+									int j;
+									for (j=0; j<nValues; ++j) {
+										char *value;
+										if (aCodeValue->getValue(j,value)) {
+											//cerr << "checkCodeValuesDoNotContainInappropriateCharacters(): have CodeValue value [" <<j << "] " << value << endl;
+											Uint32 length=0;
+											const char *ptr=value;
+											char c;
+											while (c=*ptr++) {
+												bool bad = false;
+												if (isSNOMED) {
+													if (!isupper(c) && !isdigit(c) && c != '-') {
+														bad = true;
+													}
+												}
+												else if (isDICOM) {
+													if (!isupper(c) && !isdigit(c)) {
+														bad = true;
+													}
+												}
+												if (bad) {
+													log << WMsgDC(CodeValueContainsInvalidCharactersForCodingScheme) << " - value is <" << value << "> - bad character is '" << c << "' - coding scheme is <" << vCodingSchemeDesignator << ">" << endl;
+													//success=false;
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+					delete [] al;
+				}
+			}
+		}
+		{
+			if (!::loopOverListsInSequencesWithLog(a,log,&::checkCodeValuesDoNotContainInappropriateCharacters)) {
+				success=false;
+			}
+		}
+		++listi;
+	}
+	return success;
+}
+
+
+static bool
+checkLongCodeValuesAreLongEnough(AttributeList &list,TextOutputStream &log) {
+	//cerr << "checkLongCodeValuesAreLongEnough():" << endl;
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		{
+			if (a && a->isSequence() && !a->isEmpty()) {
+				//cerr << "checkLongCodeValuesAreLongEnough(): have Sequence" << endl;
+				AttributeList **al;
+				int n;
+				if ((n=a->getLists(&al)) > 0) {
+					//cerr << "checkLongCodeValuesAreLongEnough(): have " << n << " items" << endl;
+					int i;
+					for (i=0; i<n; ++i) {
+						AttributeList *itemList = al[i];
+						Attribute *aLongCodeValue=(*itemList)[TagFromName(LongCodeValue)];
+						//cerr << "checkLongCodeValuesAreLongEnough(): have aLongCodeValue" << endl;
+						if (aLongCodeValue) {
+							Uint16 nValues= aLongCodeValue->getVM();
+							if (nValues > 0) {
+								{
+									int j;
+									for (j=0; j<nValues; ++j) {
+										char *value;
+										if (aLongCodeValue->getValue(j,value)) {
+											//cerr << "checkLongCodeValuesAreLongEnough(): have LongCodeValue value [" <<j << "] " << value << endl;
+											Uint32 length = strlen(value);
+											if (length <= 16) {
+												log << EMsgDC(LongCodeValueTooShort) << " - value is <" << value << "> - length is " << length << endl;
+												success=false;
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+					delete [] al;
+				}
+			}
+		}
+		{
+			if (!::loopOverListsInSequencesWithLog(a,log,&::checkLongCodeValuesAreLongEnough)) {
+				success=false;
+			}
+		}
+		++listi;
+	}
+	return success;
+}
+
+
+static bool
+checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes():" << endl;
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (a->getTag() == TagFromName(MeasurementUnitsCodeSequence)) {
+			if (a && a->isSequence() && !a->isEmpty()) {
+//cerr << "checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(): have MeasurementUnitsCodeSequence" << endl;
+				AttributeList **al;
+				int n;
+				if ((n=a->getLists(&al)) > 0) {
+//cerr << "checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(): have " << n << " items" << endl;
+					int i;
+					for (i=0; i<n; ++i) {
+						AttributeList *itemList = al[i];
+						Attribute *aCodeMeaning=(*itemList)[TagFromName(CodeMeaning)];
+//cerr << "checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(): have CodeMeaning" << endl;
+						if (aCodeMeaning) {
+							Uint16 nValues= aCodeMeaning->getVM();
+							if (nValues > 0) {
+//cerr << "checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(): have CodeMeaning with " << nValues << " values" << endl;
+								int j;
+								for (j=0; j<nValues; ++j) {
+									char *value;
+									if (aCodeMeaning->getValue(j,value)) {
+//cerr << "checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(): have CodeMeaning value [" <<j << "] " << value << endl;
+										Uint32 length=0;
+										const char *ptr=value;
+										while (*ptr++) ++length;
+										if (value[0] == '\'' || value[length-1] == '\''
+										 || value[0] == '\"' || value[length-1] == '\"') {
+											log << WMsgDC(CodeMeaningForMeasurementUnitsBeginsOrEndsWithQuotationCharacters) << " - meaning is <" << value << ">" << endl;
+											//success=false;
+										}
+									}
+								}
+							}
+						}
+					}
+					delete [] al;
+				}
+			}
+		}
+		else {
+			if (!::loopOverListsInSequencesWithLog(a,log,&::checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes)) {
+				success=false;
+			}
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkCodingSchemeDesignatorForMeasurementUnits(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkCodingSchemeDesignatorForMeasurementUnits():" << endl;
+	bool success=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (a && a->isSequence() && !a->isEmpty()) {
+			Tag sequenceTag = a->getTag();
+			bool isInsideUnitsCodeSequence =
+				sequenceTag == TagFromName(MeasurementUnitsCodeSequence)
+			 || sequenceTag == TagFromName(ChannelSensitivityUnitsSequence)
+			 || sequenceTag == TagFromName(MydriaticAgentConcentrationUnitsSequence)
+			 || sequenceTag == TagFromName(MeasuringUnitsSequence)
+			 ;
+			{
+//cerr << "checkCodingSchemeDesignatorForMeasurementUnits(): have Sequence" << sequenceTag << " isInsideUnitsCodeSequence = " << isInsideUnitsCodeSequence << endl;
+				AttributeList **al;
+				int n;
+				if ((n=a->getLists(&al)) > 0) {
+//cerr << "checkCodingSchemeDesignatorForMeasurementUnits(): have " << n << " items" << endl;
+					int i;
+					for (i=0; i<n; ++i) {
+						AttributeList *itemList = al[i];
+						Attribute *aCodingSchemeDesignator=(*itemList)[TagFromName(CodingSchemeDesignator)];
+						if (aCodingSchemeDesignator) {
+//cerr << "checkCodingSchemeDesignatorForMeasurementUnits(): have CodingSchemeDesignator" << endl;
+							Uint16 nValues= aCodingSchemeDesignator->getVM();
+							if (nValues > 0) {
+//cerr << "checkCodingSchemeDesignatorForMeasurementUnits(): have CodingSchemeDesignator with " << nValues << " values" << endl;
+								int j;
+								for (j=0; j<nValues; ++j) {
+									char *value;
+									if (aCodingSchemeDesignator->getValue(j,value)) {
+//cerr << "checkCodingSchemeDesignatorForMeasurementUnits(): have CodingSchemeDesignator value [" <<j << "] " << value << endl;
+										bool isUCUM = strcmp("UCUM",value) == 0;
+										if (isUCUM && !isInsideUnitsCodeSequence && sequenceTag != TagFromName(CodingSchemeIdentificationSequence)) {	// CodingSchemeIdentificationSequence is not a units code sequence, but is a legitimate place for it to be (000462)
+											log << WMsgDC(UCUMCodingSchemeDesignatorIsUsedInSequenceOtherThanUnitsCodeSequence) << " - ";
+											writeTagNumberAndNameToLog(sequenceTag,list.getDictionary(),log);
+											log << endl;
+											//success=false;
+										}
+										else if (!isUCUM && isInsideUnitsCodeSequence) {
+											log << WMsgDC(CodingSchemeDesignatorInUnitsCodeSequenceIsNotUCUM) << " - is " << value << " instead - ";
+											writeTagNumberAndNameToLog(sequenceTag,list.getDictionary(),log);
+											log << endl;
+											//success=false;
+										}
+									}
+								}
+							}
+						}
+					}
+					delete [] al;
+				}
+			}
+			if (!::loopOverListsInSequencesWithLog(a,log,&::checkCodingSchemeDesignatorForMeasurementUnits)) {
+				success=false;
+			}
+		}
+		++listi;
+	}
+	return success;
+}
+
+static bool
+checkPerFrameFunctionalGroupsSequencesAreNotAlreadyPresentInSharedFunctionalGroup(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkPerFrameFunctionalGroupsSequencesAreNotAlreadyPresentInSharedFunctionalGroup():" << endl;
+	bool success=true;
+	Attribute *aSharedFunctionalGroupsSequence = list[TagFromName(SharedFunctionalGroupsSequence)];
+	Attribute *aPerFrameFunctionalGroupsSequence = list[TagFromName(PerFrameFunctionalGroupsSequence)];
+	if (aSharedFunctionalGroupsSequence && aSharedFunctionalGroupsSequence->isSequence() && !aSharedFunctionalGroupsSequence->isEmpty()
+	 && aPerFrameFunctionalGroupsSequence && aPerFrameFunctionalGroupsSequence->isSequence() && !aPerFrameFunctionalGroupsSequence->isEmpty()) {
+		AttributeList **aSharedFunctionalGroupsSequenceLists;
+		int nSharedFunctionalGroupsSequenceItems;
+		if ((nSharedFunctionalGroupsSequenceItems=aSharedFunctionalGroupsSequence->getLists(&aSharedFunctionalGroupsSequenceLists)) == 1) {
+//cerr << "checkPerFrameFunctionalGroupsSequencesAreNotAlreadyPresentInSharedFunctionalGroup(): have single SharedFunctionalGroupsSequence item" << endl;
+			AttributeList *sharedList = aSharedFunctionalGroupsSequenceLists[0];
+			
+			AttributeList **aPerFrameFunctionalGroupsSequenceLists;
+			int nPerFrameFunctionalGroupsSequenceItems;
+			if ((nPerFrameFunctionalGroupsSequenceItems=aPerFrameFunctionalGroupsSequence->getLists(&aPerFrameFunctionalGroupsSequenceLists)) > 0) {
+//cerr << "checkPerFrameFunctionalGroupsSequencesAreNotAlreadyPresentInSharedFunctionalGroup(): have " << nPerFrameFunctionalGroupsSequenceItems << " PerFrameFunctionalGroupsSequence item"s << endl;
+				int i;
+				for (i=0; i<nPerFrameFunctionalGroupsSequenceItems; ++i) {
+					AttributeList *perFrameList = aPerFrameFunctionalGroupsSequenceLists[i];
+					AttributeListIterator listi(*perFrameList);
+					while (!listi) {
+						Attribute *a=listi();
+						if (a && a->isSequence()) {
+							Tag t = a->getTag();
+							if ((*sharedList)[t]) {
+								log << EMsgDC(FunctionalGroupSequenceAlreadyUsedInSharedFunctionalGroupsSequence) << " - ";
+								writeTagNumberAndNameToLog(t,list.getDictionary(),log);
+								log << " - in Per-frame Functional Groups Sequence Item #" << (i+1) << endl;
+								success=false;
+							}
+						}
+						++listi;
+					}
+				}
+			}
+		}
+	}
+	return success;
+}
+
+static bool
+checkCountOfDimensionIndexValuesMatchesDimensionIndexSequence(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkCountOfDimensionIndexValuesMatchesDimensionIndexSequence():" << endl;
+	bool success=true;
+	
+	int nDimensionIndexSequenceSequenceItems = 0;
+	Attribute *aDimensionIndexSequence = list[TagFromName(DimensionIndexSequence)];
+	if (aDimensionIndexSequence && aDimensionIndexSequence->isSequence() && !aDimensionIndexSequence->isEmpty()) {
+		AttributeList **aDimensionIndexSequenceSequenceLists;
+		nDimensionIndexSequenceSequenceItems=aDimensionIndexSequence->getLists(&aDimensionIndexSequenceSequenceLists);
+	}
+
+	Attribute *aPerFrameFunctionalGroupsSequence = list[TagFromName(PerFrameFunctionalGroupsSequence)];
+	if (aPerFrameFunctionalGroupsSequence && aPerFrameFunctionalGroupsSequence->isSequence() && !aPerFrameFunctionalGroupsSequence->isEmpty()) {
+		AttributeList **aPerFrameFunctionalGroupsSequenceLists;
+		int nPerFrameFunctionalGroupsSequenceItems;
+		if ((nPerFrameFunctionalGroupsSequenceItems=aPerFrameFunctionalGroupsSequence->getLists(&aPerFrameFunctionalGroupsSequenceLists)) > 0) {
+			int f;
+			for (f=0; f<nPerFrameFunctionalGroupsSequenceItems; ++f) {
+				AttributeList *perFrameList = aPerFrameFunctionalGroupsSequenceLists[f];
+				Attribute *aFrameContentSequence = (*perFrameList)[TagFromName(FrameContentSequence)];
+				if (aFrameContentSequence && aFrameContentSequence->isSequence() && !aFrameContentSequence->isEmpty()) {
+					AttributeList **aFrameContentSequenceLists;
+					int nFrameContentSequenceItems;
+					if ((nFrameContentSequenceItems=aFrameContentSequence->getLists(&aFrameContentSequenceLists)) > 0) {
+						AttributeList *frameContentSequenceList = aFrameContentSequenceLists[0];	// should only be one so only check one
+						Attribute *aDimensionIndexValues = (*frameContentSequenceList)[TagFromName(DimensionIndexValues)];
+						int nDimensionIndexValues = aDimensionIndexValues ? aDimensionIndexValues->getVM() : 0;
+						if (nDimensionIndexSequenceSequenceItems != nDimensionIndexValues) {
+							log << EMsgDC(NumberOfDimensionIndexValuesDoesNotMatchNumberOfDimensions) << " for frame " << (f+1)
+								<< " got " << nDimensionIndexValues << " - expected " << nDimensionIndexSequenceSequenceItems << endl;
+							success = false;
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	return success;
+}
+
+static bool
+checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex():" << endl;
+	bool success=true;
+	
+	int indexValueThatIsInStackPositionNumber = -1;
+	int indexValueThatIsTemporalPositionIndex = -1;
+	
+	int nDimensionIndexSequenceSequenceItems = 0;
+	Attribute *aDimensionIndexSequence = list[TagFromName(DimensionIndexSequence)];
+	if (aDimensionIndexSequence && aDimensionIndexSequence->isSequence() && !aDimensionIndexSequence->isEmpty()) {
+		AttributeList **aDimensionIndexSequenceSequenceLists;
+		nDimensionIndexSequenceSequenceItems=aDimensionIndexSequence->getLists(&aDimensionIndexSequenceSequenceLists);
+		for (int i=0; i<nDimensionIndexSequenceSequenceItems; ++i) {
+			Attribute *aDimensionIndexPointer = (*(aDimensionIndexSequenceSequenceLists[i]))[TagFromName(DimensionIndexPointer)];
+			if (aDimensionIndexPointer) {
+				Uint32 vDimensionIndexPointer;
+				(void)aDimensionIndexPointer->getValue(0,vDimensionIndexPointer);
+				if (vDimensionIndexPointer == TagFromName(InStackPositionNumber)) {
+					indexValueThatIsInStackPositionNumber = i;
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(): have index of InStackPositionNumber " << dec << indexValueThatIsInStackPositionNumber << endl;
+				}
+				else if (vDimensionIndexPointer == TagFromName(TemporalPositionIndex)) {
+					indexValueThatIsTemporalPositionIndex = i;
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(): have index of TemporalPositionIndex " << dec << indexValueThatIsTemporalPositionIndex << endl;
+				}
+			}
+		}
+	}
+
+
+	Attribute *aPerFrameFunctionalGroupsSequence = list[TagFromName(PerFrameFunctionalGroupsSequence)];
+	if (aPerFrameFunctionalGroupsSequence && aPerFrameFunctionalGroupsSequence->isSequence() && !aPerFrameFunctionalGroupsSequence->isEmpty()) {
+		AttributeList **aPerFrameFunctionalGroupsSequenceLists;
+		int nPerFrameFunctionalGroupsSequenceItems;
+		if ((nPerFrameFunctionalGroupsSequenceItems=aPerFrameFunctionalGroupsSequence->getLists(&aPerFrameFunctionalGroupsSequenceLists)) > 0) {
+			int f;
+			for (f=0; f<nPerFrameFunctionalGroupsSequenceItems; ++f) {
+				AttributeList *perFrameList = aPerFrameFunctionalGroupsSequenceLists[f];
+				Attribute *aFrameContentSequence = (*perFrameList)[TagFromName(FrameContentSequence)];
+				if (aFrameContentSequence && aFrameContentSequence->isSequence() && !aFrameContentSequence->isEmpty()) {
+					AttributeList **aFrameContentSequenceLists;
+					int nFrameContentSequenceItems;
+					if ((nFrameContentSequenceItems=aFrameContentSequence->getLists(&aFrameContentSequenceLists)) > 0) {
+						AttributeList *frameContentSequenceList = aFrameContentSequenceLists[0];	// should only be one so only check one
+						Attribute *aDimensionIndexValues = (*frameContentSequenceList)[TagFromName(DimensionIndexValues)];
+						int nDimensionIndexValues = aDimensionIndexValues ? aDimensionIndexValues->getVM() : 0;
+						
+						Attribute *aInStackPositionNumber = (*frameContentSequenceList)[TagFromName(InStackPositionNumber)];
+						if (indexValueThatIsInStackPositionNumber != -1) {
+							if (aInStackPositionNumber == NULL || aInStackPositionNumber->getVM() == 0) {
+								log << EMsgDC(MissingInStackPositionNumberUsedAsDimensionIndex) << " for frame " << (f+1) << endl;
+								success = false;
+							}
+							else {
+								Uint32 vInStackPositionNumber;
+								(void)aInStackPositionNumber->getValue(0,vInStackPositionNumber);
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(): have InStackPositionNumber " << dec << vInStackPositionNumber << endl;
+						
+								if (indexValueThatIsInStackPositionNumber < nDimensionIndexValues) {
+									Uint32 vDimensionIndexValue;
+									(void)aDimensionIndexValues->getValue(indexValueThatIsInStackPositionNumber,vDimensionIndexValue);
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(): have corresponding DimensionIndexValue " << dec << vDimensionIndexValue << endl;
+									if (vDimensionIndexValue != vInStackPositionNumber) {
+										log << EMsgDC(DimensionIndexValueForInStackPositionNumberDoesNotEqualValueOfInStackPositionNumber) << " for frame " << (f+1)
+											<< " - got DimensionIndexValue " << vDimensionIndexValue << " - expected same value as InStackPositionNumber " << vInStackPositionNumber << endl;
+										success = false;
+									}
+								}
+								else {
+									log << EMsgDC(MissingDimensionIndexValueForInStackPositionNumber) << " for frame " << (f+1) << endl;
+									success = false;
+								}
+							}
+						}
+						
+						Attribute *aTemporalPositionIndex = (*frameContentSequenceList)[TagFromName(TemporalPositionIndex)];
+						if (indexValueThatIsTemporalPositionIndex != -1) {
+							if (aTemporalPositionIndex == NULL || aTemporalPositionIndex->getVM() == 0) {
+								log << EMsgDC(MissingTemporalPositionIndexUsedAsDimensionIndex) << " for frame " << (f+1) << endl;
+								success = false;
+							}
+							else {
+								Uint32 vTemporalPositionIndex;
+								(void)aTemporalPositionIndex->getValue(0,vTemporalPositionIndex);
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(): have TemporalPositionIndex " << dec << vTemporalPositionIndex << endl;
+						
+								if (indexValueThatIsTemporalPositionIndex < nDimensionIndexValues) {
+									Uint32 vDimensionIndexValue;
+									(void)aDimensionIndexValues->getValue(indexValueThatIsTemporalPositionIndex,vDimensionIndexValue);
+//cerr << "checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(): have corresponding DimensionIndexValue " << dec << vDimensionIndexValue << endl;
+									if (vDimensionIndexValue != vTemporalPositionIndex) {
+										log << EMsgDC(DimensionIndexValueForTemporalPositionIndexDoesNotEqualValueOfTemporalPositionIndex) << " for frame " << (f+1)
+											<< " - got DimensionIndexValue " << vDimensionIndexValue << " - expected same value as TemporalPositionIndex " << vTemporalPositionIndex << endl;
+										success = false;
+									}
+								}
+								else {
+									log << EMsgDC(MissingDimensionIndexValueForTemporalPositionIndex) << " for frame " << (f+1) << endl;
+									success = false;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	return success;
+}
+
+static bool
+checkCountPerFrameFunctionalGroupsMatchesNumberOfFrames(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkCountPerFrameFunctionalGroupsMatchesNumberOfFrames():" << endl;
+	bool success=true;
+	
+	Attribute *aPerFrameFunctionalGroupsSequence = list[TagFromName(PerFrameFunctionalGroupsSequence)];
+	if (aPerFrameFunctionalGroupsSequence && aPerFrameFunctionalGroupsSequence->isSequence()) {
+		AttributeList **aPerFrameFunctionalGroupsSequenceLists;
+		int nPerFrameFunctionalGroupsSequenceItems;
+		if ((nPerFrameFunctionalGroupsSequenceItems=aPerFrameFunctionalGroupsSequence->getLists(&aPerFrameFunctionalGroupsSequenceLists)) > 0) {
+			Attribute *aNumberOfFrames=list[TagFromName(NumberOfFrames)];
+			Uint32 vNumberOfFrames = 1;
+			if (aNumberOfFrames) {
+				(void)aNumberOfFrames->getValue(0,vNumberOfFrames);
+			}
+			if (nPerFrameFunctionalGroupsSequenceItems != vNumberOfFrames) {
+				log << EMsgDC(NumberOfPerFrameFunctionalGroupsSequenceItemsDoesNotMatchNumberOfFrames)
+					<< " - have " << nPerFrameFunctionalGroupsSequenceItems << " items - but " << vNumberOfFrames << " frames" << endl;
+				success = false;
+			}
+		}
+	}
+	
+	return success;
+}
+
+static bool
+checkCoordinateContentItemsHaveAppropriateChildren(AttributeList &list,TextOutputStream &log) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren():" << endl;
+	bool success=true;
+	{
+		Attribute *aValueType = list[TagFromName(ValueType)];
+		if (aValueType) {
+			const char *vValueType=AttributeValue(aValueType);
+			if (vValueType && (strcmp(vValueType,"SCOORD") == 0 || strcmp(vValueType,"TCOORD") == 0)) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): have SCOORD" << endl;
+				bool foundAppropriateChildOrIsByReferenceRelationship = false;
+				const char *vChildValueType = NULL;
+				Attribute *aContentSequence = list[TagFromName(ContentSequence)];
+				if (aContentSequence && aContentSequence->isSequence() && !aContentSequence->isEmpty()) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): have ContentSequence for children" << endl;
+					AttributeList **al;
+					int n;
+					if ((n=aContentSequence->getLists(&al)) > 0) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): have " << n << " items" << endl;
+						int i;
+						for (i=0; i<n; ++i) {
+							AttributeList *itemList = al[i];
+							Attribute *aChildValueType=(*itemList)[TagFromName(ValueType)];
+							if (aChildValueType) {
+								vChildValueType=AttributeValue(aChildValueType);
+								if (vChildValueType &&
+										(strcmp(vValueType,"SCOORD") == 0 && strcmp(vChildValueType,"IMAGE") == 0)
+									 || (strcmp(vValueType,"TCOORD") == 0 && (strcmp(vChildValueType,"SCOORD") == 0 || strcmp(vChildValueType,"IMAGE") == 0 || strcmp(vChildValueType,"WAVEFORM") == 0))
+									) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): foundAppropriateChild " << vChildValueType << endl;
+									foundAppropriateChildOrIsByReferenceRelationship = true;
+								}
+							}
+							else {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): no child ValueType" << endl;
+								Attribute *aReferencedContentItemIdentifier=(*itemList)[TagFromName(ReferencedContentItemIdentifier)];
+								if (aReferencedContentItemIdentifier) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): have ReferencedContentItemIdentifier" << endl;
+									if (aReferencedContentItemIdentifier->getVM() > 0) {
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): found by-Reference Relationship" << endl;
+										foundAppropriateChildOrIsByReferenceRelationship = true;
+										// too hard to actually check if target of reference is legitimate :(
+									}
+								}
+							}
+							
+							bool foundAppropriateRelationship = false;
+							const char *vRelationshipType = NULL;
+							Attribute *aRelationshipType=(*itemList)[TagFromName(RelationshipType)];
+							if (aRelationshipType) {
+								vRelationshipType=AttributeValue(aRelationshipType);
+//cerr << "checkCoordinateContentItemsHaveAppropriateChildren(): foundAppropriateRelationship <" << vRelationshipType << ">" << endl;
+								if (vRelationshipType && strcmp(vRelationshipType,"SELECTED FROM") == 0) {
+									foundAppropriateRelationship = true;
+								}
+							}
+							if (!foundAppropriateRelationship) {
+								log << EMsgDC(CoordinatesContentItemHasIncorrectRelationshipChildContentItem) << " for " << vValueType
+									<< " got " << (vRelationshipType ? vRelationshipType : "no relationship") << " - expected SELECTED FROM" << endl;
+								success=false;
+							}
+						}
+						delete [] al;
+					}
+				}
+				if (!foundAppropriateChildOrIsByReferenceRelationship) {
+					log << EMsgDC(CoordinatesContentItemMissingOrIncorrectRequiredChildContentItem) << " for " << vValueType
+						<< " got " << (vChildValueType ? vChildValueType : "no child")
+						<< " expected " << (strcmp(vValueType,"SCOORD") == 0 ? "IMAGE" : "SCOORD, IMAGE or WAVEFORM")
+						<< endl;
+					success=false;
+				}
+			}
+		}
+	}
+	
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::checkCoordinateContentItemsHaveAppropriateChildren)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+static AttributeList *
+findInstanceInHierarchicalEvidenceSequence(Attribute *aEvidenceSequence,const char *vSOPInstanceUID) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences():" << endl;
+	if (vSOPInstanceUID && aEvidenceSequence && aEvidenceSequence->isSequence() && !aEvidenceSequence->isEmpty()) {
+		AttributeList **alstudy;
+		int nstudy;
+		if ((nstudy=aEvidenceSequence->getLists(&alstudy)) > 0) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have " << nstudy << " EvidenceSequence items" << endl;
+			int istudy;
+			for (istudy=0; istudy<nstudy; ++istudy) {
+				AttributeList *itemListStudy = alstudy[istudy];
+				Attribute *aReferencedSeriesSequence=(*itemListStudy)[TagFromName(ReferencedSeriesSequence)];
+				if (aReferencedSeriesSequence && aReferencedSeriesSequence->isSequence() && !aReferencedSeriesSequence->isEmpty()) {
+					AttributeList **alseries;
+					int nseries;
+					if ((nseries=aReferencedSeriesSequence->getLists(&alseries)) > 0) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have " << nseries << " ReferencedSeriesSequence items" << endl;
+						int iseries;
+						for (iseries=0; iseries<nseries; ++iseries) {
+							AttributeList *itemListSeries = alseries[iseries];
+							Attribute *aReferencedSOPSequence=(*itemListSeries)[TagFromName(ReferencedSOPSequence)];
+							if (aReferencedSOPSequence && aReferencedSOPSequence->isSequence() && !aReferencedSOPSequence->isEmpty()) {
+								AttributeList **alinstance;
+								int ninstance;
+								if ((ninstance=aReferencedSOPSequence->getLists(&alinstance)) > 0) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have " << ninstance << " ReferencedSOPSequence items" << endl;
+									int iinstance;
+									for (iinstance=0; iinstance<ninstance; ++iinstance) {
+										AttributeList *itemListInstance = alinstance[iinstance];
+										Attribute *aReferencedSOPInstanceUID=(*itemListInstance)[TagFromName(ReferencedSOPInstanceUID)];
+										if (aReferencedSOPInstanceUID) {
+											const char *vReferencedSOPInstanceUID=AttributeValue(aReferencedSOPInstanceUID);
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have ReferencedSOPInstanceUID " << vReferencedSOPInstanceUID << endl;
+											if (vReferencedSOPInstanceUID && strcmp(vSOPInstanceUID,vReferencedSOPInstanceUID) == 0) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): found match ReferencedSOPInstanceUID " << vReferencedSOPInstanceUID << endl;
+												return itemListInstance;
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	return NULL;
+}
+
+static bool
+findInstanceInHierarchicalEvidenceSequences(AttributeList &list,const char *vSOPInstanceUID,const char *vSOPClassUID,const char *vValueType,const char *subType,TextOutputStream &log) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences():" << endl;
+	bool success = false;
+	AttributeList *foundList = NULL;
+	Attribute *aCurrentRequestedProcedureEvidenceSequence = list[TagFromName(CurrentRequestedProcedureEvidenceSequence)];
+	Attribute *aPertinentOtherEvidenceSequence = list[TagFromName(PertinentOtherEvidenceSequence)];
+	if (aCurrentRequestedProcedureEvidenceSequence) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have CurrentRequestedProcedureEvidenceSequence" << endl;
+		foundList = findInstanceInHierarchicalEvidenceSequence(aCurrentRequestedProcedureEvidenceSequence,vSOPInstanceUID);
+	}
+	if (!foundList && aPertinentOtherEvidenceSequence) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have PertinentOtherEvidenceSequence" << endl;
+		foundList = findInstanceInHierarchicalEvidenceSequence(aPertinentOtherEvidenceSequence,vSOPInstanceUID);
+	}
+	if (foundList) {
+		success	= true;
+		Attribute *aReferencedSOPClassUID=(*foundList)[TagFromName(ReferencedSOPClassUID)];
+		if (aReferencedSOPClassUID) {
+			const char *vReferencedSOPClassUID=AttributeValue(aReferencedSOPClassUID);
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): have vReferencedSOPClassUID " << vReferencedSOPClassUID << endl;
+			if (vReferencedSOPClassUID && strcmp(vSOPClassUID,vReferencedSOPClassUID) == 0) {
+//cerr << "findInstanceInHierarchicalEvidenceSequences(): found match ReferencedSOPClassUID " << vSOPClassUID << endl;
+			}
+			else {
+				log << EMsgDC(SOPClassInCurrentRequestedProcedureOrPertinentOtherEvidenceSequenceDoesNotMatchReference)
+					<< " for " << vValueType << " " << (subType ? " " : "") << (subType ? subType : "") << " ReferencedSOPInstanceUID " << (vSOPInstanceUID ? vSOPInstanceUID : "missing or empty SOPInstanceUID")
+					<< " " << vValueType << " ReferencedSOPClassUID is " << vSOPClassUID << " but evidence ReferencedSOPClassUID is " << vReferencedSOPClassUID
+					<< endl;
+				success	= false;
+			}
+		}
+	}
+	else {
+		log << EMsgDC(NotListedInCurrentRequestedProcedureOrPertinentOtherEvidenceSequence)
+			<< " but have " << vValueType << (subType ? " " : "") << (subType ? subType : "") << " ReferencedSOPInstanceUID " << (vSOPInstanceUID ? vSOPInstanceUID : "missing or empty SOPInstanceUID") << endl;
+	}
+	return success;
+}
+
+static bool
+checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences(AttributeList &rootlist,AttributeList &list,TextOutputStream &log) {
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():" << endl;
+	bool success=true;
+
+	{
+		Attribute *aValueType = list[TagFromName(ValueType)];
+		if (aValueType) {
+			const char *vValueType=AttributeValue(aValueType);
+			if (vValueType && (strcmp(vValueType,"IMAGE") == 0 || strcmp(vValueType,"COMPOSITE") == 0 || strcmp(vValueType,"WAVEFORM") == 0)) {
+				const char *vReferencedSOPInstanceUID = NULL;
+				const char *vReferencedSOPClassUID = NULL;
+				const char *vPresentationStateReferencedSOPInstanceUID = NULL;
+				const char *vPresentationStateReferencedSOPClassUID = NULL;
+				const char *vRealWorldValueReferencedSOPInstanceUID = NULL;
+				const char *vRealWorldValueReferencedSOPClassUID = NULL;
+				Attribute *aReferencedSOPSequence=list[TagFromName(ReferencedSOPSequence)];
+				if (aReferencedSOPSequence && aReferencedSOPSequence->isSequence() && !aReferencedSOPSequence->isEmpty()) {
+					AttributeList **alinstance;
+					int ninstance;
+					if ((ninstance=aReferencedSOPSequence->getLists(&alinstance)) > 0) {
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences(): in " <<vValueType  << " have " << ninstance << " ReferencedSOPSequence items" << endl;
+						int iinstance;
+						for (iinstance=0; iinstance<ninstance; ++iinstance) {
+							AttributeList *itemListInstance = alinstance[iinstance];
+							Attribute *aReferencedSOPInstanceUID=(*itemListInstance)[TagFromName(ReferencedSOPInstanceUID)];
+							if (aReferencedSOPInstanceUID) {
+								vReferencedSOPInstanceUID=AttributeValue(aReferencedSOPInstanceUID);
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():  in " << vValueType  << " have ReferencedSOPInstanceUID " << vReferencedSOPInstanceUID << endl;
+							}
+							Attribute *aReferencedSOPClassUID=(*itemListInstance)[TagFromName(ReferencedSOPClassUID)];
+							if (aReferencedSOPClassUID) {
+								vReferencedSOPClassUID=AttributeValue(aReferencedSOPClassUID);
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():  in " << vValueType  << " have ReferencedSOPClassUID " << vReferencedSOPClassUID << endl;
+							}
+							
+							Attribute *aPresentationStateReferencedSOPSequence=(*itemListInstance)[TagFromName(ReferencedSOPSequence)];
+							if (aPresentationStateReferencedSOPSequence && aPresentationStateReferencedSOPSequence->isSequence() && !aPresentationStateReferencedSOPSequence->isEmpty()) {
+								AttributeList **alpresentationstate;
+								int npresentationstate;
+								if ((npresentationstate=aPresentationStateReferencedSOPSequence->getLists(&alpresentationstate)) > 0) {
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences(): in " << vValueType  << " have " << npresentationstate << " ReferencedSOPSequence items" << endl;
+									int ipresentationstate;
+									for (ipresentationstate=0; ipresentationstate<npresentationstate; ++ipresentationstate) {
+										AttributeList *itemListPresentationStateInstance = alpresentationstate[ipresentationstate];
+										Attribute *aPresentationStateReferencedSOPInstanceUID=(*itemListPresentationStateInstance)[TagFromName(ReferencedSOPInstanceUID)];
+										if (aPresentationStateReferencedSOPInstanceUID) {
+											vPresentationStateReferencedSOPInstanceUID=AttributeValue(aPresentationStateReferencedSOPInstanceUID);
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():  in " << vValueType  << " have Presentation State ReferencedSOPInstanceUID " << vPresentationStateReferencedSOPInstanceUID << endl;
+										}
+										Attribute *aPresentationStateReferencedSOPClassUID=(*itemListPresentationStateInstance)[TagFromName(ReferencedSOPClassUID)];
+										if (aPresentationStateReferencedSOPClassUID) {
+											vPresentationStateReferencedSOPClassUID=AttributeValue(aPresentationStateReferencedSOPClassUID);
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():  in " <<vValueType  << " have Presentation State ReferencedSOPClassUID " << vPresentationStateReferencedSOPClassUID << endl;
+										}
+									}
+								}
+							}
+							
+							Attribute *aReferencedRealWorldValueMappingInstanceSequence=(*itemListInstance)[TagFromName(ReferencedRealWorldValueMappingInstanceSequence)];
+							if (aReferencedRealWorldValueMappingInstanceSequence && aReferencedRealWorldValueMappingInstanceSequence->isSequence() && !aReferencedRealWorldValueMappingInstanceSequence->isEmpty()) {
+								AttributeList **alRealWorldValue;
+								int nRealWorldValue;
+								if ((nRealWorldValue=aReferencedRealWorldValueMappingInstanceSequence->getLists(&alRealWorldValue)) > 0) {
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences(): in " << vValueType  << " have " << nRealWorldValue << " ReferencedRealWorldValueMappingInstanceSequence items" << endl;
+									int iRealWorldValue;
+									for (iRealWorldValue=0; iRealWorldValue<nRealWorldValue; ++iRealWorldValue) {
+										AttributeList *itemListRealWorldValue = alRealWorldValue[iRealWorldValue];
+										Attribute *aRealWorldValueReferencedSOPInstanceUID=(*itemListRealWorldValue)[TagFromName(ReferencedSOPInstanceUID)];
+										if (aRealWorldValueReferencedSOPInstanceUID) {
+											vRealWorldValueReferencedSOPInstanceUID=AttributeValue(aRealWorldValueReferencedSOPInstanceUID);
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():  in " << vValueType  << " have Real World Value Mapping ReferencedSOPInstanceUID " << vRealWorldValueReferencedSOPInstanceUID << endl;
+										}
+										Attribute *aRealWorldValueReferencedSOPClassUID=(*itemListRealWorldValue)[TagFromName(ReferencedSOPClassUID)];
+										if (aRealWorldValueReferencedSOPClassUID) {
+											vRealWorldValueReferencedSOPClassUID=AttributeValue(aRealWorldValueReferencedSOPClassUID);
+//cerr << "checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences():  in " <<vValueType  << " have Real World Value Mapping ReferencedSOPClassUID " << vRealWorldValueReferencedSOPClassUID << endl;
+										}
+									}
+								}
+							}
+							
+						}
+					}
+				}
+				
+				if (!findInstanceInHierarchicalEvidenceSequences(rootlist,vReferencedSOPInstanceUID,vReferencedSOPClassUID,vValueType,NULL,log)) {
+					success=false;
+				}
+				// presentation state is optional, so do not check if no referenced
+				if (vPresentationStateReferencedSOPInstanceUID && !findInstanceInHierarchicalEvidenceSequences(rootlist,vPresentationStateReferencedSOPInstanceUID,vPresentationStateReferencedSOPClassUID,vValueType,"PresentationState",log)) {
+					success=false;
+				}
+				// real world value mapping is optional, so do not check if no referenced
+				if (vRealWorldValueReferencedSOPInstanceUID && !findInstanceInHierarchicalEvidenceSequences(rootlist,vRealWorldValueReferencedSOPInstanceUID,vRealWorldValueReferencedSOPClassUID,vValueType,"RealWorldValueMapping",log)) {
+					success=false;
+				}
+			}
+		}
+	}
+
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithRootListAndLog(rootlist,a,log,&::checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences)) {
+			success=false;
+		}
+		++listi;
+	}
+	return success;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool describe=options.get("describe");
+	bool dump=options.get("dump");
+	bool showfilename=options.get("filename");
+	
+	const char *profile = NULL;
+	(void)(options.get("profile",profile));
+
+	bool bad=false;
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-profile profilename]"
+			<< " [-describe]"
+			<< " [-dump]"
+			<< " [-filename]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		log << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+	
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit,
+		false/*useStopAtTag*/,Tag(0,0)/*stopAtTag*/,false/*fixBitsDuringRead*/);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	
+	// do not && each of these with success, else no function gets called after first failure !
+	
+	if (!checkMetaInformationMatchesSOPInstance(list,log)) success = false;
+	
+	if (!checkPixelDataIsTheCorrectLength(list,log)) success = false;
+	
+	if (!checkWaveformSequenceIsInternallyConsistent(list,log)) success = false;
+	
+	if (!checkNoIllegalOddNumberedGroups(list,log)) success = false;
+	
+	if (!checkLUTDataValuesMatchSpecifiedRange(list,log)) success = false;
+	
+	if (!checkNoEmptyReferencedFileIDComponents(list,log)) success = false;
+	
+	if (!checkFrameIncrementPointerValuesValid(list,log)) success = false;
+	
+	if (!checkFrameVectorCountsValid(list,log)) success = false;
+	
+	if (!checkPixelAspectRatioValidIfPresent(list,log)) success = false;
+	
+	if (!checkEstimatedRadiographicMagnificationFactorIfPresent(list,log)) success = false;
+	
+	if (!checkPixelSpacingCalibration(list,log)) success = false;
+	
+	if (!checkOrientationsAreUnitVectors(list,log)) success = false;
+	
+	if (!checkOrientationsAreOrthogonal(list,log)) success = false;
+	
+	if (!checkPatientOrientationValuesForBipedOrQuadruped(list,log)) success = false;
+	
+	if (!checkScaledNumericValues(list,log)) success = false;
+	
+	if (!checkSpacingBetweenSlicesIsNotNegative(list,log)) success = false;
+	
+	if (!checkUIDs(list,log)) success = false;
+
+	if (!checkPresentationStateDisplayedAreaSelectionValuesAreValid(list,log)) success = false;
+	
+	if (!checkCodeValuesDoNotContainInappropriateCharacters(list,log)) success = false;
+	
+	if (!checkLongCodeValuesAreLongEnough(list,log)) success = false;
+	
+	if (!checkCodeMeaningsForMeasurementUnitsDoNotContainInappropriateQuotes(list,log)) success = false;
+	
+	if (!checkCodingSchemeDesignatorForMeasurementUnits(list,log)) success = false;
+	
+	if (!checkCoordinateContentItemsHaveAppropriateChildren(list,log)) success = false;
+	
+	if (!checkInstanceReferencesAreIncludedInHierarchicalEvidenceSequences(list,list,log)) success = false;
+	
+	if (!checkPerFrameFunctionalGroupsSequencesAreNotAlreadyPresentInSharedFunctionalGroup(list,log)) success = false;
+	
+	if (!checkCountOfDimensionIndexValuesMatchesDimensionIndexSequence(list,log)) success = false;
+	
+	if (!checkDimensionIndexValuesMatchInStackPositionNumberAndTemporalPositionIndex(list,log)) success = false;
+	
+	if (!checkCountPerFrameFunctionalGroupsMatchesNumberOfFrames(list,log)) success = false;
+	
+	if (!list.validatePrivate(log)) success = false;
+	
+	checkValuesNeededToBuildDicomDirectoryArePresentAndNotEmpty(list,log);	// always only warnings ... do not affect success
+	
+	if (verbose) log << "success after manual checks " << (success ? "success" : "failure") << endl;
+
+	if (!list.validateVR(log)) {
+		log << EMsgDC(DataSetContainsInvalidValuesForVR)
+		    << endl;
+		success=false;
+	}
+	if (verbose) log << "success after validateVR " << (success ? "success" : "failure") << endl;
+
+	if (!list.validateRetired(log)) {
+		log << WMsgDC(DataSetContainsRetiredAttributes)
+		    << endl;
+	}
+
+	CompositeIOD *iod = selectCompositeIOD(&list,profile);
+	if (iod) {
+		log << iod->identify() << endl;
+		if (iod->retired()) {
+		log << WMsgDC(InformationObject)
+		    << " "
+		    << MMsgDC(Retired)
+		    << endl;
+		}
+		if (!iod->verify(&list,verbose,log,list.getDictionary())) success=false;
+		if (describe || verbose) iod->write(log,&list,list.getDictionary());
+	}
+	else {
+		log << EMsgDC(InformationObject)
+		    << " "
+		    << MMsgDC(NotFound)
+		    << endl;
+		success=false;
+	}
+	if (verbose) log << "success after iod verify " << (success ? "success" : "failure") << endl;
+
+	if (iod && !list.validateUsed(log)) {
+		log << WMsgDC(DataSetContainsAttributesNotUsedInIOD)
+		    << endl;
+	}
+	
+	if (dump) {
+		list.write(log,verbose,true/*showUsedAndIE*/);
+	}
+	if (verbose) log << "success at end " << (success ? "success" : "failure") << endl;
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dciodvfy.man b/appsrc/dcfile/dciodvfy.man
new file mode 100755
index 0000000..e3d6a0a
--- /dev/null
+++ b/appsrc/dcfile/dciodvfy.man
@@ -0,0 +1,125 @@
+.TH DCIODVFY 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Validate DICOM objects"
+.SH NAME
+dciodvfy \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Validate DICOM objects
+.SH SYNOPSIS
+.HP 10
+.B dciodvfy
+.so man1/gen.so
+[
+.B \-profile profilename
+]
+[
+.B \-describe
+]
+[
+.B \-dump
+]
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dciodvfy
+reads the named dicom file and describes the type of information object
+(SOP class instance) contained therein, validating it against the standard
+and checking for required modules and attributes, and appropriate
+representation and values of attributes.
+.SH OPTIONS
+The description and verbose output go to standard error.
+.LP
+Binary attributes are written in hexadecimal with a preceding
+"0x". Numeric string attributes are written in decimal. Attribute values
+are displayed in hexadecimal or string format as determined by the value representation.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-profile profilename
+.RS
+Validate not against the standard but the IOD matching the named profile.
+.RE
+.TP
+.B \-describe
+.RS
+Describe the contents of the object without getting too verbose.
+.RE
+.TP
+.B \-dump
+.RS
+Dump the attribute list; differs from dcdump in that the list is decorated with whether or
+not the attribute is used in the IOD and what information entity the attribute belongs to based on the IOD.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dciodvfy test.dc3
+.RE
+Warning - Value dubious for this VR - (0x0008,0x0090) ...
+.RE
+            Retired Person Name form 
+.RE
+MRImage 
+.RE
+Error - Missing attribute Type 1 Required ...
+.RE
+          Element=<FileMetaInformationVersion> Module=...
+.RE
+
+.RE
+% dciodvfy -describe test.dc3
+.RE
+Warning - Value dubious for this VR - (0x0008,0x0090) ...
+.RE
+            Retired Person Name form 
+.RE
+MRImage 
+.RE
+Error - Missing attribute Type 1 Required ...
+.RE
+          Element=<FileMetaInformationVersion> Module=...
+.RE
+        CompositeIOD <MRImage>
+.RE
+        Module <FileMetaInformation>
+.RE
+ ...
+.RE
+                (0x0002,0x0010) UI Transfer Syntax UID ...
+.RE
+...
+.RE
+        Module <Patient>
+.RE
+                (0x0010,0x0010) PN Patient's Name ... 
+.RE
+...
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcentvfy(1) ,
+.BR dcdump(1) ,
+.BR dcfile(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcj2k.man b/appsrc/dcfile/dcj2k.man
new file mode 100755
index 0000000..fd4e9e7
--- /dev/null
+++ b/appsrc/dcfile/dcj2k.man
@@ -0,0 +1,59 @@
+.TH DCJ2K 1 "29 July 2007" "DICOM PS3" "DICOM PS3 - Create J2K DICOM file"
+.SH NAME
+dcj2k \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create J2K DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcj2k "infile" "outfile" kduoptions
+.SH DESCRIPTION
+.LP
+.B dcj2k
+reads the named dicom input file and copies the information and
+pixel data to a new dicom file, with the dataset compressed using the specified
+J2K compression options and transfer syntax, and with a meta information header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options other than thosed passed through to the Kakadu kdu_compress JPEG 2000 codec.
+.LP
+The default with no options is lossless (reversible) compression.
+.LP
+The sample precision (bit depth) and signedness are extracted from the DICOM header and passed to the codec unchanged.
+.LP
+The transfer syntax 1.2.840.10008.1.2.4.90 is chosen if reversible compression is in use, otherwise
+the transfer syntax used is 1.2.840.10008.1.2.4.91.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+# Create a lossless (reversible) compressed image
+.RE
+% dcj2k in.dcm out.dcm
+.RE
+\ 
+.RE
+# or
+.RE
+% dcj2k in.dcm out.dcm Creversible=yes
+.RE
+\ 
+.RE
+# Create a lossy compressed image with 1.0 bits per pixel
+.RE
+% dcj2k in.dcm out.dcm -rate 1.0
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcunjpeg(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Only single sample (not color) compression is supported for now.
+.LP
+Kakadu is the only codec currently supported ... auto-detection of what is installed would be nice.
+
diff --git a/appsrc/dcfile/dcj2k.script b/appsrc/dcfile/dcj2k.script
new file mode 100755
index 0000000..caab5e0
--- /dev/null
+++ b/appsrc/dcfile/dcj2k.script
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# usage: dcj2k infile outfile j2koptions
+#
+# e.g. no arguments or "Creversible=yes" is lossless
+# e.g. "Creversible=no" is lossy at default rate
+# e.g. "-rate 1.0" is lossy with specified rate
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+DCCP=dccp
+DCTORAW=dctoraw
+DCKEY=dckey
+DCENCAP=dcencap
+J2KCOMPRESS=kdu_compress
+
+infile="$1"
+shift
+outfile="$1"
+shift
+j2koptions="$*"
+
+if [ -z "${j2koptions}" ]
+then
+	j2koptions="Creversible=yes"
+fi
+
+reversible=`echo "${j2koptions}" | grep "reversible=yes"`
+if [ -z "${reversible}" ]
+then
+	transfersyntax="1.2.840.10008.1.2.4.91"
+	compressionattributes="-r LossyImageCompression 01 -r LossyImageCompressionMethod ISO_15444_1"
+	addcompressionratio="yes"
+else
+	transfersyntax="1.2.840.10008.1.2.4.90"
+fi
+
+components=`$DCKEY -noerror -d -k SamplesPerPixel "${infile}" 2>&1 | grep -iv '(warning|error)'`
+if [ "${components}" != 1 ]
+then
+	echo 1>&2 "Only grayscale images supported"
+	exit 1
+fi
+
+precision=`$DCKEY -noerror -d -k BitsStored "${infile}" 2>&1 | grep -iv '(warning|error)'`
+signed=`$DCKEY -noerror -d -k PixelRepresentation "${infile}" 2>&1 | grep -iv '(warning|error)'`
+if [ -z "${signed}" ]
+then
+	signed="no"
+elif [ ${signed} = 0 ]
+then
+	signed="no"
+else
+	signed="yes"
+fi
+
+width=`$DCKEY -noerror -d -k Columns "${infile}" 2>&1 | grep -iv '(warning|error)'`
+height=`$DCKEY -noerror -d -k Rows "${infile}" 2>&1 | grep -iv '(warning|error)'`
+
+$DCCP -d PixelData "${infile}" "${TMPROOT}.header" -nodisclaimer -noadddicom
+$DCCP "${infile}" "${TMPROOT}.big.dcm" -endian big -vr explicit
+$DCTORAW -quiet "${TMPROOT}.big.dcm" "${TMPROOT}.big.raw"
+rm "${TMPROOT}.big.dcm"
+$J2KCOMPRESS -i "${TMPROOT}.big.raw" -o "${TMPROOT}.j2c" Sdims=\{"${height}","${width}"\} Sprecision="${precision}" Ssigned="${signed}" ${j2koptions} 	# creates $TMPROOT.big.raw.jpg
+if [ "${addcompressionratio}" = "yes" ]
+then
+	uncompressedfilesize=`ls -l "${TMPROOT}.big.raw" | awk '{print $5}'`
+	#echo 1>&2 "============== uncompressedfilesize = ${uncompressedfilesize}"
+	compressedfilesize=`ls -l "${TMPROOT}.j2c" | awk '{print $5}'`
+	#echo 1>&2 "============== compressedfilesize = ${compressedfilesize}"
+	compressionratio=`echo "scale=2; ${uncompressedfilesize}/${compressedfilesize}" | bc -l`
+	#echo 1>&2 "============== compressionratio = ${compressionratio}"
+	compressionattributes="${compressionattributes} -r LossyImageCompressionRatio ${compressionratio}"
+fi
+rm "${TMPROOT}.big.raw"
+$DCENCAP "${TMPROOT}.header" "${TMPROOT}.j2c" -ts "${transfersyntax}" -of "${outfile}" ${compressionattributes} -nodisclaimer -noadddicom
+rm "${TMPROOT}.header" "${TMPROOT}.j2c"
+
+exit 0
diff --git a/appsrc/dcfile/dcjls.man b/appsrc/dcfile/dcjls.man
new file mode 100755
index 0000000..64e777e
--- /dev/null
+++ b/appsrc/dcfile/dcjls.man
@@ -0,0 +1,43 @@
+.TH DCJLS 1 "09 August 2006" "DICOM PS3" "DICOM PS3 - Create JPEG-LS DICOM file"
+.SH NAME
+dcjls \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create JPEG-LS DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcjls "infile" "outfile" "transfersyntax" [nearlosslessvalue]
+.SH DESCRIPTION
+.LP
+.B dcjls
+reads the named dicom input file and copies the information and
+pixel data to a new dicom file, with the dataset compressed with the 
+lossless or near-lossless JPEG-LS (14495-1) algorithm, depending on whether
+or not a near-lossless value is specified.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+# Create a lossless compressed image
+.RE
+% dcjls in.dcm out.dcm
+.RE
+\ 
+.RE
+# Create a lossy compressed 8 bit image with a near-lossless pixel value error limit of 4
+.RE
+% dcjls in.dcm out.dcm 4
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcunjls(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcjls.script b/appsrc/dcfile/dcjls.script
new file mode 100755
index 0000000..0bd25d4
--- /dev/null
+++ b/appsrc/dcfile/dcjls.script
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# usage: dcjls infile outfile [nearlosslessvalue]
+#
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+DCCP=dccp
+DCTORAW=dctoraw
+DCKEY=dckey
+DCENCAP=dcencap
+JLS=rawnjl2
+
+infile="$1"
+shift
+outfile="$1"
+shift
+nearlosslessvalue="$1"
+shift
+
+if [ -z "$nearlosslessvalue" ]
+then
+	transfersyntax="1.2.840.10008.1.2.4.80"
+	jlsoptions=""
+else
+	transfersyntax="1.2.840.10008.1.2.4.81"
+	jlsoptions="-near $nearlosslessvalue"
+fi
+
+components=`$DCKEY -d -k SamplesPerPixel "$infile"  2>&1 | egrep -v 'Error|Warning'`
+if [ "$components" != 1 ]
+then
+	echo 1>&2 "Only grayscale images supported"
+	exit 1
+fi
+
+precision=`$DCKEY -d -k BitsStored "$infile"  2>&1 | egrep -v 'Error|Warning'`
+if [ $precision -gt 16 ]
+then
+	echo 1>&2 "Only up to 16 bits supported"
+	exit 1
+fi
+
+width=`$DCKEY -d -k Columns "$infile"  2>&1 | egrep -v 'Error|Warning'`
+height=`$DCKEY -d -k Rows "$infile"  2>&1 | egrep -v 'Error|Warning'`
+
+$DCCP -d PixelData "$infile" "$TMPROOT.header"
+$DCCP "$infile" "$TMPROOT.little.dcm" -endian little -vr explicit
+$DCTORAW -quiet "$TMPROOT.little.dcm" "$TMPROOT.little.raw"
+rm "$TMPROOT.little.dcm"
+$JLS -h "$height" -w "$width" -bits "$precision" -input-endian little $jlsoptions "$TMPROOT.little.raw" "$TMPROOT.little.raw.jls"
+
+rm "$TMPROOT.little.raw"
+$DCENCAP "$TMPROOT.header" "$TMPROOT.little.raw.jls" -ts "$transfersyntax" -of "$outfile"
+rm "$TMPROOT.header" "$TMPROOT.little.raw.jls"
+
+exit 0
diff --git a/appsrc/dcfile/dcjpeg.man b/appsrc/dcfile/dcjpeg.man
new file mode 100755
index 0000000..aeb090f
--- /dev/null
+++ b/appsrc/dcfile/dcjpeg.man
@@ -0,0 +1,63 @@
+.TH DCJPEG 1 "19 April 2009" "DICOM PS3" "DICOM PS3 - Create JPEG DICOM file"
+.SH NAME
+dcjpeg \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create JPEG DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcjpeg "infile" "outfile" "transfersyntax" jpegoptions
+.SH DESCRIPTION
+.LP
+.B dcjpeg
+reads the named dicom input file and copies the information and
+pixel data to a new dicom file, with the dataset compressed using the specified
+JPEG compression options and transfer syntax, and with a meta information header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options other than thosed passed through to the Stanford PVRG jpeg codec.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+# Create a lossless compressed image with predictor 1
+.RE
+% dcjpeg in.dcm out.dcm 1.2.840.10008.1.2.4.70 -k 1
+.RE
+\ 
+.RE
+# Create a lossy compressed 8 bit image with high quality
+.RE
+% dcjpeg in.dcm out.dcm 1.2.840.10008.1.2.4.50 -q 1
+.RE
+\ 
+.RE
+# Create a lossy compressed 12 bit image with high quality
+.RE
+% dcjpeg in.dcm out.dcm 1.2.840.10008.1.2.4.51 -ql 1
+.RE
+% ls -sk1 in.dcm out.dcm
+ 520 in.dcm
+ 184 out.dcm
+.RE
+\ 
+.RE
+# Create a lossy compressed 12 bit image with moderate quality
+.RE
+% dcjpeg in.dcm out.dcm 1.2.840.10008.1.2.4.51 -ql 200
+.RE
+% ls -sk1 in.dcm out.dcm
+ 520 in.dcm
+  32 out.dcm
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcunjpeg(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Only single frame images are supported.
diff --git a/appsrc/dcfile/dcjpeg.script b/appsrc/dcfile/dcjpeg.script
new file mode 100755
index 0000000..162571b
--- /dev/null
+++ b/appsrc/dcfile/dcjpeg.script
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# usage: dcjpeg infile outfile transfersyntax jpegoptions
+#
+# e.g. "1.2.840.10008.1.2.4.70 -k 1" is lossless with predictor 1
+# e.g. "1.2.840.10008.1.2.4.50 -q 1" is lossy 8 bit table with high quality
+# e.g. "1.2.840.10008.1.2.4.51 -ql 1" is lossy 16 bit table with high quality
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+DCCP=dccp
+DCTORAW=dctoraw
+DCKEY=dckey
+DCENCAP=dcencap
+JPEG=jpeg
+
+infile="$1"
+shift
+outfile="$1"
+shift
+transfersyntax="$1"
+shift
+
+components=`$DCKEY -d -k SamplesPerPixel "$infile" 2>&1`
+if [ "$components" != 1 ]
+then
+	echo 1>&2 "Only grayscale images supported"
+	exit 1
+fi
+
+precision=`$DCKEY -d -k BitsStored "$infile" 2>&1`
+if [ $precision -gt 12 ]
+then
+	if [ "$transfersyntax" = "1.2.840.10008.1.2.4.51" ]
+	then
+		echo 1>&2 "Only up to 12 bits supported for extended process lossy compression"
+		exit 1
+	elif [ "$transfersyntax" = "1.2.840.10008.1.2.4.50" ]
+	then
+		echo 1>&2 "Only up to 8 bits supported for baseline process lossy compression"
+		exit 1
+	fi
+fi
+
+width=`$DCKEY -d -k Columns "$infile" 2>&1`
+height=`$DCKEY -d -k Rows "$infile" 2>&1`
+
+$DCCP -d PixelData "$infile" "$TMPROOT.header"
+$DCCP "$infile" "$TMPROOT.big.dcm" -endian big -vr explicit
+$DCTORAW -quiet "$TMPROOT.big.dcm" "$TMPROOT.big.raw"
+rm "$TMPROOT.big.dcm"
+$JPEG -iw "$width" -ih "$height" -p "$precision" $* "$TMPROOT.big.raw"	# creates $TMPROOT.big.raw.jpg
+rm "$TMPROOT.big.raw"
+$DCENCAP "$TMPROOT.header" "$TMPROOT.big.raw.jpg" -ts "$transfersyntax" -of "$outfile"
+rm "$TMPROOT.header" "$TMPROOT.big.raw.jpg"
+
+exit 0
diff --git a/appsrc/dcfile/dckey.cc b/appsrc/dcfile/dckey.cc
new file mode 100644
index 0000000..c8aec80
--- /dev/null
+++ b/appsrc/dcfile/dckey.cc
@@ -0,0 +1,202 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dckey.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrnew.h"
+#include "attrval.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "dcstream.h"
+#include "elmconst.h"
+
+static const char *options_output_key[] = {
+	"key",
+	"k",
+	0
+};
+
+// Same in dctable.cc
+
+static void dumpCodeSequenceAsString(SequenceAttribute *as,TextOutputStream &log) {
+	AttributeList **itemLists;
+	int nItems = as->getLists(&itemLists);
+	for (int i=0; i<nItems; ++i) {
+		AttributeList *thisItemList = itemLists[i];
+		if (thisItemList) {
+			Attribute *aCodeValue = (*thisItemList)[TagFromName(CodeValue)];
+			Attribute *aCodingSchemeDesignator = (*thisItemList)[TagFromName(CodingSchemeDesignator)];
+			Attribute *aCodeMeaning = (*thisItemList)[TagFromName(CodeMeaning)];
+			if (aCodeValue || aCodingSchemeDesignator || aCodeMeaning) {
+				const char *vCodeValue = AttributeValue(aCodeValue,"");
+				const char *vCodingSchemeDesignator = AttributeValue(aCodingSchemeDesignator,"");
+				const char *vCodeMeaning = AttributeValue(aCodeMeaning,"");
+				log << "('"
+				    << vCodeValue
+				    << "','"
+				    << vCodingSchemeDesignator
+				    << "','"
+				    << vCodeMeaning
+				    << "')"
+				;
+			}
+		}
+	}
+}
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool showfilename=options.get("filename");
+
+	bool noerror=options.get("noerror");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	bool brief=options.get("brief");
+	bool describe=options.get("describe");
+	bool decimal=options.get("decimal") || options.get("d");
+
+	bool bad=false;
+
+	// identical to dctable.cc; should refactor this, perhaps as AttributeTag::read() ? :(
+	ElementDictionary optdict;
+	AttributeList *keylist=0;
+	const char *keyarg;
+	while (options.get(options_output_key,keyarg)) {
+		Assert(keyarg);
+		Tag tag;
+		if (!getAttributeTagFromStringHexForm(keyarg,tag)	// handle "-k (0xgggg,0xeeee)" case
+		 && !optdict.getTag(keyarg,tag)) {			// handle "-k keyword" case
+			bad=true;
+			cerr << "-" << options_output_key[0] << ": "
+			     << EMsgDC(UnrecognizedElement)
+			     << " - \"" << keyarg << "\""
+			     << endl;
+		}
+		else {
+			const char *vr=optdict.getValueRepresentation(tag);
+			if (!vr) vr="UN";
+			Attribute *a=newAttribute(vr,tag);
+			Assert(a);
+			if (!keylist) {
+				keylist=new AttributeList;
+				Assert(keylist);
+			}
+			(*keylist)+=a;
+		}
+	}
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-describe]"
+			<< " [-noerror]"
+			<< " [-ignorereaderrors]"
+			<< " [-brief]"
+			<< " [-decimal|d]"
+			<< " [-key|k elementname|(0xgggg,0xeeee)]"
+			<< " [-verbose|v]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit,
+		true/*useStopAtTag*/,TagFromName(PixelData));
+
+	if (!list.good()) {
+		log << list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	if (success || ignorereaderrors) {
+		ElementDictionary *dict=list.getDictionary();
+		Assert(dict);
+		AttributeListIterator listi(*keylist);
+		while (!listi) {
+			Attribute *ak=listi();
+			Assert(ak);
+			Tag tag=ak->getTag();
+			Attribute *ad=list[tag];
+			if (!describe && brief) {
+				const char *keyword=0;
+				if (dict) {
+					keyword=dict->getKeyword(tag);	// not description; want without spaces
+				}
+				if (keyword) {
+					log << keyword;
+				}
+				else {
+					log << "(";
+					writeZeroPaddedHexNumber(log,tag.getGroup(),4);
+					log << ",";
+					writeZeroPaddedHexNumber(log,tag.getElement(),4);
+					log << ") ";
+				}
+				log << "=";
+			}
+			if (ad) {
+				if (describe) {
+					ad->write(log,dict);
+				}
+				else {
+					if (decimal) {
+						log << double(AttributeValue(ad,double(0)));
+					}
+					else {
+						if (ad->isSequence()) {
+							SequenceAttribute *as = (SequenceAttribute *)ad;
+							dumpCodeSequenceAsString(as,log);
+						}
+						else {
+							ad->writeData(log);
+						}
+					}
+				}
+			}
+			else {
+				if (!noerror && !brief) {
+					log << EMsgDC(NotFound) << " - ";
+					tag.write(log,dict);
+				}
+			}
+			log << endl;
+			++listi;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dckey.man b/appsrc/dcfile/dckey.man
new file mode 100755
index 0000000..d01a37a
--- /dev/null
+++ b/appsrc/dcfile/dckey.man
@@ -0,0 +1,147 @@
+.TH DCKEY 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Extract attribute values"
+.SH NAME
+dckey \- ACR/NEMA DICOM PS3 ... Extract attribute values
+.SH SYNOPSIS
+.HP 10
+.B dckey
+.so man1/gen.so
+[
+.B \-ignorereaderrors
+]
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+[
+.B \-describe
+]
+[
+.B \-brief
+]
+[
+.B \-d|decimal
+]
+[
+.B \-key|k " elementname|(0xgggg,0xeeee) ] ..."
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dckey
+reads the named dicom input file and displays the values of the selected attributes.
+.LP
+Binary attributes are written in hexadecimal with a preceding
+"0x" and numeric string attributes are written in decimal as they are encoded,
+unless the \-decimal option is specified.
+.SH OPTIONS
+The attribute values, description and verbose output go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-describe
+.RS
+Display the tag, name, value representation and value length of the attribute.
+.RE
+.TP
+.B \-brief
+.RS
+Display the keyword of the attribute, and equals sign, and then the value, for use in
+scripts that automatically extract multiple values in the same dckey invocation. Implies \-noerror.
+.RE
+.TP
+.B \-ignorereaderrors
+.RS
+Attempt to extract key values even if errors encountered whilst parsing DICOM file.
+.RE
+.TP
+.B \-noerror
+.RS
+Do not report an error if the requested attribute was not found, just an empty value or line. Implied by \-brief.
+.RE
+.TP
+.B \-d|decimal
+.RS
+Display the first (or only) value of a numeric attribute as a decimal value.
+.RE
+.TP
+.B \-k|key " elementname|(0xgggg,0xeeee)"
+.RS
+Add a key to the list of attributes to be extracted. The attribute may also be specified
+as a hexadecimal pair of the form (0xgggg,0xeeee), which also allows private attributes to be fetched.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dckey -key Rows -key Columns -key ImageLocation
+.RE
+        -describe test.dc3
+.RE
+(0x0028,0x0010) US Rows    VR=<US> VL=<0x0002> [0x0100] 
+.RE
+(0x0028,0x0011) US Columns VR=<US> VL=<0x0002> [0x0100] 
+.RE
+Error - Not found - (0x0028,0x0200) US Image Location 
+.RE
+\ 
+.RE
+% dckey -k Rows -k ImagePositionPatient
+.RE
+      -k StudyDate -k StudyTime
+.RE
+      -k SOPClassUID test.dc3
+.RE
+1.2.840.10008.5.1.4.1.1.2
+.RE
+1996.04.17
+.RE
+19:38:00
+.RE
+45.000000\\-120.000000\\120.000000 
+.RE
+0x0200
+\ 
+.RE
+% dckey -d -k Rows test.dc3
+.RE
+512
+\ 
+.RE
+% dckey -brief -k Rows -k Columns test.dc3
+.RE
+Rows=0x200
+.RE
+Columns=0x200
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), dctable(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+Attempts to extract sequences or OB,OW attributes may fail nastily.
+.LP
+The order in which the attributes are extracted and written is not the same
+order as they are specified on the command line, and should not be depended
+on.
+.LP
+The \-describe and other options cannot be used at the same time.
+.LP
+The \-decimal option uses a double conversion before displaying the value and
+there may be sign extension and precision issues with some values.
+.LP
+The reading of the attributes from the DICOM file will not proceed past the
+top level Pixel Data attribute, in order to accelerate the speed of reading.
+
diff --git a/appsrc/dcfile/dclutburn.cc b/appsrc/dcfile/dclutburn.cc
new file mode 100644
index 0000000..9c19aba
--- /dev/null
+++ b/appsrc/dcfile/dclutburn.cc
@@ -0,0 +1,229 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dclutburn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+class BurnInLUTFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	const Uint16 *data;
+	Uint16 numberOfEntries;
+	Uint16 firstValueMapped;
+	Uint16 lastValueMapped;
+	Uint16 firstValue;
+	Uint16 lastValue;
+public:
+	BurnInLUTFilter(const Uint16 *data,Uint16 numberOfEntries,Uint16 firstValueMapped)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			this->data = data;
+			this->numberOfEntries = numberOfEntries;
+			this->firstValueMapped = firstValueMapped;
+			lastValueMapped = firstValueMapped + numberOfEntries - 1;
+			if (numberOfEntries > 0) {
+				firstValue = data[0];
+				lastValue = data[numberOfEntries-1];
+			}
+		}
+
+	Uint16 filter(Uint16 originalvalue)
+		{
+			Uint16 newValue;
+			if (originalvalue < firstValueMapped) {
+				newValue = firstValue;
+			}
+			else if (originalvalue > lastValueMapped) {
+				newValue = lastValue;
+			}
+			else {
+				newValue = data[originalvalue-firstValueMapped];
+			}
+			return newValue;
+		}
+};
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	int which_voilut = 0;		// 0 is first VOI lut; use by default
+	options.get("voilutnumber",which_voilut);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [-voilutnumber 0..n-1]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+
+	Uint16 VOILUT_first = 0;
+	Uint16 VOILUT_number = 0;
+	Uint16 VOILUT_depth = 0;
+	const Uint16 *vLUTData = NULL;
+	if (success) {
+//cerr << "Extracting LUT ..." << endl;
+		Attribute *aVOILUTSequence = list[TagFromName(VOILUTSequence)];
+		int nVOILUT=0;
+		if (aVOILUTSequence) {
+//cerr << "Got VOILUTSequence" << endl;
+			AttributeList **items;
+			nVOILUT=aVOILUTSequence->getLists(&items);
+			if (which_voilut >= 0 && which_voilut < nVOILUT) {
+				Assert(items[which_voilut]);
+				Attribute *aLUTDescriptor=items[which_voilut]->operator[](TagFromName(LUTDescriptor));
+				if (!aLUTDescriptor) {
+					log << EMsgDC("Missing LUT Descriptor Attribute") << endl;
+					success=false;
+				}
+				else {
+					unsigned vm=aLUTDescriptor->getVM();
+					if (vm != 3) {
+						log << EMsgDC("Wrong VM for LUT Descriptor") << " = " << dec << vm << endl;
+						success=false;
+					}
+					else {
+						Assert(aLUTDescriptor->getValue(0,VOILUT_number));
+						Assert(aLUTDescriptor->getValue(1,VOILUT_first));
+						Assert(aLUTDescriptor->getValue(2,VOILUT_depth));
+						Attribute *aLUTData=items[which_voilut]->operator[](TagFromName(LUTData));
+						if (!aLUTData) {
+							log << EMsgDC("Missing LUT Data Attribute") << endl;
+							success=false;
+						}
+						else {
+							int j;
+							Uint16 VOILUT_value;
+							Uint32 nLUTData;
+							if (aLUTData->isOtherWordNonPixel()) {
+								if (!aLUTData->getValue(vLUTData,nLUTData)) {
+									log << EMsgDC("Cannot get OW LUT Data") << endl;
+									success=false;
+								}
+							}
+							else if (aLUTData->isNumericBinary()) {		// e.g. US VR
+								nLUTData = aLUTData->getVM();
+								Uint16 *mutableData = new Uint16[nLUTData];
+								vLUTData = mutableData;
+								int i;
+								for (i=0; i < VOILUT_number; ++i) {
+									Uint16 VOILUT_value;
+									if (!aLUTData->getValue(i,VOILUT_value)) {
+										log << EMsgDC("Premature End of LUT Data") << endl;
+										success=false;
+										break;
+									}
+									mutableData[i] = VOILUT_value;
+								}
+							}
+						}
+					}
+				}
+			}
+			else {
+				log << EMsgDC("Selected VOI LUT Sequence Item missing") << " - requested " << dec << which_voilut << " but only " << nVOILUT << " available" << endl;
+			}
+		}
+		else {
+			log << EMsgDC("Missing VOI LUT Sequence") << endl;
+		}
+	}
+
+	if (success && vLUTData != NULL && VOILUT_number > 0 && VOILUT_depth > 0) {
+//cerr << "Performing burn ..." << endl;
+	
+		BurnInLUTFilter *filter = new BurnInLUTFilter(vLUTData,VOILUT_number,VOILUT_first);
+		Assert(filter);
+	
+		Attribute *aPixelData = list[TagFromName(PixelData)];
+
+		if (aPixelData) {
+			OtherUnspecifiedLargeAttributeBase *oPixelData = 0;
+
+			if (!aPixelData->isOtherData()) {
+				log << EMsgDC(PixelDataIncorrectVR) << endl;
+				success=false;
+			}
+			else {
+				oPixelData = aPixelData->castToOtherData();
+				Assert(oPixelData);
+				if (filter) oPixelData->insertPixelPointTransform(filter);
+				list-=TagFromName(VOILUTSequence);
+			}
+		}
+		else {
+			log << EMsgDC(MissingAttribute)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+		
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dclutburn.man b/appsrc/dcfile/dclutburn.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dclutdmp.cc b/appsrc/dcfile/dclutdmp.cc
new file mode 100644
index 0000000..fdea7f7
--- /dev/null
+++ b/appsrc/dcfile/dclutdmp.cc
@@ -0,0 +1,236 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dclutdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+#include "errclass.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool showfilename=options.get("filename");
+
+	unsigned input_min = 0x0000;
+	unsigned input_max = 0xffff;
+	bool minpresent=options.get("min",input_min);
+	bool maxpresent=options.get("max",input_max);
+
+	bool ancreate=options.get("ancreate");
+	
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-ancreate]"
+			<< " [-min value]"
+			<< " [-max value]"
+			<< " [-v|-verbose]"
+			<< " [-filename]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		return 1;
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	TextOutputStream  log(cerr);
+	
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		//return 1;	// Press on regardless ...
+	}
+
+
+	Attribute *aVOILUTSequence = list[TagFromName(VOILUTSequence)];
+	int nVOILUT=0;
+	if (aVOILUTSequence) {
+		if (ancreate) {
+			log << "(0x0028,0x3010) SQ VOI LUT Sequence VR=<SQ> VL=<0xffffffff> []" << endl;
+		}
+		else {
+			log << "VOILUTSequence" << endl;
+		}
+		AttributeList **items;
+		nVOILUT=aVOILUTSequence->getLists(&items);
+		if (!ancreate) {
+			log << "Contains " << dec << nVOILUT << " items" << endl;
+		}
+		int item;
+		for (item=0; item<nVOILUT; ++item) {
+			if (ancreate) {
+				log << "%item" << endl;
+			}
+			else {
+				log << "\t Item " << dec << item << endl;
+			}
+			Assert(items[item]);
+			Attribute *aLUTExplanation = items[item]->operator[](TagFromName(LUTExplanation));
+			if (aLUTExplanation) {
+				const char *vLUTExplanation=AttributeValue(aLUTExplanation);
+				if (!ancreate) {
+					log << "\t\t LUTExplanation  = " << vLUTExplanation << endl;
+				}
+			}
+			
+			Attribute *aLUTDescriptor=items[item]->operator[](TagFromName(LUTDescriptor));
+			if (!aLUTDescriptor) {
+				log << "\t\t Missing LUT Descriptor Attribute" << endl;
+			}
+			else {
+				if (ancreate) {
+					aLUTDescriptor->write(log,list.getDictionary(),false);
+					log << endl;
+					aLUTExplanation->write(log,list.getDictionary(),false);			// must go after descriptor
+					log << endl;
+				}
+				unsigned vm=aLUTDescriptor->getVM();
+				if (vm != 3) {
+					log << "\t\t Wrong VM for LUT Descriptor = " << dec << vm << endl;
+				}
+				else {
+					Uint16 VOILUT_first;
+					Uint16 VOILUT_number;
+					Uint16 VOILUT_depth;
+					Assert(aLUTDescriptor->getValue(0,VOILUT_number));
+					Assert(aLUTDescriptor->getValue(1,VOILUT_first));
+					Assert(aLUTDescriptor->getValue(2,VOILUT_depth));
+					if (!ancreate) {
+						log << "\t\t first  = " << dec << VOILUT_first << endl
+							<< "\t\t number = " << dec << VOILUT_number << endl
+							<< "\t\t depth  = " << dec << VOILUT_depth << endl;
+					}
+					Attribute *aLUTData=items[item]->operator[](TagFromName(LUTData));
+					if (!aLUTData) {
+						log << "\t\t Missing LUT Data Attribute" << endl;
+					}
+					else {
+						if (ancreate) {
+							//aLUTData->write(log,list.getDictionary(),false);
+							//log << endl;
+							log << "(0x0028,0x3006) XO LUT Data      VR=<OW>   VL=<" << hex << (VOILUT_number*2) << dec << "> [";
+						}
+						//else {
+						{
+							const char *prefix = "";
+							int j;
+							Uint16 VOILUT_value;
+							Uint32 nLUTData;
+							if (aLUTData->isOtherWordNonPixel()) {
+//cerr << "checking > 8 bit OW" << endl;
+								const Uint16 *vLUTData = NULL;
+								if (aLUTData->getValue(vLUTData,nLUTData)) {
+//cerr << "got value" << endl;
+									if (!ancreate) {
+										if (minpresent && VOILUT_number && nLUTData) {
+											for (j=input_min; j < VOILUT_first; ++j) {
+												cout << dec << j << "\t" << VOILUT_value << endl;
+											}
+										}
+									}
+									int i;
+									for (i=0,j=VOILUT_first; i < VOILUT_number; ++i,++j) {
+										VOILUT_value = vLUTData[i];
+										if (ancreate) {
+											log << prefix << hex << VOILUT_value << dec << "";
+											prefix=",";
+										}
+										else {
+											if (j >= input_min && j <= input_max) {
+												cout << dec << j << "\t" << VOILUT_value << endl;
+											}
+										}
+									}
+								}
+								else {
+									log << "\t\t Cannot get OW LUT Data" << endl;
+								}
+							}
+							else if (aLUTData->isNumericBinary()) {		// e.g. US VR
+//cerr << "checking " << aLUTData->getVR() << endl;
+								nLUTData = aLUTData->getVM();
+								if (minpresent && VOILUT_number && nLUTData && aLUTData->getValue(0,VOILUT_value)) {
+									if (!ancreate) {
+										for (j=input_min; j < VOILUT_first; ++j) {
+											cout << dec << j << "\t" << VOILUT_value << endl;
+										}
+									}
+								}
+								int i;
+								for (i=0,j=VOILUT_first; i < VOILUT_number; ++i,++j) {
+									if (aLUTData->getValue(i,VOILUT_value)) {
+										if (ancreate) {
+											log << prefix << hex << VOILUT_value << dec << "";
+											prefix=",";
+										}
+										else {
+											if (j >= input_min && j <= input_max) {
+												cout << dec << j << "\t" << VOILUT_value << endl;
+											}
+										}
+									}
+									else {
+										log << "\t\t Premature End of LUT Data" << endl;
+										break;
+									}
+								}
+							}
+							// at this point, for either encoding, VOILUT_value will contain the last value
+							if (!ancreate) {
+								if (maxpresent && VOILUT_number) {
+									for (j=VOILUT_first+VOILUT_number; j <= input_max; ++j) {
+										cout << dec << j << "\t" << VOILUT_value << endl;
+									}
+								}
+							}
+						}
+						if (ancreate) {
+							log << "]" << endl;
+						}
+					}
+				}
+			}
+			if (ancreate) {
+				log << "%enditem" << endl;
+			}
+		}
+		if (ancreate) {
+			log << "%endseq" << endl;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/dclutdmp.man b/appsrc/dcfile/dclutdmp.man
new file mode 100755
index 0000000..d1636cf
--- /dev/null
+++ b/appsrc/dcfile/dclutdmp.man
@@ -0,0 +1,76 @@
+.TH DCLUTDMP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - dump LUT contents"
+.SH NAME
+dclutdmp \- ACR/NEMA DICOM PS3 ... DICOM PS3 - dump LUT contents
+.SH SYNOPSIS
+.HP 10
+.B dclutdmp
+.so man1/gen.so
+[
+.B \-ancreate
+]
+[
+.B \-min value
+]
+[
+.B \-max value
+]
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dclutdmp
+reads the named dicom input file and dumps the contents of any VOI LUT
+present (as decimal values).
+.SH OPTIONS
+The descriptive attributes go to standard error.
+.PP
+The tab delimited input vs. output value list goes to stdout.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-ancreate
+.RS
+Display item, end item and end sequence delimiter tags in a form suitable to feed into ancreate.
+.RE
+.TP
+.B \-min value
+.TP
+.B \-max value
+.RS
+Specify the first and last input values to dump ... if these are greater than
+the specified input range of the actual LUT, then the first and last output
+values are replicated as per the standard. The values may also be less than
+the actual LUT range. This option makes it easier to
+concatenate two LUTs specified over different input values for the purposes
+of comparison.
+.RE
+.TP
+.B \-verbose
+.RS
+Dump the complete list of DICOM attributes present in the input to stderr.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR ancreate(1) ,
+.BR andump(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dclutmix.cc b/appsrc/dcfile/dclutmix.cc
new file mode 100644
index 0000000..e68a841
--- /dev/null
+++ b/appsrc/dcfile/dclutmix.cc
@@ -0,0 +1,276 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dclutmix.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static Uint16
+getIntegerValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	Uint16 value=AttributeValue(a);
+	return value;
+}
+
+class BurnInLUTFilter : public PointFilterIndependentOfOffset<Uint16,Uint16> {
+private:
+	const Uint16 *data;
+	Uint16 numberOfEntries;
+	Uint16 firstValueMapped;
+	Uint16 lastValueMapped;
+	Uint16 firstValue;
+	Uint16 lastValue;
+public:
+	BurnInLUTFilter(const Uint16 *data,Uint16 numberOfEntries,Uint16 firstValueMapped)
+			: PointFilterIndependentOfOffset<Uint16,Uint16>()
+		{
+			this->data = data;
+			this->numberOfEntries = numberOfEntries;
+			this->firstValueMapped = firstValueMapped;
+			lastValueMapped = firstValueMapped + numberOfEntries - 1;
+			if (numberOfEntries > 0) {
+				firstValue = data[0];
+				lastValue = data[numberOfEntries-1];
+			}
+		}
+
+	Uint16 filter(Uint16 originalvalue)
+		{
+			Uint16 newValue;
+			if (originalvalue < firstValueMapped) {
+				newValue = firstValue;
+			}
+			else if (originalvalue > lastValueMapped) {
+				newValue = lastValue;
+			}
+			else {
+				newValue = data[originalvalue-firstValueMapped];
+			}
+			return newValue;
+		}
+};
+
+static SequenceAttribute *
+addVOILUT(Uint32 numberofentries,
+	Uint16 firstvaluemapped,
+	Uint16 bitsallocated,
+	Uint16 *values,
+	const char *explanation,
+	TextOutputStream &log)
+{
+	Assert(bitsallocated <= 16);
+	Assert(numberofentries <= 65536);
+	Assert(values);
+
+	Attribute *aLUTDescriptor = new UnsignedShortAttribute(TagFromName(LUTDescriptor));
+	Assert(aLUTDescriptor);
+	aLUTDescriptor->addValue(numberofentries == 65536 ? 0 : numberofentries);
+	aLUTDescriptor->addValue(firstvaluemapped);
+	aLUTDescriptor->addValue(bitsallocated);
+
+	Attribute *aLUTData = new OtherWordSmallNonPixelAttribute(TagFromName(LUTData));
+	Assert(aLUTData);
+	aLUTData->setValue(values,numberofentries);
+
+	SequenceAttribute *aLUTSequence = new SequenceAttribute(TagFromName(VOILUTSequence));
+	Assert(aLUTSequence);
+
+	AttributeList *lLUTSequence = new AttributeList();
+	Assert(lLUTSequence);
+
+	(*lLUTSequence)+=aLUTData;
+	(*lLUTSequence)+=aLUTDescriptor;
+	(*lLUTSequence)+=new LongStringAttribute(TagFromName(LUTExplanation),explanation ? explanation : "");
+
+	(*aLUTSequence)+=lLUTSequence;
+
+	return aLUTSequence;
+}
+
+static Uint16 scramble(Uint16 value,int significantBits) {
+	// just reverse all bits
+	Uint16 newValue=0;
+	int i;
+	for (i=0; i<significantBits; ++i) {
+		newValue = (newValue<<1) | (value&0x0001);
+		value = value >> 1;
+	}
+	return newValue;
+}
+
+static Uint16 invert(Uint16 value,int significantBits) {
+	return (~value)&((Uint32(1)<<significantBits)-1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool bad = false;
+	
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	
+	bool useScramble=options.get("scramble");
+	bool useInvert=options.get("invert");
+	bool useIdentity=options.get("identity");
+	
+	if (!useScramble && !useInvert) {
+		bad = true;
+	}
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -scramble|invert|identity"
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+	
+	Uint16 vBitsStored = getIntegerValueElseError(list,TagFromName(BitsStored),"Bits Stored","",log);
+	Uint16 nLUTEntriesNeeded = 1 << vBitsStored;
+	
+	Uint16 *forwardLUT = new Uint16[nLUTEntriesNeeded];
+	Uint16 *inverseLUT = new Uint16[nLUTEntriesNeeded];
+	
+	int i;
+	for (i=0; i<nLUTEntriesNeeded; ++i) {
+		Uint16 newValue;
+		if (useScramble) {
+			newValue = scramble(i,vBitsStored);
+		}
+		else if (useInvert) {
+			newValue = invert(i,vBitsStored);
+		}
+		else if (useIdentity) {
+			newValue = i;
+		}
+		else {
+			Assert(0);
+		}
+cerr << hex << i << " -> " << newValue << dec << endl;
+		forwardLUT[i] = newValue;
+		inverseLUT[newValue] = i;
+	}
+	
+	list-=TagFromName(VOILUTSequence);
+	list+=addVOILUT(nLUTEntriesNeeded,0,vBitsStored,inverseLUT,"unscramble",log);
+	
+	Uint16 VOILUT_first = 0;
+	Uint16 VOILUT_number = nLUTEntriesNeeded;
+	Uint16 VOILUT_depth = vBitsStored;
+	const Uint16 *vLUTData = forwardLUT;
+
+	if (success && vLUTData != NULL && VOILUT_number > 0 && VOILUT_depth > 0) {
+		BurnInLUTFilter *filter = new BurnInLUTFilter(vLUTData,VOILUT_number,VOILUT_first);
+		Assert(filter);
+	
+		Attribute *aPixelData = list[TagFromName(PixelData)];
+
+		if (aPixelData) {
+			OtherUnspecifiedLargeAttributeBase *oPixelData = 0;
+
+			if (!aPixelData->isOtherData()) {
+				log << EMsgDC(PixelDataIncorrectVR) << endl;
+				success=false;
+			}
+			else {
+				oPixelData = aPixelData->castToOtherData();
+				Assert(oPixelData);
+				if (filter) oPixelData->insertPixelPointTransform(filter);
+			}
+		}
+		else {
+			log << EMsgDC(MissingAttribute)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+		
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dclutmix.man b/appsrc/dcfile/dclutmix.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcmerge.cc b/appsrc/dcfile/dcmerge.cc
new file mode 100644
index 0000000..ccae503
--- /dev/null
+++ b/appsrc/dcfile/dcmerge.cc
@@ -0,0 +1,93 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcmerge.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options1(options);
+	DicomInputOptions 	dicom_input_options2(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	dicom_input_options1.done();
+	dicom_input_options2.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener1(
+		options,dicom_input_options1.filename);
+	DicomInputOpenerFromOptions input_opener2(
+		options,dicom_input_options2.filename);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options1.errors();
+	cerr << dicom_input_options2.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener1.errors();
+	cerr << input_opener2.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options1.good()
+	 || !dicom_input_options2.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener1.good()
+	 || !input_opener2.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options1.usage()
+			<< dicom_input_options2.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< MMsgDC(InputFile) << " " << MMsgDC(InputFile)
+			<< "[" << MMsgDC(OutputFile) << "]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din1(*(istream *)input_opener1,
+		dicom_input_options1.transfersyntaxuid,
+		dicom_input_options1.usemetaheader);
+	DicomInputStream din2(*(istream *)input_opener2,
+		dicom_input_options2.transfersyntaxuid,
+		dicom_input_options2.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading 1st dataset ... ********" << endl; 
+	list.read(din1,&log,verbose,0xffffffff,true,dicom_input_options1.uselengthtoend,dicom_input_options1.ignoreoutofordertags,dicom_input_options1.useUSVRForLUTDataIfNotExplicit);
+	if (verbose) log << "******** While reading 2nd dataset ... ********" << endl; 
+	list.read(din2,&log,verbose,0xffffffff,true,dicom_input_options2.uselengthtoend,dicom_input_options2.ignoreoutofordertags,dicom_input_options2.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		log << list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcmerge.man b/appsrc/dcfile/dcmerge.man
new file mode 100755
index 0000000..eadc4d8
--- /dev/null
+++ b/appsrc/dcfile/dcmerge.man
@@ -0,0 +1,157 @@
+.TH DCMERGE 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Merge DICOM files"
+.SH NAME
+dcmerge \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Merge DICOM files
+.SH SYNOPSIS
+.HP 10
+.B dcmerge
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.so man1/optin.so
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcmerge
+reads the named dicom or acr-nema input filea and copies the information and
+pixel data (if any) from both into a new dicom file.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The encoding of the file will be changed to the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options. This provides a means of converting between different transfer
+syntaxes, and adding or removing Part 10 style meta-information headers
+to or from "true" DICOM files, DICOM messages captured from network
+exchanges such as with the Mallinckrodt or Oldenburg central test node
+software, or converting old ACR/NEMA or SPI files.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows pre-DICOM
+ACR-NEMA or SPI files to be converted to DICOM files containing
+conforming instances of SOP classes in a semi-automated manner. If the
+SOP Class can be automatically determined, such as for CT or MR images,
+specific SOP Class instances will be created, otherwise SC will be used.
+Unique study, series and instance identifiers will be generated from a
+time stamp, but can be overridden by command line options to allow for
+shared identifiers between files of a series.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1), though the input
+filenames must be explicitly specified, ie. they cannot be redirected from standard input. Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% echo Adds meta-information header by default
+.RE
+% dcmerge -v NM.dc3 NM2.dc3
+.RE
+******** While reading ... ********
+.RE
+ at 0x00000000,0x00000000 of 0xffffffff: (0x0008,0x0000) ...
+.RE
+...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0000) UL Group Length VR=<UL> ...
+.RE
+...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0000) UL Meta Element Group Length ...
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+...
+.RE
+(0x0008,0x0008) CS Image Type VR=<CS> VL=<24> <...>
+.RE
+...
+.RE
+\ 
+.RE
+% echo Make explicit big endian, with stamp & replacement,
+.RE
+       and removal of private attributes
+.RE
+\ 
+.RE
+% dcmerge \-v \-ts 1.2.840.10008.1.2.2 \-stamp "9999" 
+.RE
+       \-r PatientSex F \-removeprivate
+.RE
+       test.dc3 test.big
+.RE
+******** While reading ... ********
+.RE
+ at 0x00000000,0x00000000 of 0xffffffff: (0x0008,0x0000) ...
+.RE
+...
+.RE
+******** As read ... ********
+.RE
+...
+.RE
+(0x0010,0x0040) CS PatientSex VR=<CS> VL=<2> <M > 
+.RE
+...
+.RE
+(0x0028,0x0010) US Rows       VR=<US> VL=<2> [100]
+.RE
+...
+.RE
+(0x0029,0x0010) LO Private Creator ... [ACME CO ]
+.RE
+(0x0029,0x1010) DS Zoom       VR=<DS> VL=<0> <>
+.RE
+...
+.RE
+******** After replace before... ********
+.RE
+...
+.RE
+(0x0010,0x0040) CS PatientSex VR=<CS> VL=<2> <F> 
+.RE
+...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0000) UL Meta Element Group Length ...
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+...
+.RE
+(0x0010,0x0040) CS PatientSex VR=<CS> VL=<2> <F> 
+.RE
+...
+.RE
+(0x0028,0x0010) US Rows       VR=<US> VL=<2> [100]
+.RE
+...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcmkpres.cc b/appsrc/dcfile/dcmkpres.cc
new file mode 100644
index 0000000..4d146f3
--- /dev/null
+++ b/appsrc/dcfile/dcmkpres.cc
@@ -0,0 +1,766 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcmkpres.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "attrval.h"
+#include "sopclu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+
+static bool
+createPresentationState(ManagedAttributeList &input_list,ManagedAttributeList &output_list,TextOutputStream &log,
+	const char *plutshape)
+{
+	bool success = true;
+
+	// Fetch necessary attributes to reference image ...
+
+	char *vStudyInstanceUIDOfReferencedImage=0;
+	{
+		Attribute *aStudyInstanceUIDOfReferencedImage=input_list[TagFromName(StudyInstanceUID)];
+		if (aStudyInstanceUIDOfReferencedImage)
+			vStudyInstanceUIDOfReferencedImage=AttributeValue(aStudyInstanceUIDOfReferencedImage);
+		if (!vStudyInstanceUIDOfReferencedImage || !*vStudyInstanceUIDOfReferencedImage)  {
+			log << EMsgDC(MissingAttributeInReferencedImage) << " - Study Instance UID" << endl;
+			success=false;
+		}
+	}
+
+	char *vSeriesInstanceUIDOfReferencedImage=0;
+	{
+		Attribute *aSeriesInstanceUIDOfReferencedImage=input_list[TagFromName(SeriesInstanceUID)];
+		if (aSeriesInstanceUIDOfReferencedImage)
+			vSeriesInstanceUIDOfReferencedImage=AttributeValue(aSeriesInstanceUIDOfReferencedImage);
+		if (!vSeriesInstanceUIDOfReferencedImage || !*vSeriesInstanceUIDOfReferencedImage)  {
+			log << EMsgDC(MissingAttributeInReferencedImage) << " - Series Instance UID" << endl;
+			success=false;
+		}
+	}
+
+	char *vSOPInstanceUIDOfReferencedImage=0;
+	{
+		Attribute *aSOPInstanceUIDOfReferencedImage=input_list[TagFromName(SOPInstanceUID)];
+		if (aSOPInstanceUIDOfReferencedImage)
+			vSOPInstanceUIDOfReferencedImage=AttributeValue(aSOPInstanceUIDOfReferencedImage);
+		if (!vSOPInstanceUIDOfReferencedImage || !*vSOPInstanceUIDOfReferencedImage)  {
+			log << EMsgDC(MissingAttributeInReferencedImage) << " - SOP Instance UID" << endl;
+			success=false;
+		}
+	}
+
+	char *vSOPClassUIDOfReferencedImage=0;
+	{
+		Attribute *aSOPClassUIDOfReferencedImage=input_list[TagFromName(SOPClassUID)];
+		if (aSOPClassUIDOfReferencedImage)
+			vSOPClassUIDOfReferencedImage=AttributeValue(aSOPClassUIDOfReferencedImage);
+		if (!vSOPClassUIDOfReferencedImage || !*vSOPClassUIDOfReferencedImage)  {
+			log << EMsgDC(MissingAttributeInReferencedImage) << " - SOP Class UID" << endl;
+			success=false;
+		}
+	}
+
+	Uint16 vRowsOfReferencedImage=0;
+	{
+		Attribute *aRowsOfReferencedImage=input_list[TagFromName(Rows)];
+		if (aRowsOfReferencedImage)
+			vRowsOfReferencedImage=AttributeValue(aRowsOfReferencedImage);
+		else {
+			log << EMsgDC(MissingAttributeInReferencedImage) << " - Rows" << endl;
+			success=false;
+		}
+	}
+
+	Uint16 vColumnsOfReferencedImage=0;
+	{
+		Attribute *aColumnsOfReferencedImage=input_list[TagFromName(Columns)];
+		if (aColumnsOfReferencedImage)
+			vColumnsOfReferencedImage=AttributeValue(aColumnsOfReferencedImage);
+		else {
+			log << EMsgDC(MissingAttributeInReferencedImage) << " - Columns" << endl;
+			success=false;
+		}
+	}
+
+	if (!success) return false;
+
+	char *vPatientNameOfReferencedImage=0;
+	{
+		Attribute *aPatientNameOfReferencedImage=input_list[TagFromName(PatientName)];
+		if (aPatientNameOfReferencedImage)
+			vPatientNameOfReferencedImage=AttributeValue(aPatientNameOfReferencedImage);
+	}
+
+	char *vPatientIDOfReferencedImage=0;
+	{
+		Attribute *aPatientIDOfReferencedImage=input_list[TagFromName(PatientID)];
+		if (aPatientIDOfReferencedImage)
+			vPatientIDOfReferencedImage=AttributeValue(aPatientIDOfReferencedImage);
+	}
+
+	char *vPatientBirthDateOfReferencedImage=0;
+	{
+		Attribute *aPatientBirthDateOfReferencedImage=input_list[TagFromName(PatientBirthDate)];
+		if (aPatientBirthDateOfReferencedImage)
+			vPatientBirthDateOfReferencedImage=AttributeValue(aPatientBirthDateOfReferencedImage);
+	}
+
+	char *vPatientSexOfReferencedImage=0;
+	{
+		Attribute *aPatientSexOfReferencedImage=input_list[TagFromName(PatientSex)];
+		if (aPatientSexOfReferencedImage)
+			vPatientSexOfReferencedImage=AttributeValue(aPatientSexOfReferencedImage);
+	}
+
+	char *vStudyIDOfReferencedImage=0;
+	{
+		Attribute *aStudyIDOfReferencedImage=input_list[TagFromName(StudyID)];
+		if (aStudyIDOfReferencedImage)
+			vStudyIDOfReferencedImage=AttributeValue(aStudyIDOfReferencedImage);
+	}
+
+	char *vStudyDateOfReferencedImage=0;
+	{
+		Attribute *aStudyDateReferencedImage=input_list[TagFromName(StudyDate)];
+		if (aStudyDateReferencedImage)
+			vStudyDateOfReferencedImage=AttributeValue(aStudyDateReferencedImage);
+	}
+
+	char *vStudyTimeOfReferencedImage=0;
+	{
+		Attribute *aStudyTimeOfReferencedImage=input_list[TagFromName(StudyTime)];
+		if (aStudyTimeOfReferencedImage)
+			vStudyTimeOfReferencedImage=AttributeValue(aStudyTimeOfReferencedImage);
+	}
+
+	char *vReferringPhysicianNameOfReferencedImage=0;
+	{
+		Attribute *aReferringPhysicianNameOfReferencedImage=input_list[TagFromName(ReferringPhysicianName)];
+		if (aReferringPhysicianNameOfReferencedImage)
+			vReferringPhysicianNameOfReferencedImage=AttributeValue(aReferringPhysicianNameOfReferencedImage);
+	}
+
+	char *vAccessionNumberOfReferencedImage=0;
+	{
+		Attribute *aAccessionNumberOfReferencedImage=input_list[TagFromName(AccessionNumber)];
+		if (aAccessionNumberOfReferencedImage)
+			vAccessionNumberOfReferencedImage=AttributeValue(aAccessionNumberOfReferencedImage);
+	}
+
+	// various Type 1 and Type 2 attributes for mandatory Presentation State modules ...
+
+	// Patient Module
+
+	output_list+=new PersonNameAttribute(TagFromName(PatientName),vPatientNameOfReferencedImage ? vPatientNameOfReferencedImage : "^^^^");
+	output_list+=new LongStringAttribute(TagFromName(PatientID),vPatientIDOfReferencedImage ? vPatientIDOfReferencedImage : "");
+	output_list+=new DateStringAttribute(TagFromName(PatientBirthDate),vPatientBirthDateOfReferencedImage ? vPatientBirthDateOfReferencedImage : "");
+	output_list+=new CodeStringAttribute(TagFromName(PatientSex),vPatientSexOfReferencedImage ? vPatientSexOfReferencedImage : "");
+
+	// General Study Module
+	output_list+=new ShortStringAttribute(TagFromName(StudyID),vStudyIDOfReferencedImage ? vStudyIDOfReferencedImage : "");
+	output_list+=new DateStringAttribute(TagFromName(StudyDate),vStudyDateOfReferencedImage ? vStudyDateOfReferencedImage : "");
+	output_list+=new TimeStringAttribute(TagFromName(StudyTime),vStudyTimeOfReferencedImage ? vStudyTimeOfReferencedImage : "");
+	output_list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),vReferringPhysicianNameOfReferencedImage ? vReferringPhysicianNameOfReferencedImage : "^^^^");
+	output_list+=new ShortStringAttribute(TagFromName(AccessionNumber),vAccessionNumberOfReferencedImage ? vAccessionNumberOfReferencedImage : "");
+
+	output_list+=new UIStringAttribute(TagFromName(StudyInstanceUID),vStudyInstanceUIDOfReferencedImage);
+
+	// General Series Module
+
+	output_list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+
+	// General Equipment Module
+
+	output_list+=new LongStringAttribute(TagFromName(Manufacturer));
+
+	// SOP Common Module
+
+	output_list+=new IntegerStringAttribute(TagFromName(InstanceNumber),Uint16(1));
+
+	output_list+=new UIStringAttribute(TagFromName(SOPClassUID),GrayscaleSoftcopyPresentationStateStorageSOPClassUID);
+
+	// Presentation Series Module
+
+	output_list+=new CodeStringAttribute(TagFromName(Modality),"PR");
+
+	// Presentation State Module
+
+	output_list+=new CodeStringAttribute(TagFromName(ContentLabel),"TESTSTATE");
+	output_list+=new LongStringAttribute(TagFromName(ContentDescription));
+	output_list+=new DateStringAttribute(TagFromName(PresentationCreationDate),vStudyDateOfReferencedImage ? vStudyDateOfReferencedImage : "");
+	output_list+=new TimeStringAttribute(TagFromName(PresentationCreationTime),vStudyTimeOfReferencedImage ? vStudyTimeOfReferencedImage : "");
+	output_list+=new PersonNameAttribute(TagFromName(ContentCreatorName));
+
+	{
+		SequenceAttribute *aReferencedSeriesSequence = new SequenceAttribute(TagFromName(ReferencedSeriesSequence));
+		Assert(aReferencedSeriesSequence);
+
+		AttributeList *lReferencedSeriesSequence = new AttributeList();
+		Assert(lReferencedSeriesSequence);
+
+			(*lReferencedSeriesSequence)+=new UIStringAttribute(TagFromName(SeriesInstanceUID),vSeriesInstanceUIDOfReferencedImage);
+
+				SequenceAttribute *aReferencedImageSequence = new SequenceAttribute(TagFromName(ReferencedImageSequence));
+				Assert(aReferencedImageSequence);
+
+				AttributeList *lReferencedImageSequence = new AttributeList();
+				Assert(lReferencedImageSequence);
+
+				(*lReferencedImageSequence)+=new UIStringAttribute(TagFromName(ReferencedSOPClassUID),vSOPClassUIDOfReferencedImage);
+				(*lReferencedImageSequence)+=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),vSOPInstanceUIDOfReferencedImage);
+
+				(*aReferencedImageSequence)+=lReferencedImageSequence;
+
+			(*lReferencedSeriesSequence)+=aReferencedImageSequence;
+
+		(*aReferencedSeriesSequence)+=lReferencedSeriesSequence;
+
+		output_list+=aReferencedSeriesSequence;
+
+	}
+
+	// Displayed Area Module
+
+	{
+		SequenceAttribute *aDisplayedAreaSelectionSequence = new SequenceAttribute(TagFromName(DisplayedAreaSelectionSequence));
+		Assert(aDisplayedAreaSelectionSequence);
+
+		AttributeList *lDisplayedAreaSelectionSequence = new AttributeList();
+		Assert(lDisplayedAreaSelectionSequence);
+
+			Attribute *aDisplayedAreaTopLeftHandCorner = new SignedLongAttribute(TagFromName(DisplayedAreaTopLeftHandCorner));
+			Assert(aDisplayedAreaTopLeftHandCorner);
+			aDisplayedAreaTopLeftHandCorner->addValue(Uint16(1));
+			aDisplayedAreaTopLeftHandCorner->addValue(Uint16(1));
+
+			Attribute *aDisplayedAreaBottomRightHandCorner = new SignedLongAttribute(TagFromName(DisplayedAreaBottomRightHandCorner));
+			Assert(aDisplayedAreaBottomRightHandCorner);
+			aDisplayedAreaBottomRightHandCorner->addValue(Uint16(vColumnsOfReferencedImage));
+			aDisplayedAreaBottomRightHandCorner->addValue(Uint16(vRowsOfReferencedImage));
+
+			Attribute *aPresentationSizeMode = new CodeStringAttribute(TagFromName(PresentationSizeMode),"SCALE TO FIT");
+			Assert(aPresentationSizeMode);
+
+			Attribute *aPresentationPixelAspectRatio = new IntegerStringAttribute(TagFromName(PresentationPixelAspectRatio));
+			Assert(aPresentationPixelAspectRatio);
+			aPresentationPixelAspectRatio->addValue(Uint16(1));
+			aPresentationPixelAspectRatio->addValue(Uint16(1));
+
+		(*lDisplayedAreaSelectionSequence)+=aDisplayedAreaTopLeftHandCorner;
+		(*lDisplayedAreaSelectionSequence)+=aDisplayedAreaBottomRightHandCorner;
+		(*lDisplayedAreaSelectionSequence)+=aPresentationSizeMode;
+		(*lDisplayedAreaSelectionSequence)+=aPresentationPixelAspectRatio;
+
+		(*aDisplayedAreaSelectionSequence)+=lDisplayedAreaSelectionSequence;
+
+		output_list+=aDisplayedAreaSelectionSequence;
+	}
+
+	// Softcopy Presentation LUT Module
+
+	if (plutshape) {
+		output_list+=new CodeStringAttribute(TagFromName(PresentationLUTShape),plutshape);
+	}
+
+	return true;
+}
+
+static bool
+addLinearLUT(/*Managed*/AttributeList &output_list,TextOutputStream &log,bool useOWForLUTs,
+	bool ismodalitylut,bool isvoilut,bool ispresentationlut,const char *explanation,const char *luttype,
+	Uint32 numberofentries,
+	Uint16 firstvaluemapped,
+	Uint16 inputbitsallocated,
+	Uint16 outputbitsallocated,
+	Uint16 firstlutentry,
+	Int16  lutentryincrement)
+{
+cerr << "addLinearLUT(): numberofentries =" << numberofentries << endl;
+cerr << "addLinearLUT(): firstvaluemapped =" << firstvaluemapped << endl;
+cerr << "addLinearLUT(): inputbitsallocated =" << inputbitsallocated << endl;
+cerr << "addLinearLUT(): outputbitsallocated =" << outputbitsallocated << endl;
+cerr << "addLinearLUT(): firstlutentry =" << firstlutentry << endl;
+cerr << "addLinearLUT(): lutentryincrement =" << lutentryincrement << endl;
+
+	Assert(inputbitsallocated <= 16);
+	Assert(outputbitsallocated <= 16);
+	Assert(numberofentries <= 65536);
+
+	Attribute *aLUTDescriptor = new UnsignedShortAttribute(TagFromName(LUTDescriptor));
+	Assert(aLUTDescriptor);
+	aLUTDescriptor->addValue(numberofentries == 65536 ? 0 : numberofentries);
+	aLUTDescriptor->addValue(firstvaluemapped);
+	aLUTDescriptor->addValue(outputbitsallocated);
+
+	Uint16 *values = NULL;
+	Attribute *aLUTData = NULL;
+	if (useOWForLUTs) {
+		aLUTData = new OtherWordSmallNonPixelAttribute(TagFromName(LUTData));
+		values = new Uint16[numberofentries];
+	}
+	else {
+		aLUTData = new UnsignedShortAttribute(TagFromName(LUTData));
+	}
+	Assert(aLUTData);
+	
+	Int16 value;
+	Uint32 left;
+	Uint32 index;
+
+	if (outputbitsallocated <= 8) {
+
+		// pack 8 bits into 16 bit words, 1st 8 bits into low part of word
+
+		for (value=firstlutentry,left=numberofentries,index=0; left > 0; left-=2,++index) {
+			Uint16 usevalue;
+			Uint16 usevalue1;
+			Uint16 usevalue2;
+
+			if (outputbitsallocated > inputbitsallocated) {
+				unsigned shiftleftforvalue=outputbitsallocated-inputbitsallocated;
+				Assert(inputbitsallocated >= shiftleftforvalue);				// doesn't support multiple replications
+				unsigned shiftrightforfill=inputbitsallocated-shiftleftforvalue;
+
+				usevalue1 = (value<<shiftleftforvalue) | (Uint16(value)>>shiftrightforfill);	// unsigned to avoid sign replication in fill
+				value+=lutentryincrement;
+				usevalue2 = (value<<shiftleftforvalue) | (Uint16(value)>>shiftrightforfill);	// unsigned to avoid sign replication in fill
+			}
+			else {
+				usevalue1 = value>>(inputbitsallocated-outputbitsallocated);	// no sign extension :( ?
+				value+=lutentryincrement;
+				usevalue2 = value>>(inputbitsallocated-outputbitsallocated);	// no sign extension :( ?
+			}
+			value+=lutentryincrement;
+
+			usevalue=(Uint16((usevalue1 & 0xff) | (usevalue2 << 8)));
+			if (useOWForLUTs) {
+				values[index]=usevalue;
+			}
+			else {
+				aLUTData->addValue(usevalue);
+			}
+		}
+	}
+	else {
+		for (value=firstlutentry,left=numberofentries; left > 0; --left,++index) {
+			Uint16 usevalue;
+
+			if (outputbitsallocated > inputbitsallocated) {
+				unsigned shiftleftforvalue=outputbitsallocated-inputbitsallocated;
+				Assert(inputbitsallocated >= shiftleftforvalue);				// doesn't support multiple replications
+				unsigned shiftrightforfill=inputbitsallocated-shiftleftforvalue;
+
+				usevalue = (value<<shiftleftforvalue) | (Uint16(value)>>shiftrightforfill);	// unsigned to avoid sign replication in fill
+			}
+			else {
+				usevalue = value>>(inputbitsallocated-outputbitsallocated);	// no sign extension :( ?
+			}
+			value+=lutentryincrement;
+//cerr << "addLinearLUT(): adding usevalue =" << usevalue << " value =" << value << endl;
+			if (useOWForLUTs) {
+				values[index]=usevalue;
+			}
+			else {
+				aLUTData->addValue(usevalue);
+			}
+		}
+	}
+	if (useOWForLUTs) {
+		aLUTData->setValue(values,numberofentries);
+	}
+
+	SequenceAttribute *aLUTSequence = 0;
+	if      (ismodalitylut)     aLUTSequence = new SequenceAttribute(TagFromName(ModalityLUTSequence));
+	else if (isvoilut)          aLUTSequence = new SequenceAttribute(TagFromName(VOILUTSequence));
+	else if (ispresentationlut) aLUTSequence = new SequenceAttribute(TagFromName(PresentationLUTSequence));
+	else Assert(0);
+
+	Assert(aLUTSequence);
+
+	AttributeList *lLUTSequence = new AttributeList();
+	Assert(lLUTSequence);
+
+	(*lLUTSequence)+=aLUTData;
+	(*lLUTSequence)+=aLUTDescriptor;
+	if (ismodalitylut) {
+		(*lLUTSequence)+=new LongStringAttribute(TagFromName(ModalityLUTType),luttype ? luttype : "");
+	}
+	else {
+		Assert(luttype == 0);
+	}
+	(*lLUTSequence)+=new LongStringAttribute(TagFromName(LUTExplanation),explanation ? explanation : "");
+
+	(*aLUTSequence)+=lLUTSequence;
+
+	output_list+=aLUTSequence;
+
+	return true;
+}
+
+static bool
+addLinearModalityLUT(ManagedAttributeList &output_list,TextOutputStream &log,bool useOWForLUTs,
+	const char *explanation,
+	Uint32 numberofentries,
+	Uint16 firstvaluemapped,
+	Uint16 inputbitsallocated,
+	Uint16 outputbitsallocated,
+	Uint16 firstlutentry,
+	Int16  lutentryincrement)
+{
+
+	return addLinearLUT(output_list,log,useOWForLUTs,
+		true,false,false,explanation,"US",
+		numberofentries,
+		firstvaluemapped,
+		inputbitsallocated,
+		outputbitsallocated,
+		firstlutentry,
+		lutentryincrement);
+}
+
+static bool
+addLinearPresentationLUT(ManagedAttributeList &output_list,TextOutputStream &log,bool useOWForLUTs,
+	const char *explanation,
+	Uint32 numberofentries,
+	Uint16 firstvaluemapped,
+	Uint16 inputbitsallocated,
+	Uint16 outputbitsallocated,
+	Uint16 firstlutentry,
+	Int16  lutentryincrement)
+{
+
+	return addLinearLUT(output_list,log,useOWForLUTs,
+		false,false,true,explanation,0,
+		numberofentries,
+		firstvaluemapped,
+		inputbitsallocated,
+		outputbitsallocated,
+		firstlutentry,
+		lutentryincrement);
+}
+
+static bool
+addSoftcopyLinearVOILUT(ManagedAttributeList &output_list,TextOutputStream &log,bool useOWForLUTs,
+	const char *explanation,
+	Uint32 numberofentries,
+	Uint16 firstvaluemapped,
+	Uint16 inputbitsallocated,
+	Uint16 outputbitsallocated,
+	Uint16 firstlutentry,
+	Int16  lutentryincrement)
+{
+	// In Presentation State, VOI LUT Sequence is nested in Softcopy VOI LUT Sequence ...
+
+	SequenceAttribute *aSoftcopyVOILUTSequence = new SequenceAttribute(TagFromName(SoftcopyVOILUTSequence));
+	Assert(aSoftcopyVOILUTSequence);
+
+	output_list+=aSoftcopyVOILUTSequence;
+
+	AttributeList *lSoftcopyVOILUTSequence = new AttributeList();
+	Assert(lSoftcopyVOILUTSequence);
+
+	(*aSoftcopyVOILUTSequence)+=lSoftcopyVOILUTSequence;
+
+	return addLinearLUT(*lSoftcopyVOILUTSequence,log,useOWForLUTs,
+		false,true,false,explanation,0,
+		numberofentries,
+		firstvaluemapped,
+		inputbitsallocated,
+		outputbitsallocated,
+		firstlutentry,
+		lutentryincrement);
+}
+
+static bool
+addSoftcopyWindowCenterWidth(ManagedAttributeList &output_list,TextOutputStream &log,
+	const char *explanation,
+	double windowcenter,
+	double windowwidth)
+{
+	// In Presentation State, window is nested in Softcopy VOI LUT Sequence ...
+
+	SequenceAttribute *aSoftcopyVOILUTSequence = new SequenceAttribute(TagFromName(SoftcopyVOILUTSequence));
+	Assert(aSoftcopyVOILUTSequence);
+
+	output_list+=aSoftcopyVOILUTSequence;
+
+	AttributeList *lSoftcopyVOILUTSequence = new AttributeList();
+	Assert(lSoftcopyVOILUTSequence);
+
+	(*aSoftcopyVOILUTSequence)+=lSoftcopyVOILUTSequence;
+
+	Attribute *aWindowCenter = new DecimalStringAttribute(TagFromName(WindowCenter),windowcenter);
+	Assert(aWindowCenter);
+	(*lSoftcopyVOILUTSequence)+=aWindowCenter;
+
+	Attribute *aWindowWidth = new DecimalStringAttribute(TagFromName(WindowWidth),windowwidth);
+	Assert(aWindowWidth);
+	(*lSoftcopyVOILUTSequence)+=aWindowWidth;
+
+	Attribute *aWindowCenterWidthExplanation = new LongStringAttribute(TagFromName(WindowCenterWidthExplanation),explanation);
+	Assert(aWindowCenterWidthExplanation);
+	(*lSoftcopyVOILUTSequence)+=aWindowCenterWidthExplanation;
+
+	return true;
+}
+
+static bool
+addLinearVOILUT(ManagedAttributeList &output_list,TextOutputStream &log,bool useOWForLUTs,
+	const char *explanation,
+	Uint32 numberofentries,
+	Uint16 firstvaluemapped,
+	Uint16 inputbitsallocated,
+	Uint16 outputbitsallocated,
+	Uint16 firstlutentry,
+	Int16  lutentryincrement)
+{
+	return addLinearLUT(output_list,log,useOWForLUTs,
+		false,true,false,explanation,0,
+		numberofentries,
+		firstvaluemapped,
+		inputbitsallocated,
+		outputbitsallocated,
+		firstlutentry,
+		lutentryincrement);
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool useOWForLUTs=options.get("ow");
+	bool imageRatherThanPresentationState=options.get("image");
+	bool verbose=options.get("verbose") || options.get("v");
+
+	const char *plutshape = 0;
+
+	options.get("presentationlutshape",plutshape);
+
+	bool addlinearmodalitylut=false;
+	Uint32 addlinearmodalitylut_numberofentries;
+	Uint16 addlinearmodalitylut_firstvaluemapped;
+	Uint16 addlinearmodalitylut_inputbitsallocated;
+	Uint16 addlinearmodalitylut_outputbitsallocated;
+	Uint16 addlinearmodalitylut_firstlutentry;
+	Int16  addlinearmodalitylut_lutentryincrement;
+	{
+		long addlinearmodalitylut_parameters[6];
+		addlinearmodalitylut=options.get("addlinearmodalitylut",addlinearmodalitylut_parameters,6) == 6;
+		if (addlinearmodalitylut) {
+			addlinearmodalitylut_numberofentries=addlinearmodalitylut_parameters[0];
+			addlinearmodalitylut_firstvaluemapped=addlinearmodalitylut_parameters[1];
+			addlinearmodalitylut_inputbitsallocated=addlinearmodalitylut_parameters[2];
+			addlinearmodalitylut_outputbitsallocated=addlinearmodalitylut_parameters[3];
+			addlinearmodalitylut_firstlutentry=addlinearmodalitylut_parameters[4];
+			addlinearmodalitylut_lutentryincrement=addlinearmodalitylut_parameters[5];
+		}
+	}
+
+	bool addlinearpresentationlut=false;
+	Uint32 addlinearpresentationlut_numberofentries;
+	Uint16 addlinearpresentationlut_firstvaluemapped;
+	Uint16 addlinearpresentationlut_inputbitsallocated;
+	Uint16 addlinearpresentationlut_outputbitsallocated;
+	Uint16 addlinearpresentationlut_firstlutentry;
+	Int16  addlinearpresentationlut_lutentryincrement;
+	{
+		long addlinearpresentationlut_parameters[6];
+		addlinearpresentationlut=options.get("addlinearpresentationlut",addlinearpresentationlut_parameters,6) == 6;
+		if (addlinearpresentationlut) {
+			addlinearpresentationlut_numberofentries=addlinearpresentationlut_parameters[0];
+			addlinearpresentationlut_firstvaluemapped=addlinearpresentationlut_parameters[1];
+			addlinearpresentationlut_inputbitsallocated=addlinearpresentationlut_parameters[2];
+			addlinearpresentationlut_outputbitsallocated=addlinearpresentationlut_parameters[3];
+			addlinearpresentationlut_firstlutentry=addlinearpresentationlut_parameters[4];
+			addlinearpresentationlut_lutentryincrement=addlinearpresentationlut_parameters[5];
+		}
+	}
+
+	bool addsoftcopylinearvoilut=false;
+	Uint32 addsoftcopylinearvoilut_numberofentries;
+	Uint16 addsoftcopylinearvoilut_firstvaluemapped;
+	Uint16 addsoftcopylinearvoilut_inputbitsallocated;
+	Uint16 addsoftcopylinearvoilut_outputbitsallocated;
+	Uint16 addsoftcopylinearvoilut_firstlutentry;
+	Int16  addsoftcopylinearvoilut_lutentryincrement;
+	{
+		long addsoftcopylinearvoilut_parameters[6];
+		addsoftcopylinearvoilut=options.get("addsoftcopylinearvoilut",addsoftcopylinearvoilut_parameters,6) == 6;
+		if (addsoftcopylinearvoilut) {
+			addsoftcopylinearvoilut_numberofentries=addsoftcopylinearvoilut_parameters[0];
+			addsoftcopylinearvoilut_firstvaluemapped=addsoftcopylinearvoilut_parameters[1];
+			addsoftcopylinearvoilut_inputbitsallocated=addsoftcopylinearvoilut_parameters[2];
+			addsoftcopylinearvoilut_outputbitsallocated=addsoftcopylinearvoilut_parameters[3];
+			addsoftcopylinearvoilut_firstlutentry=addsoftcopylinearvoilut_parameters[4];
+			addsoftcopylinearvoilut_lutentryincrement=addsoftcopylinearvoilut_parameters[5];
+		}
+	}
+
+	bool addsoftcopywindowcenterwidth=false;
+	const char *addsoftcopywindowcenterwidth_explanation;
+	double addsoftcopywindowcenterwidth_center;
+	double addsoftcopywindowcenterwidth_width;
+	{
+		const char *addsoftcopywindowcenterwidth_parameters[3];
+		addsoftcopywindowcenterwidth=options.get("addsoftcopywindowcenterwidth",addsoftcopywindowcenterwidth_parameters,3) == 3;
+		if (addsoftcopywindowcenterwidth) {
+			addsoftcopywindowcenterwidth_center=atof(addsoftcopywindowcenterwidth_parameters[0]);
+			addsoftcopywindowcenterwidth_width=atof(addsoftcopywindowcenterwidth_parameters[1]);
+			addsoftcopywindowcenterwidth_explanation=addsoftcopywindowcenterwidth_parameters[2];
+		}
+	}
+
+	if (!plutshape && !addlinearpresentationlut) {
+		plutshape="IDENTITY";
+	}
+
+	bool addlinearvoilut=false;
+	Uint32 addlinearvoilut_numberofentries;
+	Uint16 addlinearvoilut_firstvaluemapped;
+	Uint16 addlinearvoilut_inputbitsallocated;
+	Uint16 addlinearvoilut_outputbitsallocated;
+	Uint16 addlinearvoilut_firstlutentry;
+	Int16  addlinearvoilut_lutentryincrement;
+	{
+		long addlinearvoilut_parameters[6];
+		addlinearvoilut=options.get("addlinearvoilut",addlinearvoilut_parameters,6) == 6;
+		if (addlinearvoilut) {
+			addlinearvoilut_numberofentries=addlinearvoilut_parameters[0];
+			addlinearvoilut_firstvaluemapped=addlinearvoilut_parameters[1];
+			addlinearvoilut_inputbitsallocated=addlinearvoilut_parameters[2];
+			addlinearvoilut_outputbitsallocated=addlinearvoilut_parameters[3];
+			addlinearvoilut_firstlutentry=addlinearvoilut_parameters[4];
+			addlinearvoilut_lutentryincrement=addlinearvoilut_parameters[5];
+		}
+	}
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-ow]"
+			<< " [-addlinearmodalitylut nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr]"
+			<< " [-addlinearpresentationlut nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr]"
+			<< " [-addsoftcopylinearvoilut nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr]"
+			<< " [-addsoftcopywindowcenterwidth center width explanation]"
+			<< " [-presentationlutshape IDENTITY|INVERSE]"
+			<< " [-image]"
+			<< " [-addlinearvoilut nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList input_list;
+	ManagedAttributeList *output_list = NULL;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	input_list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!input_list.good()) {
+		log << input_list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		if (imageRatherThanPresentationState) {
+			output_list=&input_list;
+		}
+		else {
+			output_list=new ManagedAttributeList();
+			success=createPresentationState(input_list,*output_list,log,plutshape);
+		}
+		
+		if (success && addlinearmodalitylut) {
+			success=addLinearModalityLUT(*output_list,log,useOWForLUTs,0 /* no explanation */,
+				addlinearmodalitylut_numberofentries,
+				addlinearmodalitylut_firstvaluemapped,
+				addlinearmodalitylut_inputbitsallocated,
+				addlinearmodalitylut_outputbitsallocated,
+				addlinearmodalitylut_firstlutentry,
+				addlinearmodalitylut_lutentryincrement);
+		}
+		if (success && addlinearpresentationlut) {
+			success=addLinearPresentationLUT(*output_list,log,useOWForLUTs,0 /* no explanation */,
+				addlinearpresentationlut_numberofentries,
+				addlinearpresentationlut_firstvaluemapped,
+				addlinearpresentationlut_inputbitsallocated,
+				addlinearpresentationlut_outputbitsallocated,
+				addlinearpresentationlut_firstlutentry,
+				addlinearpresentationlut_lutentryincrement);
+		}
+		if (success && addsoftcopylinearvoilut) {
+			success=addSoftcopyLinearVOILUT(*output_list,log,useOWForLUTs,0 /* no explanation */,
+				addsoftcopylinearvoilut_numberofentries,
+				addsoftcopylinearvoilut_firstvaluemapped,
+				addsoftcopylinearvoilut_inputbitsallocated,
+				addsoftcopylinearvoilut_outputbitsallocated,
+				addsoftcopylinearvoilut_firstlutentry,
+				addsoftcopylinearvoilut_lutentryincrement);
+		}
+		if (success && addsoftcopywindowcenterwidth) {
+			success=addSoftcopyWindowCenterWidth(*output_list,log,
+				addsoftcopywindowcenterwidth_explanation,
+				addsoftcopywindowcenterwidth_center,
+				addsoftcopywindowcenterwidth_width);
+		}
+		if (success && addlinearvoilut) {
+			success=addLinearVOILUT(*output_list,log,useOWForLUTs,0 /* no explanation */,
+				addlinearvoilut_numberofentries,
+				addlinearvoilut_firstvaluemapped,
+				addlinearvoilut_inputbitsallocated,
+				addlinearvoilut_outputbitsallocated,
+				addlinearvoilut_firstlutentry,
+				addlinearvoilut_lutentryincrement);
+		}
+	}
+
+	if (success && !usualManagedAttributeListWrite(*output_list,dout,dicom_output_options,log,verbose)) success=false;
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcmkpres.man b/appsrc/dcfile/dcmkpres.man
new file mode 100755
index 0000000..0037513
--- /dev/null
+++ b/appsrc/dcfile/dcmkpres.man
@@ -0,0 +1,101 @@
+.TH DCMKPRES 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Create DICOM presentation state"
+.SH NAME
+dcmkpres \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create DICOM presentation state
+.SH SYNOPSIS
+.HP 10
+.B dcmkpres
+.so man1/gen.so
+[
+.B \-addlinearmodalitylut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+]
+[
+.B \-addlinearpresentationlut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+]
+[
+.B \-addsoftcopylinearvoilut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+]
+[
+.B \-addsoftcopywindowcenterwidth " center width explanation"
+]
+[
+.B \-presentationlutshape " IDENTITY|INVERSE"
+]
+[
+.B \-image
+]
+[
+.B \-addlinearvoilut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+]
+[
+.B \-v|verbose
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcmkpres
+reads the named dicom or acr-nema input image file and creates either a grayscale softcopy presentation state that is part of the same study and references
+the input image, or a modified image with any additional lookup tables added.
+.LP
+Lookup tables may be added containing linear ramps, with the parameters being the number of LUT entries, the first input value mapped, the number of bits in the input values, the number of bits in the LUT entries, the first LUT entry value (before shifting based on the difference between the input and output bits) and the LUT entry increment value (before shifting based on the difference between the input and output bits, i.e. should usually have a value of 1 or -1). Note that when the o [...]
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-ow
+.RS
+Use an OW, rather than US, value representation for the LUT Data. US VR attributes are limited to
+only 65536 bytes (32768 LUT entries) in an explicit VR encoding, and hence are deprecated, though
+permitted for historical reasons. The use of this flag is strongly advised, but the default
+behavior is the deprecated behavior for historical reasons.
+.RE
+.TP
+.B \-addlinearmodalitylut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+.RS
+Add a linear Modality LUT with the specified parameters.
+.RE
+.TP
+.B \-addlinearpresentationlut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+.RS
+Add a linear Softcopy Presentation LUT with the specified parameters.
+.RE
+.TP
+.B \-addsoftcopylinearvoilut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+.RS
+Add a linear Softcopy VOI LUT with the specified parameters.
+.RE
+.TP
+.B \-addsoftcopywindowcenterwidth " center width explanation"
+.RS
+Add window center and width attributes within the Softcopy VOI LUT Sequence.
+.RE
+.TP
+.B \-image
+.RS
+Leave the input as an image, rather than turning it into a presentation state.
+.RE
+.TP
+.B \-addlinearvoilut " nentries 1stvaluemapped inbits outbits 1stlutentry lutentryincr"
+.RS
+Add a linear VOI LUT with the specified parameters (for images not presentation states).
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+It would be nice to generate other than linear ramps.
diff --git a/appsrc/dcfile/dcmulti.cc b/appsrc/dcfile/dcmulti.cc
new file mode 100644
index 0000000..04f12e0
--- /dev/null
+++ b/appsrc/dcfile/dcmulti.cc
@@ -0,0 +1,7996 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcmulti.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#include <cctype>
+#else
+#include <fstream.h>
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrseq.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "uidgen.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static const double defaultWindowCenter = 127.5;
+static const double defaultWindowWidth = 256;
+
+static ElementDictionary staticDictionary;
+
+// Define a funky derived OX class to be able to writeBase() and not activateSource() ...
+
+class OtherUnspecifiedLargeAttributeDummy : public OtherUnspecifiedLargeAttributeBase {
+public:
+	OtherUnspecifiedLargeAttributeDummy(Tag t,
+			Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+			TransferSyntax *transfersyntax,
+			Uint16 bytesinword,
+			Uint16 bitsallocated,
+			Uint16 bitsstored,
+			Uint16 highbit,
+			Uint32 length=0xffffffff)
+		: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+		{
+			srcpixeldata=0;
+
+			srcbitsallocated=bitsallocated;
+			srcbitsstored=bitsstored;
+			srchighbit=highbit;
+
+			Assert(transfersyntax);
+			setOutputEncoding(
+				transfersyntax,
+				bytesinword,bitsallocated,
+				bitsstored,highbit,length);
+		}
+
+	virtual ~OtherUnspecifiedLargeAttributeDummy()
+		{
+		}
+
+	bool activateSource(void)
+		{
+			Assert(0);	// only here to make concrete ... pixel data is actually written manually
+			return true;
+		}
+
+	bool activateSourceWithoutUnpacking(void)
+		{
+			Assert(0);	// only here to make concrete ... pixel data is actually written manually
+			return true;
+		}
+
+	DicomOutputStream& writeBase(DicomOutputStream& dout)
+		{
+			return OtherUnspecifiedLargeAttributeBase::writeBase(dout);	//protected method
+		}
+
+	TextOutputStream& writeBase(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false)
+		{
+			return OtherUnspecifiedLargeAttributeBase::writeBase(stream,dict,verbose);	//protected method
+		}
+};
+
+// Various utility functions ...
+
+// getStringFromTime() should really be added as a static function to generic/datetype.h
+
+static char *getStringFromTime(Time time) {
+//cerr << "getStringFromTime: isgood()=" << time.isgood() << " hh=" << time.getHour() << " mm=" << time.getMinute() << " ss=" << time.getSecond() << " ms=" << time.getMilliSecond() << endl;
+	ostrstream ost;
+	ost << dec << setfill('0');
+	if (time.isgood()) {
+		ost << setw(2) << time.getHour()
+		    << setw(2) << time.getMinute()
+		    << setw(2) << time.getSecond();
+		if (time.getMilliSecond())
+			ost << '.' << setw(3) << time.getMilliSecond();
+	}
+	ost << ends;
+	return ost.str();
+}
+
+// removeLeadingSpaces() is copied from libsrc/src/attrtyps.cc and probably should be factored out somewhere
+
+static const char*
+removeLeadingSpaces(const char *from)
+{
+	if (from) while (*from && isspace(*from)) ++from;
+	return from;
+}
+
+static bool arrayOfStringValuesContains(char **a,int n,const char *v) {
+//cerr << "arrayOfStringValuesContains:" << endl;
+	if (a && v) {
+		int i;
+		for (i=0; i<n; ++i) {
+//cerr << "arrayOfStringValuesContains: i=" << i << endl;
+			if (a[i] && strcmp(a[i],v) == 0) {
+//cerr << "arrayOfStringValuesContains: true" << endl;
+				return true;
+			}
+		}
+	}
+//cerr << "arrayOfStringValuesContains: false" << endl;
+	return false;
+}					
+
+static char *makeDateTimeString(const char *d,const char *t) {
+//cerr << "makeDateTimeString: d=" << d << " t=" << t << endl;
+	int l= (d ? strlen(d) : 0) + (t ? strlen(t) : 0) + 1;
+	char *dt=new char[l];
+	*dt=0;
+	if (d) strcat(dt,d);
+	if (t) strcat(dt,t);
+	return dt;
+}
+
+// Various functions to check and match values ...
+
+static bool
+errorIfStringValuesDontMatch(const char *firstValue,
+	const char *newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	Assert(firstValue);
+	Assert(newValue);
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (strcmp(firstValue,newValue) != 0) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << (newValue ? newValue : "")
+		    << "> previously seen as  <"
+		    << (firstValue ? firstValue : "")
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static bool
+errorIfIntegerValuesDontMatch(Uint16 firstValue,
+	Uint16 newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	//Assert(firstValue);	// May legitimately be zero ?
+	//Assert(newValue);	// May legitimately be zero ?
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (firstValue != newValue) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << newValue
+		    << "> previously seen as  <"
+		    << firstValue
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static bool
+errorIfFloatValuesDontMatch(double firstValue,
+	double newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	//Assert(firstValue);	// May legitimately be zero ?
+	//Assert(newValue);	// May legitimately be zero ?
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (firstValue != newValue) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << newValue
+		    << "> previously seen as  <"
+		    << firstValue
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static const char *
+getStringValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	const char *value=AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	return a ? value : "";
+}
+
+static Uint16
+getIntegerValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	Uint16 value=AttributeValue(a);
+	return value;
+}
+
+static double
+getFloatValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	double value=AttributeValue(a);
+	return value;
+}
+
+static const char *
+getAndCheckStringMatchElseError(bool first,const char * &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	const char *value=getStringValueElseError(list,tag,label,filename,log);
+	Assert(value);
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfStringValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+static Uint16
+getAndCheckIntegerMatchElseError(bool first,Uint16 &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Uint16 value=getIntegerValueElseError(list,tag,label,filename,log);
+	//Assert(value);	// May legitimately be zero ?
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfIntegerValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+static double
+getAndCheckFloatMatchElseError(bool first,double &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	double value=getFloatValueElseError(list,tag,label,filename,log);
+	//Assert(value);	// May legitimately be zero ?
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfFloatValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+
+static const char *fixRescaleTypeForCTIfNecessary(const char *use_type,bool addMultiFrameCTStuff,bool imageIsDerived) {
+	if (use_type == NULL) {
+		use_type = addMultiFrameCTStuff && !imageIsDerived ? "HU" : "US";
+	}
+	else if (strncmp(use_type,"Houn",4) == 0) {	// e.g., "Hounsfield Units", or incorrectly spelled "Houndsfield Units"
+		use_type="HU";				// use standard abbreviation instead
+	}
+	// else leave it alone
+	return use_type;
+}
+
+// Functions to get value to sort using ImagePositionPatient ...
+
+static double getDistanceWithinImagePlane(double tlhc_X,double tlhc_Y,double tlhc_Z,
+		double reference_tlhc_X,double reference_tlhc_Y,double reference_tlhc_Z,
+		double row_X,double row_Y,double row_Z,double col_X,double col_Y,double col_Z) {
+
+	// length of row (and column) is sqrt(dot product of vector with itself)
+	// should be 1 since both row and col vectors unit vectors
+	// but just in case ...
+
+	double row_length=sqrt(row_X*row_X+row_Y*row_Y+row_Z*row_Z);
+	double col_length=sqrt(col_X*col_X+col_Y*col_Y+col_Z*col_Z);
+
+//cerr << "getDistanceWithinImagePlane: row_length = " << row_length << endl;
+//cerr << "getDistanceWithinImagePlane: col_length = " << col_length << endl;
+
+	Assert(row_length != 0);
+	Assert(col_length != 0);
+
+	// calculate vector between tlhc and reference tlhc
+
+	double difference_X = tlhc_X - reference_tlhc_X;
+	double difference_Y = tlhc_Y - reference_tlhc_Y;
+	double difference_Z = tlhc_Z - reference_tlhc_Z;
+
+//cerr << "getDistanceWithinImagePlane: difference_X = " << difference_X << endl;
+//cerr << "getDistanceWithinImagePlane: difference_Y = " << difference_Y << endl;
+//cerr << "getDistanceWithinImagePlane: difference_Z = " << difference_Z << endl;
+
+	// project difference vector onto row (and column) axes to get distance
+	// by computing dot product of difference vector and row (and column) vector
+	// and dividing by length of row (or column) vector ...
+
+	double row_distance = (difference_X*row_X+difference_Y*row_Y+difference_Z*row_Z)/row_length;
+	double col_distance = (difference_X*col_X+difference_Y*col_Y+difference_Z*col_Z)/col_length;
+	
+	// distance we want is hypotenuse ...
+	
+	double distance = sqrt(row_distance*row_distance + col_distance*col_distance);
+	
+//cerr << "getDistanceWithinImagePlane: distance = " << distance << endl;
+	
+	return distance;
+}
+
+static double getDistanceAlongNormalToImagePlane(double tlhc_X,double tlhc_Y,double tlhc_Z,
+		double reference_tlhc_X,double reference_tlhc_Y,double reference_tlhc_Z,
+		double row_X,double row_Y,double row_Z,double col_X,double col_Y,double col_Z) {
+
+	// compute normal to image plane - cross product of row and column vectors ...
+
+	double normal_X = row_Y*col_Z - row_Z*col_Y;
+	double normal_Y = row_Z*col_X - row_X*col_Z;
+	double normal_Z = row_X*col_Y - row_Y*col_X;
+
+//cerr << "getDistanceAlongNormalToImagePlane:normal_X = " << normal_X << endl;
+//cerr << "getDistanceAlongNormalToImagePlane:normal_Y = " << normal_Y << endl;
+//cerr << "getDistanceAlongNormalToImagePlane:normal_Z = " << normal_Z << endl;
+
+	// length of normal is sqrt(dot product of normal with itself)
+	// should be 1 since both row and col vectors unit vectors
+	// but just in case ...
+
+	double normal_length=sqrt(normal_X*normal_X+normal_Y*normal_Y+normal_Z*normal_Z);
+
+//cerr << "getDistanceAlongNormalToImagePlane:normal_length = " << normal_length << endl;
+
+	Assert(normal_length != 0);
+
+	// calculate vector between tlhc and reference tlhc
+
+	double difference_X = tlhc_X - reference_tlhc_X;
+	double difference_Y = tlhc_Y - reference_tlhc_Y;
+	double difference_Z = tlhc_Z - reference_tlhc_Z;
+
+//cerr << "getDistanceAlongNormalToImagePlane:difference_X = " << difference_X << endl;
+//cerr << "getDistanceAlongNormalToImagePlane:difference_Y = " << difference_Y << endl;
+//cerr << "getDistanceAlongNormalToImagePlane:difference_Z = " << difference_Z << endl;
+
+	// project difference vector onto normal to get distance
+	// by computing dot product of difference vector and normal vector
+	// and dividing by length of normal vector ...
+
+	double distance = (difference_X*normal_X+difference_Y*normal_Y+difference_Z*normal_Z)/normal_length;
+	
+//cerr << "getDistanceAlongNormalToImagePlane: distance = " << distance << endl;
+	
+	return distance;
+}
+
+static double
+getDistanceAlongNormalToImagePlane(bool first,AttributeList &list,
+	double &reference_tlhc_X,double &reference_tlhc_Y,double &reference_tlhc_Z,
+	const char *filename,TextOutputStream &log)
+{
+	Attribute *aImagePositionPatient=isValuePresentElseError(list,
+		TagFromName(ImagePositionPatient),"Image Position Patient",filename,log);
+	Attribute *aImageOrientationPatient=isValuePresentElseError(list,
+		TagFromName(ImageOrientationPatient),"Image Orientation Patient",filename,log);
+
+	if (!aImagePositionPatient || !aImageOrientationPatient) return 0;
+
+	if (aImagePositionPatient->getVM() != 3) {
+		log << filename << ": " 
+		    << EMsgDC(BadAttributeValueMultiplicity)
+		    << " - Image Position Patient - "
+		    << MMsgDC(Expected) << " 3 "
+		    << MMsgDC(Got) << " " << aImagePositionPatient->getVM()
+		    << endl;
+		return 0;
+	}
+
+	if (aImageOrientationPatient->getVM() != 6) {
+		log << filename << ": " 
+		    << EMsgDC(BadAttributeValueMultiplicity)
+		    << " - Image Orientation Patient - "
+		    << MMsgDC(Expected) << " 6 "
+		    << MMsgDC(Got) << " " << aImageOrientationPatient->getVM()
+		    << endl;
+		return 0;
+	}
+
+	double tlhc_X; aImagePositionPatient->getValue(0,tlhc_X);
+	double tlhc_Y; aImagePositionPatient->getValue(1,tlhc_Y);
+	double tlhc_Z; aImagePositionPatient->getValue(2,tlhc_Z);
+
+//cerr << "tlhc_X = " << tlhc_X << endl;
+//cerr << "tlhc_Y = " << tlhc_Y << endl;
+//cerr << "tlhc_Z = " << tlhc_Z << endl;
+
+	double distance;
+
+	// if first time, set reference TLHC to current TLHC and return distance of zero
+
+	if (first) {
+		reference_tlhc_X=tlhc_X;
+		reference_tlhc_Y=tlhc_Y;
+		reference_tlhc_Z=tlhc_Z;
+	}
+
+	{
+		double row_X; aImageOrientationPatient->getValue(0,row_X);
+		double row_Y; aImageOrientationPatient->getValue(1,row_Y);
+		double row_Z; aImageOrientationPatient->getValue(2,row_Z);
+
+//cerr << "row_X = " << row_X << endl;
+//cerr << "row_Y = " << row_Y << endl;
+//cerr << "row_Z = " << row_Z << endl;
+
+		double col_X; aImageOrientationPatient->getValue(3,col_X);
+		double col_Y; aImageOrientationPatient->getValue(4,col_Y);
+		double col_Z; aImageOrientationPatient->getValue(5,col_Z);
+
+//cerr << "col_X = " << col_X << endl;
+//cerr << "col_Y = " << col_Y << endl;
+//cerr << "col_Z = " << col_Z << endl;
+
+		distance = getDistanceAlongNormalToImagePlane(tlhc_X,tlhc_Y,tlhc_Z,
+			reference_tlhc_X,reference_tlhc_Y,reference_tlhc_Z,
+			row_X,row_Y,row_Z,col_X,col_Y,col_Z);
+	}
+//cerr << "distance = " << distance << endl;
+
+	return distance;
+}
+
+// Function to get value to sort using ImageOrientationPatient ...
+
+static double
+getAngleOfNormalToImagePlane(bool first,AttributeList &list,
+	double &reference_normal_X,double &reference_normal_Y,double &reference_normal_Z,
+	double &reference_normal_length,
+	const char *filename,TextOutputStream &log)
+{
+	Attribute *aImageOrientationPatient=isValuePresentElseError(list,
+		TagFromName(ImageOrientationPatient),"Image Orientation Patient",filename,log);
+
+	if (!aImageOrientationPatient) return 0;
+
+	if (aImageOrientationPatient->getVM() != 6) {
+		log << filename << ": " 
+		    << EMsgDC(BadAttributeValueMultiplicity)
+		    << " - Image Orientation Patient - "
+		    << MMsgDC(Expected) << " 6 "
+		    << MMsgDC(Got) << " " << aImageOrientationPatient->getVM()
+		    << endl;
+		return 0;
+	}
+
+	double angle;
+
+	double row_X; aImageOrientationPatient->getValue(0,row_X);
+	double row_Y; aImageOrientationPatient->getValue(1,row_Y);
+	double row_Z; aImageOrientationPatient->getValue(2,row_Z);
+
+//cerr << "row_X = " << row_X << endl;
+//cerr << "row_Y = " << row_Y << endl;
+//cerr << "row_Z = " << row_Z << endl;
+
+	double col_X; aImageOrientationPatient->getValue(3,col_X);
+	double col_Y; aImageOrientationPatient->getValue(4,col_Y);
+	double col_Z; aImageOrientationPatient->getValue(5,col_Z);
+
+//cerr << "col_X = " << col_X << endl;
+//cerr << "col_Y = " << col_Y << endl;
+//cerr << "col_Z = " << col_Z << endl;
+
+	// compute normal to image plane - cross product of row and column vectors ...
+
+	double normal_X = row_Y*col_Z - row_Z*col_Y;
+	double normal_Y = row_Z*col_X - row_X*col_Z;
+	double normal_Z = row_X*col_Y - row_Y*col_X;
+
+//cerr << "normal_X = " << normal_X << endl;
+//cerr << "normal_Y = " << normal_Y << endl;
+//cerr << "normal_Z = " << normal_Z << endl;
+
+	// length of normal is sqrt(dot product of normal with itself)
+	// should be 1 since both row and col vectors unit vectors
+	// but just in case ...
+
+	double normal_length=sqrt(normal_X*normal_X+normal_Y*normal_Y+normal_Z*normal_Z);
+
+//cerr << "normal_length = " << normal_length << endl;
+
+	Assert(normal_length != 0);
+
+	// if first time, set reference normal to current normal
+
+	if (first) {
+		reference_normal_X=normal_X;
+		reference_normal_Y=normal_Y;
+		reference_normal_Z=normal_Z;
+		reference_normal_length=normal_length;
+	}
+
+	// calculate angle in degrees between normal and reference normal
+	// by computing arccos of dot product of vectors divided by lengths ...
+
+	angle=acos(
+		 (normal_X*reference_normal_X+normal_Y*reference_normal_Y+normal_Z*reference_normal_Z)
+		/(normal_length*reference_normal_length)
+		 ) * (360.0 / (M_PI * 2.0));
+
+//cerr << "angle = " << angle << endl;
+
+	return angle;
+}
+
+// structure and sort compare to sort filenames by some numeric value
+
+struct sortentry {
+	double value;
+	const char *filename;
+};
+
+static int
+//sortentrycompareascending(const sortentry *i, const sortentry *j)
+//sortentrycompareascending(sortentry *i, sortentry *j)
+sortentrycompareascending(const void *ip, const void *jp)
+{
+	const sortentry *i=(const sortentry *)ip;
+	const sortentry *j=(const sortentry *)jp;
+	if (i->value > j->value)
+		return (1);
+	if (i->value < j->value)
+		return (-1);
+	return (0);
+}
+
+static int
+//sortentrycomparedescending(const sortentry *i, const sortentry *j)
+//sortentrycomparedescending(sortentry *i, sortentry *j)
+sortentrycomparedescending(const void *ip, const void *jp)
+{
+	const sortentry *i=(const sortentry *)ip;
+	const sortentry *j=(const sortentry *)jp;
+	if (i->value > j->value)
+		return (-1);
+	if (i->value < j->value)
+		return (1);
+	return (0);
+}
+
+static void
+dumpsortedfilenamestable(sortentry *table,int n,const char *name,ostream &log)
+{
+	int i;
+	for (i=0; i<n; ++i) {
+		log << name << "[" << i << "] = " << table[i].value << " in " << table[i].filename << endl;
+	}
+}
+
+static int
+doublecompareascending(const void *ip, const void *jp)
+{
+	const double *i=(const double *)ip;
+	const double *j=(const double *)jp;
+	if (*i > *j)
+		return (1);
+	if (*i < *j)
+		return (-1);
+	return (0);
+}
+
+static int
+doublecomparedescending(const void *ip, const void *jp)
+{
+	const double *i=(const double *)ip;
+	const double *j=(const double *)jp;
+	if (*i > *j)
+		return (-1);
+	if (*i < *j)
+		return (1);
+	return (0);
+}
+
+static void allocatePerFrameArrayAndCopySharedSingleStringValue(char *&shared,char **&perFrame,char *v,int numberofframes,int currentframe)
+{
+//cerr <<"allocatePerFrameArrayAndCopySharedSingleStringValue:" << endl;
+        perFrame = new char *[numberofframes];
+        Assert(perFrame);
+        int k;
+        for (k=0; k<currentframe; ++k) perFrame[k]=shared;
+        shared=0;
+        perFrame[currentframe]=v;
+}
+
+
+static void allocatePerFrameArrayAndCopySharedMultipleStringValues(int n,char **&shared,char ***&perFrame,char **v,int numberofframes,int currentframe)
+{
+        perFrame = new char **[numberofframes];
+        Assert(perFrame);
+        int k;
+        for (k=0; k<currentframe; ++k) {
+                perFrame[k]=shared;		// same value array is re-used multiple times
+        }
+        shared=NULL;
+        perFrame[currentframe]=v;		// supplied value array is used, not a copy
+}
+
+static void allocatePerFrameArrayAndCopySharedSingleUint32Value(Uint32 &shared,Uint32 *&perFrame,Uint32 v,int numberofframes,int currentframe)
+{
+        perFrame = new Uint32[numberofframes];
+        Assert(perFrame);
+        int k;
+        for (k=0; k<currentframe; ++k) perFrame[k]=shared;
+        shared=0;
+        perFrame[currentframe]=v;
+}
+
+
+static void allocatePerFrameArrayAndCopySharedMultipleUint32Values(int n,Uint32 *&shared,Uint32 **&perFrame,Uint32 *v,int numberofframes,int currentframe)
+{
+        perFrame = new Uint32 *[numberofframes];
+        Assert(perFrame);
+        int k;
+        for (k=0; k<currentframe; ++k) {
+                perFrame[k]=shared;		// same value array is re-used multiple times
+        }
+        shared=NULL;
+        perFrame[currentframe]=v;		// supplied value array is used, not a copy
+}
+
+static void allocatePerFrameArrayAndCopySharedSingleDoubleValue(double &shared,double *&perFrame,double v,int numberofframes,int currentframe)
+{
+        perFrame = new double[numberofframes];
+        Assert(perFrame);
+        int k;
+        for (k=0; k<currentframe; ++k) perFrame[k]=shared;
+        shared=0;
+        perFrame[currentframe]=v;
+}
+
+static void allocatePerFrameArrayAndCopySharedMultipleDoubleValues(int n,double *&shared,double **&perFrame,double *v,int numberofframes,int currentframe)
+{
+        perFrame = new double *[numberofframes];
+        Assert(perFrame);
+        int k;
+        for (k=0; k<currentframe; ++k) {
+                perFrame[k]=shared;		// same value array is re-used multiple times
+        }
+        shared=NULL;
+        perFrame[currentframe]=v;		// supplied value array is used, not a copy
+}
+
+static bool multipleStringValuesAreEqual(int n,char **a,char **b)
+{
+//cerr << "multipleStringValuesAreEqual: n = " << n << endl;
+	Assert(a);
+	Assert(b);
+        bool same = true;
+        int i;
+        for (i=0; i<n && same; ++i) {
+//cerr << "multipleStringValuesAreEqual: a[" << i << "] = <" << (a[i] ? a[i] : "null") << ">" << endl;
+//cerr << "multipleStringValuesAreEqual: b[" << i << "] = <" << (b[i] ? b[i] : "null") << ">" << endl;
+                if ((a[i] && !b[i]) || (!a[i] && b[i]) || (a[i] && b[i] && strcmp(a[i],b[i]) != 0)) same=false;
+                //if (strcmp(a[i],b[i]) != 0) same=false;
+//cerr << "multipleStringValuesAreEqual: same = " << (same ? "T" : "F") << endl;
+        }
+        return same;
+}
+
+static char **createMultipleStringValues(int n,char *fill=NULL)
+{
+//cerr << "createMultipleStringValues: n = " << n << endl;
+        char **v=new char *[n];
+        Assert(v);
+        int m;
+        for (m=0; m<n; ++m) v[m]=fill;
+        return v;
+}
+
+static char **getCopyOfMultipleStringValues(int nMax,int &nActual,Attribute *a)
+{
+//cerr << "getCopyOfMultipleStringValues: nMax = " << nMax << endl;
+        Assert(a);
+        char **v=createMultipleStringValues(nMax);
+        int vm=a->getVM();
+//cerr << "getCopyOfMultipleStringValues: vm = " << vm << endl;
+	nActual = vm > nMax ? nMax : vm;
+//cerr << "getCopyOfMultipleStringValues: nActual = " << nActual << endl;
+        int m;
+        for (m=0; m<nActual; ++m) a->getValue(m,v[m]);
+        for (m=nActual; m<nMax; ++m) v[m]="";		// fill missing values with zero length string rather than null; saves checks later
+        return v;
+}
+
+
+static bool multipleUint32ValuesAreEqual(int n,Uint32 *a,Uint32 *b)
+{
+        bool same = true;
+        int i;
+        for (i=0; i<n && same; ++i) {
+                if (a[i] != b[i]) same=false;
+        }
+        return same;
+}
+
+static Uint32 *createMultipleUint32Values(int n,Uint32 fill=0)
+{
+        Uint32 *v=new Uint32[n];
+        Assert(v);
+        int m;
+        for (m=0; m<n; ++m) v[m]=fill;
+        return v;
+}
+
+static Uint32 *getCopyOfMultipleUint32ValuesElseError(int n,Attribute *a,const char *label,const char *filename,TextOutputStream &log)
+{
+        Assert(a);
+        Uint32 *v=createMultipleUint32Values(n);
+        int vm=a->getVM();
+        if (vm < n) {
+                log << filename << ": " 
+                    << EMsgDC(BadValueMultiplicity) << ", expected " << n << " but got " << vm
+                    << " - " << label
+                    << endl;
+        }
+        int m;
+        for (m=0; m<vm; ++m) a->getValue(m,v[m]);
+       
+        return v;
+}
+
+static bool multipleDoubleValuesAreEqual(int n,double *a,double *b)
+{
+        bool same = true;
+        int i;
+        for (i=0; i<n && same; ++i) {
+                if (fabs(a[i]-b[i]) > .000001) same=false;
+        }
+        return same;
+}
+
+static double *createMultipleDoubleValues(int n,double fill=0)
+{
+        double *v=new double[n];
+        Assert(v);
+        int m;
+        for (m=0; m<n; ++m) v[m]=fill;
+        return v;
+}
+
+static double *getCopyOfMultipleDoubleValuesElseError(int n,Attribute *a,const char *label,const char *filename,TextOutputStream &log)
+{
+        Assert(a);
+        double *v=createMultipleDoubleValues(n);
+        int vm=a->getVM();
+        if (vm < n) {
+                log << filename << ": " 
+                    << EMsgDC(BadValueMultiplicity) << ", expected " << n << " but got " << vm
+                    << " - " << label
+                    << endl;
+        }
+        int m;
+        for (m=0; m<vm; ++m) a->getValue(m,v[m]);
+       
+        return v;
+}
+
+static void trackSingleValuedStringAttributePerFrame(AttributeList &list,Tag tag,const char *label,bool &encountered,char *&shared,char **&perFrame,int numberofframes,int currentframe,const char *filename,TextOutputStream &log)
+{
+//cerr << "trackSingleValuedStringAttributePerFrame: frame " << currentframe << " " << label << endl;
+        Attribute *a = list[tag];
+        if (a) {
+                char *v=AttributeValue(a);
+                if (encountered) {
+                        Assert(currentframe>0);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;
+                        }
+                        else {
+                                if ((shared && !v) || (!shared && v) || (shared && v && strcmp(shared,v) != 0)) {
+                                        allocatePerFrameArrayAndCopySharedSingleStringValue(shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                else {
+                        encountered=true;
+                        if (currentframe == 0) {
+                                shared=v;
+                        }
+                        else {
+                                log << filename << ": " 
+                                        << EMsgDC(MissingAttribute) << " in prior frames"
+                                        << " - " << label
+                                        << endl;
+                                Assert(perFrame == NULL);
+                                shared=NULL;
+                                allocatePerFrameArrayAndCopySharedSingleStringValue(shared,perFrame,v,numberofframes,currentframe);
+                        }
+                }
+        }
+        else {	// a == null
+                if (encountered) {
+                        log << filename << ": " 
+                                << EMsgDC(MissingAttribute) << " in current frame"
+                                << " - " << label
+                                << endl;
+                        char *v=NULL;		// best we can do
+                        if (perFrame) {
+                                perFrame[currentframe]=v;
+                        }
+                        else {
+                                if ((shared && !v) || (!shared && v) || (shared && v && strcmp(shared,v) != 0)) {
+                                        allocatePerFrameArrayAndCopySharedSingleStringValue(shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                // else do nothing ... not here now and haven't seen it yet
+        }
+}
+
+
+static void trackMultiValuedStringAttributePerFrame(AttributeList &list,Tag tag,const char *label,int nMax,int &nActual,bool &encountered,char **&shared,char ***&perFrame,int numberofframes,int currentframe,const char *filename,TextOutputStream &log)
+{
+//cerr << "trackMultiValuedStringAttributePerFrame: frame " << currentframe << " " << label << endl;
+        Attribute *a = list[tag];
+        if (a) {
+		int previousNActual=nActual;
+                char **v=getCopyOfMultipleStringValues(nMax,nActual,a);
+                if (encountered) {
+                        Assert(currentframe>0);
+			//Assert(previousNActual == nActual);	// must be the same number of values for every frame 
+			if (previousNActual > nActual) {
+				nActual=previousNActual;	// hmm :(
+			} 
+                        if (perFrame) {
+                                perFrame[currentframe]=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                if (!multipleStringValuesAreEqual(nMax,shared,v)) {
+                                        allocatePerFrameArrayAndCopySharedMultipleStringValues(nMax,shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                else {
+                        encountered=true;
+                        if (currentframe == 0) {
+                                shared=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                log << filename << ": " 
+                                        << EMsgDC(MissingAttribute) << " in prior frames"
+                                        << " - " << label
+                                        << endl;
+                                Assert(perFrame == NULL);
+                                shared=createMultipleStringValues(nMax);
+                                allocatePerFrameArrayAndCopySharedMultipleStringValues(nMax,shared,perFrame,v,numberofframes,currentframe);
+                        }
+                }
+        }
+        else {	// a == null
+                if (encountered) {
+                        log << filename << ": " 
+                                << EMsgDC(MissingAttribute) << " in current frame"
+                                << " - " << label
+                                << endl;
+                        char **v=createMultipleStringValues(nMax);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                if (!multipleStringValuesAreEqual(nMax,shared,v)) {
+                                        allocatePerFrameArrayAndCopySharedMultipleStringValues(nMax,shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                // else do nothing ... not here now and haven't seen it yet
+        }
+}
+
+static void trackSingleValuedUint32AttributePerFrame(AttributeList &list,Tag tag,const char *label,bool &encountered,Uint32 &shared,Uint32 *&perFrame,int numberofframes,int currentframe,const char *filename,TextOutputStream &log)
+{
+//cerr << "trackSingleValuedIntegerAttributePerFrame: frame " << currentframe << " " << label << endl;
+        Attribute *a = list[tag];
+        if (a) {
+                Uint32 v=AttributeValue(a);
+                if (encountered) {
+                        Assert(currentframe>0);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;
+                        }
+                        else {
+                                if (shared != v) {
+                                        allocatePerFrameArrayAndCopySharedSingleUint32Value(shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                else {
+                        encountered=true;
+                        if (currentframe == 0) {
+                                shared=v;
+                        }
+                        else {
+                                log << filename << ": " 
+                                        << EMsgDC(MissingAttribute) << " in prior frames"
+                                        << " - " << label
+                                        << endl;
+                                Assert(perFrame == NULL);
+                                shared=0;
+                                allocatePerFrameArrayAndCopySharedSingleUint32Value(shared,perFrame,v,numberofframes,currentframe);
+                        }
+                }
+        }
+        else {	// a == null
+                if (encountered) {
+                        log << filename << ": " 
+                                << EMsgDC(MissingAttribute) << " in current frame"
+                                << " - " << label
+                                << endl;
+                        Uint32 v=0;		// best we can do
+                        if (perFrame) {
+                                perFrame[currentframe]=v;
+                        }
+                        else {
+                                if (shared != v) {
+                                        allocatePerFrameArrayAndCopySharedSingleUint32Value(shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                // else do nothing ... not here now and haven't seen it yet
+        }
+}
+
+static void trackMultiValuedUint32AttributePerFrame(AttributeList &list,Tag tag,const char *label,int n,bool &encountered,Uint32 *&shared,Uint32 **&perFrame,int numberofframes,int currentframe,const char *filename,TextOutputStream &log)
+{
+//cerr << "trackMultiValuedUint32AttributePerFrame: frame " << currentframe << " " << label << endl;
+        Attribute *a = list[tag];
+        if (a) {
+                Uint32 *v=getCopyOfMultipleUint32ValuesElseError(n,a,label,filename,log);
+                if (encountered) {
+                        Assert(currentframe>0);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                if (!multipleUint32ValuesAreEqual(n,shared,v)) {
+                                        allocatePerFrameArrayAndCopySharedMultipleUint32Values(n,shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                else {
+                        encountered=true;
+                        if (currentframe == 0) {
+                                shared=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                log << filename << ": " 
+                                        << EMsgDC(MissingAttribute) << " in prior frames"
+                                        << " - " << label
+                                        << endl;
+                                Assert(perFrame == NULL);
+                                shared=createMultipleUint32Values(n);
+                                allocatePerFrameArrayAndCopySharedMultipleUint32Values(n,shared,perFrame,v,numberofframes,currentframe);
+                        }
+                }
+        }
+        else {	// a == null
+                if (encountered) {
+                        log << filename << ": " 
+                                << EMsgDC(MissingAttribute) << " in current frame"
+                                << " - " << label
+                                << endl;
+                        Uint32 *v=createMultipleUint32Values(n);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                if (!multipleUint32ValuesAreEqual(n,shared,v)) {
+                                        allocatePerFrameArrayAndCopySharedMultipleUint32Values(n,shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                // else do nothing ... not here now and haven't seen it yet
+        }
+}
+
+static void trackSingleValuedDoubleAttributePerFrame(AttributeList &list,Tag tag,const char *label,bool &encountered,double &shared,double *&perFrame,int numberofframes,int currentframe,const char *filename,TextOutputStream &log)
+{
+//cerr << "trackSingleValuedDoubleAttributePerFrame: frame " << currentframe << " " << label << endl;
+        Attribute *a = list[tag];
+        if (a) {
+                double v=AttributeValue(a);
+                if (encountered) {
+                        Assert(currentframe>0);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;
+                        }
+                        else {
+                                if (shared != v) {
+                                        allocatePerFrameArrayAndCopySharedSingleDoubleValue(shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                else {
+                        encountered=true;
+                        if (currentframe == 0) {
+                                shared=v;
+                        }
+                        else {
+                                log << filename << ": " 
+                                        << EMsgDC(MissingAttribute) << " in prior frames"
+                                        << " - " << label
+                                        << endl;
+                                Assert(perFrame == NULL);
+                                shared=0;
+                                allocatePerFrameArrayAndCopySharedSingleDoubleValue(shared,perFrame,v,numberofframes,currentframe);
+                        }
+                }
+        }
+        else {	// a == null
+                if (encountered) {
+                        log << filename << ": " 
+                                << EMsgDC(MissingAttribute) << " in current frame"
+                                << " - " << label
+                                << endl;
+                        double v=0;		// best we can do
+                        if (perFrame) {
+                                perFrame[currentframe]=v;
+                        }
+                        else {
+                                if (shared != v) {
+                                        allocatePerFrameArrayAndCopySharedSingleDoubleValue(shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                // else do nothing ... not here now and haven't seen it yet
+        }
+}
+
+static void trackMultiValuedDoubleAttributePerFrame(AttributeList &list,Tag tag,const char *label,int n,bool &encountered,double *&shared,double **&perFrame,int numberofframes,int currentframe,const char *filename,TextOutputStream &log)
+{
+//cerr << "trackMultiValuedDoubleAttributePerFrame: frame " << currentframe << " " << label << endl;
+        Attribute *a = list[tag];
+        if (a) {
+                double *v=getCopyOfMultipleDoubleValuesElseError(n,a,label,filename,log);
+                if (encountered) {
+                        Assert(currentframe>0);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                if (!multipleDoubleValuesAreEqual(n,shared,v)) {
+                                        allocatePerFrameArrayAndCopySharedMultipleDoubleValues(n,shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                else {
+                        encountered=true;
+                        if (currentframe == 0) {
+                                shared=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                log << filename << ": " 
+                                        << EMsgDC(MissingAttribute) << " in prior frames"
+                                        << " - " << label
+                                        << endl;
+                                Assert(perFrame == NULL);
+                                shared=createMultipleDoubleValues(n);
+                                allocatePerFrameArrayAndCopySharedMultipleDoubleValues(n,shared,perFrame,v,numberofframes,currentframe);
+                        }
+                }
+        }
+        else {	// a == null
+                if (encountered) {
+                        log << filename << ": " 
+                                << EMsgDC(MissingAttribute) << " in current frame"
+                                << " - " << label
+                                << endl;
+                        double *v=createMultipleDoubleValues(n);
+                        if (perFrame) {
+                                perFrame[currentframe]=v;	// NB. does not create a new copy
+                        }
+                        else {
+                                if (!multipleDoubleValuesAreEqual(n,shared,v)) {
+                                        allocatePerFrameArrayAndCopySharedMultipleDoubleValues(n,shared,perFrame,v,numberofframes,currentframe);
+                                }
+                                // else same as existing shared ... done
+                        }
+                }
+                // else do nothing ... not here now and haven't seen it yet
+        }
+}
+
+static bool findInStringRegardlessOfCase(const char *big, const char *little) {
+	if (!big || !*big || !little || !*little) return false;
+	int nb = strlen(big);
+	int nl = strlen(little);
+	if (nl > nb) return false;			// big string has to be bigger
+	const char *btry = big;
+	const char *blast = btry + (nb-nl+1);
+	while (btry<blast) {
+		const char *lp=little;
+		const char *bp=btry;
+		while (toupper(*lp) == toupper(*bp)) {
+			if (!*++lp) return true;	// success when got to end of (null-terminated) little string
+			++bp;
+		}
+		++btry;
+	}
+	return false;
+}
+
+static const char *returnDifferentValueOnlyIfActuallyDifferent(char ***perFrame_ImageType,int nFrames,int whichValue,const char *defaultValue,const char *differentValue) {
+	const char *imageType=defaultValue;
+	if (perFrame_ImageType && nFrames && perFrame_ImageType[0] && perFrame_ImageType[0][whichValue]) {
+		imageType = perFrame_ImageType[0][whichValue];
+		int i;
+		for (i=1; i < nFrames; ++i) {
+			if (!perFrame_ImageType[i] || !perFrame_ImageType[i][whichValue] || strcmp(imageType,perFrame_ImageType[i][whichValue]) != 0) {
+				imageType=differentValue;
+				break;
+			}
+		}
+	}
+	return imageType;
+}
+
+static int countDifferentSingleValuedUint32Values(bool encountered,Uint32 shared,Uint32 *perFrame,int n) {
+//cerr << "countDifferentSingleValuedUint32Values:" << endl;
+	int count=0;
+	if (encountered) {
+		if (perFrame) {
+			Uint32 *observed = new Uint32[n];
+			{ int j; for (j=0; j<n; ++j) observed[j]=Uint32(-1); }	// unlikely value
+			int i;
+			for (i=0; i<n; ++i) {
+				Uint32 v = perFrame[i];
+//cerr << "countDifferentSingleValuedUint32Values: [" << dec << i << "] = " << v << endl;
+				int j;
+				bool found=false;
+				for (j=0; j<count && !found; ++j) if (observed[j] == v) found=true;
+				if (!found) {
+//cerr << "countDifferentSingleValuedUint32Values: not found, adding" << endl;
+					observed[count] = v;
+					++count;
+				}
+			}
+		}
+		else {
+			count=1;
+		}
+	}
+//cerr << "countDifferentSingleValuedUint32Values: count = " << dec << count << endl;
+	return count;
+}
+					
+static const char *reMapOldMRToNewMRImageTypeValue3(const char *o) {
+	const char *n;
+	if      (strcmp(o,"VELOCITY MAP") == 0) n="VELOCITY";
+	else if (strcmp(o,"T1 MAP") == 0) n="T1";
+	else if (strcmp(o,"T2 MAP") == 0) n="T2";
+	else if (strcmp(o,"DIFFUSION MAP") == 0) n="DIFFUSION";
+	else n=o;
+	return n;
+}
+
+static const char *extractNewMRImageTypeValue4FromOldValueType3(const char *o) {
+	const char *n;
+	if      (strcmp(o,"VELOCITY MAP") == 0) n="VELOCITY";
+	else if (strcmp(o,"T1 MAP") == 0) n="T1_MAP";
+	else if (strcmp(o,"T2 MAP") == 0) n="T2_MAP";
+	else if (strcmp(o,"DIFFUSION MAP") == 0) n="DIFFUSION";
+	else if (strcmp(o,"DENSITY MAP") == 0) n="RHO";
+	else if (strcmp(o,"PHASE SUBTRACT") == 0) n="SUBTRACTION";
+	else if (strcmp(o,"MODULUS SUBTRACT") == 0) n="SUBTRACTION";
+	else if (strcmp(o,"IMAGE ADDITION") == 0) n="ADDITION";
+	//else n=o;
+	else n="NONE";
+	return n;
+}
+
+// The following builds both the CommonCTMRImageDescriptionMacro and the MRImageDescriptionMacro (if MR) ...
+
+static bool makeCTMRImageDescriptionMacroAttributesAndAppendToList(bool isMR,AttributeList &list,bool frameLevel,int frame,int nFrames,
+		bool encountered_ImageType,char **shared_ImageType,char ***perFrame_ImageType,int nValues_ImageType,
+		bool encountered_PixelPresentation,char *shared_PixelPresentation,char **perFrame_PixelPresentation,
+		bool encountered_VolumetricProperties,char *shared_VolumetricProperties,char **perFrame_VolumetricProperties,
+		bool encountered_VolumeBasedCalculationTechnique,char *shared_VolumeBasedCalculationTechnique,char **perFrame_VolumeBasedCalculationTechnique,
+		bool encountered_ComplexImageComponent,char *shared_ComplexImageComponent,char **perFrame_ComplexImageComponent,
+		bool encountered_AcquisitionContrast,char *shared_AcquisitionContrast,char **perFrame_AcquisitionContrast,
+		TextOutputStream &log) {
+//cerr << "makeCTMRImageDescriptionMacroAttributesAndAppendToList: start frameLevel=" << frameLevel << endl;		
+//cerr << "encountered_ImageType = " << encountered_ImageType << endl;
+//cerr << "nValues_ImageType = " << nValues_ImageType << endl;
+//cerr << "shared_ImageType [0] = " << (shared_ImageType ? shared_ImageType [0] : "null") << endl;
+//cerr << "perFrame_ImageType [frame][0] = " << (perFrame_ImageType ? (frameLevel ? (perFrame_ImageType[frame] ? perFrame_ImageType[frame][0] : "[frame][0] null") : "not frame so no index") : "all null") << endl;
+//cerr << "shared_ImageType [1] = " << (shared_ImageType ? shared_ImageType [1] : "null") << endl;
+//cerr << "perFrame_ImageType [frame][1] = " << (perFrame_ImageType ? (frameLevel ? (perFrame_ImageType[frame] ? perFrame_ImageType[frame][1] : "[frame][1] null") : "not frame so no index") : "all null") << endl;
+//cerr << "shared_ImageType [2] = " << (shared_ImageType ? shared_ImageType [2] : "null") << endl;
+//cerr << "perFrame_ImageType [frame][2] = " << (perFrame_ImageType ? (frameLevel ? (perFrame_ImageType[frame] ? perFrame_ImageType[frame][2] : "[frame][2] null") : "not frame so no index") : "all null") << endl;
+//cerr << "shared_ImageType [3] = " << (shared_ImageType ? shared_ImageType [3] : "null") << endl;
+//cerr << "perFrame_ImageType [frame][3] = " << (perFrame_ImageType ? (frameLevel ? (perFrame_ImageType[frame] ? perFrame_ImageType[frame][3] : "[frame][3] null") : "not frame so no index") : "all null") << endl;
+
+	bool isDerived=false;
+	
+	if (frameLevel) {
+		Attribute *aFrameType = new CodeStringAttribute(TagFromName(FrameType));
+		Assert(aFrameType);
+		list+=aFrameType;
+		
+		const char *value1 = encountered_ImageType && nValues_ImageType > 0
+			? (perFrame_ImageType && perFrame_ImageType[frame] ? perFrame_ImageType[frame][0] : (shared_ImageType ? shared_ImageType [0] : "ORIGINAL")) : "ORIGINAL";
+		const char *value3 = encountered_ImageType && nValues_ImageType > 2
+			? (perFrame_ImageType && perFrame_ImageType[frame] ? perFrame_ImageType[frame][2] : (shared_ImageType ? shared_ImageType [2] : "")) : "";
+		const char *value4 = strcmp(value1,"ORIGINAL") == 0 ? "NONE" : (
+			encountered_ImageType && nValues_ImageType > 3
+			? (perFrame_ImageType && perFrame_ImageType[frame] ? perFrame_ImageType[frame][3] : (shared_ImageType ? shared_ImageType [3] : 0)) : 0);
+
+ 		if (!value4) {
+ 			if (isMR) {
+ 				value4=extractNewMRImageTypeValue4FromOldValueType3(value3);
+ 			}
+ 			else {
+ 				value4="";	// must not be left as null, else addValue() below fails (000414), and we always want a fourth value for enhanced objects (? :()
+ 			}
+ 		}
+		
+		if (isMR) value3 = reMapOldMRToNewMRImageTypeValue3(value3);
+
+//cerr << "value1 = " << value1 << endl;
+//cerr << "value3 = " << value3 << endl;
+//cerr << "value4 = " << value4 << endl;
+
+		aFrameType->addValue(value1);
+		aFrameType->addValue("PRIMARY");
+		aFrameType->addValue(value3);
+		aFrameType->addValue(value4);
+		
+		if (value1 && strcmp(value1,"DERIVED") == 0) isDerived=true;
+	}
+	else {
+		list-=TagFromName(ImageType);
+		Attribute *aImageType = new CodeStringAttribute(TagFromName(ImageType));
+		Assert(aImageType);
+		list+=aImageType;
+		
+		// Should probably actually trawl through all perFrame_ImageType value 0 to see if same, because could be a different value that is different
+		const char *value1 = encountered_ImageType && nValues_ImageType > 0
+			? (perFrame_ImageType ? returnDifferentValueOnlyIfActuallyDifferent(perFrame_ImageType,nFrames,0,"ORIGINAL","MIXED")
+			: (shared_ImageType ? shared_ImageType [0] : "ORIGINAL")) : "ORIGINAL";
+		// not allowed to be Type 2 at image level, OTHER is not a standard  defined term but nothing else is suitable ...
+		const char *value3 = encountered_ImageType && nValues_ImageType > 2
+			? (perFrame_ImageType
+				? returnDifferentValueOnlyIfActuallyDifferent(perFrame_ImageType,nFrames,2,"OTHER","OTHER")
+				: (shared_ImageType ? shared_ImageType [2] : "OTHER"))
+			: "OTHER";
+		const char *value4 = strcmp(value1,"ORIGINAL") == 0 ? "NONE" : (
+			encountered_ImageType && nValues_ImageType > 3
+			? (perFrame_ImageType
+				? returnDifferentValueOnlyIfActuallyDifferent(perFrame_ImageType,nFrames,3,0,"MIXED")
+				: (shared_ImageType ? shared_ImageType [3] : 0))
+			: 0
+			);
+ 		if (!value4) {
+ 			if (isMR) {
+ 				value4=extractNewMRImageTypeValue4FromOldValueType3(value3);
+ 			}
+ 			else {
+ 				value4="";	// must not be left as null, else addValue() below fails (000414), and we always want a fourth value for enhanced objects (? :()
+ 			}
+ 		}
+		
+		if (isMR) value3 = reMapOldMRToNewMRImageTypeValue3(value3);
+
+		aImageType->addValue(value1);
+		aImageType->addValue("PRIMARY");
+		aImageType->addValue(value3);
+		aImageType->addValue(value4);
+		
+		if (value1 && strcmp(value1,"DERIVED") == 0) isDerived=true;
+	}
+	
+	list+=new CodeStringAttribute(TagFromName(PixelPresentation),
+		encountered_PixelPresentation ?
+			(perFrame_PixelPresentation ? (frameLevel ? (perFrame_PixelPresentation[frame] ? perFrame_PixelPresentation[frame] : "MONOCHROME") : "MIXED")
+			: shared_PixelPresentation) : "MONOCHROME");
+	list+=new CodeStringAttribute(TagFromName(VolumetricProperties),encountered_VolumetricProperties ? (perFrame_VolumetricProperties ?
+			(frameLevel ? (perFrame_VolumetricProperties[frame] ? perFrame_VolumetricProperties[frame] : "VOLUME") : "MIXED")
+			: shared_VolumetricProperties) : "VOLUME");
+	list+=new CodeStringAttribute(TagFromName(VolumeBasedCalculationTechnique),
+		encountered_VolumeBasedCalculationTechnique ? (perFrame_VolumeBasedCalculationTechnique ?
+			(frameLevel ? (perFrame_VolumeBasedCalculationTechnique[frame] ? perFrame_VolumeBasedCalculationTechnique[frame] : "NONE") : "MIXED")
+			: shared_VolumeBasedCalculationTechnique) : "NONE");
+	if (isMR) {
+		// do the MR Image Description Macro stuff as well ...
+		list+=new CodeStringAttribute(TagFromName(ComplexImageComponent),
+			encountered_ComplexImageComponent ? (perFrame_ComplexImageComponent ?
+				(frameLevel ? (perFrame_ComplexImageComponent[frame] ? perFrame_ComplexImageComponent[frame] : "MAGNITUDE") : "MIXED")
+				: shared_ComplexImageComponent) : "MAGNITUDE");
+		list+=new CodeStringAttribute(TagFromName(AcquisitionContrast),
+			encountered_AcquisitionContrast ? (perFrame_AcquisitionContrast ?
+				(frameLevel ? (perFrame_AcquisitionContrast[frame] ? perFrame_AcquisitionContrast[frame] : "UNKNOWN") : "MIXED")
+				: shared_AcquisitionContrast) : "UNKNOWN");
+	}
+//cerr << "makeCTMRImageDescriptionMacroAttributesAndAppendToList: done isDerived = " << (isDerived ? "T" : "F") << endl;
+	return isDerived;
+}
+
+struct dateTimeSortEntry {
+	long du;
+	long tu;
+	char *ds;
+	char *ts;
+};
+
+static int
+dateTimeCompare(const void *ip, const void *jp)
+{
+//cerr << "dateTimeCompare: " << dec << ((struct dateTimeSortEntry *)ip)->ds << ((struct dateTimeSortEntry *)ip)->ts
+//			    << " " << ((struct dateTimeSortEntry *)jp)->ds << ((struct dateTimeSortEntry *)jp)->ts << endl;
+//cerr << "dateTimeCompare: " << dec << ((struct dateTimeSortEntry *)ip)->du << ((struct dateTimeSortEntry *)ip)->tu
+//			    << " " << ((struct dateTimeSortEntry *)jp)->du << ((struct dateTimeSortEntry *)jp)->tu << endl;
+	long rv;
+	long d = ((struct dateTimeSortEntry *)ip)->du - ((struct dateTimeSortEntry *)jp)->du;
+	if (d == 0) {
+//cerr << "dateTimeCompare: same date, compare times" << endl;
+		rv=((struct dateTimeSortEntry *)ip)->tu - ((struct dateTimeSortEntry *)jp)->tu;
+	}
+	else {
+		rv=d;
+	}
+//cerr << "dateTimeCompare: rv = " << dec << rv << endl;
+	// Need to be careful of limited precision of int vs. long and sign extension, hence this cautious approach ...
+	int irv = rv < 0 ? -1 : (rv > 0 ? 1 : 0);
+//cerr << "dateTimeCompare: irv = " << dec << irv << endl;
+	return irv;
+}
+
+static void addEarliestContentDateAndTime(AttributeList &list,int numberofinputfiles,
+	bool encountered_ContentDate,char *shared_ContentDate,char **perFrame_ContentDate,
+	bool encountered_ContentTime,char *shared_ContentTime,char **perFrame_ContentTime,
+	TextOutputStream &log) {
+//cerr << "addEarliestContentDateAndTime: start" << endl;
+	
+	char *badDate = "29990101";
+	char *badTime = "000000";
+	
+	char *useDate = NULL;
+	char *useTime = NULL;
+	
+	if (encountered_ContentDate && !perFrame_ContentDate) {
+		useDate = shared_ContentDate;					// all the same date
+		if (encountered_ContentTime && !perFrame_ContentTime) {
+			useTime = shared_ContentTime;				// all the same time on the same date
+		}
+	}
+	
+	struct dateTimeSortEntry *perFrame_ContentDateTime = NULL;
+	if (!useDate || !useTime) {
+		// Scan for the earliest data and time
+		perFrame_ContentDateTime = new dateTimeSortEntry[numberofinputfiles];
+		Assert(perFrame_ContentDateTime);
+		int i;
+		for (i=0; i<numberofinputfiles; ++i) {
+			char *ds=encountered_ContentDate ? (perFrame_ContentDate ? perFrame_ContentDate[i] : shared_ContentDate) : (char *)NULL;
+			char *ts=encountered_ContentTime ? (perFrame_ContentTime ? perFrame_ContentTime[i] : shared_ContentTime) : (char *)NULL;
+			if (!ds || !strlen(ds)) ds=badDate;	// deliberately large so will be the last value chosen
+			if (!ts || !strlen(ts)) ts=badTime;
+//cerr << "addEarliestContentDateAndTime: ds = " << ds << " and ts = " << ts << endl;
+			perFrame_ContentDateTime[i].ds=ds;
+			perFrame_ContentDateTime[i].ts=ts;			
+			perFrame_ContentDateTime[i].du = Date(ds,DateOrderMonthMiddleYearFirst);
+			perFrame_ContentDateTime[i].tu = Time(ts);
+//cerr << "addEarliestContentDateAndTime: perFrame_ContentDateTime[" << i << "].du and tu = " << perFrame_ContentDateTime[i].du << " " << perFrame_ContentDateTime[i].tu << endl;
+		}
+		qsort((void *)perFrame_ContentDateTime,numberofinputfiles,sizeof(dateTimeSortEntry),dateTimeCompare);
+		useDate=perFrame_ContentDateTime[0].ds;
+		useTime=perFrame_ContentDateTime[0].ts;
+//cerr << "addEarliestContentDateAndTime: after sort using " << dec << useDate << useTime << endl;
+	}
+	if (useDate && strcmp(useDate,badDate) != 0) {
+		list+=new DateStringAttribute(TagFromName(ContentDate),useDate ? useDate : badDate);	// don't add date unless it was good
+	}
+	if (useTime && (!useDate || strcmp(useDate,badDate) != 0)) {
+		list+=new TimeStringAttribute(TagFromName(ContentTime),getStringFromTime(Time(useTime ? useTime : badTime)));	// don't add time unless it was good, but add it even if date absent or bad
+	}
+	if (perFrame_ContentDateTime) delete[] perFrame_ContentDateTime;
+//cerr << "addEarliestContentDateAndTime: done" << endl;
+}
+					
+static void addEarliestAcquisitionDateAndTime(AttributeList &list,int numberofinputfiles,
+	bool encountered_AcquisitionDate,char *shared_AcquisitionDate,char **perFrame_AcquisitionDate,
+	bool encountered_AcquisitionTime,char *shared_AcquisitionTime,char **perFrame_AcquisitionTime,
+	TextOutputStream &log) {
+//cerr << "addEarliestAcquisitionDateAndTime: start" << endl;
+	char *badDate = "29990101";
+	char *badTime = "000000";
+
+	char *useDate = NULL;
+	char *useTime = NULL;
+	
+	if (encountered_AcquisitionDate && !perFrame_AcquisitionDate) {
+		useDate = shared_AcquisitionDate;					// all the same date
+		if (encountered_AcquisitionTime && !perFrame_AcquisitionTime) {
+			useTime = shared_AcquisitionTime;				// all the same time on the same date
+//cerr << "addEarliestAcquisitionDateAndTime: all the same time on the same date using " << dec << useDate << useTime << endl;
+		}
+	}
+	
+	struct dateTimeSortEntry *perFrame_AcquisitionDateTime = NULL;
+	if (!useDate || !useTime) {
+		// Scan for the earliest data and time
+		perFrame_AcquisitionDateTime = new dateTimeSortEntry[numberofinputfiles];
+		Assert(perFrame_AcquisitionDateTime);
+		int i;
+		for (i=0; i<numberofinputfiles; ++i) {
+			char *ds=encountered_AcquisitionDate ? (perFrame_AcquisitionDate ? perFrame_AcquisitionDate[i] : shared_AcquisitionDate) : (char *)NULL;
+			char *ts=encountered_AcquisitionTime ? (perFrame_AcquisitionTime ? perFrame_AcquisitionTime[i] : shared_AcquisitionTime) : (char *)NULL;
+			if (!ds || !strlen(ds)) ds=badDate;	// deliberately large so will be the last value chosen
+			if (!ts || !strlen(ts)) ts=badTime;
+//cerr << "addEarliestAcquisitionDateAndTime: ds = " << ds << " and ts = " << ts << endl;
+			perFrame_AcquisitionDateTime[i].ds=ds;
+			perFrame_AcquisitionDateTime[i].ts=ts;			
+			perFrame_AcquisitionDateTime[i].du = Date(ds,DateOrderMonthMiddleYearFirst);
+			perFrame_AcquisitionDateTime[i].tu = Time(ts);
+//cerr << "addEarliestAcquisitionDateAndTime: perFrame_AcquisitionDateTime[" << i << "].du and tu = " << perFrame_AcquisitionDateTime[i].du << " " << perFrame_AcquisitionDateTime[i].tu << endl;
+		}
+		qsort((void *)perFrame_AcquisitionDateTime,numberofinputfiles,sizeof(dateTimeSortEntry),dateTimeCompare);
+		useDate=perFrame_AcquisitionDateTime[0].ds;
+		useTime=perFrame_AcquisitionDateTime[0].ts;
+//cerr << "addEarliestAcquisitionDateAndTime: after sort using " << dec << useDate << useTime << endl;
+	}
+	
+	list+=new DateTimeStringAttribute(TagFromName(AcquisitionDateTime),makeDateTimeString(useDate ? useDate : badDate,getStringFromTime(Time(useTime ? useTime : badTime))));
+	
+	// use Acquisition values instead of Content values if the latter are absent ...
+	// (assumes addEarliestContentDateAndTime() has already been executed)
+	
+	if (!list[TagFromName(ContentDate)]) list+=new DateStringAttribute(TagFromName(ContentDate),useDate ? useDate : badDate);
+	if (!list[TagFromName(ContentTime)]) list+=new TimeStringAttribute(TagFromName(ContentTime),getStringFromTime(Time(useTime ? useTime : badTime)));
+	
+	if (perFrame_AcquisitionDateTime) delete[] perFrame_AcquisitionDateTime;
+//cerr << "addEarliestAcquisitionDateAndTime: done" << endl;
+}
+
+static void copyImagedNucleusIntoResonantNucleusIfNotAlreadyPresent(AttributeList &dst,AttributeList &src) {
+//cerr << "copyImagedNucleusIntoResonantNucleusIfNotAlreadyPresent: start" << endl;
+	const char *vImagedNucleus = AttributeValue(src[TagFromName(ImagedNucleus)]);
+	if (vImagedNucleus) {
+		if      (strcmp(vImagedNucleus,"H")      == 0) vImagedNucleus="1H";
+		else if (strcmp(vImagedNucleus,"H1")     == 0) vImagedNucleus="1H";
+		else if (strcmp(vImagedNucleus,"HE3")    == 0) vImagedNucleus="3HE";
+		else if (strcmp(vImagedNucleus,"LI7")    == 0) vImagedNucleus="17L";
+		else if (strcmp(vImagedNucleus,"C13")    == 0) vImagedNucleus="13C";
+		else if (strcmp(vImagedNucleus,"F19")    == 0) vImagedNucleus="19F";
+		else if (strcmp(vImagedNucleus,"NA23")   == 0) vImagedNucleus="23NA";
+		else if (strcmp(vImagedNucleus,"P31")    == 0) vImagedNucleus="31P";
+		else if (strcmp(vImagedNucleus,"XE129")  == 0) vImagedNucleus="129XE";
+		// else leave it alone, probably in correct form, if not then OK as non-standard defined term
+		// (could consider converting to upper case) :(
+	}
+	else {
+		vImagedNucleus="1H";
+	}
+	dst+=new CodeStringAttribute(TagFromName(ResonantNucleus),vImagedNucleus);
+//cerr << "copyImagedNucleusIntoResonantNucleusIfNotAlreadyPresent: done" << endl;
+}
+
+static void copyAttributeIntoNewAttributeIfNotAlreadyPresent(Tag dstTag,Tag srcTag,AttributeList &dst,AttributeList &src) {
+	// assumes VRs the same
+	if (!dst[dstTag]) {
+		Attribute *a = src[srcTag];
+		if (a) {
+			src-=srcTag;
+			a->setTag(dstTag);
+			dst+=a;
+		}
+	}
+}
+
+static void copyAttributeIfNotAlreadyPresent(Tag tag,AttributeList &dst,AttributeList &src) {
+	if (!dst[tag]) {
+		Attribute *a = src[tag];
+		if (a) {
+			src-=tag;
+			dst+=a;
+		}
+	}
+}
+
+static void copyPatientModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientBirthDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientSex),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ReferencedPatientSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientBirthTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(OtherPatientIDs),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(OtherPatientNames),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(EthnicGroup),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientComments),dst,src);
+}
+
+static void copyGeneralStudyModule(AttributeList &dst,AttributeList &src){
+	copyAttributeIfNotAlreadyPresent(TagFromName(StudyInstanceUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StudyDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StudyTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ReferringPhysicianName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StudyID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AccessionNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StudyDescription),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PhysiciansOfRecord),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(NameOfPhysiciansReadingStudy),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ReferencedStudySequence),dst,src);
+}
+
+static void copyPatientStudyModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(AdmittingDiagnosesDescription),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AdmittingDiagnosesCodeSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientAge),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientSize),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientWeight),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(Occupation),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AdditionalPatientHistory),dst,src);
+}
+
+static void copyGeneralSeriesModule(AttributeList &dst,AttributeList &src,bool addMultiFrameCTOrMRStuff) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(Modality),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SeriesInstanceUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SeriesNumber),dst,src);
+	if (!addMultiFrameCTOrMRStuff) copyAttributeIfNotAlreadyPresent(TagFromName(Laterality),dst,src);	// No longer used in MR as of CP 365
+	copyAttributeIfNotAlreadyPresent(TagFromName(SeriesDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SeriesTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PerformingPhysicianName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ProtocolName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SeriesDescription),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(OperatorsName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ReferencedPerformedProcedureStepSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(BodyPartExamined),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientPosition),dst,src);
+	//copyAttributeIfNotAlreadyPresent(TagFromName(SmallestPixelValueInSeries),dst,src);	// probably invalidated even if present
+	//copyAttributeIfNotAlreadyPresent(TagFromName(LargestPixelValueInSeries),dst,src);	// probably invalidated even if present
+	copyAttributeIfNotAlreadyPresent(TagFromName(RequestAttributesSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PerformedProcedureStepID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PerformedProcedureStepStartDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PerformedProcedureStepStartTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PerformedProcedureStepDescription),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PerformedProtocolCodeSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(CommentsOnThePerformedProcedureStep),dst,src);
+}
+
+static void copyFrameOfReferenceModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameOfReferenceUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PositionReferenceIndicator),dst,src);
+}
+
+static void copySynchronizationFrameOfReferenceModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(SynchronizationFrameOfReferenceUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SynchronizationTrigger),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(TriggerSourceOrType),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SynchronizationChannel),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionTimeSynchronized),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(TimeSource),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(TimeDistributionProtocol),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(NTPSourceAddress),dst,src);
+}
+
+static void copyGeneralEquipmentModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(Manufacturer),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstitutionName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstitutionAddress),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StationName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstitutionalDepartmentName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ManufacturerModelName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DeviceSerialNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SoftwareVersions),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SpatialResolution),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DateOfLastCalibration),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(TimeOfLastCalibration),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PixelPaddingValue),dst,src);
+}
+
+static void copyImagePixelModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(SamplesPerPixel),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PhotometricInterpretation),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(Rows),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(Columns),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(BitsAllocated),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(BitsStored),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(HighBit),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PixelRepresentation),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PixelData),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PlanarConfiguration),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PixelAspectRatio),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SmallestImagePixelValue),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(LargestImagePixelValue),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RedPaletteColorLookupTableDescriptor),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(GreenPaletteColorLookupTableDescriptor),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(BluePaletteColorLookupTableDescriptor),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RedPaletteColorLookupTableData),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(GreenPaletteColorLookupTableData),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(BluePaletteColorLookupTableData),dst,src);
+}
+
+static void copyContrastBolusModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusAgent),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusRoute),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusVolume),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusStartTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusStopTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusTotalDose),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusAgentSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusAdministrationRouteSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastFlowRate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastFlowDuration),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusIngredient),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContrastBolusIngredientConcentration),dst,src);
+}
+
+static void copySoftcopyPresentationLUTModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(PresentationLUTSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PresentationLUTShape),dst,src);
+}
+
+static void copyAcquisitionContextModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionContextSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionContextDescription),dst,src);
+}
+
+static void copySOPCommonModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(SOPClassUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SOPInstanceUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SpecificCharacterSet),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstanceCreationDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstanceCreationTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstanceCreatorUID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(TimezoneOffsetFromUTC),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstanceNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SOPInstanceStatus),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SOPAuthorizationDateTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SOPAuthorizationComment),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AuthorizationEquipmentCertificationNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(MACParametersSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DigitalSignaturesSequence),dst,src);
+}
+
+static void copySCEquipmentModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(ConversionType),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(Modality),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SecondaryCaptureDeviceID),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SecondaryCaptureDeviceManufacturer),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SecondaryCaptureDeviceManufacturerModelName),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SecondaryCaptureDeviceSoftwareVersions),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(VideoImageFormatAcquired),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DigitalImageFormatAcquired),dst,src);
+}
+
+static void copyGeneralImageModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(InstanceNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PatientOrientation),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContentDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ContentTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ImageType),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionDate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(AcquisitionDateTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ReferencedImageSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DerivationDescription),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DerivationCodeSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SourceImageSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ImagesInAcquisition),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ImageComments),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(QualityControlImage),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(BurnedInAnnotation),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(LossyImageCompression),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(LossyImageCompressionRatio),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(IconImageSequence),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PresentationLUTShape),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(IrradiationEventUID),dst,src);
+}
+
+static void copyCineModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameTime),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameTimeVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StartTrim),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(StopTrim),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RecommendedDisplayFrameRate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(CineRate),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameDelay),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(EffectiveDuration),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ActualFrameDuration),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PreferredPlaybackSequencing),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ImageTriggerDelay),dst,src);
+}
+
+static void copyMultiFrameModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(NumberOfFrames),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameIncrementPointer),dst,src);
+}
+
+static void copyFramePointersModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(RepresentativeFrameNumber),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameNumbersOfInterest),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameOfInterestDescription),dst,src);
+}
+
+static void copySCImageModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(DateOfSecondaryCapture),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(TimeOfSecondaryCapture),dst,src);
+}
+
+static void copySCMultiFrameImageModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(BurnedInAnnotation),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PresentationLUTShape),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(Illumination),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(ReflectedAmbientLight),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RescaleIntercept),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RescaleSlope),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RescaleType),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameIncrementPointer),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(NominalScannedPixelSpacing),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DigitizingDeviceTransportDirection),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(RotationOfScannedFilm),dst,src);
+}
+
+static void copySCMultiFrameVectorModule(AttributeList &dst,AttributeList &src) {
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameTimeVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(PageNumberVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameLabelVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FramePrimaryAngleVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(FrameSecondaryAngleVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(SliceLocationVector),dst,src);
+	copyAttributeIfNotAlreadyPresent(TagFromName(DisplayWindowLabelVector),dst,src);
+}
+
+static SequenceAttribute *makeNewSequenceAttributeWithoutItem(AttributeList *list,Tag tag) {
+	SequenceAttribute *a=new SequenceAttribute(tag);
+	Assert(a);
+	Assert(list);
+	(*list)+=a;
+	return a;
+}
+
+static AttributeList *makeNewSequenceAttributeWithItem(AttributeList *list,Tag tag) {
+	SequenceAttribute *a=makeNewSequenceAttributeWithoutItem(list,tag);
+	Assert(a);
+	AttributeList *itemlist = new AttributeList();
+	Assert(itemlist);
+	(*a)+=itemlist;
+	return itemlist;
+}
+
+static const char *makeCoilTypeFromName(const char *tryValue) {
+//cerr << "makeCoilTypeFromName:" << endl;
+	const char *useValue=0;
+	if (tryValue) {
+//cerr << "makeCoilTypeFromName: try " << tryValue << endl;
+		if      (findInStringRegardlessOfCase(tryValue,"BODY")) useValue="BODY";
+		else if (findInStringRegardlessOfCase(tryValue,"HEAD")) useValue="VOLUME";
+		else if (findInStringRegardlessOfCase(tryValue,"NECK")) useValue="VOLUME";
+		else if (findInStringRegardlessOfCase(tryValue,"KNEE")) useValue="VOLUME";
+		else if (findInStringRegardlessOfCase(tryValue,"SHOULDER")) useValue="SURFACE";
+		else if (findInStringRegardlessOfCase(tryValue,"TORSO")) useValue="VOLUME";		// GE
+		else if (findInStringRegardlessOfCase(tryValue,"SURFACE")) useValue="SURFACE";
+		else if (findInStringRegardlessOfCase(tryValue,"MULTICOIL")) useValue="MULTICOIL";
+		else if (findInStringRegardlessOfCase(tryValue,"ARRAY")) useValue="MULTICOIL";
+		else if (findInStringRegardlessOfCase(tryValue,"HE")) useValue="VOLUME";		// Siemens head coil
+		else if (findInStringRegardlessOfCase(tryValue,"H")) useValue="VOLUME";			// Philips head coil
+		else if (findInStringRegardlessOfCase(tryValue,"B")) useValue="BODY";			// Philips body coil
+		else if (findInStringRegardlessOfCase(tryValue,"S")) useValue="SURFACE";		// Philips surface coil
+		else useValue="UNKNOWN";	// not a standard defined term
+	}
+	else {
+		useValue="UNKNOWN";
+	}
+//cerr << "makeCoilTypeFromName: return " << useValue << endl;
+	return useValue;	
+}
+
+static const char *
+lookUpAndFillInCodeMeaning(
+	const char *csd,
+	const char *cv,
+	const char *cmDefault,
+	const char *csvn)
+{
+	const char *cm = cmDefault;
+	if (csd && cv) {
+		if (strcmp(csd,"SNM3") == 0 || strcmp(csd,"SRT") == 0) {
+			if      (strcmp(cv,"T-A0100") == 0) { cm="Brain"; }
+			else if (strcmp(cv,"T-D1100") == 0) { cm="Head"; }
+			else if (strcmp(cv,"T-11100") == 0) { cm="Skull"; }
+			else if (strcmp(cv,"T-D1217") == 0) { cm="Maxilla and mandible"; }
+			else if (strcmp(cv,"T-45010") == 0) { cm="Carotid artery"; }
+			else if (strcmp(cv,"T-D1600") == 0) { cm="Neck"; }
+			else if (strcmp(cv,"T-11500") == 0) { cm="Spine"; }
+			else if (strcmp(cv,"T-11501") == 0) { cm="Cervical spine"; }
+			else if (strcmp(cv,"T-11502") == 0) { cm="Thoracic spine"; }
+			else if (strcmp(cv,"T-11503") == 0) { cm="Lumbar spine"; }
+			else if (strcmp(cv,"T-11AD0") == 0) { cm="Sacrum"; }
+			else if (strcmp(cv,"T-11BF0") == 0) { cm="Coccyx"; }
+			else if (strcmp(cv,"T-32000") == 0) { cm="Heart"; }
+			else if (strcmp(cv,"T-D3000") == 0) { cm="Chest"; }
+			else if (strcmp(cv,"T-D4000") == 0) { cm="Abdomen"; }
+			else if (strcmp(cv,"T-62000") == 0) { cm="Liver"; }
+			else if (strcmp(cv,"T-D6000") == 0) { cm="Pelvis"; }
+			else if (strcmp(cv,"T-D0300") == 0) { cm="Extremity"; }
+			else if (strcmp(cv,"T-D8200") == 0) { cm="Arm"; }
+			else if (strcmp(cv,"T-D8700") == 0) { cm="Hand"; }
+			else if (strcmp(cv,"T-D8600") == 0) { cm="Wrist joint"; }
+			else if (strcmp(cv,"T-D8300") == 0) { cm="Elbow"; }
+			else if (strcmp(cv,"T-D2220") == 0) { cm="Shoulder"; }
+			else if (strcmp(cv,"T-12310") == 0) { cm="Clavicle"; }
+			else if (strcmp(cv,"T-15710") == 0) { cm="Hip joint"; }
+			else if (strcmp(cv,"T-D9200") == 0) { cm="Knee"; }
+			else if (strcmp(cv,"T-D9400") == 0) { cm="Leg"; }
+			else if (strcmp(cv,"T-D9100") == 0) { cm="Thigh"; }
+			else if (strcmp(cv,"T-D9440") == 0) { cm="Calf of leg"; }
+			else if (strcmp(cv,"T-D9700") == 0) { cm="Foot"; }
+			else if (strcmp(cv,"T-15750") == 0) { cm="Ankle joint"; }
+			else if (strcmp(cv,"T-04000") == 0) { cm="Breast"; }
+			else if (strcmp(cv,"T-AB959") == 0) { cm="Internal auditory canal"; }
+			else if (strcmp(cv,"T-D1000") == 0) { cm="Head and Neck"; }
+			else if (strcmp(cv,"R-FAB52") == 0) { cm="Neck and Chest"; }
+			else if (strcmp(cv,"R-FAB53") == 0) { cm="Neck, Chest and Abdomen"; }
+			else if (strcmp(cv,"R-FAB54") == 0) { cm="Neck, Chest, Abdomen and Pelvis"; }
+			else if (strcmp(cv,"R-FAB55") == 0) { cm="Chest and Abdomen"; }
+			else if (strcmp(cv,"R-FAB56") == 0) { cm="Chest, Abdomen and Pelvis"; }
+			else if (strcmp(cv,"R-FAB57") == 0) { cm="Abdomen and Pelvis"; }
+
+			else if (strcmp(cv,"F-6175A") == 0) { cm="N-acetylaspartate"; }
+			else if (strcmp(cv,"F-61620") == 0) { cm="Choline"; }
+			else if (strcmp(cv,"F-61380") == 0) { cm="Creatine"; }
+		}
+		else if (strcmp(csd,"DCM") == 0) {
+			if      (strcmp(cv,"113040") == 0)	{ cm="Lossy Compression"; }
+			else if (strcmp(cv,"113041") == 0)	{ cm="Apparent Diffusion Coefficient"; }
+			else if (strcmp(cv,"113042") == 0)	{ cm="Pixel by pixel addition"; }
+			else if (strcmp(cv,"113043") == 0)	{ cm="Diffusion weighted"; }
+			else if (strcmp(cv,"113044") == 0)	{ cm="Diffusion Anisotropy"; }
+			else if (strcmp(cv,"113045") == 0)	{ cm="Diffusion Attenuated"; }
+			else if (strcmp(cv,"113046") == 0)	{ cm="Pixel by pixel division"; }
+			else if (strcmp(cv,"113047") == 0)	{ cm="Pixel by pixel mask"; }
+			else if (strcmp(cv,"113048") == 0)	{ cm="Pixel by pixel Maximum"; }
+			else if (strcmp(cv,"113049") == 0)	{ cm="Pixel by pixel mean"; }
+			else if (strcmp(cv,"113050") == 0)	{ cm="Metabolite Maps from spectroscopy data"; }
+			else if (strcmp(cv,"113051") == 0)	{ cm="Pixel by pixel Minimum"; }
+			else if (strcmp(cv,"113052") == 0)	{ cm="Mean Transit Time"; }
+			else if (strcmp(cv,"113053") == 0)	{ cm="Pixel by pixel multiplication"; }
+			else if (strcmp(cv,"113054") == 0)	{ cm="Negative Enhancement Integral"; }
+			else if (strcmp(cv,"113055") == 0)	{ cm="Regional Cerebral Blood Flow"; }
+			else if (strcmp(cv,"113056") == 0)	{ cm="Regional Cerebral Blood Volume"; }
+			else if (strcmp(cv,"113057") == 0)	{ cm="R-Coefficient Map"; }
+			else if (strcmp(cv,"113058") == 0)	{ cm="Proton Density map"; }
+			else if (strcmp(cv,"113059") == 0)	{ cm="Signal Change Map"; }
+			else if (strcmp(cv,"113060") == 0)	{ cm="Signal to Noise Map"; }
+			else if (strcmp(cv,"113061") == 0)	{ cm="Standard Deviation"; }
+			else if (strcmp(cv,"113062") == 0)	{ cm="Pixel by pixel subtraction"; }
+			else if (strcmp(cv,"113063") == 0)	{ cm="T1 Map"; }
+			else if (strcmp(cv,"113064") == 0)	{ cm="T2* Map"; }
+			else if (strcmp(cv,"113065") == 0)	{ cm="T2 Map"; }
+			else if (strcmp(cv,"113066") == 0)	{ cm="Time Course of Signal"; }
+			else if (strcmp(cv,"113067") == 0)	{ cm="Temperature encoded"; }
+			else if (strcmp(cv,"113068") == 0)	{ cm="Student�s T-Test"; }
+			else if (strcmp(cv,"113069") == 0)	{ cm="Time To Peak map"; }
+			else if (strcmp(cv,"113070") == 0)	{ cm="Velocity encoded"; }
+			else if (strcmp(cv,"113071") == 0)	{ cm="Z-Score Map"; }
+			else if (strcmp(cv,"113072") == 0)	{ cm="Multiplanar reformat"; }
+			else if (strcmp(cv,"113073") == 0)	{ cm="Curved multiplanar reformat"; }
+			else if (strcmp(cv,"113074") == 0)	{ cm="Volume rendering"; }
+			else if (strcmp(cv,"113075") == 0)	{ cm="Surface rendering"; }
+			else if (strcmp(cv,"113076") == 0)	{ cm="Segmentation"; }
+			else if (strcmp(cv,"113077") == 0)	{ cm="Volume editing"; }
+			else if (strcmp(cv,"113078") == 0)	{ cm="Maximum intensity projection"; }
+			else if (strcmp(cv,"113079") == 0)	{ cm="Minimum intensity projection"; }
+			else if (strcmp(cv,"113085") == 0)	{ cm="Spatial resampling"; }
+			else if (strcmp(cv,"113086") == 0)	{ cm="Edge enhancement"; }
+			else if (strcmp(cv,"113087") == 0)	{ cm="Smooth"; }
+			else if (strcmp(cv,"113088") == 0)	{ cm="Gaussian blur"; }
+			else if (strcmp(cv,"113089") == 0)	{ cm="Unsharp mask"; }
+			else if (strcmp(cv,"113090") == 0)	{ cm="Image stitching"; }
+			else if (strcmp(cv,"121311") == 0)	{ cm="Localizer"; }
+			else if (strcmp(cv,"121322") == 0)	{ cm="Source image for image processing operation"; }
+		}
+		else if (strcmp(csd,"99PMPMRMF") == 0) {
+			if      (strcmp(cv,"000001") == 0)	{ cm="Multiplanar reformat"; }
+			else if (strcmp(cv,"000002") == 0)	{ cm="Curved multiplanar reformat"; }
+			else if (strcmp(cv,"000003") == 0)	{ cm="Volume rendering"; }
+			else if (strcmp(cv,"000004") == 0)	{ cm="Surface rendering"; }
+			else if (strcmp(cv,"000005") == 0)	{ cm="Segmentation"; }
+			else if (strcmp(cv,"000006") == 0)	{ cm="Volume editing"; }
+			else if (strcmp(cv,"000007") == 0)	{ cm="Maximum intensity projection"; }
+			else if (strcmp(cv,"000008") == 0)	{ cm="Minimum intensity projection"; }
+			else if (strcmp(cv,"000009") == 0)	{ cm="Spatial resampling"; }
+			else if (strcmp(cv,"000010") == 0)	{ cm="Edge enhancement"; }
+			else if (strcmp(cv,"000011") == 0)	{ cm="Smooth"; }
+			else if (strcmp(cv,"000012") == 0)	{ cm="Gaussian blur"; }
+			else if (strcmp(cv,"000013") == 0)	{ cm="Unsharp mask"; }
+		}
+	}
+	return cm;
+}
+
+static void addCodeSequenceItemToItemList(
+	AttributeList *i,
+	const char *csd,
+	const char *cv,
+	const char *cm,
+	const char *csvn)
+{
+	Assert(i);
+	cm = lookUpAndFillInCodeMeaning(csd,cv,cm,csvn);
+	if (csd  && strlen(csd))  (*i)+=new ShortStringAttribute(TagFromName(CodingSchemeDesignator),csd);
+	if (cv   && strlen(cv))   (*i)+=new ShortStringAttribute(TagFromName(CodeValue),cv);
+	if (cm   && strlen(cm))   (*i)+=new  LongStringAttribute(TagFromName(CodeMeaning),cm);
+	if (csvn && strlen(csvn)) (*i)+=new ShortStringAttribute(TagFromName(CodingSchemeVersion),csvn);
+}
+
+static void addCodeSequenceItemToAttribute(
+	SequenceAttribute *a,
+	const char *csd,
+	const char *cv,
+	const char *cm,
+	const char *csvn)
+{
+	Assert(a);                                                
+	AttributeList *i = new AttributeList();
+	Assert(i);
+	(*a)+=i;
+	addCodeSequenceItemToItemList(i,csd,cv,cm,csvn);
+}
+
+static const char *searchStringAttributeForPotentialBodyParts(const char *tryValue) {
+//cerr << "searchStringAttributeForPotentialBodyParts:" << endl;
+	const char *useValue=0;
+	if (tryValue) {
+//cerr << "searchStringAttributeForPotentialBodyParts: try " << tryValue << endl;
+		if      (findInStringRegardlessOfCase(tryValue,"NECK") && findInStringRegardlessOfCase(tryValue,"CHEST") && findInStringRegardlessOfCase(tryValue,"ABD") && findInStringRegardlessOfCase(tryValue,"PELV")) useValue="NECKCHESTABDPELV";
+		else if (findInStringRegardlessOfCase(tryValue,"NECK") && findInStringRegardlessOfCase(tryValue,"CHEST") && findInStringRegardlessOfCase(tryValue,"ABD")) useValue="NECKCHESTABDOMEN";
+		else if (findInStringRegardlessOfCase(tryValue,"NECK") && findInStringRegardlessOfCase(tryValue,"CHEST")) useValue="NECKCHEST";
+		else if (findInStringRegardlessOfCase(tryValue,"CHEST") && findInStringRegardlessOfCase(tryValue,"ABD") && findInStringRegardlessOfCase(tryValue,"PELV")) useValue="CHESTABDPELVIS";
+		else if (findInStringRegardlessOfCase(tryValue,"CHEST") && findInStringRegardlessOfCase(tryValue,"ABD")) useValue="CHESTABDOMEN";
+		else if (findInStringRegardlessOfCase(tryValue,"ABD") && findInStringRegardlessOfCase(tryValue,"PELVIS")) useValue="ABDOMENPELVIS";
+		else if (findInStringRegardlessOfCase(tryValue,"HEAD") && findInStringRegardlessOfCase(tryValue,"NECK")) useValue="HEADNECK";
+		else if (findInStringRegardlessOfCase(tryValue,"BRAIN")) useValue="BRAIN";
+		else if (findInStringRegardlessOfCase(tryValue,"HEAD")) useValue="HEAD";
+		else if (findInStringRegardlessOfCase(tryValue,"SKULL")) useValue="SKULL";
+		else if (findInStringRegardlessOfCase(tryValue,"JAW")) useValue="JAW";
+		else if (findInStringRegardlessOfCase(tryValue,"CAROTID")) useValue="CAROTID";
+		else if (findInStringRegardlessOfCase(tryValue,"NECK")) useValue="NECK";
+		else if (findInStringRegardlessOfCase(tryValue,"SPINE")) useValue="SPINE";
+		else if (findInStringRegardlessOfCase(tryValue,"CSPINE")) useValue="CSPINE";
+		else if (findInStringRegardlessOfCase(tryValue,"TSPINE")) useValue="TSPINE";
+		else if (findInStringRegardlessOfCase(tryValue,"LSPINE")) useValue="LSPINE";
+		else if (findInStringRegardlessOfCase(tryValue,"SSPINE")) useValue="SSPINE";
+		else if (findInStringRegardlessOfCase(tryValue,"COCCYX")) useValue="COCCYX";
+		else if (findInStringRegardlessOfCase(tryValue,"HEART")) useValue="HEART";
+		else if (findInStringRegardlessOfCase(tryValue,"CARDIAC")) useValue="HEART";
+		else if (findInStringRegardlessOfCase(tryValue,"CHEST")) useValue="CHEST";
+		else if (findInStringRegardlessOfCase(tryValue,"ABDOMEN")) useValue="ABDOMEN";
+		else if (findInStringRegardlessOfCase(tryValue,"LIVER")) useValue="LIVER";
+		else if (findInStringRegardlessOfCase(tryValue,"PELVIS")) useValue="PELVIS";
+		else if (findInStringRegardlessOfCase(tryValue,"EXTREMITY")) useValue="EXTREMITY";
+		else if (findInStringRegardlessOfCase(tryValue,"ARM")) useValue="ARM";
+		else if (findInStringRegardlessOfCase(tryValue,"HAND")) useValue="HAND";
+		else if (findInStringRegardlessOfCase(tryValue,"WRIST")) useValue="WRIST";
+		else if (findInStringRegardlessOfCase(tryValue,"ELBOW")) useValue="ELBOW";
+		else if (findInStringRegardlessOfCase(tryValue,"SHOULDER")) useValue="SHOULDER";
+		else if (findInStringRegardlessOfCase(tryValue,"CLAVICLE")) useValue="CLAVICLE";
+		else if (findInStringRegardlessOfCase(tryValue,"HIP")) useValue="HIP";
+		else if (findInStringRegardlessOfCase(tryValue,"KNEE")) useValue="KNEE";
+		else if (findInStringRegardlessOfCase(tryValue,"LEG")) useValue="LEG";
+		else if (findInStringRegardlessOfCase(tryValue,"THIGH")) useValue="LEG";
+		else if (findInStringRegardlessOfCase(tryValue,"CALF")) useValue="CALF";
+		else if (findInStringRegardlessOfCase(tryValue,"FOOT")) useValue="FOOT";
+		else if (findInStringRegardlessOfCase(tryValue,"ANKLE")) useValue="ANKLE";
+		else if (findInStringRegardlessOfCase(tryValue,"BREAST")) useValue="BREAST";
+		else if (findInStringRegardlessOfCase(tryValue,"IAC")) useValue="IAC";
+		else if (findInStringRegardlessOfCase(tryValue,"CAP")) useValue="CHESTABDPELVIS";
+		else if (findInStringRegardlessOfCase(tryValue,"C/A/P")) useValue="CHESTABDPELVIS";
+	}
+//cerr << "searchStringAttributeForPotentialBodyParts: return " << useValue << endl;
+	return useValue;
+}
+
+static SequenceAttribute *makeAnatomicRegionSequenceFromBodyPart(const char *bodyPart) {
+	SequenceAttribute *aAnatomicRegionSequence=new SequenceAttribute(TagFromName(AnatomicRegionSequence));
+	Assert(aAnatomicRegionSequence);                                                
+	
+	const char *csd = 0;
+	const char *cv = 0;
+	
+	if (bodyPart) {
+		if      (strcmp(bodyPart,"BRAIN") == 0)		{ csd="SNM3"; cv="T-A0100"; }
+		else if (strcmp(bodyPart,"HEAD") == 0)		{ csd="SNM3"; cv="T-D1100"; }
+		else if (strcmp(bodyPart,"SKULL") == 0)		{ csd="SNM3"; cv="T-11100"; }
+		else if (strcmp(bodyPart,"JAW") == 0)		{ csd="SNM3"; cv="T-D1217"; }
+		else if (strcmp(bodyPart,"CAROTID") == 0)	{ csd="SNM3"; cv="T-45010"; }
+		else if (strcmp(bodyPart,"NECK") == 0)		{ csd="SNM3"; cv="T-D1600"; }
+		else if (strcmp(bodyPart,"SPINE") == 0)		{ csd="SNM3"; cv="T-11500"; }
+		else if (strcmp(bodyPart,"CSPINE") == 0)	{ csd="SNM3"; cv="T-11501"; }
+		else if (strcmp(bodyPart,"TSPINE") == 0)	{ csd="SNM3"; cv="T-11502"; }
+		else if (strcmp(bodyPart,"LSPINE") == 0)	{ csd="SNM3"; cv="T-11503"; }
+		else if (strcmp(bodyPart,"SSPINE") == 0)	{ csd="SNM3"; cv="T-11AD0"; }
+		else if (strcmp(bodyPart,"COCCYX") == 0)	{ csd="SNM3"; cv="T-11BF0"; }
+		else if (strcmp(bodyPart,"HEART") == 0)		{ csd="SNM3"; cv="T-32000"; }
+		else if (strcmp(bodyPart,"CHEST") == 0)		{ csd="SNM3"; cv="T-D3000"; }
+		else if (strcmp(bodyPart,"ABDOMEN") == 0)	{ csd="SNM3"; cv="T-D4000"; }
+		else if (strcmp(bodyPart,"LIVER") == 0)		{ csd="SNM3"; cv="T-62000"; }
+		else if (strcmp(bodyPart,"PELVIS") == 0)	{ csd="SNM3"; cv="T-D6000"; }
+		else if (strcmp(bodyPart,"EXTREMITY") == 0)	{ csd="SNM3"; cv="T-D0300"; }
+		else if (strcmp(bodyPart,"ARM") == 0)		{ csd="SNM3"; cv="T-D8200"; }
+		else if (strcmp(bodyPart,"HAND") == 0)		{ csd="SNM3"; cv="T-D8700"; }
+		else if (strcmp(bodyPart,"WRIST") == 0)		{ csd="SNM3"; cv="T-D8600"; }
+		else if (strcmp(bodyPart,"ELBOW") == 0)		{ csd="SNM3"; cv="T-D8300"; }
+		else if (strcmp(bodyPart,"SHOULDER") == 0)	{ csd="SNM3"; cv="T-D2220"; }
+		else if (strcmp(bodyPart,"CLAVICLE") == 0)	{ csd="SNM3"; cv="T-12310"; }
+		else if (strcmp(bodyPart,"HIP") == 0)		{ csd="SNM3"; cv="T-15710"; }
+		else if (strcmp(bodyPart,"KNEE") == 0)		{ csd="SNM3"; cv="T-D9200"; }
+		else if (strcmp(bodyPart,"LEG") == 0)		{ csd="SNM3"; cv="T-D9400"; }
+		else if (strcmp(bodyPart,"THIGH") == 0)		{ csd="SNM3"; cv="T-D9100"; }
+		else if (strcmp(bodyPart,"CALF") == 0)		{ csd="SNM3"; cv="T-D9440"; }
+		else if (strcmp(bodyPart,"FOOT") == 0)		{ csd="SNM3"; cv="T-D9700"; }
+		else if (strcmp(bodyPart,"ANKLE") == 0)		{ csd="SNM3"; cv="T-15750"; }
+		else if (strcmp(bodyPart,"BREAST") == 0)	{ csd="SNM3"; cv="T-04000"; }
+		else if (strcmp(bodyPart,"IAC") == 0)		{ csd="SNM3"; cv="T-AB959"; }
+		else if (strcmp(bodyPart,"HEADNECK") == 0)				{ csd="SRT"; cv="T-D1000"; }
+		else if (strcmp(bodyPart,"NECKCHEST") == 0)				{ csd="SRT"; cv="R-FAB52"; } 
+		else if (strcmp(bodyPart,"NECKCHESTABDOMEN") == 0)		{ csd="SRT"; cv="R-FAB53"; }
+		else if (strcmp(bodyPart,"NECKCHESTABDPELV") == 0)		{ csd="SRT"; cv="R-FAB54"; }
+		else if (strcmp(bodyPart,"CHESTABDOMEN") == 0)			{ csd="SRT"; cv="R-FAB55"; }
+		else if (strcmp(bodyPart,"CHESTABDPELVIS") == 0)		{ csd="SRT"; cv="R-FAB56"; }
+		else if (strcmp(bodyPart,"ABDOMENPELVIS") == 0)			{ csd="SRT"; cv="R-FAB57"; }
+	}
+	
+	addCodeSequenceItemToAttribute(aAnatomicRegionSequence,csd,cv,0,0);
+
+	return aAnatomicRegionSequence;
+}
+
+static SequenceAttribute *makeMeasurementUnitsCodeSequence(const char *value,const char *meaning) {
+	SequenceAttribute *aMeasurementUnitsCodeSequence=new SequenceAttribute(TagFromName(MeasurementUnitsCodeSequence));
+	Assert(aMeasurementUnitsCodeSequence);                                                
+
+	addCodeSequenceItemToAttribute(aMeasurementUnitsCodeSequence,"UCUM",value,meaning,"1.4");
+
+	return aMeasurementUnitsCodeSequence;
+}
+
+static SequenceAttribute *makeMeasurementUnitsCodeSequence(const char *value) {
+	const char *meaning = value;
+	if (value) {
+		int length = strlen(value);
+		if (strcmp(value,"1") == 0) {
+			meaning = "no units";
+		}
+		else if (length > 2 && value[0] == '{' && value[length-1] == '}') {	// remove braces from meaning
+			char *newMeaning = new char[length-1];
+			strncpy(newMeaning,value+1,length-2);
+			newMeaning[length-2]=0;
+			meaning=newMeaning;
+		}
+	}
+	return makeMeasurementUnitsCodeSequence(value,meaning);
+}
+
+static void addMetaboliteMapCodeSequence(AttributeList *iMRMetaboliteMapSequence,const char *description) {
+//cerr << "addMetaboliteMapCodeSequence:" << endl;
+	const char *csd = 0;
+	const char *cv = 0;
+	
+	if (description) {
+		if      (strcmp(description,"NAA") == 0)		{ csd="SRT"; cv="F-6175A"; }
+		else if (strcmp(description,"Choline") == 0)		{ csd="SRT"; cv="F-61620"; }
+		else if (strcmp(description,"Creatine") == 0)		{ csd="SRT"; cv="F-61380"; }
+	}
+	
+	if (csd && cv) {
+//cerr << "addMetaboliteMapCodeSequence: adding " << cv << endl;
+		SequenceAttribute *aMetaboliteMapCodeSequence=new SequenceAttribute(TagFromName(MetaboliteMapCodeSequence));
+		Assert(aMetaboliteMapCodeSequence);
+		(*iMRMetaboliteMapSequence)+=aMetaboliteMapCodeSequence;                                                
+		addCodeSequenceItemToAttribute(aMetaboliteMapCodeSequence,csd,cv,0,0);
+	}
+}
+
+static void
+makeSupplementalPaletteColorLUT(
+		AttributeList *list,
+		bool minimalAttributesOnly,
+		int addSupplementalPaletteColorLUT_numberOfEntries,
+		int addSupplementalPaletteColorLUT_firstValueMapped,
+		int addSupplementalPaletteColorLUT_firstRedValue,
+		int addSupplementalPaletteColorLUT_incrementRedValue,
+		int addSupplementalPaletteColorLUT_entryToStartIncrementingRedValue,
+		int addSupplementalPaletteColorLUT_entryToStartDecrementingRedValue,
+		int addSupplementalPaletteColorLUT_entryToStopChangingRedValue,
+		int addSupplementalPaletteColorLUT_firstGreenValue,
+		int addSupplementalPaletteColorLUT_incrementGreenValue,
+		int addSupplementalPaletteColorLUT_entryToStartIncrementingGreenValue,
+		int addSupplementalPaletteColorLUT_entryToStartDecrementingGreenValue,
+		int addSupplementalPaletteColorLUT_entryToStopChangingGreenValue,
+		int addSupplementalPaletteColorLUT_firstBlueValue,
+		int addSupplementalPaletteColorLUT_incrementBlueValue,
+		int addSupplementalPaletteColorLUT_entryToStartIncrementingBlueValue,
+		int addSupplementalPaletteColorLUT_entryToStartDecrementingBlueValue,
+		int addSupplementalPaletteColorLUT_entryToStopChangingBlueValue) {
+//cerr << "makeSupplementalPaletteColorLUT:" << endl;
+	Assert(list);
+	
+	//if (!minimalAttributesOnly) (*list)+=new UnsignedShortAttribute(TagFromName(LargestMonochromePixelValue),
+	//	Uint16(addSupplementalPaletteColorLUT_firstValueMapped-1));
+			
+	(*list)+=new UnsignedShortAttribute(TagFromName(RedPaletteColorLookupTableDescriptor),
+			Uint16(addSupplementalPaletteColorLUT_numberOfEntries),
+			Uint16(addSupplementalPaletteColorLUT_firstValueMapped),
+			Uint16(16));
+	(*list)+=new UnsignedShortAttribute(TagFromName(GreenPaletteColorLookupTableDescriptor),
+			Uint16(addSupplementalPaletteColorLUT_numberOfEntries),
+			Uint16(addSupplementalPaletteColorLUT_firstValueMapped),
+			Uint16(16));
+	(*list)+=new UnsignedShortAttribute(TagFromName(BluePaletteColorLookupTableDescriptor),
+			Uint16(addSupplementalPaletteColorLUT_numberOfEntries),
+			Uint16(addSupplementalPaletteColorLUT_firstValueMapped),
+			Uint16(16));
+
+	OtherWordSmallNonPixelAttributeBase *aRedPaletteColorLookupTableData = new OtherWordSmallNonPixelAttributeBase(TagFromName(RedPaletteColorLookupTableData));
+	Assert(aRedPaletteColorLookupTableData);
+	(*list)+=aRedPaletteColorLookupTableData;
+	OtherWordSmallNonPixelAttributeBase *aGreenPaletteColorLookupTableData = new OtherWordSmallNonPixelAttributeBase(TagFromName(GreenPaletteColorLookupTableData));
+	Assert(aGreenPaletteColorLookupTableData);
+	(*list)+=aGreenPaletteColorLookupTableData;
+	OtherWordSmallNonPixelAttributeBase *aBluePaletteColorLookupTableData = new OtherWordSmallNonPixelAttributeBase(TagFromName(BluePaletteColorLookupTableData));
+	Assert(aBluePaletteColorLookupTableData);
+	(*list)+=aBluePaletteColorLookupTableData;
+
+	Uint16 *redValues = new Uint16[addSupplementalPaletteColorLUT_numberOfEntries];
+	Assert(redValues);
+	Uint16 *greenValues = new Uint16[addSupplementalPaletteColorLUT_numberOfEntries];
+	Assert(greenValues);
+	Uint16 *blueValues = new Uint16[addSupplementalPaletteColorLUT_numberOfEntries];
+	Assert(blueValues);
+	Uint16 r = addSupplementalPaletteColorLUT_firstRedValue;
+	Uint16 g = addSupplementalPaletteColorLUT_firstGreenValue;
+	Uint16 b = addSupplementalPaletteColorLUT_firstBlueValue;
+	int i;
+	for (i=0; i<addSupplementalPaletteColorLUT_numberOfEntries; ++i) {
+//cerr << "r=0x" << hex << r << " g=0x" << g << " b=0x" << b << dec << endl;
+		redValues[i]=r;
+		if (i <= addSupplementalPaletteColorLUT_entryToStopChangingRedValue) {
+			if (i >= addSupplementalPaletteColorLUT_entryToStartDecrementingRedValue) {
+				r-=addSupplementalPaletteColorLUT_incrementRedValue;
+			}
+			else if (i >= addSupplementalPaletteColorLUT_entryToStartIncrementingRedValue) {
+				r+=addSupplementalPaletteColorLUT_incrementRedValue;
+			}
+		}
+		greenValues[i]=g;
+		if (i <= addSupplementalPaletteColorLUT_entryToStopChangingGreenValue) {
+			if (i >= addSupplementalPaletteColorLUT_entryToStartDecrementingGreenValue) {
+				g-=addSupplementalPaletteColorLUT_incrementGreenValue;
+			}
+			else if (i >= addSupplementalPaletteColorLUT_entryToStartIncrementingGreenValue) {
+				g+=addSupplementalPaletteColorLUT_incrementGreenValue;
+			}
+		}
+		blueValues[i]=b;
+		if (i <= addSupplementalPaletteColorLUT_entryToStopChangingBlueValue) {
+			if (i >= addSupplementalPaletteColorLUT_entryToStartDecrementingBlueValue) {
+				b-=addSupplementalPaletteColorLUT_incrementBlueValue;
+			}
+			else if (i >= addSupplementalPaletteColorLUT_entryToStartIncrementingBlueValue) {
+				b+=addSupplementalPaletteColorLUT_incrementBlueValue;
+			}
+		}
+	}
+	aRedPaletteColorLookupTableData->setValue(redValues,addSupplementalPaletteColorLUT_numberOfEntries);
+	aGreenPaletteColorLookupTableData->setValue(greenValues,addSupplementalPaletteColorLUT_numberOfEntries);
+	aBluePaletteColorLookupTableData->setValue(blueValues,addSupplementalPaletteColorLUT_numberOfEntries);
+	if (redValues) delete[] redValues;
+	if (greenValues) delete[] greenValues;
+	if (blueValues) delete[] blueValues;
+}
+
+static void
+makeSequenceUsingSOPInstanceReferenceMacro(
+		AttributeList *list,
+		bool minimalAttributesOnly,
+		Tag sequenceTag,
+		const char *studyInstanceUID,
+		const char *seriesInstanceUID,
+		const char *retrieveAETitle,
+		const char *storageMediaFileSetID,
+		const char *storageMediaFileSetUID,
+		const char *referencedSOPClassUID,
+		const char *referencedSOPInstanceUID) {
+//cerr << "makeSequenceUsingSOPInstanceReferenceMacro:" << endl;
+	Assert(list);
+	AttributeList *iStudySequence = makeNewSequenceAttributeWithItem(list,sequenceTag);
+	Assert(iStudySequence);
+	if (!minimalAttributesOnly) {
+		if (studyInstanceUID && strlen(studyInstanceUID))
+			(*iStudySequence)+= new UIStringAttribute(TagFromName(StudyInstanceUID),studyInstanceUID);
+		AttributeList *iReferencedSeriesSequence  = makeNewSequenceAttributeWithItem(iStudySequence,TagFromName(ReferencedSeriesSequence));
+		Assert(iReferencedSeriesSequence);
+		if (seriesInstanceUID && strlen(seriesInstanceUID))
+			(*iReferencedSeriesSequence)+= new UIStringAttribute(TagFromName(SeriesInstanceUID),seriesInstanceUID);
+		if (retrieveAETitle && strlen(retrieveAETitle))
+			(*iReferencedSeriesSequence)+= new UIStringAttribute(TagFromName(RetrieveAETitle),retrieveAETitle);
+		if (storageMediaFileSetID && strlen(storageMediaFileSetID))
+			(*iReferencedSeriesSequence)+= new UIStringAttribute(TagFromName(StorageMediaFileSetID),storageMediaFileSetID);
+		if (storageMediaFileSetUID && strlen(storageMediaFileSetUID))
+			(*iReferencedSeriesSequence)+= new UIStringAttribute(TagFromName(StorageMediaFileSetUID),storageMediaFileSetUID);
+		AttributeList *iReferencedSOPSequence  = makeNewSequenceAttributeWithItem(iReferencedSeriesSequence,TagFromName(ReferencedSOPSequence));
+		Assert(iReferencedSOPSequence);
+		if (referencedSOPClassUID && strlen(referencedSOPClassUID))
+			(*iReferencedSOPSequence)+= new UIStringAttribute(TagFromName(ReferencedSOPClassUID),referencedSOPClassUID);
+		if (referencedSOPInstanceUID && strlen(referencedSOPInstanceUID))
+			(*iReferencedSOPSequence)+= new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),referencedSOPInstanceUID);
+	}
+}		
+
+static void
+makeReferencedImageEvidenceSequence(
+		AttributeList *list,
+		bool minimalAttributesOnly,
+		const char *studyInstanceUID,
+		const char *seriesInstanceUID,
+		const char *referencedSOPClassUID,
+		const char *referencedSOPInstanceUID) {
+//cerr << "makeReferencedImageEvidenceSequence:" << endl;
+	makeSequenceUsingSOPInstanceReferenceMacro(list,minimalAttributesOnly,TagFromName(ReferencedImageEvidenceSequence),
+		studyInstanceUID,seriesInstanceUID,NULL,NULL,NULL,referencedSOPClassUID,referencedSOPInstanceUID);
+}
+
+static void
+makeSourceImageEvidenceSequence(
+		AttributeList *list,
+		bool minimalAttributesOnly,
+		const char *studyInstanceUID,
+		const char *seriesInstanceUID,
+		const char *referencedSOPClassUID,
+		const char *referencedSOPInstanceUID) {
+//cerr << "makeSourceImageEvidenceSequence:" << endl;
+	makeSequenceUsingSOPInstanceReferenceMacro(list,minimalAttributesOnly,TagFromName(SourceImageEvidenceSequence),
+		studyInstanceUID,seriesInstanceUID,NULL,NULL,NULL,referencedSOPClassUID,referencedSOPInstanceUID);
+}
+
+static void
+makeReferencedImageSequence(
+		AttributeList *functionalGroupsSequence,
+		bool minimalAttributesOnly,
+		const char *referencedSOPClassUID,
+		const char *referencedSOPInstanceUID,
+		const char *referencedFrameNumbers,
+		const char *purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+		const char *purposeOfReferenceCodeSequenceCodeValue,
+		const char *purposeOfReferenceCodeSequenceCodeMeaning,
+		const char *purposeOfReferenceCodeSequenceCodingSchemeVersion) {
+//cerr << "makeReferencedImageSequence:" << endl;
+	if (minimalAttributesOnly) {
+		(void)makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(ReferencedImageSequence));
+	}
+	else {
+		Assert(functionalGroupsSequence);
+		AttributeList *iReferencedImageSequence  = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(ReferencedImageSequence));
+		if (referencedSOPClassUID && strlen(referencedSOPClassUID))
+			(*iReferencedImageSequence)+= new UIStringAttribute(TagFromName(ReferencedSOPClassUID),referencedSOPClassUID);
+		if (referencedSOPInstanceUID && strlen(referencedSOPInstanceUID))
+			(*iReferencedImageSequence)+= new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),referencedSOPInstanceUID);
+		if (referencedFrameNumbers && strlen(referencedFrameNumbers))
+			(*iReferencedImageSequence)+= new IntegerStringAttribute(TagFromName(ReferencedFrameNumber),referencedFrameNumbers);
+			// NB. Tag is (0x0008,0x1160) IS Referenced Frame Number; not (0x0040,0xa136) US Referenced Frame Numbers
+	
+		AttributeList *iPurposeOfReferenceCodeSequence  = makeNewSequenceAttributeWithItem(iReferencedImageSequence,TagFromName(PurposeOfReferenceCodeSequence));
+		addCodeSequenceItemToItemList(iPurposeOfReferenceCodeSequence,
+			purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+			purposeOfReferenceCodeSequenceCodeValue,
+			purposeOfReferenceCodeSequenceCodeMeaning,
+			purposeOfReferenceCodeSequenceCodingSchemeVersion);
+	}
+}
+
+static void
+makeDerivationImageSequence(
+		AttributeList *functionalGroupsSequence,
+		bool minimalAttributesOnly,
+		const char *derivationCodeSequenceCodingSchemeDesignator,
+		const char *derivationCodeSequenceCodeValue,
+		const char *derivationCodeSequenceCodeMeaning,
+		const char *derivationCodeSequenceCodingSchemeVersion,
+		const char *referencedSOPClassUID,
+		const char *referencedSOPInstanceUID,
+		const char *referencedFrameNumbers,
+		const char *purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+		const char *purposeOfReferenceCodeSequenceCodeValue,
+		const char *purposeOfReferenceCodeSequenceCodeMeaning,
+		const char *purposeOfReferenceCodeSequenceCodingSchemeVersion) {
+//cerr << "makeDerivationImageSequence:" << endl;
+	if (minimalAttributesOnly) {
+		(void)makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(DerivationImageSequence));
+	}
+	else {
+		Assert(functionalGroupsSequence);
+		AttributeList *iDerivationImageSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(DerivationImageSequence));
+		AttributeList *iDerivationCodeSequence  = makeNewSequenceAttributeWithItem(iDerivationImageSequence,TagFromName(DerivationCodeSequence));
+		addCodeSequenceItemToItemList(iDerivationCodeSequence,
+			derivationCodeSequenceCodingSchemeDesignator,
+			derivationCodeSequenceCodeValue,
+			derivationCodeSequenceCodeMeaning,
+			derivationCodeSequenceCodingSchemeVersion);
+		AttributeList *iSourceImageSequence  = makeNewSequenceAttributeWithItem(iDerivationImageSequence,TagFromName(SourceImageSequence));
+		if (referencedSOPClassUID && strlen(referencedSOPClassUID))
+			(*iSourceImageSequence)+= new UIStringAttribute(TagFromName(ReferencedSOPClassUID),referencedSOPClassUID);
+		if (referencedSOPInstanceUID && strlen(referencedSOPInstanceUID))
+			(*iSourceImageSequence)+= new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),referencedSOPInstanceUID);
+		if (referencedFrameNumbers && strlen(referencedFrameNumbers))
+			(*iSourceImageSequence)+= new IntegerStringAttribute(TagFromName(ReferencedFrameNumber),referencedFrameNumbers);
+			// NB. Tag is (0x0008,0x1160) IS Referenced Frame Number; not (0x0040,0xa136) US Referenced Frame Numbers
+	
+		AttributeList *iPurposeOfReferenceCodeSequence  = makeNewSequenceAttributeWithItem(iSourceImageSequence,TagFromName(PurposeOfReferenceCodeSequence));
+		addCodeSequenceItemToItemList(iPurposeOfReferenceCodeSequence,
+			purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+			purposeOfReferenceCodeSequenceCodeValue,
+			purposeOfReferenceCodeSequenceCodeMeaning,
+			purposeOfReferenceCodeSequenceCodingSchemeVersion);
+	}
+}
+
+static void
+makeMRSpatialSaturationSequence(
+		AttributeList *functionalGroupsSequence,
+		bool minimalAttributesOnly,
+		int addSatSlab_numberOfSlabs,
+		double *addSatSlab_thickness,	
+		double *addSatSlab_orientX,double *addSatSlab_orientY,double *addSatSlab_orientZ,	
+		double *addSatSlab_midpointX,double *addSatSlab_midpointY,double *addSatSlab_midpointZ) {
+//cerr << "makeMRSpatialSaturationSequence:" << endl;
+	Assert(addSatSlab_thickness);
+	Assert(addSatSlab_orientX);
+	Assert(addSatSlab_orientY);
+	Assert(addSatSlab_orientZ);
+	Assert(addSatSlab_midpointX);
+	Assert(addSatSlab_midpointY);
+	Assert(addSatSlab_midpointZ);
+	Assert(functionalGroupsSequence);
+	SequenceAttribute *aMRSpatialSaturationSequence=new SequenceAttribute(TagFromName(MRSpatialSaturationSequence));
+	Assert(aMRSpatialSaturationSequence);
+	Assert(functionalGroupsSequence);
+	(*functionalGroupsSequence)+=aMRSpatialSaturationSequence;
+	if (!minimalAttributesOnly) {
+		int i;
+		for (i=0; i<addSatSlab_numberOfSlabs; ++i) {
+			AttributeList *itemlist = new AttributeList();
+			Assert(itemlist);
+			(*itemlist)+=new FloatDoubleAttribute(TagFromName(SlabThickness),addSatSlab_thickness[i]);
+			(*itemlist)+=new FloatDoubleAttribute(TagFromName(SlabOrientation),addSatSlab_orientX[i],addSatSlab_orientY[i],addSatSlab_orientZ[i]);
+			(*itemlist)+=new FloatDoubleAttribute(TagFromName(MidSlabPosition),addSatSlab_midpointX[i],addSatSlab_midpointY[i],addSatSlab_midpointZ[i]);
+			(*aMRSpatialSaturationSequence)+=itemlist;
+		}
+	}
+}
+
+static bool makeFrameAnatomySequence(
+	AttributeList *functionalGroupsSequence,
+	bool frameLevel,int frame,
+	bool encountered_BodyPartExamined,char *shared_BodyPartExamined,char **perFrame_BodyPartExamined,
+	bool encountered_StudyDescription,char *shared_StudyDescription,char **perFrame_StudyDescription,
+	bool encountered_SeriesDescription,char *shared_SeriesDescription,char **perFrame_SeriesDescription,
+	bool encountered_ImageComments,char *shared_ImageComments,char **perFrame_ImageComments,
+	bool encountered_PatientName,char *shared_PatientName,char **perFrame_PatientName,
+	bool encountered_Laterality,char *shared_Laterality,char **perFrame_Laterality) {
+	
+//cerr << "makeFrameAnatomySequence: framelevel " << frameLevel << " frame " << dec << frame << endl;
+//cerr << "makeFrameAnatomySequence: shared_BodyPartExamined " << shared_BodyPartExamined << endl;
+//cerr << "makeFrameAnatomySequence: shared_StudyDescription " << shared_StudyDescription << endl;
+//cerr << "makeFrameAnatomySequence: shared_SeriesDescription " << shared_SeriesDescription << endl;
+//cerr << "makeFrameAnatomySequence: shared_ImageComments " << shared_ImageComments << endl;
+//cerr << "makeFrameAnatomySequence: shared_Laterality " << shared_Laterality << endl;
+	Assert(functionalGroupsSequence);
+
+	// When we want the values for the frame level, use either the per-frame value, or shared value if the former absent
+	// When we want the values for the shared level, they all must be from the shared values
+
+	const char *useBodyPart = 0;
+	if (encountered_BodyPartExamined) {
+		if (frameLevel) {
+			useBodyPart=perFrame_BodyPartExamined ? perFrame_BodyPartExamined[frame] : shared_BodyPartExamined;
+		}
+		else {
+			if (!perFrame_BodyPartExamined) {
+				useBodyPart=shared_BodyPartExamined;
+			}
+		}
+	}
+	if (useBodyPart && strlen(useBodyPart) == 0) useBodyPart=0;
+	if (!useBodyPart && encountered_StudyDescription) {
+		if (frameLevel) {
+			useBodyPart=searchStringAttributeForPotentialBodyParts(perFrame_StudyDescription ? perFrame_StudyDescription[frame] : shared_StudyDescription);
+		}
+		else {
+			if (!perFrame_StudyDescription) {
+				useBodyPart=searchStringAttributeForPotentialBodyParts(shared_StudyDescription);
+			}
+		}
+	}
+	if (useBodyPart && strlen(useBodyPart) == 0) useBodyPart=0;
+	if (!useBodyPart && encountered_SeriesDescription) {
+		if (frameLevel) {
+			useBodyPart=searchStringAttributeForPotentialBodyParts(perFrame_SeriesDescription ? perFrame_SeriesDescription[frame] : shared_SeriesDescription);
+		}
+		else {
+			if (!perFrame_SeriesDescription) {
+				useBodyPart=searchStringAttributeForPotentialBodyParts(shared_SeriesDescription);
+			}
+		}
+	}
+	if (useBodyPart && strlen(useBodyPart) == 0) useBodyPart=0;
+	if (!useBodyPart && encountered_ImageComments) {
+		if (frameLevel) {
+			useBodyPart=searchStringAttributeForPotentialBodyParts(perFrame_ImageComments ? perFrame_ImageComments[frame] : shared_ImageComments);
+		}
+		else {
+			if (!perFrame_ImageComments) {
+				useBodyPart=searchStringAttributeForPotentialBodyParts(shared_ImageComments);
+			}
+		}
+	}
+	if (useBodyPart && strlen(useBodyPart) == 0) useBodyPart=0;
+	if (!useBodyPart && encountered_PatientName) {
+		if (frameLevel) {
+			useBodyPart=searchStringAttributeForPotentialBodyParts(perFrame_PatientName ? perFrame_PatientName[frame] : shared_PatientName);
+		}
+		else {
+			if (!perFrame_PatientName) {
+				useBodyPart=searchStringAttributeForPotentialBodyParts(shared_PatientName);
+			}
+		}
+	}
+	if (useBodyPart && strlen(useBodyPart) == 0) useBodyPart=0;
+	
+//cerr << "makeFrameAnatomySequence: useBodyPart " << useBodyPart << endl;
+	
+	const char *useLaterality;
+	if (encountered_Laterality) {
+		if (frameLevel) {
+			useLaterality=perFrame_Laterality ? perFrame_Laterality[frame] : shared_Laterality;
+			useLaterality=useLaterality && strlen(useLaterality) ? useLaterality : "U";		// no further recourse, so assume unpaired
+		}
+		else {
+			if (perFrame_Laterality) {
+				useLaterality=0;								// leave it for the frame level
+			}
+			else {
+				useLaterality=shared_Laterality;
+				useLaterality=useLaterality && strlen(useLaterality) ? useLaterality : "U";	// shared and zero length, make it unpaired, no better frame level info available
+			}
+		}
+	}
+	else {
+		useLaterality="U";										// regardless of frame or shared level, it wasn't there
+	}
+	
+//cerr << "makeFrameAnatomySequence: useLaterality " << useLaterality << endl;
+
+	if (useBodyPart && useLaterality) {
+		AttributeList *iFrameAnatomySequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(FrameAnatomySequence));
+		(*iFrameAnatomySequence)+=makeAnatomicRegionSequenceFromBodyPart(useBodyPart);
+		(*iFrameAnatomySequence)+=new CodeStringAttribute(TagFromName(FrameLaterality),useLaterality);
+		return true;
+	}
+	else {
+		return false;
+	}
+}
+
+static void makeRealWorldValueMappingSequence(AttributeList *functionalGroupsSequence,int frame,
+		int pixelRepresentation,
+		bool encountered_RealWorldValueSlope,double shared_RealWorldValueSlope,double *perFrame_RealWorldValueSlope,
+		bool encountered_RealWorldValueIntercept,double shared_RealWorldValueIntercept,double *perFrame_RealWorldValueIntercept,
+		bool encountered_Units,char *shared_Units,char **perFrame_Units,
+		bool encountered_RealWorldValueFirstValueMapped,Uint32 shared_RealWorldValueFirstValueMapped,Uint32 *perFrame_RealWorldValueFirstValueMapped,
+		bool encountered_RealWorldValueLastValueMapped,Uint32 shared_RealWorldValueLastValueMapped,Uint32 *perFrame_RealWorldValueLastValueMapped,
+		bool encountered_LUTExplanation,char *shared_LUTExplanation,char **perFrame_LUTExplanation,
+		bool encountered_LUTLabel,char *shared_LUTLabel,char **perFrame_LUTLabel) {
+//cerr << "makeRealWorldValueMappingSequence" << endl;
+	double useRealWorldValueSlope = perFrame_RealWorldValueSlope
+		? perFrame_RealWorldValueSlope[frame]
+		: (encountered_RealWorldValueSlope ? shared_RealWorldValueSlope : 1.0);
+	double useRealWorldValueIntercept = perFrame_RealWorldValueIntercept
+		? perFrame_RealWorldValueIntercept[frame]
+		: (encountered_RealWorldValueIntercept ? shared_RealWorldValueIntercept : 0.0);
+	const char *useUnits = perFrame_Units
+		? perFrame_Units[frame]
+		: (encountered_Units ? shared_Units : NULL);
+	Uint32 useRealWorldValueFirstValueMapped = perFrame_RealWorldValueFirstValueMapped
+		? perFrame_RealWorldValueFirstValueMapped[frame]
+		: (encountered_RealWorldValueFirstValueMapped ? shared_RealWorldValueFirstValueMapped : 0);
+	Uint32 useRealWorldValueLastValueMapped = perFrame_RealWorldValueLastValueMapped
+		? perFrame_RealWorldValueLastValueMapped[frame]
+		: (encountered_RealWorldValueLastValueMapped ? shared_RealWorldValueLastValueMapped : 0);
+	const char *useLUTExplanation = perFrame_LUTExplanation
+		? perFrame_LUTExplanation[frame]
+		: (encountered_LUTExplanation ? shared_LUTExplanation : "");
+	const char *useLUTLabel = perFrame_LUTLabel
+		? perFrame_LUTLabel[frame]
+		: (encountered_LUTLabel ? shared_LUTLabel : "");
+	
+	if (useUnits != NULL) {		// use the absence of Units as a flag that THIS FRAME has no real world value mapping
+		Assert(functionalGroupsSequence);
+		AttributeList *iRealWorldValueMappingSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(RealWorldValueMappingSequence));
+		
+		(*iRealWorldValueMappingSequence)+=new FloatDoubleAttribute(TagFromName(RealWorldValueIntercept),useRealWorldValueIntercept);
+		(*iRealWorldValueMappingSequence)+=new FloatDoubleAttribute(TagFromName(RealWorldValueSlope),useRealWorldValueSlope);
+		(*iRealWorldValueMappingSequence)+=makeMeasurementUnitsCodeSequence(useUnits);
+		(*iRealWorldValueMappingSequence)+=(pixelRepresentation == 0)
+			? (Attribute *)(new UnsignedShortAttribute(TagFromName(RealWorldValueFirstValueMapped),(Uint16)useRealWorldValueFirstValueMapped))
+			: (Attribute *)(new SignedShortAttribute(TagFromName(RealWorldValueFirstValueMapped),(Int16)useRealWorldValueFirstValueMapped));
+		(*iRealWorldValueMappingSequence)+=(pixelRepresentation == 0)
+			? (Attribute *)(new UnsignedShortAttribute(TagFromName(RealWorldValueLastValueMapped),(Uint16)useRealWorldValueLastValueMapped))
+			: (Attribute *)(new SignedShortAttribute(TagFromName(RealWorldValueLastValueMapped),(Int16)useRealWorldValueLastValueMapped));
+		(*iRealWorldValueMappingSequence)+=new LongStringAttribute(TagFromName(LUTExplanation),useLUTExplanation); 
+		(*iRealWorldValueMappingSequence)+=new ShortStringAttribute(TagFromName(LUTLabel),useLUTLabel);
+	}
+}	
+
+static double
+computeAcquisitionDurationInMilliSecondsFromTiming(
+		bool encountered_RepetitionTime,double shared_RepetitionTime,double *perFrame_RepetitionTime,
+		bool encountered_NumberOfAverages,double shared_NumberOfAverages,double *perFrame_NumberOfAverages,
+		bool encountered_AcquisitionMatrix,Uint32 *shared_AcquisitionMatrix,Uint32 **perFrame_AcquisitionMatrix,
+		bool encountered_EchoTrainLength,Uint32 shared_EchoTrainLength,Uint32 *perFrame_EchoTrainLength,
+		bool encountered_ScanningSequence,char **shared_ScanningSequence,char ***perFrame_ScanningSequence,int nValues_ScanningSequence,
+		int frame) {
+	double use_RepetitionTime = encountered_RepetitionTime ? (perFrame_RepetitionTime ? perFrame_RepetitionTime[frame] : shared_RepetitionTime) : 0;
+	double use_NumberOfAverages = encountered_NumberOfAverages ? (perFrame_NumberOfAverages ? perFrame_NumberOfAverages[frame] : shared_NumberOfAverages) : 0;
+	// Acquisition Matrix contains freq rows\freq cols\phase rows\phase cols
+	Uint32 *use_AcquisitionMatrix = encountered_AcquisitionMatrix ? (perFrame_AcquisitionMatrix ? perFrame_AcquisitionMatrix[frame] : shared_AcquisitionMatrix) : NULL;
+	Uint32 use_frequencyEncodingSteps = use_AcquisitionMatrix ? use_AcquisitionMatrix[0] + use_AcquisitionMatrix[1] : 0;
+	Uint32 use_EchoTrainLength = encountered_EchoTrainLength ? (perFrame_EchoTrainLength ? perFrame_EchoTrainLength[frame] : shared_EchoTrainLength) : 1;
+	char **use_ScanningSequence = encountered_ScanningSequence ? (perFrame_ScanningSequence ? perFrame_ScanningSequence[0] : shared_ScanningSequence) : NULL;
+	bool isEchoPlanar = arrayOfStringValuesContains(use_ScanningSequence,nValues_ScanningSequence,"EP");
+
+//cerr << "computeAcquisitionDurationInMilliSecondsFromTiming: use_frequencyEncodingSteps " << use_frequencyEncodingSteps << endl;
+//cerr << "computeAcquisitionDurationInMilliSecondsFromTiming: use_EchoTrainLength " << use_EchoTrainLength << endl;
+//cerr << "computeAcquisitionDurationInMilliSecondsFromTiming: use_NumberOfAverages " << use_NumberOfAverages << endl;
+//cerr << "computeAcquisitionDurationInMilliSecondsFromTiming: use_RepetitionTime " << use_RepetitionTime << endl;
+
+	return use_RepetitionTime*use_NumberOfAverages*(isEchoPlanar ? 1 : use_frequencyEncodingSteps)/(use_EchoTrainLength == 0 ? 1 : use_EchoTrainLength);
+}
+
+static void makeMRFOVGeometrySequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,const char *requiredMRAcquisitionType,
+		bool encountered_MRAcquisitionPhaseEncodingStepsOutOfPlane,Uint32 shared_MRAcquisitionPhaseEncodingStepsOutOfPlane,Uint32 *perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane,
+		bool encountered_InPlanePhaseEncodingDirection,char *shared_InPlanePhaseEncodingDirection,char **perFrame_InPlanePhaseEncodingDirection,
+		bool encountered_NumberOfPhaseEncodingSteps,Uint32 shared_NumberOfPhaseEncodingSteps,Uint32 *perFrame_NumberOfPhaseEncodingSteps,
+		bool encountered_PercentSampling,double shared_PercentSampling,double *perFrame_PercentSampling,
+		bool encountered_PercentPhaseFieldOfView,double shared_PercentPhaseFieldOfView,double *perFrame_PercentPhaseFieldOfView,
+		bool encountered_AcquisitionMatrix,Uint32 *shared_AcquisitionMatrix,Uint32 **perFrame_AcquisitionMatrix) {
+//cerr << "makeMRFOVGeometrySequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iMRFOVGeometrySequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(MRFOVGeometrySequence));
+	
+	if (treatAsNotOriginalFrame) return;
+	
+	Uint32 matrix_MRAcquisitionPhaseEncodingStepsInPlane = 0;
+	Uint32 matrix_MRAcquisitionFrequencyEncodingSteps = 0;
+	const char *matrix_InPlanePhaseEncodingDirection = "";
+	// Acquisition Matrix contains freq rows\freq cols\phase rows\phase cols
+	Uint32 *use_AcquisitionMatrix = encountered_AcquisitionMatrix ?
+		(perFrame_AcquisitionMatrix ? perFrame_AcquisitionMatrix[frame] : shared_AcquisitionMatrix) : NULL;
+	if (use_AcquisitionMatrix) {
+//cerr << "use_AcquisitionMatrix " << dec << use_AcquisitionMatrix[0] << "," << use_AcquisitionMatrix[1] << "," << use_AcquisitionMatrix[2] << "," << use_AcquisitionMatrix[3] << endl;
+		matrix_MRAcquisitionPhaseEncodingStepsInPlane = use_AcquisitionMatrix[2] + use_AcquisitionMatrix[3];
+		matrix_MRAcquisitionFrequencyEncodingSteps = use_AcquisitionMatrix[0] + use_AcquisitionMatrix[1];
+		if      (use_AcquisitionMatrix[2] > 0 && use_AcquisitionMatrix[3] == 0) matrix_InPlanePhaseEncodingDirection = "ROW";
+		else if (use_AcquisitionMatrix[2] == 0 && use_AcquisitionMatrix[3] > 0) matrix_InPlanePhaseEncodingDirection = "COLUMN";
+	}
+
+	const char *use_InPlanePhaseEncodingDirection = encountered_InPlanePhaseEncodingDirection ?
+		(perFrame_InPlanePhaseEncodingDirection ? perFrame_InPlanePhaseEncodingDirection[frame] : shared_InPlanePhaseEncodingDirection) : "";
+//cerr << "use_InPlanePhaseEncodingDirection " << use_InPlanePhaseEncodingDirection << endl;
+	// New MR object uses COLUMN rather than COL in old MR object
+	if (use_InPlanePhaseEncodingDirection && strcmp(use_InPlanePhaseEncodingDirection,"COL") == 0) use_InPlanePhaseEncodingDirection="COLUMN";
+//cerr << "use_InPlanePhaseEncodingDirection " << use_InPlanePhaseEncodingDirection << endl;
+	if (!use_InPlanePhaseEncodingDirection || !strlen(use_InPlanePhaseEncodingDirection)) use_InPlanePhaseEncodingDirection = matrix_InPlanePhaseEncodingDirection;
+//cerr << "use_InPlanePhaseEncodingDirection " << use_InPlanePhaseEncodingDirection << endl;
+	
+	Uint32 use_MRAcquisitionPhaseEncodingStepsInPlane = encountered_NumberOfPhaseEncodingSteps ?
+		(perFrame_NumberOfPhaseEncodingSteps ? perFrame_NumberOfPhaseEncodingSteps[frame] : shared_NumberOfPhaseEncodingSteps) : Uint32(0);
+//cerr << "use_MRAcquisitionPhaseEncodingStepsInPlane " << dec << use_MRAcquisitionPhaseEncodingStepsInPlane << endl;
+	if (use_MRAcquisitionPhaseEncodingStepsInPlane == 0) use_MRAcquisitionPhaseEncodingStepsInPlane = matrix_MRAcquisitionPhaseEncodingStepsInPlane;
+//cerr << "use_MRAcquisitionPhaseEncodingStepsInPlane " << dec << use_MRAcquisitionPhaseEncodingStepsInPlane << endl;
+	
+	Uint32 use_MRAcquisitionPhaseEncodingStepsOutOfPlane = encountered_MRAcquisitionPhaseEncodingStepsOutOfPlane ?
+		(perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane ? perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane[frame] : shared_MRAcquisitionPhaseEncodingStepsOutOfPlane) : Uint32(0);
+
+	Uint32 use_MRAcquisitionFrequencyEncodingSteps = matrix_MRAcquisitionFrequencyEncodingSteps;		// Nowhere else to get it from :(
+	
+	double use_PercentSampling = encountered_PercentSampling ?
+		(perFrame_PercentSampling ? perFrame_PercentSampling[frame] : shared_PercentSampling) : double(100);
+	double use_PercentPhaseFieldOfView = encountered_PercentPhaseFieldOfView ?
+		(perFrame_PercentPhaseFieldOfView ? perFrame_PercentPhaseFieldOfView[frame] : shared_PercentPhaseFieldOfView) : double(100);
+
+	(*iMRFOVGeometrySequence)+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),use_InPlanePhaseEncodingDirection);
+	(*iMRFOVGeometrySequence)+=new UnsignedShortAttribute(TagFromName(MRAcquisitionFrequencyEncodingSteps),use_MRAcquisitionFrequencyEncodingSteps);
+	(*iMRFOVGeometrySequence)+=new UnsignedShortAttribute(TagFromName(MRAcquisitionPhaseEncodingStepsInPlane),use_MRAcquisitionPhaseEncodingStepsInPlane);
+	if (requiredMRAcquisitionType && strlen(requiredMRAcquisitionType) > 0 && strcmp(requiredMRAcquisitionType,"3D") == 0) {
+		(*iMRFOVGeometrySequence)+=new UnsignedShortAttribute(TagFromName(MRAcquisitionPhaseEncodingStepsOutOfPlane),use_MRAcquisitionPhaseEncodingStepsOutOfPlane);
+	}
+	(*iMRFOVGeometrySequence)+=new DecimalStringAttribute(TagFromName(PercentSampling),use_PercentSampling);
+	(*iMRFOVGeometrySequence)+=new DecimalStringAttribute(TagFromName(PercentPhaseFieldOfView),use_PercentPhaseFieldOfView);
+}
+								
+static void makeMRTimingAndRelatedParametersSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,const char *vEchoPulseSequence,
+		bool encountered_RepetitionTime,double shared_RepetitionTime,double *perFrame_RepetitionTime,
+		bool encountered_FlipAngle,double shared_FlipAngle,double *perFrame_FlipAngle,
+		bool encountered_EchoTrainLength,Uint32 shared_EchoTrainLength,Uint32 *perFrame_EchoTrainLength,
+		bool encountered_RFEchoTrainLength,Uint32 shared_RFEchoTrainLength,Uint32 *perFrame_RFEchoTrainLength,
+		bool encountered_GradientEchoTrainLength,Uint32 shared_GradientEchoTrainLength,Uint32 *perFrame_GradientEchoTrainLength,
+		bool encountered_SAR,double shared_SAR,double *perFrame_SAR,
+		bool encountered_GradientOutputType,char *shared_GradientOutputType,char **perFrame_GradientOutputType,
+		bool encountered_GradientOutput,double shared_GradientOutput,double *perFrame_GradientOutput
+		) {
+//cerr << "makeMRTimingAndRelatedParametersSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iMRTimingAndRelatedParametersSequence = makeNewSequenceAttributeWithItem(
+		functionalGroupsSequence,TagFromName(MRTimingAndRelatedParametersSequence));
+	
+	if (treatAsNotOriginalFrame) return;
+	
+	(*iMRTimingAndRelatedParametersSequence)+=new DecimalStringAttribute(TagFromName(RepetitionTime),
+		perFrame_RepetitionTime ? perFrame_RepetitionTime[frame] : (encountered_RepetitionTime ? shared_RepetitionTime : double(0)));
+	(*iMRTimingAndRelatedParametersSequence)+=new DecimalStringAttribute(TagFromName(FlipAngle),
+		perFrame_FlipAngle ? perFrame_FlipAngle[frame] : (encountered_FlipAngle ? shared_FlipAngle : double(90)));
+		
+	Uint32 use_EchoTrainLength = perFrame_EchoTrainLength ? perFrame_EchoTrainLength[frame] : (encountered_EchoTrainLength ? shared_EchoTrainLength : Uint32(1));
+
+	Uint16 use_RFEchoTrainLength = 0;
+	if (encountered_RFEchoTrainLength) {
+		use_RFEchoTrainLength = perFrame_RFEchoTrainLength ? perFrame_RFEchoTrainLength[frame] : shared_RFEchoTrainLength;
+	}
+	else if (encountered_EchoTrainLength && vEchoPulseSequence && strcmp(vEchoPulseSequence,"SPIN") == 0) {
+		use_RFEchoTrainLength = use_EchoTrainLength;
+	}
+	
+	Uint16 use_GradientEchoTrainLength = 0;
+	if (encountered_GradientEchoTrainLength) {
+		use_GradientEchoTrainLength = perFrame_GradientEchoTrainLength ? perFrame_GradientEchoTrainLength[frame] : shared_GradientEchoTrainLength;
+	}
+	else if (encountered_EchoTrainLength && vEchoPulseSequence && strcmp(vEchoPulseSequence,"GRADIENT") == 0) {
+		use_GradientEchoTrainLength = use_EchoTrainLength;
+	}
+
+	(*iMRTimingAndRelatedParametersSequence)+=new IntegerStringAttribute(TagFromName(EchoTrainLength),use_EchoTrainLength);
+	(*iMRTimingAndRelatedParametersSequence)+=new UnsignedShortAttribute(TagFromName(RFEchoTrainLength),use_RFEchoTrainLength);
+	(*iMRTimingAndRelatedParametersSequence)+=new UnsignedShortAttribute(TagFromName(GradientEchoTrainLength),use_GradientEchoTrainLength);
+								
+	AttributeList *iSpecificAbsorptionRateSequence = makeNewSequenceAttributeWithItem(
+		iMRTimingAndRelatedParametersSequence,TagFromName(SpecificAbsorptionRateSequence));
+	(*iSpecificAbsorptionRateSequence)+=new CodeStringAttribute(TagFromName(SpecificAbsorptionRateDefinition),"IEC_WHOLE_BODY"); // just a guess :(
+	(*iSpecificAbsorptionRateSequence)+=new FloatDoubleAttribute(TagFromName(SpecificAbsorptionRateValue),
+		perFrame_SAR ? perFrame_SAR[frame] : (encountered_SAR ? shared_SAR : double(0)));
+	
+	if (encountered_GradientOutputType || encountered_GradientOutput) {
+		(*iMRTimingAndRelatedParametersSequence)+=new CodeStringAttribute(TagFromName(GradientOutputType),
+			perFrame_GradientOutputType ? perFrame_GradientOutputType[frame] : (encountered_GradientOutputType ? shared_GradientOutputType : ""));
+		(*iMRTimingAndRelatedParametersSequence)+=new FloatDoubleAttribute(TagFromName(GradientOutput),
+			perFrame_GradientOutput ? perFrame_GradientOutput[frame] : (encountered_GradientOutput ? shared_GradientOutput : double(0)));
+	}
+	
+	SequenceAttribute *aOperatingModeSequence=new SequenceAttribute(TagFromName(OperatingModeSequence));
+	Assert(aOperatingModeSequence);
+	(*iMRTimingAndRelatedParametersSequence)+=aOperatingModeSequence;
+	{
+		AttributeList *item = new AttributeList();
+		Assert(item);
+		(*aOperatingModeSequence)+=item;
+		(*item)+=new CodeStringAttribute(TagFromName(OperatingModeType),"STATIC FIELD");
+		(*item)+=new CodeStringAttribute(TagFromName(OperatingMode),"IEC_NORMAL");
+	}
+	{
+		AttributeList *item = new AttributeList();
+		Assert(item);
+		(*aOperatingModeSequence)+=item;
+		(*item)+=new CodeStringAttribute(TagFromName(OperatingModeType),"RF");
+		(*item)+=new CodeStringAttribute(TagFromName(OperatingMode),"IEC_NORMAL");
+	}
+	{
+		AttributeList *item = new AttributeList();
+		Assert(item);
+		(*aOperatingModeSequence)+=item;
+		(*item)+=new CodeStringAttribute(TagFromName(OperatingModeType),"GRADIENT");
+		(*item)+=new CodeStringAttribute(TagFromName(OperatingMode),"IEC_NORMAL");
+	}
+}
+
+static void makeMRModifierSequence(
+		AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_InversionTime,double shared_InversionTime,double *perFrame_InversionTime,
+		bool     isGradientRecalled,
+		bool    isInversionRecovery,
+		bool     isFlowCompensation,
+		bool             isSpoiling,
+		bool isSpatialPresaturation,
+		bool   isPartialFourierFreq,
+		bool  isPartialFourierPhase) {
+//cerr << "makeMRModifierSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iMRModifierSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(MRModifierSequence));
+
+	if (treatAsNotOriginalFrame) return;
+	
+	(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(InversionRecovery),isInversionRecovery ? "YES" : "NO");
+	if (isInversionRecovery && encountered_InversionTime) {
+		(*iMRModifierSequence)+=new FloatDoubleAttribute(TagFromName(InversionTimes),perFrame_InversionTime ? perFrame_InversionTime[frame] : shared_InversionTime);
+	}
+	(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(FlowCompensation),isFlowCompensation ? "OTHER" : "NONE");			// unknown ACCELERATION, VELOCITY
+	if (isFlowCompensation) (*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(FlowCompensationDirection),"OTHER");		// direction unknown
+	if (isGradientRecalled) (*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(Spoiling),isSpoiling ? "GRADIENT" : "NONE");	// unknown RF or RF_AND_GRADIENT
+	(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(T2Preparation),"NO");							// unknown :(
+	(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(SpectrallySelectedExcitation),"NONE");					// unknown :(
+	(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(SpatialPresaturation),isSpatialPresaturation ? "SLAB" : "NONE");
+	{
+		const char *partialFourier;
+		if (isPartialFourierFreq || isPartialFourierPhase) {
+			partialFourier="YES";
+			(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(PartialFourierDirection),
+				isPartialFourierFreq ? (isPartialFourierPhase ? "COMBINATION" : "FREQUENCY") : "PHASE");
+		}
+		else {
+			partialFourier="NO";
+		}
+		(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(PartialFourier),partialFourier);
+	}
+	(*iMRModifierSequence)+=new CodeStringAttribute(TagFromName(ParallelAcquisition),"NO");					// unknown :(
+}
+
+static void makeMRImagingModifierSequence(
+		AttributeList *functionalGroupsSequence,
+		bool treatAsNotOriginalFrame,
+		bool isMagnetizationTransfer,
+		double imagingFrequency,
+		double pixelBandwidth) {
+//cerr << "makeMRImagingModifierSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iMRImagingModifierSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(MRImagingModifierSequence));
+	
+	if (treatAsNotOriginalFrame) return;
+	
+	(*iMRImagingModifierSequence)+=new CodeStringAttribute(TagFromName(MagnetizationTransfer),isMagnetizationTransfer ? "OFF_RESONANCE" : "NONE");	// ON_RESONANCE ?
+	(*iMRImagingModifierSequence)+=new CodeStringAttribute(TagFromName(BloodSignalNulling),"NO");
+	(*iMRImagingModifierSequence)+=new CodeStringAttribute(TagFromName(Tagging),"NONE");
+	(*iMRImagingModifierSequence)+=new FloatDoubleAttribute(TagFromName(TransmitterFrequency),imagingFrequency);
+	(*iMRImagingModifierSequence)+=new DecimalStringAttribute(TagFromName(PixelBandwidth),pixelBandwidth);
+}
+
+static void makeMRDiffusionSequence(
+		AttributeList *functionalGroupsSequence,
+		bool treatAsNotOriginalFrame,
+		double use_DiffusionBValue,
+		const char *use_DiffusionDirectionality) {
+//cerr << "makeMRDiffusionSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iMRDiffusionSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(MRDiffusionSequence));
+	
+	if (treatAsNotOriginalFrame) return;
+	
+	(*iMRDiffusionSequence)+=new FloatDoubleAttribute(TagFromName(DiffusionBValue),use_DiffusionBValue);
+	(*iMRDiffusionSequence)+=new CodeStringAttribute(TagFromName(DiffusionDirectionality),use_DiffusionDirectionality);
+}
+
+static void makeMRVelocityEncodingSequence(
+										   AttributeList *functionalGroupsSequence,
+										   bool treatAsNotOriginalFrame,
+										   double   *useVelocityEncodingDirection,
+										   double useVelocityEncodingMinimumValue,
+										   double useVelocityEncodingMaximumValue) {
+	//cerr << "makeMRVelocityEncodingSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iMRVelocityEncodingSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(MRVelocityEncodingSequence));
+	
+	if (treatAsNotOriginalFrame) return;
+	
+	if (useVelocityEncodingDirection) {
+		(*iMRVelocityEncodingSequence)+=new FloatDoubleAttribute(TagFromName(VelocityEncodingDirection),useVelocityEncodingDirection[0],useVelocityEncodingDirection[1],useVelocityEncodingDirection[2]);
+	}
+	(*iMRVelocityEncodingSequence)+=new FloatDoubleAttribute(TagFromName(VelocityEncodingMinimumValue),useVelocityEncodingMinimumValue);
+	(*iMRVelocityEncodingSequence)+=new FloatDoubleAttribute(TagFromName(VelocityEncodingMaximumValue),useVelocityEncodingMaximumValue);
+}
+
+static void makeVelocityEncodingAcquisitionSequence(AttributeList *list,double *useVelocityEncodingDirection) {
+	//cerr << "makeMRVelocityAcquisitionEncodingSequence" << endl;
+	AttributeList *iVelocityEncodingAcquisitionSequence = makeNewSequenceAttributeWithItem(list,TagFromName(VelocityEncodingAcquisitionSequence));
+	
+	if (useVelocityEncodingDirection) {
+		(*iVelocityEncodingAcquisitionSequence)+=new FloatDoubleAttribute(TagFromName(VelocityEncodingDirection),useVelocityEncodingDirection[0],useVelocityEncodingDirection[1],useVelocityEncodingDirection[2]);
+	}
+}
+
+
+static void makeMRPulseSequenceModule(
+		AttributeList *list,int numberofinputfiles,
+		const char *requiredSequenceName,const char *requiredProtocolName,const char *requiredMRAcquisitionType,
+		bool encountered_ScanningSequence,char **shared_ScanningSequence,char ***perFrame_ScanningSequence,int nValues_ScanningSequence,
+		bool encountered_SequenceVariant,char **shared_SequenceVariant,char ***perFrame_SequenceVariant,int nValues_SequenceVariant,
+		bool encountered_ScanOptions,char **shared_ScanOptions,char ***perFrame_ScanOptions,int nValues_ScanOptions,
+		bool encountered_EchoNumbers,Uint32 shared_EchoNumbers,Uint32 *perFrame_EchoNumbers,
+		bool encountered_VelocityEncodingDirection,double *shared_VelocityEncodingDirection,double **perFrame_VelocityEncodingDirection,
+		bool phaseContrast) {
+//cerr << "makeMRPulseSequenceModule" << endl;
+	Assert(list);
+	(*list)+=new ShortStringAttribute(TagFromName(PulseSequenceName),
+			requiredSequenceName && strlen(requiredSequenceName)
+			? requiredSequenceName
+			: (requiredProtocolName && strlen(requiredProtocolName) ? requiredProtocolName : "UNNAMED"));
+							
+	const char *useMRAcquisitionType = requiredMRAcquisitionType && strlen(requiredMRAcquisitionType) ? requiredMRAcquisitionType : "2D";
+	(*list)+=new CodeStringAttribute(TagFromName(MRAcquisitionType),useMRAcquisitionType);
+	if (strcmp(useMRAcquisitionType,"3D") == 0) 
+		(*list)+=new CodeStringAttribute(TagFromName(CoverageOfKSpace),"FULL");		// nop way to determine ELLIPTICAL, WEIGHTED
+					
+	// choose based on shared Scanning Sequence if possible, otherwise give up and just use first ...
+						
+	char **useScanningSequence = encountered_ScanningSequence ? 
+		(perFrame_ScanningSequence ? perFrame_ScanningSequence[0] : shared_ScanningSequence) : NULL;
+	char **useSequenceVariant = encountered_SequenceVariant ? 
+		(perFrame_SequenceVariant ? perFrame_SequenceVariant[0] : shared_SequenceVariant) : NULL;
+	char **useScanOptions = encountered_ScanOptions ? 
+		(perFrame_ScanOptions ? perFrame_ScanOptions[0] : shared_ScanOptions) : NULL;
+						
+	bool     isSpinEcho       = arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"SE")
+				 || arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"IR");	// ?? but some images have IR alone :(
+	bool isGradientEcho       = arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"GR");
+	bool   isEchoPlanar       = arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"EP");
+	bool isSaturationRecovery = arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"SR");	// not a standard enumerated value
+						
+	bool               isTRSS = arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"TRSS");
+	bool                 isSS = arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"SS");
+	bool    isSegmentedKSpace = arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"SK");
+						
+	bool                 isFS = arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"FS");
+						
+	(*list)+=new CodeStringAttribute(TagFromName(EchoPulseSequence),
+		isSpinEcho ? (isGradientEcho ? "BOTH" : "SPIN") : (isGradientEcho ? "GRADIENT" : "SPIN"));	// spin by default since no other or none :(
+							
+	(*list)+=new CodeStringAttribute(TagFromName(SteadyStatePulseSequence),
+		isTRSS ? "TIME_REVERSED" : (isSS ? "FREE_PRECESSION" : "NONE"));	// can't distinguish FREE_PRECESSION, TRANSVERSE, LONGITUDINAL 
+
+	(*list)+=new CodeStringAttribute(TagFromName(EchoPlanarPulseSequence),isEchoPlanar ? "YES" : "NO");
+	(*list)+=new CodeStringAttribute(TagFromName(SaturationRecovery),isSaturationRecovery ? "YES" : "NO");
+	(*list)+=new CodeStringAttribute(TagFromName(SpectrallySelectedSuppression),isFS ? "FAT" : "NONE");		// can't determine WATER, SILICON_GEL
+						
+	(*list)+=new CodeStringAttribute(TagFromName(SegmentedKSpaceTraversal),isEchoPlanar ? "FULL" : "SINGLE");	// can't determine PARTIAL
+						
+	if (isSpinEcho) {
+		(*list)+=new CodeStringAttribute(TagFromName(MultipleSpinEcho),
+			countDifferentSingleValuedUint32Values(encountered_EchoNumbers,shared_EchoNumbers,perFrame_EchoNumbers,numberofinputfiles) > 1
+			? "YES" : "NO");
+							
+	}
+	(*list)+=new CodeStringAttribute(TagFromName(RectilinearPhaseEncodeReordering),isSegmentedKSpace ? "SEGMENTED" : "LINEAR");
+
+	// Fixed values ... no way to automatically derive these ... :(
+					
+	(*list)+=new CodeStringAttribute(TagFromName(MultiPlanarExcitation),"NO");
+	(*list)+=new CodeStringAttribute(TagFromName(PhaseContrast),phaseContrast ? "YES" : "NO");
+	(*list)+=new CodeStringAttribute(TagFromName(TimeOfFlightContrast),"NO");
+	(*list)+=new CodeStringAttribute(TagFromName(GeometryOfKSpaceTraversal),"RECTILINEAR");
+	(*list)+=new CodeStringAttribute(TagFromName(OversamplingPhase),"NONE");
+	(*list)+=new UnsignedShortAttribute(TagFromName(NumberOfKSpaceTrajectories),Uint32(1));
+	
+	if (phaseContrast && encountered_VelocityEncodingDirection) {
+		double   *useVelocityEncodingDirection = perFrame_VelocityEncodingDirection == NULL ? shared_VelocityEncodingDirection : perFrame_VelocityEncodingDirection[0];
+		if (useVelocityEncodingDirection) {
+			makeVelocityEncodingAcquisitionSequence(list,useVelocityEncodingDirection);
+		}
+	}
+	
+}
+
+static const char* getAcquisitionTypeToUse(int frame,bool encountered_ImageType,char **shared_ImageType,char ***perFrame_ImageType,int nValues_ImageType,
+		bool encountered_AcquisitionType,char *shared_AcquisitionType,char **perFrame_AcquisitionType) {
+	const char *imageTypeValue3 = encountered_ImageType && nValues_ImageType > 2
+		? (perFrame_ImageType && perFrame_ImageType[frame] ? perFrame_ImageType[frame][2] : (shared_ImageType ? shared_ImageType [2] : "")) : "";
+	const char *defaultAcquisitionType = strcmp(imageTypeValue3,"LOCALIZER") == 0 ? "CONSTANT_ANGLE" : "SEQUENCED";
+	const char *useAcquisitionType = perFrame_AcquisitionType ? perFrame_AcquisitionType[frame] : (encountered_AcquisitionType ? shared_AcquisitionType : defaultAcquisitionType);
+	return useAcquisitionType;
+}
+
+static void makeCTAcquisitionTypeSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_ImageType,char **shared_ImageType,char ***perFrame_ImageType,int nValues_ImageType,
+		bool encountered_AcquisitionType,char *shared_AcquisitionType,char **perFrame_AcquisitionType,
+		bool encountered_TubeAngle,double shared_TubeAngle,double *perFrame_TubeAngle,
+		bool encountered_ConstantVolumeFlag,char *shared_ConstantVolumeFlag,char **perFrame_ConstantVolumeFlag,
+		bool encountered_FluoroscopyFlag,char *shared_FluoroscopyFlag,char **perFrame_FluoroscopyFlag) {
+//cerr << "makeCTAcquisitionTypeSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTAcquisitionTypeSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTAcquisitionTypeSequence));
+	if (treatAsNotOriginalFrame) return;
+
+	const char *useAcquisitionType = getAcquisitionTypeToUse(frame,encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+			encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType);
+	(*iCTAcquisitionTypeSequence)+=new CodeStringAttribute(TagFromName(AcquisitionType),useAcquisitionType);
+	if (strcmp(useAcquisitionType,"CONSTANT_ANGLE") == 0) {
+		double useTubeAngle = perFrame_AcquisitionType ? perFrame_TubeAngle[frame] : (encountered_TubeAngle ? shared_TubeAngle : double(0.0));
+		(*iCTAcquisitionTypeSequence)+=new FloatDoubleAttribute(TagFromName(TubeAngle),useTubeAngle);
+	}
+	(*iCTAcquisitionTypeSequence)+=new CodeStringAttribute(TagFromName(ConstantVolumeFlag),
+			perFrame_ConstantVolumeFlag ? perFrame_ConstantVolumeFlag[frame] : (encountered_ConstantVolumeFlag ? shared_ConstantVolumeFlag : "NO"));
+	(*iCTAcquisitionTypeSequence)+=new CodeStringAttribute(TagFromName(FluoroscopyFlag),
+			perFrame_FluoroscopyFlag ? perFrame_FluoroscopyFlag[frame] : (encountered_FluoroscopyFlag ? shared_FluoroscopyFlag : "NO"));
+}
+
+static void makeCTAcquisitionDetailsSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_ImageType,char **shared_ImageType,char ***perFrame_ImageType,int nValues_ImageType,
+		bool encountered_AcquisitionType,char *shared_AcquisitionType,char **perFrame_AcquisitionType,
+		bool encountered_RotationDirection,char *shared_RotationDirection,char **perFrame_RotationDirection,
+		bool encountered_RevolutionTime,double shared_RevolutionTime,double *perFrame_RevolutionTime,
+		bool encountered_SingleCollimationWidth,double shared_SingleCollimationWidth,double *perFrame_SingleCollimationWidth,
+		bool encountered_TotalCollimationWidth,double shared_TotalCollimationWidth,double *perFrame_TotalCollimationWidth,
+		bool encountered_TableHeight,double shared_TableHeight,double *perFrame_TableHeight,
+		bool encountered_GantryDetectorTilt,double shared_GantryDetectorTilt,double *perFrame_GantryDetectorTilt,
+		bool encountered_DataCollectionDiameter,double shared_DataCollectionDiameter,double *perFrame_DataCollectionDiameter) {
+//cerr << "makeCTAcquisitionDetailsSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTAcquisitionDetailsSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTAcquisitionDetailsSequence));
+	if (treatAsNotOriginalFrame) return;
+
+	const char *useAcquisitionType = getAcquisitionTypeToUse(frame,encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+			encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType);
+
+	if (strcmp(useAcquisitionType,"CONSTANT_ANGLE") != 0) {
+		const char *useRotationDirection = perFrame_RotationDirection ? perFrame_RotationDirection[frame] : (encountered_RotationDirection ? shared_RotationDirection : "CW");
+		(*iCTAcquisitionDetailsSequence)+=new CodeStringAttribute(TagFromName(RotationDirection),useRotationDirection);
+		double useRevolutionTime = perFrame_RevolutionTime ? perFrame_RevolutionTime[frame] : (encountered_RevolutionTime ? shared_RevolutionTime : double(0.0));
+		(*iCTAcquisitionDetailsSequence)+=new FloatDoubleAttribute(TagFromName(RevolutionTime),useRevolutionTime);
+	}
+	double useSingleCollimationWidth = perFrame_SingleCollimationWidth ? perFrame_SingleCollimationWidth[frame] : (encountered_SingleCollimationWidth ? shared_SingleCollimationWidth : double(0.0));
+	(*iCTAcquisitionDetailsSequence)+=new FloatDoubleAttribute(TagFromName(SingleCollimationWidth),useSingleCollimationWidth);
+	double useTotalCollimationWidth = perFrame_TotalCollimationWidth ? perFrame_TotalCollimationWidth[frame] : (encountered_TotalCollimationWidth ? shared_TotalCollimationWidth : double(0.0));
+	(*iCTAcquisitionDetailsSequence)+=new FloatDoubleAttribute(TagFromName(TotalCollimationWidth),useTotalCollimationWidth);
+	double useTableHeight = perFrame_TableHeight ? perFrame_TableHeight[frame] : (encountered_TableHeight ? shared_TableHeight : double(0.0));
+	(*iCTAcquisitionDetailsSequence)+=new DecimalStringAttribute(TagFromName(TableHeight),useTableHeight);
+	double useGantryDetectorTilt = perFrame_GantryDetectorTilt ? perFrame_GantryDetectorTilt[frame] : (encountered_GantryDetectorTilt ? shared_GantryDetectorTilt : double(0.0));
+	(*iCTAcquisitionDetailsSequence)+=new DecimalStringAttribute(TagFromName(GantryDetectorTilt),useGantryDetectorTilt);
+	double useDataCollectionDiameter = perFrame_DataCollectionDiameter ? perFrame_DataCollectionDiameter[frame] : (encountered_DataCollectionDiameter ? shared_DataCollectionDiameter : double(0.0));
+	(*iCTAcquisitionDetailsSequence)+=new DecimalStringAttribute(TagFromName(DataCollectionDiameter),useDataCollectionDiameter);
+}
+
+static void makeCTTableDynamicsSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_ImageType,char **shared_ImageType,char ***perFrame_ImageType,int nValues_ImageType,
+		bool encountered_AcquisitionType,char *shared_AcquisitionType,char **perFrame_AcquisitionType,
+		bool encountered_TableSpeed,double shared_TableSpeed,double *perFrame_TableSpeed,
+		bool encountered_TableFeedPerRotation,double shared_TableFeedPerRotation,double *perFrame_TableFeedPerRotation,
+		bool encountered_SpiralPitchFactor,double shared_SpiralPitchFactor,double *perFrame_SpiralPitchFactor) {
+//cerr << "makeCTTableDynamicsSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTTableDynamicsSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTTableDynamicsSequence));
+	if (treatAsNotOriginalFrame) return;
+
+	const char *useAcquisitionType = getAcquisitionTypeToUse(frame,encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+			encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType);
+
+	if (strcmp(useAcquisitionType,"SPIRAL") == 0 || strcmp(useAcquisitionType,"CONSTANT_ANGLE") == 0) {
+		double useTableSpeed = perFrame_TableSpeed ? perFrame_TableSpeed[frame] : (encountered_TableSpeed ? shared_TableSpeed : double(0.0));
+		(*iCTTableDynamicsSequence)+=new FloatDoubleAttribute(TagFromName(TableSpeed),useTableSpeed);
+	}
+	if (strcmp(useAcquisitionType,"SPIRAL") == 0) {
+		double useTableFeedPerRotation = perFrame_TableFeedPerRotation ? perFrame_TableFeedPerRotation[frame] : (encountered_TableFeedPerRotation ? shared_TableFeedPerRotation : double(0.0));
+		(*iCTTableDynamicsSequence)+=new FloatDoubleAttribute(TagFromName(TableFeedPerRotation),useTableFeedPerRotation);
+		double useSpiralPitchFactor = perFrame_SpiralPitchFactor ? perFrame_SpiralPitchFactor[frame] : (encountered_SpiralPitchFactor ? shared_SpiralPitchFactor : double(0.0));
+		(*iCTTableDynamicsSequence)+=new FloatDoubleAttribute(TagFromName(SpiralPitchFactor),useSpiralPitchFactor);
+	}
+}
+
+static void makeCTPositionSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		Uint16 rows,Uint16 columns,
+		double *reference_ImagePositionPatient,	// null if none or shared
+		bool encountered_PatientPosition,char *shared_PatientPosition,char **perFrame_PatientPosition,
+		bool encountered_PixelSpacing,double *shared_PixelSpacing,double **perFrame_PixelSpacing,
+		bool encountered_SliceLocation,double shared_SliceLocation,double *perFrame_SliceLocation,
+		bool encountered_TablePosition,double shared_TablePosition,double *perFrame_TablePosition,
+		bool encountered_ImagePositionPatient,double *shared_ImagePositionPatient,double **perFrame_ImagePositionPatient,
+		bool encountered_ImageOrientationPatient,double *shared_ImageOrientationPatient,double **perFrame_ImageOrientationPatient,
+		bool encountered_DataCollectionCenterPatient,double *shared_DataCollectionCenterPatient,double **perFrame_DataCollectionCenterPatient,
+		bool encountered_ReconstructionTargetCenterPatient,double *shared_ReconstructionTargetCenterPatient,double **perFrame_ReconstructionTargetCenterPatient) {
+//cerr << "makeCTPositionSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTPositionSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTPositionSequence));
+	if (treatAsNotOriginalFrame) return;
+	
+	double *usePixelSpacing = perFrame_PixelSpacing ? perFrame_PixelSpacing[frame] : (encountered_PixelSpacing ? shared_PixelSpacing : NULL);
+	double *useImagePositionPatient = perFrame_ImagePositionPatient ? perFrame_ImagePositionPatient[frame] : (encountered_ImagePositionPatient ? shared_ImagePositionPatient : NULL);
+	double *useImageOrientationPatient = perFrame_ImageOrientationPatient ? perFrame_ImageOrientationPatient[frame] : (encountered_ImageOrientationPatient ? shared_ImageOrientationPatient : NULL);
+
+	double distanceAlongNormal=0.0;
+	if (reference_ImagePositionPatient && useImagePositionPatient && useImageOrientationPatient) {
+		distanceAlongNormal = getDistanceAlongNormalToImagePlane(
+				useImagePositionPatient[0],useImagePositionPatient[1],useImagePositionPatient[2],
+				reference_ImagePositionPatient[0],reference_ImagePositionPatient[1],reference_ImagePositionPatient[2],
+				useImageOrientationPatient[0],useImageOrientationPatient[1],useImageOrientationPatient[2],
+				useImageOrientationPatient[3],useImageOrientationPatient[4],useImageOrientationPatient[5]);
+//cerr << "makeCTPositionSequence: distanceAlongNormal=" << distanceAlongNormal << endl;
+		// In the CT Position Macro, Table Position is defined to be gantry relative,
+		// "Positions as the table moves into the gantry viewed from the front are more negative",
+		// so should correct based on patient vs. gantry position (feet first or head first)
+		char *usePatientPosition = perFrame_PatientPosition ? perFrame_PatientPosition[frame] : (encountered_PatientPosition ? shared_PatientPosition : NULL);
+		if (usePatientPosition && strlen(usePatientPosition) >= 2 && strncmp(usePatientPosition,"FF",2) == 0) {		// first two are always either FF or HF
+			distanceAlongNormal=-distanceAlongNormal;	// change sign if feet first
+//cerr << "makeCTPositionSequence: changed since of distanceAlongNormal since feet first position" << endl;
+		}
+	}
+	
+	double useSliceLocation = perFrame_SliceLocation ? perFrame_SliceLocation[frame] : (encountered_SliceLocation ? shared_SliceLocation : distanceAlongNormal);
+//cerr << "makeCTPositionSequence: useSliceLocation=" << useSliceLocation << endl;
+	double useTablePosition = perFrame_TablePosition ? perFrame_TablePosition[frame] : (encountered_TablePosition ? shared_TablePosition : useSliceLocation);
+//cerr << "makeCTPositionSequence: useTablePosition=" << useTablePosition << endl;
+
+	(*iCTPositionSequence)+=new FloatDoubleAttribute(TagFromName(TablePosition),useTablePosition);
+	
+	double *imageCenter = NULL;
+	if (useImagePositionPatient && useImageOrientationPatient && usePixelSpacing) {
+		imageCenter = new double[3];
+		double centerColumn =  double(columns-1)/2*usePixelSpacing[1];
+		double centerRow =  double(rows-1)/2*usePixelSpacing[0];
+		imageCenter[0] = useImagePositionPatient[0] + useImageOrientationPatient[0]*centerColumn + useImageOrientationPatient[3]*centerRow;
+		imageCenter[1] = useImagePositionPatient[1] + useImageOrientationPatient[1]*centerColumn + useImageOrientationPatient[4]*centerRow;
+		imageCenter[2] = useImagePositionPatient[2] + useImageOrientationPatient[2]*centerColumn + useImageOrientationPatient[5]*centerRow;
+//cerr << "makeCTPositionSequence: usePixelSpacing[0]=" << usePixelSpacing[0] << endl;
+//cerr << "makeCTPositionSequence: usePixelSpacing[1]=" << usePixelSpacing[1] << endl;
+//cerr << "makeCTPositionSequence: useImagePositionPatient[0]=" << useImagePositionPatient[0] << endl;
+//cerr << "makeCTPositionSequence: useImagePositionPatient[1]=" << useImagePositionPatient[1] << endl;
+//cerr << "makeCTPositionSequence: useImagePositionPatient[2]=" << useImagePositionPatient[2] << endl;
+//cerr << "makeCTPositionSequence: useImageOrientationPatient[0]=" << useImageOrientationPatient[0] << endl;
+//cerr << "makeCTPositionSequence: useImageOrientationPatient[1]=" << useImageOrientationPatient[1] << endl;
+//cerr << "makeCTPositionSequence: useImageOrientationPatient[2]=" << useImageOrientationPatient[2] << endl;
+//cerr << "makeCTPositionSequence: useImageOrientationPatient[3]=" << useImageOrientationPatient[3] << endl;
+//cerr << "makeCTPositionSequence: useImageOrientationPatient[4]=" << useImageOrientationPatient[4] << endl;
+//cerr << "makeCTPositionSequence: useImageOrientationPatient[5]=" << useImageOrientationPatient[5] << endl;
+//cerr << "makeCTPositionSequence: imageCenter[0]=" << imageCenter[0] << endl;
+//cerr << "makeCTPositionSequence: imageCenter[1]=" << imageCenter[1] << endl;
+//cerr << "makeCTPositionSequence: imageCenter[2]=" << imageCenter[2] << endl;
+	}
+	
+	double *useReconstructionTargetCenterPatient = perFrame_ReconstructionTargetCenterPatient
+		? perFrame_ReconstructionTargetCenterPatient[frame]
+		: (encountered_ReconstructionTargetCenterPatient ? shared_ReconstructionTargetCenterPatient : imageCenter);
+	if (useReconstructionTargetCenterPatient) {
+		FloatDoubleAttribute *aReconstructionTargetCenterPatient =  new FloatDoubleAttribute(TagFromName(ReconstructionTargetCenterPatient));
+		Assert(aReconstructionTargetCenterPatient);
+		(*iCTPositionSequence)+=aReconstructionTargetCenterPatient;
+		aReconstructionTargetCenterPatient->addValue(useReconstructionTargetCenterPatient[0]);
+		aReconstructionTargetCenterPatient->addValue(useReconstructionTargetCenterPatient[1]);
+		aReconstructionTargetCenterPatient->addValue(useReconstructionTargetCenterPatient[2]);
+//cerr << "makeCTPositionSequence: useReconstructionTargetCenterPatient[0]=" << useReconstructionTargetCenterPatient[0] << endl;
+//cerr << "makeCTPositionSequence: useReconstructionTargetCenterPatient[1]=" << useReconstructionTargetCenterPatient[1] << endl;
+//cerr << "makeCTPositionSequence: useReconstructionTargetCenterPatient[2]=" << useReconstructionTargetCenterPatient[2] << endl;
+	}
+
+	double *useDataCollectionCenterPatient = perFrame_DataCollectionCenterPatient
+		? perFrame_DataCollectionCenterPatient[frame]
+		: (encountered_DataCollectionCenterPatient ? shared_DataCollectionCenterPatient : useReconstructionTargetCenterPatient);
+	if (useDataCollectionCenterPatient) {
+		FloatDoubleAttribute *aDataCollectionCenterPatient =  new FloatDoubleAttribute(TagFromName(DataCollectionCenterPatient));
+		Assert(aDataCollectionCenterPatient);
+		(*iCTPositionSequence)+=aDataCollectionCenterPatient;
+		aDataCollectionCenterPatient->addValue(useDataCollectionCenterPatient[0]);
+		aDataCollectionCenterPatient->addValue(useDataCollectionCenterPatient[1]);
+		aDataCollectionCenterPatient->addValue(useDataCollectionCenterPatient[2]);
+//cerr << "makeCTPositionSequence: useDataCollectionCenterPatient[0]=" << useDataCollectionCenterPatient[0] << endl;
+//cerr << "makeCTPositionSequence: useDataCollectionCenterPatient[1]=" << useDataCollectionCenterPatient[1] << endl;
+//cerr << "makeCTPositionSequence: useDataCollectionCenterPatient[2]=" << useDataCollectionCenterPatient[2] << endl;
+	}
+}		
+		
+static void makeCTGeometrySequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_DistanceSourceToDetector,double shared_DistanceSourceToDetector,double *perFrame_DistanceSourceToDetector,
+		bool encountered_DistanceSourceToDataCollectionCenter,double shared_DistanceSourceToDataCollectionCenter,double *perFrame_DistanceSourceToDataCollectionCenter,
+		bool encountered_DistanceSourceToPatient,double shared_DistanceSourceToPatient,double *perFrame_DistanceSourceToPatient) {
+//cerr << "makeCTGeometrySequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTGeometrySequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTGeometrySequence));
+	if (treatAsNotOriginalFrame) return;
+	
+	double useDistanceSourceToDetector = perFrame_DistanceSourceToDetector ? perFrame_DistanceSourceToDetector[frame] : (encountered_DistanceSourceToDetector ? shared_DistanceSourceToDetector : double(0.0));
+	(*iCTGeometrySequence)+=new DecimalStringAttribute(TagFromName(DistanceSourceToDetector),useDistanceSourceToDetector);
+	double useDistanceSourceToPatient = perFrame_DistanceSourceToPatient ? perFrame_DistanceSourceToPatient[frame] : (encountered_DistanceSourceToPatient ? shared_DistanceSourceToPatient : (useDistanceSourceToDetector/2));
+	double useDistanceSourceToDataCollectionCenter = perFrame_DistanceSourceToDataCollectionCenter ? perFrame_DistanceSourceToDataCollectionCenter[frame] : (encountered_DistanceSourceToDataCollectionCenter ? shared_DistanceSourceToDataCollectionCenter : useDistanceSourceToPatient);
+	(*iCTGeometrySequence)+=new FloatDoubleAttribute(TagFromName(DistanceSourceToDataCollectionCenter),useDistanceSourceToDataCollectionCenter);
+}
+
+static const char *extractConvolutionKernelGroupFromConvolutionKernel(const char *o) {
+	const char *n;
+	if      (strcmp(o,"STANDARD") == 0) n="SOFT_TISSUE";	// GE
+	else if (strcmp(o,"STND") == 0)     n="SOFT_TISSUE";	// GE
+	else if (strcmp(o,"STD+") == 0)     n="SOFT_TISSUE";	// GE
+	else if (strcmp(o,"SOFT") == 0)     n="SOFT_TISSUE";	// GE
+	else if (strcmp(o,"DETAIL") == 0)   n="SOFT_TISSUE";	// GE
+	else if (strcmp(o,"BONE") == 0)     n="BONE";		// GE
+	else if (strcmp(o,"EDGE") == 0)     n="BONE";		// GE
+	else if (strcmp(o,"LUNG") == 0)     n="LUNG";		// GE
+	else if (strlen(o) == 4 && isupper(o[0]) && isdigit(o[1]) && isdigit(o[2]) && islower(o[3])) {	// Siemens e.g., "B35s"
+		if      (o[0] == 'B') n="BONE";
+		else if (o[0] == 'T') n="CONSTANT_ANGLE";
+		else if (o[0] == 'S') n="SOFT_TISSUE";
+		else if (o[0] == 'H') n="BRAIN";
+	}
+	else if (strcmp(o,"CONSTANT_ANGLE") == 0)  n="CONSTANT_ANGLE";		// Ours
+	else if (strcmp(o,"LOCALIZER") == 0)       n="CONSTANT_ANGLE";		// Ours
+	else n=o;
+	return n;
+}
+
+static void makeCTReconstructionSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		Uint16 rows,Uint16 columns,
+		bool encountered_ImageType,char **shared_ImageType,char ***perFrame_ImageType,int nValues_ImageType,
+		bool encountered_AcquisitionType,char *shared_AcquisitionType,char **perFrame_AcquisitionType,
+		bool encountered_PixelSpacing,double *shared_PixelSpacing,double **perFrame_PixelSpacing,
+		bool encountered_ReconstructionAlgorithm,char *shared_ReconstructionAlgorithm,char **perFrame_ReconstructionAlgorithm,
+		bool encountered_ConvolutionKernel,char *shared_ConvolutionKernel,char **perFrame_ConvolutionKernel,
+		bool encountered_ConvolutionKernelGroup,char *shared_ConvolutionKernelGroup,char **perFrame_ConvolutionKernelGroup,
+		bool encountered_ReconstructionDiameter,double shared_ReconstructionDiameter,double *perFrame_ReconstructionDiameter,
+		bool encountered_ReconstructionFieldOfView,double *shared_ReconstructionFieldOfView,double **perFrame_ReconstructionFieldOfView,
+		bool encountered_ReconstructionPixelSpacing,double *shared_ReconstructionPixelSpacing,double **perFrame_ReconstructionPixelSpacing,
+		bool encountered_ReconstructionAngle,double shared_ReconstructionAngle,double *perFrame_ReconstructionAngle,
+		bool encountered_ImageFilter,char *shared_ImageFilter,char **perFrame_ImageFilter) {
+//cerr << "makeCTReconstructionSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTReconstructionSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTReconstructionSequence));
+	if (treatAsNotOriginalFrame) return;
+	
+	const char *useAcquisitionType = getAcquisitionTypeToUse(frame,encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+			encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType);
+
+	const char *useReconstructionAlgorithm = perFrame_ReconstructionAlgorithm ? perFrame_ReconstructionAlgorithm[frame] : (encountered_ReconstructionAlgorithm ? shared_ReconstructionAlgorithm : "ITERATIVE");
+	(*iCTReconstructionSequence)+=new CodeStringAttribute(TagFromName(ReconstructionAlgorithm),useReconstructionAlgorithm);
+
+	const char *defaultConvolutionKernel = strcmp(useAcquisitionType,"CONSTANT_ANGLE") == 0 ? "CONSTANT_ANGLE" : "";
+	const char *useConvolutionKernel = perFrame_ConvolutionKernel ? perFrame_ConvolutionKernel[frame] : (encountered_ConvolutionKernel ? shared_ConvolutionKernel : defaultConvolutionKernel);
+	(*iCTReconstructionSequence)+=new ShortStringAttribute(TagFromName(ConvolutionKernel),useConvolutionKernel);
+	const char *useConvolutionKernelGroup = perFrame_ConvolutionKernelGroup ? perFrame_ConvolutionKernelGroup[frame] : (encountered_ConvolutionKernelGroup ? shared_ConvolutionKernelGroup : 
+		extractConvolutionKernelGroupFromConvolutionKernel(useConvolutionKernel));
+	(*iCTReconstructionSequence)+=new CodeStringAttribute(TagFromName(ConvolutionKernelGroup),useConvolutionKernelGroup);
+
+	double defaultReconstructionAngle = strcmp(useAcquisitionType,"CONSTANT_ANGLE") == 0 ? 0.0 : 360.0;
+	double useReconstructionAngle = perFrame_ReconstructionAngle ? perFrame_ReconstructionAngle[frame] : (encountered_ReconstructionAngle ? shared_ReconstructionAngle : defaultReconstructionAngle);
+	(*iCTReconstructionSequence)+=new FloatDoubleAttribute(TagFromName(ReconstructionAngle),useReconstructionAngle);
+	
+	const char *useImageFilter = perFrame_ImageFilter ? perFrame_ImageFilter[frame] : (encountered_ImageFilter ? shared_ImageFilter : "None");
+	(*iCTReconstructionSequence)+=new ShortStringAttribute(TagFromName(ImageFilter),useImageFilter);
+
+	double useReconstructionDiameter = 0;
+	double useReconstructionFieldOfViewXDimension = 0;
+	double useReconstructionFieldOfViewYDimension = 0;
+	double useReconstructionPixelSpacingXValue = 0;
+	double useReconstructionPixelSpacingYValue = 0;
+	
+	if (encountered_ReconstructionDiameter) {
+		useReconstructionDiameter = perFrame_ReconstructionDiameter ? perFrame_ReconstructionDiameter[frame] : shared_ReconstructionDiameter;
+	}
+	if (encountered_ReconstructionFieldOfView) {
+		double *useReconstructionFieldOfView = perFrame_ReconstructionFieldOfView ? perFrame_ReconstructionFieldOfView[frame] : shared_ReconstructionFieldOfView;
+		useReconstructionFieldOfViewXDimension = useReconstructionFieldOfView[0];
+		useReconstructionFieldOfViewYDimension = useReconstructionFieldOfView[1];
+	}
+	if (encountered_ReconstructionPixelSpacing) {
+		double *useReconstructionPixelSpacing = perFrame_ReconstructionPixelSpacing ? perFrame_ReconstructionPixelSpacing[frame] : shared_ReconstructionPixelSpacing;
+		useReconstructionPixelSpacingYValue = useReconstructionPixelSpacing[0];
+		useReconstructionPixelSpacingXValue = useReconstructionPixelSpacing[1];
+	}
+	if (encountered_PixelSpacing) {
+		double *usePixelSpacing = perFrame_PixelSpacing ? perFrame_PixelSpacing[frame] : shared_PixelSpacing;
+		if (useReconstructionPixelSpacingXValue <= 0 && useReconstructionPixelSpacingYValue <= 0) {
+			useReconstructionPixelSpacingYValue = usePixelSpacing[0];
+			useReconstructionPixelSpacingXValue = usePixelSpacing[1];
+		}
+		if (useReconstructionFieldOfViewXDimension <= 0 && useReconstructionFieldOfViewYDimension <= 0 && useReconstructionDiameter <= 0) {
+			double columnHeightInMM = rows * usePixelSpacing[0];
+			double rowWidthInMM = columns * usePixelSpacing[1];
+			if (columnHeightInMM == rowWidthInMM) {
+				useReconstructionDiameter=columnHeightInMM;
+			}
+			else {
+				useReconstructionFieldOfViewXDimension = rowWidthInMM;
+				useReconstructionFieldOfViewYDimension = columnHeightInMM;
+			}
+		}
+	}
+
+	if (useReconstructionFieldOfViewXDimension > 0 && useReconstructionFieldOfViewYDimension > 0) {
+		FloatDoubleAttribute *aReconstructionFieldOfView =  new FloatDoubleAttribute(TagFromName(ReconstructionFieldOfView));
+		Assert(aReconstructionFieldOfView);
+		(*iCTReconstructionSequence)+=aReconstructionFieldOfView;
+		aReconstructionFieldOfView->addValue(useReconstructionFieldOfViewXDimension);
+		aReconstructionFieldOfView->addValue(useReconstructionFieldOfViewYDimension);
+	}
+	else {
+		(*iCTReconstructionSequence)+=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),useReconstructionDiameter);
+	}
+	{
+		FloatDoubleAttribute *aReconstructionPixelSpacing =  new FloatDoubleAttribute(TagFromName(ReconstructionPixelSpacing));
+		Assert(aReconstructionPixelSpacing);
+		(*iCTReconstructionSequence)+=aReconstructionPixelSpacing;
+		aReconstructionPixelSpacing->addValue(useReconstructionPixelSpacingXValue);
+		aReconstructionPixelSpacing->addValue(useReconstructionPixelSpacingYValue);
+	}
+}
+
+static void makeCTExposureSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_ExposureTime,Uint32 shared_ExposureTime,Uint32 *perFrame_ExposureTime,
+		bool encountered_XRayTubeCurrent,Uint32 shared_XRayTubeCurrent,Uint32 *perFrame_XRayTubeCurrent,
+		bool encountered_Exposure,Uint32 shared_Exposure,Uint32 *perFrame_Exposure,
+		bool encountered_ExposureInuAs,Uint32 shared_ExposureInuAs,Uint32 *perFrame_ExposureInuAs,
+		bool encountered_ExposureTimeInms,double shared_ExposureTimeInms,double *perFrame_ExposureTimeInms,
+		bool encountered_XRayTubeCurrentInmA,double shared_XRayTubeCurrentInmA,double *perFrame_XRayTubeCurrentInmA,
+		bool encountered_ExposureInmAs,double shared_ExposureInmAs,double *perFrame_ExposureInmAs,
+		bool encountered_ExposureModulationType,char *shared_ExposureModulationType,char **perFrame_ExposureModulationType,
+		bool encountered_EstimatedDoseSaving,double shared_EstimatedDoseSaving,double *perFrame_EstimatedDoseSaving,
+		bool encountered_CTDIvol,double shared_CTDIvol,double *perFrame_CTDIvol) {
+//cerr << "makeCTExposureSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTExposureSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTExposureSequence));
+	if (treatAsNotOriginalFrame) return;
+
+	double useExposureTime = (double)(perFrame_ExposureTime ? perFrame_ExposureTime[frame] : (encountered_ExposureTime ? shared_ExposureTime : Uint32(0)));
+	double useXRayTubeCurrent = (double)(perFrame_XRayTubeCurrent ? perFrame_XRayTubeCurrent[frame] : (encountered_XRayTubeCurrent ? shared_XRayTubeCurrent : Uint32(0)));
+	Uint32 useExposure = perFrame_Exposure ? perFrame_Exposure[frame] : (encountered_Exposure ? shared_Exposure : Uint32(0));
+	double useExposureInuAs = (double)(perFrame_ExposureInuAs ? perFrame_ExposureInuAs[frame] : (encountered_ExposureInuAs ? shared_ExposureInuAs : (useExposure*1000)));
+
+	double useExposureTimeInms = perFrame_ExposureTimeInms ? perFrame_ExposureTimeInms[frame] : (encountered_ExposureTimeInms ? shared_ExposureTimeInms : useExposureTime);
+	double useXRayTubeCurrentInmA = perFrame_XRayTubeCurrentInmA ? perFrame_XRayTubeCurrentInmA[frame] : (encountered_XRayTubeCurrentInmA ? shared_XRayTubeCurrentInmA : useXRayTubeCurrent);
+	double useExposureInmAs = perFrame_ExposureInmAs ? perFrame_ExposureInmAs[frame] : (encountered_ExposureInmAs ? shared_ExposureInmAs : (useExposureInuAs/1000.0));
+	
+	(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(ExposureTimeInms),useExposureTimeInms);
+	(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(XRayTubeCurrentInmA),useXRayTubeCurrentInmA);
+	(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(ExposureInmAs),useExposureInmAs);
+
+	const char *useExposureModulationType = perFrame_ExposureModulationType ? perFrame_ExposureModulationType[frame] : (encountered_ExposureModulationType ? shared_ExposureModulationType : "NONE");
+	(*iCTExposureSequence)+=new CodeStringAttribute(TagFromName(ExposureModulationType),useExposureModulationType);
+	
+	if (strcmp(useExposureModulationType,"NONE") != 0) {	// is conditional and may not be present otherwise
+		if (encountered_EstimatedDoseSaving) {
+			double useEstimatedDoseSaving = perFrame_EstimatedDoseSaving ? perFrame_EstimatedDoseSaving[frame] : shared_EstimatedDoseSaving;
+			(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(EstimatedDoseSaving),useEstimatedDoseSaving);
+		}
+		else {
+			(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(EstimatedDoseSaving));	// is Type 2
+		}
+	}
+	if (encountered_CTDIvol) {
+		double useCTDIvol = perFrame_CTDIvol ? perFrame_CTDIvol[frame] : shared_CTDIvol;
+		(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(CTDIvol),useCTDIvol);
+	}
+	else {
+		(*iCTExposureSequence)+=new FloatDoubleAttribute(TagFromName(CTDIvol));				// is Type 2
+	}
+}
+
+static void makeCTXRayDetailsSequence(AttributeList *functionalGroupsSequence,int frame,bool treatAsNotOriginalFrame,
+		bool encountered_KVP,double shared_KVP,double *perFrame_KVP,
+		bool encountered_FocalSpots,double shared_FocalSpots,double *perFrame_FocalSpots,
+		bool encountered_FilterType,char *shared_FilterType,char **perFrame_FilterType,
+		bool encountered_FilterMaterial,char *shared_FilterMaterial,char **perFrame_FilterMaterial) {
+//cerr << "makeCTXRayDetailsSequence" << endl;
+	Assert(functionalGroupsSequence);
+	AttributeList *iCTXRayDetailsSequence = makeNewSequenceAttributeWithItem(functionalGroupsSequence,TagFromName(CTXRayDetailsSequence));
+	if (treatAsNotOriginalFrame) return;
+	
+	double useKVP = perFrame_KVP ? perFrame_KVP[frame] : (encountered_KVP ? shared_KVP : double(0.0));
+	(*iCTXRayDetailsSequence)+=new DecimalStringAttribute(TagFromName(KVP),useKVP);
+	double useFocalSpots = perFrame_FocalSpots ? perFrame_FocalSpots[frame] : (encountered_FocalSpots ? shared_FocalSpots : double(0.0));
+	(*iCTXRayDetailsSequence)+=new DecimalStringAttribute(TagFromName(FocalSpots),useFocalSpots);
+	const char *useFilterType = perFrame_FilterType ? perFrame_FilterType[frame] : (encountered_FilterType ? shared_FilterType : "NONE");
+	(*iCTXRayDetailsSequence)+=new ShortStringAttribute(TagFromName(FilterType),useFilterType);
+	const char *useFilterMaterial = perFrame_FilterMaterial ? perFrame_FilterMaterial[frame] : (encountered_FilterMaterial ? shared_FilterMaterial : "NONE");
+	(*iCTXRayDetailsSequence)+=new CodeStringAttribute(TagFromName(FilterMaterial),useFilterMaterial);
+}
+
+static void makeContrastBolusUsageSequence(AttributeList *functionalGroupsSequence,int frame,
+	bool encountered_ContrastBolusAgent,char **shared_ContrastBolusAgent,char ***perFrame_ContrastBolusAgent,int nValues_ContrastBolusAgent,
+	bool encountered_ContrastBolusRoute,char **shared_ContrastBolusRoute,char ***perFrame_ContrastBolusRoute,int nValues_ContrastBolusRoute,
+	bool encountered_ContrastBolusVolume,char **shared_ContrastBolusVolume,char ***perFrame_ContrastBolusVolume,int nValues_ContrastBolusVolume,
+	bool encountered_ContrastBolusIngredientConcentration,char **shared_ContrastBolusIngredientConcentration,
+		char ***perFrame_ContrastBolusIngredientConcentration,int nValues_ContrastBolusIngredientConcentration,
+	bool encountered_ContrastBolusAgentAdministered,char **shared_ContrastBolusAgentAdministered,
+		char ***perFrame_ContrastBolusAgentAdministered,int nValues_ContrastBolusAgentAdministered,
+	bool encountered_ContrastBolusAgentDetected,char **shared_ContrastBolusAgentDetected,char ***perFrame_ContrastBolusAgentDetected,int nValues_ContrastBolusAgentDetected,
+	bool encountered_ContrastBolusAgentPhase,char **shared_ContrastBolusAgentPhase,char ***perFrame_ContrastBolusAgentPhase,int nValues_ContrastBolusAgentPhase) {
+//cerr << "makeContrastBolusUsageSequence" << endl;
+	if (nValues_ContrastBolusAgent) {
+		Assert(functionalGroupsSequence);
+		SequenceAttribute *aContrastBolusUsageSequence=makeNewSequenceAttributeWithoutItem(functionalGroupsSequence,TagFromName(ContrastBolusUsageSequence));
+		Assert(aContrastBolusUsageSequence);
+		
+		for (int agent=0; agent<nValues_ContrastBolusAgent; ++agent) {
+			AttributeList *itemlist = new AttributeList();
+			Assert(itemlist);
+			(*aContrastBolusUsageSequence)+=itemlist;
+			
+			(*itemlist)+=new UnsignedShortAttribute(TagFromName(ContrastBolusAgentNumber),agent+1);		// DICOM numbers from 1 not 0
+			
+			const char *useContrastBolusRoute = encountered_ContrastBolusRoute && nValues_ContrastBolusRoute > agent
+				? (perFrame_ContrastBolusRoute && perFrame_ContrastBolusRoute[frame]
+					? perFrame_ContrastBolusRoute[frame][agent]
+					: (shared_ContrastBolusRoute
+						? shared_ContrastBolusRoute[agent]
+						: "IV"))
+				: "IV";
+//cerr << "makeContrastBolusUsageSequence: agent=" << agent << " useContrastBolusRoute " << useContrastBolusRoute << endl;
+
+			const char *useContrastBolusAgentAdministered = encountered_ContrastBolusAgentAdministered && nValues_ContrastBolusAgentAdministered > agent
+				? (perFrame_ContrastBolusAgentAdministered && perFrame_ContrastBolusAgentAdministered[frame]
+					? perFrame_ContrastBolusAgentAdministered[frame][agent]
+					: (shared_ContrastBolusAgentAdministered
+						? shared_ContrastBolusAgentAdministered[agent]
+						: "YES"))
+				: "YES";
+//cerr << "makeContrastBolusUsageSequence: agent=" << agent << " useContrastBolusAgentAdministered " << useContrastBolusAgentAdministered << endl;
+			(*itemlist)+=new CodeStringAttribute(TagFromName(ContrastBolusAgentAdministered),useContrastBolusAgentAdministered);
+
+			const char *useContrastBolusAgentDetected = encountered_ContrastBolusAgentDetected && nValues_ContrastBolusAgentDetected > agent
+				? (perFrame_ContrastBolusAgentDetected && perFrame_ContrastBolusAgentDetected[frame]
+					? perFrame_ContrastBolusAgentDetected[frame][agent]
+					: (shared_ContrastBolusAgentDetected
+						? shared_ContrastBolusAgentDetected[agent]
+						: ""))
+				: "";
+//cerr << "makeContrastBolusUsageSequence: agent=" << agent << " useContrastBolusAgentDetected " << useContrastBolusAgentDetected << endl;
+			(*itemlist)+=new CodeStringAttribute(TagFromName(ContrastBolusAgentDetected),useContrastBolusAgentDetected);
+
+			const char *useContrastBolusAgentPhase = encountered_ContrastBolusAgentPhase && nValues_ContrastBolusAgentPhase > agent
+				? (perFrame_ContrastBolusAgentPhase && perFrame_ContrastBolusAgentPhase[frame]
+					? perFrame_ContrastBolusAgentPhase[frame][agent]
+					: (shared_ContrastBolusAgentPhase
+						? shared_ContrastBolusAgentPhase[agent]
+						: ""))
+				: "";
+//cerr << "makeContrastBolusUsageSequence: agent=" << agent << " useContrastBolusAgentPhase " << useContrastBolusAgentPhase << endl;
+
+			if (strcmp(useContrastBolusRoute,"IV") == 0) {
+				(*itemlist)+=new CodeStringAttribute(TagFromName(ContrastBolusAgentPhase),useContrastBolusAgentPhase);
+			}
+		}
+	}
+	// else do not add at all if no contrast
+}
+
+static const char *makeContrastBolusAgentCodeSequenceFromContrastBolusAgentAndReturnIngredient(AttributeList *itemlist,const char *contrastBolusAgent) {
+	const char *csd = 0;
+	const char *cv = 0;
+	const char *cm = 0;
+	const char *ingredient = 0;
+	
+	if (contrastBolusAgent) {
+		if      (findInStringRegardlessOfCase(contrastBolusAgent,"AIR"))		{ ingredient="AIR";        csd="SNM3"; cv="A-80230"; cm="Air"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"O2"))			{ ingredient="OXYGEN";     csd="SNM3"; cv="C-10110"; cm="Oxygen"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"OXYGEN"))		{ ingredient="OXYGEN";     csd="SNM3"; cv="C-10110"; cm="Oxygen"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"WATER"))		{ ingredient="WATER";      csd="SNM3"; cv="C-10120"; cm="Water"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"CO2"))		{ ingredient="CO2";        csd="SNM3"; cv="C-10520"; cm="Carbon dioxide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"CARBON")
+		      && findInStringRegardlessOfCase(contrastBolusAgent,"DIOXIDE"))		{ ingredient="CO2";        csd="SNM3"; cv="C-10520"; cm="Carbon dioxide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"BARIUM"))		{ ingredient="BARIUM";     csd="SNM3"; cv="C-12217"; cm="Barium Sulfate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Gadopentetate"))	{ ingredient="GADOLINIUM"; csd="SRT";  cv="C-B03AA"; cm="Dimeglumine gadopentetate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Magnevist"))		{ ingredient="GADOLINIUM"; csd="SRT";  cv="C-B03AA"; cm="Dimeglumine gadopentetate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Gadodiamide"))	{ ingredient="GADOLINIUM"; csd="SRT";  cv="C-B03C3"; cm="Gadodiamide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Omniscan"))		{ ingredient="GADOLINIUM"; csd="SRT";  cv="C-B03C3"; cm="Gadodiamide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"GAD"))		{ ingredient="GADOLINIUM"; csd="SNM3"; cv="C-17800"; cm="Gadolinium"; }
+		
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Diatrizoate"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Angiovist"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Cardiografin"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Cystografin"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Gastrografin"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Gastrovist"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Hypaque"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Renografin"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Renovist"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Urovist"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0317"; cm="Diatrizoate"; }
+		
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iodipamide"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0318"; cm="Iodipamide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Cholographin"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0318"; cm="Iodipamide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Sinografin"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0318"; cm="Iodipamide"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iodamide"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0326"; cm="Iodamide meglumine"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Renovue"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0326"; cm="Iodamide meglumine"; }
+		
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iopanoic"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0328"; cm="Iopanoic acid"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Telepaque"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0328"; cm="Iopanoic acid"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iophendylate"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0331"; cm="Iophendylate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Pantopaque"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0331"; cm="Iophendylate"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Ipodate"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0335"; cm="Ipodate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Bilivist"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0335"; cm="Ipodate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Oragrafin"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0335"; cm="Ipodate"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Propyliodone"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0337"; cm="Propyliodone"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Dionosil"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0337"; cm="Propyliodone"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Acetrizoate"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0338"; cm="Sodium acetrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Salpix"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0338"; cm="Sodium acetrizoate"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Metrizamide"))	{ ingredient="IODINE";     csd="SNM3"; cv="C-B0348"; cm="Metrizamide"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Amipaque"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0348"; cm="Metrizamide"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iohexol"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0322"; cm="Iohexol"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Omnipaque"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0322"; cm="Iohexol"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iodixanol"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B03BC"; cm="Iodixanol"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Visipaque"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B03BC"; cm="Iodixanol"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iothalamate"))	{ ingredient="IODINE";     csd="SRT";  cv="C-B038B"; cm="Iothalamate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Conray"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B038B"; cm="Iothalamate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Vascoray"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B038B"; cm="Iothalamate"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Ioxaglate"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0339"; cm="Ioxaglate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Hexbrix"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0339"; cm="Ioxaglate"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Metrizoate"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B03C9"; cm="Metrizoate"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Isopaque"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B03C9"; cm="Metrizoate"; }
+
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Iopamidol"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0329"; cm="Iopamidol"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Isovue"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0329"; cm="Iopamidol"; }
+		
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Optiray"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0332"; cm="Ioversol"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"Ioversol"))		{ ingredient="IODINE";     csd="SRT";  cv="C-B0332"; cm="Ioversol"; }
+		
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"non")
+		      && findInStringRegardlessOfCase(contrastBolusAgent,"ionic"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0302"; cm="Non-ionic iodinated contrast agent"; }
+		else if (findInStringRegardlessOfCase(contrastBolusAgent,"ionic"))		{ ingredient="IODINE";     csd="SNM3"; cv="C-B0301"; cm="Ionic iodinated contrast agent"; }
+
+		else										{ ingredient="";           csd="SNM3"; cv="C-B0300"; cm="Contrast agent"; }
+	}
+	
+	addCodeSequenceItemToItemList(itemlist,csd,cv,cm,NULL);
+	return ingredient;
+}
+
+static SequenceAttribute *makeContrastBolusAdministrationRouteSequenceFromContrastBolusRoute(const char *contrastBolusRoute) {
+	SequenceAttribute *aContrastBolusAdministrationRouteSequence=new SequenceAttribute(TagFromName(ContrastBolusAdministrationRouteSequence));
+	Assert(aContrastBolusAdministrationRouteSequence);                                                
+	
+	const char *csd = 0;
+	const char *cv = 0;
+	const char *cm = 0;
+	
+	if (contrastBolusRoute) {
+		if      (findInStringRegardlessOfCase(contrastBolusRoute,"IV"))			{ csd="SNM3"; cv="G-D101"; cm="Intravenous route"; }
+		else if (findInStringRegardlessOfCase(contrastBolusRoute,"ORAL"))		{ csd="SNM3"; cv="G-D140"; cm="Oral route"; }
+		else if (findInStringRegardlessOfCase(contrastBolusRoute,"VAGINAL"))		{ csd="SNM3"; cv="G-D164"; cm="Vaginal route"; }
+		else if (findInStringRegardlessOfCase(contrastBolusRoute,"RECTAL"))		{ csd="SNM3"; cv="G-D160"; cm="Per rectum"; }
+		else if (findInStringRegardlessOfCase(contrastBolusRoute,"INTRATHECAL"))	{ csd="SNM3"; cv="G-D108"; cm="Intrathecal route"; }
+	}
+	
+	addCodeSequenceItemToAttribute(aContrastBolusAdministrationRouteSequence,csd,cv,cm,0);
+
+	return aContrastBolusAdministrationRouteSequence;
+}
+
+static SequenceAttribute *makeContrastBolusIngredientCodeSequenceFromIngredient(const char *ingredient) {
+	SequenceAttribute *aContrastBolusIngredientCodeSequence=new SequenceAttribute(TagFromName(ContrastBolusIngredientCodeSequence));
+	Assert(aContrastBolusIngredientCodeSequence);                                                
+	
+	const char *csd = 0;
+	const char *cv = 0;
+	const char *cm = 0;
+	
+	if (ingredient) {
+		if      (findInStringRegardlessOfCase(ingredient,"IODINE"))	{ csd="SRT"; cv="C-11400"; cm="Iodine"; }
+		else if (findInStringRegardlessOfCase(ingredient,"GADOLINIUM"))	{ csd="SRT"; cv="C-17800"; cm="Gadolinium"; }
+		else if (findInStringRegardlessOfCase(ingredient,"OXYGEN"))	{ csd="SRT"; cv="C-10110"; cm="Oxygen"; }
+		else if (findInStringRegardlessOfCase(ingredient,"CO2"))	{ csd="SRT"; cv="C-10520"; cm="Carbon Dioxide"; }
+		else if (findInStringRegardlessOfCase(ingredient,"BARIUM"))	{ csd="SRT"; cv="C-12200"; cm="Barium"; }
+		else if (findInStringRegardlessOfCase(ingredient,"XENON"))	{ csd="SRT"; cv="C-17200"; cm="Xenon"; }
+		else if (findInStringRegardlessOfCase(ingredient,"WATER"))	{ csd="SRT"; cv="C-10120"; cm="Water"; }
+		else if (findInStringRegardlessOfCase(ingredient,"AIR"))	{ csd="SRT"; cv="A-80230"; cm="Air"; }
+		else if (findInStringRegardlessOfCase(ingredient,"IRON"))	{ csd="SRT"; cv="C-130F9"; cm="Iron"; }
+	}
+
+	addCodeSequenceItemToAttribute(aContrastBolusIngredientCodeSequence,csd,cv,cm,0);
+
+	return aContrastBolusIngredientCodeSequence;
+}
+
+static void makeEnhancedContrastBolusModule(AttributeList *list,
+	bool encountered_ContrastBolusAgent,char **shared_ContrastBolusAgent,char ***perFrame_ContrastBolusAgent,int nValues_ContrastBolusAgent,
+	bool encountered_ContrastBolusRoute,char **shared_ContrastBolusRoute,char ***perFrame_ContrastBolusRoute,int nValues_ContrastBolusRoute,
+	bool encountered_ContrastBolusVolume,char **shared_ContrastBolusVolume,char ***perFrame_ContrastBolusVolume,int nValues_ContrastBolusVolume,
+	bool encountered_ContrastBolusIngredientConcentration,char **shared_ContrastBolusIngredientConcentration,
+		char ***perFrame_ContrastBolusIngredientConcentration,int nValues_ContrastBolusIngredientConcentration) {
+//cerr << "makeEnhancedContrastBolusModule" << endl;
+	if (nValues_ContrastBolusAgent) {
+		Assert(list);
+		SequenceAttribute *aContrastBolusAgentSequence=makeNewSequenceAttributeWithoutItem(list,TagFromName(ContrastBolusAgentSequence));
+		Assert(aContrastBolusAgentSequence);
+		for (int agent=0; agent<nValues_ContrastBolusAgent; ++agent) {
+			AttributeList *itemlist = new AttributeList();
+			Assert(itemlist);
+			(*aContrastBolusAgentSequence)+=itemlist;
+
+			const char *useContrastBolusAgent = encountered_ContrastBolusAgent && nValues_ContrastBolusAgent > agent
+				? (perFrame_ContrastBolusAgent && perFrame_ContrastBolusAgent[0]
+					? perFrame_ContrastBolusAgent[0][agent]
+					: (shared_ContrastBolusAgent
+						? shared_ContrastBolusAgent[agent]
+						: ""))
+				: "";
+//cerr << "makeEnhancedContrastBolusModule: agent=" << agent << " useContrastBolusAgent " << useContrastBolusAgent << endl;
+			const char *ingredient = makeContrastBolusAgentCodeSequenceFromContrastBolusAgentAndReturnIngredient(itemlist,useContrastBolusAgent);
+			
+			(*itemlist)+=new UnsignedShortAttribute(TagFromName(ContrastBolusAgentNumber),agent+1);		// DICOM numbers from 1 not 0
+
+			const char *useContrastBolusRoute = encountered_ContrastBolusRoute && nValues_ContrastBolusRoute > agent
+				? (perFrame_ContrastBolusRoute && perFrame_ContrastBolusRoute[0]
+					? perFrame_ContrastBolusRoute[0][agent]
+					: (shared_ContrastBolusRoute
+						? shared_ContrastBolusRoute[agent]
+						: "IV"))
+				: "IV";
+//cerr << "makeEnhancedContrastBolusModule: agent=" << agent << " useContrastBolusRoute " << useContrastBolusRoute << endl;
+			(*itemlist)+=makeContrastBolusAdministrationRouteSequenceFromContrastBolusRoute(useContrastBolusRoute);
+
+			(*itemlist)+=makeContrastBolusIngredientCodeSequenceFromIngredient(ingredient);
+			
+			const char *useContrastBolusVolume = encountered_ContrastBolusVolume && nValues_ContrastBolusVolume > agent
+				? (perFrame_ContrastBolusVolume && perFrame_ContrastBolusVolume[0]
+					? perFrame_ContrastBolusVolume[0][agent]
+					: (shared_ContrastBolusVolume
+						? shared_ContrastBolusVolume[agent]
+						: ""))
+				: "";
+//cerr << "makeEnhancedContrastBolusModule: agent=" << agent << " useContrastBolusVolume " << useContrastBolusVolume << endl;
+			(*itemlist)+=new DecimalStringAttribute(TagFromName(ContrastBolusVolume),useContrastBolusVolume);
+			
+			const char *useContrastBolusIngredientConcentration = encountered_ContrastBolusIngredientConcentration && nValues_ContrastBolusIngredientConcentration > agent
+				? (perFrame_ContrastBolusIngredientConcentration && perFrame_ContrastBolusIngredientConcentration[0]
+					? perFrame_ContrastBolusIngredientConcentration[0][agent]
+					: (shared_ContrastBolusIngredientConcentration
+						? shared_ContrastBolusIngredientConcentration[agent]
+						: ""))
+				: "";
+//cerr << "makeEnhancedContrastBolusModule: agent=" << agent << " useContrastBolusIngredientConcentration " << useContrastBolusIngredientConcentration << endl;
+			(*itemlist)+=new DecimalStringAttribute(TagFromName(ContrastBolusIngredientConcentration),useContrastBolusIngredientConcentration);
+			//ContrastAdministrationProfileSequence
+		}
+	}
+	// else do not add at all if no contrast
+}
+
+struct StackDescriptor {
+	double *reference_ImagePositionPatient;
+	double *reference_ImageOrientationPatient;
+	double reference_HorizontalFOV;
+	double reference_VerticalFOV;
+	double reference_SliceThickness;
+	double *distancesAlongNormal;
+	int nDistancesAlongNormal;
+};
+
+static bool floatEquals(double a,double b) {
+	return (fabs(a-b)< .001) ? true : false;
+}
+
+static void findFrameInStackDescriptorsOrInsert(int i,int numberofinputfiles,StackDescriptor *tableOfStackDescriptors,int &numberOfStackDescriptors,
+		Uint32 *perFrame_Rows,Uint32 shared_Rows,
+		Uint32 *perFrame_Columns,Uint32 shared_Columns,
+		double **perFrame_ImagePositionPatient,double *shared_ImagePositionPatient,
+		double **perFrame_ImageOrientationPatient,double *shared_ImageOrientationPatient,
+		double *perFrame_SliceThickness,double shared_SliceThickness,
+		double **perFrame_PixelSpacing,double *shared_PixelSpacing,
+		int &useStack,int &useDistance) {
+
+	Uint32 use_Rows = perFrame_Rows ? perFrame_Rows[i] : shared_Rows;
+	Uint32 use_Columns = perFrame_Columns ? perFrame_Columns[i] : shared_Columns;
+	double *use_ImagePositionPatient = perFrame_ImagePositionPatient ? perFrame_ImagePositionPatient[i] : shared_ImagePositionPatient;
+	double *use_ImageOrientationPatient = perFrame_ImageOrientationPatient ? perFrame_ImageOrientationPatient[i] : shared_ImageOrientationPatient;
+	double use_SliceThickness = perFrame_SliceThickness ? perFrame_SliceThickness[i] : shared_SliceThickness;
+	double *use_PixelSpacing = perFrame_PixelSpacing ? perFrame_PixelSpacing[i] : shared_PixelSpacing;
+			
+	Assert(use_ImagePositionPatient);
+	Assert(use_ImageOrientationPatient);
+	Assert(use_PixelSpacing);
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImagePositionPatient[0]=" << use_ImagePositionPatient[0] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImagePositionPatient[1]=" << use_ImagePositionPatient[1] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImagePositionPatient[2]=" << use_ImagePositionPatient[2] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImageOrientationPatient[0]=" << use_ImageOrientationPatient[0] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImageOrientationPatient[1]=" << use_ImageOrientationPatient[1] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImageOrientationPatient[2]=" << use_ImageOrientationPatient[2] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImageOrientationPatient[3]=" << use_ImageOrientationPatient[3] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImageOrientationPatient[4]=" << use_ImageOrientationPatient[4] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_ImageOrientationPatient[5]=" << use_ImageOrientationPatient[5] << endl;
+	double use_VerticalFOV = use_Rows * use_PixelSpacing[0];
+	double use_HorizontalFOV = use_Columns * use_PixelSpacing[1];
+//cerr << "findFrameInStackDescriptorsOrInsert: use_VerticalFOV=" << use_VerticalFOV << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_HorizontalFOV=" << use_HorizontalFOV << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: use_SliceThickness=" << use_SliceThickness << endl;
+	double toleranceWithinPlane = 5.0/100.0 * use_VerticalFOV;	// allow up to 5% jitter (or progressive displacement) in stack
+									// this is sufficient to distinguish side-by-side para-coronal peripheral angio
+									// yet match contiguous lumbar spine para-axials
+	useStack=-1;
+	useDistance;
+	int j;
+	for (j=0; j < numberOfStackDescriptors; ++j) {
+		StackDescriptor *d = tableOfStackDescriptors+j;
+		Assert(d);
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImagePositionPatient[0]=" << d->reference_ImagePositionPatient[0] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImagePositionPatient[1]=" << d->reference_ImagePositionPatient[1] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImagePositionPatient[2]=" << d->reference_ImagePositionPatient[2] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImageOrientationPatient[0]=" << d->reference_ImageOrientationPatient[0] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImageOrientationPatient[1]=" << d->reference_ImageOrientationPatient[1] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImageOrientationPatient[2]=" << d->reference_ImageOrientationPatient[2] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImageOrientationPatient[3]=" << d->reference_ImageOrientationPatient[3] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImageOrientationPatient[4]=" << d->reference_ImageOrientationPatient[4] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_ImageOrientationPatient[5]=" << d->reference_ImageOrientationPatient[5] << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_VerticalFOV=" << d->reference_VerticalFOV << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_HorizontalFOV=" << d->reference_HorizontalFOV << endl;
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] d->reference_SliceThickness=" << d->reference_SliceThickness << endl;
+		if (floatEquals(d->reference_ImageOrientationPatient[0],use_ImageOrientationPatient[0])
+		 && floatEquals(d->reference_ImageOrientationPatient[1],use_ImageOrientationPatient[1])
+		 && floatEquals(d->reference_ImageOrientationPatient[2],use_ImageOrientationPatient[2])
+		 && floatEquals(d->reference_ImageOrientationPatient[3],use_ImageOrientationPatient[3])
+		 && floatEquals(d->reference_ImageOrientationPatient[4],use_ImageOrientationPatient[4])
+		 && floatEquals(d->reference_ImageOrientationPatient[5],use_ImageOrientationPatient[5])
+		 && floatEquals(d->reference_VerticalFOV,use_VerticalFOV)
+		 && floatEquals(d->reference_HorizontalFOV,use_HorizontalFOV)
+		 && floatEquals(d->reference_SliceThickness,use_SliceThickness)
+		 && getDistanceWithinImagePlane(use_ImagePositionPatient[0],use_ImagePositionPatient[1],use_ImagePositionPatient[2],
+				d->reference_ImagePositionPatient[0],d->reference_ImagePositionPatient[1],d->reference_ImagePositionPatient[2],
+				use_ImageOrientationPatient[0],use_ImageOrientationPatient[1],use_ImageOrientationPatient[2],
+				use_ImageOrientationPatient[3],use_ImageOrientationPatient[4],use_ImageOrientationPatient[5]) < toleranceWithinPlane
+		) {
+//cerr << "findFrameInStackDescriptorsOrInsert: [" << j << "] MATCH" << endl;
+			useStack=j;
+			double distanceAlongNormal = getDistanceAlongNormalToImagePlane(
+				use_ImagePositionPatient[0],use_ImagePositionPatient[1],use_ImagePositionPatient[2],
+				d->reference_ImagePositionPatient[0],d->reference_ImagePositionPatient[1],d->reference_ImagePositionPatient[2],
+				use_ImageOrientationPatient[0],use_ImageOrientationPatient[1],use_ImageOrientationPatient[2],
+				use_ImageOrientationPatient[3],use_ImageOrientationPatient[4],use_ImageOrientationPatient[5]);
+			Assert(d->distancesAlongNormal);
+			Assert(d->nDistancesAlongNormal);
+			useDistance=-1;
+			int k;
+			for (k=0; k < d->nDistancesAlongNormal; ++k) {
+				if (d->distancesAlongNormal[k] == distanceAlongNormal) {
+					useDistance=k;
+					break;
+				}
+			}
+			if (useDistance == -1) {
+				useDistance=d->nDistancesAlongNormal++;
+				d->distancesAlongNormal[useDistance]=distanceAlongNormal;
+			}
+			break;
+			}
+	}
+	if (useStack == -1) {
+cerr << "findFrameInStackDescriptorsOrInsert: NO MATCH" << endl;
+		// there was no matching stack, so make a new one ...
+		useStack=numberOfStackDescriptors++;
+		StackDescriptor *d = tableOfStackDescriptors+useStack;
+		// and copy in the values ...
+		d->reference_ImagePositionPatient = new double[3];
+		Assert(d->reference_ImagePositionPatient);
+		d->reference_ImagePositionPatient[0] = use_ImagePositionPatient[0];
+		d->reference_ImagePositionPatient[1] = use_ImagePositionPatient[1];
+		d->reference_ImagePositionPatient[2] = use_ImagePositionPatient[2];
+		d->reference_ImageOrientationPatient = new double[6];
+		Assert(d->reference_ImageOrientationPatient);
+		d->reference_ImageOrientationPatient[0] = use_ImageOrientationPatient[0];
+		d->reference_ImageOrientationPatient[1] = use_ImageOrientationPatient[1];
+		d->reference_ImageOrientationPatient[2] = use_ImageOrientationPatient[2];
+		d->reference_ImageOrientationPatient[3] = use_ImageOrientationPatient[3];
+		d->reference_ImageOrientationPatient[4] = use_ImageOrientationPatient[4];
+		d->reference_ImageOrientationPatient[5] = use_ImageOrientationPatient[5];
+		d->reference_VerticalFOV = use_Rows * use_PixelSpacing[0];
+		d->reference_HorizontalFOV = use_Columns * use_PixelSpacing[1];
+		d->reference_SliceThickness = use_SliceThickness;
+		// and create the first in-stack position entry based on distance along the normal to the plane ...
+		d->distancesAlongNormal=new double[numberofinputfiles];		// probably nothing like numberofinputfiles in-stack positions, but upper bound
+		Assert(d->distancesAlongNormal);
+		useDistance=0;
+		d->nDistancesAlongNormal=1;
+		d->distancesAlongNormal[useDistance]=getDistanceAlongNormalToImagePlane(
+			use_ImagePositionPatient[0],use_ImagePositionPatient[1],use_ImagePositionPatient[2],
+			d->reference_ImagePositionPatient[0],d->reference_ImagePositionPatient[1],d->reference_ImagePositionPatient[2],
+			use_ImageOrientationPatient[0],use_ImageOrientationPatient[1],use_ImageOrientationPatient[2],
+			use_ImageOrientationPatient[3],use_ImageOrientationPatient[4],use_ImageOrientationPatient[5]);
+	}
+//cerr << "Frame " << dec << i << " stack " << useStack << " in-stack position " << useDistance << endl;
+	// values are returned in useStack and useDistance arguments
+}
+
+static int findFrameInTableOfTimesOrInsert(int i,int numberofinputfiles,double *tableOfTimes,int &numberOfTimes,
+		double *perFrame_TriggerTime,double shared_TriggerTime,
+		char **perFrame_AcquisitionTime,char *shared_AcquisitionTime,
+		char **perFrame_AcquisitionDate,char *shared_AcquisitionDate,
+		char **perFrame_ContentTime,char *shared_ContentTime,
+		char **perFrame_ContentDate,char *shared_ContentDate,
+		bool doItWithTriggerTime,bool doItWithAcquisitionTime,bool doItWithAcquisitionTimeAndDate,
+		bool doItWithContentTime,bool doItWithContentTimeAndDate) {
+
+	
+	double useTime=0;
+	if (doItWithTriggerTime) {
+		useTime=perFrame_TriggerTime ? perFrame_TriggerTime[i] : shared_TriggerTime;
+	}
+	else if (doItWithAcquisitionTime) {
+		char *use_AcquisitionTime = perFrame_AcquisitionTime ? perFrame_AcquisitionTime[i] : shared_AcquisitionTime;
+		//if (use_AcquisitionTime) useTime=Uint32(Time(use_AcquisitionTime));
+		if (use_AcquisitionTime) {
+			Time *t = new Time(use_AcquisitionTime);	// there seems to be something funky about allowing Time's to go out of scope :(
+			useTime=*t;
+			if (t) delete t;
+		}
+	}
+	else if (doItWithAcquisitionTimeAndDate) {
+		char *use_AcquisitionTime = perFrame_AcquisitionTime ? perFrame_AcquisitionTime[i] : shared_AcquisitionTime;
+		char *use_AcquisitionDate = perFrame_AcquisitionDate ? perFrame_AcquisitionDate[i] : shared_AcquisitionDate;
+		// date not implemented yet :(
+		//if (use_AcquisitionTime) useTime=Uint32(Time(use_AcquisitionTime));
+		if (use_AcquisitionTime) {
+			Time *t = new Time(use_AcquisitionTime);	// there seems to be something funky about allowing Time's to to go out of scope :(
+			useTime=*t;
+			if (t) delete t;
+		}
+	}
+	else if (doItWithContentTime) {
+		char *use_ContentTime = perFrame_ContentTime ? perFrame_ContentTime[i] : shared_ContentTime;
+		//if (use_ContentTime) useTime=Uint32(Time(use_ContentTime));
+		if (use_ContentTime) {
+			Time *t = new Time(use_ContentTime);	// there seems to be something funky about allowing Time's to go out of scope :(
+			useTime=*t;
+			if (t) delete t;
+		}
+	}
+	else if (doItWithContentTimeAndDate) {
+		char *use_ContentTime = perFrame_ContentTime ? perFrame_ContentTime[i] : shared_ContentTime;
+		char *use_ContentDate = perFrame_ContentDate ? perFrame_ContentDate[i] : shared_ContentDate;
+		// date not implemented yet :(
+		//if (use_ContentTime) useTime=Uint32(Time(use_ContentTime));
+		if (use_ContentTime) {
+			Time *t = new Time(use_ContentTime);	// there seems to be something funky about allowing Time's to to go out of scope :(
+			useTime=*t;
+			if (t) delete t;
+		}
+	}
+	else {
+		Assert(0);
+	}
+			
+	int useTemporalPosition=-1;
+	int j;
+	Assert(tableOfTimes);
+	for (j=0; j < numberOfTimes; ++j) {
+		if (tableOfTimes[j] == useTime) {
+			useTemporalPosition=j;
+			break;
+			}
+	}
+	if (useTemporalPosition == -1) {
+		// there was no matching temporal position, so make a new one ...
+		useTemporalPosition=numberOfTimes++;
+		tableOfTimes[useTemporalPosition]=useTime;
+	}
+	return useTemporalPosition;
+}
+
+
+static int findDoubleInTableOfDoublesOrInsert(double value,double *table,int &tableSize) {
+
+	int found=-1;
+	int j;
+	Assert(table);
+	for (j=0; j < tableSize; ++j) {
+		if (table[j] == value) {
+			found=j;
+			break;
+			}
+	}
+	if (found == -1) {
+		// there was no matching value, so make a new one ...
+		found=tableSize++;
+		table[found]=value;
+	}
+	return found;
+}
+
+static void sortUniqueDimensionValues(int nFrames,int nDimensions,double **dimensionValues,int **dimensionIndices) {
+cerr << "sortUniqueDimensionValues: nDimensions " << nDimensions << " nFrames " << nFrames << endl;
+	for (int d=0; d<nDimensions; ++d) {
+cerr << "sortUniqueDimensionValues: dimension " << d << endl;
+		double *differentDimensionValues = new double[nFrames];	// upper bound
+		Assert(differentDimensionValues);
+		int nDifferentDimensionValues=0;
+		int i;
+		for (i=0; i<nFrames; i++) {
+			double v=dimensionValues[d][i];
+			findDoubleInTableOfDoublesOrInsert(v,differentDimensionValues,nDifferentDimensionValues);
+		}
+		if (nDifferentDimensionValues) {
+cerr << "sortUniqueDimensionValues: dimension " << d << " has nDifferentDimensionValues " << nDifferentDimensionValues << endl;
+			qsort((char *)(differentDimensionValues),nDifferentDimensionValues,sizeof(double),doublecompareascending);
+		}
+		// now copy the frame indices into the dimensionIndices ...
+		for (i=0; i<nFrames; i++) {
+			double v=dimensionValues[d][i];
+			int l = findDoubleInTableOfDoublesOrInsert(v,differentDimensionValues,nDifferentDimensionValues);
+			dimensionIndices[d][i]=l;
+cerr << "sortUniqueDimensionValues: dimension " << d << " frame " << i << " value " << v << " index " << l << endl;
+		}
+		if (differentDimensionValues) delete[] differentDimensionValues;
+	}
+}
+
+
+static void partitionFramesByValuesForDimensions(int nFrames,int d,int nDimensions,double **dimensionValues,int **dimensionIndices,int partitionedSetSize,int *partitionedSet) {
+	double *differentDimensionValues = new double[nFrames];	// upper bound
+	Assert(differentDimensionValues);
+	int nDifferentDimensionValues=0;
+cerr << "partitionFramesByValuesForDimensions: dimension " << d << " partitionedSetSize " << partitionedSetSize << endl;
+	int i;
+	for (i=0; i<partitionedSetSize; i++) {
+		int j=partitionedSet[i];
+		double v=dimensionValues[d][j];
+		findDoubleInTableOfDoublesOrInsert(v,differentDimensionValues,nDifferentDimensionValues);
+	}
+	if (nDifferentDimensionValues) {
+cerr << "partitionFramesByValuesForDimensions: nDifferentDimensionValues " << nDifferentDimensionValues << endl;
+		qsort((char *)(differentDimensionValues),nDifferentDimensionValues,sizeof(double),doublecompareascending);
+		// build new partitions, one for each different value ...
+		int nextd = d+1;
+		int l;
+		for (l=0; l<nDifferentDimensionValues; ++l) {
+			// count how many of this value ...
+			int newPartitionedSetSize=0;
+			for (i=0; i<partitionedSetSize; i++) {
+				double v = dimensionValues[d][partitionedSet[i]];
+				if (l == findDoubleInTableOfDoublesOrInsert(v,differentDimensionValues,nDifferentDimensionValues))
+					++newPartitionedSetSize;
+			}
+cerr << "partitionFramesByValuesForDimensions:  index " << l << " newPartitionedSetSize " << newPartitionedSetSize << endl;
+			int *newPartitionedSet=new int[newPartitionedSetSize];
+			Assert(newPartitionedSet);
+			// now copy the frame indices into the new set ...
+			int next=0;
+			for (i=0; i<partitionedSetSize; i++) {
+				double v = dimensionValues[d][partitionedSet[i]];
+				if (l == findDoubleInTableOfDoublesOrInsert(v,differentDimensionValues,nDifferentDimensionValues)) {
+					newPartitionedSet[next++]=partitionedSet[i];
+					dimensionIndices[d][partitionedSet[i]]=l;
+cerr << "partitionFramesByValuesForDimensions: dimension " << d << " value " << v << " index " << l << endl;
+				}
+			}
+			Assert(next == newPartitionedSetSize);
+			if (nextd < nDimensions) partitionFramesByValuesForDimensions(nFrames,nextd,nDimensions,dimensionValues,dimensionIndices,newPartitionedSetSize,newPartitionedSet);
+			if (newPartitionedSet) delete[] newPartitionedSet;
+		}
+		if (differentDimensionValues) delete[] differentDimensionValues;
+	}
+}
+
+static double
+getNumericValueFromNonNumericAttributeForDimensionSorting(Attribute *a) {
+	double v=0;
+	const char *s = AttributeValue(a);
+	if (a->getTag() == TagFromName(FrameType)) {
+		if (strcmp(s,"ORIGINAL") == 0) v=1;
+		else if (strcmp(s,"DERIVED") == 0) v=2;
+//cerr << "getNumericValueFromNonNumericAttributeForDimensionSorting: FrameType " << s << " = " << v << endl;
+	}
+	else if (a->getTag() == TagFromName(ContrastBolusAgentPhase)) {
+		if (strcmp(s,"PRE_CONTRAST") == 0) v=1;
+		else if (strcmp(s,"IMMEDIATE") == 0) v=2;
+		else if (strcmp(s,"DYNAMIC") == 0) v=3;
+		else if (strcmp(s,"ARTERIAL") == 0) v=4;
+		else if (strcmp(s,"CAPILLARY") == 0) v=5;
+		else if (strcmp(s,"PORTAL_VENOUS") == 0) v=6;
+		else if (strcmp(s,"VENOUS") == 0) v=7;
+		else if (strcmp(s,"STEADY_STATE") == 0) v=8;
+		else if (strcmp(s,"POST_CONTRAST") == 0) v=9;
+		else if (strcmp(s,"DELAYED") == 0) v=10;
+//cerr << "getNumericValueFromNonNumericAttributeForDimensionSorting: ContrastBolusAgentPhase " << s << " = " << v << endl;
+	}
+	else {
+		const char *p = s;
+		bool allDigits = true;
+		while (*p != 0 && allDigits) if (!isdigit(*p++)) allDigits=false;
+		if (allDigits) {
+			v = (s ? strtol(s,NULL,0) : 0);		// e.g. for IDs which are SH VR but usually contain numbers
+//cerr << "getNumericValueFromNonNumericAttributeForDimensionSorting: " << a->getTag() << " all digits value = " << v << endl;
+		}
+		else {
+			// make number based on the numeric ascii values of all the characters
+			p=s;
+			while (*p != 0) {
+				v*=128;
+				v+=toascii(*p++)&0x7f;
+			}
+//cerr << "getNumericValueFromNonNumericAttributeForDimensionSorting: " << a->getTag() << " non digits value = " << v << endl;
+		}
+	}
+	return v;
+}
+						
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool veryveryverbose=options.get("veryveryverbose") || options.get("vvv");
+	if (veryveryverbose) veryverbose=true;
+	if (veryverbose) verbose=true;
+
+	const char *sortbyname;
+	bool sortby=options.get("sortby",sortbyname);
+	Tag sortbytag;
+
+	if (sortby && !staticDictionary.getTag(sortbyname,sortbytag)) {
+		cerr << "Sort tag <" << sortbyname << "> is not a valid data element" << endl;
+		bad=true;
+	}
+
+	bool noMRMultiFrame=options.get("nomrmf");
+
+	bool noCTMultiFrame=options.get("noctmf");
+
+	bool makeStack=options.get("makestack");
+
+	bool descending=options.get("descending");	// should check present only if sortby
+	
+	bool stackdescending=options.get("stackdescending");	// should check present only if  makestack
+	
+	bool addTemporalPosition=options.get("temporalposition");
+
+	bool copyAll=options.get("copyall");
+
+	bool accumulateDuration=options.get("accumulateduration");
+
+	bool deriveDurationFromTiming=options.get("derivedurationfromtiming");
+	
+	bool addNonDerivedStuffAnyway=options.get("addnonderivedstuffanyway");
+
+	bool addPositionStuffAnyway=options.get("addpositionstuffanyway");
+
+	bool addTimingStuffAnyway=options.get("addtimingstuffanyway");
+
+	bool phaseContrast=options.get("phasecontrast");
+
+	bool minimalAttributesOnly=options.get("minimalattributes");
+
+	bool nowindow=options.get("nowindow");
+	
+	bool addEnhancedContrastBolusModuleAndMacro=options.get("enhancedcontrast");
+	
+	bool addSynchronizationModule=options.get("sync");
+
+	bool addSupplementalPaletteColorLUT = false;
+	int addSupplementalPaletteColorLUT_numberOfEntries = 0;
+	int addSupplementalPaletteColorLUT_firstValueMapped = 0;
+	int addSupplementalPaletteColorLUT_firstRedValue = 0;
+	int addSupplementalPaletteColorLUT_incrementRedValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStartIncrementingRedValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStartDecrementingRedValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStopChangingRedValue = 0;
+	int addSupplementalPaletteColorLUT_firstGreenValue = 0;
+	int addSupplementalPaletteColorLUT_incrementGreenValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStartIncrementingGreenValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStartDecrementingGreenValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStopChangingGreenValue = 0;
+	int addSupplementalPaletteColorLUT_firstBlueValue = 0;
+	int addSupplementalPaletteColorLUT_incrementBlueValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStartIncrementingBlueValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStartDecrementingBlueValue = 0;
+	int addSupplementalPaletteColorLUT_entryToStopChangingBlueValue = 0;
+	{
+		int addSupplementalPaletteColorLUTArgs[17];
+		int n = options.get("addcolorlut",addSupplementalPaletteColorLUTArgs,17);
+//cerr << "addSupplementalPaletteColorLUT returns " << dec << n << endl;
+		if (n > 0) {
+			if (n == 17) {
+				addSupplementalPaletteColorLUT=true;
+				addSupplementalPaletteColorLUT_numberOfEntries = addSupplementalPaletteColorLUTArgs[0];
+				addSupplementalPaletteColorLUT_firstValueMapped = addSupplementalPaletteColorLUTArgs[1];
+				
+				addSupplementalPaletteColorLUT_firstRedValue = addSupplementalPaletteColorLUTArgs[2];
+				addSupplementalPaletteColorLUT_incrementRedValue = addSupplementalPaletteColorLUTArgs[3];
+				addSupplementalPaletteColorLUT_entryToStartIncrementingRedValue = addSupplementalPaletteColorLUTArgs[4];
+				addSupplementalPaletteColorLUT_entryToStartDecrementingRedValue = addSupplementalPaletteColorLUTArgs[5];
+				addSupplementalPaletteColorLUT_entryToStopChangingRedValue = addSupplementalPaletteColorLUTArgs[6];
+				
+				addSupplementalPaletteColorLUT_firstGreenValue = addSupplementalPaletteColorLUTArgs[7];
+				addSupplementalPaletteColorLUT_incrementGreenValue = addSupplementalPaletteColorLUTArgs[8];
+				addSupplementalPaletteColorLUT_entryToStartIncrementingGreenValue = addSupplementalPaletteColorLUTArgs[9];
+				addSupplementalPaletteColorLUT_entryToStartDecrementingGreenValue = addSupplementalPaletteColorLUTArgs[10];
+				addSupplementalPaletteColorLUT_entryToStopChangingGreenValue = addSupplementalPaletteColorLUTArgs[11];
+
+				addSupplementalPaletteColorLUT_firstBlueValue = addSupplementalPaletteColorLUTArgs[12];
+				addSupplementalPaletteColorLUT_incrementBlueValue = addSupplementalPaletteColorLUTArgs[13];
+				addSupplementalPaletteColorLUT_entryToStartIncrementingBlueValue = addSupplementalPaletteColorLUTArgs[14];
+				addSupplementalPaletteColorLUT_entryToStartDecrementingBlueValue = addSupplementalPaletteColorLUTArgs[15];
+				addSupplementalPaletteColorLUT_entryToStopChangingBlueValue = addSupplementalPaletteColorLUTArgs[16];
+			}
+			else {
+				cerr << "addcolorlut needs 17 arguments, not " << dec << n << endl;
+				bad=true;
+			}
+		}
+	}
+			
+	bool forceReferencedPerFrame=options.get("perframereference");
+
+	bool addReferenced = false;
+	const char *addReferenced_studyInstanceUID;
+	const char *addReferenced_seriesInstanceUID;
+	const char *addReferenced_referencedSOPClassUID;
+	const char *addReferenced_referencedSOPInstanceUID;
+	const char *addReferenced_referencedFrameNumbers;
+	const char *addReferenced_purposeOfReferenceCodeSequenceCodingSchemeDesignator;
+	const char *addReferenced_purposeOfReferenceCodeSequenceCodeValue;
+	const char *addReferenced_purposeOfReferenceCodeSequenceCodeMeaning;
+	const char *addReferenced_purposeOfReferenceCodeSequenceCodingSchemeVersion;
+	{
+		const char *addReferencedArgs[9];
+		int n = options.get("addreferenced",addReferencedArgs,9);
+//cerr << "addReferenced returns " << dec << n << endl;
+		if (n > 0) {
+			if (n == 9) {
+//cerr << "option: addReferenced: addReferencedArgs[0] " << addReferencedArgs[0] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[1] " << addReferencedArgs[1] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[2] " << addReferencedArgs[2] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[3] " << addReferencedArgs[3] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[4] " << addReferencedArgs[4] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[5] " << addReferencedArgs[5] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[6] " << addReferencedArgs[6] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[7] " << addReferencedArgs[7] << endl;
+//cerr << "option: addReferenced: addReferencedArgs[8] " << addReferencedArgs[8] << endl;
+				addReferenced=true;
+				                                    addReferenced_studyInstanceUID = removeLeadingSpaces(addReferencedArgs[0]);
+				                                   addReferenced_seriesInstanceUID = removeLeadingSpaces(addReferencedArgs[1]);
+				                               addReferenced_referencedSOPClassUID = removeLeadingSpaces(addReferencedArgs[2]);
+				                            addReferenced_referencedSOPInstanceUID = removeLeadingSpaces(addReferencedArgs[3]);
+				                              addReferenced_referencedFrameNumbers = removeLeadingSpaces(addReferencedArgs[4]);
+				addReferenced_purposeOfReferenceCodeSequenceCodingSchemeDesignator = removeLeadingSpaces(addReferencedArgs[5]);
+				             addReferenced_purposeOfReferenceCodeSequenceCodeValue = removeLeadingSpaces(addReferencedArgs[6]);
+				           addReferenced_purposeOfReferenceCodeSequenceCodeMeaning = removeLeadingSpaces(addReferencedArgs[7]);
+				   addReferenced_purposeOfReferenceCodeSequenceCodingSchemeVersion = removeLeadingSpaces(addReferencedArgs[8]);
+			}
+			else {
+				cerr << "addreferenced needs 9 arguments, not " << dec << n << endl;
+				bad=true;
+			}
+		}
+	}
+
+	bool forceDerivationPerFrame=options.get("perframederivation");
+
+	bool addDerivation = false;
+	const char *addDerivation_studyInstanceUID;
+	const char *addDerivation_seriesInstanceUID;
+	const char *addDerivation_referencedSOPClassUID;
+	const char *addDerivation_referencedSOPInstanceUID;
+	const char *addDerivation_referencedFrameNumbers;
+	const char *addDerivation_derivationCodeSequenceCodingSchemeDesignator;
+	const char *addDerivation_derivationCodeSequenceCodeValue;
+	const char *addDerivation_derivationCodeSequenceCodeMeaning;
+	const char *addDerivation_derivationCodeSequenceCodingSchemeVersion;
+	const char *addDerivation_purposeOfReferenceCodeSequenceCodingSchemeDesignator;
+	const char *addDerivation_purposeOfReferenceCodeSequenceCodeValue;
+	const char *addDerivation_purposeOfReferenceCodeSequenceCodeMeaning;
+	const char *addDerivation_purposeOfReferenceCodeSequenceCodingSchemeVersion;
+	{
+		const char *addDerivationArgs[13];
+		int n = options.get("addderivation",addDerivationArgs,13);
+//cerr << "addderivation returns " << dec << n << endl;
+		if (n > 0) {
+			if (n == 13) {
+//cerr << "option: addderivation: addDerivationArgs[0] " << addDerivationArgs[0] << endl;
+//cerr << "option: addderivation: addDerivationArgs[1] " << addDerivationArgs[1] << endl;
+//cerr << "option: addderivation: addDerivationArgs[2] " << addDerivationArgs[2] << endl;
+//cerr << "option: addderivation: addDerivationArgs[3] " << addDerivationArgs[3] << endl;
+//cerr << "option: addderivation: addDerivationArgs[4] " << addDerivationArgs[4] << endl;
+//cerr << "option: addderivation: addDerivationArgs[5] " << addDerivationArgs[5] << endl;
+//cerr << "option: addderivation: addDerivationArgs[6] " << addDerivationArgs[6] << endl;
+//cerr << "option: addderivation: addDerivationArgs[7] " << addDerivationArgs[7] << endl;
+//cerr << "option: addderivation: addDerivationArgs[8] " << addDerivationArgs[8] << endl;
+//cerr << "option: addderivation: addDerivationArgs[9] " << addDerivationArgs[9] << endl;
+//cerr << "option: addderivation: addDerivationArgs[10] " << addDerivationArgs[10] << endl;
+//cerr << "option: addderivation: addDerivationArgs[11] " << addDerivationArgs[11] << endl;
+//cerr << "option: addderivation: addDerivationArgs[12] " << addDerivationArgs[12] << endl;
+				addDerivation=true;
+				                                    addDerivation_studyInstanceUID = removeLeadingSpaces(addDerivationArgs[0]);
+				                                   addDerivation_seriesInstanceUID = removeLeadingSpaces(addDerivationArgs[1]);
+				                               addDerivation_referencedSOPClassUID = removeLeadingSpaces(addDerivationArgs[2]);
+				                            addDerivation_referencedSOPInstanceUID = removeLeadingSpaces(addDerivationArgs[3]);
+				                              addDerivation_referencedFrameNumbers = removeLeadingSpaces(addDerivationArgs[4]);
+				        addDerivation_derivationCodeSequenceCodingSchemeDesignator = removeLeadingSpaces(addDerivationArgs[5]);
+						     addDerivation_derivationCodeSequenceCodeValue = removeLeadingSpaces(addDerivationArgs[6]);
+				                   addDerivation_derivationCodeSequenceCodeMeaning = removeLeadingSpaces(addDerivationArgs[7]);
+				           addDerivation_derivationCodeSequenceCodingSchemeVersion = removeLeadingSpaces(addDerivationArgs[8]);
+				addDerivation_purposeOfReferenceCodeSequenceCodingSchemeDesignator = removeLeadingSpaces(addDerivationArgs[9]);
+				             addDerivation_purposeOfReferenceCodeSequenceCodeValue = removeLeadingSpaces(addDerivationArgs[10]);
+				           addDerivation_purposeOfReferenceCodeSequenceCodeMeaning = removeLeadingSpaces(addDerivationArgs[11]);
+				   addDerivation_purposeOfReferenceCodeSequenceCodingSchemeVersion = removeLeadingSpaces(addDerivationArgs[12]);
+			}
+			else {
+				cerr << "addderivation needs 13 arguments, not " << dec << n << endl;
+				bad=true;
+			}
+		}
+	}
+
+	static const int addSatSlab_maximumNumberOfSlabs = 6;		// i.e. two on each possible side
+	int addSatSlab_numberOfSlabs = 0;
+	double addSatSlab_thickness[addSatSlab_maximumNumberOfSlabs];	
+	double addSatSlab_orientX[addSatSlab_maximumNumberOfSlabs];	
+	double addSatSlab_orientY[addSatSlab_maximumNumberOfSlabs];	
+	double addSatSlab_orientZ[addSatSlab_maximumNumberOfSlabs];	
+	double addSatSlab_midpointX[addSatSlab_maximumNumberOfSlabs];	
+	double addSatSlab_midpointY[addSatSlab_maximumNumberOfSlabs];	
+	double addSatSlab_midpointZ[addSatSlab_maximumNumberOfSlabs];	
+	while (true) {
+		double addSatSlab_Args[7];
+		int n = options.get("addsatslab",addSatSlab_Args,7);
+		if (n < 0) {
+			break;
+		}
+		else {
+			if (n == 7) {
+				Assert(addSatSlab_numberOfSlabs < addSatSlab_maximumNumberOfSlabs);
+				addSatSlab_thickness[addSatSlab_numberOfSlabs] = addSatSlab_Args[0];	
+				  addSatSlab_orientX[addSatSlab_numberOfSlabs] = addSatSlab_Args[1];	
+				  addSatSlab_orientY[addSatSlab_numberOfSlabs] = addSatSlab_Args[2];	
+				  addSatSlab_orientZ[addSatSlab_numberOfSlabs] = addSatSlab_Args[3];	
+				addSatSlab_midpointX[addSatSlab_numberOfSlabs] = addSatSlab_Args[4];	
+				addSatSlab_midpointY[addSatSlab_numberOfSlabs] = addSatSlab_Args[5];	
+				addSatSlab_midpointZ[addSatSlab_numberOfSlabs] = addSatSlab_Args[6];
+				++addSatSlab_numberOfSlabs;
+			}
+			else {
+				cerr << "addsatslab needs 7 arguments, not " << dec << n << endl;
+				bad=true;
+			}
+		}
+	}
+
+	const int MAX_DIMENSION_ORGANIZATIONS = 10;
+	const int MAX_DIMENSIONS = 20;
+	
+	const char ***dimensionIndexNames = NULL;
+	Tag **dimensionIndexPointers = NULL;
+	Tag **dimensionFunctionalGroupPointers = NULL;
+	
+	const char **dimensionOrganizationLabels = NULL;
+	const char **dimensionOrganizationUIDs = NULL;
+	
+	int *nDimensions = NULL;
+	int nDimensionOrganizations = 0;
+
+	{
+		const char *argumentNames[2];
+		
+		int argCount;
+		while ((argCount=options.get("dimension",argumentNames,2)) == 2 || (argCount=options.get("multidimension",argumentNames,4)) == 4) {
+//cerr << "option: dimension or multidimension: argCount " << argCount << endl;
+			const char *indexPointerName = argumentNames[0];
+			const char *functionalGroupPointerName = argumentNames[1];
+//cerr << "option: dimension or multidimension: indexPointerName " << indexPointerName << endl;
+//cerr << "option: dimension or multidimension: functionalGroupPointerName " << functionalGroupPointerName << endl;
+			const char *organizationLabel = argCount == 4 ? argumentNames[2] : NULL;
+			const char *organizationUID =  argCount == 4 ? argumentNames[3] : NULL;
+			
+			if (organizationLabel) {
+				const char *p = organizationLabel;
+				while (*p && isspace(*p)) ++p;
+				if (!*p) organizationLabel=NULL;
+			}
+
+			if (organizationUID) {
+				const char *p = organizationUID;
+				while (*p && isspace(*p)) ++p;
+				if (!*p) organizationUID=NULL;
+			}
+
+			int organizationNumber = argCount ==  2 ? 0 : nDimensionOrganizations;	// forces assumption of new organization unless recognized
+			
+			if (organizationLabel != NULL && nDimensionOrganizations > 0 && dimensionOrganizationLabels != NULL) {
+//cerr << "option: dimension or multidimension: checking for organization with label" << organizationLabel << endl;
+				for (int i=0; i<nDimensionOrganizations; ++i) {
+//cerr << "option: dimension or multidimension: checking organization " << i << endl;
+					if (dimensionOrganizationLabels[i] != NULL && strcmp(organizationLabel,dimensionOrganizationLabels[i]) == 0) {
+//cerr << "option: dimension or multidimension: found organization " << i << endl;
+						organizationNumber=i;
+						break;
+					}
+				}
+			}
+			else if (organizationUID != NULL && nDimensionOrganizations > 0 && dimensionOrganizationUIDs != NULL) {
+//cerr << "option: dimension or multidimension: checking for organization with uid" << organizationUID << endl;
+				for (int i=0; i<nDimensionOrganizations; ++i) {
+//cerr << "option: dimension or multidimension: checking organization " << i << endl;
+					if (dimensionOrganizationUIDs[i] != NULL && strcmp(organizationLabel,dimensionOrganizationUIDs[i]) == 0) {
+						organizationNumber=i;
+//cerr << "option: dimension or multidimension: found organization " << i << endl;
+						break;
+					}
+				}
+			}
+			
+			Tag indexPointerTag;
+			if (!staticDictionary.getTag(indexPointerName,indexPointerTag)) {
+				cerr << "Dimension index pointer <" << indexPointerName << "> is not a valid data element" << endl;
+				bad=true;
+			}
+			Tag functionalGroupPointerTag;
+			if (!staticDictionary.getTag(functionalGroupPointerName,functionalGroupPointerTag)) {
+				cerr << "Dimension functional group pointer <" << functionalGroupPointerName << "> is not a valid data element" << endl;
+				bad=true;
+			}
+			if (!bad) {
+				while (organizationNumber >= nDimensionOrganizations) {
+					if (nDimensionOrganizations < MAX_DIMENSION_ORGANIZATIONS) {
+						if (nDimensionOrganizations == 0) {
+							Assert(dimensionIndexNames == NULL);
+							Assert(dimensionIndexPointers == NULL);
+							Assert(dimensionFunctionalGroupPointers == NULL);
+							Assert(dimensionOrganizationLabels == NULL);
+							Assert(dimensionOrganizationUIDs == NULL);
+							Assert(nDimensions == NULL);
+							dimensionIndexNames=new const char **[MAX_DIMENSION_ORGANIZATIONS];
+							Assert(dimensionIndexNames);
+							dimensionIndexPointers=new Tag *[MAX_DIMENSION_ORGANIZATIONS];
+							Assert(dimensionIndexPointers);
+							dimensionFunctionalGroupPointers=new Tag *[MAX_DIMENSION_ORGANIZATIONS];
+							Assert(dimensionFunctionalGroupPointers);
+							dimensionOrganizationLabels=new const char *[MAX_DIMENSION_ORGANIZATIONS];
+							Assert(dimensionOrganizationLabels);
+							dimensionOrganizationUIDs=new const char *[MAX_DIMENSION_ORGANIZATIONS];
+							Assert(dimensionOrganizationUIDs);
+							nDimensions = new int[MAX_DIMENSION_ORGANIZATIONS];
+							Assert(nDimensions);
+							for (int i=0; i<MAX_DIMENSION_ORGANIZATIONS; ++i) {
+								dimensionIndexNames[i]=NULL;
+								dimensionIndexPointers[i]=NULL;
+								dimensionFunctionalGroupPointers[i]=NULL;
+								dimensionOrganizationLabels[i]=NULL;
+								dimensionOrganizationUIDs[i]=NULL;
+								nDimensions[i]=0;
+							}
+						}
+						++nDimensionOrganizations;
+					}
+					else {
+						cerr << "Exceeded maximum number of dimension organizations supported (" << MAX_DIMENSION_ORGANIZATIONS << ") - ignoring <" << indexPointerName << ">" << endl;
+						bad=true;
+					}
+				}
+			}
+			if (!bad) {
+				Assert(organizationNumber < nDimensionOrganizations);
+				int dimensionNumber = nDimensions[organizationNumber];
+				if (dimensionNumber < MAX_DIMENSIONS) {
+					if (dimensionNumber == 0) {
+						Assert(dimensionIndexNames[organizationNumber] == NULL);
+						Assert(dimensionIndexPointers[organizationNumber] == NULL);
+						Assert(dimensionFunctionalGroupPointers[organizationNumber] == NULL);
+						Assert(dimensionOrganizationLabels[organizationNumber] == NULL);
+						Assert(dimensionOrganizationUIDs[organizationNumber] == NULL);
+						
+						dimensionIndexNames[organizationNumber]=new const char *[MAX_DIMENSIONS];
+						Assert(dimensionIndexNames[organizationNumber]);
+						dimensionIndexPointers[organizationNumber]=new Tag[MAX_DIMENSIONS];
+						Assert(dimensionIndexPointers[organizationNumber]);
+						dimensionFunctionalGroupPointers[organizationNumber]=new Tag[MAX_DIMENSIONS];
+						Assert(dimensionFunctionalGroupPointers[organizationNumber]);
+					}
+					dimensionIndexNames[organizationNumber][dimensionNumber]=indexPointerName;
+					dimensionIndexPointers[organizationNumber][dimensionNumber]=indexPointerTag;
+					dimensionFunctionalGroupPointers[organizationNumber][dimensionNumber]=functionalGroupPointerTag;
+					if (dimensionOrganizationLabels[organizationNumber] == NULL) {
+						dimensionOrganizationLabels[organizationNumber]=organizationLabel;
+					}
+					else {
+						if (organizationLabel != NULL && dimensionOrganizationLabels[organizationNumber] != NULL
+						 && strcmp(organizationLabel,dimensionOrganizationLabels[organizationNumber]) != 0) {
+							cerr << "Different label <" << organizationLabel << "> for dimension organization " << organizationNumber
+							     << " was <" << dimensionOrganizationLabels[organizationNumber] << ">" << endl;
+							bad=true;
+						 }
+					}
+					if (dimensionOrganizationUIDs[organizationNumber] == NULL) {
+						dimensionOrganizationUIDs[organizationNumber]=organizationUID;
+					}
+					else {
+						if (organizationUID != NULL && dimensionOrganizationUIDs[organizationNumber] != NULL
+						 && strcmp(organizationUID,dimensionOrganizationUIDs[organizationNumber]) != 0) {
+							cerr << "Different UID <" << organizationUID << "> for dimension organization " << organizationNumber
+							     << " was <" << dimensionOrganizationUIDs[organizationNumber] << ">" << endl;
+							bad=true;
+						 }
+					}
+					nDimensions[organizationNumber]++;
+				}
+				else {
+					cerr << "Exceeded maximum number of dimensions supported (" << MAX_DIMENSIONS << ") - ignoring <" << indexPointerName << ">" << endl;
+					bad=true;
+				}
+			}
+		}
+	}
+	
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	int numberofinputfiles=!options;
+
+	struct sortentry *sortedfilenamestable = new sortentry [numberofinputfiles];
+	Assert(sortedfilenamestable);
+	struct sortentry *ptr = sortedfilenamestable;
+
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		ptr->filename=filename;
+//cerr << "option: filename " << filename << endl;
+		ptr->value=0;			// leave sort value unused
+		++ptr;
+	}
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose|-vvv|-veryveryverbose]"
+			<< " [-sortby elementname [-descending]]"
+			<< " [-nomrmf]"
+			<< " [-noctmf]"
+			<< " [-makestack [-stackdescending]]"
+			<< " [-temporalposition]"
+			<< " [-dimension elementname functionalgroupname]*"
+			<< " [-multidimension elementname functionalgroupname organizationlabel organizationuid]*"
+			<< " [-addreferenced class instance frames|\" \" purposescheme code mng vers [-perframereference]]"
+			<< " [-addderivation class instance frames|\" \" derivationscheme code mng vers purposescheme code mng vers [-perframederivation]]"
+			<< " [-addsatslab thickness orientX orientY orientZ midpointX midpointY midpointZ]"
+			<< " [-addcolorlut numberofentries firstvaluemapped firstred incrred startincrred startdecrred stopred firstgreen incrgreen startincrgreen startdecrgreen stopgreen firstblue incrblue startincrblue startdecrblue stopblue]"
+			<< " [-accumulateduration]"
+			<< " [-derivedurationfromtiming]"
+			<< " [-addnonderivedstuffanyway]"
+			<< " [-addpositionstuffanyway]"
+			<< " [-addtimingstuffanyway]"
+			<< " [-phasecontrast]"
+			<< " [-minimalattributes]"
+			<< " [-nowindow]"
+			<< " [-enhancedcontrast]"
+			<< " [-sync]"
+			<< " [-copyall]"
+			<< " [-irradiationeventuid uid]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	if (sortby) {
+
+		// Make additional pass through images files to get sorttag
+
+		double reference_tlhc_X;	// these are used for ImagePositionPatient only
+		double reference_tlhc_Y;
+		double reference_tlhc_Z;
+		double reference_normal_X;	// these are used for ImageOrientationPatient only
+		double reference_normal_Y;
+		double reference_normal_Z;
+		double reference_normal_length;
+
+		int i;
+		for (i=0; i < numberofinputfiles; ++i) {
+
+			// open and read each image file ...
+
+			const char *filename=sortedfilenamestable[i].filename;
+			Assert(filename);
+			if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+			ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+			ifstream *fstr=new ifstream(filename);
+#endif
+			if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+				cerr << AMsgDC(FileReadOpenFailed);
+				if (filename) cerr <<" - \"" << filename << "\"";
+				success=false;
+				break;
+			}
+
+			DicomInputStream din(*(istream *)fstr,
+				dicom_input_options.transfersyntaxuid,
+				dicom_input_options.usemetaheader);
+
+			ManagedAttributeList list;
+
+			if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+			list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+			if (!list.good()) {
+				log << list.errors()
+				    << EMsgDC(DatasetReadFailed) << endl;
+				success=false;
+				break;
+			}
+
+			// extract sort key attributes value ...
+
+			double value;
+			if (sortbytag == TagFromName(ImagePositionPatient)) {
+				value=getDistanceAlongNormalToImagePlane(i == 0,list,
+					reference_tlhc_X,reference_tlhc_Y,reference_tlhc_Z,
+					filename,log);
+			}
+			else if (sortbytag == TagFromName(ImageOrientationPatient)) {
+				value=getAngleOfNormalToImagePlane(i == 0,list,
+					reference_normal_X,reference_normal_Y,reference_normal_Z,
+					reference_normal_length,filename,log);
+			}
+			else {
+				value=getFloatValueElseError(list,sortbytag,sortbyname,filename,log);
+			}
+
+			sortedfilenamestable[i].value = value;
+
+			// clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+			if (fstr) delete fstr;
+		}
+
+		if (veryverbose) {
+			log << "Before sorting" << endl;
+			dumpsortedfilenamestable(sortedfilenamestable,numberofinputfiles,sortbyname,log);
+		}
+		qsort((char *)sortedfilenamestable,numberofinputfiles,sizeof(sortentry),
+			descending ? sortentrycomparedescending : sortentrycompareascending);
+
+		if (verbose) {
+			log << "After sorting" << endl;
+			dumpsortedfilenamestable(sortedfilenamestable,numberofinputfiles,sortbyname,log);
+		}
+	}
+
+	if (!success) exit(1);
+
+	int *stackID=NULL;
+	int *inStackPositionNumber=NULL;
+	int *temporalPositionIndex=NULL;
+
+	if (makeStack || addTemporalPosition) {
+
+		// Make additional pass through images files to plan stacks, temporal positions and dimensions
+		
+		// Step 1 - read all image files and track necessary attributes values ...
+		// (and while we are at it, track stuff for deriving temporal position index)
+
+		double reference_tlhc_X;	// these are used for ImagePositionPatient only
+		double reference_tlhc_Y;
+		double reference_tlhc_Z;
+		double reference_normal_X;	// these are used for ImageOrientationPatient only
+		double reference_normal_Y;
+		double reference_normal_Z;
+		double reference_normal_length;
+
+		// Track these for stacks ...
+		
+		bool encountered_Rows = false;
+		bool encountered_Columns = false;
+		bool encountered_ImagePositionPatient = false;
+		bool encountered_ImageOrientationPatient = false;
+		bool encountered_SliceThickness = false;
+		bool encountered_PixelSpacing = false;
+		
+		Uint32 shared_Rows = 0;
+		Uint32 shared_Columns = 0;
+		double *shared_ImagePositionPatient = NULL;
+		double *shared_ImageOrientationPatient = NULL;
+		double shared_SliceThickness = 0;
+		double *shared_PixelSpacing = NULL;
+		
+		Uint32 *perFrame_Rows = 0;
+		Uint32 *perFrame_Columns = 0;
+		double **perFrame_ImagePositionPatient = NULL;
+		double **perFrame_ImageOrientationPatient = NULL;
+		double *perFrame_SliceThickness = NULL;
+		double **perFrame_PixelSpacing = NULL;
+		
+		// Track these for temporal position index ...
+		
+		bool encountered_AcquisitionDate = false;
+		bool encountered_AcquisitionTime = false;
+		bool encountered_ContentDate = false;
+		bool encountered_ContentTime = false;
+		bool encountered_TriggerTime = false;
+		bool encountered_TemporalPositionIndex = false;
+        
+		char *shared_AcquisitionDate = NULL;
+		char *shared_AcquisitionTime = NULL;
+		char *shared_ContentDate = NULL;
+		char *shared_ContentTime = NULL;
+		double shared_TriggerTime = 0;
+		Uint32 shared_TemporalPositionIndex = 0;
+        
+		char **perFrame_AcquisitionDate = NULL;
+		char **perFrame_AcquisitionTime = NULL;
+		char **perFrame_ContentDate = NULL;
+		char **perFrame_ContentTime = NULL;
+		double *perFrame_TriggerTime = NULL;
+		Uint32 *perFrame_TemporalPositionIndex = NULL;
+
+		int i;
+		for (i=0; i < numberofinputfiles; ++i) {
+
+			// open and read each image file ...
+
+			const char *filename=sortedfilenamestable[i].filename;
+			Assert(filename);
+			if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+			ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+			ifstream *fstr=new ifstream(filename);
+#endif
+			if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+				cerr << AMsgDC(FileReadOpenFailed);
+				if (filename) cerr <<" - \"" << filename << "\"";
+				success=false;
+				break;
+			}
+
+			DicomInputStream din(*(istream *)fstr,
+				dicom_input_options.transfersyntaxuid,
+				dicom_input_options.usemetaheader);
+
+			ManagedAttributeList list;
+
+			if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+			list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+			if (!list.good()) {
+				log << list.errors()
+				    << EMsgDC(DatasetReadFailed) << endl;
+				success=false;
+				break;
+			}
+
+			if (makeStack) {
+				trackSingleValuedUint32AttributePerFrame(list,TagFromName(Rows),"Rows",
+					encountered_Rows,shared_Rows,perFrame_Rows,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedUint32AttributePerFrame(list,TagFromName(Columns),"Columns",
+					encountered_Columns,shared_Columns,perFrame_Columns,
+					numberofinputfiles,i,filename,log);
+
+				trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ImagePositionPatient),"Image Position (Patient)",3,
+					encountered_ImagePositionPatient,shared_ImagePositionPatient,perFrame_ImagePositionPatient,
+					numberofinputfiles,i,filename,log);
+
+				trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ImageOrientationPatient),"Image Orientation (Patient)",6,
+					encountered_ImageOrientationPatient,shared_ImageOrientationPatient,perFrame_ImageOrientationPatient,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(SliceThickness),"Slice Thickness",
+					encountered_SliceThickness,shared_SliceThickness,perFrame_SliceThickness,
+					numberofinputfiles,i,filename,log);
+
+				trackMultiValuedDoubleAttributePerFrame(list,TagFromName(PixelSpacing),"Pixel Spacing",2,
+					encountered_PixelSpacing,shared_PixelSpacing,perFrame_PixelSpacing,
+					numberofinputfiles,i,filename,log);
+			}
+			
+			if (addTemporalPosition) {
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(AcquisitionDate),"Acquisition Date",
+                                        encountered_AcquisitionDate,shared_AcquisitionDate,perFrame_AcquisitionDate,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(AcquisitionTime),"Acquisition Time",
+                                        encountered_AcquisitionTime,shared_AcquisitionTime,perFrame_AcquisitionTime,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ContentDate),"Content Date",
+                                        encountered_ContentDate,shared_ContentDate,perFrame_ContentDate,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ContentTime),"Content Time",
+                                        encountered_ContentTime,shared_ContentTime,perFrame_ContentTime,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TriggerTime),"Trigger Time",
+                                        encountered_TriggerTime,shared_TriggerTime,perFrame_TriggerTime,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedUint32AttributePerFrame(list,TagFromName(TemporalPositionIndex),"Temporal Position Index",
+					encountered_TemporalPositionIndex,shared_TemporalPositionIndex,perFrame_TemporalPositionIndex,
+					numberofinputfiles,i,filename,log);
+			}
+			
+			// clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+			if (fstr) delete fstr;
+		}
+		
+		if (makeStack) {
+		
+			// Step 2 ... scan through attribute values that were tracked for each frame and identify the stacks,
+			// as well as identifying unique in-stack positions (based on distance along the normal to the stack
+			// plane)
+		
+			StackDescriptor *tableOfStackDescriptors = new StackDescriptor[numberofinputfiles];		// probably nothing like numberofinputfiles stacks, but upper bound
+			Assert(tableOfStackDescriptors);
+			int numberOfStackDescriptors = 0;
+			{ int j; for (j=0; j<numberofinputfiles; ++j) tableOfStackDescriptors[j].distancesAlongNormal=NULL; tableOfStackDescriptors[j].nDistancesAlongNormal=0; }
+		
+			for (i=0; i < numberofinputfiles; ++i) {
+				int useStack;
+				int useDistance;
+				findFrameInStackDescriptorsOrInsert(i,numberofinputfiles,tableOfStackDescriptors,numberOfStackDescriptors,
+					perFrame_Rows,shared_Rows,
+					perFrame_Columns,shared_Columns,
+					perFrame_ImagePositionPatient,shared_ImagePositionPatient,
+					perFrame_ImageOrientationPatient,shared_ImageOrientationPatient,
+					perFrame_SliceThickness,shared_SliceThickness,
+					perFrame_PixelSpacing,shared_PixelSpacing,
+					useStack,useDistance);
+//cerr << "Before sort Frame " << dec << i << " stack " << useStack << " in-stack position (unsorted) " << useDistance << endl;
+			}
+		
+			// Step 3 ... for each stack, sort the in-stack positions by distance along the normal
+		
+			if (tableOfStackDescriptors) {
+				int j;
+				for (j=0; j<numberOfStackDescriptors; ++j) {
+					double *distancesAlongNormal = tableOfStackDescriptors[j].distancesAlongNormal;
+					int nDistancesAlongNormal = tableOfStackDescriptors[j].nDistancesAlongNormal;
+					Assert(nDistancesAlongNormal);
+					Assert(distancesAlongNormal);
+		
+					qsort((char *)distancesAlongNormal,nDistancesAlongNormal,sizeof(double),
+						stackdescending ? doublecomparedescending : doublecompareascending);
+				}
+			}
+		
+			// Step 4 ... make another pass through the tracked attribute values, this time assigning a stack identifier
+			// and an in-stack position identifier (based on the implicit location in sorted distancesAlongNormal[])
+
+			stackID = new int[numberofinputfiles];
+			Assert(stackID);
+			inStackPositionNumber = new int[numberofinputfiles];
+			Assert(inStackPositionNumber);
+			for (i=0; i < numberofinputfiles; ++i) {
+				int useStack;
+				int useDistance;
+				findFrameInStackDescriptorsOrInsert(i,numberofinputfiles,tableOfStackDescriptors,numberOfStackDescriptors,
+					perFrame_Rows,shared_Rows,
+					perFrame_Columns,shared_Columns,
+					perFrame_ImagePositionPatient,shared_ImagePositionPatient,
+					perFrame_ImageOrientationPatient,shared_ImageOrientationPatient,
+					perFrame_SliceThickness,shared_SliceThickness,
+					perFrame_PixelSpacing,shared_PixelSpacing,
+					useStack,useDistance);
+//cerr << "After sort Frame " << dec << i << " stack " << useStack << " in-stack position (sorted) " << useDistance << " position " << tableOfStackDescriptors[useStack].distancesAlongNormal[useDistance] << endl;
+					stackID[i]=useStack+1;
+					inStackPositionNumber[i]=useDistance+1;	// standard says these starts from 1
+			}
+
+			// Step 5 - clean up ...
+		
+			if (tableOfStackDescriptors) {
+				// Not numberofinputfiles ... since above numberOfStackDescriptors won't have been initialized !
+				//{ int j; for (j=0; j<numberOfStackDescriptors; ++j)
+				//	if (tableOfStackDescriptors[j].distancesAlongNormal) delete[] tableOfStackDescriptors[j].distancesAlongNormal; }
+				//delete[] tableOfStackDescriptors;
+			}
+		
+			// Left with per frame arrays stackID[] and inStackPositionNumber[] which are used later in building Frame Content Macro
+		}
+		if (addTemporalPosition) {
+			if (encountered_TemporalPositionIndex) {
+				temporalPositionIndex = new int[numberofinputfiles];
+				Assert(temporalPositionIndex);
+				for (i=0; i < numberofinputfiles; ++i) {
+					temporalPositionIndex[i] = perFrame_TemporalPositionIndex ? perFrame_TemporalPositionIndex[i] : shared_TemporalPositionIndex;
+				}
+			}
+			else {
+		
+				// Step 2 ... scan through attribute values that were tracked for each frame and identify the temporal positions
+			
+				bool doItWithTriggerTime = false;
+				bool doItWithAcquisitionTime = false;
+				bool doItWithAcquisitionTimeAndDate = false;
+				bool doItWithContentTime = false;
+				bool doItWithContentTimeAndDate = false;
+
+cerr << "encountered_TriggerTime = " << encountered_TriggerTime << endl;
+cerr << "perFrame_TriggerTime = " << perFrame_TriggerTime << endl;
+cerr << "encountered_AcquisitionTime = " << encountered_AcquisitionTime << endl;
+cerr << "perFrame_AcquisitionTime = " << perFrame_AcquisitionTime << endl;
+cerr << "encountered_AcquisitionDate = " << encountered_AcquisitionDate << endl;
+cerr << "perFrame_AcquisitionDate = " << perFrame_AcquisitionDate << endl;
+cerr << "encountered_ContentTime = " << encountered_ContentTime << endl;
+cerr << "perFrame_ContentTime = " << perFrame_ContentTime << endl;
+cerr << "encountered_ContentDate = " << encountered_ContentDate << endl;
+cerr << "perFrame_ContentDate = " << perFrame_ContentDate << endl;
+			
+				if (encountered_TriggerTime && perFrame_TriggerTime) {
+					// different trigger times available
+					doItWithTriggerTime=true;
+				}
+				else if (encountered_AcquisitionTime && perFrame_AcquisitionTime && (!encountered_AcquisitionDate || !perFrame_AcquisitionDate)) {
+					// different acquisition times available and missing or same date
+					doItWithAcquisitionTime=true;
+				}
+				else if (encountered_AcquisitionTime && encountered_AcquisitionDate && (perFrame_AcquisitionTime || perFrame_AcquisitionDate)) {
+					// both time and date present and either time or date or both vary per frame
+					doItWithAcquisitionTimeAndDate=true;
+				}
+				else if (encountered_ContentTime && perFrame_ContentTime && (!encountered_ContentDate || !perFrame_ContentDate)) {
+					// different content times available and missing or same date
+					doItWithContentTime=true;
+				}
+				else if (encountered_ContentTime && encountered_ContentDate && (perFrame_ContentTime || perFrame_ContentDate)) {
+					// both time and date present and either time or date or both vary per frame
+					doItWithContentTimeAndDate=true;
+				}
+			
+				if (doItWithTriggerTime
+				 || doItWithAcquisitionTime
+				 || doItWithAcquisitionTimeAndDate
+				 || doItWithContentTime
+				 || doItWithContentTimeAndDate) {
+					double *tableOfTimes = new double[numberofinputfiles];		// probably nothing like numberofinputfiles temporal positions, but upper bound
+					Assert(tableOfTimes);
+					int numberOfTimes = 0;
+					{ int j; for (j=0; j<numberofinputfiles; ++j) tableOfTimes[j]=0; }
+		
+					for (i=0; i < numberofinputfiles; ++i) {
+						int useTemporalPositionIndex = findFrameInTableOfTimesOrInsert(i,numberofinputfiles,tableOfTimes,numberOfTimes,
+							perFrame_TriggerTime,shared_TriggerTime,
+							perFrame_AcquisitionTime,shared_AcquisitionTime,
+							perFrame_AcquisitionDate,shared_AcquisitionDate,
+							perFrame_ContentTime,shared_ContentTime,
+							perFrame_ContentDate,shared_ContentDate,
+							doItWithTriggerTime,doItWithAcquisitionTime,doItWithAcquisitionTimeAndDate,
+							doItWithContentTime,doItWithContentTimeAndDate);
+//cerr << "Before sort Frame " << dec << i << " useTemporalPositionIndex " << useTemporalPositionIndex << endl;
+					}
+			
+					// Step 3 ... for each temporal position, sort by time
+		
+					qsort((char *)tableOfTimes,numberOfTimes,sizeof(double),doublecompareascending);
+		
+					// Step 4 ... make another pass through the tracked attribute values, this time assigning a
+					// temporal position identifier (based on the implicit location in sorted times table)
+
+					temporalPositionIndex = new int[numberofinputfiles];
+					Assert(temporalPositionIndex);
+					for (i=0; i < numberofinputfiles; ++i) {
+						int useTemporalPositionIndex = findFrameInTableOfTimesOrInsert(i,numberofinputfiles,tableOfTimes,numberOfTimes,
+							perFrame_TriggerTime,shared_TriggerTime,
+							perFrame_AcquisitionTime,shared_AcquisitionTime,
+							perFrame_AcquisitionDate,shared_AcquisitionDate,
+							perFrame_ContentTime,shared_ContentTime,
+							perFrame_ContentDate,shared_ContentDate,
+							doItWithTriggerTime,doItWithAcquisitionTime,doItWithAcquisitionTimeAndDate,
+							doItWithContentTime,doItWithContentTimeAndDate);
+//cerr << "After sort Frame " << dec << i << " useTemporalPositionIndex " << useTemporalPositionIndex << " time " << tableOfTimes[useTemporalPositionIndex] << endl;
+						temporalPositionIndex[i]=useTemporalPositionIndex+1;	// standard (should) say these start from 1
+					}
+
+					// Step 5 - clean up ...
+		
+					if (tableOfTimes) {
+						//delete[] tableOfTimes;
+					}
+					// Left with per frame array temporalPositionIndex[] which is used later in building Frame Content Macro
+				}
+				else {
+					log << "Cannot add temporal position since no times vary per frame" << endl;
+					addTemporalPosition=false;
+				}
+			}
+		}
+	}
+
+	if (!success) exit(1);
+
+        bool useExtraPixelDataWritePass = false;
+        
+        bool addMultiFrameSecondaryCaptureStuff = false;
+        bool addMultiFrameMRStuff = false;
+        bool addMultiFrameCTStuff = false;
+
+	// iterate through image files to extract and check attribute values ...
+ 
+	// attributes required to have constant values for all image files ...
+
+        Uint16 requiredRows;
+        Uint16 requiredColumns;
+        Uint16 requiredBitsAllocated;
+        Uint16 requiredBitsStored;
+        Uint16 requiredHighBit;
+        Uint16 requiredPixelRepresentation;
+        Uint16 requiredSamplesPerPixel;
+        
+	{
+                const char *requiredPatientID;
+                const char *requiredStudyInstanceUID;
+                const char *requiredSeriesInstanceUID;
+                const char *requiredSOPClassUID;
+                const char *requiredPatientName;
+                const char *requiredStudyID;
+                Uint16 requiredSeriesNumber;
+                const char *requiredModality;
+
+                double requiredSliceThickness;
+
+                //Uint16 requiredEchoNumbers;
+                double requiredEchoTime;
+                double requiredRepetitionTime;
+		const char *requiredImagedNucleus;
+		double requiredMagneticFieldStrength;
+                const char *requiredProtocolName;
+                const char *requiredSequenceName;
+                const char *requiredMRAcquisitionType;
+
+                double requiredRescaleSlope;
+                double requiredRescaleIntercept;
+                
+		Uint32 studyIDForUIDGeneration = 0;
+		Uint32 seriesNumberForUIDGeneration = 0;
+		Uint32 instanceNumberForUIDGeneration = 0;
+
+		bool encountered_EchoTime = false;
+		bool encountered_RepetitionTime = false;
+		bool encountered_InversionTime = false;
+		bool encountered_FlipAngle = false;
+		bool encountered_SliceThickness = false;
+		bool encountered_PixelSpacing = false;
+		bool encountered_AcquisitionNumber = false;
+		bool encountered_AcquisitionDate = false;
+		bool encountered_AcquisitionTime = false;
+		bool encountered_AcquisitionDuration = false;
+		bool encountered_ImageComments = false;
+		bool encountered_ImagePositionPatient = false;
+		bool encountered_ImageOrientationPatient = false;
+		bool encountered_TriggerTime = false;
+		bool encountered_NominalCardiacTriggerDelayTime = false;
+		bool encountered_ImageType = false;
+		bool encountered_ContentDate = false;
+		bool encountered_ContentTime = false;
+		bool encountered_ScanningSequence = false;
+		bool encountered_SequenceVariant = false;
+		bool encountered_ScanOptions = false;
+		bool encountered_EchoNumbers = false;
+		bool encountered_BodyPartExamined = false;
+		bool encountered_PatientName = false;
+		bool encountered_StudyDescription = false;
+		bool encountered_SeriesDescription = false;
+		bool encountered_Laterality = false;
+		bool encountered_MRAcquisitionPhaseEncodingStepsOutOfPlane = false;
+		bool encountered_InPlanePhaseEncodingDirection = false;
+		bool encountered_NumberOfPhaseEncodingSteps = false;
+		bool encountered_PercentSampling = false;
+		bool encountered_PercentPhaseFieldOfView = false;
+		bool encountered_ImagingFrequency = false;
+		bool encountered_PixelBandwidth = false;
+		bool encountered_ReceiveCoilName = false;
+		bool encountered_TransmitCoilName = false;
+		bool encountered_Manufacturer = false;
+		bool encountered_NumberOfAverages = false;
+		bool encountered_EchoTrainLength = false;
+		bool encountered_RFEchoTrainLength = false;
+		bool encountered_GradientEchoTrainLength = false;
+		bool encountered_SAR = false;
+		bool encountered_PixelPresentation = false;
+		bool encountered_VolumetricProperties = false;
+		bool encountered_VolumeBasedCalculationTechnique = false;
+		bool encountered_ComplexImageComponent = false;
+		bool encountered_AcquisitionContrast = false;
+		bool encountered_AcquisitionMatrix = false;
+ 		bool encountered_WindowCenter = false;
+ 		bool encountered_WindowWidth = false;
+		bool encountered_WindowCenterWidthExplanation = false;
+ 		bool encountered_DiffusionBValue = false;
+ 		bool encountered_DiffusionDirectionality = false;
+ 		bool encountered_GradientOutput = false;
+ 		bool encountered_GradientOutputType = false;
+ 		bool encountered_RescaleSlope = false;
+ 		bool encountered_RescaleIntercept = false;
+ 		bool encountered_RescaleType = false;
+ 		bool encountered_RealWorldValueSlope = false;
+ 		bool encountered_RealWorldValueIntercept = false;
+ 		bool encountered_Units = false;
+ 		bool encountered_RealWorldValueFirstValueMapped = false;
+ 		bool encountered_RealWorldValueLastValueMapped = false;
+ 		bool encountered_LUTExplanation = false;
+ 		bool encountered_LUTLabel = false;
+ 		bool encountered_VelocityEncodingDirection = false;
+		bool encountered_VelocityEncodingMinimumValue = false;
+		bool encountered_VelocityEncodingMaximumValue = false;
+		bool encountered_MetaboliteMapDescription = false;
+		bool encountered_ChemicalShiftMinimumIntegrationLimitInppm = false;
+		bool encountered_ChemicalShiftMaximumIntegrationLimitInppm = false;
+		bool encountered_AcquisitionType = false;
+		bool encountered_TubeAngle = false;
+		bool encountered_ConstantVolumeFlag = false;
+		bool encountered_FluoroscopyFlag = false;
+		bool encountered_RotationDirection = false;
+		bool encountered_RevolutionTime = false;
+		bool encountered_SingleCollimationWidth = false;
+		bool encountered_TotalCollimationWidth = false;
+		bool encountered_TableHeight = false;
+		bool encountered_GantryDetectorTilt = false;
+		bool encountered_DataCollectionDiameter = false;
+		bool encountered_TableSpeed = false;
+		bool encountered_TableFeedPerRotation = false;
+		bool encountered_SpiralPitchFactor = false;
+		bool encountered_SliceLocation = false;
+		bool encountered_TablePosition = false;
+		bool encountered_DataCollectionCenterPatient = false;
+		bool encountered_ReconstructionTargetCenterPatient = false;
+		bool encountered_DistanceSourceToDetector = false;
+		bool encountered_DistanceSourceToDataCollectionCenter = false;
+		bool encountered_DistanceSourceToPatient = false;
+		bool encountered_ReconstructionAlgorithm = false;
+		bool encountered_ConvolutionKernel = false;
+		bool encountered_ConvolutionKernelGroup = false;
+		bool encountered_ReconstructionDiameter = false;
+		bool encountered_ReconstructionFieldOfView = false;
+		bool encountered_ReconstructionPixelSpacing = false;
+		bool encountered_ReconstructionAngle = false;
+		bool encountered_ImageFilter = false;
+		bool encountered_ExposureTime = false;
+		bool encountered_XRayTubeCurrent = false;
+		bool encountered_Exposure = false;
+		bool encountered_ExposureInuAs = false;
+		bool encountered_ExposureTimeInms = false;
+		bool encountered_XRayTubeCurrentInmA = false;
+		bool encountered_ExposureInmAs = false;
+		bool encountered_ExposureModulationType = false;
+		bool encountered_EstimatedDoseSaving = false;
+		bool encountered_KVP = false;
+		bool encountered_CTDIvol = false;
+		bool encountered_FocalSpots = false;
+		bool encountered_FilterType = false;
+		bool encountered_FilterMaterial = false;
+		bool encountered_PatientPosition = false;
+		bool encountered_ContrastBolusAgent = false;
+		bool encountered_ContrastBolusRoute = false;
+		bool encountered_ContrastBolusVolume = false;
+		bool encountered_ContrastBolusIngredientConcentration = false;
+		bool encountered_ContrastBolusAgentAdministered = false;
+		bool encountered_ContrastBolusAgentDetected = false;
+		bool encountered_ContrastBolusAgentPhase = false;
+		bool encountered_CardiacCyclePosition = false;
+		bool encountered_RespiratoryCyclePosition = false;
+		//bool encountered_TriggerWindow = false;
+		bool encountered_RRIntervalTimeNominal = false;
+		bool encountered_IrradiationEventUID = false;
+
+		double shared_EchoTime = 0;
+		double shared_RepetitionTime = 0;
+		double shared_InversionTime = 0;
+		double shared_FlipAngle = 0;
+		double shared_SliceThickness = 0;
+		double *shared_PixelSpacing = NULL;
+		Uint32 shared_AcquisitionNumber = 0;
+		char *shared_AcquisitionDate = NULL;
+		char *shared_AcquisitionTime = NULL;
+		double shared_AcquisitionDuration = 0;
+		char *shared_ContentDate = NULL;
+		char *shared_ContentTime = NULL;
+		char *shared_ImageComments = NULL;
+		double *shared_ImagePositionPatient = NULL;
+		double *shared_ImageOrientationPatient = NULL;
+		double shared_TriggerTime = 0;
+		double shared_NominalCardiacTriggerDelayTime = 0;
+		char **shared_ImageType = NULL;
+		char **shared_ScanningSequence = NULL;
+		char **shared_SequenceVariant = NULL;
+		char **shared_ScanOptions = NULL;
+		Uint32 shared_EchoNumbers = 0;
+		char *shared_BodyPartExamined = NULL;
+		char *shared_PatientName = NULL;
+		char *shared_StudyDescription = NULL;
+		char *shared_SeriesDescription = NULL;
+		char *shared_Laterality = NULL;
+		Uint32 shared_MRAcquisitionPhaseEncodingStepsOutOfPlane = 0;
+		char *shared_InPlanePhaseEncodingDirection = NULL;
+		Uint32 shared_NumberOfPhaseEncodingSteps = 0;
+		double shared_PercentSampling = 0;
+		double shared_PercentPhaseFieldOfView = 0;
+		double shared_ImagingFrequency = 0;
+		double shared_PixelBandwidth = 0;
+		char *shared_ReceiveCoilName = NULL;
+		char *shared_TransmitCoilName = NULL;
+		char *shared_Manufacturer = NULL;
+		double shared_NumberOfAverages = 0;
+		Uint32 shared_EchoTrainLength = 0;
+		Uint32 shared_RFEchoTrainLength = 0;
+		Uint32 shared_GradientEchoTrainLength = 0;
+		double shared_SAR = 0;
+		char *shared_PixelPresentation = NULL;
+		char *shared_VolumetricProperties = NULL;
+		char *shared_VolumeBasedCalculationTechnique = NULL;
+		char *shared_ComplexImageComponent = NULL;
+		char *shared_AcquisitionContrast = NULL;
+		Uint32 *shared_AcquisitionMatrix = NULL;
+ 		double shared_WindowCenter = 0;
+ 		double shared_WindowWidth = 0;
+		char *shared_WindowCenterWidthExplanation = NULL;
+ 		double shared_DiffusionBValue = 0;
+ 		char *shared_DiffusionDirectionality = NULL;
+ 		double shared_GradientOutput = 0;
+ 		char *shared_GradientOutputType = NULL;
+ 		double shared_RescaleSlope = 0;
+ 		double shared_RescaleIntercept = 0;
+ 		char * shared_RescaleType = NULL;
+ 		double shared_RealWorldValueSlope = 0;
+ 		double shared_RealWorldValueIntercept = 0;
+		char *shared_Units = NULL;
+		Uint32 shared_RealWorldValueFirstValueMapped = 0;
+		Uint32 shared_RealWorldValueLastValueMapped = 0;
+		char *shared_LUTExplanation = NULL;
+		char *shared_LUTLabel = NULL;
+ 		double *shared_VelocityEncodingDirection = NULL;
+		double shared_VelocityEncodingMinimumValue = 0;
+		double shared_VelocityEncodingMaximumValue = 0;
+		char *shared_MetaboliteMapDescription = NULL;
+		double shared_ChemicalShiftMinimumIntegrationLimitInppm = 0;
+		double shared_ChemicalShiftMaximumIntegrationLimitInppm = 0;
+ 		char *shared_AcquisitionType = NULL;
+		double shared_TubeAngle = 0;
+ 		char *shared_ConstantVolumeFlag = NULL;
+ 		char *shared_FluoroscopyFlag = NULL;
+ 		char *shared_RotationDirection = NULL;
+		double shared_RevolutionTime = 0;
+		double shared_SingleCollimationWidth = 0;
+		double shared_TotalCollimationWidth = 0;
+		double shared_TableHeight = 0;
+		double shared_GantryDetectorTilt = 0;
+		double shared_DataCollectionDiameter = 0;
+		double shared_TableSpeed = 0;
+		double shared_TableFeedPerRotation = 0;
+		double shared_SpiralPitchFactor = 0;
+		double shared_SliceLocation = 0;
+		double shared_TablePosition = 0;
+		double *shared_DataCollectionCenterPatient = NULL;
+		double *shared_ReconstructionTargetCenterPatient = NULL;
+		double shared_DistanceSourceToDetector = 0;
+		double shared_DistanceSourceToDataCollectionCenter = 0;
+		double shared_DistanceSourceToPatient = 0;
+ 		char *shared_ReconstructionAlgorithm = NULL;
+ 		char *shared_ConvolutionKernel = NULL;
+ 		char *shared_ConvolutionKernelGroup = NULL;
+		double shared_ReconstructionDiameter = 0;
+		double *shared_ReconstructionFieldOfView = NULL;
+		double *shared_ReconstructionPixelSpacing = NULL;
+		double shared_ReconstructionAngle = 0;
+ 		char *shared_ImageFilter = NULL;
+		Uint32 shared_ExposureTime = 0;
+		Uint32 shared_XRayTubeCurrent = 0;
+		Uint32 shared_Exposure = 0;
+		Uint32 shared_ExposureInuAs = 0;
+		double shared_ExposureTimeInms = 0;
+		double shared_XRayTubeCurrentInmA = 0;
+		double shared_ExposureInmAs = 0;
+ 		char *shared_ExposureModulationType = NULL;
+		double shared_EstimatedDoseSaving = 0;
+		double shared_KVP = 0;
+		double shared_CTDIvol = 0;
+		double shared_FocalSpots = 0;
+ 		char *shared_FilterType = NULL;
+ 		char *shared_FilterMaterial = NULL;
+		char *shared_PatientPosition = NULL;
+		char **shared_ContrastBolusAgent = NULL;
+		char **shared_ContrastBolusRoute = NULL;
+		char **shared_ContrastBolusVolume = NULL;
+		char **shared_ContrastBolusIngredientConcentration = NULL;
+		char **shared_ContrastBolusAgentAdministered = NULL;
+		char **shared_ContrastBolusAgentDetected = NULL;
+		char **shared_ContrastBolusAgentPhase = NULL;
+		char *shared_CardiacCyclePosition = NULL;
+		char *shared_RespiratoryCyclePosition = NULL;
+		//double shared_TriggerWindow = 0;
+		double shared_RRIntervalTimeNominal = 0;
+		char *shared_IrradiationEventUID = NULL;
+
+		double *perFrame_EchoTime = NULL;
+		double *perFrame_RepetitionTime = NULL;
+		double *perFrame_InversionTime = NULL;
+		double *perFrame_FlipAngle = NULL;
+		double *perFrame_SliceThickness = NULL;
+		double **perFrame_PixelSpacing = NULL;
+		Uint32 *perFrame_AcquisitionNumber = NULL;
+		char **perFrame_AcquisitionDate = NULL;
+		char **perFrame_AcquisitionTime = NULL;
+		double *perFrame_AcquisitionDuration = NULL;
+		char **perFrame_ContentDate = NULL;
+		char **perFrame_ContentTime = NULL;
+		char **perFrame_ImageComments = NULL;
+		double **perFrame_ImagePositionPatient = NULL;
+		double **perFrame_ImageOrientationPatient = NULL;
+		double *perFrame_TriggerTime = NULL;
+		double *perFrame_NominalCardiacTriggerDelayTime = NULL;
+		char ***perFrame_ImageType = NULL;
+		char ***perFrame_ScanningSequence = NULL;
+		char ***perFrame_SequenceVariant = NULL;
+		char ***perFrame_ScanOptions = NULL;
+		Uint32 *perFrame_EchoNumbers = NULL;
+		char **perFrame_BodyPartExamined = NULL;
+		char **perFrame_PatientName = NULL;
+		char **perFrame_StudyDescription = NULL;
+		char **perFrame_SeriesDescription = NULL;
+		char **perFrame_Laterality = NULL;
+		Uint32 *perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane = NULL;
+		char **perFrame_InPlanePhaseEncodingDirection = NULL;
+		Uint32 *perFrame_NumberOfPhaseEncodingSteps = NULL;
+		double *perFrame_PercentSampling = NULL;
+		double *perFrame_PercentPhaseFieldOfView = NULL;
+		double *perFrame_ImagingFrequency = NULL;
+		double *perFrame_PixelBandwidth = NULL;
+		char **perFrame_ReceiveCoilName = NULL;
+		char **perFrame_TransmitCoilName = NULL;
+		char **perFrame_Manufacturer = NULL;
+		double *perFrame_NumberOfAverages = NULL;
+		Uint32 *perFrame_EchoTrainLength = NULL;
+		Uint32 *perFrame_RFEchoTrainLength = NULL;
+		Uint32 *perFrame_GradientEchoTrainLength = NULL;
+		double *perFrame_SAR = NULL;
+		char **perFrame_PixelPresentation = NULL;
+		char **perFrame_VolumetricProperties = NULL;
+		char **perFrame_VolumeBasedCalculationTechnique = NULL;
+		char **perFrame_ComplexImageComponent = NULL;
+		char **perFrame_AcquisitionContrast = NULL;
+		Uint32 **perFrame_AcquisitionMatrix = NULL;
+ 		double *perFrame_WindowCenter = NULL;
+ 		double *perFrame_WindowWidth = NULL;
+		char **perFrame_WindowCenterWidthExplanation = NULL;
+ 		double *perFrame_DiffusionBValue = NULL;
+ 		char **perFrame_DiffusionDirectionality = NULL;
+ 		double *perFrame_GradientOutput = NULL;
+ 		char **perFrame_GradientOutputType = NULL;
+ 		double *perFrame_RescaleSlope = NULL;
+ 		double *perFrame_RescaleIntercept = NULL;
+ 		char **perFrame_RescaleType = NULL;
+ 		double *perFrame_RealWorldValueSlope = NULL;
+ 		double *perFrame_RealWorldValueIntercept = NULL;
+		char **perFrame_Units = NULL;
+		Uint32 *perFrame_RealWorldValueFirstValueMapped = NULL;
+		Uint32 *perFrame_RealWorldValueLastValueMapped = NULL;
+		char **perFrame_LUTExplanation = NULL;
+		char **perFrame_LUTLabel = NULL;
+ 		double **perFrame_VelocityEncodingDirection = NULL;
+		double *perFrame_VelocityEncodingMinimumValue = NULL;
+		double *perFrame_VelocityEncodingMaximumValue = NULL;
+		char **perFrame_MetaboliteMapDescription = NULL;
+		double *perFrame_ChemicalShiftMinimumIntegrationLimitInppm = NULL;
+		double *perFrame_ChemicalShiftMaximumIntegrationLimitInppm = NULL;
+		char **perFrame_AcquisitionType = NULL;
+		double *perFrame_TubeAngle = NULL;
+		char **perFrame_ConstantVolumeFlag = NULL;
+		char **perFrame_FluoroscopyFlag = NULL;
+		char **perFrame_RotationDirection = NULL;
+		double *perFrame_RevolutionTime = NULL;
+		double *perFrame_SingleCollimationWidth = NULL;
+		double *perFrame_TotalCollimationWidth = NULL;
+		double *perFrame_TableHeight = NULL;
+		double *perFrame_GantryDetectorTilt = NULL;
+		double *perFrame_DataCollectionDiameter = NULL;
+		double *perFrame_TableSpeed = NULL;
+		double *perFrame_TableFeedPerRotation = NULL;
+		double *perFrame_SpiralPitchFactor = NULL;
+		double *perFrame_SliceLocation = NULL;
+		double *perFrame_TablePosition = NULL;
+		double **perFrame_DataCollectionCenterPatient = NULL;
+		double **perFrame_ReconstructionTargetCenterPatient = NULL;
+		double *perFrame_DistanceSourceToDetector = NULL;
+		double *perFrame_DistanceSourceToDataCollectionCenter = NULL;
+		double *perFrame_DistanceSourceToPatient = NULL;
+		char **perFrame_ReconstructionAlgorithm = NULL;
+		char **perFrame_ConvolutionKernel = NULL;
+		char **perFrame_ConvolutionKernelGroup = NULL;
+		double *perFrame_ReconstructionDiameter = NULL;
+		double **perFrame_ReconstructionFieldOfView = NULL;
+		double **perFrame_ReconstructionPixelSpacing = NULL;
+		double *perFrame_ReconstructionAngle = NULL;
+		char **perFrame_ImageFilter = NULL;
+		Uint32 *perFrame_ExposureTime = NULL;
+		Uint32 *perFrame_XRayTubeCurrent = NULL;
+		Uint32 *perFrame_Exposure = NULL;
+		Uint32 *perFrame_ExposureInuAs = NULL;
+		double *perFrame_ExposureTimeInms = NULL;
+		double *perFrame_XRayTubeCurrentInmA = NULL;
+		double *perFrame_ExposureInmAs = NULL;
+		char **perFrame_ExposureModulationType = NULL;
+		double *perFrame_EstimatedDoseSaving = NULL;
+		double *perFrame_KVP = NULL;
+		double *perFrame_CTDIvol = NULL;
+		double *perFrame_FocalSpots = NULL;
+		char **perFrame_FilterType = NULL;
+		char **perFrame_FilterMaterial = NULL;
+		char **perFrame_PatientPosition = NULL;
+		char ***perFrame_ContrastBolusAgent = NULL;
+		char ***perFrame_ContrastBolusRoute = NULL;
+		char ***perFrame_ContrastBolusVolume = NULL;
+		char ***perFrame_ContrastBolusIngredientConcentration = NULL;
+		char ***perFrame_ContrastBolusAgentAdministered = NULL;
+		char ***perFrame_ContrastBolusAgentDetected = NULL;
+		char ***perFrame_ContrastBolusAgentPhase = NULL;
+		char **perFrame_CardiacCyclePosition = NULL;
+		char **perFrame_RespiratoryCyclePosition = NULL;
+		//double *perFrame_TriggerWindow = NULL;
+		double *perFrame_RRIntervalTimeNominal = NULL;
+		char **perFrame_IrradiationEventUID = NULL;
+
+		int nValues_ImageType = 0;
+		int nValues_ScanningSequence = 0;
+		int nValues_SequenceVariant = 0;
+		int nValues_ScanOptions = 0;
+		int nValues_ContrastBolusAgent = 0;
+		int nValues_ContrastBolusRoute = 0;
+		int nValues_ContrastBolusVolume = 0;
+		int nValues_ContrastBolusIngredientConcentration = 0;
+		int nValues_ContrastBolusAgentAdministered = 0;
+		int nValues_ContrastBolusAgentDetected = 0;
+		int nValues_ContrastBolusAgentPhase = 0;
+
+                ManagedAttributeList newList;
+
+                int i;
+                for (i=0; i < numberofinputfiles; ++i) {
+//cerr << "Frame " << i << " tracking ... " << endl;				
+
+                        // open and read each image file ...
+
+                        const char *filename=sortedfilenamestable[i].filename;
+                        Assert(filename);
+                        if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+                        ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+                        ifstream *fstr=new ifstream(filename);
+#endif
+                        if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+                                cerr << AMsgDC(FileReadOpenFailed);
+                                if (filename) cerr <<" - \"" << filename << "\"";
+                                success=false;
+                                break;
+                            }
+
+                        DicomInputStream din(*(istream *)fstr,
+                                dicom_input_options.transfersyntaxuid,
+                                dicom_input_options.usemetaheader);
+
+                        ManagedAttributeList list;
+
+                        if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+                        list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+                        if (!list.good()) {
+                                log << list.errors()
+                                    << EMsgDC(DatasetReadFailed) << endl;
+                                success=false;
+                                break;
+                        }
+
+                        // extract and check that attributes values are consistent for all image files ...
+
+                        const char *patientID=getAndCheckStringMatchElseError(i == 0,requiredPatientID,list,
+                                TagFromName(PatientID),"Patient ID",filename,log);
+
+                        const char *patientName=getAndCheckStringMatchElseError(i == 0,requiredPatientName,list,
+                                TagFromName(PatientName),"Patient Name",filename,log);
+
+                        const char *studyInstanceUID=getAndCheckStringMatchElseError(i == 0,requiredStudyInstanceUID,list,
+                                TagFromName(StudyInstanceUID),"Study Instance UID",filename,log);
+
+                        const char *studyID=getAndCheckStringMatchElseError(i == 0,requiredStudyID,list,
+                                TagFromName(StudyID),"Study ID",filename,log);
+				
+			if (i == 0) {
+				Attribute *aStudyID = dicom_output_options.replacebeforelist ? (*dicom_output_options.replacebeforelist)[TagFromName(StudyID)] : NULL;
+				const char *vStudyIDForUIDGeneration = aStudyID ? AttributeValue(aStudyID,"0") : requiredStudyID /*what is already in the dataset*/;
+//cerr << "vStudyIDForUIDGeneration = " << vStudyIDForUIDGeneration << endl;
+//if (dicom_output_options.replacebeforelist) { cerr << "(*dicom_output_options.replacebeforelist)[TagFromName(StudyID)] = " << ((*dicom_output_options.replacebeforelist)[TagFromName(StudyID)]) << endl; }
+//cerr << "vStudyIDForUIDGeneration strtol = " << strtol(vStudyIDForUIDGeneration,NULL,0) << endl;
+//cerr << "vStudyIDForUIDGeneration atoi = " << atoi(vStudyIDForUIDGeneration) << endl;
+				studyIDForUIDGeneration = vStudyIDForUIDGeneration ? atoi(vStudyIDForUIDGeneration) : 0;
+			}
+
+                        const char *seriesInstanceUID=getAndCheckStringMatchElseError(i == 0,requiredSeriesInstanceUID,list,
+                                TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+
+                        const char *SOPClassUID=getAndCheckStringMatchElseError(i == 0,requiredSOPClassUID,list,
+                                TagFromName(SOPClassUID),"SOP Class UID",filename,log);
+
+                        Uint16 seriesNumber=getAndCheckIntegerMatchElseError(i == 0,requiredSeriesNumber,list,
+                                TagFromName(SeriesNumber),"Series Number",filename,log);
+
+			if (i == 0) {
+				Attribute *aSeriesNumber = dicom_output_options.replacebeforelist ? (*dicom_output_options.replacebeforelist)[TagFromName(SeriesNumber)] : NULL;
+				seriesNumberForUIDGeneration = aSeriesNumber ? Uint32(AttributeValue(aSeriesNumber,"0")) : requiredSeriesNumber /*what is already in the dataset*/;
+			}
+			
+			{
+				Attribute *aInstanceNumber = dicom_output_options.replacebeforelist ? (*dicom_output_options.replacebeforelist)[TagFromName(InstanceNumber)] : NULL;
+				if (!aInstanceNumber) {
+					aInstanceNumber=list[TagFromName(InstanceNumber)];	/*what is already in the dataset*/
+				}
+				instanceNumberForUIDGeneration = aInstanceNumber ? Uint32(AttributeValue(aInstanceNumber,"0")) : 0 ;
+			}
+
+                        const char *modality=getAndCheckStringMatchElseError(i == 0,requiredModality,list,
+                                TagFromName(Modality),"Modality",filename,log);
+
+                        Uint16 rows=getAndCheckIntegerMatchElseError(i == 0,requiredRows,list,
+                                TagFromName(Rows),"Rows",filename,log);
+
+                        Uint16 columns=getAndCheckIntegerMatchElseError(i == 0,requiredColumns,list,
+                                TagFromName(Columns),"Columns",filename,log);
+
+                        Uint16 bitsAllocated=getAndCheckIntegerMatchElseError(i == 0,requiredBitsAllocated,list,
+                                TagFromName(BitsAllocated),"Bits Allocated",filename,log);
+
+                        Uint16 bitsStored=getAndCheckIntegerMatchElseError(i == 0,requiredBitsStored,list,
+                                TagFromName(BitsStored),"Bits Stored",filename,log);
+
+                        Uint16 highBit=getAndCheckIntegerMatchElseError(i == 0,requiredHighBit,list,
+                                TagFromName(HighBit),"High Bit",filename,log);
+
+                        Uint16 pixelRepresentation=getAndCheckIntegerMatchElseError(i == 0,requiredPixelRepresentation,list,
+                                TagFromName(PixelRepresentation),"Pixel Representation",filename,log);
+
+                        Uint16 samplesPerPixel=getAndCheckIntegerMatchElseError(i == 0,requiredSamplesPerPixel,list,
+                                TagFromName(SamplesPerPixel),"Samples Per Pixel",filename,log);
+
+                        if (strcmp(requiredSOPClassUID,MRImageStorageSOPClassUID) == 0
+                        || strcmp(requiredSOPClassUID,CTImageStorageSOPClassUID) == 0) {
+                                double sliceThickness=getAndCheckFloatMatchElseError(i == 0,requiredSliceThickness,list,
+                                        TagFromName(SliceThickness),"Slice Thickness",filename,log);
+                        }
+
+                        if (strcmp(requiredSOPClassUID,MRImageStorageSOPClassUID) == 0) {
+                                //Uint16 echoNumber=getAndCheckIntegerMatchElseError(i == 0,requiredEchoNumbers,list,
+                                //	TagFromName(EchoNumbers),"Echo Number",filename,log);
+                                double echoTime=getAndCheckFloatMatchElseError(i == 0,requiredEchoTime,list,
+                                        TagFromName(EchoTime),"Echo Time",filename,log);
+                                double repetitionTime=getAndCheckFloatMatchElseError(i == 0,requiredRepetitionTime,list,
+                                        TagFromName(RepetitionTime),"Repetition Time",filename,log);
+                                double magneticFieldStrength=getAndCheckFloatMatchElseError(i == 0,requiredMagneticFieldStrength,list,
+                                        TagFromName(MagneticFieldStrength),"Magnetic Field Strength",filename,log);
+				const char *imagedNucleus=getAndCheckStringMatchElseError(i == 0,requiredImagedNucleus,list,
+					TagFromName(ImagedNucleus),"Imaged Nucleus",filename,log);
+				const char *protocolName=getAndCheckStringMatchElseError(i == 0,requiredProtocolName,list,
+					TagFromName(ProtocolName),"Protocol Name",filename,log);
+				const char *sequenceName=getAndCheckStringMatchElseError(i == 0,requiredSequenceName,list,
+					TagFromName(SequenceName),"Sequence Name",filename,log);
+				const char *MRAcquisitionType=getAndCheckStringMatchElseError(i == 0,requiredMRAcquisitionType,list,
+					TagFromName(MRAcquisitionType),"MR Acquisition Type",filename,log);
+
+                        }
+
+                        if (strcmp(requiredSOPClassUID,CTImageStorageSOPClassUID) == 0) {
+                                double rescaleSlope=getAndCheckFloatMatchElseError(i == 0,requiredRescaleSlope,list,
+                                        TagFromName(RescaleSlope),"Rescale Slope",filename,log);
+                                double rescaleIntercept=getAndCheckFloatMatchElseError(i == 0,requiredRescaleIntercept,list,
+                                        TagFromName(RescaleIntercept),"Rescale Intercept",filename,log);
+                        }
+
+                        // should also check PixelSpacing, ImageOrientationPatient ...
+
+                        // Get pixel data attribute for later use ...
+
+                        Attribute *apixeldata=list[TagFromName(PixelData)];
+                        if (!apixeldata) {
+                                log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+                                success=false;
+                                break;
+                        }
+
+                        // for the first file, copy everything except pixels, and add frame stuff ...
+
+                        if (i == 0) {
+                                // Check and add frame stuff ...
+
+                                Attribute *aNumberOfFrames=list[TagFromName(NumberOfFrames)];
+                                if (aNumberOfFrames) {
+                                        Uint16 vNumberOfFrames = AttributeValue(aNumberOfFrames);
+                                        if (vNumberOfFrames > 1) {
+                                                log << "Number Of Frames found in <" << filename
+                                                    << "> and greater than 1 - input images cannot be multiframe - aborting" << endl;
+                                                success=false;
+                                                break;
+                                        }
+                                        list-=TagFromName(NumberOfFrames);
+                                }
+                                list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),Uint16(numberofinputfiles));
+
+                                // delete old Instance Number and add new one with fixed value of 1 ...
+
+                                list-=TagFromName(InstanceNumber);
+                                list+=new IntegerStringAttribute(TagFromName(InstanceNumber),Uint16(1));
+
+                                // delete old SOP Instance UID ... usualManagedAttributeListWrite() adds new one ...
+
+                                list-=TagFromName(SOPInstanceUID);
+
+                                // check for single-frame SOP classes which have multi-frame equivalent, else leave alone ...
+
+                                const char *newSOPClassUID = 0;
+                                if (strcmp(SOPClassUID,MRImageStorageSOPClassUID) == 0) {
+                                        if (!noMRMultiFrame) {
+						newSOPClassUID=EnhancedMRImageStorageSOPClassUID;
+						addMultiFrameMRStuff=true;
+						useExtraPixelDataWritePass=true;
+					}
+                                }
+                                else if (strcmp(SOPClassUID,CTImageStorageSOPClassUID) == 0) {
+                                        if (!noCTMultiFrame) {
+						newSOPClassUID=EnhancedCTImageStorageSOPClassUID;
+						addMultiFrameCTStuff=true;
+						useExtraPixelDataWritePass=true;
+					}
+                                }
+                                else if (strcmp(SOPClassUID,SecondaryCaptureImageStorageSOPClassUID) == 0) {
+                                        const char *photometricInterpretation=getStringValueElseError(list,TagFromName(PhotometricInterpretation),"Photometric Interpretation",filename,log);
+                                        if (photometricInterpretation) {
+                                                if (strcmp(photometricInterpretation,"RGB") == 0) {
+                                                        if (samplesPerPixel == 3 && bitsAllocated == 8 && bitsStored == 8 && highBit == 7 && pixelRepresentation == 0) {	// should check PlanarConfiguration also
+                                                                newSOPClassUID=MultiframeTrueColorSecondaryCaptureImageStorageSOPClassUID;
+                                                        }
+                                                }
+                                                else if (strcmp(photometricInterpretation,"MONOCHROME2") == 0) {
+                                                        if (samplesPerPixel == 1 && bitsAllocated == 1 && bitsStored == 1 && highBit == 0 && pixelRepresentation == 0) {
+                                                                newSOPClassUID=MultiframeSingleBitSecondaryCaptureImageStorageSOPClassUID;
+                                                                addMultiFrameSecondaryCaptureStuff=true;
+                                                        }
+                                                        else if (samplesPerPixel == 1 && bitsAllocated == 8 && bitsStored == 8 && highBit == 7 && pixelRepresentation == 0) {
+                                                                newSOPClassUID=MultiframeGrayscaleByteSecondaryCaptureImageStorageSOPClassUID;
+                                                                addMultiFrameSecondaryCaptureStuff=true;
+                                                        }
+                                                        else if (samplesPerPixel == 1 && bitsAllocated == 16 && bitsStored > 8 && bitsStored <= 16 && highBit == (bitsStored-1) && pixelRepresentation == 0) {
+                                                                newSOPClassUID=MultiframeGrayscaleWordSecondaryCaptureImageStorageSOPClassUID;
+                                                                addMultiFrameSecondaryCaptureStuff=true;
+                                                        }
+                                                }
+                                        }
+                                }
+                                if (newSOPClassUID) {
+                                        list-=TagFromName(SOPClassUID);
+                                        list+=new UIStringAttribute(TagFromName(SOPClassUID),newSOPClassUID);
+                                }
+                                if (addMultiFrameSecondaryCaptureStuff) {
+                                        list-=TagFromName(PresentationLUTShape);
+                                        list+=new CodeStringAttribute(TagFromName(PresentationLUTShape),"IDENTITY");
+
+                                        if (numberofinputfiles > 1) {
+                                                AttributeTagAttribute *aFrameIncrementPointer = new AttributeTagAttribute(TagFromName(FrameIncrementPointer));
+                                                aFrameIncrementPointer->addValue(TagFromName(DisplayWindowLabelVector));
+                                                list+=aFrameIncrementPointer;
+
+                                                ShortStringAttribute *aDisplayWindowLabelVector = new ShortStringAttribute(TagFromName(DisplayWindowLabelVector));
+                                                for (int i=1; i<=numberofinputfiles; ++i) aDisplayWindowLabelVector->addValue((Uint16)i);
+                                                list+=aDisplayWindowLabelVector;
+                                        }
+                                }
+                        }
+                        
+			// capture stuff for each frame before list goes away ...
+                        
+                        if (addMultiFrameMRStuff || addMultiFrameCTStuff) {
+//cerr << "Frame " << i << " tracking ... addMultiFrameMRStuff and addMultiFrameCTStuff" << endl;				
+                                // For every frame track the following ...
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(SliceThickness),"Slice Thickness",
+                                        encountered_SliceThickness,shared_SliceThickness,perFrame_SliceThickness,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(PixelSpacing),"Pixel Spacing",2,
+                                        encountered_PixelSpacing,shared_PixelSpacing,perFrame_PixelSpacing,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(AcquisitionNumber),"Acquisition Number",
+                                        encountered_AcquisitionNumber,shared_AcquisitionNumber,perFrame_AcquisitionNumber,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(AcquisitionDate),"Acquisition Date",
+                                        encountered_AcquisitionDate,shared_AcquisitionDate,perFrame_AcquisitionDate,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(AcquisitionTime),"Acquisition Time",
+                                        encountered_AcquisitionTime,shared_AcquisitionTime,perFrame_AcquisitionTime,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(AcquisitionDuration),"Acquisition Duration",
+                                        encountered_AcquisitionDuration,shared_AcquisitionDuration,perFrame_AcquisitionDuration,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ContentDate),"Content Date",
+                                        encountered_ContentDate,shared_ContentDate,perFrame_ContentDate,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ContentTime),"Content Time",
+                                        encountered_ContentTime,shared_ContentTime,perFrame_ContentTime,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ImageComments),"Image Comments",
+                                        encountered_ImageComments,shared_ImageComments,perFrame_ImageComments,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ImagePositionPatient),"Image Position (Patient)",3,
+                                        encountered_ImagePositionPatient,shared_ImagePositionPatient,perFrame_ImagePositionPatient,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ImageOrientationPatient),"Image Orientation (Patient)",6,
+                                        encountered_ImageOrientationPatient,shared_ImageOrientationPatient,perFrame_ImageOrientationPatient,
+                                        numberofinputfiles,i,filename,log);
+                                        
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TriggerTime),"Trigger Time",
+                                        encountered_TriggerTime,shared_TriggerTime,perFrame_TriggerTime,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(NominalCardiacTriggerDelayTime),"Nominal Cardiac Trigger Delay Time",
+                                        encountered_NominalCardiacTriggerDelayTime,shared_NominalCardiacTriggerDelayTime,perFrame_NominalCardiacTriggerDelayTime,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ImageType),"Image Type",4,nValues_ImageType,
+                                        encountered_ImageType,shared_ImageType,perFrame_ImageType,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(BodyPartExamined),"Body Part Examined",
+                                        encountered_BodyPartExamined,shared_BodyPartExamined,perFrame_BodyPartExamined,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(PatientName),"Patient Name",
+                                        encountered_PatientName,shared_PatientName,perFrame_PatientName,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(StudyDescription),"Study Description",
+                                        encountered_StudyDescription,shared_StudyDescription,perFrame_StudyDescription,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(SeriesDescription),"Series Description",
+                                        encountered_SeriesDescription,shared_SeriesDescription,perFrame_SeriesDescription,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(Laterality),"Laterality",
+                                        encountered_Laterality,shared_Laterality,perFrame_Laterality,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(Manufacturer),"Manufacturer",
+                                        encountered_Manufacturer,shared_Manufacturer,perFrame_Manufacturer,
+                                        numberofinputfiles,i,filename,log);
+				
+				// The window values are actually potentially multi-valued; we just want to track the first one
+				// though we could do all of them :(
+				
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(WindowCenter),"Window Center",
+                                        encountered_WindowCenter,shared_WindowCenter,perFrame_WindowCenter,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(WindowWidth),"Window Width",
+                                        encountered_WindowWidth,shared_WindowWidth,perFrame_WindowWidth,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(WindowCenterWidthExplanation),"Window Center Width Explanation",
+                                        encountered_WindowCenterWidthExplanation,shared_WindowCenterWidthExplanation,perFrame_WindowCenterWidthExplanation,
+                                        numberofinputfiles,i,filename,log);
+					
+				// these aren't in the original single frame CT or MR object, but may be manually inserted into source
+				// images to be able to build a correct CT or MR multi-frame ...
+				
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(PixelPresentation),"Pixel Presentation",
+					encountered_PixelPresentation,shared_PixelPresentation,perFrame_PixelPresentation,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(VolumetricProperties),"Volumetric Properties",
+					encountered_VolumetricProperties,shared_VolumetricProperties,perFrame_VolumetricProperties,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(VolumeBasedCalculationTechnique),"Volume Based Calculation Technique",
+					encountered_VolumeBasedCalculationTechnique,shared_VolumeBasedCalculationTechnique,perFrame_VolumeBasedCalculationTechnique,
+                                        numberofinputfiles,i,filename,log);
+					
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RescaleSlope),"Rescale Slope",
+                                        encountered_RescaleSlope,shared_RescaleSlope,perFrame_RescaleSlope,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RescaleIntercept),"Rescale Intercept",
+                                        encountered_RescaleIntercept,shared_RescaleIntercept,perFrame_RescaleIntercept,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(RescaleType),"Rescale Type",
+ 					encountered_RescaleType,shared_RescaleType,perFrame_RescaleType,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RealWorldValueSlope),"Real World Value Slope",
+                                        encountered_RealWorldValueSlope,shared_RealWorldValueSlope,perFrame_RealWorldValueSlope,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RealWorldValueIntercept),"Real World Value Intercept",
+                                        encountered_RealWorldValueIntercept,shared_RealWorldValueIntercept,perFrame_RealWorldValueIntercept,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(Units),"Units",
+ 					encountered_Units,shared_Units,perFrame_Units,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(RealWorldValueFirstValueMapped),"Real World Value First Value Mapped",
+                                        encountered_RealWorldValueFirstValueMapped,shared_RealWorldValueFirstValueMapped,perFrame_RealWorldValueFirstValueMapped,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(RealWorldValueLastValueMapped),"Real World Value Last Value Mapped",
+                                        encountered_RealWorldValueLastValueMapped,shared_RealWorldValueLastValueMapped,perFrame_RealWorldValueLastValueMapped,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(LUTExplanation),"LUT Explanation",
+ 					encountered_LUTExplanation,shared_LUTExplanation,perFrame_LUTExplanation,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(LUTLabel),"LUT Label",
+ 					encountered_LUTLabel,shared_LUTLabel,perFrame_LUTLabel,
+					numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusAgent),"Contrast/Bolus Agent",10,nValues_ContrastBolusAgent,
+                                        encountered_ContrastBolusAgent,shared_ContrastBolusAgent,perFrame_ContrastBolusAgent,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusRoute),"Contrast/Bolus Route",10,nValues_ContrastBolusRoute,
+                                        encountered_ContrastBolusRoute,shared_ContrastBolusRoute,perFrame_ContrastBolusRoute,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusVolume),"Contrast/Bolus Volume",10,nValues_ContrastBolusVolume,
+                                        encountered_ContrastBolusVolume,shared_ContrastBolusVolume,perFrame_ContrastBolusVolume,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusIngredientConcentration),"Contrast/Bolus Ingredient Concentration",
+					10,nValues_ContrastBolusIngredientConcentration,
+                                        encountered_ContrastBolusIngredientConcentration,shared_ContrastBolusIngredientConcentration,perFrame_ContrastBolusIngredientConcentration,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusAgentAdministered),"Contrast/Bolus Administered",10,nValues_ContrastBolusAgentAdministered,
+                                        encountered_ContrastBolusAgentAdministered,shared_ContrastBolusAgentAdministered,perFrame_ContrastBolusAgentAdministered,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusAgentDetected),"Contrast/Bolus Detected",10,nValues_ContrastBolusAgentDetected,
+                                        encountered_ContrastBolusAgentDetected,shared_ContrastBolusAgentDetected,perFrame_ContrastBolusAgentDetected,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ContrastBolusAgentPhase),"Contrast/Bolus Phase",10,nValues_ContrastBolusAgentPhase,
+                                        encountered_ContrastBolusAgentPhase,shared_ContrastBolusAgentPhase,perFrame_ContrastBolusAgentPhase,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(CardiacCyclePosition),"Cardiac Cycle Position",
+ 					encountered_CardiacCyclePosition,shared_CardiacCyclePosition,perFrame_CardiacCyclePosition,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(RespiratoryCyclePosition),"Respiratory Cycle Position",
+ 					encountered_RespiratoryCyclePosition,shared_RespiratoryCyclePosition,perFrame_RespiratoryCyclePosition,
+					numberofinputfiles,i,filename,log);
+					
+                                //trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TriggerWindow),"Trigger Window",
+                                //        encountered_TriggerWindow,shared_TriggerWindow,perFrame_TriggerWindow,
+                                //        numberofinputfiles,i,filename,log);
+										
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RRIntervalTimeNominal),"R-R Interval Time Nominal",
+                                        encountered_RRIntervalTimeNominal,shared_RRIntervalTimeNominal,perFrame_RRIntervalTimeNominal,
+                                        numberofinputfiles,i,filename,log);
+								
+                               trackSingleValuedStringAttributePerFrame(list,TagFromName(IrradiationEventUID),"Irradiation Event UID",
+ 					encountered_IrradiationEventUID,shared_IrradiationEventUID,perFrame_IrradiationEventUID,
+					numberofinputfiles,i,filename,log);
+			}
+                        if (addMultiFrameCTStuff) {
+//cerr << "Frame " << i << " tracking ... addMultiFrameCTStuff" << endl;				
+                                // For every frame track the following ...
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(AcquisitionType),"Acquisition Type",
+					encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TubeAngle),"Tube Angle",
+                                        encountered_TubeAngle,shared_TubeAngle,perFrame_TubeAngle,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(ConstantVolumeFlag),"Constant Volume Flag",
+					encountered_ConstantVolumeFlag,shared_ConstantVolumeFlag,perFrame_ConstantVolumeFlag,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(FluoroscopyFlag),"Fluoroscopy Flag",
+					encountered_FluoroscopyFlag,shared_FluoroscopyFlag,perFrame_FluoroscopyFlag,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(RotationDirection),"Rotation Direction",
+					encountered_RotationDirection,shared_RotationDirection,perFrame_RotationDirection,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RevolutionTime),"Revolution Time",
+                                        encountered_RevolutionTime,shared_RevolutionTime,perFrame_RevolutionTime,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(SingleCollimationWidth),"Single Collimation Width",
+                                        encountered_SingleCollimationWidth,shared_SingleCollimationWidth,perFrame_SingleCollimationWidth,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TotalCollimationWidth),"Total Collimation Width",
+                                        encountered_TotalCollimationWidth,shared_TotalCollimationWidth,perFrame_TotalCollimationWidth,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TableHeight),"Table Height",
+                                        encountered_TableHeight,shared_TableHeight,perFrame_TableHeight,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(GantryDetectorTilt),"Gantry/Detector Tilt",
+					encountered_GantryDetectorTilt,shared_GantryDetectorTilt,perFrame_GantryDetectorTilt,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(DataCollectionDiameter),"Data Collection Diameter",
+					encountered_DataCollectionDiameter,shared_DataCollectionDiameter,perFrame_DataCollectionDiameter,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TableSpeed),"Table Speed",
+					encountered_TableSpeed,shared_TableSpeed,perFrame_TableSpeed,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TableFeedPerRotation),"Table Feed per Rotation",
+					encountered_TableFeedPerRotation,shared_TableFeedPerRotation,perFrame_TableFeedPerRotation,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(SpiralPitchFactor),"Spiral Pitch Factor",
+					encountered_SpiralPitchFactor,shared_SpiralPitchFactor,perFrame_SpiralPitchFactor,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(SliceLocation),"Slice Location",
+					encountered_SliceLocation,shared_SliceLocation,perFrame_SliceLocation,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(TablePosition),"Table Position",
+					encountered_TablePosition,shared_TablePosition,perFrame_TablePosition,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(DataCollectionCenterPatient),"Data Collection Center (Patient)",3,
+                                        encountered_DataCollectionCenterPatient,shared_DataCollectionCenterPatient,perFrame_DataCollectionCenterPatient,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ReconstructionTargetCenterPatient),"Reconstruction Target Center (Patient)",3,
+                                        encountered_ReconstructionTargetCenterPatient,shared_ReconstructionTargetCenterPatient,perFrame_ReconstructionTargetCenterPatient,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(DistanceSourceToDetector),"Distance Source to Detector",
+                                        encountered_DistanceSourceToDetector,shared_DistanceSourceToDetector,perFrame_DistanceSourceToDetector,
+					numberofinputfiles,i,filename,log);
+
+                                 trackSingleValuedDoubleAttributePerFrame(list,TagFromName(DistanceSourceToDataCollectionCenter),"Distance Source to Data Collection Center",
+                                       encountered_DistanceSourceToDataCollectionCenter,shared_DistanceSourceToDataCollectionCenter,perFrame_DistanceSourceToDataCollectionCenter,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(DistanceSourceToPatient),"Distance Source to Patient",
+                                        encountered_DistanceSourceToPatient,shared_DistanceSourceToPatient,perFrame_DistanceSourceToPatient,
+					numberofinputfiles,i,filename,log);
+
+ 				trackSingleValuedStringAttributePerFrame(list,TagFromName(ReconstructionAlgorithm),"Reconstruction Algorithm",
+                                       encountered_ReconstructionAlgorithm,shared_ReconstructionAlgorithm,perFrame_ReconstructionAlgorithm,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(ConvolutionKernel),"Convolution Kernel",
+                                        encountered_ConvolutionKernel,shared_ConvolutionKernel,perFrame_ConvolutionKernel,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(ConvolutionKernelGroup),"Convolution Kernel Group",
+                                        encountered_ConvolutionKernelGroup,shared_ConvolutionKernelGroup,perFrame_ConvolutionKernelGroup,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ReconstructionDiameter),"Reconstruction Diameter",
+                                        encountered_ReconstructionDiameter,shared_ReconstructionDiameter,perFrame_ReconstructionDiameter,
+					numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ReconstructionFieldOfView),"Reconstruction Field of View",2,
+                                        encountered_ReconstructionFieldOfView,shared_ReconstructionFieldOfView,perFrame_ReconstructionFieldOfView,
+					numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedDoubleAttributePerFrame(list,TagFromName(ReconstructionPixelSpacing),"Reconstruction Pixel Spacing",2,
+                                        encountered_ReconstructionPixelSpacing,shared_ReconstructionPixelSpacing,perFrame_ReconstructionPixelSpacing,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ReconstructionAngle),"Reconstruction Angle",
+                                        encountered_ReconstructionAngle,shared_ReconstructionAngle,perFrame_ReconstructionAngle,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(ImageFilter),"Image Filter",
+                                        encountered_ImageFilter,shared_ImageFilter,perFrame_ImageFilter,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(ExposureTime),"Exposure Time",
+                                        encountered_ExposureTime,shared_ExposureTime,perFrame_ExposureTime,
+					numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(XRayTubeCurrent),"XRay Tube Current",
+                                        encountered_XRayTubeCurrent,shared_XRayTubeCurrent,perFrame_XRayTubeCurrent,
+					numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(Exposure),"Exposure",
+                                        encountered_Exposure,shared_Exposure,perFrame_Exposure,
+					numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(ExposureInuAs),"Exposure in uAs",
+                                        encountered_ExposureInuAs,shared_ExposureInuAs,perFrame_ExposureInuAs,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ExposureTimeInms),"Exposure Time in ms",
+                                        encountered_ExposureTimeInms,shared_ExposureTimeInms,perFrame_ExposureTimeInms,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(XRayTubeCurrentInmA),"XRay Tube Current in mA",
+                                        encountered_XRayTubeCurrentInmA,shared_XRayTubeCurrentInmA,perFrame_XRayTubeCurrentInmA,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ExposureInmAs),"Exposure in mAs",
+                                        encountered_ExposureInmAs,shared_ExposureInmAs,perFrame_ExposureInmAs,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(ExposureModulationType),"Exposure Modulation Type",
+                                        encountered_ExposureModulationType,shared_ExposureModulationType,perFrame_ExposureModulationType,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(EstimatedDoseSaving),"Estimated Dose Saving",
+                                        encountered_EstimatedDoseSaving,shared_EstimatedDoseSaving,perFrame_EstimatedDoseSaving,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(KVP),"KVP",
+                                        encountered_KVP,shared_KVP,perFrame_KVP,
+					numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(FocalSpots),"Focal Spot(s)",
+                                        encountered_FocalSpots,shared_FocalSpots,perFrame_FocalSpots,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(FilterType),"Filter Type",
+                                        encountered_FilterType,shared_FilterType,perFrame_FilterType,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(FilterMaterial),"Filter Material",
+                                        encountered_FilterMaterial,shared_FilterMaterial,perFrame_FilterMaterial,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(PatientPosition),"Patient Position",
+                                        encountered_PatientPosition,shared_PatientPosition,perFrame_PatientPosition,
+					numberofinputfiles,i,filename,log);
+			}
+			
+                        if (addMultiFrameMRStuff) {
+//cerr << "Frame " << i << " tracking ... addMultiFrameMRStuff" << endl;				
+                                // For every frame track the following ...
+                                
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(EchoTime),"Echo Time",
+                                        encountered_EchoTime,shared_EchoTime,perFrame_EchoTime,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(RepetitionTime),"Repetition Time",
+                                        encountered_RepetitionTime,shared_RepetitionTime,perFrame_RepetitionTime,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(InversionTime),"Inversion Time",
+                                        encountered_InversionTime,shared_InversionTime,perFrame_InversionTime,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(FlipAngle),"Flip Angle",
+                                        encountered_FlipAngle,shared_FlipAngle,perFrame_FlipAngle,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ScanningSequence),"Scanning Sequence",5,nValues_ScanningSequence,
+                                        encountered_ScanningSequence,shared_ScanningSequence,perFrame_ScanningSequence,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(SequenceVariant),"Sequence Variant",8,nValues_SequenceVariant,
+                                        encountered_SequenceVariant,shared_SequenceVariant,perFrame_SequenceVariant,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackMultiValuedStringAttributePerFrame(list,TagFromName(ScanOptions),"Scan Options",9,nValues_ScanOptions,
+                                        encountered_ScanOptions,shared_ScanOptions,perFrame_ScanOptions,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(EchoNumbers),"Echo Number(s)",
+                                        encountered_EchoNumbers,shared_EchoNumbers,perFrame_EchoNumbers,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedUint32AttributePerFrame(list,TagFromName(MRAcquisitionPhaseEncodingStepsOutOfPlane),"MR Acquisition Phase Encoding Steps out-of-plane",
+                                        encountered_MRAcquisitionPhaseEncodingStepsOutOfPlane,shared_MRAcquisitionPhaseEncodingStepsOutOfPlane,perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane,
+                                        numberofinputfiles,i,filename,log);
+
+                               trackSingleValuedStringAttributePerFrame(list,TagFromName(InPlanePhaseEncodingDirection),"In-plane Phase Encoding Direction",
+                                        encountered_InPlanePhaseEncodingDirection,shared_InPlanePhaseEncodingDirection,perFrame_InPlanePhaseEncodingDirection,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedUint32AttributePerFrame(list,TagFromName(NumberOfPhaseEncodingSteps),"Number of Phase Encoding Steps",
+                                        encountered_NumberOfPhaseEncodingSteps,shared_NumberOfPhaseEncodingSteps,perFrame_NumberOfPhaseEncodingSteps,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(PercentSampling),"Percent Sampling",
+                                        encountered_PercentSampling,shared_PercentSampling,perFrame_PercentSampling,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(PercentPhaseFieldOfView),"Percent Phase Field of View",
+                                        encountered_PercentPhaseFieldOfView,shared_PercentPhaseFieldOfView,perFrame_PercentPhaseFieldOfView,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ImagingFrequency),"Imaging Frequency",
+                                        encountered_ImagingFrequency,shared_ImagingFrequency,perFrame_ImagingFrequency,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(PixelBandwidth),"Pixel Bandwidth",
+                                        encountered_PixelBandwidth,shared_PixelBandwidth,perFrame_PixelBandwidth,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ReceiveCoilName),"Receive Coil Name",
+                                        encountered_ReceiveCoilName,shared_ReceiveCoilName,perFrame_ReceiveCoilName,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(TransmitCoilName),"Transmit Coil Name",
+                                        encountered_TransmitCoilName,shared_TransmitCoilName,perFrame_TransmitCoilName,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(NumberOfAverages),"Number of Averages",
+                                        encountered_NumberOfAverages,shared_NumberOfAverages,perFrame_NumberOfAverages,
+                                        numberofinputfiles,i,filename,log);
+
+                                 trackSingleValuedUint32AttributePerFrame(list,TagFromName(EchoTrainLength),"Echo Train Length",
+                                        encountered_EchoTrainLength,shared_EchoTrainLength,perFrame_EchoTrainLength,
+                                        numberofinputfiles,i,filename,log);
+
+                                 trackSingleValuedUint32AttributePerFrame(list,TagFromName(RFEchoTrainLength),"RF Echo Train Length",
+                                        encountered_RFEchoTrainLength,shared_RFEchoTrainLength,perFrame_RFEchoTrainLength,
+                                        numberofinputfiles,i,filename,log);
+
+                                 trackSingleValuedUint32AttributePerFrame(list,TagFromName(GradientEchoTrainLength),"Gradient Echo Train Length",
+                                        encountered_GradientEchoTrainLength,shared_GradientEchoTrainLength,perFrame_GradientEchoTrainLength,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(SAR),"SAR",
+                                        encountered_SAR,shared_SAR,perFrame_SAR,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackMultiValuedUint32AttributePerFrame(list,TagFromName(AcquisitionMatrix),"Acquisition Matrix",4,
+					encountered_AcquisitionMatrix,shared_AcquisitionMatrix,perFrame_AcquisitionMatrix,
+                                        numberofinputfiles,i,filename,log);
+
+				// these aren't in the original single frame MR object, but may be manually inserted into source
+				// images to be able to build a correct MR multi-frame ...
+				
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(ComplexImageComponent),"Complex Image Component",
+ 					encountered_ComplexImageComponent,shared_ComplexImageComponent,perFrame_ComplexImageComponent,
+                                        numberofinputfiles,i,filename,log);
+					
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(AcquisitionContrast),"Acquisition Contrast",
+					encountered_AcquisitionContrast,shared_AcquisitionContrast,perFrame_AcquisitionContrast,
+					numberofinputfiles,i,filename,log);
+					
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(DiffusionBValue),"Diffusion b-value",
+                                        encountered_DiffusionBValue,shared_DiffusionBValue,perFrame_DiffusionBValue,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedStringAttributePerFrame(list,TagFromName(DiffusionDirectionality),"Diffusion Directionality",
+ 					encountered_DiffusionDirectionality,shared_DiffusionDirectionality,perFrame_DiffusionDirectionality,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(GradientOutput),"Gradient Output",
+                                        encountered_GradientOutput,shared_GradientOutput,perFrame_GradientOutput,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(GradientOutputType),"Gradient Output Type",
+					encountered_GradientOutputType,shared_GradientOutputType,perFrame_GradientOutputType,
+                                        numberofinputfiles,i,filename,log);
+					
+				trackMultiValuedDoubleAttributePerFrame(list,TagFromName(VelocityEncodingDirection),"Velocity Encoding Direction",3,
+					encountered_VelocityEncodingDirection,shared_VelocityEncodingDirection,perFrame_VelocityEncodingDirection,
+					numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(VelocityEncodingMinimumValue),"Velocity Encoding Minimum Value",
+                                        encountered_VelocityEncodingMinimumValue,shared_VelocityEncodingMinimumValue,perFrame_VelocityEncodingMinimumValue,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedDoubleAttributePerFrame(list,TagFromName(VelocityEncodingMaximumValue),"Velocity Encoding Maximum Value",
+                                        encountered_VelocityEncodingMaximumValue,shared_VelocityEncodingMaximumValue,perFrame_VelocityEncodingMaximumValue,
+                                        numberofinputfiles,i,filename,log);
+
+				trackSingleValuedStringAttributePerFrame(list,TagFromName(MetaboliteMapDescription),"Metabolite Map Description",
+					encountered_MetaboliteMapDescription,shared_MetaboliteMapDescription,perFrame_MetaboliteMapDescription,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ChemicalShiftMinimumIntegrationLimitInppm),"Chemical Shift Minimum Integration Limit in ppm",
+                                        encountered_ChemicalShiftMinimumIntegrationLimitInppm,shared_ChemicalShiftMinimumIntegrationLimitInppm,perFrame_ChemicalShiftMinimumIntegrationLimitInppm,
+                                        numberofinputfiles,i,filename,log);
+
+                                trackSingleValuedDoubleAttributePerFrame(list,TagFromName(ChemicalShiftMaximumIntegrationLimitInppm),"Chemical Shift Maximum Integration Limit in ppm",
+                                        encountered_ChemicalShiftMaximumIntegrationLimitInppm,shared_ChemicalShiftMaximumIntegrationLimitInppm,perFrame_ChemicalShiftMaximumIntegrationLimitInppm,
+                                        numberofinputfiles,i,filename,log);
+			}
+                        
+                        if (i == 0) {
+//cerr << "Frame 0 so do the copying of attributes ... " << endl;				
+                                // delete any Data Set Trailing Padding which would otherwise follow pixel data ...
+
+                                list-=TagFromName(DataSetTrailingPadding);
+
+                                // delete PixelData ... written later ...
+
+                                list-=TagFromName(PixelData);
+
+                                if (copyAll) {
+					newList+=list;	// Copy (actually move) everything from old list for first frame to new list ...
+
+				}
+				else {
+					// Selectively copy what is needed from old list for first frame to new list ...
+//cerr << "Selectively copy what is needed from old list" << endl;				
+					copyPatientModule(newList,list);
+					copyGeneralStudyModule(newList,list);
+					copyPatientStudyModule(newList,list);
+					copyGeneralSeriesModule(newList,list,addMultiFrameMRStuff || addMultiFrameCTStuff);
+					copyFrameOfReferenceModule(newList,list);
+					copySynchronizationFrameOfReferenceModule(newList,list);
+					copyGeneralEquipmentModule(newList,list);
+					copyImagePixelModule(newList,list);
+					if (!addEnhancedContrastBolusModuleAndMacro) {
+						copyContrastBolusModule(newList,list);
+					}
+					copySoftcopyPresentationLUTModule(newList,list);
+					copyAcquisitionContextModule(newList,list);
+					copySOPCommonModule(newList,list);
+				
+					if (addMultiFrameSecondaryCaptureStuff) {
+						copySCEquipmentModule(newList,list);
+						copyGeneralImageModule(newList,list);
+						copyCineModule(newList,list);
+						copyMultiFrameModule(newList,list);
+						copyFramePointersModule(newList,list);
+						copySCImageModule(newList,list);
+						copySCMultiFrameImageModule(newList,list);
+						copySCMultiFrameVectorModule(newList,list);
+					}
+					else if (addMultiFrameMRStuff || addMultiFrameCTStuff) {
+						// for Enhanced MR or CT Image Module ...
+						copyAttributeIfNotAlreadyPresent(TagFromName(LossyImageCompression),newList,list);
+						copyAttributeIfNotAlreadyPresent(TagFromName(LossyImageCompressionRatio),newList,list);
+						copyAttributeIfNotAlreadyPresent(TagFromName(IconImageSequence),newList,list);
+						copyAttributeIfNotAlreadyPresent(TagFromName(BurnedInAnnotation),newList,list);
+						if (!newList[TagFromName(BurnedInAnnotation)]) {
+							newList+=new CodeStringAttribute(TagFromName(BurnedInAnnotation),"NO");
+						}
+					}
+					else {	// do not know what we are making ...
+						copyGeneralImageModule(newList,list);
+						copyCineModule(newList,list);
+						copyMultiFrameModule(newList,list);
+						copyFramePointersModule(newList,list);
+					}
+				}
+				// Regardless, cannot use (old) list after this point
+                                
+                                if (!useExtraPixelDataWritePass) {
+//cerr << "Write of newList on 1st frame" << endl;
+                                        if (!usualManagedAttributeListWrite(newList,dout,dicom_output_options,log,veryverbose)) {
+                                                success=false;
+                                                break;
+                                        }
+
+                                        // Now add "empty" pixel data attribute without pixels but correct value length ...
+
+                                        OtherUnspecifiedLargeAttributeDummy *dummyPixelData = new
+                                                OtherUnspecifiedLargeAttributeDummy(TagFromName(PixelData),
+                                                        requiredRows,requiredColumns,numberofinputfiles,requiredSamplesPerPixel,
+                                                        dout.getTransferSyntaxToWriteDataSet(),
+                                                        0 /* let encoding rules calculate bytesinword */,
+                                                        requiredBitsAllocated,requiredBitsStored,requiredHighBit,
+                                                        0xffffffff /* let encoding rules calculate length */);
+                                        Assert(dummyPixelData);
+
+                                        dummyPixelData->writeBase(dout);
+
+                                        if (veryverbose) {
+                                                dummyPixelData->writeBase(log,&staticDictionary,false);
+                                                log << "[]" << endl;
+                                        }
+                                }
+                        }
+
+                        if (!useExtraPixelDataWritePass && apixeldata) {
+//cerr << "Writing pixel data on first pass (non-deferred)" << endl;
+                                if (!apixeldata->isOtherData()) {
+                                        log << EMsgDC(PixelDataIncorrectVR) << endl;
+                                        success=false;
+                                        break;
+                                }
+                                else {
+                                        // Check for compatible transfer syntax and append to pixel data ...
+                                        TransferSyntax *its=din.getTransferSyntaxToReadDataSet();
+                                        Assert(its);
+                                        TransferSyntax *ots=dout.getTransferSyntaxToWriteDataSet();
+                                        Assert(ots);
+
+                                        if (its->isEncapsulated()) {
+                                                log << "Can't read encapsulated transfer syntax from file <" << filename << ">" << endl;
+                                                success=false;
+                                                break;
+                                        }
+                                        else if (its->getEndian() != ots->getEndian()) {
+                                                log << "Input byte order in input file <" << filename << "> differs from output - not supported" << endl;
+                                                success=false;
+                                                break;
+                                        }
+                                        else {
+                                                OtherUnspecifiedLargeAttributeBase *opixeldata = apixeldata->castToOtherData();
+                                                Assert(opixeldata);
+                                                opixeldata->writeRaw(dout);
+
+                                                if (verbose) log << "wrote frame " << i
+							 << " from filename <" << filename << ">" << endl;
+                                        }
+                                }
+                        }
+                        
+                        if (i == numberofinputfiles-1) {
+                                if (addMultiFrameMRStuff || addMultiFrameCTStuff) {
+//cerr << "Adding MF stuff" << endl;
+					// Keep track of this in case needed to generate CT Position Sequence (used to generate position along slice normals)
+					double *reference_ImagePositionPatient = perFrame_ImagePositionPatient
+						? perFrame_ImagePositionPatient[0]
+						: (encountered_ImagePositionPatient ? shared_ImagePositionPatient : NULL);
+						
+					// Build the MultiFrame Dimension Module ...
+//cerr << "Build the MultiFrame Dimension Module" << endl;
+
+					// DimensionOrganizationSequence is Type 2 ... always add it
+					SequenceAttribute *aDimensionOrganizationSequence=new SequenceAttribute(TagFromName(DimensionOrganizationSequence));
+					Assert(aDimensionOrganizationSequence);
+					newList-=TagFromName(DimensionOrganizationSequence);
+					newList+=aDimensionOrganizationSequence;
+					if (!minimalAttributesOnly && nDimensionOrganizations) {
+						// but only create and add a UID if there really are any dimensions
+						for (int ido=0; ido<nDimensionOrganizations; ++ido) {
+							Assert(dimensionOrganizationUIDs);
+							if (dimensionOrganizationUIDs[ido] == NULL || strlen(dimensionOrganizationUIDs[ido]) == 0) {
+								dimensionOrganizationUIDs[ido] = StrDup(GeneratedDimensionOrganizationUID(dicom_output_options.stamp,
+									studyIDForUIDGeneration,seriesNumberForUIDGeneration,ido));
+							}
+							AttributeList *iDimensionOrganizationSequence = new AttributeList();
+							Assert(iDimensionOrganizationSequence);
+							(*aDimensionOrganizationSequence)+=iDimensionOrganizationSequence;
+							(*iDimensionOrganizationSequence)+=new UIStringAttribute(TagFromName(DimensionOrganizationUID),dimensionOrganizationUIDs[ido]);
+						}
+					}
+					// DimensionIndexSequence is also Type 2 ... always add it
+					SequenceAttribute *aDimensionIndexSequence=new SequenceAttribute(TagFromName(DimensionIndexSequence));
+					Assert(aDimensionIndexSequence);
+					newList-=TagFromName(DimensionIndexSequence);
+					newList+=aDimensionIndexSequence;
+					if (!minimalAttributesOnly) {
+						for (int ido=0; ido<nDimensionOrganizations; ++ido) {
+							Assert(nDimensions);
+							for (int d=0; d<nDimensions[ido]; ++d) {
+								AttributeList *iDimensionIndexSequence = new AttributeList();
+								Assert(iDimensionIndexSequence);
+								(*aDimensionIndexSequence)+=iDimensionIndexSequence;
+								Assert(dimensionIndexPointers[0]);
+								(*iDimensionIndexSequence)+=new AttributeTagAttribute(TagFromName(DimensionIndexPointer),dimensionIndexPointers[ido][d]);
+								Assert(dimensionFunctionalGroupPointers);
+								(*iDimensionIndexSequence)+=new AttributeTagAttribute(TagFromName(FunctionalGroupPointer),dimensionFunctionalGroupPointers[ido][d]);
+								Assert(dimensionOrganizationUIDs);
+								Assert(dimensionOrganizationUIDs[ido]);
+								Assert(strlen(dimensionOrganizationUIDs[ido]));
+								(*iDimensionIndexSequence)+=new UIStringAttribute(TagFromName(DimensionOrganizationUID),dimensionOrganizationUIDs[ido]);
+							}
+						}
+					}
+					
+					if (addSynchronizationModule) {
+//cerr << "Build the Synchronization Module" << endl;
+						// The SynchronizationFrameOfReferenceUID will be added during the usual list write
+						// because of the presence of the following attributes of the module
+						// (can't do it now because will be removed if -removeinstanceuid option)
+
+						if (!newList[TagFromName(SynchronizationTrigger)]) {
+			 				newList+=new CodeStringAttribute(TagFromName(SynchronizationTrigger),"NO TRIGGER");
+						}
+						if (!newList[TagFromName(AcquisitionTimeSynchronized)]) {
+							newList+=new CodeStringAttribute(TagFromName(AcquisitionTimeSynchronized),"Y");
+						}
+					}
+					
+					// Build the common part of the Multi-frame Functional Groups Module (as refactored by Sup 58) ...
+//cerr << "Build the common part of the Multi-frame Functional Groups Module" << endl;
+
+					newList-=TagFromName(InstanceNumber);
+					newList+=new IntegerStringAttribute(TagFromName(InstanceNumber),Uint16(1));
+
+					addEarliestContentDateAndTime(newList,numberofinputfiles,
+						encountered_ContentDate,shared_ContentDate,perFrame_ContentDate,
+						encountered_ContentTime,shared_ContentTime,perFrame_ContentTime,
+						log);
+
+					newList-=TagFromName(NumberOfFrames);
+					newList+=new IntegerStringAttribute(TagFromName(NumberOfFrames),Uint16(numberofinputfiles));
+/*
+                Element <ConcatenationFrameOffsetNumber> not present
+                Element <RepresentativeFrameNumber> not present
+                Element <ConcatenationUID> not present
+                Element <InConcatenationNumber> not present
+                Element <InConcatenationTotalNumber> not present
+*/
+					
+					// Build the Enhanced MR and CT Image Modules ...
+//cerr << "Build the Enhanced MR and CT Image Modules" << endl;
+					
+					bool imageIsDerived = makeCTMRImageDescriptionMacroAttributesAndAppendToList(addMultiFrameMRStuff,
+						newList,false /* frame level */,0,numberofinputfiles,
+						encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+						encountered_PixelPresentation,shared_PixelPresentation,perFrame_PixelPresentation,
+						encountered_VolumetricProperties,shared_VolumetricProperties,perFrame_VolumetricProperties,
+						encountered_VolumeBasedCalculationTechnique,shared_VolumeBasedCalculationTechnique,perFrame_VolumeBasedCalculationTechnique,
+						encountered_ComplexImageComponent,shared_ComplexImageComponent,perFrame_ComplexImageComponent,
+						encountered_AcquisitionContrast,shared_AcquisitionContrast,perFrame_AcquisitionContrast,
+						log);
+//cerr << "imageIsDerived= " << (imageIsDerived ? "T" : "F") << endl;
+
+					if (!newList[TagFromName(LossyImageCompression)])					// since might have been copied from 1st file in copyGeneralImageModule()
+						newList+=new CodeStringAttribute(TagFromName(LossyImageCompression),"00");	// let's just assume they weren't ... should really check each frame :(
+
+					// Build the MR Image and Spectroscopy Instance Macro, and the same attributes that are in the Enhanced CT Image Module
+//cerr << "Build the MR Image and Spectroscopy Instance Macro" << endl;
+					
+					if (encountered_AcquisitionNumber && !perFrame_AcquisitionNumber) {
+						newList-=TagFromName(AcquisitionNumber);
+						if (!minimalAttributesOnly) newList+=new IntegerStringAttribute(TagFromName(AcquisitionNumber),shared_AcquisitionNumber);
+					}
+					
+					if (!imageIsDerived || addNonDerivedStuffAnyway) {
+						if (addMultiFrameMRStuff) {
+							copyImagedNucleusIntoResonantNucleusIfNotAlreadyPresent(newList,list);
+							copyAttributeIfNotAlreadyPresent(TagFromName(MagneticFieldStrength),newList,list);
+							copyAttributeIfNotAlreadyPresent(TagFromName(KSpaceFiltering),newList,list);
+							if (!newList[TagFromName(KSpaceFiltering)]) {
+								newList+=new CodeStringAttribute(TagFromName(KSpaceFiltering),"NONE");
+							}
+						}
+						addEarliestAcquisitionDateAndTime(newList,numberofinputfiles,
+							encountered_AcquisitionDate,shared_AcquisitionDate,perFrame_AcquisitionDate,
+							encountered_AcquisitionTime,shared_AcquisitionTime,perFrame_AcquisitionTime,
+							log);
+					
+						double use_AcquisitionDuration;
+						if (addMultiFrameMRStuff && deriveDurationFromTiming) {
+							// should do better if varies per frame than just use frame 0 values :(
+							use_AcquisitionDuration=computeAcquisitionDurationInMilliSecondsFromTiming(
+								encountered_RepetitionTime,shared_RepetitionTime,perFrame_RepetitionTime,
+								encountered_NumberOfAverages,shared_NumberOfAverages,perFrame_NumberOfAverages,
+								encountered_AcquisitionMatrix,shared_AcquisitionMatrix,perFrame_AcquisitionMatrix,
+								encountered_EchoTrainLength,shared_EchoTrainLength,perFrame_EchoTrainLength,
+								encountered_ScanningSequence,shared_ScanningSequence,perFrame_ScanningSequence,nValues_ScanningSequence,
+								0)/1000;
+						}
+						else {
+							use_AcquisitionDuration = encountered_AcquisitionDuration ? (perFrame_AcquisitionDuration ? 0 : shared_AcquisitionDuration) : 0;
+						}
+						if (accumulateDuration) use_AcquisitionDuration=use_AcquisitionDuration*numberofinputfiles;
+						newList+=(minimalAttributesOnly && !addMultiFrameMRStuff)
+							? new FloatDoubleAttribute(TagFromName(AcquisitionDuration))	// is Type 2C for CT, 1C for MR
+							: new FloatDoubleAttribute(TagFromName(AcquisitionDuration),use_AcquisitionDuration);
+					}
+					
+					// Add ReferencedRawDataSequence derived from AcquisitionNumber
+					if (!minimalAttributesOnly && encountered_AcquisitionNumber) {
+						SequenceAttribute *aReferencedRawDataSequence=new SequenceAttribute(TagFromName(ReferencedRawDataSequence));
+						Assert(aReferencedRawDataSequence);
+						newList-=TagFromName(ReferencedRawDataSequence);
+						newList+=aReferencedRawDataSequence;
+						
+						int useAcquisitionNumber = perFrame_AcquisitionNumber ? perFrame_AcquisitionNumber[0] : shared_AcquisitionNumber;
+						{
+							AttributeList *iReferencedRawDataSequence = new AttributeList();
+							Assert(iReferencedRawDataSequence);
+							(*aReferencedRawDataSequence)+=iReferencedRawDataSequence;
+							
+							Attribute *aStudyInstanceUID=new UIStringAttribute(TagFromName(StudyInstanceUID),
+								GeneratedStudyInstanceUID(dicom_output_options.stamp,studyIDForUIDGeneration));
+							Assert(aStudyInstanceUID);
+							(*iReferencedRawDataSequence)+=aStudyInstanceUID;
+								
+							SequenceAttribute *aReferencedSeriesSequence=new SequenceAttribute(TagFromName(ReferencedSeriesSequence));
+							Assert(aReferencedSeriesSequence);
+							(*iReferencedRawDataSequence)+=aReferencedSeriesSequence;
+
+							AttributeList *iReferencedSeriesSequence = new AttributeList();
+							Assert(iReferencedSeriesSequence);
+							(*aReferencedSeriesSequence)+=iReferencedSeriesSequence;
+							
+							Attribute *aSeriesInstanceUID=new UIStringAttribute(TagFromName(SeriesInstanceUID),
+								GeneratedSeriesInstanceUID(dicom_output_options.stamp,studyIDForUIDGeneration,seriesNumberForUIDGeneration));
+							Assert(aSeriesInstanceUID);
+							(*iReferencedSeriesSequence)+=aSeriesInstanceUID;
+								
+							SequenceAttribute *aReferencedSOPSequence=new SequenceAttribute(TagFromName(ReferencedSOPSequence));
+							Assert(aReferencedSOPSequence);
+							(*iReferencedSeriesSequence)+=aReferencedSOPSequence;
+
+							AttributeList *iReferencedSOPSequence = new AttributeList();
+							Assert(iReferencedSOPSequence);
+							(*aReferencedSOPSequence)+=iReferencedSOPSequence;
+							
+							Attribute *aReferencedSOPInstanceUID=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),
+								GeneratedRawDataUID(dicom_output_options.stamp,studyIDForUIDGeneration,useAcquisitionNumber));
+							Assert(aReferencedSOPInstanceUID);
+							(*iReferencedSOPSequence)+=aReferencedSOPInstanceUID;
+							
+							Attribute *aReferencedSOPClassUID=new UIStringAttribute(TagFromName(ReferencedSOPClassUID),RawDataStorageSOPClassUID);
+							Assert(aReferencedSOPClassUID);
+							(*iReferencedSOPSequence)+=aReferencedSOPClassUID;
+						}
+					}
+/*
+                Sequence <ReferencedWaveformSequence> not present
+                Sequence <ReferencedImageEvidenceSequence> not present
+                Sequence <SourceImageEvidenceSequence> not present
+                Sequence <ReferencedGrayscalePresentationStateSequence> not present
+*/
+					newList-=TagFromName(ContentQualification);
+					newList+=new CodeStringAttribute(TagFromName(ContentQualification),"PRODUCT");
+
+					if (addMultiFrameMRStuff) {
+						// ResonantNucleus copied from ImagedNucleus earlier
+						// MagneticFieldStrength copied earlier
+
+						newList-=TagFromName(ApplicableSafetyStandardAgency);
+						newList+=new CodeStringAttribute(TagFromName(ApplicableSafetyStandardAgency),"FDA");
+
+						if (minimalAttributesOnly) {
+							// remove anything optional that might have been copied earlier from 1st file
+							newList-=TagFromName(ApplicableSafetyStandardDescription);
+						}
+					}
+					
+					if (minimalAttributesOnly) {
+						// remove anything optional that might have been copied earlier from 1st file
+						newList-=TagFromName(ImageComments);
+					}
+					
+					// SamplesPerPixel should already be 1
+					// PhotometricInterpretation should already be MONOCHROME2
+					// LargestMonochromePixelValue is no longer used
+					// BitsAllocated has to be 8 or 16 for MR; 16 for CT
+					// BitStored has to be 8, 12 or 16 for MR; 12 or 16 for CT
+					{
+						Uint16 vBitsStored = getIntegerValueElseError(newList,TagFromName(BitsStored),"Bits Stored",filename,log);
+						Uint16 nBitsStored = vBitsStored;
+						if (addMultiFrameMRStuff) {
+							if (nBitsStored < 8) nBitsStored=8;
+							else if (nBitsStored > 8 && nBitsStored < 12) nBitsStored=12;
+							else if (nBitsStored > 12 && nBitsStored < 16) nBitsStored=16;
+						}
+						else {
+							if (nBitsStored < 16) nBitsStored=16;
+							else if (nBitsStored <= 12) nBitsStored=12;
+							else if (nBitsStored <= 16) nBitsStored=16;
+						}
+						if (nBitsStored != vBitsStored) {
+							if (verbose) log << "Changing Bits Stored from " << dec << vBitsStored << " to " << nBitsStored << endl;
+							newList-=TagFromName(BitsStored);
+							newList+=new UnsignedShortAttribute(TagFromName(BitsStored),nBitsStored);
+						}
+					}
+					// HighBit has to be one less than BitStored
+					{
+						Uint16 vBitsStored = getIntegerValueElseError(newList,TagFromName(BitsStored),"Bits Stored",filename,log);
+						Uint16 vHighBit = getIntegerValueElseError(newList,TagFromName(HighBit),"High Bit",filename,log);
+						Uint16 nHighBit = vHighBit;
+						if (nHighBit != vBitsStored-1) nHighBit=vBitsStored-1;
+						
+						if (nHighBit != vHighBit) {
+							if (verbose) log << "Changing High Bit from " << dec << vHighBit << " to " << nHighBit << endl;
+							newList-=TagFromName(HighBit);
+							newList+=new UnsignedShortAttribute(TagFromName(HighBit),nHighBit);
+						}
+					}
+					
+					if (minimalAttributesOnly) {
+						// remove anything optional that might have been copied earlier from 1st file
+						newList-=TagFromName(SpacingBetweenSlices);	// an MR thing
+						newList-=TagFromName(IconImageSequence);
+					}
+					
+					// LossyImageCompression	copied earlier from 1st file
+					// LossyImageCompressionRatio	copied earlier from 1st file
+					
+					// Set a flag that indicates whether or not to add the MR-specific stuff
+					// which is required if value 1 of Image Type is ORIGINAL or MIXED
+					// but also add it if we encountered Scanning Sequence in the input
+					// (i.e. make it even for DERIVED if we may have enough information to make it from)
+					
+					//bool addMROriginalOrMixedStuff;
+					//{
+					//	const char *imageTypeValue1 = AttributeValue(newList[TagFromName(ImageType)]);
+					//	addMROriginalOrMixedStuff = imageTypeValue1 && (
+					//				   strcmp(imageTypeValue1,"ORIGINAL") == 0
+					//				|| strcmp(imageTypeValue1,"MIXED") == 0
+					//				// || encountered_ScanningSequence
+					//				);
+					//}
+ 					
+					//if (addMROriginalOrMixedStuff)
+					if (addMultiFrameMRStuff && (!imageIsDerived || addNonDerivedStuffAnyway)) {
+						makeMRPulseSequenceModule(&newList,numberofinputfiles,
+								requiredSequenceName,requiredProtocolName,requiredMRAcquisitionType,
+								encountered_ScanningSequence,shared_ScanningSequence,perFrame_ScanningSequence,nValues_ScanningSequence,
+								encountered_SequenceVariant,shared_SequenceVariant,perFrame_SequenceVariant,nValues_SequenceVariant,
+								encountered_ScanOptions,shared_ScanOptions,perFrame_ScanOptions,nValues_ScanOptions,
+								encountered_EchoNumbers,shared_EchoNumbers,perFrame_EchoNumbers,
+								encountered_VelocityEncodingDirection,shared_VelocityEncodingDirection,perFrame_VelocityEncodingDirection,
+								phaseContrast);
+					}
+ 					// Build the Softcopy Presentation LUT Module ...
+//cerr << "Build the Softcopy Presentation LUT Module" << endl;
+					newList+=new CodeStringAttribute(TagFromName(PresentationLUTShape),"IDENTITY");
+
+					if (addSupplementalPaletteColorLUT) {
+						makeSupplementalPaletteColorLUT(
+							&newList,
+							minimalAttributesOnly,
+							addSupplementalPaletteColorLUT_numberOfEntries,
+							addSupplementalPaletteColorLUT_firstValueMapped,
+							addSupplementalPaletteColorLUT_firstRedValue,
+							addSupplementalPaletteColorLUT_incrementRedValue,
+							addSupplementalPaletteColorLUT_entryToStartIncrementingRedValue,
+							addSupplementalPaletteColorLUT_entryToStartDecrementingRedValue,
+							addSupplementalPaletteColorLUT_entryToStopChangingRedValue,
+							addSupplementalPaletteColorLUT_firstGreenValue,
+							addSupplementalPaletteColorLUT_incrementGreenValue,
+							addSupplementalPaletteColorLUT_entryToStartIncrementingGreenValue,
+							addSupplementalPaletteColorLUT_entryToStartDecrementingGreenValue,
+							addSupplementalPaletteColorLUT_entryToStopChangingGreenValue,
+							addSupplementalPaletteColorLUT_firstBlueValue,
+							addSupplementalPaletteColorLUT_incrementBlueValue,
+							addSupplementalPaletteColorLUT_entryToStartIncrementingBlueValue,
+							addSupplementalPaletteColorLUT_entryToStartDecrementingBlueValue,
+							addSupplementalPaletteColorLUT_entryToStopChangingBlueValue);
+					}
+
+					if (addEnhancedContrastBolusModuleAndMacro) {
+						makeEnhancedContrastBolusModule(&newList,
+						encountered_ContrastBolusAgent,shared_ContrastBolusAgent,perFrame_ContrastBolusAgent,nValues_ContrastBolusAgent,
+						encountered_ContrastBolusRoute,shared_ContrastBolusRoute,perFrame_ContrastBolusRoute,nValues_ContrastBolusRoute,
+						encountered_ContrastBolusVolume,shared_ContrastBolusVolume,perFrame_ContrastBolusVolume,nValues_ContrastBolusVolume,
+						encountered_ContrastBolusIngredientConcentration,shared_ContrastBolusIngredientConcentration,
+							perFrame_ContrastBolusIngredientConcentration,nValues_ContrastBolusIngredientConcentration);
+					}
+					
+					// Add the attributes tracked per frame to either the shared or per-frame function groups ...
+					
+					const char *vEchoPulseSequence = NULL;					// Need this for making echo train lengths
+					{
+						Attribute *a = newList[TagFromName(EchoPulseSequence)];		// filled in as GRADIENT, SPIN or BOTH by makeMRPulseSequenceModule
+						if (a) {							// can be misssing, e.g. derived
+							vEchoPulseSequence = AttributeValue(a);
+						}
+					}
+										
+					bool frameAnatomySequenceDoneAtSharedLevel = false;
+					//bool frameIsDerived = false;
+                                        
+                                        SequenceAttribute *aAcquisitionContextSequence=new SequenceAttribute(TagFromName(AcquisitionContextSequence));
+                                        Assert(aAcquisitionContextSequence);
+                                        newList-=TagFromName(AcquisitionContextSequence);
+                                        newList+=aAcquisitionContextSequence;
+                                        
+                                        SequenceAttribute *aPerFrameFunctionalGroupsSequence=new SequenceAttribute(TagFromName(PerFrameFunctionalGroupsSequence));
+                                        Assert(aPerFrameFunctionalGroupsSequence);
+                                        newList-=TagFromName(PerFrameFunctionalGroupsSequence);
+                                        newList+=aPerFrameFunctionalGroupsSequence;
+                                
+                                        SequenceAttribute *aSharedFunctionalGroupsSequence=new SequenceAttribute(TagFromName(SharedFunctionalGroupsSequence));
+                                        Assert(aSharedFunctionalGroupsSequence);
+                                        newList-=TagFromName(SharedFunctionalGroupsSequence);
+                                        newList+=aSharedFunctionalGroupsSequence;
+                                        
+                                        AttributeList *iSharedFunctionalGroupsSequence = new AttributeList();
+                                        Assert(iSharedFunctionalGroupsSequence);
+                                        (*aSharedFunctionalGroupsSequence)+=iSharedFunctionalGroupsSequence;
+//cerr << "adding shared functional groups" << endl;
+                                        if (perFrame_SliceThickness == NULL
+					 && perFrame_PixelSpacing == NULL) {
+						AttributeList *iPixelMeasuresSequence = makeNewSequenceAttributeWithItem(
+							iSharedFunctionalGroupsSequence,TagFromName(PixelMeasuresSequence));
+                                                if (encountered_SliceThickness)
+							(*iPixelMeasuresSequence)+=new DecimalStringAttribute(TagFromName(SliceThickness),shared_SliceThickness);
+                                                if (encountered_PixelSpacing)
+							(*iPixelMeasuresSequence)+=new DecimalStringAttribute(TagFromName(PixelSpacing),shared_PixelSpacing[0],shared_PixelSpacing[1]);
+                                        }
+                                        if (perFrame_ImagePositionPatient == NULL) {
+						AttributeList *iPlanePositionSequence = makeNewSequenceAttributeWithItem(
+							iSharedFunctionalGroupsSequence,TagFromName(PlanePositionSequence));
+                                                if (encountered_ImagePositionPatient && (!imageIsDerived || addNonDerivedStuffAnyway || addPositionStuffAnyway))
+							(*iPlanePositionSequence)+=new DecimalStringAttribute(TagFromName(ImagePositionPatient),
+								shared_ImagePositionPatient[0],shared_ImagePositionPatient[1],shared_ImagePositionPatient[2]);
+                                        }
+                                         if (perFrame_ImageOrientationPatient == NULL) {
+						AttributeList *iPlaneOrientationSequence = makeNewSequenceAttributeWithItem(
+							iSharedFunctionalGroupsSequence,TagFromName(PlaneOrientationSequence));
+                                                if (encountered_ImageOrientationPatient && (!imageIsDerived || addNonDerivedStuffAnyway || addPositionStuffAnyway))
+							(*iPlaneOrientationSequence)+=new DecimalStringAttribute(TagFromName(ImageOrientationPatient),
+								shared_ImageOrientationPatient[0],shared_ImageOrientationPatient[1],shared_ImageOrientationPatient[2],
+								shared_ImageOrientationPatient[3],shared_ImageOrientationPatient[4],shared_ImageOrientationPatient[5]);
+                                        }
+                                        if (perFrame_NominalCardiacTriggerDelayTime == NULL
+					 && perFrame_TriggerTime == NULL
+					 && perFrame_RRIntervalTimeNominal == NULL
+					 /*&& perFrame_TriggerWindow == NULL*/) {
+                                                if (encountered_TriggerTime || encountered_NominalCardiacTriggerDelayTime || encountered_RRIntervalTimeNominal/* || encountered_TriggerWindow*/) {
+							AttributeList *iCardiacSynchronizationSequence = makeNewSequenceAttributeWithItem(
+								iSharedFunctionalGroupsSequence,TagFromName(CardiacSynchronizationSequence));
+							double use_NominalCardiacTriggerDelayTime = encountered_TriggerTime ?  shared_TriggerTime : shared_NominalCardiacTriggerDelayTime;
+							(*iCardiacSynchronizationSequence)+=new FloatDoubleAttribute(TagFromName(NominalCardiacTriggerDelayTime),use_NominalCardiacTriggerDelayTime);
+							if (encountered_RRIntervalTimeNominal) {
+								(*iCardiacSynchronizationSequence)+=new FloatDoubleAttribute(TagFromName(RRIntervalTimeNominal),shared_RRIntervalTimeNominal);
+							}
+							//if (encountered_TriggerWindow) {
+							//	(*iCardiacSynchronizationSequence)+=new IntegerStringAttribute(TagFromName(TriggerWindow),Uint16(shared_TriggerWindow));
+							//}
+						}
+					}
+                    if ((perFrame_WindowCenter == NULL
+					 && perFrame_WindowWidth == NULL
+					 && perFrame_WindowCenterWidthExplanation == NULL) || nowindow) {
+						if (minimalAttributesOnly || nowindow) {
+							// Do NOT add empty FrameVOILUTSequence ... changed from Type 2 to Type 1 by Sup 83, but is U macro in CT and MR
+							//(void)makeNewSequenceAttributeWithoutItem(iSharedFunctionalGroupsSequence,TagFromName(FrameVOILUTSequence));
+						}
+						else {
+							AttributeList *iFrameVOILUTSequence = makeNewSequenceAttributeWithItem(
+								iSharedFunctionalGroupsSequence,TagFromName(FrameVOILUTSequence));
+							(*iFrameVOILUTSequence)+=new DecimalStringAttribute(TagFromName(WindowCenter),encountered_WindowCenter ? shared_WindowCenter : defaultWindowCenter);
+							(*iFrameVOILUTSequence)+=new DecimalStringAttribute(TagFromName(WindowWidth),encountered_WindowWidth ? shared_WindowWidth : defaultWindowWidth);
+							if (encountered_WindowCenterWidthExplanation) {
+								(*iFrameVOILUTSequence)+=new LongStringAttribute(TagFromName(WindowCenterWidthExplanation),shared_WindowCenterWidthExplanation);
+							}
+						}
+                    }
+					{
+						frameAnatomySequenceDoneAtSharedLevel=makeFrameAnatomySequence(iSharedFunctionalGroupsSequence,
+							false /*frameLevel*/,0,
+							encountered_BodyPartExamined,shared_BodyPartExamined,perFrame_BodyPartExamined,
+							encountered_StudyDescription,shared_StudyDescription,perFrame_StudyDescription,
+							encountered_SeriesDescription,shared_SeriesDescription,perFrame_SeriesDescription,
+							encountered_ImageComments,shared_ImageComments,perFrame_ImageComments,
+							encountered_PatientName,shared_PatientName,perFrame_PatientName,
+							encountered_Laterality,shared_Laterality,perFrame_Laterality);
+					}
+                                        if (perFrame_RescaleSlope == NULL
+					 && perFrame_RescaleIntercept == NULL
+					 && perFrame_RescaleType == NULL) {
+//cerr << "adding shared PixelValueTransformationSequence" << endl;
+						AttributeList *iPixelValueTransformationSequence = makeNewSequenceAttributeWithItem(
+							iSharedFunctionalGroupsSequence,TagFromName(PixelValueTransformationSequence));
+						double use_intercept = encountered_RescaleIntercept ? shared_RescaleIntercept : 0.0;
+						double use_slope = encountered_RescaleSlope ? shared_RescaleSlope : 1.0;
+						if (use_slope == 0) {
+							use_slope=1.0;	// a slope of zero means it was probably missing for that frame
+							use_intercept=0.0;
+						}
+						const char *use_type = encountered_RescaleType ? shared_RescaleType : NULL;
+						use_type=fixRescaleTypeForCTIfNecessary(use_type,addMultiFrameCTStuff,imageIsDerived);
+//cerr << "adding RescaleIntercept" << endl;
+                                                (*iPixelValueTransformationSequence)+=new DecimalStringAttribute(TagFromName(RescaleIntercept),use_intercept);
+//cerr << "adding RescaleSlope" << endl;
+                                                (*iPixelValueTransformationSequence)+=new DecimalStringAttribute(TagFromName(RescaleSlope),use_slope);
+//cerr << "adding RescaleType = " << use_type << endl;
+						(*iPixelValueTransformationSequence)+=new LongStringAttribute(TagFromName(RescaleType),use_type);
+                                        }
+					if (addDerivation && !forceDerivationPerFrame) {
+						makeDerivationImageSequence(
+							iSharedFunctionalGroupsSequence,
+							minimalAttributesOnly,
+							addDerivation_derivationCodeSequenceCodingSchemeDesignator,
+							addDerivation_derivationCodeSequenceCodeValue,
+							addDerivation_derivationCodeSequenceCodeMeaning,
+							addDerivation_derivationCodeSequenceCodingSchemeVersion,
+							addDerivation_referencedSOPClassUID,
+							addDerivation_referencedSOPInstanceUID,
+							addDerivation_referencedFrameNumbers,
+							addDerivation_purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+							addDerivation_purposeOfReferenceCodeSequenceCodeValue,
+							addDerivation_purposeOfReferenceCodeSequenceCodeMeaning,
+							addDerivation_purposeOfReferenceCodeSequenceCodingSchemeVersion);
+					}
+					if (addReferenced && !forceReferencedPerFrame) {
+						makeReferencedImageSequence(
+							iSharedFunctionalGroupsSequence,
+							minimalAttributesOnly,
+							addReferenced_referencedSOPClassUID,
+							addReferenced_referencedSOPInstanceUID,
+							addReferenced_referencedFrameNumbers,
+							addReferenced_purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+							addReferenced_purposeOfReferenceCodeSequenceCodeValue,
+							addReferenced_purposeOfReferenceCodeSequenceCodeMeaning,
+							addReferenced_purposeOfReferenceCodeSequenceCodingSchemeVersion);
+					}
+					if (addMultiFrameMRStuff) {
+						if (addSatSlab_numberOfSlabs > 0) {
+							makeMRSpatialSaturationSequence(
+								iSharedFunctionalGroupsSequence,
+								minimalAttributesOnly,
+								addSatSlab_numberOfSlabs,
+								addSatSlab_thickness,	
+								addSatSlab_orientX,addSatSlab_orientY,addSatSlab_orientZ,	
+								addSatSlab_midpointX,addSatSlab_midpointY,addSatSlab_midpointZ);
+						}
+						else {
+							// we may need to add an empty MRSpatialSaturationSequence anyway
+							// since the condition on the macro is based on SpatialPresaturation being SLAB
+							// and ImageType value 1 ORIGINAL or MIXED
+							// 
+							// achieve this by scanning for any frame that may trigger SpatialPresaturation
+							// to be set to slab
+						
+							if (!imageIsDerived || addNonDerivedStuffAnyway) {
+								bool needSpatialPresaturationRegardless = false;
+								if (encountered_ScanOptions) {
+									if (shared_ScanOptions && arrayOfStringValuesContains(shared_ScanOptions,nValues_ScanOptions,"SP")) {
+										needSpatialPresaturationRegardless=true;
+									}
+									else if (perFrame_ScanOptions) {
+										int i;
+										for (int i=0; i<numberofinputfiles; ++i) {
+											if (perFrame_ScanOptions[i] && arrayOfStringValuesContains(perFrame_ScanOptions[i],nValues_ScanOptions,"SP")) {
+												needSpatialPresaturationRegardless=true;
+												break;
+											}
+										}
+									}
+								}
+								if (needSpatialPresaturationRegardless) {
+									(void)makeNewSequenceAttributeWithoutItem(iSharedFunctionalGroupsSequence,TagFromName(MRSpatialSaturationSequence));
+								}
+							}
+						}
+					}
+					if (perFrame_RealWorldValueSlope == NULL
+					 && perFrame_RealWorldValueIntercept == NULL
+					 && perFrame_Units == NULL
+					 && perFrame_RealWorldValueFirstValueMapped == NULL
+					 && perFrame_RealWorldValueLastValueMapped == NULL
+					 && perFrame_LUTExplanation == NULL
+					 && perFrame_LUTLabel == NULL) {
+//cerr << "adding shared RealWorldValueMappingSequence" << endl;
+						makeRealWorldValueMappingSequence(iSharedFunctionalGroupsSequence,0,pixelRepresentation,
+							encountered_RealWorldValueSlope,shared_RealWorldValueSlope,perFrame_RealWorldValueSlope,
+							encountered_RealWorldValueIntercept,shared_RealWorldValueIntercept,perFrame_RealWorldValueIntercept,
+							encountered_Units,shared_Units,perFrame_Units,
+							encountered_RealWorldValueFirstValueMapped,shared_RealWorldValueFirstValueMapped,perFrame_RealWorldValueFirstValueMapped,
+							encountered_RealWorldValueLastValueMapped,shared_RealWorldValueLastValueMapped,perFrame_RealWorldValueLastValueMapped,
+							encountered_LUTExplanation,shared_LUTExplanation,perFrame_LUTExplanation,
+							encountered_LUTLabel,shared_LUTLabel,perFrame_LUTLabel);
+					}
+					if (perFrame_ImageType == NULL
+					 && perFrame_PixelPresentation == NULL
+					 && perFrame_VolumetricProperties == NULL
+					 && perFrame_VolumeBasedCalculationTechnique == NULL
+					 && perFrame_ComplexImageComponent == NULL
+					 && perFrame_AcquisitionContrast == NULL) {
+//cerr << "adding shared MR or CT Image Frame Type Macro" << endl;
+						AttributeList *iImageFrameTypeSequence = makeNewSequenceAttributeWithItem(
+							iSharedFunctionalGroupsSequence,
+							addMultiFrameMRStuff ? TagFromName(MRImageFrameTypeSequence) : TagFromName(CTImageFrameTypeSequence));
+							
+						// include the MR Image Description Macro, using Frame Type not Image Type at this level
+						// (the same macro is also used in the Enhanced MR Image Module)
+							
+						/* frameIsDerived = */ makeCTMRImageDescriptionMacroAttributesAndAppendToList(addMultiFrameMRStuff,
+							*iImageFrameTypeSequence,true /* frame level */,0,numberofinputfiles,
+							encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+							encountered_PixelPresentation,shared_PixelPresentation,perFrame_PixelPresentation,
+							encountered_VolumetricProperties,shared_VolumetricProperties,perFrame_VolumetricProperties,
+							encountered_VolumeBasedCalculationTechnique,shared_VolumeBasedCalculationTechnique,perFrame_VolumeBasedCalculationTechnique,
+							encountered_ComplexImageComponent,shared_ComplexImageComponent,perFrame_ComplexImageComponent,
+							encountered_AcquisitionContrast,shared_AcquisitionContrast,perFrame_AcquisitionContrast,
+							log);							
+					}
+					if (addEnhancedContrastBolusModuleAndMacro) {
+						// regardless of original or derived ...
+						if (perFrame_ContrastBolusAgent == NULL
+						 && perFrame_ContrastBolusRoute == NULL
+						 && perFrame_ContrastBolusVolume == NULL
+						 && perFrame_ContrastBolusIngredientConcentration == NULL
+						 && perFrame_ContrastBolusAgentAdministered == NULL
+						 && perFrame_ContrastBolusAgentDetected == NULL
+						 && perFrame_ContrastBolusAgentPhase == NULL) {
+							makeContrastBolusUsageSequence(iSharedFunctionalGroupsSequence,0,
+								encountered_ContrastBolusAgent,shared_ContrastBolusAgent,perFrame_ContrastBolusAgent,nValues_ContrastBolusAgent,
+								encountered_ContrastBolusRoute,shared_ContrastBolusRoute,perFrame_ContrastBolusRoute,nValues_ContrastBolusRoute,
+								encountered_ContrastBolusVolume,shared_ContrastBolusVolume,perFrame_ContrastBolusVolume,nValues_ContrastBolusVolume,
+								encountered_ContrastBolusIngredientConcentration,shared_ContrastBolusIngredientConcentration,
+									perFrame_ContrastBolusIngredientConcentration,nValues_ContrastBolusIngredientConcentration,
+								encountered_ContrastBolusAgentAdministered,shared_ContrastBolusAgentAdministered,
+									perFrame_ContrastBolusAgentAdministered,nValues_ContrastBolusAgentAdministered,
+								encountered_ContrastBolusAgentDetected,shared_ContrastBolusAgentDetected,
+									perFrame_ContrastBolusAgentDetected,nValues_ContrastBolusAgentDetected,
+								encountered_ContrastBolusAgentPhase,shared_ContrastBolusAgentPhase,
+									perFrame_ContrastBolusAgentPhase,nValues_ContrastBolusAgentPhase);
+						}
+					}
+					if (addMultiFrameCTStuff) {
+						{
+							// Irradiation Event Identification is mandatory whether derived or not
+							if (perFrame_IrradiationEventUID == NULL) {
+//cerr << "adding per-frame IrradiationEventIdentificationSequence" << endl;
+								AttributeList *iIrradiationEventIdentificationSequence = makeNewSequenceAttributeWithItem(
+									iSharedFunctionalGroupsSequence,TagFromName(IrradiationEventIdentificationSequence));
+								(*iIrradiationEventIdentificationSequence)+=new UIStringAttribute(TagFromName(IrradiationEventUID),
+									encountered_IrradiationEventUID
+										? shared_IrradiationEventUID
+										: StrDup(GeneratedIrradiationEventUID(dicom_output_options.stamp,
+											studyIDForUIDGeneration,seriesNumberForUIDGeneration,instanceNumberForUIDGeneration))
+									);
+							}
+						}
+						if (!imageIsDerived || addNonDerivedStuffAnyway) {	// NB. not !frameIsDerived, since values may be shared but frame type value 1 varies per-frame
+//cerr << "Adding CT-specific stuff for non-derived image at shared level" << endl;
+							if (perFrame_AcquisitionType == NULL
+							 && perFrame_TubeAngle == NULL
+							 && perFrame_ConstantVolumeFlag == NULL
+							 && perFrame_FluoroscopyFlag == NULL) {
+								makeCTAcquisitionTypeSequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+									encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+									encountered_TubeAngle,shared_TubeAngle,perFrame_TubeAngle,
+									encountered_ConstantVolumeFlag,shared_ConstantVolumeFlag,perFrame_ConstantVolumeFlag,
+									encountered_FluoroscopyFlag,shared_FluoroscopyFlag,perFrame_FluoroscopyFlag);
+							}
+							if (perFrame_RevolutionTime == NULL
+							 && perFrame_SingleCollimationWidth == NULL
+							 && perFrame_TotalCollimationWidth == NULL
+							 && perFrame_TableHeight == NULL
+							 && perFrame_GantryDetectorTilt == NULL
+							 && perFrame_DataCollectionDiameter == NULL) {
+								makeCTAcquisitionDetailsSequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+									encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+									encountered_RotationDirection,shared_RotationDirection,perFrame_RotationDirection,
+									encountered_RevolutionTime,shared_RevolutionTime,perFrame_RevolutionTime,
+									encountered_SingleCollimationWidth,shared_SingleCollimationWidth,perFrame_SingleCollimationWidth,
+									encountered_TotalCollimationWidth,shared_TotalCollimationWidth,perFrame_TotalCollimationWidth,
+									encountered_TableHeight,shared_TableHeight,perFrame_TableHeight,
+									encountered_GantryDetectorTilt,shared_GantryDetectorTilt,perFrame_GantryDetectorTilt,
+									encountered_DataCollectionDiameter,shared_DataCollectionDiameter,perFrame_DataCollectionDiameter);
+							}
+							if (perFrame_TableSpeed == NULL
+							 && perFrame_TableFeedPerRotation == NULL
+							 && perFrame_SpiralPitchFactor == NULL) {
+								makeCTTableDynamicsSequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+									encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+									encountered_TableSpeed,shared_TableSpeed,perFrame_TableSpeed,
+									encountered_TableFeedPerRotation,shared_TableFeedPerRotation,perFrame_TableFeedPerRotation,
+									encountered_SpiralPitchFactor,shared_SpiralPitchFactor,perFrame_SpiralPitchFactor);
+							}
+							if (perFrame_PatientPosition == NULL
+							 && perFrame_PixelSpacing == NULL
+							 && perFrame_SliceLocation == NULL
+							 && perFrame_TablePosition == NULL
+							 && perFrame_ImagePositionPatient == NULL
+							 && perFrame_ImageOrientationPatient == NULL
+							 && perFrame_DataCollectionCenterPatient == NULL
+							 && perFrame_ReconstructionTargetCenterPatient == NULL) {
+								makeCTPositionSequence(iSharedFunctionalGroupsSequence,0,false,
+									rows,columns,
+									reference_ImagePositionPatient,
+									encountered_PatientPosition,shared_PatientPosition,perFrame_PatientPosition,
+									encountered_PixelSpacing,shared_PixelSpacing,perFrame_PixelSpacing,
+									encountered_SliceLocation,shared_SliceLocation,perFrame_SliceLocation,
+									encountered_TablePosition,shared_TablePosition,perFrame_TablePosition,
+									encountered_ImagePositionPatient,shared_ImagePositionPatient,perFrame_ImagePositionPatient,
+									encountered_ImageOrientationPatient,shared_ImageOrientationPatient,perFrame_ImageOrientationPatient,
+									encountered_DataCollectionCenterPatient,shared_DataCollectionCenterPatient,perFrame_DataCollectionCenterPatient,
+									encountered_ReconstructionTargetCenterPatient,shared_ReconstructionTargetCenterPatient,perFrame_ReconstructionTargetCenterPatient);
+							}
+							if (perFrame_DistanceSourceToDetector == NULL
+							 && perFrame_DistanceSourceToDataCollectionCenter == NULL) {
+								makeCTGeometrySequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_DistanceSourceToDetector,shared_DistanceSourceToDetector,perFrame_DistanceSourceToDetector,
+									encountered_DistanceSourceToDataCollectionCenter,shared_DistanceSourceToDataCollectionCenter,
+																perFrame_DistanceSourceToDataCollectionCenter,
+									encountered_DistanceSourceToPatient,shared_DistanceSourceToPatient,perFrame_DistanceSourceToPatient);
+							}
+							if (perFrame_ReconstructionAlgorithm == NULL
+							 && perFrame_ConvolutionKernel == NULL
+							 && perFrame_ConvolutionKernelGroup == NULL
+							 && perFrame_ReconstructionDiameter == NULL
+							 && perFrame_ReconstructionFieldOfView == NULL
+							 && perFrame_ReconstructionPixelSpacing == NULL
+							 && perFrame_ReconstructionAngle == NULL
+							 && perFrame_ImageFilter == NULL) {
+								makeCTReconstructionSequence(iSharedFunctionalGroupsSequence,0,false,
+									rows,columns,
+									encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+									encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+									encountered_PixelSpacing,shared_PixelSpacing,perFrame_PixelSpacing,
+									encountered_ReconstructionAlgorithm,shared_ReconstructionAlgorithm,perFrame_ReconstructionAlgorithm,
+									encountered_ConvolutionKernel,shared_ConvolutionKernel,perFrame_ConvolutionKernel,
+									encountered_ConvolutionKernelGroup,shared_ConvolutionKernelGroup,perFrame_ConvolutionKernelGroup,
+									encountered_ReconstructionDiameter,shared_ReconstructionDiameter,perFrame_ReconstructionDiameter,
+									encountered_ReconstructionFieldOfView,shared_ReconstructionFieldOfView,perFrame_ReconstructionFieldOfView,
+									encountered_ReconstructionPixelSpacing,shared_ReconstructionPixelSpacing,perFrame_ReconstructionPixelSpacing,
+									encountered_ReconstructionAngle,shared_ReconstructionAngle,perFrame_ReconstructionAngle,
+									encountered_ImageFilter,shared_ImageFilter,perFrame_ImageFilter);
+							}
+							if (perFrame_ExposureTime == NULL
+							 && perFrame_XRayTubeCurrent == NULL
+							 && perFrame_Exposure == NULL
+							 && perFrame_ExposureInuAs == NULL
+							 && perFrame_ExposureTimeInms == NULL
+							 && perFrame_XRayTubeCurrentInmA == NULL
+							 && perFrame_ExposureInmAs == NULL
+							 && perFrame_ExposureModulationType == NULL
+							 && perFrame_EstimatedDoseSaving == NULL
+							 && perFrame_CTDIvol == NULL) {
+								makeCTExposureSequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_ExposureTime,shared_ExposureTime,perFrame_ExposureTime,
+									encountered_XRayTubeCurrent,shared_XRayTubeCurrent,perFrame_XRayTubeCurrent,
+									encountered_Exposure,shared_Exposure,perFrame_Exposure,
+									encountered_ExposureInuAs,shared_ExposureInuAs,perFrame_ExposureInuAs,
+									encountered_ExposureTimeInms,shared_ExposureTimeInms,perFrame_ExposureTimeInms,
+									encountered_XRayTubeCurrentInmA,shared_XRayTubeCurrentInmA,perFrame_XRayTubeCurrentInmA,
+									encountered_ExposureInmAs,shared_ExposureInmAs,perFrame_ExposureInmAs,
+									encountered_ExposureModulationType,shared_ExposureModulationType,perFrame_ExposureModulationType,
+									encountered_EstimatedDoseSaving,shared_EstimatedDoseSaving,perFrame_EstimatedDoseSaving,
+									encountered_CTDIvol,shared_CTDIvol,perFrame_CTDIvol);
+							}
+							if (perFrame_KVP == NULL
+							 && perFrame_FocalSpots == NULL
+							 && perFrame_FilterType == NULL
+							 && perFrame_FilterMaterial == NULL) {
+								makeCTXRayDetailsSequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_KVP,shared_KVP,perFrame_KVP,
+									encountered_FocalSpots,shared_FocalSpots,perFrame_FocalSpots,
+									encountered_FilterType,shared_FilterType,perFrame_FilterType,
+									encountered_FilterMaterial,shared_FilterMaterial,perFrame_FilterMaterial);
+							}
+						}
+ 					}
+					if (addMultiFrameMRStuff) {
+						// if we need it regardless or we saw one of them
+						// && the descriptors are not varying on per-frame basis, add a shared MR Metabolite Map Sequence
+						if (((shared_ImageType != NULL && nValues_ImageType >= 3 && strcmp(shared_ImageType[2],"METABOLITE_MAP") == 0)
+						      || encountered_MetaboliteMapDescription
+						      || encountered_ChemicalShiftMinimumIntegrationLimitInppm
+						      || encountered_ChemicalShiftMaximumIntegrationLimitInppm)
+						    && perFrame_MetaboliteMapDescription == NULL
+						    && perFrame_ChemicalShiftMinimumIntegrationLimitInppm == NULL
+						    && perFrame_ChemicalShiftMaximumIntegrationLimitInppm == NULL) {
+							AttributeList *iMRMetaboliteMapSequence = makeNewSequenceAttributeWithItem(
+								iSharedFunctionalGroupsSequence,TagFromName(MRMetaboliteMapSequence));
+							
+							const char *use_MetaboliteMapDescription = encountered_MetaboliteMapDescription ? shared_MetaboliteMapDescription : "";
+							(*iMRMetaboliteMapSequence)+=new ShortTextAttribute(TagFromName(MetaboliteMapDescription),use_MetaboliteMapDescription);
+							addMetaboliteMapCodeSequence(iMRMetaboliteMapSequence,use_MetaboliteMapDescription);
+							
+							if (encountered_ChemicalShiftMinimumIntegrationLimitInppm && encountered_ChemicalShiftMaximumIntegrationLimitInppm) { // both are Type 1
+								AttributeList *iChemicalShiftSequence = makeNewSequenceAttributeWithItem(
+									iMRMetaboliteMapSequence,TagFromName(ChemicalShiftSequence));
+								(*iChemicalShiftSequence)+=new FloatDoubleAttribute(TagFromName(ChemicalShiftMinimumIntegrationLimitInppm),
+									shared_ChemicalShiftMinimumIntegrationLimitInppm);
+								(*iChemicalShiftSequence)+=new FloatDoubleAttribute(TagFromName(ChemicalShiftMaximumIntegrationLimitInppm),
+									shared_ChemicalShiftMaximumIntegrationLimitInppm);
+							}
+						}					
+
+						//if (addMROriginalOrMixedStuff) {
+						if (!imageIsDerived || addNonDerivedStuffAnyway) {	// NB. not !frameIsDerived, since values may be shared but frame type value 1 varies per-frame
+//cerr << "Adding MR-specific stuff for non-derived image at shared level" << endl;
+							if (perFrame_RepetitionTime == NULL
+							 && perFrame_FlipAngle == NULL
+							 && perFrame_EchoTrainLength == NULL
+							 && perFrame_RFEchoTrainLength == NULL
+							 && perFrame_GradientEchoTrainLength == NULL
+							 && perFrame_SAR == NULL) {
+								makeMRTimingAndRelatedParametersSequence(iSharedFunctionalGroupsSequence,0,false,vEchoPulseSequence,
+									encountered_RepetitionTime,shared_RepetitionTime,perFrame_RepetitionTime,
+									encountered_FlipAngle,shared_FlipAngle,perFrame_FlipAngle,
+									encountered_EchoTrainLength,shared_EchoTrainLength,perFrame_EchoTrainLength,
+									encountered_RFEchoTrainLength,shared_RFEchoTrainLength,perFrame_RFEchoTrainLength,
+									encountered_GradientEchoTrainLength,shared_GradientEchoTrainLength,perFrame_GradientEchoTrainLength,
+									encountered_SAR,shared_SAR,perFrame_SAR,
+									encountered_GradientOutputType,shared_GradientOutputType,perFrame_GradientOutputType,
+									encountered_GradientOutput,shared_GradientOutput,perFrame_GradientOutput);
+							}
+							if (perFrame_EchoTime == NULL) {
+								AttributeList *iMREchoSequence = makeNewSequenceAttributeWithItem(
+									iSharedFunctionalGroupsSequence,TagFromName(MREchoSequence));
+								if (encountered_EchoTime)
+									(*iMREchoSequence)+=new FloatDoubleAttribute(TagFromName(EffectiveEchoTime),shared_EchoTime);
+							}
+							if (perFrame_InPlanePhaseEncodingDirection == NULL
+							 && perFrame_NumberOfPhaseEncodingSteps == NULL
+							 && perFrame_PercentSampling == NULL
+							 && perFrame_PercentPhaseFieldOfView == NULL
+							 && perFrame_AcquisitionMatrix == NULL) {
+								makeMRFOVGeometrySequence(iSharedFunctionalGroupsSequence,0,false,requiredMRAcquisitionType,
+									encountered_MRAcquisitionPhaseEncodingStepsOutOfPlane,shared_MRAcquisitionPhaseEncodingStepsOutOfPlane,
+									perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane,
+									encountered_InPlanePhaseEncodingDirection,shared_InPlanePhaseEncodingDirection,perFrame_InPlanePhaseEncodingDirection,
+									encountered_NumberOfPhaseEncodingSteps,shared_NumberOfPhaseEncodingSteps,perFrame_NumberOfPhaseEncodingSteps,
+									encountered_PercentSampling,shared_PercentSampling,perFrame_PercentSampling,
+									encountered_PercentPhaseFieldOfView,shared_PercentPhaseFieldOfView,perFrame_PercentPhaseFieldOfView,
+									encountered_AcquisitionMatrix,shared_AcquisitionMatrix,perFrame_AcquisitionMatrix);
+							}
+						
+							if (perFrame_ScanningSequence == NULL
+							 && perFrame_SequenceVariant == NULL
+							 && perFrame_ScanOptions == NULL) {
+								char **useScanningSequence = encountered_ScanningSequence ? shared_ScanningSequence : NULL;
+								char **useSequenceVariant = encountered_SequenceVariant ? shared_SequenceVariant : NULL;
+								char **useScanOptions = encountered_ScanOptions ? shared_ScanOptions : NULL;
+								
+								makeMRModifierSequence(iSharedFunctionalGroupsSequence,0,false,
+									encountered_InversionTime,shared_InversionTime,perFrame_InversionTime,
+									useScanningSequence && arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"GR"),
+									useScanningSequence && arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"IR"),
+									useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"FC"),
+									useSequenceVariant && arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"SP"),
+									useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"SP"),
+									useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"PFF"),
+									useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"PFP"));
+							}
+							if (perFrame_SequenceVariant == NULL
+							 && perFrame_ImagingFrequency == NULL
+							 && perFrame_PixelBandwidth == NULL) {
+								char  **useSequenceVariant =  encountered_SequenceVariant ? shared_SequenceVariant : NULL;
+								double useImagingFrequency = encountered_ImagingFrequency ? shared_ImagingFrequency : 0;
+								double   usePixelBandwidth =   encountered_PixelBandwidth ? shared_PixelBandwidth : 0;
+								
+								makeMRImagingModifierSequence(iSharedFunctionalGroupsSequence,false,
+									useSequenceVariant && arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"MTC"),
+									useImagingFrequency,
+									usePixelBandwidth);
+							}
+							if (perFrame_ReceiveCoilName == NULL) {
+								AttributeList *iMRReceiveCoilSequence = makeNewSequenceAttributeWithItem(
+									iSharedFunctionalGroupsSequence,TagFromName(MRReceiveCoilSequence));
+								const char *useReceiveCoilName = encountered_ReceiveCoilName && shared_ReceiveCoilName ? shared_ReceiveCoilName : "NONAME";
+								const char *useManufacturer = minimalAttributesOnly ? "" : (encountered_Manufacturer && !perFrame_Manufacturer && shared_Manufacturer ? shared_Manufacturer : "");
+								(*iMRReceiveCoilSequence)+=new ShortStringAttribute(TagFromName(ReceiveCoilName),useReceiveCoilName);
+								(*iMRReceiveCoilSequence)+=new LongStringAttribute(TagFromName(ReceiveCoilManufacturerName),useManufacturer);
+								(*iMRReceiveCoilSequence)+=new CodeStringAttribute(TagFromName(QuadratureReceiveCoil),
+									encountered_ReceiveCoilName && findInStringRegardlessOfCase(useReceiveCoilName,"QUAD") ? "YES" : "NO");
+								(*iMRReceiveCoilSequence)+=new CodeStringAttribute(TagFromName(ReceiveCoilType),
+									encountered_ReceiveCoilName ? makeCoilTypeFromName(useReceiveCoilName) : "UNKNOWN");	// default is not a standard defined term
+							}
+							if (perFrame_TransmitCoilName == NULL) {
+								AttributeList *iMRTransmitCoilSequence = makeNewSequenceAttributeWithItem(
+									iSharedFunctionalGroupsSequence,TagFromName(MRTransmitCoilSequence));
+								const char *useTransmitCoilName = encountered_TransmitCoilName && shared_TransmitCoilName ? shared_TransmitCoilName : "NONAME";
+								const char *useManufacturer = minimalAttributesOnly ? "" : (encountered_Manufacturer && !perFrame_Manufacturer && shared_Manufacturer ? shared_Manufacturer : "");
+								(*iMRTransmitCoilSequence)+=new ShortStringAttribute(TagFromName(TransmitCoilName),useTransmitCoilName);
+								(*iMRTransmitCoilSequence)+=new LongStringAttribute(TagFromName(TransmitCoilManufacturerName),useManufacturer);
+								(*iMRTransmitCoilSequence)+=new CodeStringAttribute(TagFromName(TransmitCoilType),
+									encountered_TransmitCoilName ? makeCoilTypeFromName(useTransmitCoilName) : "UNKNOWN");	// default is not a standard defined term
+							}
+							if (perFrame_NumberOfAverages == NULL) {
+								AttributeList *iMRAveragesSequence = makeNewSequenceAttributeWithItem(
+									iSharedFunctionalGroupsSequence,TagFromName(MRAveragesSequence));
+								(*iMRAveragesSequence)+=new DecimalStringAttribute(TagFromName(NumberOfAverages),encountered_NumberOfAverages ? shared_NumberOfAverages : double(1));
+							}
+							// Do we need MRDiffusionSequence in Shared Functional Groups ?
+							if (encountered_AcquisitionContrast && perFrame_AcquisitionContrast == NULL
+							 && shared_AcquisitionContrast != NULL && strcmp(shared_AcquisitionContrast,"DIFFUSION") == 0
+							 && perFrame_DiffusionBValue == NULL && perFrame_DiffusionDirectionality == NULL) {
+								double use_DiffusionBValue = encountered_DiffusionBValue ? shared_DiffusionBValue : 0;
+								const char *use_DiffusionDirectionality = encountered_DiffusionDirectionality ? shared_DiffusionDirectionality : "ISOTROPIC";
+								makeMRDiffusionSequence(iSharedFunctionalGroupsSequence,false,
+									use_DiffusionBValue,
+									use_DiffusionDirectionality);
+							}
+							if (phaseContrast) {
+								if (perFrame_VelocityEncodingDirection == NULL
+								 && perFrame_VelocityEncodingMinimumValue == NULL
+								 && perFrame_VelocityEncodingMaximumValue == NULL) {
+									double   *useVelocityEncodingDirection = encountered_VelocityEncodingDirection    ? shared_VelocityEncodingDirection : NULL;
+									double useVelocityEncodingMinimumValue = encountered_VelocityEncodingMinimumValue ? shared_VelocityEncodingMinimumValue : 0;
+									double useVelocityEncodingMaximumValue = encountered_VelocityEncodingMaximumValue ? shared_VelocityEncodingMaximumValue : 0;
+									makeMRVelocityEncodingSequence(iSharedFunctionalGroupsSequence,false,
+										useVelocityEncodingDirection,useVelocityEncodingMinimumValue,useVelocityEncodingMaximumValue);
+								}
+							}
+						}
+					}
+					
+//cerr << "adding per-frame functional groups" << endl;
+					int j;
+                                        for (j=0; j<numberofinputfiles; ++j) {
+//cerr << "added new item to PerFrameFunctionalGroupsSequence: frame " << dec << j << " filename " << filename << endl;
+                                                AttributeList *iPerFrameFunctionalGroupsSequence = new AttributeList();
+                                                Assert(iPerFrameFunctionalGroupsSequence);
+                                                (*aPerFrameFunctionalGroupsSequence)+=iPerFrameFunctionalGroupsSequence;
+						if (perFrame_NominalCardiacTriggerDelayTime != NULL
+						 || perFrame_TriggerTime != NULL
+						 || perFrame_RRIntervalTimeNominal != NULL
+						 /*|| perFrame_TriggerWindow != NULL*/) {
+//cerr << "adding per-frame CardiacSynchronizationSequence" << endl;
+							AttributeList *iCardiacSynchronizationSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(CardiacSynchronizationSequence));
+							double use_TriggerTime = perFrame_TriggerTime ? perFrame_TriggerTime[j] : shared_TriggerTime;
+							double use_NominalCardiacTriggerDelayTime = perFrame_NominalCardiacTriggerDelayTime ? perFrame_NominalCardiacTriggerDelayTime[j] : shared_NominalCardiacTriggerDelayTime;
+							use_NominalCardiacTriggerDelayTime = encountered_TriggerTime ?  use_TriggerTime : use_NominalCardiacTriggerDelayTime;
+							(*iCardiacSynchronizationSequence)+=new FloatDoubleAttribute(TagFromName(NominalCardiacTriggerDelayTime),use_NominalCardiacTriggerDelayTime);
+
+							double use_RRIntervalTimeNominal = perFrame_RRIntervalTimeNominal ? perFrame_RRIntervalTimeNominal[j] : shared_RRIntervalTimeNominal;
+							if (encountered_RRIntervalTimeNominal) {
+								(*iCardiacSynchronizationSequence)+=new FloatDoubleAttribute(TagFromName(RRIntervalTimeNominal),shared_RRIntervalTimeNominal);
+							}
+							
+							//double use_TriggerWindow = perFrame_TriggerWindow ? perFrame_TriggerWindow[j] : shared_TriggerWindow;
+							//if (encountered_TriggerWindow) {
+							//	(*iCardiacSynchronizationSequence)+=new IntegerStringAttribute(TagFromName(TriggerWindow),Uint16(use_TriggerWindow));
+							//}
+						}
+						if ((perFrame_WindowCenter != NULL
+						 || perFrame_WindowWidth != NULL
+						 || perFrame_WindowCenterWidthExplanation != NULL) && !nowindow) {
+//cerr << "adding per-frame FrameVOILUTSequence" << endl;
+							AttributeList *iFrameVOILUTSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(FrameVOILUTSequence));
+							(*iFrameVOILUTSequence)+=new DecimalStringAttribute(TagFromName(WindowCenter),
+								encountered_WindowCenter ? (perFrame_WindowCenter ? perFrame_WindowCenter[j] : shared_WindowCenter) : defaultWindowCenter);
+							(*iFrameVOILUTSequence)+=new DecimalStringAttribute(TagFromName(WindowWidth),
+								encountered_WindowWidth ? (perFrame_WindowWidth ? perFrame_WindowWidth[j] : shared_WindowWidth) : defaultWindowWidth);
+							const char *use_explanation = encountered_WindowCenterWidthExplanation
+								? (perFrame_WindowCenterWidthExplanation ? perFrame_WindowCenterWidthExplanation[j] : shared_WindowCenterWidthExplanation)
+								: NULL;
+							if (use_explanation) {
+								(*iFrameVOILUTSequence)+=new LongStringAttribute(TagFromName(WindowCenterWidthExplanation),use_explanation);
+							}
+						}
+						if (perFrame_RescaleSlope != NULL
+						 || perFrame_RescaleIntercept != NULL
+						 || perFrame_RescaleType != NULL) {
+//cerr << "adding per-frame PixelValueTransformationSequence" << endl;
+							AttributeList *iPixelValueTransformationSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(PixelValueTransformationSequence));
+							double use_intercept = encountered_RescaleIntercept ? (perFrame_RescaleIntercept ? perFrame_RescaleIntercept[j] : shared_RescaleIntercept) : 0.0;
+							double use_slope = encountered_RescaleSlope ? (perFrame_RescaleSlope ? perFrame_RescaleSlope[j] : shared_RescaleSlope) : 1.0;
+							if (use_slope == 0) {
+								use_slope=1.0;	// a slope of zero means it was probably missing for that frame
+								use_intercept=0.0;
+							}
+							const char *use_type = encountered_RescaleType ? (perFrame_RescaleType ? perFrame_RescaleType[j] : shared_RescaleType) : NULL;
+							use_type=fixRescaleTypeForCTIfNecessary(use_type,addMultiFrameCTStuff,imageIsDerived);
+//cerr << "adding RescaleIntercept" << endl;
+							(*iPixelValueTransformationSequence)+=new DecimalStringAttribute(TagFromName(RescaleIntercept),use_intercept);
+//cerr << "adding RescaleSlope" << endl;
+							(*iPixelValueTransformationSequence)+=new DecimalStringAttribute(TagFromName(RescaleSlope),use_slope);
+//cerr << "adding RescaleType = " << use_type << endl;
+							(*iPixelValueTransformationSequence)+=new LongStringAttribute(TagFromName(RescaleType),use_type);
+						}
+						if (perFrame_RealWorldValueSlope != NULL
+						 || perFrame_RealWorldValueIntercept != NULL
+						 || perFrame_Units != NULL
+						 || perFrame_RealWorldValueFirstValueMapped != NULL
+						 || perFrame_RealWorldValueLastValueMapped != NULL
+						 || perFrame_LUTExplanation != NULL
+						 || perFrame_LUTLabel != NULL
+						) {
+//cerr << "adding per-frame RealWorldValueMappingSequence" << endl;
+							makeRealWorldValueMappingSequence(iPerFrameFunctionalGroupsSequence,j,pixelRepresentation,
+								encountered_RealWorldValueSlope,shared_RealWorldValueSlope,perFrame_RealWorldValueSlope,
+								encountered_RealWorldValueIntercept,shared_RealWorldValueIntercept,perFrame_RealWorldValueIntercept,
+								encountered_Units,shared_Units,perFrame_Units,
+								encountered_RealWorldValueFirstValueMapped,shared_RealWorldValueFirstValueMapped,perFrame_RealWorldValueFirstValueMapped,
+								encountered_RealWorldValueLastValueMapped,shared_RealWorldValueLastValueMapped,perFrame_RealWorldValueLastValueMapped,
+								encountered_LUTExplanation,shared_LUTExplanation,perFrame_LUTExplanation,
+								encountered_LUTLabel,shared_LUTLabel,perFrame_LUTLabel);
+						}
+						if (addDerivation && forceDerivationPerFrame) {
+							makeDerivationImageSequence(
+								iPerFrameFunctionalGroupsSequence,
+								minimalAttributesOnly,
+								addDerivation_derivationCodeSequenceCodingSchemeDesignator,
+								addDerivation_derivationCodeSequenceCodeValue,
+								addDerivation_derivationCodeSequenceCodeMeaning,
+								addDerivation_derivationCodeSequenceCodingSchemeVersion,
+								addDerivation_referencedSOPClassUID,
+								addDerivation_referencedSOPInstanceUID,
+								addDerivation_referencedFrameNumbers,
+								addDerivation_purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+								addDerivation_purposeOfReferenceCodeSequenceCodeValue,
+								addDerivation_purposeOfReferenceCodeSequenceCodeMeaning,
+								addDerivation_purposeOfReferenceCodeSequenceCodingSchemeVersion);
+						}
+						if (addReferenced && forceReferencedPerFrame) {
+							makeReferencedImageSequence(
+								iPerFrameFunctionalGroupsSequence,
+								minimalAttributesOnly,
+								addReferenced_referencedSOPClassUID,
+								addReferenced_referencedSOPInstanceUID,
+								addReferenced_referencedFrameNumbers,
+								addReferenced_purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+								addReferenced_purposeOfReferenceCodeSequenceCodeValue,
+								addReferenced_purposeOfReferenceCodeSequenceCodeMeaning,
+								addReferenced_purposeOfReferenceCodeSequenceCodingSchemeVersion);
+						}
+						if (!frameAnatomySequenceDoneAtSharedLevel) {
+//cerr << "adding per-frame FrameAnatomySequence" << endl;
+							makeFrameAnatomySequence(iPerFrameFunctionalGroupsSequence,
+								true /*frameLevel*/,j,
+								encountered_BodyPartExamined,shared_BodyPartExamined,perFrame_BodyPartExamined,
+								encountered_StudyDescription,shared_StudyDescription,perFrame_StudyDescription,
+								encountered_SeriesDescription,shared_SeriesDescription,perFrame_SeriesDescription,
+								encountered_ImageComments,shared_ImageComments,perFrame_ImageComments,
+								encountered_PatientName,shared_PatientName,perFrame_PatientName,
+								encountered_Laterality,shared_Laterality,perFrame_Laterality);
+						}
+						if (addMultiFrameMRStuff) {
+							if (perFrame_MetaboliteMapDescription != NULL
+							 || perFrame_ChemicalShiftMinimumIntegrationLimitInppm != NULL
+							 || perFrame_ChemicalShiftMaximumIntegrationLimitInppm != NULL) {
+								AttributeList *iMRMetaboliteMapSequence = makeNewSequenceAttributeWithItem(
+									iPerFrameFunctionalGroupsSequence,TagFromName(MRMetaboliteMapSequence));
+								const char *use_MetaboliteMapDescription = perFrame_MetaboliteMapDescription
+									? perFrame_MetaboliteMapDescription[j] : (encountered_MetaboliteMapDescription
+										? shared_MetaboliteMapDescription : "");
+								double useChemicalShiftMinimumIntegrationLimitInppm = perFrame_ChemicalShiftMinimumIntegrationLimitInppm
+										? perFrame_ChemicalShiftMinimumIntegrationLimitInppm[j] : shared_ChemicalShiftMinimumIntegrationLimitInppm;
+								double useChemicalShiftMaximumIntegrationLimitInppm = perFrame_ChemicalShiftMaximumIntegrationLimitInppm
+										? perFrame_ChemicalShiftMaximumIntegrationLimitInppm[j] : shared_ChemicalShiftMaximumIntegrationLimitInppm;
+									
+								(*iMRMetaboliteMapSequence)+=new ShortTextAttribute(TagFromName(MetaboliteMapDescription),use_MetaboliteMapDescription);
+								addMetaboliteMapCodeSequence(iMRMetaboliteMapSequence,use_MetaboliteMapDescription);
+								if (encountered_ChemicalShiftMinimumIntegrationLimitInppm && encountered_ChemicalShiftMaximumIntegrationLimitInppm) { // both are Type 1
+									AttributeList *iChemicalShiftSequence = makeNewSequenceAttributeWithItem(
+										iMRMetaboliteMapSequence,TagFromName(ChemicalShiftSequence));
+									(*iChemicalShiftSequence)+=new FloatDoubleAttribute(TagFromName(ChemicalShiftMinimumIntegrationLimitInppm),
+										useChemicalShiftMinimumIntegrationLimitInppm);
+									(*iChemicalShiftSequence)+=new FloatDoubleAttribute(TagFromName(ChemicalShiftMaximumIntegrationLimitInppm),
+										useChemicalShiftMaximumIntegrationLimitInppm);
+								}
+							}
+						}
+						
+						bool frameIsDerived = imageIsDerived;	// may be over-ridden if there is a per-frame (rather than shared) MR Image Frame Type Macro
+						
+						if (perFrame_ImageType != NULL
+						 || perFrame_PixelPresentation != NULL
+						 || perFrame_VolumetricProperties != NULL
+						 || perFrame_VolumeBasedCalculationTechnique != NULL
+						 || perFrame_ComplexImageComponent != NULL
+						 || perFrame_AcquisitionContrast != NULL) {
+//cerr << "adding per-frame MR or CT Image Frame Type Macro" << endl;
+							AttributeList *iImageFrameTypeSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,
+								addMultiFrameMRStuff ? TagFromName(MRImageFrameTypeSequence) : TagFromName(CTImageFrameTypeSequence));
+							
+							// include the Common CT MR and MR Image Description Macro, using Frame Type not Image Type at this level
+							// (the same macro is also used in the Enhanced MR and CT Image Modules)
+							
+							frameIsDerived = makeCTMRImageDescriptionMacroAttributesAndAppendToList(addMultiFrameMRStuff,
+								*iImageFrameTypeSequence,true /* frame level */,j,numberofinputfiles,
+								encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+								encountered_PixelPresentation,shared_PixelPresentation,perFrame_PixelPresentation,
+								encountered_VolumetricProperties,shared_VolumetricProperties,perFrame_VolumetricProperties,
+								encountered_VolumeBasedCalculationTechnique,shared_VolumeBasedCalculationTechnique,perFrame_VolumeBasedCalculationTechnique,
+								encountered_ComplexImageComponent,shared_ComplexImageComponent,perFrame_ComplexImageComponent,
+								encountered_AcquisitionContrast,shared_AcquisitionContrast,perFrame_AcquisitionContrast,
+								log);							
+						}
+
+						// The Frame Content Macro is always present
+//cerr << "adding per-frame Frame Content Macro" << endl;
+						{
+							AttributeList *iFrameContentSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(FrameContentSequence));
+                                                        
+                                                        if (!minimalAttributesOnly && encountered_AcquisitionNumber) {
+                                                                (*iFrameContentSequence)+=new UnsignedShortAttribute(TagFromName(FrameAcquisitionNumber),
+                                                                        perFrame_AcquisitionNumber ? perFrame_AcquisitionNumber[j] : shared_AcquisitionNumber);
+                                                        }
+                                                        
+                                                        if (!frameIsDerived || addNonDerivedStuffAnyway || addTimingStuffAnyway) {
+								double use_AcquisitionDuration;
+								if (addMultiFrameMRStuff && deriveDurationFromTiming) {
+									use_AcquisitionDuration=computeAcquisitionDurationInMilliSecondsFromTiming(
+										encountered_RepetitionTime,shared_RepetitionTime,perFrame_RepetitionTime,
+										encountered_NumberOfAverages,shared_NumberOfAverages,perFrame_NumberOfAverages,
+										encountered_AcquisitionMatrix,shared_AcquisitionMatrix,perFrame_AcquisitionMatrix,
+										encountered_EchoTrainLength,shared_EchoTrainLength,perFrame_EchoTrainLength,
+										encountered_ScanningSequence,shared_ScanningSequence,perFrame_ScanningSequence,nValues_ScanningSequence,
+										j);
+//cerr << "use_AcquisitionDuration: derived " << use_AcquisitionDuration << endl;
+								}
+								else {
+									use_AcquisitionDuration = encountered_AcquisitionDuration ? (perFrame_AcquisitionDuration ? perFrame_AcquisitionDuration[j] : shared_AcquisitionDuration) : 0;
+									use_AcquisitionDuration=use_AcquisitionDuration*1000;	// image level is seconds, frame level is milliseconds
+								}
+								if (accumulateDuration) use_AcquisitionDuration=use_AcquisitionDuration*numberofinputfiles;
+//cerr << "use_AcquisitionDuration: " << use_AcquisitionDuration << endl;
+								if (encountered_AcquisitionDate && encountered_AcquisitionTime) {
+									char *ad = perFrame_AcquisitionDate ? perFrame_AcquisitionDate[j] : shared_AcquisitionDate;
+//cerr << "AcquisitionDate: " << ad << endl;
+									char *at = perFrame_AcquisitionTime ? perFrame_AcquisitionTime[j] : shared_AcquisitionTime;
+//cerr << "AcquisitionTime: " << at << endl;
+									Uint32 acquisitionTime = Time(at);	// gets time in milliseconds
+//cerr << "acquisitionTime: " << acquisitionTime << endl;
+									Uint32 referenceTime = (Uint32)(acquisitionTime + (use_AcquisitionDuration+0.5)/2);
+//cerr << "referenceTime: " << referenceTime << endl;
+									if (accumulateDuration) {
+										acquisitionTime=(Uint32)(acquisitionTime+use_AcquisitionDuration*j);
+										referenceTime=(Uint32)(referenceTime+use_AcquisitionDuration*j);
+									}
+//cerr << "acquisitionTime: accumulated " << acquisitionTime << endl;
+//cerr << "referenceTime: accumulated " << referenceTime << endl;
+									char *adt = makeDateTimeString(ad,getStringFromTime(Time(acquisitionTime)));
+//cerr << "AcquisitionDateTime: " << adt << endl;
+									char *rdt = makeDateTimeString(ad,getStringFromTime(Time(referenceTime)));
+//cerr << "ReferenceDateTime: " << rdt << endl;
+									(*iFrameContentSequence)+=new DateTimeStringAttribute(TagFromName(FrameReferenceDateTime),rdt);
+									(*iFrameContentSequence)+=new DateTimeStringAttribute(TagFromName(FrameAcquisitionDateTime),adt);
+								}
+								(*iFrameContentSequence)+=new FloatDoubleAttribute(TagFromName(FrameAcquisitionDuration),use_AcquisitionDuration);
+                                                        }
+
+                                                        if (!minimalAttributesOnly && encountered_ImageComments) {
+                                                                Attribute *aFrameComments=new LongTextAttribute(TagFromName(FrameComments));
+                                                                Assert(aFrameComments);
+                                                                (*iFrameContentSequence)+=aFrameComments;
+                                                                char *useImageComments = perFrame_ImageComments ? perFrame_ImageComments[j] : shared_ImageComments;
+                                                                if (useImageComments && strlen(useImageComments) > 0) aFrameComments->addValue(useImageComments);
+                                                        }
+
+                                                        if (!minimalAttributesOnly && encountered_CardiacCyclePosition) {
+                                                                Attribute *aCardiacCyclePosition=new CodeStringAttribute(TagFromName(CardiacCyclePosition));
+                                                                Assert(aCardiacCyclePosition);
+                                                                (*iFrameContentSequence)+=aCardiacCyclePosition;
+                                                                char *useCardiacCyclePosition = perFrame_CardiacCyclePosition ? perFrame_CardiacCyclePosition[j] : shared_CardiacCyclePosition;
+                                                                if (useCardiacCyclePosition && strlen(useCardiacCyclePosition) > 0) aCardiacCyclePosition->addValue(useCardiacCyclePosition);
+                                                        }
+
+                                                        if (!minimalAttributesOnly && encountered_RespiratoryCyclePosition) {
+                                                                Attribute *aRespiratoryCyclePosition=new CodeStringAttribute(TagFromName(RespiratoryCyclePosition));
+                                                                Assert(aRespiratoryCyclePosition);
+                                                                (*iFrameContentSequence)+=aRespiratoryCyclePosition;
+                                                                char *useRespiratoryCyclePosition = perFrame_RespiratoryCyclePosition ? perFrame_RespiratoryCyclePosition[j] : shared_RespiratoryCyclePosition;
+                                                                if (useRespiratoryCyclePosition && strlen(useRespiratoryCyclePosition) > 0) aRespiratoryCyclePosition->addValue(useRespiratoryCyclePosition);
+                                                        }
+
+							if (!minimalAttributesOnly && makeStack && stackID && inStackPositionNumber) {
+								(*iFrameContentSequence)+=new ShortStringAttribute(TagFromName(StackID),Uint32(stackID[j]));
+								(*iFrameContentSequence)+=new UnsignedLongAttribute(TagFromName(InStackPositionNumber),inStackPositionNumber[j]);
+							}
+							if (!minimalAttributesOnly && addTemporalPosition && temporalPositionIndex) {
+								(*iFrameContentSequence)+=new UnsignedLongAttribute(TagFromName(TemporalPositionIndex),temporalPositionIndex[j]);
+							}
+							
+							// DimensionIndexValues can not be done yet ... have to first do functional groups for every frame, then add it later
+                                                }
+
+                                                if (perFrame_SliceThickness != NULL
+						 || perFrame_PixelSpacing != NULL) {
+//cerr << "adding per-frame PixelMeasuresSequence" << endl;
+							AttributeList *iPixelMeasuresSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(PixelMeasuresSequence));
+							// NB. This is not predicated on any original or derived stuff,
+							// since that is what the standard says, unlike the Plane Position or Orientation Macros
+							{
+								(*iPixelMeasuresSequence)+=new DecimalStringAttribute(TagFromName(SliceThickness),
+									perFrame_SliceThickness ? perFrame_SliceThickness[j] : shared_SliceThickness);
+                                                                
+								Attribute *aPixelSpacing=new DecimalStringAttribute(TagFromName(PixelSpacing));
+								Assert(aPixelSpacing);
+								(*iPixelMeasuresSequence)+=aPixelSpacing;
+								if (perFrame_PixelSpacing) {
+									Assert(perFrame_PixelSpacing[j]);
+									aPixelSpacing->addValue(perFrame_PixelSpacing[j][0]);
+									aPixelSpacing->addValue(perFrame_PixelSpacing[j][1]);
+								}
+								else {
+									Assert(shared_PixelSpacing);
+									aPixelSpacing->addValue(shared_PixelSpacing[0]);
+									aPixelSpacing->addValue(shared_PixelSpacing[1]);
+								}
+							}
+                                                }
+                                                if (perFrame_ImagePositionPatient != NULL) {
+//cerr << "adding per-frame PlanePositionSequence" << endl;
+							AttributeList *iPlanePositionSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(PlanePositionSequence));
+                                                        Assert(perFrame_ImagePositionPatient[j]);
+                                                        if (!frameIsDerived || addNonDerivedStuffAnyway || addPositionStuffAnyway) (*iPlanePositionSequence)+=new DecimalStringAttribute(TagFromName(ImagePositionPatient),
+                                                               perFrame_ImagePositionPatient[j][0],perFrame_ImagePositionPatient[j][1],perFrame_ImagePositionPatient[j][2]);
+                                                }
+                                                if (perFrame_ImageOrientationPatient != NULL) {
+//cerr << "adding per-frame PlaneOrientationSequence" << endl;
+							AttributeList *iPlaneOrientationSequence = makeNewSequenceAttributeWithItem(
+								iPerFrameFunctionalGroupsSequence,TagFromName(PlaneOrientationSequence));
+                                                        Assert(perFrame_ImageOrientationPatient[j]);
+                                                        if (!frameIsDerived || addNonDerivedStuffAnyway || addPositionStuffAnyway) (*iPlaneOrientationSequence)+=new DecimalStringAttribute(TagFromName(ImageOrientationPatient),
+                                                         	perFrame_ImageOrientationPatient[j][0],perFrame_ImageOrientationPatient[j][1],perFrame_ImageOrientationPatient[j][2],
+                                                                perFrame_ImageOrientationPatient[j][3],perFrame_ImageOrientationPatient[j][4],perFrame_ImageOrientationPatient[j][5]);
+                                                }
+						if (addEnhancedContrastBolusModuleAndMacro) {
+							// regardless of original or derived ...
+							if (perFrame_ContrastBolusAgent != NULL
+							 || perFrame_ContrastBolusRoute != NULL
+							 || perFrame_ContrastBolusVolume != NULL
+							 || perFrame_ContrastBolusIngredientConcentration != NULL
+							 || perFrame_ContrastBolusAgentAdministered != NULL
+							 || perFrame_ContrastBolusAgentDetected != NULL
+							 || perFrame_ContrastBolusAgentPhase != NULL)
+							 {
+								makeContrastBolusUsageSequence(iPerFrameFunctionalGroupsSequence,j,
+									encountered_ContrastBolusAgent,shared_ContrastBolusAgent,perFrame_ContrastBolusAgent,nValues_ContrastBolusAgent,
+									encountered_ContrastBolusRoute,shared_ContrastBolusRoute,perFrame_ContrastBolusRoute,nValues_ContrastBolusRoute,
+									encountered_ContrastBolusVolume,shared_ContrastBolusVolume,perFrame_ContrastBolusVolume,nValues_ContrastBolusVolume,
+									encountered_ContrastBolusIngredientConcentration,shared_ContrastBolusIngredientConcentration,
+										perFrame_ContrastBolusIngredientConcentration,nValues_ContrastBolusIngredientConcentration,
+									encountered_ContrastBolusAgentAdministered,shared_ContrastBolusAgentAdministered,
+										perFrame_ContrastBolusAgentAdministered,nValues_ContrastBolusAgentAdministered,
+									encountered_ContrastBolusAgentDetected,shared_ContrastBolusAgentDetected,
+										perFrame_ContrastBolusAgentDetected,nValues_ContrastBolusAgentDetected,
+									encountered_ContrastBolusAgentPhase,shared_ContrastBolusAgentPhase,
+										perFrame_ContrastBolusAgentPhase,nValues_ContrastBolusAgentPhase);
+							}
+						}
+						if (addMultiFrameCTStuff) {
+							{
+								// Irradiation Event Identification is mandatory whether derived or not
+								if (perFrame_IrradiationEventUID != NULL) {
+//cerr << "adding per-frame IrradiationEventIdentificationSequence" << endl;
+									AttributeList *iIrradiationEventIdentificationSequence = makeNewSequenceAttributeWithItem(
+										iPerFrameFunctionalGroupsSequence,TagFromName(IrradiationEventIdentificationSequence));
+									(*iIrradiationEventIdentificationSequence)+=new UIStringAttribute(TagFromName(IrradiationEventUID),perFrame_IrradiationEventUID[j]);
+								}
+							}
+							if (!imageIsDerived || addNonDerivedStuffAnyway) {
+								// need to add these regardless of whether original or mixed
+								// and in the case of mixed the methods will add empty sequences for th derived frames
+//cerr << "Adding CT-specific stuff for non-derived image at per-frame level" << endl;
+								if (perFrame_AcquisitionType != NULL
+								 || perFrame_TubeAngle != NULL
+								 || perFrame_ConstantVolumeFlag != NULL
+								 || perFrame_FluoroscopyFlag != NULL) {
+//cerr << "adding per-frame CTAcquisitionTypeSequence" << endl << flush;
+									makeCTAcquisitionTypeSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+										encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+										encountered_TubeAngle,shared_TubeAngle,perFrame_TubeAngle,
+										encountered_ConstantVolumeFlag,shared_ConstantVolumeFlag,perFrame_ConstantVolumeFlag,
+										encountered_FluoroscopyFlag,shared_FluoroscopyFlag,perFrame_FluoroscopyFlag);
+								}
+								if (perFrame_RotationDirection != NULL
+								 || perFrame_RevolutionTime != NULL
+								 || perFrame_SingleCollimationWidth != NULL
+								 || perFrame_TotalCollimationWidth != NULL
+								 || perFrame_TableHeight != NULL
+								 || perFrame_GantryDetectorTilt != NULL
+								 || perFrame_DataCollectionDiameter != NULL) {
+//cerr << "adding per-frame CTAcquisitionDetailsSequence" << endl << flush;
+									makeCTAcquisitionDetailsSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+										encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+										encountered_RotationDirection,shared_RotationDirection,perFrame_RotationDirection,
+										encountered_RevolutionTime,shared_RevolutionTime,perFrame_RevolutionTime,
+										encountered_SingleCollimationWidth,shared_SingleCollimationWidth,perFrame_SingleCollimationWidth,
+										encountered_TotalCollimationWidth,shared_TotalCollimationWidth,perFrame_TotalCollimationWidth,
+										encountered_TableHeight,shared_TableHeight,perFrame_TableHeight,
+										encountered_GantryDetectorTilt,shared_GantryDetectorTilt,perFrame_GantryDetectorTilt,
+										encountered_DataCollectionDiameter,shared_DataCollectionDiameter,perFrame_DataCollectionDiameter);
+								}
+								if (perFrame_TableSpeed != NULL
+								 || perFrame_TableFeedPerRotation != NULL
+								 || perFrame_SpiralPitchFactor != NULL) {
+//cerr << "adding per-frame CTTableDynamicsSequence" << endl << flush;
+									makeCTTableDynamicsSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+										encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+										encountered_TableSpeed,shared_TableSpeed,perFrame_TableSpeed,
+										encountered_TableFeedPerRotation,shared_TableFeedPerRotation,perFrame_TableFeedPerRotation,
+										encountered_SpiralPitchFactor,shared_SpiralPitchFactor,perFrame_SpiralPitchFactor);
+								}
+								if (perFrame_PatientPosition != NULL
+								 || perFrame_PixelSpacing != NULL
+								 || perFrame_SliceLocation != NULL
+								 || perFrame_TablePosition != NULL
+								 || perFrame_ImagePositionPatient != NULL
+								 || perFrame_ImageOrientationPatient != NULL
+								 || perFrame_DataCollectionCenterPatient != NULL
+								 || perFrame_ReconstructionTargetCenterPatient != NULL) {
+//cerr << "adding per-frame CTPositionSequence" << endl << flush;
+									makeCTPositionSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										rows,columns,
+										reference_ImagePositionPatient,
+										encountered_PatientPosition,shared_PatientPosition,perFrame_PatientPosition,
+										encountered_PixelSpacing,shared_PixelSpacing,perFrame_PixelSpacing,
+										encountered_SliceLocation,shared_SliceLocation,perFrame_SliceLocation,
+										encountered_TablePosition,shared_TablePosition,perFrame_TablePosition,
+										encountered_ImagePositionPatient,shared_ImagePositionPatient,perFrame_ImagePositionPatient,
+										encountered_ImageOrientationPatient,shared_ImageOrientationPatient,perFrame_ImageOrientationPatient,
+										encountered_DataCollectionCenterPatient,shared_DataCollectionCenterPatient,perFrame_DataCollectionCenterPatient,
+										encountered_ReconstructionTargetCenterPatient,shared_ReconstructionTargetCenterPatient,
+											perFrame_ReconstructionTargetCenterPatient);
+								}
+								if (perFrame_DistanceSourceToDetector != NULL
+								 || perFrame_DistanceSourceToDataCollectionCenter != NULL) {
+									makeCTGeometrySequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_DistanceSourceToDetector,shared_DistanceSourceToDetector,perFrame_DistanceSourceToDetector,
+										encountered_DistanceSourceToDataCollectionCenter,shared_DistanceSourceToDataCollectionCenter,
+																	perFrame_DistanceSourceToDataCollectionCenter,
+										encountered_DistanceSourceToPatient,shared_DistanceSourceToPatient,perFrame_DistanceSourceToPatient);
+								}
+								if (perFrame_ReconstructionAlgorithm != NULL
+								 || perFrame_ConvolutionKernel != NULL
+								 || perFrame_ConvolutionKernelGroup != NULL
+								 || perFrame_ReconstructionDiameter != NULL
+								 || perFrame_ReconstructionFieldOfView != NULL
+								 || perFrame_ReconstructionPixelSpacing != NULL
+								 || perFrame_ReconstructionAngle != NULL
+								 || perFrame_ImageFilter != NULL) {
+									makeCTReconstructionSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										rows,columns,
+										encountered_ImageType,shared_ImageType,perFrame_ImageType,nValues_ImageType,
+										encountered_AcquisitionType,shared_AcquisitionType,perFrame_AcquisitionType,
+										encountered_PixelSpacing,shared_PixelSpacing,perFrame_PixelSpacing,
+										encountered_ReconstructionAlgorithm,shared_ReconstructionAlgorithm,perFrame_ReconstructionAlgorithm,
+										encountered_ConvolutionKernel,shared_ConvolutionKernel,perFrame_ConvolutionKernel,
+										encountered_ConvolutionKernelGroup,shared_ConvolutionKernelGroup,perFrame_ConvolutionKernelGroup,
+										encountered_ReconstructionDiameter,shared_ReconstructionDiameter,perFrame_ReconstructionDiameter,
+										encountered_ReconstructionFieldOfView,shared_ReconstructionFieldOfView,perFrame_ReconstructionFieldOfView,
+										encountered_ReconstructionPixelSpacing,shared_ReconstructionPixelSpacing,perFrame_ReconstructionPixelSpacing,
+										encountered_ReconstructionAngle,shared_ReconstructionAngle,perFrame_ReconstructionAngle,
+										encountered_ImageFilter,shared_ImageFilter,perFrame_ImageFilter);
+								}
+								if (perFrame_ExposureTime != NULL
+								 || perFrame_XRayTubeCurrent != NULL
+								 || perFrame_Exposure != NULL
+								 || perFrame_ExposureInuAs != NULL
+								 || perFrame_ExposureTimeInms != NULL
+								 || perFrame_XRayTubeCurrentInmA != NULL
+								 || perFrame_ExposureInmAs != NULL
+								 || perFrame_ExposureModulationType != NULL
+								 || perFrame_EstimatedDoseSaving != NULL
+								 || perFrame_CTDIvol != NULL) {
+									makeCTExposureSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_ExposureTime,shared_ExposureTime,perFrame_ExposureTime,
+										encountered_XRayTubeCurrent,shared_XRayTubeCurrent,perFrame_XRayTubeCurrent,
+										encountered_Exposure,shared_Exposure,perFrame_Exposure,
+										encountered_ExposureInuAs,shared_ExposureInuAs,perFrame_ExposureInuAs,
+										encountered_ExposureTimeInms,shared_ExposureTimeInms,perFrame_ExposureTimeInms,
+										encountered_XRayTubeCurrentInmA,shared_XRayTubeCurrentInmA,perFrame_XRayTubeCurrentInmA,
+										encountered_ExposureInmAs,shared_ExposureInmAs,perFrame_ExposureInmAs,
+										encountered_ExposureModulationType,shared_ExposureModulationType,perFrame_ExposureModulationType,
+										encountered_EstimatedDoseSaving,shared_EstimatedDoseSaving,perFrame_EstimatedDoseSaving,
+										encountered_CTDIvol,shared_CTDIvol,perFrame_CTDIvol);
+								}
+								if (perFrame_KVP != NULL
+								 || perFrame_FocalSpots != NULL
+								 || perFrame_FilterType != NULL
+								 || perFrame_FilterMaterial != NULL) {
+									makeCTXRayDetailsSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_KVP,shared_KVP,perFrame_KVP,
+										encountered_FocalSpots,shared_FocalSpots,perFrame_FocalSpots,
+										encountered_FilterType,shared_FilterType,perFrame_FilterType,
+										encountered_FilterMaterial,shared_FilterMaterial,perFrame_FilterMaterial);
+								}
+							}
+						}
+						if (addMultiFrameMRStuff) {
+							//if (addMROriginalOrMixedStuff) {
+							//if (!frameIsDerived || addNonDerivedStuffAnyway) {
+							if (!imageIsDerived || addNonDerivedStuffAnyway) {
+								// need to add these regardless of whether original or mixed
+								// and in the case of mixed the methods will add empty sequences for th derived frames
+//cerr << "Adding MR-specific stuff for non-derived image at per-frame level" << endl;
+								if (perFrame_RepetitionTime != NULL
+								 || perFrame_FlipAngle != NULL
+								 || perFrame_EchoTrainLength != NULL
+								 || perFrame_RFEchoTrainLength != NULL
+								 || perFrame_GradientEchoTrainLength != NULL
+								 || perFrame_SAR != NULL) {
+//cerr << "adding per-frame MRTimingAndRelatedParametersSequence" << endl << flush;
+									makeMRTimingAndRelatedParametersSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,vEchoPulseSequence,
+										encountered_RepetitionTime,shared_RepetitionTime,perFrame_RepetitionTime,
+										encountered_FlipAngle,shared_FlipAngle,perFrame_FlipAngle,
+										encountered_EchoTrainLength,shared_EchoTrainLength,perFrame_EchoTrainLength,
+										encountered_RFEchoTrainLength,shared_RFEchoTrainLength,perFrame_RFEchoTrainLength,
+										encountered_GradientEchoTrainLength,shared_GradientEchoTrainLength,perFrame_GradientEchoTrainLength,
+										encountered_SAR,shared_SAR,perFrame_SAR,
+										encountered_GradientOutputType,shared_GradientOutputType,perFrame_GradientOutputType,
+										encountered_GradientOutput,shared_GradientOutput,perFrame_GradientOutput);
+								}
+								if (perFrame_EchoTime != NULL) {
+//cerr << "adding per-frame MREchoSequence" << endl;
+									AttributeList *iMREchoSequence = makeNewSequenceAttributeWithItem(
+										iPerFrameFunctionalGroupsSequence,TagFromName(MREchoSequence));
+									/* if (!frameIsDerived || addNonDerivedStuffAnyway) */
+										(*iMREchoSequence)+=new FloatDoubleAttribute(TagFromName(EffectiveEchoTime),perFrame_EchoTime[j]);
+								}
+//cerr << "adding per-frame MRFOVGeometrySequence" << endl;
+								if (perFrame_InPlanePhaseEncodingDirection != NULL
+								 || perFrame_NumberOfPhaseEncodingSteps != NULL
+								 || perFrame_PercentSampling != NULL
+								 || perFrame_PercentPhaseFieldOfView != NULL
+								 || perFrame_AcquisitionMatrix != NULL) {
+									makeMRFOVGeometrySequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										requiredMRAcquisitionType,
+										encountered_MRAcquisitionPhaseEncodingStepsOutOfPlane,shared_MRAcquisitionPhaseEncodingStepsOutOfPlane,
+										perFrame_MRAcquisitionPhaseEncodingStepsOutOfPlane,
+										encountered_InPlanePhaseEncodingDirection,shared_InPlanePhaseEncodingDirection,perFrame_InPlanePhaseEncodingDirection,
+										encountered_NumberOfPhaseEncodingSteps,shared_NumberOfPhaseEncodingSteps,perFrame_NumberOfPhaseEncodingSteps,
+										encountered_PercentSampling,shared_PercentSampling,perFrame_PercentSampling,
+										encountered_PercentPhaseFieldOfView,shared_PercentPhaseFieldOfView,perFrame_PercentPhaseFieldOfView,
+										encountered_AcquisitionMatrix,shared_AcquisitionMatrix,perFrame_AcquisitionMatrix);
+								}
+//cerr << "adding per-frame MRModifierSequence" << endl;
+								if (perFrame_ScanningSequence != NULL
+								 || perFrame_SequenceVariant != NULL
+								 || perFrame_ScanOptions != NULL) {
+									char **useScanningSequence = encountered_ScanningSequence ? 
+										(perFrame_ScanningSequence ? perFrame_ScanningSequence[j] : shared_ScanningSequence) : NULL;
+									char **useSequenceVariant = encountered_SequenceVariant ? 
+										(perFrame_SequenceVariant ? perFrame_SequenceVariant[j] : shared_SequenceVariant) : NULL;
+									char **useScanOptions = encountered_ScanOptions ? 
+										(perFrame_ScanOptions ? perFrame_ScanOptions[j] : shared_ScanOptions) : NULL;
+								
+									makeMRModifierSequence(iPerFrameFunctionalGroupsSequence,j,frameIsDerived && !addNonDerivedStuffAnyway,
+										encountered_InversionTime,shared_InversionTime,perFrame_InversionTime,
+										useScanningSequence && arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"GR"),
+										useScanningSequence && arrayOfStringValuesContains(useScanningSequence,nValues_ScanningSequence,"IR"),
+										useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"FC"),
+										useSequenceVariant && arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"SP"),
+										useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"SP"),
+										useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"PFF"),
+										useScanOptions && arrayOfStringValuesContains(useScanOptions,nValues_ScanOptions,"PFP"));
+								}
+//cerr << "adding per-frame MRImagingModifierSequence" << endl;
+								if (perFrame_SequenceVariant != NULL
+								 || perFrame_ImagingFrequency != NULL
+								 || perFrame_PixelBandwidth != NULL) {
+									char  **useSequenceVariant =  encountered_SequenceVariant ?
+										(perFrame_SequenceVariant ? perFrame_SequenceVariant[j] : shared_SequenceVariant) : NULL;
+									double useImagingFrequency = encountered_ImagingFrequency ?
+										(perFrame_ImagingFrequency ? perFrame_ImagingFrequency[j] : shared_ImagingFrequency) : 0;
+									double   usePixelBandwidth =   encountered_PixelBandwidth ?
+										(perFrame_PixelBandwidth ? perFrame_PixelBandwidth[j] : shared_PixelBandwidth) : 0;
+								
+									makeMRImagingModifierSequence(iPerFrameFunctionalGroupsSequence,frameIsDerived && !addNonDerivedStuffAnyway,
+										useSequenceVariant && arrayOfStringValuesContains(useSequenceVariant,nValues_SequenceVariant,"MTC"),
+										useImagingFrequency,
+										usePixelBandwidth);
+								}
+//cerr << "adding per-frame MRReceiveCoilSequence" << endl;
+								if (perFrame_ReceiveCoilName != NULL) {
+									AttributeList *iMRReceiveCoilSequence = makeNewSequenceAttributeWithItem(
+										iPerFrameFunctionalGroupsSequence,TagFromName(MRReceiveCoilSequence));
+									/* if (!frameIsDerived || addNonDerivedStuffAnyway) */ {
+										const char *useReceiveCoilName = perFrame_ReceiveCoilName[j] ? perFrame_ReceiveCoilName[j] : "NONAME";
+										const char *useManufacturer = encountered_Manufacturer ? (perFrame_Manufacturer ? (perFrame_Manufacturer[j] ? perFrame_Manufacturer[j] : "") : shared_Manufacturer) : "";
+										(*iMRReceiveCoilSequence)+=new ShortStringAttribute(TagFromName(ReceiveCoilName),useReceiveCoilName);
+										(*iMRReceiveCoilSequence)+=new LongStringAttribute(TagFromName(ReceiveCoilManufacturerName),useManufacturer);
+										(*iMRReceiveCoilSequence)+=new CodeStringAttribute(TagFromName(QuadratureReceiveCoil),
+											findInStringRegardlessOfCase(useReceiveCoilName,"QUAD") ? "YES" : "NO");
+										(*iMRReceiveCoilSequence)+=new CodeStringAttribute(TagFromName(ReceiveCoilType),
+											makeCoilTypeFromName(useReceiveCoilName));
+									}
+								}
+//cerr << "adding per-frame MRTransmitCoilSequence" << endl;
+								if (perFrame_TransmitCoilName != NULL) {
+									AttributeList *iMRTransmitCoilSequence = makeNewSequenceAttributeWithItem(
+										iPerFrameFunctionalGroupsSequence,TagFromName(MRTransmitCoilSequence));
+									/* if (!frameIsDerived || addNonDerivedStuffAnyway) */ {
+										const char *useTransmitCoilName = perFrame_TransmitCoilName[j] ? perFrame_TransmitCoilName[j] : "NONAME";
+										const char *useManufacturer = encountered_Manufacturer ? (perFrame_Manufacturer ? (perFrame_Manufacturer[j] ? perFrame_Manufacturer[j] : "") : shared_Manufacturer) : "";
+										(*iMRTransmitCoilSequence)+=new ShortStringAttribute(TagFromName(TransmitCoilName),useTransmitCoilName);
+										(*iMRTransmitCoilSequence)+=new LongStringAttribute(TagFromName(TransmitCoilManufacturerName),useManufacturer);
+										(*iMRTransmitCoilSequence)+=new CodeStringAttribute(TagFromName(TransmitCoilType),
+											makeCoilTypeFromName(useTransmitCoilName));
+									}
+								}
+//cerr << "adding per-frame NumberOfAverages" << endl;
+								if (perFrame_NumberOfAverages != NULL) {
+									AttributeList *iMRAveragesSequence = makeNewSequenceAttributeWithItem(
+										iPerFrameFunctionalGroupsSequence,TagFromName(MRAveragesSequence));
+									/* if (!frameIsDerived || addNonDerivedStuffAnyway) */ (*iMRAveragesSequence)+=new DecimalStringAttribute(TagFromName(NumberOfAverages),perFrame_NumberOfAverages[j]);
+								}
+								// Do we need MRDiffusionSequence in Per-Frame Functional Groups ?
+								if ((encountered_AcquisitionContrast && perFrame_AcquisitionContrast != NULL && strcmp(perFrame_AcquisitionContrast[j],"DIFFUSION") == 0)
+								 || perFrame_DiffusionBValue != NULL
+								 || perFrame_DiffusionDirectionality != NULL) {
+									double use_DiffusionBValue = encountered_DiffusionBValue ? (perFrame_DiffusionBValue ? perFrame_DiffusionBValue[j] : shared_DiffusionBValue) : 0;
+									const char *use_DiffusionDirectionality = encountered_DiffusionDirectionality ? (perFrame_DiffusionDirectionality ? perFrame_DiffusionDirectionality[j] : shared_DiffusionDirectionality) : "ISOTROPIC";
+									makeMRDiffusionSequence(iPerFrameFunctionalGroupsSequence,frameIsDerived && !addNonDerivedStuffAnyway,
+										use_DiffusionBValue,
+										use_DiffusionDirectionality);
+								}
+								if (phaseContrast) {
+									if (perFrame_VelocityEncodingDirection != NULL
+									 || perFrame_VelocityEncodingMinimumValue != NULL
+									 || perFrame_VelocityEncodingMaximumValue != NULL) {
+										double   *useVelocityEncodingDirection = encountered_VelocityEncodingDirection    ? (perFrame_VelocityEncodingDirection ? perFrame_VelocityEncodingDirection[j] : shared_VelocityEncodingDirection) : NULL;
+										double useVelocityEncodingMinimumValue = encountered_VelocityEncodingMinimumValue ? (perFrame_VelocityEncodingMinimumValue ? perFrame_VelocityEncodingMinimumValue[j] : shared_VelocityEncodingMinimumValue) : 0;
+										double useVelocityEncodingMaximumValue = encountered_VelocityEncodingMaximumValue ? (perFrame_VelocityEncodingMaximumValue ? perFrame_VelocityEncodingMaximumValue[j] : shared_VelocityEncodingMaximumValue) : 0;
+										makeMRVelocityEncodingSequence(iPerFrameFunctionalGroupsSequence,frameIsDerived && !addNonDerivedStuffAnyway,
+										useVelocityEncodingDirection,useVelocityEncodingMinimumValue,useVelocityEncodingMaximumValue);
+									}
+								}
+							}
+						}
+					}
+					
+					// Now need to pass through all functional groups for all frames building dimension index values ...
+					
+					if (nDimensionOrganizations) {
+						
+						// Step 1 ... build an organizations * dimensions * inputfiles array of all the double values, without trying to ascertain uniqueness yet
+						
+						double ***dimensionValues = new double**[nDimensionOrganizations];
+						Assert(dimensionValues);
+						for (int ido=0; ido<nDimensionOrganizations; ++ido) {
+							dimensionValues[ido] = new double*[nDimensions[ido]];
+							Assert(dimensionValues[ido]);
+							for (int d=0; d<nDimensions[ido]; ++d) {
+								dimensionValues[ido][d] = new double[numberofinputfiles];
+								Assert(dimensionValues[ido][d]);
+							}
+						}
+						
+						AttributeList **iPerFrameFunctionalGroupsSequence;
+						int n = aPerFrameFunctionalGroupsSequence->getLists(&iPerFrameFunctionalGroupsSequence);
+						Assert(n == numberofinputfiles);
+                                                Assert(iPerFrameFunctionalGroupsSequence);
+	
+						for (j=0; j<numberofinputfiles; ++j) {
+							AttributeList *thisFramesFunctionalGroupItem = iPerFrameFunctionalGroupsSequence[j];
+							Assert(thisFramesFunctionalGroupItem);
+							for (int ido=0; ido<nDimensionOrganizations; ++ido) {
+								for (int d=0; d<nDimensions[ido]; ++d) {
+									SequenceAttribute *aFunctionalGroup =
+										(SequenceAttribute *)((*thisFramesFunctionalGroupItem)[dimensionFunctionalGroupPointers[ido][d]]);
+									Assert(aFunctionalGroup);
+									AttributeList **iFunctionalGroup;
+									int n = aFunctionalGroup->getLists(&iFunctionalGroup);
+									Assert(n >= 1);					// might be more than one item, say ContrastBolusUsageSequence
+									Assert(iFunctionalGroup);
+									AttributeList *ifg = iFunctionalGroup[0];	// we use only the first item
+									Assert(ifg);
+									Attribute *a = (*ifg)[dimensionIndexPointers[ido][d]];
+									Assert(a);
+									double v;
+									if (a->isNumeric()) {
+										v=AttributeValue(a);
+									}
+									else {
+										// specifically to deal with StackID which is SH VR even though numeric,
+										// or FrameType, which is defined terms in a particular order
+										// or ContrastBolusAgentPhase, which is defined terms in a particular order
+										v=getNumericValueFromNonNumericAttributeForDimensionSorting(a);
+									}
+									dimensionValues[ido][d][j]=v;
+cerr << "frame " << dec << j << " organization " << ido <<  " dimension " << d << " value " << v << endl;
+								}
+							}
+						}
+						
+						// Step 2 ... for each dimension, for each frame whose parent dimensions all have the same value, find unique values and sort
+
+						int ***dimensionIndices = new int**[nDimensionOrganizations];
+						Assert(dimensionIndices);
+						for (int ido=0; ido<nDimensionOrganizations; ++ido) {
+							dimensionIndices[ido]=new int*[nDimensions[ido]];
+							Assert(dimensionIndices[ido]);
+							for (int d=0; d<nDimensions[ido]; ++d) {
+								dimensionIndices[ido][d] = new int[numberofinputfiles];
+								Assert(dimensionIndices[ido][d]);
+							}
+						
+							if (false) {
+								int *partitionedSet = new int[numberofinputfiles];
+								Assert(partitionedSet);
+								for (int i=0; i<numberofinputfiles; ++i) partitionedSet[i]=i;
+								partitionFramesByValuesForDimensions(numberofinputfiles,0,
+									nDimensions[ido],dimensionValues[ido],dimensionIndices[ido],numberofinputfiles,partitionedSet);
+							}
+							else {
+								sortUniqueDimensionValues(numberofinputfiles,nDimensions[ido],dimensionValues[ido],dimensionIndices[ido]);
+							}
+						}
+						
+						// Step 3 ... insert the Dimension Index Values to each per-frame functional group sequence
+						
+						for (j=0; j<numberofinputfiles; ++j) {
+							AttributeList *thisFramesFunctionalGroupItem = iPerFrameFunctionalGroupsSequence[j];
+							Assert(thisFramesFunctionalGroupItem);
+							
+							// find Frame Content Sequence to add the Dimension Index Values to ...
+							AttributeList *iFrameContentSequence;
+							{
+								SequenceAttribute *aFrameContentSequence = (SequenceAttribute *)((*thisFramesFunctionalGroupItem)[TagFromName(FrameContentSequence)]);
+								Assert(aFrameContentSequence);
+								AttributeList **frameContentSequenceItems;
+								int n = aFrameContentSequence->getLists(&frameContentSequenceItems);
+								Assert(n == 1);
+								Assert(frameContentSequenceItems);
+								iFrameContentSequence = frameContentSequenceItems[0];
+								Assert(iFrameContentSequence);
+							}
+
+							Attribute *aDimensionIndexValues = new UnsignedLongAttribute(TagFromName(DimensionIndexValues));
+							Assert(aDimensionIndexValues);
+							(*iFrameContentSequence)+=aDimensionIndexValues;
+							
+							for (int ido=0; ido<nDimensionOrganizations; ++ido) {
+								for (int d=0; d<nDimensions[ido]; ++d) {
+									int index = dimensionIndices[ido][d][j];
+cerr << "frame " << dec << j << " organization " << ido << " dimension " << d << " index " << index << " value " << dimensionValues[ido][d][j] << endl;
+									aDimensionIndexValues->addValue(Uint32(index)+1);	// indices are numbered from 1
+								}
+							}
+						}
+					}
+				}
+				
+				// why delay adding evidence sequences until here (after last frame read and processed) ?
+				// in case one day we gather this dynamically and merge, rather than just using command
+				// line arguments
+				
+				if (addReferenced) makeReferencedImageEvidenceSequence(
+					&newList,
+					minimalAttributesOnly,
+					addReferenced_studyInstanceUID,
+					addReferenced_seriesInstanceUID,
+					addReferenced_referencedSOPClassUID,
+					addReferenced_referencedSOPInstanceUID);
+				if (addDerivation) makeSourceImageEvidenceSequence(
+					&newList,
+					minimalAttributesOnly,
+					addDerivation_studyInstanceUID,
+					addDerivation_seriesInstanceUID,
+					addDerivation_referencedSOPClassUID,
+					addDerivation_referencedSOPInstanceUID);
+			
+                                if (useExtraPixelDataWritePass) {
+                                        // we have deferred writing newList until now ... so do it now ...
+//cerr << "Deferred write of newList" << endl;
+                                        if (!usualManagedAttributeListWrite(newList,dout,dicom_output_options,log,veryverbose)) {
+                                                success=false;
+                                                break;
+                                        }
+                                }
+				
+                        }
+
+                        // clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+                        if (fstr) delete fstr;
+                }
+        }
+        
+        if (useExtraPixelDataWritePass) {
+//cerr << "Entering extra Pixel Data write pass" << endl;
+                int i;
+                for (i=0; i < numberofinputfiles; ++i) {
+
+                        // open and read each image file ...
+
+                        const char *filename=sortedfilenamestable[i].filename;
+                        Assert(filename);
+                        if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+                        ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+                        ifstream *fstr=new ifstream(filename);
+#endif
+                        if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+                                cerr << AMsgDC(FileReadOpenFailed);
+                                if (filename) cerr <<" - \"" << filename << "\"";
+                                success=false;
+                                break;
+                            }
+
+                        DicomInputStream din(*(istream *)fstr,
+                                dicom_input_options.transfersyntaxuid,
+                                dicom_input_options.usemetaheader);
+
+                        ManagedAttributeList list;
+
+                        if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+                        list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+                        if (!list.good()) {
+                                log << list.errors()
+                                    << EMsgDC(DatasetReadFailed) << endl;
+                                success=false;
+                                break;
+                        }
+
+                        // Get pixel data attribute for later use ...
+
+                        Attribute *apixeldata=list[TagFromName(PixelData)];
+                        if (!apixeldata) {
+                                log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+                                success=false;
+                                break;
+                        }
+
+                        if (i == 0) {
+                                 // Now add "empty" pixel data attribute without pixels but correct value length ...
+
+                                OtherUnspecifiedLargeAttributeDummy *dummyPixelData = new
+                                        OtherUnspecifiedLargeAttributeDummy(TagFromName(PixelData),
+                                                requiredRows,requiredColumns,numberofinputfiles,requiredSamplesPerPixel,
+                                                dout.getTransferSyntaxToWriteDataSet(),
+                                                0 /* let encoding rules calculate bytesinword */,
+                                                requiredBitsAllocated,requiredBitsStored,requiredHighBit,
+                                                0xffffffff /* let encoding rules calculate length */);
+                                Assert(dummyPixelData);
+
+                                dummyPixelData->writeBase(dout);
+
+                                if (veryverbose) {
+                                        dummyPixelData->writeBase(log,&staticDictionary,false);
+                                        log << "[]" << endl;
+                                }
+                        }
+
+                        if (apixeldata) {
+                                if (!apixeldata->isOtherData()) {
+                                        log << EMsgDC(PixelDataIncorrectVR) << endl;
+                                        success=false;
+                                        break;
+                                }
+                                else {
+                                        // Check for compatible transfer syntax and append to pixel data ...
+                                        TransferSyntax *its=din.getTransferSyntaxToReadDataSet();
+                                        Assert(its);
+                                        TransferSyntax *ots=dout.getTransferSyntaxToWriteDataSet();
+                                        Assert(ots);
+
+                                        if (its->isEncapsulated()) {
+                                                log << "Can't read encapsulated transfer syntax from file <" << filename << ">" << endl;
+                                                success=false;
+                                                break;
+                                        }
+                                        else if (its->getEndian() != ots->getEndian()) {
+                                                log << "Input byte order in input file <" << filename << "> differs from output - not supported" << endl;
+                                                success=false;
+                                                break;
+                                        }
+                                        else {
+                                                OtherUnspecifiedLargeAttributeBase *opixeldata = apixeldata->castToOtherData();
+                                                Assert(opixeldata);
+                                                opixeldata->writeRaw(dout);
+
+                                                if (verbose) log << "wrote frame " << i
+							 << " from filename <" << filename << ">" << endl;
+                                        }
+                                }
+                        }
+
+                        // clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+                        if (fstr) delete fstr;
+                }
+        }
+        
+	if (numberofinputfiles && sortedfilenamestable) delete[] sortedfilenamestable;
+
+	return success ? 0 : 1;
+}
+
+	
+
+
diff --git a/appsrc/dcfile/dcmulti.man b/appsrc/dcfile/dcmulti.man
new file mode 100755
index 0000000..987d704
--- /dev/null
+++ b/appsrc/dcfile/dcmulti.man
@@ -0,0 +1,462 @@
+.TH DCMULTI 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Make multiframe image"
+.SH NAME
+dcmulti \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Make multiframe image from single frames
+.SH SYNOPSIS
+.HP 10
+.B dcmulti
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+[
+.B \-v|verbose|vv|veryverbose|vvv|veryveryverbose
+]
+[
+.B \-l
+]
+[
+.B \-noicons
+]
+[
+.B \-position
+]
+[
+.B \-sortby " elementname "
+[
+.B \-descending
+]
+]
+[
+.B \-nomrmf
+]
+[
+.B \-makestack
+[
+.B \-stackdescending
+]
+]
+[
+.B \-temporalposition
+]
+[
+.B \-dimension " elementname functionalgroupname "
+]
+[
+.B \-multidimension " elementname functionalgroupname organizationlabel organizationuid"
+]
+[
+.B \-addreferenced " class instance frames purposescheme code mng vers "
+[
+.B \-perframereference
+]
+]
+[
+.B \-addderivation " class instance frames derivationcheme code mng vers purposecheme code mng vers "
+[
+.B \-perframederivation
+]
+]
+[
+.B \-addsatslab " thickness orientX orientY orientZ midpointX midpointY midpointZ "
+]
+[
+.B \-addcolorlut " numberofentries firstvaluemapped firstred incrred firstgreen incrgreen firstblue incrblue "
+]
+[
+.B \-accumulateduration
+]
+[
+.B \-derivedurationfromtiming
+]
+[
+.B \-addnonderivedstuffanyway
+]
+[
+.B \-addpositionstuffanyway
+]
+[
+.B \-addtimingstuffanyway
+]
+[
+.B \-phasecontrast
+]
+[
+.B \-minimalattributes
+]
+[
+.B \-nowindow
+]
+[
+.B \-enhancedcontrast
+]
+[
+.B \-sync
+]
+[
+.B \-copyall
+]
+[
+.B \-input-nometa
+]
+[
+.B \-input-ts " uid"
+]
+[
+.B \-input-default
+]
+[
+.B \-input-byteorder|-input-endian " big|little"
+]
+[
+.B \-input-vr " implicit|explicit"
+]
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcmulti
+reads the named dicom single frame input files, checks to ensure that
+patient, study, series and image information, are consistent
+and concatenates all the images into a multiframe image as output.
+.LP
+Moderately extensive checking is performed to ensure that patient, study
+and series level identifiers and UIDs are consistent. Image level attributes
+related to pixel representation (i.e. the Image Pixel Module) are also
+checked, since inconsistency in these will render the output
+meaningless. For specific modalities, such as CT and MR, other image
+level attributes are checked for consistency, such as rescale
+parameters, pulse sequence parameters and slice thickness.
+.LP
+It is recommended that before building a multiframe object, the source
+images be manually checked for consistency of important attributes,
+for example by using the dctable(1) utility on the same set of images.
+.LP
+The images will be concatenated in the order specified on the command
+line, unless the \-sortby option is specified, in which case they will
+first be sorted in ascending order (unless \-descending is specified)
+by the values of the attribute. Any numeric attribute that is expected
+to be present in the images can be specified.
+.LP
+In addition, either
+ImagePositionPatient or ImageOrientationPatient may be specified
+as sort keys. These multi-valued attributes are handled specially
+for sorting.
+.LP
+For ImagePositionPatient, the images will be sorted
+by relative position along a vector normal to the plane of the
+first image (which ideally be the same plane and normal for all
+images though this is not required). For example, for axial images
+that are oriented as if viewed from below, images closer to the
+feet will sort before images closer to the head, since the normal is
+directed from the image plane toward the viewer, and the DICOM coordinate
+system along the Z axis values toward the head are more positive.
+Note that the first image supplied on the command line does not have
+to be the first in the volume for this to work.
+.LP
+Note that a similar effect can be achieved by sorting on SliceLocation,
+but this is an optional attribute, may not be present or completed,
+does not have a defined sign with respect to orientation of the patient,
+and may not correctly reflect complicated oblique slices in MR.
+.LP
+For ImageOrientationPatient, the images will be sorted
+by relative angle between vectors normal to the planes of
+the current image and the first image. Ideally, all these
+normals should be coplanar for the sort to be meaningful.
+Note that the first image supplied on the command line does not have
+to be the first rotation in the volume for this to work.
+.LP
+The output file will contain a Number Of Frames attribute with the
+number of frames generated (equal to the number of input files),
+but there is no provision to automatically generate a Frame Increment
+Pointer. If necessary this can be added on the command line together
+with the appropriate vectors of values, using the \-r option, or
+built using ancreate(1) and merged into the output of this utility
+with dcmerge(1).
+.LP
+The output file will contain attributes for the general and SOP Class
+specific modules copied from the first image, unless -copyall is
+specified in which case it will contain all the same attributes as the the first sorted
+input file. This includes patient, study and series level identifiers and
+UIDs, except that Instance Number will be set to 1 and a new SOP Instance
+UID will be generated. Any Data Set Trailing Padding in the input images
+will also be removed.
+.LP
+Note especially that the SOPClassUID will not be changed, that is it will
+be the same as the (first sorted) input file, with the exception of the
+SC and MR SOP Classes, in which case an appropriate new SC multi-frame
+oir MR SOP Class will be chosen. In the case of CT images, where
+multiframe images are not allowed, this will generate an illegal DICOM
+dataset. The SOPClassUID can be replaced on the command line by using
+the \-r option, but since there is no standard SOP Class for multiframe
+CT, it is not obvious what the output SOP
+Class should be. Until the standard is extended, the use of a private
+SOP class is recommended. In the case where the multiframe output of
+this utility is only being used as an intermediate step to another
+multiframe file format or for import into a viewing application that
+can't sort slices but can read volumes, then the issue of SOP Class
+can probably safely be ignored.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The output encoding of the file needs to have the same byte order
+(little or big endian) as the input files.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-v|verbose
+.RS
+List sort order and which file contributres to which frame as it is written.
+.RE
+.TP
+.B \-vv|veryverbose
+.RE
+.B \-vvv|veryveryverbose
+.RS
+Dump contents of files and data structures with increasing verbosity.
+.RE
+.TP
+.B \-sortby elementname [\-descending]
+.RS
+Sort by the specified DICOM element name in ascending (default) or
+descending numeric order.
+.RE
+.TP
+.B \-nomrmf
+.RS
+Do not make MR multi-frame, and leave the single frame MR SOP Class UID alone.
+.RE
+.TP
+.B \-makestack [\-stackdescending]
+.RS
+Build MR multi-frame object stacks from position and orientation information and assign each
+frame a Stack ID and In-stack Position Number. The order in which the frames in a stack are
+sorted by position along the normal to the plane orientation is ascending unless descending
+is specified. Note that the frames are not physically re-organized by stack ... only the
+identifiers are created. The sort direction (ascending or descending) of the stack may be different from the direction
+of the encoded frames themselves.
+.RE
+.TP
+.B \-temporalposition
+.RS
+For MR multi-frame, find temporal positions based on Trigger Time, or Acquisition Time if
+Trigger Time is absent, and insert Temporal Position Index into Frame Content Macro. Note that the frames are not physically re-organized by temporal position ... only the identifiers are created.
+.RE
+.TP
+.B \-dimension elementname functionalgroupname
+.RE
+.B \-multidimension elementname functionalgroupname organizationlabel organizationuid
+.RS
+Zero or more dimensions may be specified, those encountered earlier on the command line being the
+major dimensions (varying slowest). It is necessary to specify both the name of the element that
+is used as the index of the dimension (e.g. TriggerDelayTime, InStackPositionNumber) as well as
+the name of the sequence of the functional group in which it is contained (e.g. CardiacTriggerSequence,
+FrameContentSequence). The specified element should be of a numeric VR, except for selected exceptions
+that include FrameType and ContrastBolusAgentPhase, for which pre-determined sort orders are defined.
+If the \-dimension argument is used, there is only a single dimension organization. If the \-multidimension
+argument is used, then more than one dimension organization (set of dimensions) can be specified, and
+these are distinguished from each other if either the specified label or the specified uid are distinct.
+Either the label or the uid or both may be blank. If they are both blank, then a default dimension organization
+will be used (this is then the same as using \-dimension). If the uid is blank then a uid will be generated
+by the application for each dimension organization (including the default and those with distinct labels).
+.RE
+.TP
+.B \-addreferenced class instance frames purposescheme code mng vers
+.RS
+Add Referenced Image Sequence using the supplied parameters (frame may be zero length
+if whole image).
+.RE
+.TP
+.B \-perframereference
+.RS
+Add the Referenced Image Sequence to the Per-frame rather than Shared functional groups sequence
+(even though all identical).
+.RE
+.TP
+.B \-addderivation class instance frames derivationcheme code mng vers purposecheme code mng vers
+.RS
+Add Derivation Image Sequence using the supplied parameters (frame may be zero length
+if whole image).
+.RE
+.B \-perframederivation
+.RS
+Add the Derivation Image Sequence to the Per-frame rather than Shared functional groups sequence
+(even though all identical).
+.RE
+.TP
+.B \-addsatslab thickness orientX orientY orientZ midpointX midpointY midpointZ
+.RS
+Add Saturation Slab using the supplied parameters.
+.RE
+.TP
+.B \-addcolorlut numberofentries firstvaluemapped firstred incrred firstgreen incrgreen firstblue incrblue
+.RS
+Add a Supplemental Color LUT using the supplied parameters.
+.RE
+.TP
+.B \-accumulateduration
+.RS
+Summate frame acquisition durations to compute acquisition duration for whole object
+(e.g. for a cine MR acquisition). Default is to expect that frame and image acquisition
+durations are the same
+.RE
+.TP
+.B \-derivedurationfromtiming
+.RS
+Derive a value for frame acquisition duration and acquisition duration from MR timing
+parameters like number of averages, number of frequency encoding steps, repetition
+time and echo train length.
+.RE
+.TP
+.B \-addnonderivedstuffanyway
+.RS
+Normally at the image and frame level if the first value of Image Type is DERIVED, acquisition specific
+stuff is not added ... this option forces it to be added anyway.
+.RE
+.TP
+.B \-addpositionstuffanyway
+.RS
+Normally at the image and frame level if the first value of Image Type is DERIVED, position and orientation
+stuff is not added ... this option forces it to be added anyway.
+.RE
+.TP
+.B \-addtimingstuffanyway
+.RS
+Normally at the image and frame level if the first value of Image Type is DERIVED, acquisition and reference timing
+stuff is not added ... this option forces it to be added anyway.
+.RE
+.TP
+.B \-phasecontrast
+.RS
+Add MR Velocity Encoding Sequence.
+.RE
+.TP
+.B \-minimalattributes
+.RS
+Only add minimal required standard attributes for the Enhanced CT or MR SOP Class and nothing more.
+.RE
+.TP
+.B \-nowindow
+.RS
+Do not add.
+.RE
+.TP
+.B \-enhancedcontrast
+.RS
+Add Enhanced Contrast/Bolus Module and Contrast/Bolus Usage Sequence. Requires non-standard multivalued
+string attributes in source.
+.RE
+.TP
+.B \-sync
+.RS
+Add the Synchronization Module. Replaces any Synchronization Frame of Reference UID already present in source,
+any adds default values for minimal attributes if not already present in source.
+.RE
+.TP
+.B \-copyall
+.RS
+Copy all attributes from first file rather than only those in modules thought to
+be relevant to the multi-frame IOD being created.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcmulti IMAGES/[0-9]* -verbose >MFIMAGE
+.RE
+wrote frame 0 from filename <IMAGES/0>
+.RE
+wrote frame 1 from filename <IMAGES/1>
+.RE
+ ...
+.RE
+\ 
+.RE
+% dcmulti IMAGES/[0-9]* -verbose -sortby InstanceNumber -descending >MFIMAGE
+.RE
+After sorting
+.RE
+InstanceNumber[0] = 10 in IMAGES/9
+.RE
+InstanceNumber[1] = 9 in IMAGES/8
+.RE
+ ...
+.RE
+wrote frame 0 from filename <IMAGES/9>
+.RE
+wrote frame 1 from filename <IMAGES/8>
+.RE
+ ...
+.RE
+\ 
+.RE
+% dcmulti IMAGES/[0-9]* -verbose -sortby ImageOrientationPatient >MFIMAGE
+.RE
+After sorting
+.RE
+ImageOrientationPatient[0] = 0 in IMAGES/0
+.RE
+ImageOrientationPatient[1] = 45 in IMAGES/1
+.RE
+ ...
+.RE
+wrote frame 0 from filename <IMAGES/0>
+.RE
+wrote frame 1 from filename <IMAGES/1>
+.RE
+ ...
+.RE
+\ 
+.RE
+% dcmulti IMAGES/[0-9]* -verbose -sortby ImagePositionPatient >MFIMAGE
+.RE
+After sorting
+.RE
+ImageOrientationPatient[0] = \-124.262 in IMAGES/0
+.RE
+ImageOrientationPatient[1] = \-120.872 in IMAGES/1
+.RE
+ ...
+.RE
+wrote frame 0 from filename <IMAGES/0>
+.RE
+wrote frame 1 from filename <IMAGES/1>
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), 
+.BR ancreate(1), 
+.BR dcmerge(1), 
+.BR dctable(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+Data Set Trailing Padding is explicitly removed from the input images,
+but if there is anything else after the Pixel Data tag, the output
+file will be invalid (tags out of order) since the multiframe Pixel
+Data tag is added after everything else in the first input file is
+copied. If there are private things after the Pixel Data the use
+of the \-removeprivate option may help. This is only a problem
+when using the -copyall flag.
+.LP
+Byte order of input and output must be the same, due to the crude
+raw copying that is used to build the multiframe pixel data.
+.LP
+There is no support for bulding encapsulated transfer syntax
+representations of the multiframe image pixel data (i.e. with
+delimiters, JPEG, RLE, etc.)
+.LP
+If any of the Image Pixel Module attributes are inconsistent, such
+as different matrix sizes, an error will be flagged but the output
+file will still be built (though it will be meaningless).
+.LP
+Should check some multi valued attributes like PixelSpacing are
+consistent but doesn't yet.
diff --git a/appsrc/dcfile/dcmvhier.8only.man b/appsrc/dcfile/dcmvhier.8only.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcmvhier.8only.script b/appsrc/dcfile/dcmvhier.8only.script
new file mode 100755
index 0000000..76efdc0
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.8only.script
@@ -0,0 +1,90 @@
+#!/bin/sh
+#
+# usage: dcmvhier.8only "file"
+#
+# this script moves a single dicom file into a patient/study/series/image
+# hierarchy of the form:
+#
+#	PatientID/StudyDate/ModalitySeriesNumber/$$
+#
+# with only 8 character A-Z0-9_ component names
+#
+# Typically used as
+#
+#	find . -type f -exec dcmvhier.8only '{}' ';'
+#
+
+DCMSUFFIX=".dcm"
+
+DCKEY="dckey -ignoreoutofordertags"
+MV="mv"
+MKDIRHIER="mkdir -p"
+CMP="cmp"
+RM="rm"
+
+srcfile="$*"
+	#echo "$srcfile"
+
+	patientid=`$DCKEY -k PatientID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Z0-9_]//g'`
+	patientlabel="$patientid"
+	if [ -z "$patientlabel" ]; then patientlabel="NONAME"; fi
+	patientlabel=`echo "$patientlabel" | sed 's/^\([A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_]\).*$/\1/'`
+
+	studydate=`$DCKEY -k StudyDate "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9]//g'`
+	if [ -z "$studydate" ]
+	then
+		studyid=`$DCKEY -k StudyID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Z0-9_]//g'`
+		studylabel="$studyid"
+	else
+		studylabel="$studydate"
+	fi
+	if [ -z "$studylabel" ]; then studylabel="NOSTUDY"; fi
+	studylabel=`echo "$studylabel" | sed 's/^\([A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_]\).*$/\1/'`
+
+	seriesnum=`$DCKEY -k SeriesNumber "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9]//g'`
+	modality=`$DCKEY -k Modality "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Z0-9_]//g'`
+	serieslabel="$modality$seriesnum"
+	if [ -z "$serieslabel" ]; then serieslabel="NOSERIES"; fi
+	serieslabel=`echo "$serieslabel" | sed 's/^\([A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_]\).*$/\1/'`
+
+	#instancenum=`$DCKEY -k InstanceNumber "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9]//g'`
+	#if [ -z "$instancenum" ]
+	#then
+	#	acqnum=`$DCKEY -k AcquisitionNumber "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9]//g'`
+	#	instancelabel="$acqnum"
+	#else
+	#	instancelabel="$instancenum"
+	#fi
+	if [ -z "$instancelabel" ]; then instancelabel="$$"; fi
+	instancelabel=`echo "$instancelabel" | sed 's/^\([A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_][A-Z0-9_]\).*$/\1/'`
+	
+	if [ ! -z "$patientlabel" -a ! -z "$studylabel" -a ! -z "$serieslabel" -a ! -z "$instancelabel" ]
+	then
+		newdir="$patientlabel/$studylabel/$serieslabel"
+		if [ ! -d "$newdir" ]
+		then
+			#echo $MKDIRHIER "$newdir"
+			$MKDIRHIER "$newdir"
+		fi
+		newfile="$newdir/$instancelabel"
+		if [ ! -f "$newfile" ]
+		then
+			echo $MV "$srcfile" "$newfile"
+			$MV "$srcfile" "$newfile"
+		else
+			if [ `ls -i "$srcfile" | awk '{print $1}'` = `ls -i "$newfile" | awk '{print $1}'` ]
+			then
+				echo "$srcfile: Same file (inode) as $newfile" 1>&2
+				# move anyway, in case we want to rename it
+				$MV "$srcfile" "$newfile"
+			else
+				if $CMP "$srcfile" "$newfile"
+				then
+					echo "$srcfile: removing, same content as existing $newfile" 1>&2
+					$RM "$srcfile"
+				else
+					echo "$srcfile: leaving, not overwriting different $newfile" 1>&2
+				fi
+			fi
+		fi
+	fi
diff --git a/appsrc/dcfile/dcmvhier.all.man b/appsrc/dcfile/dcmvhier.all.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcmvhier.all.script b/appsrc/dcfile/dcmvhier.all.script
new file mode 100755
index 0000000..2e3bd56
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.all.script
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Usage: dcmvhier.all dirname
+#
+# where dirname is the directory name where .dcm images are
+#
+
+DCMSUFFIX="dcm"
+
+DCMVHIER="dcmvhier"
+
+if [ ! $# = 1 ]
+then
+	echo 1>&2 "Usage: `basename $0` dirname"
+	exit 1
+fi
+
+FINDARG='*.'"$DCMSUFFIX"
+
+"$DCMVHIER" `find "$1" -name "$FINDARG" -print`
+
+exit 0
+
diff --git a/appsrc/dcfile/dcmvhier.datedesc.man b/appsrc/dcfile/dcmvhier.datedesc.man
new file mode 100644
index 0000000..e9beae6
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.datedesc.man
@@ -0,0 +1,44 @@
+.TH DCMVHIER 1 "14 August 2008" "DICOM PS3" "DICOM PS3 - Move DICOM files into hierarchy"
+.SH NAME
+dcmvhier.datedesc \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Move DICOM files into hierarchy
+.SH SYNOPSIS
+.HP 10
+.B dcmvhier.datedesc filename
+.SH DESCRIPTION
+.LP
+.B dcmvhier.datedesc
+reads the named dicom or acr-nema input file and moves it into a directory
+hierarchy of the form "PatientName [PatientID]/StudyDate StudyTime [StudyID - StudyDescription]/Series SeriesNumber [Modality - Series Description]/SOPInstanceUID.dcm", rooted at
+the current working directory. Any characters
+in the identifiers other than numbers, letters, underscore, hyphen and period
+are deleted before creating the path name. The files are moved, not copied,
+and renamed. If any of the necessary identifiers is missing the script aborts.
+If the directory hierarchy does not yet exist it is created, but if the image
+file name already exists in that directory, the script aborts (to avoid
+overwriting images not properly disamibiguated by the selected identifiers
+and characters).
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+find . -type f -exec dcmvhier.datedesc '{}' ';'
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcmvhier(1),
+.BR dcmvhier.8only(1),
+.BR dcmvhier.uid(1),
+.BR dcmvhier.datedescnoid(1),
+.BR dcmvhier.all(1)
+.LP
+\ 
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcmvhier.datedesc.script b/appsrc/dcfile/dcmvhier.datedesc.script
new file mode 100755
index 0000000..968af40
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.datedesc.script
@@ -0,0 +1,85 @@
+#!/bin/sh
+#
+# usage: dcmvhier.datedesc "file"
+#
+# this script moves a single dicom file into a patient/study/series/image
+# hierarchy of the form:
+#
+#	PatientName [PatientID]/StudyDate StudyTime [StudyID - StudyDescription]/Series SeriesNumber [Modality - Series Description]/SOPInstanceUID.dcm
+#
+# Typically used as
+#
+#	find . -type f -exec dcmvhier.datedesc '{}' ';'
+#
+
+DCMSUFFIX=".dcm"
+
+DCKEY="dckey -ignoreoutofordertags -ignorereaderrors -noerror"
+MV="mv"
+MKDIRHIER="mkdir -p"
+CMP="cmp"
+RM="rm"
+
+srcfile="$*"
+	#echo "$srcfile"
+
+	patientid=`$DCKEY -k PatientID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$patientid" ]; then patientid="NOID"; fi
+	patientname=`$DCKEY -k PatientName "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ^=,.]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g' -e 's/^[.]/_/'`
+	if [ -z "$patientname" ]; then patientname="NONAME"; fi
+	patientlabel="$patientname [$patientid]"
+
+	studydate=`$DCKEY -k StudyDate "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$studydate" ]; then studydate="19000101"; fi
+	studytime=`$DCKEY -k StudyTime "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g' -e 's/^\([0-9][0-9][0-9][0-9][0-9][0-9]\).*$/\1/'`
+	if [ -z "$studytime" ]; then studytime="000000"; fi
+	studyid=`$DCKEY -k StudyID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	studydesc=`$DCKEY -k StudyDescription "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$studydesc" ]
+	then
+		studylabel="$studydate $studytime [$studyid]"
+	else
+		studylabel="$studydate $studytime [$studyid - $studydesc]"
+	fi
+
+	seriesnum=`$DCKEY -k SeriesNumber "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9]//g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g' -e 's/^\([0-9]\)$/00\1/' -e 's/^\([0-9][0-9]\)$/0\1/' `
+	if [ -z "$seriesnum" ]; then seriesnum="000"; fi
+	seriesdesc=`$DCKEY -k SeriesDescription "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	modality=`$DCKEY -k Modality "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	serieslabel="Series $seriesnum [$modality - $seriesdesc]"
+
+	instanceuid=`$DCKEY -k SOPInstanceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$instanceuid" ]
+	then
+		echo "$srcfile: No SOP Instance UID - doing nothing" 1>&2
+	else
+		instancelabel="$instanceuid"
+
+		newdir="$patientlabel/$studylabel/$serieslabel"
+		if [ ! -d "$newdir" ]
+		then
+			#echo $MKDIRHIER "$newdir"
+			$MKDIRHIER "$newdir"
+		fi
+		newfile="$newdir/$instancelabel$DCMSUFFIX"
+		if [ ! -f "$newfile" ]
+		then
+			echo $MV "$srcfile" "$newfile"
+			$MV "$srcfile" "$newfile"
+		else
+			if [ `ls -i "$srcfile" | awk '{print $1}'` = `ls -i "$newfile" | awk '{print $1}'` ]
+			then
+				echo "$srcfile: Same file (inode) as $newfile" 1>&2
+				# move anyway, in case we want to rename it
+				$MV "$srcfile" "$newfile"
+			else
+				if $CMP "$srcfile" "$newfile"
+				then
+					echo "$srcfile: removing, same content as existing $newfile" 1>&2
+					$RM "$srcfile"
+				else
+					echo "$srcfile: leaving, not overwriting different $newfile" 1>&2
+				fi
+			fi
+		fi
+	fi
diff --git a/appsrc/dcfile/dcmvhier.datedescnoid.man b/appsrc/dcfile/dcmvhier.datedescnoid.man
new file mode 100644
index 0000000..85eba7f
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.datedescnoid.man
@@ -0,0 +1,44 @@
+.TH DCMVHIER 1 "14 August 2008" "DICOM PS3" "DICOM PS3 - Move DICOM files into hierarchy"
+.SH NAME
+dcmvhier.datedescnoid \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Move DICOM files into hierarchy
+.SH SYNOPSIS
+.HP 10
+.B dcmvhier.datedescnoid filename
+.SH DESCRIPTION
+.LP
+.B dcmvhier
+reads the named dicom or acr-nema input file and moves it into a directory
+hierarchy of the form "PatientName [PatientID]/StudyDate StudyTime/Series SeriesNumber [Series Description]/SOPInstanceUID.dcm", rooted at
+the current working directory. Any characters
+in the identifiers other than numbers, letters, underscore, hyphen and period
+are deleted before creating the path name. The files are moved, not copied,
+and renamed. If any of the necessary identifiers is missing the script aborts.
+If the directory hierarchy does not yet exist it is created, but if the image
+file name already exists in that directory, the script aborts (to avoid
+overwriting images not properly disamibiguated by the selected identifiers
+and characters).
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+find . -type f -exec dcmvhier.datedescnoid '{}' ';'
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcmvhier(1),
+.BR dcmvhier.8only(1),
+.BR dcmvhier.uid(1),
+.BR dcmvhier.datedesc(1),
+.BR dcmvhier.all(1)
+.LP
+\ 
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcmvhier.datedescnoid.script b/appsrc/dcfile/dcmvhier.datedescnoid.script
new file mode 100755
index 0000000..7a29915
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.datedescnoid.script
@@ -0,0 +1,77 @@
+#!/bin/sh
+#
+# usage: dcmvhier.datedescnoid "file"
+#
+# this script moves a single dicom file into a patient/study/series/image
+# hierarchy of the form:
+#
+#	PatientName [PatientID]/StudyDate StudyTime/Series SeriesNumber [Series Description]/SOPInstanceUID.dcm
+#
+# Typically used as
+#
+#	find . -type f -exec dcmvhier.datedescnoid '{}' ';'
+#
+
+DCMSUFFIX=".dcm"
+
+DCKEY="dckey -ignoreoutofordertags -ignorereaderrors -noerror"
+MV="mv"
+MKDIRHIER="mkdir -p"
+CMP="cmp"
+RM="rm"
+
+srcfile="$*"
+	#echo "$srcfile"
+
+	patientid=`$DCKEY -k PatientID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$patientid" ]; then patientid="NOID"; fi
+	patientname=`$DCKEY -k PatientName "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ^=,.]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g' -e 's/^[.]/_/'`
+	if [ -z "$patientname" ]; then patientname="NONAME"; fi
+	patientlabel="$patientname [$patientid]"
+
+	studydate=`$DCKEY -k StudyDate "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$studydate" ]; then studydate="19000101"; fi
+	studytime=`$DCKEY -k StudyTime "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g' -e 's/^\([0-9][0-9][0-9][0-9][0-9][0-9]\).*$/\1/'`
+	if [ -z "$studytime" ]; then studytime="000000"; fi
+	studylabel="$studydate $studytime"
+
+	seriesnum=`$DCKEY -k SeriesNumber "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9]//g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g' -e 's/^\([0-9]\)$/00\1/' -e 's/^\([0-9][0-9]\)$/0\1/' `
+	if [ -z "$seriesnum" ]; then seriesnum="000"; fi
+	seriesdesc=`$DCKEY -k SeriesDescription "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^A-Za-z0-9 ]/_/g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	serieslabel="Series $seriesnum [$seriesdesc]"
+
+	instanceuid=`$DCKEY -k SOPInstanceUID "$srcfile" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g' -e 's/^[ _]*//g' -e 's/[ _]*$//g' -e 's/[ ][ ]*/ /g' -e 's/[_][_]*/_/g' -e 's/[_][ ]/ /g'`
+	if [ -z "$instanceuid" ]
+	then
+		echo "$srcfile: No SOP Instance UID - doing nothing" 1>&2
+	else
+		instancelabel="$instanceuid"
+
+		newdir="$patientlabel/$studylabel/$serieslabel"
+		if [ ! -d "$newdir" ]
+		then
+			#echo $MKDIRHIER "$newdir"
+			$MKDIRHIER "$newdir"
+		fi
+		newfile="$newdir/$instancelabel$DCMSUFFIX"
+		if [ ! -f "$newfile" ]
+		then
+			echo $MV "$srcfile" "$newfile"
+			$MV "$srcfile" "$newfile"
+		else
+			if [ `ls -i "$srcfile" | awk '{print $1}'` = `ls -i "$newfile" | awk '{print $1}'` ]
+			then
+				echo "$srcfile: Same file (inode) as $newfile" 1>&2
+				# move anyway, in case we want to rename it
+				$MV "$srcfile" "$newfile"
+			else
+				if $CMP "$srcfile" "$newfile"
+				then
+					echo "$srcfile: removing, same content as existing $newfile" 1>&2
+					$RM "$srcfile"
+				else
+					echo "$srcfile: leaving, not overwriting different $newfile" 1>&2
+				fi
+			fi
+		fi
+	fi
diff --git a/appsrc/dcfile/dcmvhier.man b/appsrc/dcfile/dcmvhier.man
new file mode 100755
index 0000000..e629475
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.man
@@ -0,0 +1,45 @@
+.TH DCMVHIER 1 "14 August 2008" "DICOM PS3" "DICOM PS3 - Move DICOM files into hierarchy"
+.SH NAME
+dcmvhier \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Move DICOM files into hierarchy
+.SH SYNOPSIS
+.HP 10
+.B dcmvhier filelist
+.SH DESCRIPTION
+.LP
+.B dcmvhier
+reads the named dicom or acr-nema input files and moves them into a directory
+hierarchy of the form PatientID/StudyID/SeriesNumber/ImageNumber, rooted at
+the current working directory. Any characters
+in the identifiers other than numbers, letters, underscore, hyphen and period
+are deleted before creating the path name. The files are moved, not copied,
+and renamed. If any of the necessary identifiers is missing the script aborts.
+If the directory hierarchy does not yet exist it is created, but if the image
+file name already exists in that directory, the script aborts (to avoid
+overwriting images not properly disamibiguated by the selected identifiers
+and characters).
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+.BR dcmvhier.8only(1),
+.BR dcmvhier.uid(1),
+.BR dcmvhier.datedesc(1),
+.BR dcmvhier.datedescnoid(1),
+.BR dcmvhier.all(1)
+.LP
+\ 
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+No effort is made to check that other patient/study/series level attributes (such
+as UIDs) are the same values within all images of the created patient/study/series
+directories.
diff --git a/appsrc/dcfile/dcmvhier.script b/appsrc/dcfile/dcmvhier.script
new file mode 100755
index 0000000..6957b36
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.script
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+# usage: dcmvhier files
+#
+# this script moves dicom files into a patient/study/series/image
+# hierarchy
+
+DCMSUFFIX=".dcm"
+
+DCKEY="dckey -ignoreoutofordertags -ignorereaderrors -noerror"
+MV="mv"
+MKDIRHIER="mkdir -p"
+
+TMPFILE="/tmp/`basename $0`.$$.tmp"
+
+counter=1
+
+for i in $*
+do
+	#echo "$i"
+
+	patientid=`$DCKEY -k PatientID "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	patientname=`$DCKEY -k PatientName "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	patientlabel=$patientid$patientname
+	if [ -z "$patientlabel" ]
+	then
+		echo "$i: Warning: Missing both Patient ID and Name - moving to BADPATIENT" 1>&2
+		patientlabel="BADPATIENT"
+	fi
+
+	studyid=`$DCKEY -k StudyID "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	if [ -z "$studyid" ]
+	then
+		studyid="000000"
+	fi
+
+	seriesnum=`$DCKEY -k SeriesNumber "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	if [ -z "$seriesnum" ]
+	then
+		seriesnum="0"
+	fi
+
+	imagenum=`$DCKEY -k InstanceNumber "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	if [ -z "$imagenum" ]
+	then
+		imagenum="$$_$counter"
+	fi
+
+	if [ ! -d "$patientlabel/$studyid/$seriesnum" ]
+	then
+		$MKDIRHIER "$patientlabel/$studyid/$seriesnum"
+	fi
+
+ 	if [ ! -f "$patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX" ]
+	then
+		echo $MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX"
+		$MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX"
+	else
+		if [ ! -f "$patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX" ]
+		then
+			echo $MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX"
+			$MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX"
+		else
+			echo "$i: Not overwriting $patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX - aborting" 1>&2
+			echo "$i: Not overwriting $patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX - aborting" 1>&2
+			exit 1
+		fi
+	fi
+
+	counter=`expr $counter '+' 1`
+done
+
+rm -f "$TMPFILE"
diff --git a/appsrc/dcfile/dcmvhier.uid.man b/appsrc/dcfile/dcmvhier.uid.man
new file mode 100755
index 0000000..525319b
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.uid.man
@@ -0,0 +1,45 @@
+.TH DCMVHIER 1 "14 August 2008" "DICOM PS3" "DICOM PS3 - Move DICOM files into hierarchy by UID"
+.SH NAME
+dcmvhier \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Move DICOM files into hierarchy by UID
+.SH SYNOPSIS
+.HP 10
+.B dcmvhier.uid filelist
+.SH DESCRIPTION
+.LP
+.B dcmvhier.uid
+reads the named dicom or acr-nema input files and moves them into a directory
+hierarchy of the form PatientID/StudyInstanceUID/SeriesInstanceUID/ImageNumber, rooted at
+the current working directory. Any characters
+in the identifiers other than numbers, letters, underscore, hyphen and period
+are deleted before creating the path name. The files are moved, not copied,
+and renamed. If any of the necessary identifiers is missing the script aborts.
+If the directory hierarchy does not yet exist it is created, but if the image
+file name already exists in that directory, the script aborts (to avoid
+overwriting images not properly disamibiguated by the selected identifiers
+and characters).
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+.BR dcmvhier(1),
+.BR dcmvhier.8only(1),
+.BR dcmvhier.datedesc(1),
+.BR dcmvhier.datedescnoid(1),
+.BR dcmvhier.all(1)
+.LP
+\ 
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+No effort is made to check that other patient/study/series level attributes (such
+as IDs) are the same values within all images of the created patient/study/series
+directories.
diff --git a/appsrc/dcfile/dcmvhier.uid.script b/appsrc/dcfile/dcmvhier.uid.script
new file mode 100755
index 0000000..c793247
--- /dev/null
+++ b/appsrc/dcfile/dcmvhier.uid.script
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+# usage: dcmvhier files
+#
+# this script moves dicom files into a patient/study/series/image
+# hierarchy
+
+DCMSUFFIX=".dcm"
+
+DCKEY="dckey -ignoreoutofordertags -ignorereaderrors -noerror"
+MV="mv"
+MKDIRHIER="mkdir -p"
+
+TMPFILE="/tmp/`basename $0`.$$.tmp"
+
+counter=1
+
+for i in $*
+do
+	#echo "$i"
+
+	patientid=`$DCKEY -k PatientID "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	patientname=`$DCKEY -k PatientName "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	patientlabel=$patientid$patientname
+	if [ -z "$patientlabel" ]
+	then
+		echo "$i: Warning: Missing both Patient ID and Name - moving to BADPATIENT" 1>&2
+		patientlabel="BADPATIENT"
+	fi
+
+	studyid=`$DCKEY -k StudyInstanceUID "$i" 2>&1 | egrep -v 'Error|Warning'`
+	if [ -z "$studyid" ]
+	then
+		studyid="000000"
+	fi
+
+	seriesnum=`$DCKEY -k SeriesInstanceUID "$i" 2>&1 | egrep -v 'Error|Warning'`
+	if [ -z "$seriesnum" ]
+	then
+		seriesnum="0"
+	fi
+
+	imagenum=`$DCKEY -k InstanceNumber "$i" 2>&1 | egrep -v 'Error|Warning' | sed -e 's/[^0-9a-zA-Z_.-]//g'`
+	if [ -z "$imagenum" ]
+	then
+		imagenum="$$_$counter"
+	fi
+
+	if [ ! -d "$patientlabel/$studyid/$seriesnum" ]
+	then
+		$MKDIRHIER "$patientlabel/$studyid/$seriesnum"
+	fi
+
+ 	if [ ! -f "$patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX" ]
+	then
+		echo $MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX"
+		$MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX"
+	else
+		if [ ! -f "$patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX" ]
+		then
+			echo $MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX"
+			$MV "$i" "$patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX"
+		else
+			echo "$i: Not overwriting $patientlabel/$studyid/$seriesnum/$imagenum$DCMSUFFIX - aborting" 1>&2
+			echo "$i: Not overwriting $patientlabel/$studyid/$seriesnum/$imagenum.$counter$DCMSUFFIX - aborting" 1>&2
+			exit 1
+		fi
+	fi
+
+	counter=`expr $counter '+' 1`
+done
+
+rm -f "$TMPFILE"
diff --git a/appsrc/dcfile/dcortho.cc b/appsrc/dcfile/dcortho.cc
new file mode 100644
index 0000000..b3c2fdd
--- /dev/null
+++ b/appsrc/dcfile/dcortho.cc
@@ -0,0 +1,318 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcortho.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static inline Float32 Abs(Float32 x) { return ((x < 0) ? -x : x); }
+static inline Float32 Sqrt(Float32 x) { return sqrt(x); }
+
+static void
+MakeImagePlaneModuleOrthogonalToXYZ(ManagedAttributeList &list,
+		Float32 originX,Float32 originY,Float32 originZ)
+{
+//cerr << "originX = " << dec << originX << endl;
+//cerr << "originY = " << dec << originY << endl;
+//cerr << "originZ = " << dec << originZ << endl;
+
+	Attribute *aImagePositionPatient=list[TagFromName(ImagePositionPatient)];		// DICOM patient relative
+	Attribute *aImageOrientationPatient=list[TagFromName(ImageOrientationPatient)];		// DICOM patient relative
+
+	Assert(aImagePositionPatient && aImagePositionPatient->getVM() == 3);
+	Assert(aImageOrientationPatient && aImageOrientationPatient->getVM() == 6);
+
+	Float32 position_X; (void)aImagePositionPatient->getValue(0,position_X);
+	Float32 position_Y; (void)aImagePositionPatient->getValue(1,position_Y);
+	Float32 position_Z; (void)aImagePositionPatient->getValue(2,position_Z);
+
+	Float32 orientation_row_X; (void)aImageOrientationPatient->getValue(0,orientation_row_X);
+	Float32 orientation_row_Y; (void)aImageOrientationPatient->getValue(1,orientation_row_Y);
+	Float32 orientation_row_Z; (void)aImageOrientationPatient->getValue(2,orientation_row_Z);
+	Float32 orientation_col_X; (void)aImageOrientationPatient->getValue(3,orientation_col_X);
+	Float32 orientation_col_Y; (void)aImageOrientationPatient->getValue(4,orientation_col_Y);
+	Float32 orientation_col_Z; (void)aImageOrientationPatient->getValue(5,orientation_col_Z);
+
+	// Remove the attributes since they will be replaced later
+
+	list-=aImagePositionPatient;
+	list-=aImageOrientationPatient;
+
+	delete aImagePositionPatient;
+	delete aImageOrientationPatient;
+
+//cerr << "input position_X = " << dec << position_X << endl;
+//cerr << "input position_Y = " << dec << position_Y << endl;
+//cerr << "input position_Z = " << dec << position_Z << endl;
+//cerr << "input orientation_row_X = " << dec << orientation_row_X << endl;
+//cerr << "input orientation_row_Y = " << dec << orientation_row_Y << endl;
+//cerr << "input orientation_row_Z = " << dec << orientation_row_Z << endl;
+//cerr << "input orientation_col_X = " << dec << orientation_col_X << endl;
+//cerr << "input orientation_col_Y = " << dec << orientation_col_Y << endl;
+//cerr << "input orientation_col_Z = " << dec << orientation_col_Z << endl;
+
+	position_X-=originX;
+	position_Y-=originY;
+	position_Z-=originZ;
+
+//cerr << "corrected position_X = " << dec << position_X << endl;
+//cerr << "corrected position_Y = " << dec << position_Y << endl;
+//cerr << "corrected position_Z = " << dec << position_Z << endl;
+
+	// Determine major axis or row and column
+
+	bool major_row_axis_is_X = false;
+	bool major_row_axis_is_Y = false;
+	bool major_row_axis_is_Z = false;
+
+	bool major_col_axis_is_X = false;
+	bool major_col_axis_is_Y = false;
+	bool major_col_axis_is_Z = false;
+
+	bool position_axis_is_X = false;
+	bool position_axis_is_Y = false;
+	bool position_axis_is_Z = false;
+
+	int major_row_axis_sign;
+	int major_col_axis_sign;
+	int position_axis_sign;
+
+	if (Abs(orientation_row_X) >= Abs(orientation_row_Y)) {
+		if (Abs(orientation_row_X) >= Abs(orientation_row_Z)) {
+			major_row_axis_is_X=true;
+			major_row_axis_sign = (orientation_row_X < 0) ? -1 : 1;
+		}
+		else {
+			major_row_axis_is_Z=true;
+			major_row_axis_sign = (orientation_row_Z < 0) ? -1 : 1;
+		}
+	}
+	else {
+		if (Abs(orientation_row_Y) >= Abs(orientation_row_Z)) {
+			major_row_axis_is_Y=true;
+			major_row_axis_sign = (orientation_row_Y < 0) ? -1 : 1;
+		}
+		else {
+			major_row_axis_is_Z=true;
+			major_row_axis_sign = (orientation_row_Z < 0) ? -1 : 1;
+		}
+	}
+
+	if (Abs(orientation_col_X) >= Abs(orientation_col_Y)) {
+		if (Abs(orientation_col_X) >= Abs(orientation_col_Z)) {
+			major_col_axis_is_X=true;
+			major_col_axis_sign = (orientation_col_X < 0) ? -1 : 1;
+		}
+		else {
+			major_col_axis_is_Z=true;
+			major_col_axis_sign = (orientation_col_Z < 0) ? -1 : 1;
+		}
+	}
+	else {
+		if (Abs(orientation_col_Y) >= Abs(orientation_col_Z)) {
+			major_col_axis_is_Y=true;
+			major_col_axis_sign = (orientation_col_Y < 0) ? -1 : 1;
+		}
+		else {
+			major_col_axis_is_Z=true;
+			major_col_axis_sign = (orientation_col_Z < 0) ? -1 : 1;
+		}
+	}
+
+	// position axis is the remaining one ...
+
+	if      (major_row_axis_is_X && major_col_axis_is_Y) {
+		position_axis_is_Z=true;
+		position_axis_sign = (position_Z < 0) ? -1 : 1;
+	}
+	else if (major_row_axis_is_X && major_col_axis_is_Z) {
+		position_axis_is_Y=true;
+		position_axis_sign = (position_Y < 0) ? -1 : 1;
+	}
+	else if (major_row_axis_is_Y && major_col_axis_is_Z) {
+		position_axis_is_X=true;
+		position_axis_sign = (position_X < 0) ? -1 : 1;
+	}
+	else Assert(0);
+
+//cerr << "major_row_axis_is_X = " << dec << major_row_axis_is_X << endl;
+//cerr << "major_row_axis_is_Y = " << dec << major_row_axis_is_Y << endl;
+//cerr << "major_row_axis_is_Z = " << dec << major_row_axis_is_Z << endl;
+//cerr << "major_col_axis_is_X = " << dec << major_col_axis_is_X << endl;
+//cerr << "major_col_axis_is_Y = " << dec << major_col_axis_is_Y << endl;
+//cerr << "major_col_axis_is_Z = " << dec << major_col_axis_is_Z << endl;
+//cerr << "position_axis_is_X = " << dec << position_axis_is_X << endl;
+//cerr << "position_axis_is_Y = " << dec << position_axis_is_Y << endl;
+//cerr << "position_axis_is_Z = " << dec << position_axis_is_Z << endl;
+
+//cerr << "major_row_axis_sign = " << dec << major_row_axis_sign << endl;
+//cerr << "major_col_axis_sign = " << dec << major_col_axis_sign << endl;
+//cerr << "position_axis_sign = "  << dec << position_axis_sign  << endl;
+
+	// goal now is to zero out all except major axis for both
+	// position and orientation
+
+	// assume all are vectors from origin of zero ...
+
+	Float32 position_vector_from_origin = Sqrt(position_X*position_X
+						  +position_Y*position_Y
+						  +position_Z*position_Z) * position_axis_sign;
+	Float32 row_vector_from_origin = Sqrt(orientation_row_X*orientation_row_X
+					     +orientation_row_Y*orientation_row_Y
+					     +orientation_row_Z*orientation_row_Z) * major_row_axis_sign;
+	Float32 col_vector_from_origin = Sqrt(orientation_col_X*orientation_col_X
+					     +orientation_col_Y*orientation_col_Y
+					     +orientation_col_Z*orientation_col_Z) * major_col_axis_sign;
+
+	// Are now going to replace original values (which are being lost) ...
+
+	position_X = position_axis_is_X ? position_vector_from_origin : 0;
+	position_Y = position_axis_is_Y ? position_vector_from_origin : 0;
+	position_Z = position_axis_is_Z ? position_vector_from_origin : 0;
+
+	orientation_row_X = major_row_axis_is_X ? row_vector_from_origin : 0;
+	orientation_row_Y = major_row_axis_is_Y ? row_vector_from_origin : 0;
+	orientation_row_Z = major_row_axis_is_Z ? row_vector_from_origin : 0;
+
+	orientation_col_X = major_col_axis_is_X ? col_vector_from_origin : 0;
+	orientation_col_Y = major_col_axis_is_Y ? col_vector_from_origin : 0;
+	orientation_col_Z = major_col_axis_is_Z ? col_vector_from_origin : 0;
+
+
+//cerr << "uncorrected position_X = " << dec << position_X << endl;
+//cerr << "uncorrected position_Y = " << dec << position_Y << endl;
+//cerr << "uncorrected position_Z = " << dec << position_Z << endl;
+
+	position_X+=originX;
+	position_Y+=originY;
+	position_Z+=originZ;
+
+//cerr << "output position_X = " << dec << position_X << endl;
+//cerr << "output position_Y = " << dec << position_Y << endl;
+//cerr << "output position_Z = " << dec << position_Z << endl;
+//cerr << "output orientation_row_X = " << dec << orientation_row_X << endl;
+//cerr << "output orientation_row_Y = " << dec << orientation_row_Y << endl;
+//cerr << "output orientation_row_Z = " << dec << orientation_row_Z << endl;
+//cerr << "output orientation_col_X = " << dec << orientation_col_X << endl;
+//cerr << "output orientation_col_Y = " << dec << orientation_col_Y << endl;
+//cerr << "output orientation_col_Z = " << dec << orientation_col_Z << endl;
+
+	// Replace the (already removed) attributes with new ones ...
+
+	aImagePositionPatient=new DecimalStringAttribute(TagFromName(ImagePositionPatient));
+	Assert(aImagePositionPatient);
+	aImagePositionPatient->addValue(position_X);
+	aImagePositionPatient->addValue(position_Y);
+	aImagePositionPatient->addValue(position_Z);
+	list+=aImagePositionPatient;
+
+	aImageOrientationPatient=new DecimalStringAttribute(TagFromName(ImageOrientationPatient));
+	Assert(aImageOrientationPatient);
+	aImageOrientationPatient->addValue(orientation_row_X);
+	aImageOrientationPatient->addValue(orientation_row_Y);
+	aImageOrientationPatient->addValue(orientation_row_Z);
+	aImageOrientationPatient->addValue(orientation_col_X);
+	aImageOrientationPatient->addValue(orientation_col_Y);
+	aImageOrientationPatient->addValue(orientation_col_Z);
+	list+=aImageOrientationPatient;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool success=true;
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	Float32 originX;
+	Float32 originY;
+	Float32 originZ;
+	if (!options.get("x",originX)) {
+		cerr << "Must specify -x origin of 1st slice" << endl;
+		success=false;
+	}
+	if (!options.get("y",originY)) {
+		cerr << "Must specify -y origin of 1st slice" << endl;
+		success=false;
+	}
+	if (!options.get("z",originZ)) {
+		cerr << "Must specify --z origin of 1st slice" << endl;
+		success=false;
+	}
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || !success) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -x nn.n -y nn.n -z nn.n"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		log << list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		// Don't write list warnings yet ...
+		// done in usualManagedAttributeListWrite ...
+
+		MakeImagePlaneModuleOrthogonalToXYZ(list,originX,originY,originZ);
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcortho.man b/appsrc/dcfile/dcortho.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcostosr.cc b/appsrc/dcfile/dcostosr.cc
new file mode 100644
index 0000000..09e54ba
--- /dev/null
+++ b/appsrc/dcfile/dcostosr.cc
@@ -0,0 +1,369 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcostosr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrval.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "sopclu.h"
+#include "elmconst.h"
+
+static void
+copyRelevantAttributes(ManagedAttributeList& list,ManagedAttributeList& newList,bool verbose,TextOutputStream& log) {
+
+
+	newList+= new ShortStringAttribute(TagFromName(StudyID),(char *)AttributeValue(list[TagFromName(StudyID)],""));
+	newList+= new LongStringAttribute(TagFromName(StudyDescription),(char *)AttributeValue(list[TagFromName(StudyDescription)],""));
+	newList+= new ShortStringAttribute(TagFromName(AccessionNumber),(char *)AttributeValue(list[TagFromName(AccessionNumber)],""));
+	newList+= new UIStringAttribute(TagFromName(StudyInstanceUID),(char *)AttributeValue(list[TagFromName(StudyInstanceUID)],""));
+	newList+= new PersonNameAttribute(TagFromName(PatientName),(char *)AttributeValue(list[TagFromName(PatientName)],""));
+	newList+= new LongStringAttribute(TagFromName(PatientID),(char *)AttributeValue(list[TagFromName(PatientID)],""));
+	newList+= new IntegerStringAttribute(TagFromName(SeriesNumber),(Uint32)AttributeValue(list[TagFromName(SeriesNumber)],1)+1000);
+	newList+= new IntegerStringAttribute(TagFromName(InstanceNumber),(Uint32)AttributeValue(list[TagFromName(InstanceNumber)],1));
+	newList+= new DateStringAttribute(TagFromName(PatientBirthDate),(char *)AttributeValue(list[TagFromName(PatientBirthDate)],""));
+	newList+= new CodeStringAttribute(TagFromName(PatientSex),(char *)AttributeValue(list[TagFromName(PatientSex)],""));
+	newList+= new DateStringAttribute(TagFromName(StudyDate),(char *)AttributeValue(list[TagFromName(StudyDate)],""));
+	newList+= new TimeStringAttribute(TagFromName(StudyTime),(char *)AttributeValue(list[TagFromName(StudyTime)],""));
+	newList+= new PersonNameAttribute(TagFromName(ReferringPhysicianName),(char *)AttributeValue(list[TagFromName(ReferringPhysicianName)],""));
+	newList+= new LongStringAttribute(TagFromName(Manufacturer),(char *)AttributeValue(list[TagFromName(Manufacturer)],""));
+	newList+= new DateStringAttribute(TagFromName(ContentDate),(char *)AttributeValue(list[TagFromName(ContentDate)],""));
+	newList+= new TimeStringAttribute(TagFromName(ContentTime),(char *)AttributeValue(list[TagFromName(ContentTime)],""));
+
+	// should copy these but lazy for now (since not likely in Osiris output):(
+
+	newList+= new SequenceAttribute(TagFromName(PerformedProcedureCodeSequence));
+	newList+= new SequenceAttribute(TagFromName(ReferencedPerformedProcedureStepSequence));
+}
+
+static Uint16 findGroupContainingOverlayID(AttributeList *list,Uint32 id) {
+	Uint16 g=0x6001;
+	Attribute *a;
+	while ((a=(*list)[Tag(g,0x1000)])) {
+		Uint32 vOverlayID;
+		a->getValue(0,vOverlayID);
+		if (id == vOverlayID) return g;
+		g+=0x0002;
+	}
+	return 0;
+}
+
+static Attribute *
+newSingleCodedSequenceAttribute(Tag tag,char *cv,char *csd,char *cm) {
+	SequenceAttribute *a = new SequenceAttribute(tag);
+	Assert(a);
+	AttributeList *list = new AttributeList();
+	Assert(list);
+	(*a)+=list;
+	(*list)+=new ShortStringAttribute(TagFromName(CodeValue),cv);
+	(*list)+=new ShortStringAttribute(TagFromName(CodingSchemeDesignator),csd);
+	(*list)+=new LongStringAttribute(TagFromName(CodeMeaning),cm);
+	return a;
+}
+
+static void
+addLesionItem(SequenceAttribute *aMeasurementsContentSequence,char *vROIType,char *vLabel,int nContourPoints,Float32 *vContourPoints,
+		const char *vReferencedSOPClassUID,const char *vReferencedSOPInstanceUID) {
+	Assert(aMeasurementsContentSequence);
+	AttributeList *list = new AttributeList();
+	Assert(list);
+	(*aMeasurementsContentSequence)+=list;
+	(*list)+=new CodeStringAttribute(TagFromName(ValueType),"TEXT");
+	(*list)+=new CodeStringAttribute(TagFromName(RelationshipType),"CONTAINS");
+	(*list)+=newSingleCodedSequenceAttribute(TagFromName(ConceptNameCodeSequence),"333301","99RADPHARM","Lesion");
+
+	// parse out label
+
+	char *nameFromLabel;
+	char *valueFromLabel;
+	char *unitsFromLabel;
+
+	int lLabel=strlen(vLabel);
+	char *equalsPosition = strrchr(vLabel,'=');
+	if (equalsPosition) {
+		int lNameFromLabel=equalsPosition-vLabel;
+		nameFromLabel=new char[lNameFromLabel];
+		strncpy(nameFromLabel,vLabel,equalsPosition-vLabel);
+
+		char *lastSpacePosition = strrchr(vLabel,' ');
+		if (lastSpacePosition && lastSpacePosition > equalsPosition) {
+			int lUnitsFromLabel=lLabel-(lastSpacePosition-vLabel);
+			unitsFromLabel=new char[lUnitsFromLabel];
+			strncpy(unitsFromLabel,lastSpacePosition+1,lUnitsFromLabel);
+		}
+		else {
+			unitsFromLabel=0;
+			lastSpacePosition=vLabel+lLabel-1;
+		}
+		int lValueFromLabel=lastSpacePosition-equalsPosition-1;
+		valueFromLabel=new char[lValueFromLabel];
+		strncpy(valueFromLabel,equalsPosition+1,lValueFromLabel);
+	}
+	else {
+		nameFromLabel=vLabel;
+		valueFromLabel=0;
+		unitsFromLabel=0;
+	}
+cerr << "nameFromLabel = <" << nameFromLabel << ">" << endl;
+cerr << "valueFromLabel = <" << valueFromLabel << ">" << endl;
+cerr << "unitsFromLabel = <" << unitsFromLabel << ">" << endl;
+
+	(*list)+=new UnlimitedTextAttribute(TagFromName(TextValue),nameFromLabel);
+
+	AttributeList *listToAddScoordTo;
+
+	if (valueFromLabel && unitsFromLabel) {
+		SequenceAttribute *aNumericContentSequence = new SequenceAttribute(TagFromName(ContentSequence));
+		(*list)+=aNumericContentSequence;
+		AttributeList *ncsl = new AttributeList();
+		Assert(ncsl);
+		(*aNumericContentSequence)+=ncsl;
+		listToAddScoordTo=ncsl;
+		(*ncsl)+=new CodeStringAttribute(TagFromName(ValueType),"NUM");
+		(*ncsl)+=new CodeStringAttribute(TagFromName(RelationshipType),"HAS PROPERTIES");
+		(*ncsl)+=newSingleCodedSequenceAttribute(TagFromName(ConceptNameCodeSequence),"121206","DCM","Distance");
+
+		SequenceAttribute *aMeasuredValueSequence = new SequenceAttribute(TagFromName(MeasuredValueSequence));
+		(*ncsl)+=aMeasuredValueSequence;
+		AttributeList *mvsl = new AttributeList();
+		Assert(mvsl);
+		(*aMeasuredValueSequence)+=mvsl;
+		(*mvsl)+=new DecimalStringAttribute(TagFromName(NumericValue),valueFromLabel);
+		(*mvsl)+=newSingleCodedSequenceAttribute(TagFromName(MeasurementUnitsCodeSequence),unitsFromLabel,"UCUM",unitsFromLabel);
+	}
+	else {
+		listToAddScoordTo=list;
+	}
+
+	Assert(listToAddScoordTo);
+	SequenceAttribute *aScoordContentSequence = new SequenceAttribute(TagFromName(ContentSequence));
+	(*listToAddScoordTo)+=aScoordContentSequence;
+	AttributeList *scol = new AttributeList();
+	Assert(scol);
+	(*aScoordContentSequence)+=scol;
+	(*scol)+=new CodeStringAttribute(TagFromName(ValueType),"SCOORD");
+	(*scol)+=new CodeStringAttribute(TagFromName(RelationshipType),"INFERRED FROM");
+	// no ConceptNameCodeSequence
+
+	if (vROIType) {
+		if (strcmp(vROIType,"CALLIPER") == 0) {
+			(*scol)+=new CodeStringAttribute(TagFromName(GraphicType),"POLYLINE");
+			Attribute *aGraphicData = new FloatSingleAttribute(TagFromName(GraphicData));
+			Assert(aGraphicData);
+			(*scol)+=aGraphicData;
+			if (nContourPoints >= 4 && vContourPoints) {
+				aGraphicData->addValue(vContourPoints[0]);
+				aGraphicData->addValue(vContourPoints[1]);
+				aGraphicData->addValue(vContourPoints[2]);
+				aGraphicData->addValue(vContourPoints[3]);
+			}
+		}
+		else if (strcmp(vROIType,"ELLIPSE") == 0) {
+			(*scol)+=new CodeStringAttribute(TagFromName(GraphicType),"ELLIPSE");
+			Attribute *aGraphicData = new FloatSingleAttribute(TagFromName(GraphicData));
+			Assert(aGraphicData);
+			(*scol)+=aGraphicData;
+			if (nContourPoints >= 4 && vContourPoints) {
+				aGraphicData->addValue(vContourPoints[0]);
+				aGraphicData->addValue(vContourPoints[1]);
+				aGraphicData->addValue(vContourPoints[2]);
+				aGraphicData->addValue(vContourPoints[3]);
+			}
+		}
+	}	
+
+
+	SequenceAttribute *aImageContentSequence = new SequenceAttribute(TagFromName(ContentSequence));
+	(*scol)+=aImageContentSequence;
+	AttributeList *imgl = new AttributeList();
+	Assert(imgl);
+	(*aImageContentSequence)+=imgl;
+	(*imgl)+=new CodeStringAttribute(TagFromName(ValueType),"IMAGE");
+	(*imgl)+=new CodeStringAttribute(TagFromName(RelationshipType),"SELECTED FROM");
+	// no ConceptNameCodeSequence
+
+	SequenceAttribute *aReferencedSOPSequence = new SequenceAttribute(TagFromName(ReferencedSOPSequence));
+	(*imgl)+=aReferencedSOPSequence;
+	AttributeList *rsopl = new AttributeList();
+	Assert(rsopl);
+	(*aReferencedSOPSequence)+=rsopl;
+	(*rsopl)+=new UIStringAttribute(TagFromName(ReferencedSOPClassUID),vReferencedSOPClassUID);
+	(*rsopl)+=new UIStringAttribute(TagFromName(ReferencedSOPInstanceUID),vReferencedSOPInstanceUID);
+
+}
+
+static void
+copyOverlayAttributesIntoContent(ManagedAttributeList& list,ManagedAttributeList& newList,bool verbose,TextOutputStream& log,const char *useuid) {
+	newList+= new SequenceAttribute(TagFromName(VerifyingObserverSequence));
+
+// goal is::
+// : CONTAINER: (333300,99RADPHARM,"Measurements")  [SEPARATE]
+//	>HAS OBS CONTEXT: PNAME: (121008,DCM,"Person 0bserver Name")  = "Smith^John^^Dr^"
+//      >CONTAINS: TEXT: (000444,LNdemo,"Lesion")  = "1"
+//               >>HAS PROPERTIES: NUM: (121206,DCM,"Distance")  = 130 (mm,UCUM,"mm")
+//                        >>>INFERRED FROM: SCOORD
+//                                >>>>SELECTED FROM: IMAGE:
+//      >CONTAINS: TEXT: (000444,LNdemo,"Lesion")  = "1"
+//                >>INFERRED FROM: SCOORD
+//                        >>>SELECTED FROM: IMAGE:
+
+
+	newList+=new CodeStringAttribute(TagFromName(ValueType),"CONTAINER");
+	newList+=new CodeStringAttribute(TagFromName(ContinuityOfContent),"SEPARATE");
+
+	SequenceAttribute *aContentSequence = new SequenceAttribute(TagFromName(ContentSequence));
+	newList+=aContentSequence;
+
+	newList+=newSingleCodedSequenceAttribute(TagFromName(ConceptNameCodeSequence),"333300","99RADPHARM","Measurements");
+
+	const char *vReferencedSOPClassUID = AttributeValue(list[TagFromName(SOPClassUID)]);
+	const char *vReferencedSOPInstanceUID = useuid ? useuid : AttributeValue(list[TagFromName(SOPInstanceUID)]);
+
+	Attribute *a = list[Tag(0x6001,0x10c0)];	// UIN Overlay Sequence
+	if (a && a->isSequence()) {
+		SequenceAttribute *aSeq=(SequenceAttribute *)a;
+		AttributeList **itemLists;
+		int nLists=aSeq->getLists(&itemLists);
+		if (nLists == 1) {
+			AttributeList *itemList = itemLists[0];
+cerr << "search groups" << endl;
+			Uint16 g=0x6001;
+			while ((*itemList)[Tag(g,0x0010)]) {
+cerr << "group =0x" << hex << g << dec << endl;
+				Uint32 vOverlayID = AttributeValue((*itemList)[Tag(g,0x1000)]);
+cerr << "Overlay ID = " << vOverlayID << endl;
+				char *vROIType = AttributeValue((*itemList)[Tag(g,0x10B0)],"");
+cerr << "ROI Type = " << vROIType << endl;
+				// this mess is because it is an LT not an IS (unlike OverlayID) ...
+				char *sAttachedAnnotation = AttributeValue((*itemList)[Tag(g,0x10B2)]);
+				Uint32 vAttachedAnnotation = sAttachedAnnotation ?(Uint32)atof(sAttachedAnnotation) : 0;
+cerr << "Attached Annotation = " << vAttachedAnnotation << endl;
+				Uint16 groupOfAttachedAnnotation = vAttachedAnnotation ? findGroupContainingOverlayID(itemList,vAttachedAnnotation) : 0;
+cerr << "Attached Annotation group =0x" << hex << groupOfAttachedAnnotation << dec << endl;
+
+				Attribute *aContourPoints = (*itemList)[Tag(g,0x10BA)];
+				if (vROIType && strcmp(vROIType,"ANNOTATION") != 0 && groupOfAttachedAnnotation && aContourPoints) {
+					char *vLabel = AttributeValue((*itemList)[Tag(groupOfAttachedAnnotation,0x10A0)],"");
+cerr << "Label = " << vLabel << endl;
+					int nContourPoints = aContourPoints->getVM();
+					Float32 vContourPoints[nContourPoints];
+					int i;
+					for (i=0; i<nContourPoints; ++i) {
+						aContourPoints->getValue(i,*(vContourPoints+i));
+cerr << "Contour point[" << i << "] = " << vContourPoints[i] << endl;
+					}
+
+					addLesionItem(aContentSequence,vROIType,vLabel,nContourPoints,vContourPoints,
+						vReferencedSOPClassUID,vReferencedSOPInstanceUID);
+				}
+
+				g+=0x0002;
+			}
+		}
+	}
+}
+
+static void
+addDeNovoAttributes(ManagedAttributeList& newList,bool verbose,TextOutputStream& log) {
+	newList+=new UIStringAttribute(TagFromName(SOPClassUID),EnhancedSRStorageSOPClassUID);
+	newList+=new CodeStringAttribute(TagFromName(Modality),"SR");
+	newList+=new CodeStringAttribute(TagFromName(CompletionFlag),"COMPLETE");
+	newList+=new CodeStringAttribute(TagFromName(VerificationFlag),"UNVERIFIED");
+}
+
+static void
+addNewSeriesAndInstanceUIDs(ManagedAttributeList& list,bool verbose,TextOutputStream& log) {
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+
+	const char *useSOPInstanceUID=0;
+	options.get("useuid",useSOPInstanceUID);
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-useuid SOPInstanceUID]"
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+
+	if (success) {
+		ManagedAttributeList newList;
+
+		copyRelevantAttributes(list,newList,verbose,log);
+		copyOverlayAttributesIntoContent(list,newList,verbose,log,useSOPInstanceUID);
+		addDeNovoAttributes(newList,verbose,log);
+		addNewSeriesAndInstanceUIDs(newList,verbose,log);
+
+		if (!usualManagedAttributeListWrite(newList,dout,
+			dicom_output_options,log,verbose)) success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
+
+
+
+
+
diff --git a/appsrc/dcfile/dcostosr.man b/appsrc/dcfile/dcostosr.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcpatmpl.man b/appsrc/dcfile/dcpatmpl.man
new file mode 100644
index 0000000..2b92d6e
--- /dev/null
+++ b/appsrc/dcfile/dcpatmpl.man
@@ -0,0 +1,32 @@
+.TH dcpatmpl 1 "10 November 2007" "DICOM PS3" "Apply patient and study template"
+.SH NAME
+dcpatmpl \- ACR/NEMA DICOM PS3 ... Apply patient and study template
+.SH SYNOPSIS
+.HP 10
+.B dcpatmpl
+.B templatefile srcdir dstdir
+.SH DESCRIPTION
+.LP
+.B dcpatmpl
+reads a single DICOM file as a template, extracts from it the patient and study module attributes,
+and applies them to the DICOM files found in the source directory, copying them to the
+destination directory.
+.LP
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
diff --git a/appsrc/dcfile/dcpatmpl.script b/appsrc/dcfile/dcpatmpl.script
new file mode 100755
index 0000000..ee7354f
--- /dev/null
+++ b/appsrc/dcfile/dcpatmpl.script
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# usage: dcpatmpl templatefile srcdir dstdir
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+COMMANDFILE="${TMPROOT}_command.sh"
+
+DCCP=dccp
+
+usage() {
+	echo 1>&2 "Usage: $1 templatefile srcdir dstdir"
+}
+
+if [ $# = 3 ]
+then
+	if [ -f "$1" -a -d "$2" ]
+	then
+		templatefile="$1"
+		srcdir="$2"
+		dstdir="$3"
+		echo > "${COMMANDFILE}" "#!/bin/sh"
+		echo >>"${COMMANDFILE}" 'echo "Copy $1 to $2/$$"'
+		echo >>"${COMMANDFILE}" "${DCCP} -nodisclaimer \\"
+		echo >>"${COMMANDFILE}" '$1 \'
+		echo >>"${COMMANDFILE}" '$2/$$ \'
+		dciodvfy -describe "${templatefile}" 2>&1 \
+			| egrep '(Module [<][A-Za-z0-9]*[>]$)|([(]0x[0-9a-fA-F]*,0x[0-9a-fA-F]*[)])' \
+			| sed -e '1,/Module <Patient>/d' -e '/Module <GeneralSeries>/,$d' \
+			| egrep -v '(Module [<][A-Za-z0-9]*[>]$)' \
+			| sed -e 's/^[^(]*\([(]0x[0-9a-fA-F]*,0x[0-9a-fA-F]*[)]\).*<\([^>]*\)>[ ]*$/-r "\1" "\2"/' -e 's/""$/" "/' -e 's/"-/" -/' -e 's/$/ \\/' \
+			>> "${COMMANDFILE}"
+		echo >>"${COMMANDFILE}" ""
+		chmod +x "${COMMANDFILE}"
+		#cat "${COMMANDFILE}"
+		
+		mkdir -p "${dstdir}"
+		find "${srcdir}" -type f -exec "${COMMANDFILE}" '{}' "${dstdir}" ';'
+		
+		rm "${COMMANDFILE}"
+	else
+		usage `basename $0`
+		exit 1
+	fi
+else
+	usage `basename $0`
+	exit 1
+fi
+
+exit 0
diff --git a/appsrc/dcfile/dcposn.cc b/appsrc/dcfile/dcposn.cc
new file mode 100644
index 0000000..125ffc5
--- /dev/null
+++ b/appsrc/dcfile/dcposn.cc
@@ -0,0 +1,92 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcposn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+#include "pixposn.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool showfilename=options.get("filename");
+
+	bool bad=false;
+	unsigned row,col;
+
+	bad|=!(options.get("row",row) || options.get("y",row));
+	bad|=!(options.get("col",col) || options.get("x",col));
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-filename]"
+			<< " -[col|x] n -[row|y] n"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		return 1;
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	PositionOfPixel positioner(list,log,true);
+	Float64 patientX,patientY,patientZ;
+	if (positioner.getPosition(row,col,patientX,patientY,patientZ)) {
+		cout << dec
+		     << "\tRow=" << row
+		     << "\tCol=" << col
+		     << setiosflags(ios::fixed|ios::showpoint)
+		     << "\tX=" <<  setprecision(1) << patientX
+		     << "\tY=" <<  setprecision(1) << patientY
+		     << "\tZ=" <<  setprecision(1) << patientZ
+		     << endl;
+	}
+	else {
+		// errors already logged
+		success=false;
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcposn.man b/appsrc/dcfile/dcposn.man
new file mode 100755
index 0000000..2fbe68c
--- /dev/null
+++ b/appsrc/dcfile/dcposn.man
@@ -0,0 +1,73 @@
+.TH DCPOSN 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM locate position"
+.SH NAME
+dcposn \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM locate position
+.SH SYNOPSIS
+.HP 10
+.B dcposn
+.so man1/gen.so
+[
+.B \-col|x n
+]
+[
+.B \-row|y n
+]
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcposn
+reads the named dicom input file and locates the requested image
+pixel position in 3D space using the attributes of the Image Plane module
+(Image Position Patient and Image Orientation Patient) if present.
+.LP
+The spatial position is described as patient (not gantry) relative
+x, y and z co-ordinates, where x is +ve leftwards,
+y is +ve anteriorly and
+z is +ve cranially.
+.SH OPTIONS
+The co-ordinates and verbose output go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-col|x n \-row|y n
+.RS
+The specified image pixel position begins from 0 in the top left hand
+corner of the image.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+%dcposn -x 0 -y 0 expmeta.dc3
+.RE
+Row=0 Col=0   X=45.0 Y=-119.5 Z=119.5
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+This program really only exists for automated testing of the image plane
+module.
diff --git a/appsrc/dcfile/dcpost.cc b/appsrc/dcfile/dcpost.cc
new file mode 100644
index 0000000..6d7e514
--- /dev/null
+++ b/appsrc/dcfile/dcpost.cc
@@ -0,0 +1,647 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcpost.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static Attribute *
+isValuePresentElseAbort(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << AMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		exit(1);
+	}
+}
+
+static void
+rotate( double dst_row_dircos_x,double dst_row_dircos_y,double dst_row_dircos_z,
+	double dst_col_dircos_x,double dst_col_dircos_y,double dst_col_dircos_z,
+	double dst_nrm_dircos_x,double dst_nrm_dircos_y,double dst_nrm_dircos_z,
+	double  src_pos_x,double  src_pos_y,double  src_pos_z,
+	double &dst_pos_x,double &dst_pos_y,double &dst_pos_z)
+{
+	dst_pos_x = dst_row_dircos_x * src_pos_x
+		  + dst_row_dircos_y * src_pos_y
+		  + dst_row_dircos_z * src_pos_z;
+
+	dst_pos_y = dst_col_dircos_x * src_pos_x
+		  + dst_col_dircos_y * src_pos_y
+		  + dst_col_dircos_z * src_pos_z;
+
+	dst_pos_z = dst_nrm_dircos_x * src_pos_x
+		  + dst_nrm_dircos_y * src_pos_y
+		  + dst_nrm_dircos_z * src_pos_z;
+}
+
+static bool
+getPositionOrientationSpacingAndSize(AttributeList &list,const char *filename,TextOutputStream &log,bool verbose,
+	double &row_dircos_x,double &row_dircos_y,double &row_dircos_z,
+	double &col_dircos_x,double &col_dircos_y,double &col_dircos_z,
+	double &nrm_dircos_x,double &nrm_dircos_y,double &nrm_dircos_z,
+	double &pos_x,double &pos_y,double &pos_z,
+	unsigned long &rows,unsigned long &cols,
+	double &row_spacing,double &col_spacing,
+	double &row_length,double &col_length)
+{
+
+	// the localizer is the "destination" for the posting operation
+
+	Attribute *aImageOrientationPatient = isValuePresentElseAbort(list,
+		TagFromName(ImageOrientationPatient),"ImageOrientationPatient",filename,log);
+
+	if (aImageOrientationPatient->getVM() != 6) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValueMultiplicity)
+		    << " - ImageOrientationPatient"
+		    << endl;
+		return false;
+	}
+
+	if (!aImageOrientationPatient->getValue(0,row_dircos_x)
+	 || !aImageOrientationPatient->getValue(1,row_dircos_y)
+	 || !aImageOrientationPatient->getValue(2,row_dircos_z)
+	 || !aImageOrientationPatient->getValue(3,col_dircos_x)
+	 || !aImageOrientationPatient->getValue(4,col_dircos_y)
+	 || !aImageOrientationPatient->getValue(5,col_dircos_z)
+	) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValue)
+		    << " - ImageOrientationPatient"
+		    << endl;
+		return false;
+	}
+
+//cerr << "row_dircos_x = " << row_dircos_x << endl;
+//cerr << "row_dircos_y = " << row_dircos_y << endl;
+//cerr << "row_dircos_z = " << row_dircos_z << endl;
+
+//cerr << "col_dircos_x = " << col_dircos_x << endl;
+//cerr << "col_dircos_y = " << col_dircos_y << endl;
+//cerr << "col_dircos_z = " << col_dircos_z << endl;
+
+	// compute nrm to row and col (i.e. cross product of row and col unit vectors)
+
+	nrm_dircos_x = row_dircos_y * col_dircos_z - row_dircos_z * col_dircos_y;
+	nrm_dircos_y = row_dircos_z * col_dircos_x - row_dircos_x * col_dircos_z;
+	nrm_dircos_z = row_dircos_x * col_dircos_y - row_dircos_y * col_dircos_x;
+
+//cerr << "nrm_dircos_x = " << nrm_dircos_x << endl;
+//cerr << "nrm_dircos_y = " << nrm_dircos_y << endl;
+//cerr << "nrm_dircos_z = " << nrm_dircos_z << endl;
+
+	// check are unit vectors ...
+
+	if (!(fabs(row_dircos_x*row_dircos_x+row_dircos_y*row_dircos_y+row_dircos_z*row_dircos_z - 1.0) < 0.000001)
+	 || !(fabs(col_dircos_x*col_dircos_x+col_dircos_y*col_dircos_y+col_dircos_z*col_dircos_z - 1.0) < 0.000001)
+	 || !(fabs(nrm_dircos_x*nrm_dircos_x+nrm_dircos_y*nrm_dircos_y+nrm_dircos_z*nrm_dircos_z - 1.0) < 0.000001)
+	) {
+		log << filename << ": "
+		    << "Abort - row, column or normal are not unit vectors"
+		    << " - ImageOrientationPatient"
+		    << endl;
+		return false;
+	}
+
+	// check are orthogonal (dot product is zero, i.e. cos 90)
+
+	if (!(fabs(row_dircos_x*col_dircos_x+row_dircos_y*col_dircos_y+row_dircos_z*col_dircos_z) < 0.000001)
+	 || !(fabs(row_dircos_x*nrm_dircos_x+row_dircos_y*nrm_dircos_y+row_dircos_z*nrm_dircos_z) < 0.000001)
+	 || !(fabs(col_dircos_x*nrm_dircos_x+col_dircos_y*nrm_dircos_y+col_dircos_z*nrm_dircos_z) < 0.000001)
+	) {
+		log << filename << ": "
+		    << "Abort - row, column and normal are not orthogonal"
+		    << " - ImageOrientationPatient"
+		    << endl;
+		return false;
+	}
+
+	Attribute *aImagePositionPatient = isValuePresentElseAbort(list,
+		TagFromName(ImagePositionPatient),"ImagePositionPatient",filename,log);
+
+	if (aImagePositionPatient->getVM() != 3) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValueMultiplicity)
+		    << " - ImagePositionPatient"
+		    << endl;
+		return false;
+	}
+
+	if (!aImagePositionPatient->getValue(0,pos_x)
+	 || !aImagePositionPatient->getValue(1,pos_y)
+	 || !aImagePositionPatient->getValue(2,pos_z)
+	) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValue)
+		    << " - ImagePositionPatient"
+		    << endl;
+		return false;
+	}
+
+//cerr << "pos_x = " << pos_x << endl;
+//cerr << "pos_y = " << pos_y << endl;
+//cerr << "pos_z = " << pos_z << endl;
+
+	Attribute *aPixelSpacing = isValuePresentElseAbort(list,
+		TagFromName(PixelSpacing),"PixelSpacing",filename,log);
+
+	if (aPixelSpacing->getVM() != 2) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValueMultiplicity)
+		    << " - PixelSpacing"
+		    << endl;
+		return false;
+	}
+
+	if (!aPixelSpacing->getValue(0,row_spacing)
+	 || !aPixelSpacing->getValue(1,col_spacing)
+	) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValue)
+		    << " - PixelSpacing"
+		    << endl;
+		return false;
+	}
+
+//cerr << "row_spacing = " << row_spacing << endl;
+//cerr << "col_spacing = " << col_spacing << endl;
+
+	Attribute *aRows = isValuePresentElseAbort(list,
+		TagFromName(Rows),"Rows",filename,log);
+
+	if (aRows->getVM() != 1) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValueMultiplicity)
+		    << " - Rows"
+		    << endl;
+		return false;
+	}
+
+	if (!aRows->getValue(0,rows)) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValue)
+		    << " - Rows"
+		    << endl;
+		return false;
+	}
+
+//cerr << "rows = " << rows << endl;
+
+	Attribute *aColumns = isValuePresentElseAbort(list,
+		TagFromName(Columns),"Columns",filename,log);
+
+	if (aColumns->getVM() != 1) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValueMultiplicity)
+		    << " - Columns"
+		    << endl;
+		return false;
+	}
+
+	if (!aColumns->getValue(0,cols)) {
+		log << filename << ": "
+		    << AMsgDC(BadAttributeValue)
+		    << " - Columns"
+		    << endl;
+		return false;
+	}
+
+//cerr << "cols = " << cols << endl;
+
+	row_length=cols*row_spacing;
+	col_length=rows*col_spacing;
+
+//cerr << "row_length = " << row_length << endl;
+//cerr << "col_length = " << col_length << endl;
+
+	return true;
+}
+
+static inline void
+drawPixel(Uint16 *graphics_buffer,unsigned long graphics_buffer_rows,unsigned long graphics_buffer_cols,
+	int row_pixel,int col_pixel)
+{
+//cerr << "drawPixel: row=" << row_pixel << " col=" << col_pixel << endl;
+	if (row_pixel >= 1 && row_pixel <= graphics_buffer_rows
+	 && col_pixel >= 1 && col_pixel <= graphics_buffer_cols) {
+		unsigned long which_bit=(row_pixel-1)*graphics_buffer_cols+(col_pixel-1);
+		graphics_buffer[which_bit/16] |= Uint16(1)<<(which_bit%16);
+//cerr << "drawPixel: which_bit=" << which_bit << " %16=" << (which_bit%16) << " word=" << (which_bit/16) << endl;
+	}
+	else {
+//cerr << "clipped" << endl;
+	}
+}
+
+static void
+drawLine(Uint16 *graphics_buffer,unsigned long graphics_buffer_rows,unsigned long graphics_buffer_cols,
+	int from_row_pixel,int from_col_pixel,int to_row_pixel,int to_col_pixel)
+{
+	// start and end pixels are not yet clipped to boundaries
+	// pixels are DICOM style ... TLHC is 1,1, BRHC is cols,rows
+
+	if (abs(to_col_pixel-from_col_pixel) > abs(to_row_pixel-from_row_pixel)) {
+		// integer increment along column axis
+//cerr << "doing integer increment along column axis" << endl;
+		if (from_col_pixel > to_col_pixel) {
+			// swap drawing direction to keep column increment positive
+//cerr << "swap drawing direction to keep column increment positive" << endl;
+			int tmp;
+			tmp=from_col_pixel; from_col_pixel=to_col_pixel; to_col_pixel=tmp;
+			tmp=from_row_pixel; from_row_pixel=to_row_pixel; to_row_pixel=tmp;
+		}
+		double drow=to_row_pixel-from_row_pixel;
+		double dcol=to_col_pixel-from_col_pixel;
+//cerr << "drow = " << drow << endl;
+//cerr << "dcol = " << dcol << endl;
+
+		Assert(fabs(dcol) > 0.00001);
+		double slope=drow/dcol;
+//cerr << "slope drow/dcol = " << slope << endl;
+		Assert(-1.0 <= slope && slope <= 1.0);		// otherwise would be doing rows
+		int col;
+		double row=from_row_pixel+0.5;	// the 0.5 is a constant throughout for the rounding operation
+		for (col=from_col_pixel; col <= to_col_pixel; ++col) {
+			drawPixel(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,int(row),col);
+			row+=slope;
+		}
+	}
+	else if (to_row_pixel != from_row_pixel) {
+		// integer increment along row axis
+//cerr << "doing integer increment along row axis" << endl;
+		if (from_row_pixel > to_row_pixel) {
+			// swap drawing direction to keep row increment positive
+//cerr << "swap drawing direction to keep row increment positive" << endl;
+			int tmp;
+			tmp=from_col_pixel; from_col_pixel=to_col_pixel; to_col_pixel=tmp;
+			tmp=from_row_pixel; from_row_pixel=to_row_pixel; to_row_pixel=tmp;
+		}
+		double drow=to_row_pixel-from_row_pixel;
+		double dcol=to_col_pixel-from_col_pixel;
+//cerr << "drow = " << drow << endl;
+//cerr << "dcol = " << dcol << endl;
+
+		Assert(fabs(drow) > 0.00001);
+		double slope=dcol/drow;
+//cerr << "slope dcol/drow = " << slope << endl;
+		int row;
+		double col=from_col_pixel+0.5;	// the 0.5 is a constant throughout for the rounding operation
+		for (row=from_row_pixel; row <= to_row_pixel; ++row) {
+			drawPixel(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,row,int(col));
+			col+=slope;
+		}
+	}
+	else {
+		// to_col_pixel == from_col_pixel && to_row_pixel == from_row_pixel
+//cerr << "just draw a point" << endl;
+		drawPixel(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,to_row_pixel,to_col_pixel);
+	}
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool veryveryverbose=options.get("veryveryverbose") || options.get("vvv");
+	if (veryveryverbose) veryverbose=true;
+	if (veryverbose) verbose=true;
+
+	const char *localizer_filename;
+	if (!options.get("localizer",localizer_filename)) {
+		cerr << "Must specify a localizer image" << endl;
+		bad=true;
+	}
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	int numberofinputfiles=!options;
+
+	const char **filenamestable = new const char *[numberofinputfiles];
+	Assert(filenamestable);
+	const char **ptr;
+	for (ptr=filenamestable; !options && (*ptr++=options()); ++options);
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose|-vvv|-veryveryverbose]"
+			<< " [-localizer filename]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	// Open the localizer image ...
+
+	if (veryverbose) log << "Reading \"" << localizer_filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+	ifstream *fstr=new ifstream(localizer_filename,ios::in|ios::binary);
+#else
+	ifstream *fstr=new ifstream(localizer_filename);
+#endif
+	if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+		log << AMsgDC(FileReadOpenFailed);
+		if (localizer_filename) log <<" - \"" << localizer_filename << "\"";
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)fstr,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList localizer_list;
+		
+	if (veryverbose) log << "******** While reading ... " << localizer_filename << " ... ********" << endl; 
+	localizer_list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+	if (!localizer_list.good()) {
+		log << localizer_list.errors()
+			<< EMsgDC(DatasetReadFailed) << endl;
+		exit(1);
+	}
+
+	double dst_row_dircos_x;
+	double dst_row_dircos_y;
+	double dst_row_dircos_z;
+	double dst_col_dircos_x;
+	double dst_col_dircos_y;
+	double dst_col_dircos_z;
+	double dst_nrm_dircos_x;
+	double dst_nrm_dircos_y;
+	double dst_nrm_dircos_z;
+	double dst_pos_x;
+	double dst_pos_y;
+	double dst_pos_z;
+	double dst_row_spacing;
+	double dst_col_spacing;
+	double dst_row_length;
+	double dst_col_length;
+	unsigned long dst_rows;
+	unsigned long dst_cols;
+
+	if (!getPositionOrientationSpacingAndSize(localizer_list,localizer_filename,log,verbose,
+		dst_row_dircos_x,dst_row_dircos_y,dst_row_dircos_z,
+		dst_col_dircos_x,dst_col_dircos_y,dst_col_dircos_z,
+		dst_nrm_dircos_x,dst_nrm_dircos_y,dst_nrm_dircos_z,
+		dst_pos_x,dst_pos_y,dst_pos_z,
+		dst_rows,dst_cols,
+		dst_row_spacing,dst_col_spacing,
+		dst_row_length,dst_col_length)
+	) exit(1);
+
+	unsigned long graphics_buffer_rows=dst_rows;
+	unsigned long graphics_buffer_cols=dst_cols;
+	unsigned long graphics_buffer_size=(graphics_buffer_rows*graphics_buffer_cols-1)/16+1;
+	Uint16 *graphics_buffer=new Uint16[graphics_buffer_size];
+	Assert(graphics_buffer);
+	{ unsigned long i; Uint16 *ptr; for (i=0,ptr=graphics_buffer; i<graphics_buffer_size; ++i) *ptr++=0; }
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		const char *filename=filenamestable[i];
+		Assert(filename);
+		if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			log << AMsgDC(FileReadOpenFailed);
+			if (filename) log <<" - \"" << filename << "\"";
+			exit(1);
+		}
+
+		DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+		
+		if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+		list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+		if (!list.good()) {
+			log << list.errors()
+				<< EMsgDC(DatasetReadFailed) << endl;
+			exit(1);
+		}
+
+		double src_row_dircos_x;
+		double src_row_dircos_y;
+		double src_row_dircos_z;
+		double src_col_dircos_x;
+		double src_col_dircos_y;
+		double src_col_dircos_z;
+		double src_nrm_dircos_x;
+		double src_nrm_dircos_y;
+		double src_nrm_dircos_z;
+		double src_pos_x;
+		double src_pos_y;
+		double src_pos_z;
+		double src_row_spacing;
+		double src_col_spacing;
+		double src_row_length;
+		double src_col_length;
+		unsigned long src_rows;
+		unsigned long src_cols;
+
+
+		if (!getPositionOrientationSpacingAndSize(list,filename,log,verbose,
+			src_row_dircos_x,src_row_dircos_y,src_row_dircos_z,
+			src_col_dircos_x,src_col_dircos_y,src_col_dircos_z,
+			src_nrm_dircos_x,src_nrm_dircos_y,src_nrm_dircos_z,
+			src_pos_x,src_pos_y,src_pos_z,
+			src_rows,src_cols,
+			src_row_spacing,src_col_spacing,
+			src_row_length,src_col_length)
+		) exit(1);
+
+		// Build a square to project with 4 corners TLHC, TRHC, BRHC, BLHC ...
+
+		double pos_x[4];
+		double pos_y[4];
+		double pos_z[4];
+
+		// TLHC is what is in ImagePositionPatient
+
+		pos_x[0]=src_pos_x;
+		pos_y[0]=src_pos_y;
+		pos_z[0]=src_pos_z;
+
+		// TRHC
+
+		pos_x[1]=src_pos_x + src_row_dircos_x*(src_row_length-1);
+		pos_y[1]=src_pos_y + src_row_dircos_y*(src_row_length-1);
+		pos_z[1]=src_pos_z + src_row_dircos_z*(src_row_length-1);
+
+		// BRHC
+
+		pos_x[2]=src_pos_x + src_row_dircos_x*(src_row_length-1) + src_col_dircos_x*(src_col_length-1);
+		pos_y[2]=src_pos_y + src_row_dircos_y*(src_row_length-1) + src_col_dircos_y*(src_col_length-1);
+		pos_z[2]=src_pos_z + src_row_dircos_z*(src_row_length-1) + src_col_dircos_z*(src_col_length-1);
+
+		// BLHC
+
+		pos_x[3]=src_pos_x + src_col_dircos_x*(src_col_length-1);
+		pos_y[3]=src_pos_y + src_col_dircos_y*(src_col_length-1);
+		pos_z[3]=src_pos_z + src_col_dircos_z*(src_col_length-1);
+
+		int row_pixel[4];
+		int col_pixel[4];
+
+		int i;
+		for (i=0; i<4; ++i) {
+
+			// we want to view the source slice from the "point of view" of
+			// the target localizer, i.e. a parallel projection of the source
+			// onto the target
+
+			// do this by imagining that the target localizer is a view port
+			// into a relocated and rotated co-ordinate space, where the
+			// viewport has a row vector of +X, col vector of +Y and normal +Z,
+			// then the X and Y values of the projected target correspond to
+			// col and row offsets in mm from the TLHC of the localizer image !
+
+			// move everything to origin of target
+
+//cerr << "original pos_x = " << pos_x[i] << endl;
+//cerr << "original pos_y = " << pos_y[i] << endl;
+//cerr << "original pos_z = " << pos_z[i] << endl;
+
+			pos_x[i] -= dst_pos_x;
+			pos_y[i] -= dst_pos_y;
+			pos_z[i] -= dst_pos_z;
+
+//cerr << "reoriginate src_pos_x = " << pos_x[i] << endl;
+//cerr << "reoriginate src_pos_y = " << pos_y[i] << endl;
+//cerr << "reoriginate src_pos_z = " << pos_z[i] << endl;
+
+			// The rotation is easy ... just rotate by the row, col and normal
+			// vectors ...
+
+			rotate( dst_row_dircos_x,dst_row_dircos_y,dst_row_dircos_z,
+				dst_col_dircos_x,dst_col_dircos_y,dst_col_dircos_z,
+				dst_nrm_dircos_x,dst_nrm_dircos_y,dst_nrm_dircos_z,
+				pos_x[i],pos_y[i],pos_z[i],
+				pos_x[i],pos_y[i],pos_z[i]);
+
+//cerr << "\t\t After rotate, pos_x = " << pos_x[i] << endl;
+//cerr << "\t\t After rotate, pos_y = " << pos_y[i] << endl;
+//cerr << "\t\t After rotate, pos_z = " << pos_z[i] << endl;
+
+			// DICOM coordinates are center of pixel 1\1
+
+			col_pixel[i] = int(pos_x[i]/dst_col_spacing + 0.5);
+			row_pixel[i] = int(pos_y[i]/dst_row_spacing + 0.5);
+
+//cerr << "Col offset = " << pos_x[i] << " (mm)\t " << col_pixel[i] << " (pixels)" << endl;
+//cerr << "Row offset = " << pos_y[i] << " (mm)\t " << row_pixel[i] << " (pixels)" << endl;
+		}
+
+		// draw the trapezoid (will repeatedly draw the same line if orthogonal) ...
+
+		drawLine(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,
+			row_pixel[0],col_pixel[0],row_pixel[1],col_pixel[1]);
+		drawLine(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,
+			row_pixel[1],col_pixel[1],row_pixel[2],col_pixel[2]);
+		drawLine(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,
+			row_pixel[2],col_pixel[2],row_pixel[3],col_pixel[3]);
+		drawLine(graphics_buffer,graphics_buffer_rows,graphics_buffer_cols,
+			row_pixel[3],col_pixel[3],row_pixel[0],col_pixel[0]);
+	}
+
+	unsigned u=0x0000;	// Use Overlay Group 0x6000 ...
+
+	localizer_list+=new UnsignedShortAttribute(Tag(OverlayRows_GROUP+u,OverlayRows_ELEMENT),graphics_buffer_rows);
+	localizer_list+=new UnsignedShortAttribute(Tag(OverlayColumns_GROUP+u,OverlayColumns_ELEMENT),graphics_buffer_cols);
+	localizer_list+=new CodeStringAttribute(Tag(OverlayType_GROUP+u,OverlayType_ELEMENT),"G");
+	localizer_list+=new UnsignedShortAttribute(Tag(OverlayBitsAllocated_GROUP+u,OverlayBitsAllocated_ELEMENT),1);
+	localizer_list+=new UnsignedShortAttribute(Tag(OverlayBitPosition_GROUP+u,OverlayBitPosition_ELEMENT),0);
+
+	SignedShortAttribute *aOverlayOrigin = new SignedShortAttribute(Tag(OverlayOrigin_GROUP+u,OverlayOrigin_ELEMENT));
+	Assert(aOverlayOrigin);
+	aOverlayOrigin->addValue(Int16(1));
+	aOverlayOrigin->addValue(Int16(1));
+	localizer_list+=aOverlayOrigin;
+
+	OtherWordSmallNonPixelAttribute *aOverlayData =
+		new OtherWordSmallNonPixelAttribute(Tag(OverlayData_GROUP+u,OverlayData_ELEMENT));
+	Assert(aOverlayData);
+	aOverlayData->setValue(graphics_buffer,graphics_buffer_size);
+	localizer_list+=aOverlayData;
+
+	if (!usualManagedAttributeListWrite(localizer_list,dout,
+		dicom_output_options,log,veryverbose)) success=false;
+
+	//if (numberofinputfiles && filenamestable) delete[] filenamestable;
+	//if (localizer_din) delete localizer_din;
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcpost.man b/appsrc/dcfile/dcpost.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcproj.cc b/appsrc/dcfile/dcproj.cc
new file mode 100644
index 0000000..5eb38ae
--- /dev/null
+++ b/appsrc/dcfile/dcproj.cc
@@ -0,0 +1,590 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcproj.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+#include "transyn.h"
+
+#ifndef __Header_MemSrc__
+#define __Header_MemSrc__
+
+#include "srcsink.h"
+
+class Memory_PixelDataSource : public SourceBase<Uint16> {
+protected:
+	signed rows;
+	Uint16 columns;
+
+	signed row;
+	Uint16 *buffer;
+	Uint16 *bufptr;
+public:
+	Memory_PixelDataSource(Uint16 *srcbuffer,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			buffer=srcbuffer;	// reference not copy
+			Assert(buffer);
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+			bufptr=buffer-columns;	// position BEFORE buffer, since 1st "read" increments it
+			row=-1;
+		}
+
+	~Memory_PixelDataSource()
+		{
+			// don't delete buffer ... responsibility of caller of constructor
+		}
+
+	size_t read(void)
+		{
+			bufptr+=columns;
+			++row;
+			return columns;
+		}
+
+	const Uint16 *getBuffer(void)
+		{
+			Assert (bufptr >= buffer);	// Just in case someone calls getBuffer() without read()
+//cerr << "Memory_PixelDataSource::getBuffer: row = " << dec << row << endl;
+			return bufptr;
+		}
+
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return row < rows; }
+};
+
+
+#endif // __Header_MemSrc__
+
+enum ProjectionType { MIP = 1, SUM, FUZZY };
+
+class ImageFromProjectedFrames {
+private:
+	Uint16 *projectedfulldepthimage;
+
+	Memory_PixelDataSource *resultsource;
+
+	SupplySource *supplysource;
+
+	Uint16 columns;
+	Uint16 rows;
+	Uint16 frames;
+	Uint16 bitsallocated;
+	Uint16 bitsstored;
+	Uint16 highbit;
+	bool   issigned;
+
+	ProjectionType projectiontype;
+
+	class SourceBase<Uint16> *getSourceSource(void)
+		{
+			Assert(supplysource);
+			return supplysource->getSource();
+		}
+
+
+public:
+	ImageFromProjectedFrames(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		Uint16 vPixelRepresentation,
+		ProjectionType t)
+		{
+			projectedfulldepthimage=0;
+			resultsource=0;
+
+			supplysource=s;
+			columns=vColumns;
+			rows=vRows;
+			frames=vNumberOfFrames;
+			bitsallocated=vBitsAllocated;
+			bitsstored=vBitsStored;
+			highbit=vHighBit;
+			issigned=vPixelRepresentation;
+
+			projectiontype=t;
+
+			Assert(supplysource);
+			Assert(columns);
+			Assert(rows);
+			Assert(frames);
+			Assert(bitsallocated);
+			Assert(bitsstored);
+			Assert(highbit);
+		}
+
+	~ImageFromProjectedFrames()
+		{
+			if (projectedfulldepthimage) delete[] projectedfulldepthimage;
+			if (resultsource) delete resultsource;
+		}
+
+	bool createProjectedFullDepthImageFromSourceFrames(void);
+
+	class SourceBase<Uint16> *getResultSource(void)
+		{
+			if (!resultsource) {
+				Assert(projectedfulldepthimage);
+				resultsource=new Memory_PixelDataSource(projectedfulldepthimage,rows,columns);
+			}
+			Assert(resultsource);
+			return resultsource;
+		}
+};
+
+bool
+ImageFromProjectedFrames::createProjectedFullDepthImageFromSourceFrames(void)
+{
+cerr << "ImageFromProjectedFrames::createProjectedFullDepthImageFromSourceFrames start" << endl;
+
+	Assert(!projectedfulldepthimage);
+
+	Assert(rows);
+	Assert(columns);
+
+	projectedfulldepthimage=new Uint16[columns*rows];
+	Assert(projectedfulldepthimage);
+
+	class SourceBase<Uint16> *source = getSourceSource();
+	if (!source) return false;
+
+
+	unsigned row=0;
+	unsigned column=0;
+	unsigned frame=0;
+	size_t n;
+	const Uint16 *buffer;
+	Uint16 *dstptr=projectedfulldepthimage;
+	while (source->read()) {
+		n=source->getBufferCount();
+		Assert(n);
+		buffer=source->getBuffer();
+		Assert(buffer);
+		while (n--) {
+			Uint16 srcvalue=*buffer++;
+			Uint16 dstvalue=*dstptr;
+
+//cerr << "srcvalue[" << dec << frame << "," << row << "," << column << "] = " << hex << srcvalue << dec << endl;
+
+			// here is the meat ... map source value into destination value
+
+			if (frame == 0) {		// first pass ... just copy values
+				*dstptr=srcvalue;
+			}
+			else {
+				if (projectiontype == MIP) {	// Maximum Intensity Projection
+					if (issigned) {
+						if (Int16(srcvalue) > Int16(dstvalue)) *dstptr=Uint16(srcvalue);
+					}
+					else {
+						if (srcvalue > dstvalue) *dstptr=srcvalue;
+					}
+				}
+				else if (projectiontype == SUM) {	// simple sum (clipped within 16 bits)
+					// should clip properly here ... for now truncate
+					if (issigned) {
+						*dstptr=Uint16(Int16(srcvalue)+Int16(dstvalue));
+					}
+					else {
+						*dstptr=srcvalue+dstvalue;
+					}
+				}
+				else if (projectiontype == FUZZY) {	// fuzzy segmentation
+					long s;
+					long d;
+					if (issigned) {
+						s=Int16(srcvalue);
+						d=Int16(dstvalue);
+					}
+					else {
+						s=Uint16(srcvalue);
+						d=Uint16(dstvalue);
+					}
+
+					long lowrampstartvalue=0;
+					long lowrampendvalue=35;
+					long highrampstartvalue=150;
+					long highrampendvalue=2000;
+
+					Assert(lowrampstartvalue <= lowrampendvalue);
+					Assert(lowrampendvalue <= highrampstartvalue);
+					Assert(highrampstartvalue <= highrampendvalue);
+
+					long belowrampweight=0;
+					long onrampweight=256;
+					long aboverampweight=0;
+
+					long contrib;
+
+					if      (s < lowrampstartvalue)  contrib=belowrampweight;
+					else if (s > highrampendvalue)   contrib=aboverampweight;
+					else if (s > lowrampendvalue
+					      && s < highrampstartvalue) contrib=onrampweight;
+					else if (s >= lowrampstartvalue
+					      && s <= lowrampendvalue) {
+						contrib=long((double(s)-lowrampstartvalue)
+							     /(lowrampendvalue-lowrampstartvalue+1)
+							     *(onrampweight-belowrampweight));
+					}
+					else if (s >= highrampstartvalue
+					      && s <= highrampendvalue) {
+						contrib=long(highrampendvalue-((double(s)-highrampstartvalue))
+							     /(highrampendvalue-highrampstartvalue+1)
+							     *(onrampweight-aboverampweight));
+					}
+					else {
+						Assert(0);
+					}
+					
+					if (issigned) {
+						*dstptr=Uint16(Int16(d+contrib));
+					}
+					else {
+						*dstptr=Uint16(d+contrib);
+					}
+				}
+				else {
+					Assert(0);
+				}
+			}
+
+			// end of meat ... increment indices and counts ...
+
+			++dstptr;
+
+			if (++column >= columns) {
+				column=0;
+//cerr << "Row = " << dec << row << endl;
+				if (++row >= rows) {
+					row=0;
+cerr << "Frame = " << dec << frame << endl;
+					Assert(frame<frames);
+					++frame;
+					dstptr=projectedfulldepthimage;
+				}
+			}
+		}
+	}
+
+cerr << "ImageFromProjectedFrames::createProjectedFullDepthImageFromSourceFrames at end: column = " << dec << column << endl;
+cerr << "ImageFromProjectedFrames::createProjectedFullDepthImageFromSourceFrames at end: row = " << dec << row << endl;
+cerr << "ImageFromProjectedFrames::createProjectedFullDepthImageFromSourceFrames at end: frame = " << dec << frame << endl;
+
+	//Assert(column == 0 && row == 0 && frame == frames);
+
+cerr << "ImageFromProjectedFrames::createProjectedFullDepthImageFromSourceFrames done" << endl;
+
+	return true;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	ProjectionType projectiontype = ProjectionType(0);
+
+	if (options.get("mip")) projectiontype=MIP;
+	if (options.get("sum")) projectiontype=SUM;
+	if (options.get("fuzzy")) projectiontype=FUZZY;
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-mip|-sum|-fuzzy]"
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	if (!list.good()) {
+		log << list.errors()
+		    << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+		success=false;
+	}
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+		success=false;
+	}
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (!aNumberOfFrames) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"NumberOfFrames\""
+		    << endl;
+		success=false;
+	}
+	else
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+		success=false;
+	}
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+		success=false;
+	}
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+		success=false;
+	}
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+		success=false;
+	}
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+		success=false;
+	}
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+		success=false;
+	}
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+
+	Uint32 length=0;
+	if (!aPixelData) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelData\""
+		    << endl;
+		success=false;
+	}
+	else {
+		length=aPixelData->getVL();
+	}
+
+	if (!quiet) {
+		log << "Read ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPixelData Value Length = " << hex << length << dec << endl;
+	}
+
+	if (vBitsAllocated > 16) {
+		log << EMsgDC(Unsupported) << " - BitsAllocated = " << vBitsAllocated << " (> 16)" << endl;
+		success=false;
+	}
+
+	if (vBitsStored > 16) {
+		log << EMsgDC(Unsupported) << " - BitsStored = " << vBitsStored << " (> 16)" << endl;
+		success=false;
+	}
+
+	if (vHighBit > 15) {
+		log << EMsgDC(Unsupported) << " - HighBit = " << vHighBit << " (> 15)" << endl;
+		success=false;
+	}
+
+	if (vSamplesPerPixel != 1) {
+		log << EMsgDC(Unsupported) << " - SamplesPerPixel = " << vSamplesPerPixel << " (!= 1)" << endl;
+		success=false;
+	}
+
+	Assert((Uint32)vRows*vColumns*vSamplesPerPixel <= length/vNumberOfFrames*8/vBitsAllocated);	// framelengthinwords
+
+	if (!vRows || !vColumns
+	 || !vPhotometricInterpretation || !vSamplesPerPixel
+	 || !vBitsAllocated) {
+		log << EMsgDC(MissingMandatoryAttributes) << endl;
+		success=false;
+	}
+
+	if (vNumberOfFrames < 2) {
+		log << "Single frames not supported" << endl;
+		success=false;
+	}
+
+	if (din.getTransferSyntaxToReadDataSet()->isEncapsulated()) {
+		log << "Encapsulated (compressed) input data not supported" << endl;
+		success=false;
+	}
+
+	OtherUnspecifiedLargeAttributeBase *oPixelData = 0;
+	SupplySourceFromAttribute *sPixelData = 0;
+	ImageFromProjectedFrames *image = 0;
+	TransferSyntax *transfersyntax = 0;
+
+	if (success) {
+		Assert(aPixelData);
+
+		if (!aPixelData->isOtherData()) {
+			log << EMsgDC(PixelDataIncorrectVR) << endl;
+			success=false;
+		}
+		else {
+			oPixelData = aPixelData->castToOtherData();
+			Assert(oPixelData);
+			sPixelData = new SupplySourceFromAttribute(oPixelData);
+			Assert(sPixelData);
+
+			image=new ImageFromProjectedFrames(sPixelData,vColumns,vRows,vNumberOfFrames,
+					vBitsAllocated,vBitsStored,vHighBit,vPixelRepresentation,
+					projectiontype);
+			Assert(image);
+			image->createProjectedFullDepthImageFromSourceFrames();
+cerr << "remove old" << endl;
+			list-=TagFromName(NumberOfFrames);
+			list-=aPixelData;
+cerr << "create transfersyntax" << endl;
+			transfersyntax = new TransferSyntax (
+				dicom_output_options.transfersyntaxuid
+				? dicom_output_options.transfersyntaxuid
+				: DefaultTransferSyntaxUID);
+			Assert(transfersyntax);
+cerr << "add new pixel data" << endl;
+			list+=new OtherUnspecifiedLargeAttribute(
+				TagFromName(PixelData),
+				image->getResultSource(),
+				vRows,
+				vColumns,
+				1,	// Number of Frames
+				vSamplesPerPixel,
+				transfersyntax,
+				0,vBitsAllocated,vBitsStored,vHighBit);
+cerr << "write it" << endl;
+			if (!usualManagedAttributeListWrite(list,dout,
+				dicom_output_options,log,verbose)) success=false;
+		}
+	}
+cerr << "delete stuff" << endl;
+
+	if (oPixelData) delete oPixelData;
+	if (sPixelData) delete sPixelData;
+	if (image) delete image;
+	if (transfersyntax) delete transfersyntax;
+
+	return success ? 0 : 1;
+}
+
+
diff --git a/appsrc/dcfile/dcproj.man b/appsrc/dcfile/dcproj.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcrmmeta.cc b/appsrc/dcfile/dcrmmeta.cc
new file mode 100644
index 0000000..aa50149
--- /dev/null
+++ b/appsrc/dcfile/dcrmmeta.cc
@@ -0,0 +1,157 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcrmmeta.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#include <cctype>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrtag.h"
+#include "dcstream.h"
+//#include "elmconst.h"
+//#include "elmdict.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+
+static void copyBytes(istream& i,ostream& o) {
+	const int bufsize=1024;
+	char buffer[1024];
+	int n;
+	while (n=i.read(buffer,bufsize).gcount()) o.write(buffer,n);
+}
+
+static bool
+readMeta(DicomInputStream& stream,TextOutputStream& log)
+{
+	if (stream.haveMetaHeader()) {
+		Tag tag;
+		stream >> tag;
+		if (stream.fail()) {
+			log << EMsgDC(TagReadFailed) << endl;
+			return false;
+		}
+		// Get mandatory metaheader group length value ...
+		Uint32 metaHeaderGroupLength = 0;
+		if (tag.isMetaheaderGroup() && tag.getElement() == 0x0000) {
+			char vr[3];
+			Uint32 vl;
+			if (stream.getTransferSyntaxInUse()->isExplicitVR()) {		// should always be
+				stream.read(vr,2);
+				if (stream.fail()) {
+					log << EMsgDC(VRReadFailed) << endl;
+					return false;
+				}
+				vr[2]=0;
+				if (strcmp(vr,"UL") == 0) {
+					vl=stream.read16();
+				}
+				else {
+					log << EMsgDC(MetaHeaderGroupLengthNotUL) << endl;
+					return false;
+				}
+			}
+			else {
+				log << WMsgDC(MetaHeaderIsImplicitVR) << endl;
+				stream >> vl;
+			}
+			if (stream.fail()) {
+				log << EMsgDC(VLReadFailed) << endl;
+				return false;
+			}
+			if (vl == 4) {
+				stream >> metaHeaderGroupLength;
+				if (stream.fail()) {
+					log << EMsgDC(MetaHeaderGroupLengthValueReadFailed) << endl;
+					return false;
+				}
+				// skip it
+				stream.seekg(metaHeaderGroupLength,ios::cur);
+				if (stream.fail()) {
+					log << EMsgDC(MetaHeaderReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+					return false;
+				}
+				else {
+					return true; // done
+				}
+			}
+			else {
+				log << EMsgDC(MetaHeaderGroupLengthHasWrongVL) << endl;
+				return false;
+			}
+		}
+		else {
+			log << EMsgDC(MetaHeaderMissingGroupLength) << endl;
+			return false;
+		}			
+	}
+	else {
+		return true;
+	}
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	OutputOptions		output_options(options);
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+	TextOutputStream log(cerr);
+
+	bool success=readMeta(din,log);
+	if (success) {
+		copyBytes(din,out);
+		if (!out.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcrmmeta.man b/appsrc/dcfile/dcrmmeta.man
new file mode 100755
index 0000000..31f7d2b
--- /dev/null
+++ b/appsrc/dcfile/dcrmmeta.man
@@ -0,0 +1,43 @@
+.TH DCRMMETA 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Remove meta information header"
+.SH NAME
+dcrmmeta \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Remove meta information header
+.SH SYNOPSIS
+.HP 10
+.B dcrmmeta
+.so man1/gen.so
+.so man1/optin.so
+.so man1/genout.so
+.SH DESCRIPTION
+.LP
+.B dcrmmeta
+reads the named dicom file, strips off the meta information header (if
+any is present) and copies the rest of the information to a new dicom file.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The encoding of the file will be unchanged. The actual transfer syntax
+of the enclosed file is irrelevant, as everything after the metaheader
+group is copied byte by byte. This allows removing the metaheader from
+any transfer syntax, whether or not it is supported by this toolkit. For
+this to work, the metaheader must begin with the (mandatory) group length
+element.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). There are no options specific to this program.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), dcunmeta(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcrmsfx.all.man b/appsrc/dcfile/dcrmsfx.all.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcrmsfx.all.script b/appsrc/dcfile/dcrmsfx.all.script
new file mode 100755
index 0000000..103a96d
--- /dev/null
+++ b/appsrc/dcfile/dcrmsfx.all.script
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# usage: dcrmsfx.all.script
+#
+# this script removes a .dcm extension (e.g. prior to dcdirmk)
+
+MV=mv
+
+for i in `find "$1" -name '*.dcm' -print`
+do
+	newname=`echo "$i" | sed 's/[.]dcm$//'`
+	echo "Moving $i to $newname" 
+	$MV "$i" "$newname"
+done
+
diff --git a/appsrc/dcfile/dcsmpte.cc b/appsrc/dcfile/dcsmpte.cc
new file mode 100644
index 0000000..9667fe2
--- /dev/null
+++ b/appsrc/dcfile/dcsmpte.cc
@@ -0,0 +1,144 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcsmpte.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+//#include "ioopt.h"
+#include "dcopt.h"
+
+#include "smptesrc.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	unsigned rows=512;
+	(void)(options.get("rows",rows) || options.get("x",rows));
+
+	unsigned cols=512;
+	(void)(options.get("cols",cols) || options.get("columns",cols) || options.get("y",cols));
+
+	unsigned bits=8;
+	(void)(options.get("bits",bits) || options.get("depth",bits) || options.get("d",bits));
+
+	if (bits < 1 || bits > 16) {
+		cerr << EMsgDC(OptionUnsupported) << " - bits = " << dec << bits << endl;
+		bad=true;
+	}
+
+	int minval=0;
+	(void)options.get("minval",minval);
+
+	int maxval=(int)(((long)(0x0001l)<<bits)-1);
+	(void)options.get("maxval",maxval);
+
+	bool wantsigned=options.get("signed");
+
+	bool wantinverted=options.get("invert") || options.get("inverted") || options.get("monochrome1");
+
+	dicom_output_options.done();
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_output_options.usage()
+			<< " [-rows|-y rows]"
+			<< " [-cols|-columns|-x columns]"
+			<< " [-bits|-depth|-d bits]"
+			<< " [-minval i]"
+			<< " [-mavxal i]"
+			<< " [-signed]"
+			<< " [-inverted|-invert|-monochrome1]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(OutputFile) << "]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log(cerr);
+
+	Uint16 bitsAllocated=((bits-1)/8+1)*8;
+	Uint16 bitsStored=bits;
+	Uint16 highBit=bits-1;
+
+	list+=new UnsignedShortAttribute(TagFromName(BitsAllocated),bitsAllocated);
+	list+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsStored);
+	list+=new UnsignedShortAttribute(TagFromName(HighBit),highBit);
+	list+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	list+=new UnsignedShortAttribute(TagFromName(Columns),cols);
+	list+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),1u);
+	list+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),wantsigned?1u:0u);
+	list+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),wantinverted ? "MONOCHROME1":"MONOCHROME2");
+
+	// various Type 1 and Type 2 attributes for mandatory SC modules ...
+
+	list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+	list+=new LongStringAttribute(TagFromName(PatientID));
+	list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+	list+=new CodeStringAttribute(TagFromName(PatientSex));
+	list+=new ShortStringAttribute(TagFromName(StudyID));
+	list+=new DateStringAttribute(TagFromName(StudyDate));
+	list+=new TimeStringAttribute(TagFromName(StudyTime));
+	list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+	list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+	list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+	list+=new IntegerStringAttribute(TagFromName(InstanceNumber));
+
+	list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+	list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+
+	list+=new LongStringAttribute(TagFromName(Manufacturer));
+	list+=new CodeStringAttribute(TagFromName(PatientOrientation));
+
+	SMPTE_PixelDataSource *pixeldatasrc=new SMPTE_PixelDataSource(rows,cols,wantsigned,wantinverted,(Uint16)minval,(Uint16)maxval);
+	Assert(pixeldatasrc);
+
+	list+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1,
+		1,
+		&transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/dcsmpte.man b/appsrc/dcfile/dcsmpte.man
new file mode 100755
index 0000000..802a1f4
--- /dev/null
+++ b/appsrc/dcfile/dcsmpte.man
@@ -0,0 +1,142 @@
+.TH DCSMPTE 1 "6 March 2014" "DICOM PS3" "Create DICOM SMPTE pattern"
+.SH NAME
+dcsmpte \- ACR/NEMA DICOM PS3 ... Create DICOM SMPTE pattern
+.SH SYNOPSIS
+.HP 10
+.B dcsmpte
+.so man1/gen.so
+[
+.B \-columns|\-cols|\-x " columns"
+]
+[
+.B \-rows|\-y " rows"
+]
+[
+.B \-bits|\-depth|\-d " bits"
+]
+[
+.B \-minval " i"
+]
+[
+.B \-maxval " i"
+]
+[
+.B \-signed
+]
+[
+.B \-inverted|\-invert|\-monochrome1
+]
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcsmpte
+writes a grayscale MONOCHROME2 or MONOCHROME1 SMPTE RP 133-1991 pattern as a DICOM
+Secondary Capture Image Storage SOP Class instance stored in a DICOM file.
+.LP
+During the creation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+.PP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.BI \-bits|\-depth|\-d " bits"
+.RS
+Defaults to 8.
+.RE
+.TP
+.BI \-columns|\-cols|\-x " columns"
+.RS
+Defaults to 512.
+.RE
+.TP
+.BI \-rows|\-y " rows"
+.RS
+Defaults to 512.
+.RE
+.TP
+.BI \-minval " i"
+.RS
+Defaults to 0. Specifies the pixel value to store for the 0% gray value in the SMPTE pattern
+(may be a negative value eg. ' -1024').
+.RE
+.TP
+.BI \-maxval " i"
+.RS
+Defaults to (2^bits)-1. Specifies the pixel value to store for the 100% gray value in the SMPTE pattern.
+.RE
+.TP
+.BI \-signed
+.RS
+Treat the minval and maxval as signed and set the Pixel Representation
+in the DICOM image to signed.
+.RE
+.TP
+.BI \-inverted|\-invert|\-monochrome1
+.RS
+Invert the grayscale range and set the Photometric Interpretation
+to MONOCHROME1 (zero is white) rather than the default MONOCHROME2 (zero
+is black). The image should display the same in a DICOM viewer that
+correctly handles Photometric Interpretation.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+# Create an 8 bit pattern from 0 to 100 ...
+.RE
+% dcsmpte -rows 512 -cols 512 -bits 8 -minval 0 -maxval 100 smpte.dc3
+.RE
+\ 
+.RE
+# Create an 8 bit pattern from 0 to 255 ...
+.RE
+% dcsmpte -rows 512 -cols 512 -bits 8 -minval 0 -maxval 255 smpte.dc3
+.RE
+# or using the defaults which give the same result ...
+.RE
+% dcsmpte smpte.dc3
+.RE
+\ 
+.RE
+# Create a 12 bit pattern from 0 to 4095 ...
+.RE
+% dcsmpte -rows 512 -cols 512 -bits 12 -minval 0 -maxval 4095 smpte.dc3
+.RE
+\ 
+.RE
+# Create a signed 12 bit pattern from -1024 to 3071 ...
+.RE
+% dcsmpte -rows 512 -cols 512 -bits 12 -minval ' -1024' -maxval 3071 -signed
+.RE
+\ 
+.RE
+# Create a signed 16 bit pattern from -1024 to 3071 ...
+.RE
+% dcsmpte -rows 512 -cols 512 -bits 16 -minval ' -1024' -maxval 3071 -signed
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dciodvfy(1) ,
+.BR dcbriggs(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+The crosshatch lines are covered by the grayscales squares rather than
+over the top of them as is usually implemented and implied by the
+illustrations in SMPTE RP 133-1991. This is a deliberate choice that
+seems to make it easier to compare adjacent squares to determine whether
+or not they are distinguishable.
diff --git a/appsrc/dcfile/dcsort.cc b/appsrc/dcfile/dcsort.cc
new file mode 100644
index 0000000..46be735
--- /dev/null
+++ b/appsrc/dcfile/dcsort.cc
@@ -0,0 +1,935 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcsort.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static ElementDictionary staticDictionary;
+
+// Various functions to check and match values ...
+
+static bool
+errorIfStringValuesDontMatch(const char *firstValue,
+	const char *newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	Assert(firstValue);
+	Assert(newValue);
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (strcmp(firstValue,newValue) != 0) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << (newValue ? newValue : "")
+		    << "> previously seen as  <"
+		    << (firstValue ? firstValue : "")
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static bool
+errorIfIntegerValuesDontMatch(Uint16 firstValue,
+	Uint16 newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	//Assert(firstValue);	// May legitimately be zero ?
+	//Assert(newValue);	// May legitimately be zero ?
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (firstValue != newValue) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << newValue
+		    << "> previously seen as  <"
+		    << firstValue
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static bool
+errorIfFloatValuesDontMatch(double firstValue,
+	double newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	//Assert(firstValue);	// May legitimately be zero ?
+	//Assert(newValue);	// May legitimately be zero ?
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (firstValue != newValue) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << newValue
+		    << "> previously seen as  <"
+		    << firstValue
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static const char *
+getStringValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	char *value=AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	return a ? value : "";
+}
+
+static Uint16
+getIntegerValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	Uint16 value=AttributeValue(a);
+	return value;
+}
+
+static double
+getFloatValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	double value=AttributeValue(a);
+	return value;
+}
+
+static const char *
+getAndCheckStringMatchElseError(bool first,const char * &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	const char *value=getStringValueElseError(list,tag,label,filename,log);
+	Assert(value);
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfStringValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+static Uint16
+getAndCheckIntegerMatchElseError(bool first,Uint16 &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Uint16 value=getIntegerValueElseError(list,tag,label,filename,log);
+	//Assert(value);	// May legitimately be zero ?
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfIntegerValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+static double
+getAndCheckFloatMatchElseError(bool first,double &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	double value=getFloatValueElseError(list,tag,label,filename,log);
+	//Assert(value);	// May legitimately be zero ?
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfFloatValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+
+
+// Function to get value to sort using ImagePositionPatient ...
+
+static double
+getDistanceAlongNormalToImagePlane(bool first,AttributeList &list,
+	double &reference_tlhc_X,double &reference_tlhc_Y,double &reference_tlhc_Z,
+	const char *filename,TextOutputStream &log)
+{
+	Attribute *aImagePositionPatient=isValuePresentElseError(list,
+		TagFromName(ImagePositionPatient),"Image Position Patient",filename,log);
+	Attribute *aImageOrientationPatient=isValuePresentElseError(list,
+		TagFromName(ImageOrientationPatient),"Image Orientation Patient",filename,log);
+
+	if (!aImagePositionPatient || !aImageOrientationPatient) return 0;
+
+	if (aImagePositionPatient->getVM() != 3) {
+		log << filename << ": " 
+		    << EMsgDC(BadAttributeValueMultiplicity)
+		    << " - Image Position Patient - "
+		    << MMsgDC(Expected) << " 3 "
+		    << MMsgDC(Got) << " " << aImagePositionPatient->getVM()
+		    << endl;
+		return 0;
+	}
+
+	if (aImageOrientationPatient->getVM() != 6) {
+		log << filename << ": " 
+		    << EMsgDC(BadAttributeValueMultiplicity)
+		    << " - Image Orientation Patient - "
+		    << MMsgDC(Expected) << " 6 "
+		    << MMsgDC(Got) << " " << aImageOrientationPatient->getVM()
+		    << endl;
+		return 0;
+	}
+
+	double tlhc_X; aImagePositionPatient->getValue(0,tlhc_X);
+	double tlhc_Y; aImagePositionPatient->getValue(1,tlhc_Y);
+	double tlhc_Z; aImagePositionPatient->getValue(2,tlhc_Z);
+
+//cerr << "tlhc_X = " << tlhc_X << endl;
+//cerr << "tlhc_Y = " << tlhc_Y << endl;
+//cerr << "tlhc_Z = " << tlhc_Z << endl;
+
+	double distance;
+
+	// if first time, set reference TLHC to current TLHC and return distance of zero
+
+	if (first) {
+		reference_tlhc_X=tlhc_X;
+		reference_tlhc_Y=tlhc_Y;
+		reference_tlhc_Z=tlhc_Z;
+	}
+
+	{
+		double row_X; aImageOrientationPatient->getValue(0,row_X);
+		double row_Y; aImageOrientationPatient->getValue(1,row_Y);
+		double row_Z; aImageOrientationPatient->getValue(2,row_Z);
+
+//cerr << "row_X = " << row_X << endl;
+//cerr << "row_Y = " << row_Y << endl;
+//cerr << "row_Z = " << row_Z << endl;
+
+		double col_X; aImageOrientationPatient->getValue(3,col_X);
+		double col_Y; aImageOrientationPatient->getValue(4,col_Y);
+		double col_Z; aImageOrientationPatient->getValue(5,col_Z);
+
+//cerr << "col_X = " << col_X << endl;
+//cerr << "col_Y = " << col_Y << endl;
+//cerr << "col_Z = " << col_Z << endl;
+
+		// compute normal to image plane - cross product of row and column vectors ...
+
+		double normal_X = row_Y*col_Z - row_Z*col_Y;
+		double normal_Y = row_Z*col_X - row_X*col_Z;
+		double normal_Z = row_X*col_Y - row_Y*col_X;
+
+//cerr << "normal_X = " << normal_X << endl;
+//cerr << "normal_Y = " << normal_Y << endl;
+//cerr << "normal_Z = " << normal_Z << endl;
+
+		// length of normal is sqrt(dot product of normal with itself)
+		// should be 1 since both row and col vectors unit vectors
+		// but just in case ...
+
+		double normal_length=sqrt(normal_X*normal_X+normal_Y*normal_Y+normal_Z*normal_Z);
+
+//cerr << "normal_length = " << normal_length << endl;
+
+		Assert(normal_length != 0);
+
+		// calculate vector between tlhc and reference tlhc
+
+		double difference_X = tlhc_X - reference_tlhc_X;
+		double difference_Y = tlhc_Y - reference_tlhc_Y;
+		double difference_Z = tlhc_Z - reference_tlhc_Z;
+
+//cerr << "difference_X = " << normal_X << endl;
+//cerr << "difference_Y = " << difference_Y << endl;
+//cerr << "difference_Z = " << difference_Z << endl;
+
+		// project difference vector onto normal to get distance
+		// by computing dot product of difference vector and normal vector
+		// and dividing by length of normal vector ...
+
+		distance=(difference_X*normal_X+difference_Y*normal_Y+difference_Z*normal_Z)/normal_length;
+	}
+//cerr << "distance = " << distance << endl;
+
+	return distance;
+}
+
+// Function to get value to sort using ImageOrientationPatient ...
+
+static double
+getAngleOfNormalToImagePlane(bool first,AttributeList &list,
+	double &reference_normal_X,double &reference_normal_Y,double &reference_normal_Z,
+	double &reference_normal_length,
+	const char *filename,TextOutputStream &log)
+{
+	Attribute *aImageOrientationPatient=isValuePresentElseError(list,
+		TagFromName(ImageOrientationPatient),"Image Orientation Patient",filename,log);
+
+	if (!aImageOrientationPatient) return 0;
+
+	if (aImageOrientationPatient->getVM() != 6) {
+		log << filename << ": " 
+		    << EMsgDC(BadAttributeValueMultiplicity)
+		    << " - Image Orientation Patient - "
+		    << MMsgDC(Expected) << " 6 "
+		    << MMsgDC(Got) << " " << aImageOrientationPatient->getVM()
+		    << endl;
+		return 0;
+	}
+
+	double angle;
+
+	double row_X; aImageOrientationPatient->getValue(0,row_X);
+	double row_Y; aImageOrientationPatient->getValue(1,row_Y);
+	double row_Z; aImageOrientationPatient->getValue(2,row_Z);
+
+//cerr << "row_X = " << row_X << endl;
+//cerr << "row_Y = " << row_Y << endl;
+//cerr << "row_Z = " << row_Z << endl;
+
+	double col_X; aImageOrientationPatient->getValue(3,col_X);
+	double col_Y; aImageOrientationPatient->getValue(4,col_Y);
+	double col_Z; aImageOrientationPatient->getValue(5,col_Z);
+
+//cerr << "col_X = " << col_X << endl;
+//cerr << "col_Y = " << col_Y << endl;
+//cerr << "col_Z = " << col_Z << endl;
+
+	// compute normal to image plane - cross product of row and column vectors ...
+
+	double normal_X = row_Y*col_Z - row_Z*col_Y;
+	double normal_Y = row_Z*col_X - row_X*col_Z;
+	double normal_Z = row_X*col_Y - row_Y*col_X;
+
+//cerr << "normal_X = " << normal_X << endl;
+//cerr << "normal_Y = " << normal_Y << endl;
+//cerr << "normal_Z = " << normal_Z << endl;
+
+	// length of normal is sqrt(dot product of normal with itself)
+	// should be 1 since both row and col vectors unit vectors
+	// but just in case ...
+
+	double normal_length=sqrt(normal_X*normal_X+normal_Y*normal_Y+normal_Z*normal_Z);
+
+//cerr << "normal_length = " << normal_length << endl;
+
+	Assert(normal_length != 0);
+
+	// if first time, set reference normal to current normal
+
+	if (first) {
+		reference_normal_X=normal_X;
+		reference_normal_Y=normal_Y;
+		reference_normal_Z=normal_Z;
+		reference_normal_length=normal_length;
+	}
+
+	// calculate angle in degrees between normal and reference normal
+	// by computing arccos of dot product of vectors divided by lengths ...
+
+	angle=acos(
+		 (normal_X*reference_normal_X+normal_Y*reference_normal_Y+normal_Z*reference_normal_Z)
+		/(normal_length*reference_normal_length)
+		 ) * (360.0 / (M_PI * 2.0));
+
+//cerr << "angle = " << angle << endl;
+
+	return angle;
+}
+
+// structure and sort compare to sort filenames by some numeric value
+
+struct sortentry {
+	double primaryvalue;
+	double secondaryvalue;
+	const char *filename;
+};
+
+static int
+//sortentrycompareascending(const sortentry *i, const sortentry *j)
+//sortentrycompareascending(sortentry *i, sortentry *j)
+sortentrycompareascending(const void *ip, const void *jp)
+{
+	const sortentry *i=(const sortentry *)ip;
+	const sortentry *j=(const sortentry *)jp;
+	Assert(i);
+	Assert(j);
+	if (fabs(i->primaryvalue - j->primaryvalue) < 0.00001) {	// equal
+		if (i->secondaryvalue > j->secondaryvalue)
+			return (1);
+		if (i->secondaryvalue < j->secondaryvalue)
+			return (-1);
+	}
+	else {
+		if (i->primaryvalue > j->primaryvalue)
+			return (1);
+		if (i->primaryvalue < j->primaryvalue)
+			return (-1);
+	}
+	return (0);
+}
+
+static int
+//sortentrycomparedescending(const sortentry *i, const sortentry *j)
+//sortentrycomparedescending(sortentry *i, sortentry *j)
+sortentrycomparedescending(const void *ip, const void *jp)
+{
+	const sortentry *i=(const sortentry *)ip;
+	const sortentry *j=(const sortentry *)jp;
+	Assert(i);
+	Assert(j);
+	if (fabs(i->primaryvalue - j->primaryvalue) < 0.00001) {	// equal
+		if (i->secondaryvalue > j->secondaryvalue)
+			return (-1);
+		if (i->secondaryvalue < j->secondaryvalue)
+			return (1);
+	}
+	else {
+		if (i->primaryvalue > j->primaryvalue)
+			return (-1);
+		if (i->primaryvalue < j->primaryvalue)
+			return (1);
+	}
+	return (0);
+}
+
+static void
+dumpsortedfilenamestable(sortentry *table,int n,const char *name,ostream &log)
+{
+	int i;
+	for (i=0; i<n; ++i) {
+		log << name << "[" << i << "] = " << table[i].primaryvalue << " in " << table[i].filename << endl;
+	}
+}
+
+static void
+dumpindexfilenamestable(sortentry *table,int n,bool showsortkeyvalue,bool showinterval,ostream &log)
+{
+	double lastprimaryvalue = table[0].primaryvalue;
+	int i;
+	for (i=0; i<n; ++i) {
+		double thisprimaryvalue = table[i].primaryvalue;
+		double delta = thisprimaryvalue - lastprimaryvalue;
+		lastprimaryvalue = thisprimaryvalue;
+		if (showsortkeyvalue && showinterval) {
+			log << i << "\t" << table[i].filename << "\t" << thisprimaryvalue << "\t" << delta << endl;
+		}
+		else if (showsortkeyvalue) {
+			log << i << "\t" << table[i].filename << "\t" << thisprimaryvalue << endl;
+		}
+		else {
+			log << i << "\t" << table[i].filename << endl;
+		}
+	}
+}
+
+static void
+getintervalfromindexfilenamestable(sortentry *table,int n,double tolerance,ostream &log) {
+	bool success=true;
+	double total;
+	double interval;
+	double lastprimaryvalue = table[0].primaryvalue;
+	int i;
+	for (i=1; i<n; ++i) {
+		double thisprimaryvalue = table[i].primaryvalue;
+		double delta = thisprimaryvalue - lastprimaryvalue;
+		lastprimaryvalue = thisprimaryvalue;
+		if (i == 1) {
+			interval = delta;
+			total = delta;
+		}
+		else if (fabs(interval-delta) > tolerance) {
+			log << "Error: unequal interval" << endl;
+			success=false;
+			break;
+		}
+		else {
+			total+=delta;
+			interval = total/i;
+		}
+	}
+	if (success) {
+		log << "Interval\t" << interval << endl;
+	}
+}
+
+static bool
+checkSameSeries(int numberofinputfiles,struct sortentry *sortedfilenamestable,DicomInputOptions &dicom_input_options,
+	bool verbose,bool veryverbose,bool veryveryverbose,TextOutputStream &log)
+{
+	// make pass to check attributes required to have constant values for all image files ...
+
+	bool success=true;
+
+	const char *requiredPatientID;
+	const char *requiredStudyInstanceUID;
+	const char *requiredSeriesInstanceUID;
+	const char *requiredSOPClassUID;
+	const char *requiredPatientName;
+	const char *requiredStudyID;
+	Uint16 requiredSeriesNumber;
+	const char *requiredModality;
+
+	Uint16 requiredRows;
+	Uint16 requiredColumns;
+	Uint16 requiredBitsAllocated;
+	Uint16 requiredBitsStored;
+	Uint16 requiredHighBit;
+	Uint16 requiredPixelRepresentation;
+	Uint16 requiredSamplesPerPixel;
+
+	double requiredSliceThickness;
+
+	//Uint16 requiredEchoNumber;
+	double requiredEchoTime;
+	double requiredRepetitionTime;
+
+	double requiredRescaleSlope;
+	double requiredRescaleIntercept;
+
+	// iterate through image files to extract and check attributes values ...
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+
+		// open and read each image file ...
+
+		const char *filename=sortedfilenamestable[i].filename;
+		Assert(filename);
+		if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			success=false;
+			break;
+		}
+
+		DicomInputStream din(*(istream *)fstr);
+
+		ManagedAttributeList list;
+
+		if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+		list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			break;
+		}
+
+		// extract and check that attributes values are consistent for all image files ...
+
+		const char *patientID=getAndCheckStringMatchElseError(i == 0,requiredPatientID,list,
+			TagFromName(PatientID),"Patient ID",filename,log);
+
+		const char *patientName=getAndCheckStringMatchElseError(i == 0,requiredPatientName,list,
+			TagFromName(PatientName),"Patient Name",filename,log);
+
+		const char *studyInstanceUID=getAndCheckStringMatchElseError(i == 0,requiredStudyInstanceUID,list,
+			TagFromName(StudyInstanceUID),"Study Instance UID",filename,log);
+
+		const char *studyID=getAndCheckStringMatchElseError(i == 0,requiredStudyID,list,
+			TagFromName(StudyID),"Study ID",filename,log);
+
+		const char *seriesInstanceUID=getAndCheckStringMatchElseError(i == 0,requiredSeriesInstanceUID,list,
+			TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+
+		const char *SOPClassUID=getAndCheckStringMatchElseError(i == 0,requiredSOPClassUID,list,
+			TagFromName(SOPClassUID),"SOP Class UID",filename,log);
+
+		Uint16 seriesNumber=getAndCheckIntegerMatchElseError(i == 0,requiredSeriesNumber,list,
+			TagFromName(SeriesNumber),"Series Number",filename,log);
+
+		const char *modality=getAndCheckStringMatchElseError(i == 0,requiredModality,list,
+			TagFromName(Modality),"Modality",filename,log);
+
+		Uint16 rows=getAndCheckIntegerMatchElseError(i == 0,requiredRows,list,
+			TagFromName(Rows),"Rows",filename,log);
+
+		Uint16 columns=getAndCheckIntegerMatchElseError(i == 0,requiredColumns,list,
+			TagFromName(Columns),"Columns",filename,log);
+
+		Uint16 bitsAllocated=getAndCheckIntegerMatchElseError(i == 0,requiredBitsAllocated,list,
+			TagFromName(BitsAllocated),"Bits Allocated",filename,log);
+
+		Uint16 bitsStored=getAndCheckIntegerMatchElseError(i == 0,requiredBitsStored,list,
+			TagFromName(BitsStored),"Bits Stored",filename,log);
+
+		Uint16 highBit=getAndCheckIntegerMatchElseError(i == 0,requiredHighBit,list,
+			TagFromName(HighBit),"High Bit",filename,log);
+
+		Uint16 pixelRepresentation=getAndCheckIntegerMatchElseError(i == 0,requiredPixelRepresentation,list,
+			TagFromName(PixelRepresentation),"Pixel Representation",filename,log);
+
+		Uint16 samplesPerPixel=getAndCheckIntegerMatchElseError(i == 0,requiredSamplesPerPixel,list,
+			TagFromName(SamplesPerPixel),"Samples Per Pixel",filename,log);
+
+		if (strcmp(requiredSOPClassUID,MRImageStorageSOPClassUID) == 0
+		 || strcmp(requiredSOPClassUID,CTImageStorageSOPClassUID) == 0) {
+			double sliceThickness=getAndCheckFloatMatchElseError(i == 0,requiredSliceThickness,list,
+				TagFromName(SliceThickness),"Slice Thickness",filename,log);
+		}
+
+		if (strcmp(requiredSOPClassUID,MRImageStorageSOPClassUID) == 0) {
+			//Uint16 echoNumber=getAndCheckIntegerMatchElseError(i == 0,requiredEchoNumber,list,
+			//	TagFromName(EchoNumber),"Echo Number",filename,log);
+			double echoTime=getAndCheckFloatMatchElseError(i == 0,requiredEchoTime,list,
+				TagFromName(EchoTime),"Echo Time",filename,log);
+			double repetitionTime=getAndCheckFloatMatchElseError(i == 0,requiredRepetitionTime,list,
+				TagFromName(RepetitionTime),"Repetition Time",filename,log);
+		}
+
+		if (strcmp(requiredSOPClassUID,CTImageStorageSOPClassUID) == 0) {
+			double rescaleSlope=getAndCheckFloatMatchElseError(i == 0,requiredRescaleSlope,list,
+				TagFromName(RescaleSlope),"Rescale Slope",filename,log);
+			double rescaleIntercept=getAndCheckFloatMatchElseError(i == 0,requiredRescaleIntercept,list,
+				TagFromName(RescaleIntercept),"Rescale Intercept",filename,log);
+		}
+
+		// should also check PixelSpacing, ImageOrientationPatient ...
+
+		// clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+		if (fstr) delete fstr;
+	}
+
+	return success;
+}
+
+static bool
+checkSameFrameOfReferenceUID(int numberofinputfiles,struct sortentry *sortedfilenamestable,DicomInputOptions &dicom_input_options,
+        bool verbose,bool veryverbose,bool veryveryverbose,TextOutputStream &log)
+{
+        // make pass to check attributes required to have constant values for all image files ...
+
+        bool success=true;
+
+        const char *requiredFrameOfReferenceUID;
+
+        // iterate through image files to extract and check attributes values ...
+
+        int i;
+        for (i=0; i < numberofinputfiles; ++i) {
+
+                // open and read each image file ...
+
+                const char *filename=sortedfilenamestable[i].filename;
+                Assert(filename);
+                if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+                ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+                ifstream *fstr=new ifstream(filename);
+#endif
+                if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+                        cerr << AMsgDC(FileReadOpenFailed);
+                        if (filename) cerr <<" - \"" << filename << "\"";
+                        success=false;
+                        break;
+                }
+
+                DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+                ManagedAttributeList list;
+
+                if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl;
+                list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+                if (!list.good()) {
+                        log << list.errors()
+                            << EMsgDC(DatasetReadFailed) << endl;
+                        success=false;
+                        break;
+                }
+
+                // extract and check that attributes values are consistent for all image files ...
+
+                const char *frameOfReferenceUID=getAndCheckStringMatchElseError(i == 0,requiredFrameOfReferenceUID,list,
+                        TagFromName(FrameOfReferenceUID),"Frame Of Reference UID",filename,log);
+
+                // clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+                if (fstr) delete fstr;
+        }
+
+        return success;
+}
+
+static bool
+sortBy(int numberofinputfiles,struct sortentry *&sortedfilenamestable,const char *sortbyname,Tag sortbytag,bool descending,
+	DicomInputOptions &dicom_input_options,bool showindex,bool showsortkeyvalue,bool showinterval,double tolerance,
+	bool verbose,bool veryverbose,bool veryveryverbose,TextOutputStream &log)
+{
+		// Make pass through images files to get sorttag
+
+	bool success=true;
+
+	double reference_tlhc_X;	// these are used for ImagePositionPatient only
+	double reference_tlhc_Y;
+	double reference_tlhc_Z;
+	double reference_normal_X;	// these are used for ImageOrientationPatient only
+	double reference_normal_Y;
+	double reference_normal_Z;
+	double reference_normal_length;
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+
+		// open and read each image file ...
+
+		const char *filename=sortedfilenamestable[i].filename;
+		Assert(filename);
+		if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			success=false;
+			break;
+		}
+
+		DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+
+		if (veryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+		list.read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			break;
+		}
+
+		// extract sort key attributes value ...
+
+		double value;
+		if (sortbytag == TagFromName(ImagePositionPatient)) {
+			value=getDistanceAlongNormalToImagePlane(i == 0,list,
+				reference_tlhc_X,reference_tlhc_Y,reference_tlhc_Z,
+				filename,log);
+		}
+		else if (sortbytag == TagFromName(ImageOrientationPatient)) {
+			value=getAngleOfNormalToImagePlane(i == 0,list,
+				reference_normal_X,reference_normal_Y,reference_normal_Z,
+				reference_normal_length,filename,log);
+		}
+		else {
+			value=getFloatValueElseError(list,sortbytag,sortbyname,filename,log);
+		}
+
+		sortedfilenamestable[i].primaryvalue = value;
+		sortedfilenamestable[i].secondaryvalue = getFloatValueElseError(list,TagFromName(SeriesNumber),"Series Number",filename,log);
+
+		// clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+		if (fstr) delete fstr;
+	}
+
+	if (veryverbose) {
+		log << "Before sorting" << endl;
+		dumpsortedfilenamestable(sortedfilenamestable,numberofinputfiles,sortbyname,log);
+	}
+	qsort((char *)sortedfilenamestable,numberofinputfiles,sizeof(sortentry),
+		descending ? sortentrycomparedescending : sortentrycompareascending);
+
+	if (verbose) {
+		log << "After sorting" << endl;
+		dumpsortedfilenamestable(sortedfilenamestable,numberofinputfiles,sortbyname,log);
+	}
+
+	if (showindex) {
+		dumpindexfilenamestable(sortedfilenamestable,numberofinputfiles,showsortkeyvalue,showinterval,log);
+	}
+
+	if (showinterval) {
+		getintervalfromindexfilenamestable(sortedfilenamestable,numberofinputfiles,tolerance,log);
+	}
+
+	return success;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool veryveryverbose=options.get("veryveryverbose") || options.get("vvv");
+	if (veryveryverbose) veryverbose=true;
+	if (veryverbose) verbose=true;
+
+	bool checksameseries=options.get("check");
+	bool checksameFoRUID=options.get("checkFoR");
+
+	bool showindex=options.get("index");
+	bool showsortkeyvalue=options.get("show");
+	bool showinterval=options.get("interval");
+	double tolerance = 0.01;
+	options.get("tolerance",tolerance);
+
+	const char *sortbyname;
+	bool sortby=options.get("sortby",sortbyname) || options.get("k",sortbyname);
+	Tag sortbytag;
+
+	if (sortby && !staticDictionary.getTag(sortbyname,sortbytag)) {
+		cerr << "Sort tag <" << sortbyname << "> is not a valid data element" << endl;
+		bad=true;
+	}
+
+	bool descending=options.get("descending");	// should check present only if sortby
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	int numberofinputfiles=!options;
+
+	struct sortentry *sortedfilenamestable = new sortentry [numberofinputfiles];
+	Assert(sortedfilenamestable);
+	struct sortentry *ptr = sortedfilenamestable;
+
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		ptr->filename=filename;
+		ptr->primaryvalue=0;			// leave sort value unused
+		ptr->secondaryvalue=0;			// leave sort value unused
+		++ptr;
+	}
+
+	options.done();
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose|-vvv|-veryveryverbose]"
+			<< " [-index]"
+			<< " [-check]"
+			<< " [-checkFoR]"
+			<< " [-show]"
+			<< " [-interval]"
+			<< " [-tolerance mm]"
+			<< " [-descending]"
+			<< " [-sortby|k elementname]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< endl;
+		exit(1);
+	}
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	if (checksameseries) {
+		success=checkSameSeries(numberofinputfiles,sortedfilenamestable,
+			dicom_input_options,verbose,veryverbose,veryveryverbose,log);
+	}
+
+	if (checksameFoRUID) {
+		success=checkSameFrameOfReferenceUID(numberofinputfiles,sortedfilenamestable,
+			dicom_input_options,verbose,veryverbose,veryveryverbose,log);
+	}
+
+	if (!success) exit(1);
+
+	if (sortby) {
+		success=sortBy(numberofinputfiles,sortedfilenamestable,sortbyname,sortbytag,descending,
+			dicom_input_options,showindex,showsortkeyvalue,showinterval,tolerance,
+			verbose,veryverbose,veryveryverbose,log);
+	}
+
+	if (!success) exit(1);
+
+	if (numberofinputfiles && sortedfilenamestable) delete[] sortedfilenamestable;
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcsort.man b/appsrc/dcfile/dcsort.man
new file mode 100755
index 0000000..c3eb632
--- /dev/null
+++ b/appsrc/dcfile/dcsort.man
@@ -0,0 +1,122 @@
+.TH DCSORT 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Make sorted list of images"
+.SH NAME
+dcsort \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Make sorted list of images
+.SH SYNOPSIS
+.HP 10
+.B dcsort
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-vv|veryverbose
+]
+[
+.B \-vvv|veryveryverbose
+]
+[
+.B \-index
+]
+[
+.B \-show
+]
+[
+.B \-interval
+]
+[
+.B \-tolerance mm
+]
+[
+.B \-check
+]
+[
+.B \-checkFoR
+]
+[
+.B \-descending
+]
+[
+.B \-sortby|k " attributename"
+]
+.SH DESCRIPTION
+.LP
+.B dcsort
+reads the named dicom input files and sorts them by the specified sort
+key.
+.LP
+The sort key should be a single valued numeric attribute, with the
+exception of ImageOrientationPatient and ImagePositionPatient which
+are handled as special cases.
+.LP
+There is no output by default unless the index or verbose options are
+specified.
+.SH OPTIONS
+The output and errors go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-index
+.RS
+Creates a first column of output that is the index in the sort order, starting
+from 0, and a second column that is the filename.
+.RE
+.TP
+.B \-show
+.RS
+Show the value of the sort key after the file name with the \-index option
+.RE
+.TP
+.B \-interval
+.RS
+Show the interval between values of the sort key, or an error if not equal
+.RE
+.TP
+.B \-tolerance mm
+.RS
+The tolerance value in mm to use when comparing intervals between slices; defaults to +/- 0.01 mm if unspecified
+.RE
+.TP
+.B \-check
+.RS
+Check that all the images are from the same series.
+.RE
+.TP
+.B \-checkFoR
+.RS
+Check that all the images have the same Frame of Reference (UID).
+.RE
+.TP
+.B \-descending
+.RS
+Sort in descending, rather than the default ascending, order.
+.RE
+.TP
+.B \-sortby|k " attributename"
+.RS
+Specify attributename as the sort key.
+.RE
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcsort -index -sortby SliceLocation ./1/[0-9]*
+.RE
+0	./1/1
+.RE
+1	./1/2
+.RE
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcsqextr.cc b/appsrc/dcfile/dcsqextr.cc
new file mode 100644
index 0000000..1bb2865
--- /dev/null
+++ b/appsrc/dcfile/dcsqextr.cc
@@ -0,0 +1,215 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcsqextr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "transynu.h"
+#include "attrmxls.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static bool
+writeImageInSequence(Attribute *a,
+	DicomOutputOptions& dicom_output_options,
+	TextOutputStream& log,bool verbose)
+{
+        bool success=true;
+	AttributeList **al;
+	int n;
+	if ((n=a->getLists(&al)) > 0) {
+		int i;
+		for (i=0; i<n; ++i) {
+			if ((*al[i])[TagFromName(PixelData)] && (*al[i])[TagFromName(SOPInstanceUID)]) {
+				ManagedAttributeList list;
+				list+=(*al[i]);
+
+				ostrstream ostr;
+				if (dicom_output_options.filename)
+					ostr << dicom_output_options.filename << ".";
+				ostr << String_Use(AttributeValue(
+						list[TagFromName(SOPInstanceUID)]))
+				     << "." << i
+				     << ends;
+				char *name=ostr.str();
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+				ofstream out(name,ios::out|ios::trunc|ios::binary);
+#else
+				ofstream out(name,ios::out|ios::trunc);
+#endif
+				if (!out || !out.rdbuf()->is_open()) {
+					log << EMsgDC(FileWriteOpenFailed)
+					    << " - \"" << name << "\"" << endl;
+					return false;
+				}
+				DicomOutputStream dout(out,
+					dicom_output_options.transfersyntaxuid,
+					dicom_output_options.usemetaheader,
+					dicom_output_options.useimplicitmetaheader,
+					dicom_output_options.addtiff);
+#ifdef CRAP
+				ManagedAttributeList::flag_types flags=ManagedAttributeList::flag_types(
+	                        	 (dicom_output_options.usemetaheader     ? ManagedAttributeList::metaheader:0)
+	                        	|(dicom_output_options.writedataset      ? ManagedAttributeList::dataset:0)
+	                        	|(dicom_output_options.addlengths        ? ManagedAttributeList::addlengths:0)
+	                        	|(dicom_output_options.addlengthtoend    ? ManagedAttributeList::addlengthtoend:0)
+		                        |(dicom_output_options.removeprivate     ? ManagedAttributeList::removeprivate:0)
+		                        |(dicom_output_options.removeinstanceuid ? ManagedAttributeList::removeinstanceuid:0)
+		                        |(dicom_output_options.adddicom          ? ManagedAttributeList::adddicom:0)
+		                        |(dicom_output_options.addtiff           ? ManagedAttributeList::addtiff:0)
+		                        |(dicom_output_options.adddisclaimer     ? ManagedAttributeList::adddisclaimer:0));
+
+				if (!list.clean(flags)) {
+					cerr << list.errors() << flush;
+					cerr << EMsgDC(DatasetWriteFailed) << endl;
+					return false;
+				}
+
+	                        if (dicom_output_options.deletelist) {
+	                        	list-=*(dicom_output_options.deletelist);
+	                        	if (verbose) {
+	                        		log << "******** After delete ... ********" << endl;
+	                        		log << list;
+	                        	}
+	                        }
+
+	                        if (dicom_output_options.replacebeforelist) {
+	                        	list+=*(dicom_output_options.replacebeforelist);
+		                        if (verbose) {
+		                        	log << "******** After replace before... ********" << endl;
+		                        	log << list;
+		                        }
+	                        }
+
+				if (!list.prepare(dout,flags,ManagedAttributeList::none,dicom_output_options.stamp)) {
+					cerr << list.errors() << flush;
+					cerr << EMsgDC(DatasetWriteFailed) << endl;
+					return false;
+				}
+
+	                        if (dicom_output_options.replaceafterlist) {
+	                        	list+=*(dicom_output_options.replaceafterlist);
+		                        if (verbose) {
+		                        	log << "******** After replace after ... ********" << endl;
+		                        	log << list;
+		                        }
+	                        }
+
+				if (!list.finalize(dout)) {
+					cerr << list.errors() << flush;
+					cerr << EMsgDC(DatasetWriteFailed) << endl;
+					return false;
+				}
+
+				if (!list.write(dout) || !list.good()) {
+					cerr << list.errors() << flush;
+					cerr << EMsgDC(DatasetWriteFailed) << endl;
+					return false;
+				}
+				const char *errors=list.errors();
+				if (errors) log << errors << flush;
+#else
+		                if (!usualManagedAttributeListWrite(list,dout,
+			                dicom_output_options,log,verbose)) success=false;
+#endif
+				if (verbose) {
+					log << "******** New file \"" << name << "\" ********" << endl;
+					log << list;
+				}
+				if (name) delete[] name;
+			}
+		}
+		delete [] al;
+	}
+	return success;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+#ifdef CRAP
+	if (dicom_output_options.replacebeforelist
+	 || dicom_output_options.replaceafterlist
+	 || dicom_output_options.deletelist) {
+		cerr << EMsgDC(NoReplaceOrDelete) << endl;
+		exit(1);
+	}
+#endif
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	AttributeListIterator i(list);
+	while (!i) {
+		Attribute *a=i();
+		Assert(a);
+		if (strcmp(a->getVR(),"SQ") == 0) {
+			if (!writeImageInSequence(a,dicom_output_options,log,verbose))
+				success=false;
+		}
+		++i;
+	}
+
+	if (verbose) {
+		log << "******** What is left ... ********" << endl;
+		log << list;
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcsqextr.man b/appsrc/dcfile/dcsqextr.man
new file mode 100755
index 0000000..57c523a
--- /dev/null
+++ b/appsrc/dcfile/dcsqextr.man
@@ -0,0 +1,68 @@
+.TH DCSQEXTR 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Extract Papyrus images"
+.SH NAME
+dcsqextr \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Extract Papyrus images
+.SH SYNOPSIS
+.HP 10
+.B dcsqextr
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcsqextr
+reads the named dicom or acr-nema input file, assumes that a series of images
+are contained in a sequence as in a Papyrus version 3 file, and extracts
+each of them into a separate file.
+.LP
+The input encoding of the file will be automatically determined, or can
+be explicitly specified in pathological cases using the input options
+described in dcintro(1).
+.LP
+The encoding of the output files will be changed to the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options.
+.LP
+During the extraction, the usual replace and delete operations specified in
+dcintro(1) are suppressed.
+.SH OPTIONS
+The verbose output goes to standard error. The specified output file name
+is used as a prefix, and the SOP Instance UID and image sequence number
+(not the value of the Image Number attribute) are appended to make a
+filename for each extracted image.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcsqextr MR2images.pap3 -of MR2images
+.RE
+% ls -1 MR2images.*
+.RE
+MR2images.pap3
+.RE
+MR2images.64.572.218.916.0
+.RE
+MR2images.64.572.218.916.1
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcsrdiff.man b/appsrc/dcfile/dcsrdiff.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcsrdiff.script b/appsrc/dcfile/dcsrdiff.script
new file mode 100755
index 0000000..b05625c
--- /dev/null
+++ b/appsrc/dcfile/dcsrdiff.script
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# compare the dumps of two dicom SR files
+
+if [ $# = 3 ]
+then
+	option="$1"
+	shift
+elif [ $# != 2 ]
+then
+	echo "usage: `basename $0` [-identifier] file1 file2"
+	exit 1
+fi
+
+TMPFILE1=/tmp/`basename $0`.$$.tmp1
+TMPFILE2=/tmp/`basename $0`.$$.tmp2
+
+dcsrdump ${option} "$1" >"$TMPFILE1" 2>&1
+dcsrdump ${option} "$2" >"$TMPFILE2" 2>&1
+diff "$TMPFILE1" "$TMPFILE2"
+
+rm "$TMPFILE1" "$TMPFILE2"
+
+exit 0
diff --git a/appsrc/dcfile/dcsrdump.cc b/appsrc/dcfile/dcsrdump.cc
new file mode 100644
index 0000000..7b2d24d
--- /dev/null
+++ b/appsrc/dcfile/dcsrdump.cc
@@ -0,0 +1,518 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcsrdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "attrval.h"
+
+static inline void
+indent(TextOutputStream &log,unsigned depth,bool showtabs,bool showgt) {
+	unsigned d=depth;
+	if (showtabs) while (d--) log << "\t";
+	d=depth;
+	if (showgt) while (d--) log << ">";
+}
+
+static void
+logStringValueOfAttribute(Attribute *a,TextOutputStream &log) {
+	if (a) {
+		char *v = AttributeValue(a);
+		if (v) {
+			log << v;
+			delete[] v;
+		}
+	}
+}
+
+static void
+processCodeSequenceItem(AttributeList *list,TextOutputStream &log) {
+	log << "(";
+	logStringValueOfAttribute((*list)[TagFromName(CodeValue)],log);
+	log << ",";
+	logStringValueOfAttribute((*list)[TagFromName(CodingSchemeDesignator)],log);
+	log << "," << "\"" ;
+	logStringValueOfAttribute((*list)[TagFromName(CodeMeaning)],log);
+	log << "\")";
+}
+
+static void
+processCodeSequence(Attribute *aCodeSequence,const char *label,TextOutputStream &log) {
+	log << label;
+
+	if (aCodeSequence) {
+		int nItems = 0;
+		AttributeList ** vItems = 0;
+		nItems=aCodeSequence->getLists(&vItems);
+		Assert(nItems==0 || vItems);
+
+		int i;
+		AttributeList **iptr;
+
+		for (i=0,iptr=vItems; i<nItems; ++i,++iptr) {
+			AttributeList *ptr = *iptr;
+			Assert(ptr);
+			if (i > 0) log << ", ";
+			processCodeSequenceItem(ptr,log);
+		}
+	}
+}
+
+static void
+processMeasuredValueSequence(Attribute *aMeasuredValueSequence,const char *label,TextOutputStream &log) {
+	log << label;
+
+	if (aMeasuredValueSequence) {
+		int nItems = 0;
+		AttributeList ** vItems = 0;
+		nItems=aMeasuredValueSequence->getLists(&vItems);
+		Assert(nItems==0 || vItems);
+
+		int i;
+		AttributeList **iptr;
+
+		for (i=0,iptr=vItems; i<nItems; ++i,++iptr) {
+			AttributeList *ptr = *iptr;
+			Assert(ptr);
+			if (i > 0) log << ", ";
+
+			logStringValueOfAttribute((*ptr)[TagFromName(NumericValue)],log);
+			
+			Attribute *aFloatingPointValue = (*ptr)[TagFromName(FloatingPointValue)];
+			if (aFloatingPointValue) {
+				log << " {";
+				double v;
+				if (aFloatingPointValue->getValue(0,v)) log << setprecision(16) << v;	// this is setprecision(std::numeric_limits<double>::digits10 + 1)
+				log << "}";
+			}
+
+			Attribute *aRationalNumeratorValue = (*ptr)[TagFromName(RationalNumeratorValue)];
+			Attribute *aRationalDenominatorValue = (*ptr)[TagFromName(RationalDenominatorValue)];
+			if (aRationalNumeratorValue || aRationalDenominatorValue) {
+				log << " {";
+				double v;
+				if (aRationalNumeratorValue && aRationalNumeratorValue->getValue(0,v)) log << v;
+				log << "/";
+				if (aRationalDenominatorValue && aRationalDenominatorValue->getValue(0,v)) log << v;
+				log << "}";
+			}
+
+			Attribute *aMeasurementUnitsCodeSequence=(*ptr)[TagFromName(MeasurementUnitsCodeSequence)];
+			if (aMeasurementUnitsCodeSequence) {
+				log << " ";
+				processCodeSequence(aMeasurementUnitsCodeSequence,"",log);
+			}
+		}
+	}
+}
+
+static void
+processReferencedSOPSequence(Attribute *aReferencedSOPSequence,const char *label,TextOutputStream &log) {
+	log << label;
+
+	if (aReferencedSOPSequence) {
+		int nItems = 0;
+		AttributeList ** vItems = 0;
+		nItems=aReferencedSOPSequence->getLists(&vItems);
+		Assert(nItems==0 || vItems);
+
+		int i;
+		AttributeList **iptr;
+
+		for (i=0,iptr=vItems; i<nItems; ++i,++iptr) {
+			AttributeList *ptr = *iptr;
+			Assert(ptr);
+			if (i > 0) log << ", ";
+
+			log << "(";
+			logStringValueOfAttribute((*ptr)[TagFromName(ReferencedSOPClassUID)],log);
+			log << ",";
+			logStringValueOfAttribute((*ptr)[TagFromName(ReferencedSOPInstanceUID)],log);
+			log << ")";
+			
+			// the following items are specific to the usage in IMAGE content items (and hence should do nothing in others) ...
+			
+			Attribute *aReferencedFrameNumber=(*ptr)[TagFromName(ReferencedFrameNumber)];
+			if (aReferencedFrameNumber) {
+				log << " [Frame ";
+				logStringValueOfAttribute(aReferencedFrameNumber,log);
+				log << "]";
+			}
+			
+			Attribute *aReferencedSegmentNumber=(*ptr)[TagFromName(ReferencedSegmentNumber)];
+			if (aReferencedSegmentNumber) {
+				log << " [Segment ";
+				//logStringValueOfAttribute(aReferencedSegmentNumber,log);
+				Uint16 value;
+				if (aReferencedSegmentNumber->getValue((Uint16)0,value)) {
+					log << value;
+				}
+				log << "]";
+			}
+
+			Attribute *aPresentationStateReferencedSOPSequence=(*ptr)[TagFromName(ReferencedSOPSequence)];
+			if (aPresentationStateReferencedSOPSequence) {
+				int nItems = 0;
+				AttributeList ** vItems = 0;
+				nItems=aPresentationStateReferencedSOPSequence->getLists(&vItems);
+				Assert(nItems==0 || vItems);
+				Assert(nItems==0 || vItems);
+
+				int i;
+				AttributeList **iptr;
+
+				for (i=0,iptr=vItems; i<nItems; ++i,++iptr) {
+					AttributeList *ptr = *iptr;
+					Assert(ptr);
+					if (i > 0) log << ",";
+
+					log << " (PS ";
+					logStringValueOfAttribute((*ptr)[TagFromName(ReferencedSOPClassUID)],log);
+					log << ",";
+					logStringValueOfAttribute((*ptr)[TagFromName(ReferencedSOPInstanceUID)],log);
+					log << ")";
+				}
+			}
+
+			Attribute *aReferencedRealWorldValueMappingInstanceSequence=(*ptr)[TagFromName(ReferencedRealWorldValueMappingInstanceSequence)];
+			if (aReferencedRealWorldValueMappingInstanceSequence) {
+				int nItems = 0;
+				AttributeList ** vItems = 0;
+				nItems=aReferencedRealWorldValueMappingInstanceSequence->getLists(&vItems);
+				Assert(nItems==0 || vItems);
+				Assert(nItems==0 || vItems);
+
+				int i;
+				AttributeList **iptr;
+
+				for (i=0,iptr=vItems; i<nItems; ++i,++iptr) {
+					AttributeList *ptr = *iptr;
+					Assert(ptr);
+					if (i > 0) log << ",";
+
+					log << " (RWV ";
+					logStringValueOfAttribute((*ptr)[TagFromName(ReferencedSOPClassUID)],log);
+					log << ",";
+					logStringValueOfAttribute((*ptr)[TagFromName(ReferencedSOPInstanceUID)],log);
+					log << ")";
+				}
+			}
+			
+		}
+	}
+}
+
+static void
+processScoordContentItem(AttributeList *list,TextOutputStream &log) {
+	logStringValueOfAttribute((*list)[TagFromName(GraphicType)],log);
+	log << " {";
+	//log.unsetf(ios_base::fixed,ios_base::scientific);	// :) should really explicitly establish the default floating point notation, in which the precision field specifies the maximum number of meaningful digits to display in total counting both those before and those after the decimal point
+	log << setprecision (15);							// this choice of precision is based on the fact that a DS VR is 16 characters, including the decimal point; this is excessive in that the FL VR (32 bit IEEE float) significand has a precision of 24 binary bits (about 7 decimal digits)
+	Attribute *aGraphicData=(*list)[TagFromName(GraphicData)];
+	int nGraphicData = aGraphicData ? aGraphicData->getVM() : 0;
+	int i;
+	for (i=0; i<nGraphicData; ++ i) {
+		if (i > 0) log << ",";
+		float v;
+		if (aGraphicData->getValue(i,v)) log << v;
+	}
+	log << "}";
+}
+
+static void
+processScoord3DContentItem(AttributeList *list,TextOutputStream &log) {
+	logStringValueOfAttribute((*list)[TagFromName(GraphicType)],log);
+	log << " {";
+	//log.unsetf(ios_base::fixed,ios_base::scientific);	// :) should really explicitly establish the default floating point notation, in which the precision field specifies the maximum number of meaningful digits to display in total counting both those before and those after the decimal point
+	log << setprecision (15);							// this choice of precision is based on the fact that a DS VR is 16 characters, including the decimal point; this is excessive in that the FL VR (32 bit IEEE float) significand has a precision of 24 binary bits (about 7 decimal digits)
+	Attribute *aGraphicData=(*list)[TagFromName(GraphicData)];
+	int nGraphicData = aGraphicData ? aGraphicData->getVM() : 0;
+	int i;
+	for (i=0; i<nGraphicData; ++ i) {
+		if (i > 0) log << ",";
+		float v;
+		if (aGraphicData->getValue(i,v)) log << v;
+	}
+	log << "}";
+	log << " (FoR ";
+	logStringValueOfAttribute((*list)[TagFromName(ReferencedFrameOfReferenceUID)],log);
+	log << ")";
+}
+
+static void
+processValueOfContentItem(AttributeList *list,TextOutputStream &log) {
+	Attribute *aValueType=(*list)[TagFromName(ValueType)];
+	char *vValueType=AttributeValue(aValueType);
+	if (vValueType) {
+		if      (strcmp(vValueType,"NUM") == 0) {
+			log << " = ";
+			processMeasuredValueSequence((*list)[TagFromName(MeasuredValueSequence)],"",log);
+			Attribute *aNumericValueQualifierCodeSequence=(*list)[TagFromName(NumericValueQualifierCodeSequence)];
+			if (aNumericValueQualifierCodeSequence) {
+				log << " ";
+				processCodeSequence(aNumericValueQualifierCodeSequence,"",log);
+			}
+		}
+		else if (strcmp(vValueType,"TEXT") == 0) {
+			log << " = \"";
+			logStringValueOfAttribute((*list)[TagFromName(TextValue)],log);
+			log << "\"";
+		}
+		else if (strcmp(vValueType,"CODE") == 0) {
+			log << " = ";
+			processCodeSequence((*list)[TagFromName(ConceptCodeSequence)],"",log);
+		}
+		else if (strcmp(vValueType,"DATE") == 0) {
+			log << " = \"";
+			logStringValueOfAttribute((*list)[TagFromName(Date)],log);
+			log << "\"";
+		}
+		else if (strcmp(vValueType,"TIME") == 0) {
+			log << " = \"";
+			logStringValueOfAttribute((*list)[TagFromName(Time)],log);
+			log << "\"";
+		}
+		else if (strcmp(vValueType,"DATETIME") == 0) {
+			log << " = \"";
+			logStringValueOfAttribute((*list)[TagFromName(DateTime)],log);
+			log << "\"";
+		}
+		else if (strcmp(vValueType,"PNAME") == 0) {
+			log << " = \"";
+			logStringValueOfAttribute((*list)[TagFromName(PersonName)],log);
+			log << "\"";
+		}
+		else if (strcmp(vValueType,"UIDREF") == 0) {
+			log << " = \"";
+			logStringValueOfAttribute((*list)[TagFromName(UID)],log);
+			log << "\"";
+		}
+		else if (strcmp(vValueType,"IMAGE") == 0) {
+			log << " = ";
+			processReferencedSOPSequence((*list)[TagFromName(ReferencedSOPSequence)],"",log);
+		}
+		else if (strcmp(vValueType,"WAVEFORM") == 0) {
+			processReferencedSOPSequence((*list)[TagFromName(ReferencedSOPSequence)],"",log);
+		}
+		else if (strcmp(vValueType,"SCOORD") == 0) {
+			log << " = ";
+			processScoordContentItem(list,log);
+		}
+		else if (strcmp(vValueType,"SCOORD3D") == 0) {
+			log << " = ";
+			processScoord3DContentItem(list,log);
+		}
+		else if (strcmp(vValueType,"TCOORD") == 0) {
+		}
+		else if (strcmp(vValueType,"COMPOSITE") == 0) {
+			processReferencedSOPSequence((*list)[TagFromName(ReferencedSOPSequence)],"",log);
+		}
+		else if (strcmp(vValueType,"CONTAINER") == 0) {
+			log << " [";
+			logStringValueOfAttribute((*list)[TagFromName(ContinuityOfContent)],log);
+			log << "]";
+			Attribute *aContentTemplateSequence = (*list)[TagFromName(ContentTemplateSequence)];
+			if (aContentTemplateSequence) {
+				AttributeList ** vItems = 0;
+				int nItems=aContentTemplateSequence->getLists(&vItems);
+				if (nItems > 0 && vItems) {
+					AttributeList *itemList = vItems[0];
+					Assert(itemList);
+					log << " (";
+					logStringValueOfAttribute((*itemList)[TagFromName(MappingResource)],log);
+					log << ",";
+					logStringValueOfAttribute((*itemList)[TagFromName(TemplateIdentifier)],log);
+					log << ")";
+				}
+			}
+		}
+		else {
+			log << " **** Unrecognized Value Type ****";
+		}
+
+		delete[] vValueType;
+	}
+}
+
+static void
+logReferencedContentItemIdentifier(Attribute *a,TextOutputStream &log) {
+	if (a) {
+		Uint16 vm = a->getVM();
+		if (vm > 0) {
+			const char *prefix = NULL;
+			for (Uint16 i=0; i<vm; ++i) {
+				if (prefix) {
+					log << prefix;
+				}
+				char *v;
+				a->getValue(i,v);
+				log << v;
+				delete[] v;
+				prefix=".";
+			}
+		}
+	}
+}
+
+static bool
+processContentItem(AttributeList *list,TextOutputStream &log,bool verbose,bool veryverbose,unsigned depth,const char *identifierstring)   {
+
+	bool success=true;
+
+	Attribute *             aObservationDateTime=(*list)[TagFromName(ObservationDateTime)];
+	Attribute *                  aObservationUID=(*list)[TagFromName(ObservationUID)];
+	Attribute *                aRelationshipType=(*list)[TagFromName(RelationshipType)];
+	Attribute *                 aContentSequence=(*list)[TagFromName(ContentSequence)];
+	Attribute *         aConceptNameCodeSequence=(*list)[TagFromName(ConceptNameCodeSequence)];
+	Attribute *                       aValueType=(*list)[TagFromName(ValueType)];
+	Attribute * aReferencedContentItemIdentifier=(*list)[TagFromName(ReferencedContentItemIdentifier)];
+   
+	indent(log,depth,true,true);
+	if (identifierstring) {
+		log << identifierstring << ": ";
+	}
+	
+	if (aReferencedContentItemIdentifier) {
+		log << "R-";
+	}
+	logStringValueOfAttribute(aRelationshipType,log);
+	log << ": ";
+
+	if (aReferencedContentItemIdentifier) {
+		logReferencedContentItemIdentifier(aReferencedContentItemIdentifier,log);
+	}
+	else {
+		logStringValueOfAttribute(aValueType,log);
+		log << ": ";
+
+		if (aConceptNameCodeSequence) {
+			processCodeSequence(aConceptNameCodeSequence,"",log);
+			log << " ";
+		}
+
+		processValueOfContentItem(list,log);
+	}
+	
+	if (aObservationDateTime || aObservationUID) {
+		log << " (";
+		if (aObservationDateTime) {
+			logStringValueOfAttribute(aObservationDateTime,log);
+		}
+		log << ",";
+		if (aObservationUID) {
+			logStringValueOfAttribute(aObservationUID,log);
+		}
+		log << ")";
+	}
+	
+	log << endl;
+
+	if (aContentSequence) {
+		int nContentItems = 0;
+		AttributeList ** vContentItems = 0;
+		nContentItems=aContentSequence->getLists(&vContentItems);
+		Assert(nContentItems==0 || vContentItems);
+
+		int i;
+		AttributeList **iptr;
+
+		for (i=0,iptr=vContentItems; i<nContentItems; ++i,++iptr) {
+			AttributeList *ptr = *iptr;
+			Assert(ptr);
+			char *childidentifierstring = NULL;
+			if (identifierstring) {
+				ostrstream childidentifierstream;
+				childidentifierstream << identifierstring << "." << (i+1) << ends;
+				childidentifierstring = childidentifierstream.str();
+			}
+			success&=processContentItem(ptr,log,verbose,veryverbose,depth+1,childidentifierstring);
+			if (childidentifierstring) {
+				delete [] childidentifierstring;
+			}
+		}
+	}
+	return success;
+}
+
+
+static bool
+parseStructuredReport(ManagedAttributeList &list,TextOutputStream &log,bool verbose,bool veryverbose,bool showidentifier)
+{
+	bool result = processContentItem(&list,log,verbose,veryverbose,0,showidentifier ? "1" : NULL);
+	return result;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool verbose=options.get("verbose") || options.get("v") || veryverbose;
+	bool showfilename=options.get("filename");
+	bool showidentifier=options.get("identifier");
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose]"
+			<< " [-filename]"
+			<< " [-identifier]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (veryverbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,veryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	//if (veryverbose) log << "******** As read ... ********" << endl; 
+	//log << list;
+	//list.write(log,veryverbose);
+
+	{
+		bool parseSuccess = parseStructuredReport(list,log,verbose,veryverbose,showidentifier);		// parse regardless of read success or failure
+		success=success&&parseSuccess;
+	}
+
+	return success ? 0 : 1;
+}
+
+
+
+
diff --git a/appsrc/dcfile/dcsrdump.man b/appsrc/dcfile/dcsrdump.man
new file mode 100755
index 0000000..e17c8e5
--- /dev/null
+++ b/appsrc/dcfile/dcsrdump.man
@@ -0,0 +1,72 @@
+.TH DCSRDUMP 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Describe DICOM SR content"
+.SH NAME
+dcsrdump \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Describe DICOM SR content
+.SH SYNOPSIS
+.HP 10
+.B dcsrdump
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-vv|veryverbose
+]
+[
+.B \-filename
+]
+[
+.B \-identifier
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcsrdump
+reads the named dicom structured report (SR) input file and describes the information contained.
+.SH OPTIONS
+The attribute values, description and verbose output go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Describe the parsing process; does not actually do anything at present.
+.RE
+.TP
+.B \-veryverbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents of the DICOM dataset while reading.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.TP
+.B \-identifier
+.RS
+Preceed each content item with the dot delimited numeric identifier of the content item (as used in references).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcsrdump -identifier basictextsr.dcm 
+.RE
+1: : CONTAINER: (18748-4,LN,"Diagnostic Imaging Report")  [SEPARATE] (DCMR,2000)
+.RE
+	>1.1: CONTAINS: CONTAINER: (121070,DCM,"Findings")  [SEPARATE]
+.RE
+		>>1.1.1: CONTAINS: TEXT: (121071,DCM,"Finding")  = "stuff"
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcsrmrg.cc b/appsrc/dcfile/dcsrmrg.cc
new file mode 100644
index 0000000..1c131b3
--- /dev/null
+++ b/appsrc/dcfile/dcsrmrg.cc
@@ -0,0 +1,423 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcsrmrg.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrseq.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static ElementDictionary staticDictionary;
+
+// Define a funky derived OX class to be able to writeBase() and not activateSource() ...
+
+// Various functions to check and match values ...
+
+static bool
+errorIfStringValuesDontMatch(const char *firstValue,
+	const char *newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	Assert(firstValue);
+	Assert(newValue);
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (strcmp(firstValue,newValue) != 0) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << (newValue ? newValue : "")
+		    << "> previously seen as  <"
+		    << (firstValue ? firstValue : "")
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static bool
+errorIfIntegerValuesDontMatch(Uint16 firstValue,
+	Uint16 newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	//Assert(firstValue);	// May legitimately be zero ?
+	//Assert(newValue);	// May legitimately be zero ?
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (firstValue != newValue) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << newValue
+		    << "> previously seen as  <"
+		    << firstValue
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static bool
+errorIfFloatValuesDontMatch(double firstValue,
+	double newValue,
+	const char *valueDescription,
+	const char *filename,TextOutputStream &log)
+{
+	//Assert(firstValue);	// May legitimately be zero ?
+	//Assert(newValue);	// May legitimately be zero ?
+	Assert(valueDescription);
+	Assert(filename);
+
+	bool result;
+	if (firstValue != newValue) {
+		log << filename << ": "<< "Error - Different " << valueDescription
+		    << " got  <"
+		    << newValue
+		    << "> previously seen as  <"
+		    << firstValue
+		    << "> - using original value"
+		    << endl;
+		result=false;
+	}
+	else {
+		result=true;
+	}
+	return result;
+}
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static const char *
+getStringValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	const char *value=AttributeValue(a);	//SC 2.0.1 didn't like it as ? arg :(
+	return a ? value : "";
+}
+
+static Uint16
+getIntegerValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	Uint16 value=AttributeValue(a);
+	return value;
+}
+
+static double
+getFloatValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	double value=AttributeValue(a);
+	return value;
+}
+
+static const char *
+getAndCheckStringMatchElseError(bool first,const char * &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	const char *value=getStringValueElseError(list,tag,label,filename,log);
+	Assert(value);
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfStringValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+static Uint16
+getAndCheckIntegerMatchElseError(bool first,Uint16 &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Uint16 value=getIntegerValueElseError(list,tag,label,filename,log);
+	//Assert(value);	// May legitimately be zero ?
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfIntegerValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+static double
+getAndCheckFloatMatchElseError(bool first,double &requiredValue,AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	double value=getFloatValueElseError(list,tag,label,filename,log);
+	//Assert(value);	// May legitimately be zero ?
+
+	if (first) {		// First image file
+		requiredValue=value;
+	}
+	else {
+		errorIfFloatValuesDontMatch(requiredValue,value,label,filename,log);
+	}
+
+	return value;
+}
+
+
+// structure to store filenames
+
+struct filenameentry {
+	const char *filename;
+	AttributeList *list;
+};
+
+static void
+dumpfilenamestable(filenameentry *table,int n,const char *name,ostream &log)
+{
+	int i;
+	for (i=0; i<n; ++i) {
+		log << name << "[" << i << "] = " << table[i].filename << endl;
+	}
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool veryverbose=options.get("veryverbose") || options.get("vv");
+	bool veryveryverbose=options.get("veryveryverbose") || options.get("vvv");
+	if (veryveryverbose) veryverbose=true;
+	if (veryverbose) verbose=true;
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	int numberofinputfiles=!options;
+
+	struct filenameentry *filenamestable = new filenameentry [numberofinputfiles];
+	Assert(filenamestable);
+	struct filenameentry *ptr = filenamestable;
+
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		ptr->filename=filename;
+		ptr->list=0;
+		++ptr;
+	}
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose|-vv|-veryverbose|-vvv|-veryveryverbose]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	// attributes required to have constant values for all SR files ...
+
+	const char *requiredPatientID;
+	const char *requiredStudyInstanceUID;
+	const char *requiredSeriesInstanceUID;
+	const char *requiredSOPClassUID;
+	const char *requiredPatientName;
+	const char *requiredStudyID;
+	Uint16 requiredSeriesNumber;
+	const char *requiredModality;
+
+	ManagedAttributeList newlist;
+	SequenceAttribute *aFirstContentSequence;
+
+	// iterate through image files to extract and check attributes values ...
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		// open and read each image file ...
+
+		const char *filename=filenamestable[i].filename;
+		Assert(filename);
+		if (veryverbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			success=false;
+			break;
+		}
+
+		DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList *list = new ManagedAttributeList();
+		Assert(list);
+		filenamestable[i].list=list;
+
+		if (veryveryverbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+		list->read(din,&log,veryveryverbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+		if (!list->good()) {
+			log << list->errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			break;
+		}
+
+		// extract and check that attributes values are consistent for all image files ...
+
+		const char *patientID=getAndCheckStringMatchElseError(i == 0,requiredPatientID,*list,
+			TagFromName(PatientID),"Patient ID",filename,log);
+
+		const char *patientName=getAndCheckStringMatchElseError(i == 0,requiredPatientName,*list,
+			TagFromName(PatientName),"Patient Name",filename,log);
+
+		const char *studyInstanceUID=getAndCheckStringMatchElseError(i == 0,requiredStudyInstanceUID,*list,
+			TagFromName(StudyInstanceUID),"Study Instance UID",filename,log);
+
+		const char *studyID=getAndCheckStringMatchElseError(i == 0,requiredStudyID,*list,
+			TagFromName(StudyID),"Study ID",filename,log);
+
+		const char *seriesInstanceUID=getAndCheckStringMatchElseError(i == 0,requiredSeriesInstanceUID,*list,
+			TagFromName(SeriesInstanceUID),"Series Instance UID",filename,log);
+
+		const char *SOPClassUID=getAndCheckStringMatchElseError(i == 0,requiredSOPClassUID,*list,
+			TagFromName(SOPClassUID),"SOP Class UID",filename,log);
+
+		Uint16 seriesNumber=getAndCheckIntegerMatchElseError(i == 0,requiredSeriesNumber,*list,
+			TagFromName(SeriesNumber),"Series Number",filename,log);
+
+		const char *modality=getAndCheckStringMatchElseError(i == 0,requiredModality,*list,
+			TagFromName(Modality),"Modality",filename,log);
+
+		// for the first file, copy everything ...
+
+		if (i == 0) {
+			// delete old Instance Number and add new one with fixed value of 1 ...
+
+			(*list)-=TagFromName(InstanceNumber);
+			(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),Uint16(1));
+
+			// delete old SOP Instance UID ... usualManagedAttributeListWrite() adds new one ...
+
+			(*list)-=TagFromName(SOPInstanceUID);
+
+			// delete any Data Set Trailing Padding  ...
+
+			(*list)-=TagFromName(DataSetTrailingPadding);
+
+			aFirstContentSequence=(SequenceAttribute *)((*list)[TagFromName(ContentSequence)]);
+			Assert(aFirstContentSequence);
+
+			newlist+=(*list);
+		}
+		else {
+			SequenceAttribute *aContentSequence=(SequenceAttribute *)((*list)[TagFromName(ContentSequence)]); 
+			Assert(aContentSequence);
+			AttributeList **itemLists;
+			int nLists=aContentSequence->getLists(&itemLists);
+			int i;
+			for (i=0; i<nLists; ++i) {
+				AttributeList *itemList = itemLists[i];
+				Assert(itemList);
+				Assert(aFirstContentSequence);
+				(*aFirstContentSequence)+=itemList;
+			}
+		}
+
+		// clean up ... the DICOM input stream goes out of scope with each iteration of the loop
+
+		if (fstr) delete fstr;
+	}
+cerr << "About to write:" << endl;
+
+	if (!usualManagedAttributeListWrite(newlist,dout,dicom_output_options,log,veryverbose)) {
+		success=false;
+	}
+
+	if (numberofinputfiles && filenamestable) delete[] filenamestable;
+
+	return success ? 0 : 1;
+}
+
+	
+
diff --git a/appsrc/dcfile/dcsrmrg.man b/appsrc/dcfile/dcsrmrg.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcstats.cc b/appsrc/dcfile/dcstats.cc
new file mode 100644
index 0000000..c223d61
--- /dev/null
+++ b/appsrc/dcfile/dcstats.cc
@@ -0,0 +1,207 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcstats.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+static unsigned
+howManySignificantBits(Uint16 test)
+{
+	unsigned bits;
+	for (bits=0; test; test=test>>1,++bits);
+	return bits;
+}
+
+static bool
+dumpImageStatistics(ManagedAttributeList& list,TextOutputStream& log)
+{
+	bool success;
+
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	Uint16 vBitsStored=AttributeValue(aBitsStored);
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	Uint16 vPixelRepresentation=AttributeValue(aPixelRepresentation);
+	Attribute *aLargestImagePixelValue = list[TagFromName(LargestImagePixelValue)];
+	Uint16 vLargestImagePixelValue=AttributeValue(aLargestImagePixelValue);
+	Attribute *aSmallestImagePixelValue = list[TagFromName(SmallestImagePixelValue)];
+	Uint16 vSmallestImagePixelValue=AttributeValue(aSmallestImagePixelValue);
+
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << EMsgDC(MissingAttribute) << " - \"Rows\"" << endl;
+	Uint16 vRows=AttributeValue(aRows);
+
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << EMsgDC(MissingAttribute) << " - \"Columns\"" << endl;
+	Uint16 vColumns=AttributeValue(aColumns);
+
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	Uint16 vNumberOfFrames=AttributeValue(aNumberOfFrames,1);
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+	if (!aPixelData)
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+
+	if (!aPixelData || !aRows || !aColumns) {
+		success=false;
+	}
+	else {
+		SupplySourceFromAttribute sPixelData(aPixelData);
+		class SourceBase<Uint16> *source = sPixelData.getSource();
+		if (!source) {
+			log << EMsgDC(BadAttributeValue)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+		else {
+			Int16  signedminval=Int16_MAX;
+			Int16  signedmaxval=Int16_MIN;
+			Uint16 unsignedminval=Uint16_MAX;
+			Uint16 unsignedmaxval=0;
+			Int32  signedtotal=0;
+			Uint32 unsignedtotal=0;
+
+			unsigned row=0;
+			unsigned column=0;
+			while (row < vRows*vNumberOfFrames && source->read()) {
+				size_t n=source->getBufferCount();
+				Assert(n);
+				const Uint16 *buffer=source->getBuffer();
+				Assert(buffer);
+				while (n-- && row < vRows*vNumberOfFrames) {
+					Uint16 value=*buffer++;
+					if (Int16(value) < signedminval) signedminval=value;
+					if (Int16(value) > signedmaxval) signedmaxval=value;
+					if (value < unsignedminval) unsignedminval=value;
+					if (value > unsignedmaxval) unsignedmaxval=value;
+					unsignedtotal+=value;
+					signedtotal+=Int16(value);
+					if (++column >= vColumns) {
+						column=0;
+						++row;
+					}
+				}
+			}
+			//Assert(column == 0 && row == vRows*vNumberOfFrames);
+
+			log << "Signed minimum value = " << hex << Uint16(signedminval) << dec << "\t(" << Uint16(signedminval) << " dec)" << endl;
+			log << "Signed maximum value = " << hex << Uint16(signedmaxval) << dec << "\t(" << Uint16(signedmaxval) << " dec)" << endl;
+			log << "Unsigned minimum value = " << hex << unsignedminval << dec << "\t(" << unsignedminval << " dec)" << endl;
+			log << "Unsigned maximum value = " << hex << unsignedmaxval << dec << "\t(" << unsignedmaxval << " dec)" << endl;
+
+			Uint16 signedrange=Uint16(signedmaxval-signedminval);
+			Uint16 unsignedrange=unsignedmaxval-unsignedminval;
+
+			log << "Signed range = "   << hex << signedrange   << dec << "\t(" << signedrange   << " dec)" << endl;
+			log << "Unsigned range = " << hex << unsignedrange << dec << "\t(" << unsignedrange << " dec)" << endl;
+
+			Int16 signedmean=Int16(signedtotal/(vColumns*vRows*vNumberOfFrames));
+			Uint16 unsignedmean=Uint16(unsignedtotal/(vColumns*vRows*vNumberOfFrames));
+
+			double signedmeanpercentofrange=signedrange ? ((signedmean-signedminval)*100.0/signedrange) : 0;
+			double unsignedmeanpercentofrange=unsignedrange ? ((unsignedmean-unsignedminval)*100.0/unsignedrange) : 0;
+
+			log << "Signed mean = "   << hex << Uint16(signedmean) << dec << "\t(" << Uint16(signedmean) << " dec)" << "\t(" << signedmeanpercentofrange   << "%)" << endl;
+			log << "Unsigned mean = " << hex << unsignedmean       << dec << "\t(" << unsignedmean       << " dec)" << "\t(" << unsignedmeanpercentofrange << "%)" << endl;
+
+			log << "Bits Stored = " << dec << vBitsStored << endl;
+			if (signedrange < unsignedrange) {
+				if (vPixelRepresentation == 0) {
+					log << WMsgDC(PixelRepresentationIncorrect)
+					    << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Signed)
+					    << endl;
+				}
+				log << "Significant positive bits = " << dec << howManySignificantBits(signedmaxval) << endl;
+				log << "Significant negative bits = " << dec << howManySignificantBits(-signedminval) << endl;
+				log << "Offset to make unsigned in hex is = " << hex << Uint16(-signedminval) << endl;
+				log << "Offset to make unsigned in dec is = " << dec << Uint16(-signedminval) << endl;
+			}
+			else if (signedrange > unsignedrange) {
+				if (vPixelRepresentation == 1) {
+					log << WMsgDC(PixelRepresentationIncorrect)
+					    << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Unsigned)
+					    << endl;
+				}
+				log << "Significant unsigned bits = " << dec << howManySignificantBits(unsignedmaxval) << endl;
+			}
+			else {
+				if (vPixelRepresentation == 1) {
+					log << WMsgDC(PixelRepresentationUnnecessary)
+					    << " - " << MMsgDC(CouldBe) << " " << MMsgDC(Unsigned)
+					    << endl;
+				}
+				log << "Significant unsigned bits = " << dec << howManySignificantBits(unsignedmaxval) << endl;
+			}
+			success=true;
+		}
+	}
+	return success;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool showfilename=options.get("filename");
+
+	dicom_input_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-filename]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	
+	if (showfilename) {
+		const char *filenameused = input_opener.getFilename();
+		cerr << "Filename: \"" << (filenameused && strlen(filenameused) > 0 ? filenameused : "-") << "\"" << endl;
+	}
+
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	else {
+		success=dumpImageStatistics(list,log);
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcstats.man b/appsrc/dcfile/dcstats.man
new file mode 100755
index 0000000..bd35590
--- /dev/null
+++ b/appsrc/dcfile/dcstats.man
@@ -0,0 +1,110 @@
+.TH DCSTATS 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM image statistics"
+.SH NAME
+dcstats \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM image statistics
+.SH SYNOPSIS
+.HP 10
+.B dcstats
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-filename
+]
+.so man1/optin.so
+.SH DESCRIPTION
+.LP
+.B dcstats
+reads the named dicom or acr-nema input file and describes the statistics
+of the image pixel data. The primary intent is to determine if the pixel
+representation is unsigned or signed (regardless of what other attributes
+may specify).
+.LP
+The description and verbose output go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-v|verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading and once read.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.TP
+.B \-filename
+.RS
+Show the name of the file supplied in the arguments; a hyphen will be reported if no filename was supplied.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcstats expmeta.dc3
+.RE
+Signed minimum value = 0x0      (0 dec)
+.RE
+Signed maximum value = 0x6e9    (1769 dec)
+.RE
+Unsigned minimum value = 0x0    (0 dec)
+.RE
+Unsigned maximum value = 0x6e9  (1769 dec)
+.RE
+Signed range = 0x6e9    (1769 dec)
+.RE
+Unsigned range = 0x6e9  (1769 dec)
+.RE
+.RE
+Signed mean = 0x158     (344 dec)       (19.446%)
+.RE
+Unsigned mean = 0x158   (344 dec)       (19.446%)
+.RE
+Bits Stored = 16
+.RE
+Significant unsigned bits = 11
+.RE
+\ 
+.RE
+% dcstats impnone.dc3
+.RE
+Signed minimum value = 0xfa24   (64036 dec)
+.RE
+Signed maximum value = 0x638    (1592 dec)
+.RE
+Unsigned minimum value = 0x0    (0 dec)
+.RE
+Unsigned maximum value = 0xffff (65535 dec)
+.RE
+Signed range = 0xc14    (3092 dec)
+.RE
+Unsigned range = 0xffff (65535 dec)
+.RE
+Signed mean = 0xfec2    (65218 dec)     (38.2277%)
+.RE
+Unsigned mean = 0x1cdd  (7389 dec)      (11.2749%)
+.RE
+Bits Stored = 16
+.RE
+Significant positive bits = 11
+.RE
+Significant negative bits = 11
+.RE
+Offset to make unsigned in hex is = 0x5dc
+.RE
+Offset to make unsigned in dec is = 1500
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dchist(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcsub.cc b/appsrc/dcfile/dcsub.cc
new file mode 100644
index 0000000..310a71b
--- /dev/null
+++ b/appsrc/dcfile/dcsub.cc
@@ -0,0 +1,291 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcsub.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "memsrc.h"
+
+static Int16 *
+createSubtractedImage(ManagedAttributeList& list1,ManagedAttributeList& list2,Uint16 &rows,Uint16 &columns,bool clamptozero,TextOutputStream& log)
+{
+	Int16 *result = 0;
+	bool success = true;
+
+	// first image ...
+
+	Attribute *aRows1 = list1[TagFromName(Rows)];
+	if (!aRows1)
+		log << EMsgDC(MissingAttribute) << " - \"Rows\"" << endl;
+	Uint16 vRows1=AttributeValue(aRows1);
+
+	Attribute *aColumns1 = list1[TagFromName(Columns)];
+	if (!aColumns1)
+		log << EMsgDC(MissingAttribute) << " - \"Columns\"" << endl;
+	Uint16 vColumns1=AttributeValue(aColumns1);
+
+	Attribute *aPixelData1 = list1[TagFromName(PixelData)];
+	if (!aPixelData1)
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+
+	// second image ...
+
+	Attribute *aRows2 = list2[TagFromName(Rows)];
+	if (!aRows2)
+		log << EMsgDC(MissingAttribute) << " - \"Rows\"" << endl;
+	Uint16 vRows2=AttributeValue(aRows2);
+
+	Attribute *aColumns2 = list2[TagFromName(Columns)];
+	if (!aColumns2)
+		log << EMsgDC(MissingAttribute) << " - \"Columns\"" << endl;
+	Uint16 vColumns2=AttributeValue(aColumns2);
+
+	Attribute *aPixelData2 = list2[TagFromName(PixelData)];
+	if (!aPixelData2)
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+
+	if (!aPixelData1 || !aRows1 || !aColumns1 || !aPixelData2 || !aRows2 || !aColumns2) {
+		success=false;
+	}
+	else {
+		if (vRows1 != vRows2) {
+			log << "Different number of Rows" << endl;
+			success=false;
+		}
+		rows=vRows1;
+		if (vColumns1 != vColumns2) {
+			log << "Different number of Rows" << endl;
+			success=false;
+		}
+		columns=vColumns1;
+	}
+
+	if (success) {
+		SupplySourceFromAttribute sPixelData1(aPixelData1);
+		class SourceBase<Uint16> *source1 = sPixelData1.getSource();
+		if (!source1) {
+			log << EMsgDC(BadAttributeValue)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+
+		SupplySourceFromAttribute sPixelData2(aPixelData2);
+		class SourceBase<Uint16> *source2 = sPixelData2.getSource();
+		if (!source2) {
+			log << EMsgDC(BadAttributeValue)
+			    << " - \"PixelData\""
+			    << endl;
+			success=false;
+		}
+
+		if (success) {
+			result = new Int16[rows*columns];
+			Assert(result);
+
+			Int16 *result_ptr=result;
+			unsigned row=0;
+			unsigned column=0;
+			size_t n1=0;
+			size_t n2=0;
+			const Uint16 *buffer1;
+			const Uint16 *buffer2;
+
+			while (row < rows) {
+				if (n1 <= 0) {
+					if (!source1->read()) {
+						log << "premature end of data 1" << endl;
+						success=false;
+						break;
+					}
+					n1=source1->getBufferCount();
+					buffer1=source1->getBuffer();
+				}
+				Assert(n1);
+				Assert(buffer1);
+
+				if (n2 <= 0) {
+					if (!source2->read()) {
+						log << "premature end of data 2" << endl;
+						success=false;
+						break;
+					}
+					n2=source2->getBufferCount();
+					buffer2=source2->getBuffer();
+				}
+				Assert(n1);
+				Assert(buffer1);
+
+				Uint16 symbol1=*buffer1++;
+				--n1;
+				Uint16 symbol2=*buffer2++;
+				--n2;
+
+				if (clamptozero) {
+					Int16 value=symbol2-symbol1;
+					if (value < 0) value=0;
+					*result_ptr++=value;
+				}
+				else {
+					*result_ptr++=symbol2-symbol1;
+				}
+
+				if (++column >= columns) {
+					column=0;
+					++row;
+				}
+			}
+
+			Assert(column == 0 && row == rows);
+
+			success=true;
+		}
+	}
+
+	return success ? result : 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	bool clamptozero=options.get("clamptozero");
+
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener1(
+		options,dicom_input_options.filename,cin);
+	DicomInputOpenerFromOptions input_opener2(
+		options,0,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener1.errors();
+	cerr << input_opener2.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener1.good()
+	 || !input_opener2.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-clamptozero]"
+			<< " [-ignorereaderrors]"
+			<< " "  << MMsgDC(InputFile)
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din1(*(istream *)input_opener1,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomInputStream din2(*(istream *)input_opener2,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	ManagedAttributeList list1;
+	ManagedAttributeList list2;
+
+	bool success=true;
+	TextOutputStream  log(cerr);
+	if (verbose) log << "******** While reading file 1 ... ********" << endl; 
+	list1.read(din1,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+	if (!list1.good()) {
+		if (!ignorereaderrors) {
+			log << list1.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+	if (verbose) log << "******** While reading file 2 ... ********" << endl; 
+	list2.read(din2,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags);
+
+	if (!list2.good()) {
+		if (!ignorereaderrors) {
+			log << list2.errors();
+			success=false;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+
+	if (success) {
+		Uint16 rows;
+		Uint16 columns;
+		Int16 *result=createSubtractedImage(list1,list2,rows,columns,clamptozero,log);
+
+		if (result) {
+			list1-=TagFromName(SOPInstanceUID);
+			list1-=TagFromName(SeriesInstanceUID);
+			list1-=TagFromName(StudyInstanceUID);
+
+			list1-=TagFromName(SeriesNumber);
+			list1+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+
+			// output of subtraction is signed
+
+			list1-=TagFromName(PixelRepresentation);
+			list1+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),1);
+	
+			list1-=TagFromName(PixelData);
+
+			Memory_PixelDataSource<Uint16> *pixeldatasrc = new Memory_PixelDataSource<Uint16>(rows,columns,(Uint16 *)result);
+			Assert(pixeldatasrc);
+
+			list1+=new OtherUnspecifiedLargeAttribute(
+				TagFromName(PixelData),
+				pixeldatasrc,
+				rows,
+				columns,
+				1,
+				1,
+				&transfersyntax,
+				0,16,16,15);
+
+			// Don't write list warnings yet ...
+			// done in usualManagedAttributeListWrite ...
+
+			if (!usualManagedAttributeListWrite(list1,dout,
+				dicom_output_options,log,verbose)) success=false;
+		}
+		else {
+			success=false;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcsub.man b/appsrc/dcfile/dcsub.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcswab.man b/appsrc/dcfile/dcswab.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcswab.script b/appsrc/dcfile/dcswab.script
new file mode 100755
index 0000000..65a095c
--- /dev/null
+++ b/appsrc/dcfile/dcswab.script
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# usage: dcswab infile outfile
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+ANCREATE=ancreate
+DCCP=dccp
+DCDUMP=dcdump
+DCTORAW=dctoraw
+
+$DCDUMP $1 2>&1 | grep '10) OX Pixel Data' | sed -e 's/$/ []/' | $ANCREATE -e > $TMPROOT.pixelhead
+$DCTORAW -quiet $1 $TMPROOT.raw
+dd if="$TMPROOT.raw" of="$TMPROOT.swab" conv=swab
+$DCCP $1 $TMPROOT.nopixels -d PixelData
+cat $TMPROOT.nopixels $TMPROOT.pixelhead $TMPROOT.swab > $2
+
+rm -f $TMPROOT.*
+
+exit 0
diff --git a/appsrc/dcfile/dctable.cc b/appsrc/dcfile/dctable.cc
new file mode 100644
index 0000000..ca71218
--- /dev/null
+++ b/appsrc/dcfile/dctable.cc
@@ -0,0 +1,323 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dctable.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+
+#include "attrmxls.h"
+#include "attrnew.h"
+#include "attrval.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "dcstream.h"
+#include "elmconst.h"
+
+static const char *options_output_key[] = {
+	"key",
+	"k",
+	0
+};
+
+// Same in dckey.cc
+
+static void dumpCodeSequenceAsString(SequenceAttribute *as,TextOutputStream &log) {
+	AttributeList **itemLists;
+	int nItems = as->getLists(&itemLists);
+	for (int i=0; i<nItems; ++i) {
+		AttributeList *thisItemList = itemLists[i];
+		if (thisItemList) {
+			Attribute *aCodeValue = (*thisItemList)[TagFromName(CodeValue)];
+			Attribute *aCodingSchemeDesignator = (*thisItemList)[TagFromName(CodingSchemeDesignator)];
+			Attribute *aCodeMeaning = (*thisItemList)[TagFromName(CodeMeaning)];
+			if (aCodeValue || aCodingSchemeDesignator || aCodeMeaning) {
+				const char *vCodeValue = AttributeValue(aCodeValue,"");
+				const char *vCodingSchemeDesignator = AttributeValue(aCodingSchemeDesignator,"");
+				const char *vCodeMeaning = AttributeValue(aCodeMeaning,"");
+				log << "('"
+				    << vCodeValue
+				    << "','"
+				    << vCodingSchemeDesignator
+				    << "','"
+				    << vCodeMeaning
+				    << "')"
+				;
+			}
+		}
+	}
+}
+
+// the list will have already been checked before calling; check only the sequences within the list ...
+static Attribute *
+findFirstInstanceOfAttributeNestedAnywhereInList(Tag tag,AttributeList& list) {
+//cerr << "findFirstInstanceOfAttributeNestedAnywhereInList(): Searching for Tag ("; writeZeroPaddedHexNumber(cerr,tag.getGroup(),4); cerr << ","; writeZeroPaddedHexNumber(cerr,tag.getElement(),4); cerr << ")" << endl;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+//cerr << "findFirstInstanceOfAttributeNestedAnywhereInList(): Checking Attribute ("; writeZeroPaddedHexNumber(cerr,a->getTag().getGroup(),4); cerr << ","; writeZeroPaddedHexNumber(cerr,a->getTag().getElement(),4); cerr << ")" << endl;
+		if (a->isSequence()) {
+//cerr << "findFirstInstanceOfAttributeNestedAnywhereInList(): Checking within Sequence ("; writeZeroPaddedHexNumber(cerr,a->getTag().getGroup(),4); cerr << ","; writeZeroPaddedHexNumber(cerr,a->getTag().getElement(),4); cerr << ")" << endl;
+			SequenceAttribute *as = (SequenceAttribute *)a;
+			AttributeList **itemLists;
+			int nItems = as->getLists(&itemLists);
+			for (int i=0; i<nItems; ++i) {
+				AttributeList *thisItemList = itemLists[i];
+				if (thisItemList) {
+					Attribute *aFound = (*thisItemList)[tag];
+					if (!aFound) {
+						 aFound = findFirstInstanceOfAttributeNestedAnywhereInList(tag,(*thisItemList));
+					}
+					if (aFound) {
+//cerr << "findFirstInstanceOfAttributeNestedAnywhereInList(): Found ("; writeZeroPaddedHexNumber(cerr,aFound->getTag().getGroup(),4); cerr << ","; writeZeroPaddedHexNumber(cerr,aFound->getTag().getElement(),4); cerr << ")" << endl;
+						return aFound;
+					}
+				}
+			}
+		}
+		++listi;
+	}
+	return NULL;
+}
+
+static void
+writeQuoteRemovedDecimalConvertedData(Attribute *a,TextOutputStream &stream)
+{
+	int n = a->getVM();
+	for (int i=0; i<n; ++i) {
+		if (i>0) {
+			stream << "\\";
+		}
+		char *string;
+		Uint32 l = strlen(string);
+		if (a->getValue((Uint16)i,string)) {
+			l = strlen(string);
+		}
+		else {
+			l = 0;
+		}
+		const char *p = string;
+		while (l--) {
+			char c = *p++;
+			if (c != '"') {
+				stream << c;
+			}
+		}
+	}
+}			
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	bool describe=options.get("describe");
+
+	bool nofilename=options.get("nofilename");
+	
+	bool recurseToFindIt=options.get("recurse") || options.get("r");
+	
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	
+	bool noembeddedquotes=options.get("noembeddedquotes") || options.get("decimal");
+
+	bool bad=false;
+
+	// identical to dckey.cc; should refactor this, perhaps as AttributeTag::read() ? :(
+	ElementDictionary optdict;
+	AttributeList *keylist=0;
+	const char *keyarg;
+	while (options.get(options_output_key,keyarg)) {
+		Assert(keyarg);
+		Tag tag;
+		if (!getAttributeTagFromStringHexForm(keyarg,tag)	// handle "-k (0xgggg,0xeeee)" case
+		 && !optdict.getTag(keyarg,tag)) {			// handle "-k keyword" case
+			bad=true;
+			cerr << "-" << options_output_key[0] << ": "
+			     << EMsgDC(UnrecognizedElement)
+			     << " - \"" << keyarg << "\""
+			     << endl;
+		}
+		else {
+			const char *vr=optdict.getValueRepresentation(tag);
+			if (!vr) vr="UN";
+			Attribute *a=newAttribute(vr,tag);
+			Assert(a);
+			if (!keylist) {
+				keylist=new AttributeList;
+				Assert(keylist);
+			}
+			(*keylist)+=a;
+		}
+	}
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	int numberofinputfiles=!options;
+	const char **listoffilenames = new const char * [numberofinputfiles];
+	const char **ptr = listoffilenames;
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		*ptr++=filename;
+	}
+
+	options.done();
+
+	cerr << dicom_input_options.errors();
+	cerr << options.errors();
+
+	if (!dicom_input_options.good()
+	 || !options.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< " [-ignorereaderrors]"
+			<< " [-describe]"
+			<< " [-nofilename]"
+			<< " [-noembeddedquotes|decimal]"
+			<< " [-key|k elementname|(0xgggg,0xeeee)]"
+			<< " [-recurse|r]"
+			<< " [-verbose|v]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		return 1;
+	}
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	TextOutputStream outstream(cout);
+
+	if (describe) {
+		bool addtab=false;
+		if (!nofilename) {
+			outstream << "Filename";
+			addtab=true;
+		}
+		AttributeListIterator listi(*keylist);
+		while (!listi) {
+			Attribute *ak=listi();
+			Assert(ak);
+			if (addtab) {
+				outstream << "\t";
+			}
+			addtab=true;
+			Tag tag=ak->getTag();
+			const char *desc=optdict.getDescription(tag);
+			if (desc) {
+				outstream << "\"" << desc << "\"";
+			}
+			else {
+				outstream << "(";
+				writeZeroPaddedHexNumber(outstream,tag.getGroup(),4);
+				outstream << ",";
+				writeZeroPaddedHexNumber(outstream,tag.getElement(),4);
+				outstream << ") " << flush;
+			}
+			++listi;
+		}
+		outstream << endl;
+	}
+
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		const char *filename=listoffilenames[i];
+		Assert(filename);
+		if (verbose) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			log << AMsgDC(FileReadOpenFailed);
+			if (filename) log <<" - \"" << filename << "\"";
+			success=false;
+			if (fstr) delete fstr;
+			break;
+		}
+
+		DicomInputStream din(*(istream *)fstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+
+		if (verbose) log << "******** While reading ... " << filename << " ... ********" << endl; 
+		list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << filename << ": " << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			if (!ignorereaderrors) {
+				if (fstr) delete fstr;
+				break;
+			}
+		}
+		{
+			bool addtab=false;
+			if (!nofilename) {
+				outstream << "\"" << filename << "\"";
+				addtab=true;
+			}
+			ElementDictionary *dict=list.getDictionary();
+			Assert(dict);
+			AttributeListIterator listi(*keylist);
+			while (!listi) {
+				Attribute *ak=listi();
+				Assert(ak);
+				if (addtab) {
+					outstream << "\t";
+				}
+				addtab=true;
+				Tag tag=ak->getTag();
+				Attribute *ad=list[tag];
+				if (!ad && recurseToFindIt) {
+					ad = findFirstInstanceOfAttributeNestedAnywhereInList(tag,list);
+				}
+				if (ad) {
+					outstream << "\"";
+					if (ad->isSequence()) {
+						SequenceAttribute *as = (SequenceAttribute *)ad;
+						dumpCodeSequenceAsString(as,outstream);
+					}
+					else {
+						if (noembeddedquotes) {
+							writeQuoteRemovedDecimalConvertedData(ad,outstream);
+						}
+						else {
+							ad->writeData(outstream);
+						}
+					}
+					outstream << "\"";
+				}
+				else {
+					outstream << "\"\"";
+				}
+				++listi;
+			}
+			outstream << endl;
+		}
+
+		if (fstr) delete fstr;
+	}
+
+	if (numberofinputfiles && listoffilenames) delete[] listoffilenames;
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dctable.man b/appsrc/dcfile/dctable.man
new file mode 100755
index 0000000..654e541
--- /dev/null
+++ b/appsrc/dcfile/dctable.man
@@ -0,0 +1,130 @@
+.TH DCTABLE 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Make tables of attribute values"
+.SH NAME
+dctable \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Make tables of attribute values
+.SH SYNOPSIS
+.HP 10
+.B dctable
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+[
+.B \-ignorereaderrors
+]
+[
+.B \-v|verbose
+]
+[
+.B \-r|recurse
+]
+[
+.B \-describe
+]
+[
+.B \-nofilename
+]
+[
+.B \-noembeddedquotes|decimal
+]
+[
+.B \-key|k " elementname|(0xgggg,0xeeee) ] ..."
+[
+.B \-input-nometa
+]
+[
+.B \-input-ts " uid"
+]
+[
+.B \-input-default
+]
+[
+.B \-input-byteorder|-input-endian " big|little"
+]
+[
+.B \-input-vr " implicit|explicit"
+]
+.SH DESCRIPTION
+.LP
+.B dctable
+reads the named dicom input files and creates a tab delimited table of
+the values of the selected attributes, with each value enclosed in double
+quotes.
+.LP
+Binary attributes are written in hexadecimal with a preceding
+"0x". Numeric string attributes are written in decimal.
+.LP
+The first column always contains the filenames.
+.LP
+A header is a added only if the -describe option is specified.
+.LP
+If a specified attribute is not present in a file, then it the corresponding
+entry in the table will be empty (i.e. two consecutive quotes" but this
+is not reported as an error.
+.SH OPTIONS
+The table of attribute values go to standard output, and the verbose
+output and errors go to standard error.
+.PP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-describe
+.RS
+Add a first line of output that is a header describing the attributes in each column.
+.RE
+.TP
+.B \-nofilename
+.RS
+Do not include the filename in the table.
+.RE
+.TP
+.B \-noembeddedquotes|decimal
+.RS
+Remove embedded quotes (") from within displayed values to allow them to be parsed consistenty later; also has the
+side effect of displaying numeric binary values as decimal rather than hexadecimal, hence the alternative option name.
+.RE
+.TP
+.B \-k|key " elementname|(0xgggg,0xeeee)"
+.RS
+Add a key to the list of attributes to be extracted. The attribute may also be specified
+as a hexadecimal pair of the form (0xgggg,0xeeee), which also allows private attributes to be fetched.
+.RE
+.TP
+.B \-r|recurse
+.RS
+If any attribute is not found in the top level dataset, recurse through sequence attribute items until
+the first instance is found. This is a depth-first traversal, i.e., all children of the first item of
+a sequence are searched before the sibling items.
+.RE
+.TP
+.B \-ignorereaderrors
+.RS
+Attempt to extract key values even if errors encountered whilst parsing DICOM file.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dctable -k Rows -k Columns
+.RE
+        -describe test.dc3
+.RE
+"Filename"	"Rows"	"Columns"
+.RE
+"test.dc3"	"0x0100"	"0x0100"
+.RE
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), dckey(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+Attempts to extract sequences or OB,OW attributes may fail nastily.
+.LP
+The order in which the attributes are extracted and written is not the same
+order as they are specified on the command line, and should not be depended
+on.
diff --git a/appsrc/dcfile/dctopdf.cc b/appsrc/dcfile/dctopdf.cc
new file mode 100644
index 0000000..ace634b
--- /dev/null
+++ b/appsrc/dcfile/dctopdf.cc
@@ -0,0 +1,102 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dctopdf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	OutputOptions		output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+	BinaryOutputStream bout(out,NoEndian);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	Attribute *apdfdata=list[TagFromName(EncapsulatedDocument)];
+	if (!apdfdata) {
+		log << EMsgDC(MissingAttribute) << " - \"EncapsulatedDocument\"" << endl;
+		success=false;
+	}
+	else if (!apdfdata->isOtherByteNonPixel()) {
+		log << EMsgDC(EncapsulatedDataIncorrectVR) << endl;
+		success=false;
+	}
+	else {
+		if (!quiet) {
+			log << "******** Parameters ... ********" << endl; 
+			ElementDictionary *dict=list.getDictionary();
+			Attribute *a;
+			a=list[TagFromName(MIMETypeOfEncapsulatedDocument)];
+			if (a) { a->write(log,dict); log << endl; }
+		}
+
+		apdfdata->writeData(bout);
+
+		if (!bout.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dctopdf.man b/appsrc/dcfile/dctopdf.man
new file mode 100644
index 0000000..386448c
--- /dev/null
+++ b/appsrc/dcfile/dctopdf.man
@@ -0,0 +1,49 @@
+.TH DCTOPDF 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Extract DICOM encapsulated PDF"
+.SH NAME
+dctopdf \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Extract DICOM encapsulated PDF
+.SH SYNOPSIS
+.HP 10
+.B dctopdf
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-quiet|silent
+]
+.so man1/optin.so
+.so man1/binout.so
+.SH DESCRIPTION
+.LP
+.B dctopdf
+reads the named dicom input file containing an encpasulated PDF file and stores it as a PDF file.
+.LP
+.SH OPTIONS
+The PDF output goes where it is specified or standard out.
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-quiet|silent
+.RS
+Suppress the normal description of encapsulated document parameters.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR pdftodc(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dctopgm8.cc b/appsrc/dcfile/dctopgm8.cc
new file mode 100644
index 0000000..9691d0b
--- /dev/null
+++ b/appsrc/dcfile/dctopgm8.cc
@@ -0,0 +1,1167 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dctopgm8.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+#include "transyn.h"
+
+	// gray is the real gray value in the image pixel data
+	// index is the gray value windowed to a range 0..ncells
+
+	// strategy is ...
+	//	allocate lut of gray to cell
+	//	request <= 244 cells
+	//	load those cells with a linear gray scale
+	//	fill graytocell lut with cell numbers
+	//	operator[] returns cell number given gray value
+
+class BufferedWindowedGrayImage {
+private:
+	Uint16 *bufferforfulldepthimage;
+
+	SupplySource *supplysource;
+
+	Uint16 columns;
+	Uint16 rows;
+	Uint16 frames;
+	Uint16 planes;
+	Uint16 bitsallocated;
+	Uint16 bitsstored;
+	Uint16 highbit;
+	bool issigned;
+
+	bool inverted;
+	bool needdefaultwindowsetting;
+	Uint16 mingray;
+	Uint16 maxgray;
+	Uint16 bottom;
+	Uint16 top;
+	Uint16 signxor;
+	char  *graytocell;
+	Uint32 ngrays;
+	Uint32 ncells;
+
+	class SourceBase<Uint16> *getSource(void)
+		{
+			Assert(supplysource);
+			return supplysource->getSource();
+		}
+
+	char operator[](Uint16 index)
+		{
+			Assert(index<ngrays);
+			Assert(graytocell);
+			return graytocell[index];
+		}
+
+	char mapPixel(const Uint16 src)
+		{
+			return operator[](src);
+		}
+
+	const char *getPixelMap(Uint32 &mapsize) const
+		{
+			Assert(graytocell);
+			mapsize=ncells;
+			return graytocell;
+		}
+
+	bool getBufferedFullDepthImage(void);
+
+public:
+	BufferedWindowedGrayImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		Uint16 vPixelRepresentation,bool invertedgrayscale)
+		{
+			bufferforfulldepthimage=0;
+
+			supplysource=s;
+			columns=vColumns;
+			rows=vRows;
+			frames=vNumberOfFrames;
+			planes=1;
+			bitsallocated=vBitsAllocated;
+			bitsstored=vBitsStored;
+			highbit=vHighBit;
+			issigned=vPixelRepresentation;
+			Assert(supplysource);
+			Assert(columns);
+			Assert(rows);
+			Assert(frames);
+			Assert(planes);
+			Assert(bitsallocated);
+			Assert(bitsstored);
+			Assert(highbit);
+
+			Assert(bitsstored);
+			inverted=invertedgrayscale;
+			mingray=0;
+			Uint32 mx=(Uint32(1)<<bitsstored)-1;
+			Assert(mx <= Uint16_MAX);
+			maxgray=Uint16(mx);
+			Assert(maxgray >= mingray);
+			ngrays=maxgray-mingray+1;
+
+			signxor=issigned ? 1<<(bitsstored-1) : 0;
+
+//cerr << "BufferedWindowedGrayImage::BufferedWindowedGrayImage" << "\n"
+//     << "\t invertedgrayscale=" << dec << invertedgrayscale << "\n"
+//     << "\t bitsstored=" << dec << bitsstored << "\n"
+//     << "\t issigned=" << dec << issigned << "\n"
+//     << "\t mingray=" << dec << mingray << "\n"
+//     << "\t mx=" << dec << mx << "\n"
+//     << "\t maxgray=" << dec << maxgray << "\n"
+//     << "\t ngrays=" << dec << ngrays << "\n"
+//     << "\t signxor(hex)=" << hex << signxor << dec << "\n"
+//     << endl;
+
+			graytocell=new char[ngrays];
+			Assert(graytocell);
+			ncells=0;
+			needdefaultwindowsetting=true;
+
+		}
+
+	~BufferedWindowedGrayImage()
+		{
+			if (bufferforfulldepthimage) delete[] bufferforfulldepthimage;
+
+			if (graytocell) delete[] graytocell;
+		}
+
+	bool getImageStatistics(Uint16 framecount,
+		Uint16 &minval,Uint16 &maxval);
+
+	void setOutputGrayLevelsWanted(unsigned nwanted)
+		{
+			ncells=nwanted;
+//cerr << "BufferedWindowedGrayImage::setOutputGrayLevelsWanted ngrays=" << dec << ncells << endl;
+		}
+
+	bool setWindowRange(Uint16 b,Uint16 t);
+	bool hasWindowCenterWidth(void)	{ return true; }
+	bool setWindowCenterWidth(Uint16 center,Uint16 width);
+	bool getWindowCenterWidth(Uint16 &center,Uint16 &width);
+
+	bool setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table);
+
+	bool getSigned(void)	{ return issigned; }
+	Uint16 getBits(void)	{ return bitsstored; }
+
+	bool write8BitIndexedPixels(ostream &out);
+};
+
+bool
+BufferedWindowedGrayImage::write8BitIndexedPixels(ostream &out)
+{
+//cerr << "BufferedWindowedGrayImage::write8BitIndexedPixels start" << endl;
+
+	if (!bufferforfulldepthimage) getBufferedFullDepthImage();
+	Uint16 *ptr=bufferforfulldepthimage;
+
+	unsigned row=0;
+	unsigned column=0;
+
+long count=0;
+	while (row < rows*frames) {
+		char c = mapPixel(*ptr++);
+		out.write(&c,1);
+count++;
+		if (++column >= columns) {
+			column=0;
+			++row;
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+//cerr << "BufferedWindowedGrayImage::write8BitIndexedPixels count = " << count << endl;
+//cerr << "BufferedWindowedGrayImage::write8BitIndexedPixels count-columns*rows*frames= " << count-columns*rows*frames << endl;
+//cerr << "BufferedWindowedGrayImage::write8BitIndexedPixels done" << endl;
+	return row >= rows*frames;	// read enough
+}
+
+bool
+BufferedWindowedGrayImage::getBufferedFullDepthImage(void)
+{
+//cerr << "BufferedWindowedGrayImage::getBufferedFullDepthImage start" << endl;
+
+//long count=0;
+	if (!bufferforfulldepthimage) {
+		Assert(rows);
+		Assert(columns);
+		Assert(planes==1);
+		Assert(frames);
+
+		class SourceBase<Uint16> *source = getSource();
+		if (!source) return false;
+
+		Assert(!bufferforfulldepthimage);
+		bufferforfulldepthimage=new Uint16[columns*rows*frames];
+		Assert(bufferforfulldepthimage);
+		Uint16 *ptr=bufferforfulldepthimage;
+		size_t n;
+		const Uint16 *buffer;
+		while (source->read()) {
+			n=source->getBufferCount();
+			//Assert(n);
+			buffer=source->getBuffer();
+			//Assert(buffer);
+			while (n--) {
+				*ptr++=*buffer++;
+//count++;
+			}
+		}
+	}
+	//return row >= rows*frames;	// read enough
+//cerr << "BufferedWindowedGrayImage::getBufferedFullDepthImage count = " << count << endl;
+//cerr << "BufferedWindowedGrayImage::getBufferedFullDepthImage count-columns*rows*frames= " << count-columns*rows*frames << endl;
+//cerr << "BufferedWindowedGrayImage::getBufferedFullDepthImage done" << endl;
+	return true;	// ignore premature eof
+}
+
+bool
+BufferedWindowedGrayImage::getImageStatistics(Uint16 framecount,
+		Uint16 &minval,Uint16 &maxval)
+{
+//cerr << "BufferedWindowedGrayImage::getImageStatistics start" << endl;
+	if (!bufferforfulldepthimage) getBufferedFullDepthImage();
+	Uint16 *ptr=bufferforfulldepthimage;
+
+	Int16  signedminval=Int16_MAX;
+	Int16  signedmaxval=Int16_MIN;
+	Uint16 unsignedminval=Uint16_MAX;
+	Uint16 unsignedmaxval=0;
+
+//cerr << "BufferedWindowedGrayImage::getImageStatistics start min=" << hex << minval << " max=" << hex << maxval << dec << endl;
+
+	unsigned row=0;
+	unsigned column=0;
+	while (row < rows*framecount) {
+		Uint16 value=*ptr++;
+		if (Int16(value) < signedminval) signedminval=value;
+		if (Int16(value) > signedmaxval) signedmaxval=value;
+		if (value < unsignedminval) unsignedminval=value;
+		if (value > unsignedmaxval) unsignedmaxval=value;
+		if (++column >= columns) {
+			column=0;
+			++row;
+		}
+	}
+	//Assert(column == 0 && row == rows*framecount);
+
+//cerr << "BufferedWindowedGrayImage::getImageStatistics signedminval=" << hex << Uint16(signedminval) << endl;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics signedmaxval=" << hex << Uint16(signedmaxval) << dec << endl;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics unsignedminval=" << hex << unsignedminval << endl;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics unsignedmaxval=" << hex << unsignedmaxval << dec << endl;
+
+	Uint16 signedrange=Uint16(signedmaxval-signedminval);
+	Uint16 unsignedrange=unsignedmaxval-unsignedminval;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics signedrange=" << hex << signedrange << dec << endl;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics unsignedrange=" << hex << unsignedrange << endl;
+	if (issigned) {
+		if (signedrange > unsignedrange) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Unsigned)
+			     << endl;
+			issigned=true;
+		}
+		minval=Uint16(signedminval);
+		maxval=Uint16(signedmaxval);
+	}
+	else {
+		if (signedrange < unsignedrange) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Signed)
+			     << endl;
+			issigned=false;
+		}
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+
+//cerr << "BufferedWindowedGrayImage::getImageStatistics minval before xoring=" << hex << minval << endl;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics maxval before xoring=" << hex << maxval << dec << endl;
+
+	// xor with high bit into unsigned space used to represent pixels ...
+
+	if (issigned) minval=minval^(1<<(bitsstored-1));
+	if (issigned) maxval=maxval^(1<<(bitsstored-1));
+
+//cerr << "BufferedWindowedGrayImage::getImageStatistics minval=" << hex << minval << endl;
+//cerr << "BufferedWindowedGrayImage::getImageStatistics maxval=" << hex << maxval << dec << endl;
+
+//cerr << "BufferedWindowedGrayImage::getImageStatistics done min=" << hex << minval << " max=" << hex << maxval << dec << endl;
+
+//cerr << "BufferedWindowedGrayImage::getImageStatistics done" << endl;
+	//return row >= rows*framecount;	// read enough
+	return true;	// ignore premature eof
+}
+
+bool
+BufferedWindowedGrayImage::setWindowRange(Uint16 b,Uint16 t)
+{
+	bottom=b;
+	top=t;
+
+//cerr << "BufferedWindowedGrayImage::setWindowRange"
+//     << " bottom=" << dec << bottom
+//     << " top=" << dec << top
+//     << endl;
+
+	Assert(bottom<=top);
+	Assert(bottom>=mingray);
+	Assert(top<=maxgray);
+	Assert(graytocell);
+
+	needdefaultwindowsetting=false;
+
+	unsigned long i;
+	for (i=0; i<bottom; ++i) {
+		graytocell[i^signxor]=(inverted ? (ncells-1) : 0);
+	}
+	for (i=bottom; i<=top; ++i) {
+		long index=((i-bottom)*ncells)/(top-bottom+1);
+		Assert(index>=0);
+		Assert(index<ncells);
+		Uint32 spv = i^signxor;
+		long possiblyInvertedIndex = (inverted ? (ncells-1-index) : index);
+		Assert(possiblyInvertedIndex>=0);
+		Assert(possiblyInvertedIndex<ncells);
+//cerr << "BufferedWindowedGrayImage::setWindowRange"
+//     << " mapping gray value=" << dec << i
+//     << " mapping stored as pixel value=" << dec << spv
+//     << " to index=" << dec << index
+//     << " used as possiblyInvertedIndex=" << dec << possiblyInvertedIndex
+//     << endl;
+		graytocell[spv]=possiblyInvertedIndex;
+		
+	}
+	for (i=top+1; i<ngrays; ++i) {
+		graytocell[i^signxor]=(inverted ? 0 : (ncells-1));
+	}
+	return true;
+}
+
+bool
+BufferedWindowedGrayImage::setWindowCenterWidth(Uint16 center,Uint16 width)
+{
+//cerr << "BufferedWindowedGrayImage::setImageCenterWidth"
+//     << " center=" << dec << center
+//     << " width=" << dec << width
+//     << endl;
+	long lbottom=(long)center-width/2;
+//cerr << "BufferedWindowedGrayImage::setImageCenterWidth"
+//     << " lbottom=" << dec << lbottom
+//     << endl;
+	if (lbottom < mingray) lbottom=mingray;
+	if (lbottom > maxgray) lbottom=maxgray;	 // just in case
+//cerr << "BufferedWindowedGrayImage::setImageCenterWidth"
+//     << " lbottom clamped to=" << dec << lbottom
+//     << endl;
+	long ltop=(long)center+width/2;
+//cerr << "BufferedWindowedGrayImage::setImageCenterWidth"
+//     << " ltop=" << dec << ltop
+//     << endl;
+	if (ltop > maxgray) ltop=maxgray;
+	if (ltop < mingray) ltop=mingray;	// just in case
+//cerr << "BufferedWindowedGrayImage::setImageCenterWidth"
+//     << " ltop clamped to=" << dec << ltop
+//     << endl;
+	Assert(lbottom<=Uint16_MAX);
+	Assert(ltop<=Uint16_MAX);
+	return setWindowRange(Uint16(lbottom),Uint16(ltop));
+}
+
+bool
+BufferedWindowedGrayImage::getWindowCenterWidth(Uint16 &center,Uint16 &width)
+{
+	long lcenter=(top+bottom)/2;
+	long lwidth=top-bottom;
+	Assert(lcenter<=Uint16_MAX);
+	Assert(lwidth<=Uint16_MAX);
+	center=Uint16(lcenter);
+	width=Uint16(lwidth);
+	return true;
+}
+
+
+bool
+BufferedWindowedGrayImage::setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table)
+{
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " first=" << dec << first
+//     << " number=" << dec << number
+//     << " depth=" << dec << depth
+//     << endl;
+
+	bottom=first;
+	Assert(number >= 1);
+	top=first+(number-1);
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " bottom=" << dec << bottom
+//     << " top=" << dec << top
+//     << endl;
+
+	if (bottom < mingray) bottom=mingray;
+	if (top > maxgray) top=maxgray;
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " clamped bottom=" << dec << bottom
+//     << " clamped top=" << dec << top
+//     << endl;
+
+	Assert(bottom<=top);
+	Assert(bottom>=mingray);
+	Assert(top<=maxgray);
+	Assert(graytocell);
+
+	// theoretically, LUT output range should be related to
+	// the depth (in the third LUT descriptor), however it is
+	// often sent as much less ... hence the check for the
+	// actual range here ...
+#ifdef USELUTDEPTHFORRANGE
+	unsigned long lutoutputrange=1lu<<depth;
+	Uint16 lutmin=0;
+#else
+	Uint16 lutmin=Uint16((1lu<<depth)-1);
+	Uint16 lutmax=0;
+
+	{
+		int i;
+		for (i=0; i<number; ++i) {
+			if (table[i] < lutmin) lutmin=table[i];
+			if (table[i] > lutmax) lutmax=table[i];
+		}
+	}
+	unsigned long lutoutputrange=lutmax-lutmin+1;
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " lutmax=" << dec << lutmax
+//     << endl;
+#endif
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " lutoutputrange=" << dec << lutoutputrange
+//     << " lutmin=" << dec << lutmin
+//     << endl;
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " ncells=" << dec << ncells
+//     << endl;
+
+	unsigned long i;
+
+	unsigned long bottomindex=((table[0]-lutmin)*ncells)/lutoutputrange;
+	Assert(bottomindex>=0);
+	Assert(bottomindex<ncells);
+	char bottomcell=inverted ? (ncells-bottomindex-1) : bottomindex;
+	for (i=0; i<=bottom; ++i) {
+		graytocell[i^signxor]=bottomcell;
+	}
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " bottomindex=" << dec << bottomindex
+//     << " bottomcell=" << dec << (unsigned)bottomcell
+//     << endl;
+
+	for (i=bottom+1; i<top; ++i) {
+		unsigned long lutoutput=table[i-bottom];
+		unsigned long index=((lutoutput-lutmin)*ncells)/lutoutputrange;
+		Assert(index>=0);
+		Assert(index<ncells);
+		graytocell[i^signxor]=inverted ? (ncells-index-1) : index;
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " i=" << dec << i
+//     << " i^signxor=" << dec << (i^signxor)
+//     << " lutoutput=" << dec << lutoutput
+//     << " index=" << dec << index
+//     << " inverted ? (ncells-index-1) : index=" << dec << (inverted ? (ncells-index-1) : index)
+//     << " cell=" << dec << (unsigned)(unsigned char)(inverted ? (ncells-index-1) : index)
+ //    << endl;
+
+	}
+
+	unsigned long topindex=((table[number-1]-lutmin)*ncells)/lutoutputrange;
+	Assert(topindex>=0);
+	Assert(topindex<ncells);
+	char topcell=inverted ? (ncells-topindex-1) : topindex;
+	for (i=top; i<ngrays; ++i) {
+		graytocell[i^signxor]=topcell;
+	}
+
+//cerr << "BufferedWindowedGrayImage::setVOILUT"
+//     << " topindex=" << dec << topindex
+//     << " topcell=" << dec << (unsigned)topcell
+//     << endl;
+
+	needdefaultwindowsetting=false;
+
+	return true;
+}
+
+// NB. The WindowCenterWidthTranslator converts an "internal" scale
+// of window center and width, ie. disregarding the intercept and slope
+// entirely and using the unsigned representation of what is in the
+// pixel data, to user visible width and center, in which case the sign,
+// slope and intercept are used to translate into "real world" values 
+
+class WindowCenterWidthTranslator {
+private:
+	long signxor;
+	long intercept;
+	long slopeby1024;
+public:
+	WindowCenterWidthTranslator(Uint16 bits,bool issigned,
+		double rescaleintercept,double rescaleslope);
+
+	~WindowCenterWidthTranslator() {}
+
+	Uint16 getStoredCenterFromDisplayedCenter(long l)
+		{
+			return Uint16((l-intercept)*1024/slopeby1024+signxor);
+		}
+	Uint16 getStoredWidthFromDisplayedWidth(long w)
+		{
+			return Uint16(w*1024/slopeby1024);
+		}
+	long getDisplayedCenterFromStoredCenter(long l)
+		{
+			return (l-signxor)*slopeby1024/1024+intercept;
+		}
+	long getDisplayedWidthFromStoredWidth(long w)
+		{
+			return w*slopeby1024/1024;
+		}
+};
+
+WindowCenterWidthTranslator::WindowCenterWidthTranslator(
+	Uint16 bits,bool issigned,
+	double rescaleintercept,double rescaleslope)
+{
+	signxor=issigned ? 1l<<(bits-1) : 0;
+	Assert(rescaleintercept<=LONG_MAX);
+	Assert(rescaleintercept>=LONG_MIN);
+	intercept=long(rescaleintercept);
+	Assert(rescaleslope<=LONG_MAX/1024);
+	Assert(rescaleslope>=LONG_MIN/1024);
+	slopeby1024=long(rescaleslope*1024);
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 			options(argc,argv);
+	DicomInputOptions 			dicom_input_options(options);
+	BinaryOutputOptions			output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	bool invertedgrayscaleoption=options.get("invertedgray");
+	bool forcesigned=options.get("signed");
+	bool forceunsigned=options.get("unsigned");
+	bool ignorewindowinobject=options.get("ignorewindow");
+	bool ignorevoilutinobject=options.get("ignorevoilut");
+
+	unsigned windowwidthvalue=0;
+	bool windowwidthset=options.get("windowwidth",windowwidthvalue);
+	unsigned windowcentervalue=0;
+	bool windowcenterset=options.get("windowlevel",windowcentervalue) || options.get("windowcenter",windowcentervalue);
+
+	unsigned whichvoilut=0;
+	bool whichvoilutset=options.get("voilut",whichvoilut);
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (forcesigned && forceunsigned) {
+		cerr << EMsgDC(NotBothSignedOrUnsigned) << endl;
+		bad=true;
+	};
+
+	if ( (windowwidthset && !windowcenterset)
+	 || (!windowwidthset &&  windowcenterset)) {
+		cerr << EMsgDC(NeedBothWindowCenterWidth) << endl;
+		bad=true;
+	};
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [-windowwidth width]"
+			<< " [-windowlevel|windowcenter center]"
+			<< " [-ignorewindow]"
+			<< " [-voilut numberfromzero]"
+			<< " [-ignorevoilut]"
+			<< " [-invertedgray]"
+			<< " [-signed|unsigned]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Float32 vRescaleIntercept = 0;
+	Attribute *aRescaleIntercept = list[TagFromName(RescaleIntercept)];
+	if (aRescaleIntercept)	// optional
+		vRescaleIntercept=AttributeValue(aRescaleIntercept);
+
+	Float32 vRescaleSlope = 0;
+	Attribute *aRescaleSlope = list[TagFromName(RescaleSlope)];
+	if (aRescaleSlope)	// optional
+		vRescaleSlope=AttributeValue(aRescaleSlope);
+
+	Uint16 vWindowCenter = 0;
+	Attribute *aWindowCenter = list[TagFromName(WindowCenter)];
+	if (aWindowCenter)	// optional
+		vWindowCenter=AttributeValue(aWindowCenter);
+
+	Uint16 vWindowWidth = 0;
+	Attribute *aWindowWidth = list[TagFromName(WindowWidth)];
+	if (aWindowWidth)	// optional
+		vWindowWidth=AttributeValue(aWindowWidth);
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+
+	if (!aPixelData) {
+		if (!quiet)
+			log << "\tPixeldata not in normal place ... checking for ImageLocation attribute" << endl;
+		Uint16 groupstart;
+		Uint16 groupend;
+		Attribute *aImageLocation=list[TagFromName(ImageLocation)];
+		if (aImageLocation) {
+			Uint16 vImageLocation=AttributeValue(aImageLocation);
+			if (!quiet)
+				log << "\tImageLocation = " << hex << vImageLocation << dec << endl;
+			groupstart=vImageLocation;
+			groupend=vImageLocation;
+		}
+		else {
+			groupstart=0x7fe0;
+			groupend=0x7ffd;
+		}
+		if (!quiet)
+			log << "\tNow searching for Pixeldata" << endl;
+		Uint16 group;
+		for (group=groupstart; !aPixelData && group <= groupend; ++group) {
+			Uint32 owner;
+			for (owner=((group&0x0001) ? 0x0100 : 0x0000);
+					!aPixelData && owner <= ((group&0x0001) ? 0xff00 : 0x0000); owner+=0x0100) {
+				if ((aPixelData=list[Tag(group,Uint16(owner|0x0010))]) && aPixelData->isOtherData()) {
+					if (!quiet)
+						log << "\tFound Pixeldata in ";
+						aPixelData->getTag().write(log);
+						log << endl;
+					break;
+				}
+				aPixelData=0;
+			}
+		}
+	}
+
+	Uint32 length=0;
+	if (!aPixelData) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelData\""
+		    << endl;
+		success=false;
+	}
+	else {
+		length=aPixelData->getVL();
+	}
+
+	Attribute *aVOILUTSequence = list[TagFromName(VOILUTSequence)];
+	int nVOILUT=0;
+	Uint16 *VOILUT_first = 0;
+	Uint16 *VOILUT_number = 0;
+	Uint16 *VOILUT_depth = 0;
+	Uint16 **VOILUT_table = 0;
+	if (aVOILUTSequence) {
+//cerr << "Have VOILUTSequence" << endl;
+		AttributeList **items;
+		nVOILUT=aVOILUTSequence->getLists(&items);
+		if (nVOILUT) {
+			VOILUT_first = new Uint16[nVOILUT];
+			Assert(VOILUT_first);
+			VOILUT_number = new Uint16[nVOILUT];
+			Assert(VOILUT_number);
+			VOILUT_depth = new Uint16[nVOILUT];
+			Assert(VOILUT_depth);
+			VOILUT_table = new Uint16 *[nVOILUT];
+			Assert(VOILUT_table);
+			int i;
+			for (i=0; i<nVOILUT; ++i) {
+				Assert(items[i]);
+				Attribute *aLUTDescriptor=items[i]->operator[](TagFromName(LUTDescriptor));
+				Assert(aLUTDescriptor);
+				Assert(aLUTDescriptor->getVM() == 3);
+				Assert(aLUTDescriptor->getValue(0,VOILUT_number[i]));
+				Assert(aLUTDescriptor->getValue(1,VOILUT_first[i]));
+				Assert(aLUTDescriptor->getValue(2,VOILUT_depth[i]));
+//cerr << "VOILUTSequence" << endl
+//     << "\t first[" << dec << i << "]=" << VOILUT_first[i] << endl
+//     << "\t number[" << dec << i << "]=" << VOILUT_number[i] << endl
+//     << "\t depth[" << dec << i << "]=" << VOILUT_depth[i] << endl;
+
+				Attribute *aLUTData=items[i]->operator[](TagFromName(LUTData));
+				Assert(aLUTData);
+				VOILUT_table[i]=new Uint16[VOILUT_number[i]];
+				Assert(VOILUT_table[i]);
+				int j;
+				for (j=0; j<VOILUT_number[i]; ++j) {
+					Assert(aLUTData->getValue(j,VOILUT_table[i][j]));
+				}
+			}
+		}
+	}
+
+	if (!quiet) {
+		log << "Read ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (aWindowCenter) log << vWindowCenter; log << endl;
+		log << "\tWindowWidth = "; if (aWindowWidth) log << vWindowWidth; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << nVOILUT; log << endl;
+		log << "\tPixelData Value Length = " << hex << length << dec << endl;
+	}
+
+	// Try to guess some missing attributes ...
+
+	if (vRescaleSlope*vRescaleSlope < 0.00001) vRescaleSlope=1;
+
+	if (vPixelRepresentation == 0xffff) vPixelRepresentation=0;
+	if (forceunsigned) vPixelRepresentation=0;
+	if (forcesigned) vPixelRepresentation=1;
+
+	if (!vNumberOfFrames) vNumberOfFrames=1;
+
+	if (!vSamplesPerPixel && !vPhotometricInterpretation) {
+		vSamplesPerPixel=1;
+		vPhotometricInterpretation=StrDup("MONOCHROME2");
+	}
+	else if (!vSamplesPerPixel && vPhotometricInterpretation) {
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0
+		 || strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0
+		 || strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0
+		) {
+			vSamplesPerPixel=1;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"RGB") == 0
+		 || strcmp(vPhotometricInterpretation,"HSV") == 0
+		) {
+			vSamplesPerPixel=3;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"ARGB") == 0
+		 || strcmp(vPhotometricInterpretation,"CMYK") == 0
+		) {
+			vSamplesPerPixel=4;
+		}
+	}
+	else if (!vPhotometricInterpretation && vSamplesPerPixel) {
+		switch (vSamplesPerPixel) {
+			case 1:	// could check for presence of palette
+				vPhotometricInterpretation=StrDup("MONOCHROME2");
+				break;
+			case 3:	vPhotometricInterpretation=StrDup("RGB");
+				break;
+			case 4:	vPhotometricInterpretation=StrDup("ARGB");
+				break;
+		}
+	}
+
+	if (!vBitsAllocated && length && length != 0xffffffff
+	 && (vRows && vColumns && vNumberOfFrames && vSamplesPerPixel)) {
+		vBitsAllocated=Uint16(length/((Uint32)vRows*vColumns*vNumberOfFrames*vSamplesPerPixel)*8);
+	}
+
+	if (!vBitsAllocated && vBitsStored)
+		vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+
+	if (!vBitsAllocated) {
+		if (strcmp(aPixelData->getVR(),"OW") == 0)
+			vBitsAllocated=16;
+		else
+			vBitsAllocated=8;
+	}
+
+	Assert(vBitsAllocated <= 16);
+
+	if (!vBitsStored) vBitsStored=vBitsAllocated;
+	if (!vHighBit) vHighBit=vBitsStored-1;
+
+	Uint32 framelengthinwords=length/vNumberOfFrames*8/vBitsAllocated;
+
+	if (!vRows) {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vRows=Uint16(sqrt(framelengthinwords));
+				vColumns=Uint16(length/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				Uint32 left=framelengthinwords/vSamplesPerPixel;
+				vRows=Uint16(sqrt(left));
+				vColumns=Uint16(left/vRows);
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				Uint32 left=framelengthinwords/vColumns;
+				vRows=Uint16(sqrt(length));
+				vSamplesPerPixel=1;
+			}
+			else {
+				vRows=Uint16(framelengthinwords/(vColumns*vSamplesPerPixel));
+			}
+		}
+	}
+	else {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vColumns=Uint16(framelengthinwords/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				vColumns=Uint16(framelengthinwords/(vRows*vSamplesPerPixel));
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				vSamplesPerPixel=Uint16(framelengthinwords/(vRows*vColumns));
+			}
+			// else we know all three
+		}
+	}
+
+	// use command line specified window values or the explicit option to suppress use of VOI LUT ...
+
+	if (windowwidthset || windowcenterset || ignorevoilutinobject) {
+		if (!quiet) log << "Ignoring any VOILUTs because told to or window values explicitly set" << endl;
+		nVOILUT = 0;
+	}
+
+	// use object values if present and not zero, unless overridden by command line ...
+
+	if (!windowwidthset && !windowcenterset && !ignorewindowinobject && aWindowCenter && vWindowCenter && aWindowWidth && vWindowWidth) {
+		if (!quiet) log << "Setting window values extracted from object because present not set on command line" << endl;
+		windowwidthset=true;
+		windowwidthvalue=vWindowWidth;
+		windowcenterset=true;
+		windowcentervalue=vWindowCenter;
+	}
+
+	if (!quiet) {
+		log << "Using ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tWindowCenter = "; if (windowcenterset && !nVOILUT) log << windowcentervalue; log << endl;
+		log << "\tWindowWidth = "; if (windowwidthset && !nVOILUT) log << windowwidthvalue; log << endl;
+		log << "\tVOILUTs = "; if (nVOILUT) log << whichvoilut << " of " << nVOILUT; log << endl;
+		log << "\tRows*Columns*SamplesPerPixel*BitsAllocated/8 = "
+		    << hex << (Uint32)vRows*vColumns*vSamplesPerPixel*vBitsAllocated/8
+		    << dec << endl;
+	}
+
+	Assert((Uint32)vRows*vColumns*vSamplesPerPixel <= framelengthinwords);
+
+	if (!vRows || !vColumns
+	 || !vPhotometricInterpretation || !vSamplesPerPixel
+	 || !vBitsAllocated
+	 || (vSamplesPerPixel > 1 && vPlanarConfiguration == 0xffff)) {
+		log << EMsgDC(MissingMandatoryAttributes) << endl;
+		success=false;
+	}
+
+	//if (vNumberOfFrames > 1) {
+	//	log << "Multiple frames not supported" << endl;
+	//	success=false;
+	//}
+
+	if (din.getTransferSyntaxToReadDataSet()->isEncapsulated()) {
+		log << "Encapsulated (compressed) input data not supported" << endl;
+		success=false;
+	}
+
+	OtherUnspecifiedLargeAttributeBase *oPixelData = 0;
+	SupplySourceFromAttribute *sPixelData = 0;
+	BufferedWindowedGrayImage *image = 0;
+	const char *pnmstring=0;
+
+	if (success) {
+		Assert(aPixelData);
+
+		if (!aPixelData->isOtherData()) {
+			log << EMsgDC(PixelDataIncorrectVR) << endl;
+			success=false;
+		}
+		else {
+			oPixelData = aPixelData->castToOtherData();
+			Assert(oPixelData);
+			sPixelData = new SupplySourceFromAttribute(oPixelData);
+			Assert(sPixelData);
+
+			if (vSamplesPerPixel == 1) {
+				bool monochrome=false;
+				bool invertedgrayscale=false;
+				if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0) {
+					monochrome=true;
+					invertedgrayscale=true;
+					pnmstring="P5";
+				}
+				else if (strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0) {
+					monochrome=true;
+					invertedgrayscale=false;
+					pnmstring="P5";
+				}
+				else {
+					log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+					    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+					    << "\"" << endl;
+					success=false;
+				}
+
+				if (invertedgrayscaleoption) invertedgrayscale=!invertedgrayscale;
+
+				if (vBitsAllocated <= 16) {
+					Assert(monochrome);
+					image=new BufferedWindowedGrayImage(sPixelData,vColumns,vRows,vNumberOfFrames,
+							vBitsAllocated,vBitsStored,vHighBit,
+							vPixelRepresentation,invertedgrayscale);
+				}
+				else {
+					log << EMsgDC(Unsupported) << " - BitsStored = " << vBitsStored << endl;
+					success=false;
+				}
+			}
+			else {
+				log << EMsgDC(Unsupported) << " - SamplesPerPixel = " << vSamplesPerPixel << endl;
+				success=false;
+			}
+		}
+	}
+
+	if (success) {
+		Assert(image);
+		Assert(pnmstring);
+		out << pnmstring << "\n";
+		out << vColumns << " " << vRows << "\n";
+		out << 255 << "\n";
+
+		if (!quiet) log << "Writing ..." << endl;
+
+		image->setOutputGrayLevelsWanted(256);
+
+		WindowCenterWidthTranslator wlwtranslate(
+			image->getBits(),	// Probably still same as BitsStored
+			image->getSigned(),		// May have been changed by statistics
+			vRescaleIntercept,vRescaleSlope);
+
+		bool usewlt = !nVOILUT && image->hasWindowCenterWidth();
+
+		if (nVOILUT) {
+			if (!quiet) log << "Applying VOILUT " << whichvoilut << endl;
+			image->setVOILUT(VOILUT_first[whichvoilut],
+				VOILUT_number[whichvoilut],VOILUT_depth[whichvoilut],VOILUT_table[whichvoilut]);
+		}
+
+		if (usewlt) {
+			if (windowcenterset && windowwidthset) {
+				if (!quiet) log << "Applying supplied displayed window values width " << windowwidthvalue << " center " << windowcentervalue << endl;
+				Uint16 center=(Uint16)wlwtranslate.getStoredCenterFromDisplayedCenter(windowcentervalue);
+				Uint16 width=(Uint16)wlwtranslate.getStoredWidthFromDisplayedWidth(windowwidthvalue);
+				if (!quiet) log << "Applying stored window values width " << width << " center " << center << endl;
+				image->setWindowCenterWidth(center,width);
+			}
+			else {
+				Uint16 minval;
+				Uint16 maxval;
+				image->getImageStatistics(1,minval,maxval);	// just one frame
+				if (!quiet) log << "Applying statistical window range minval " << minval << " maxval " << maxval << endl;
+				image->setWindowRange(minval,maxval);
+			}
+		}
+
+		if (!image->write8BitIndexedPixels(out)) {
+			log << EMsgDC(PixelDataReadFailed) << endl;
+			success=false;
+		}
+		out.flush();
+		if (!out.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+
+	//if (image) delete image;
+	//if (sPixelData) delete sPixelData;
+	//if (oPixelData) delete oPixelData;
+
+	return success ? 0 : 1;
+}
+
+
+
diff --git a/appsrc/dcfile/dctopgm8.man b/appsrc/dcfile/dctopgm8.man
new file mode 100755
index 0000000..fe0f739
--- /dev/null
+++ b/appsrc/dcfile/dctopgm8.man
@@ -0,0 +1,185 @@
+.TH DCTOPGM8 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM image to PNM file"
+.SH NAME
+dctopgm8 \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM image to PNM file
+.SH SYNOPSIS
+.HP 10
+.B dctopgm8
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-quiet|silent
+]
+.B \-windowwidth width
+]
+.B \-windowlevel|windowcenter center
+]
+.B \-ignorewindow
+]
+.B \-voilut numberfromzero
+]
+.B \-ignorevoilut
+]
+.B \-invertedgray
+]
+.B \-signed|unsigned
+]
+.so man1/optin.so
+.so man1/binout.so
+.SH DESCRIPTION
+.LP
+.B dctopgm8
+reads the named dicom or acr-nema input file, converts it to an 8 bit grayscale image by windowing or application of a VOI LUT and saves it as a PGM file.
+.LP
+In the absence of overriding command line options, the default behavior is to apply the first VOI LUT found, else if none, the first pair of window values in the input file, else if none, the full range of the input pixel values.
+.LP
+The input file must be unencapsulated.
+.LP
+.SH OPTIONS
+The PGM output goes where it is specified or standard out.
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-quiet|silent
+.RS
+Suppress the normal description of image parameters.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.TP
+.B \-windowwidth width
+.RS
+The window width to use (also supresses use of any VOI LUT).
+.RE
+.TP
+.B \-windowlevel|windowcenter center
+.RS
+The window center to use (also supresses use of any VOI LUT).
+.RE
+.TP
+.B \-ignorewindow
+.RS
+Ignore window center and width values in the input file, and use the full pixel value range instead (if no other command line options).
+.RE
+.TP
+.B \-voilut numberfromzero
+.RS
+Use the selected VOI LUT from the input file (indexed from 0 not 1).
+.RE
+.TP
+.B \-ignorevoilut
+.RS
+Ignore any VOI LUTs in the input file, and use the window values or the full pixel value range instead (if no other command line options).
+.RE
+.TP
+.B \-invertedgray
+.RS
+Invert the grayscale, overriding the PhotometricInterpretation in the input file.
+.RE
+.TP
+.B \-signed|unsigned
+.RS
+Override the sign specified in the PixelRepresentation in the input file.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dctopgm8 file.dcm file.pgm
+.RE
+Read ...
+.RE
+	Rows = 2294
+.RE
+	Columns = 1914
+.RE
+	NumberOfFrames = 0
+.RE
+	PhotometricInterpretation = MONOCHROME2
+.RE
+	SamplesPerPixel = 1
+.RE
+	BitsAllocated = 16
+.RE
+	BitsStored = 12
+.RE
+	HighBit = 11
+.RE
+	PixelRepresentation = 0
+.RE
+	PlanarConfiguration = 0
+.RE
+	RescaleIntercept = 0
+.RE
+	RescaleSlope = 1
+.RE
+	WindowCenter = 2905
+.RE
+	WindowWidth = 900
+.RE
+	VOILUTs = 3
+.RE
+	PixelData Value Length = 0x85fe78
+.RE
+Setting window values extracted from object because present not set on command line
+.RE
+Using ...
+.RE
+	Rows = 2294
+.RE
+	Columns = 1914
+.RE
+	NumberOfFrames = 1
+.RE
+	PhotometricInterpretation = MONOCHROME2
+.RE
+	SamplesPerPixel = 1
+.RE
+	BitsAllocated = 16
+.RE
+	BitsStored = 12
+.RE
+	HighBit = 11
+.RE
+	PixelRepresentation = 0
+.RE
+	PlanarConfiguration = 0
+.RE
+	RescaleIntercept = 0
+.RE
+	RescaleSlope = 1
+.RE
+	WindowCenter = 
+.RE
+	WindowWidth = 
+.RE
+	VOILUTs = 0 of 3
+.RE
+	Rows*Columns*SamplesPerPixel*BitsAllocated/8 = 0x85fe78
+.RE
+Writing ...
+.RE
+Applying VOILUT 0
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctopnm(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dctopgx.cc b/appsrc/dcfile/dctopgx.cc
new file mode 100644
index 0000000..f00b191
--- /dev/null
+++ b/appsrc/dcfile/dctopgx.cc
@@ -0,0 +1,251 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dctopgx.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+#include "transyn.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	BinaryOutputOptions	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	if (!quiet) {
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRows*Columns*SamplesPerPixel*BitsAllocated/8 = "
+		    << hex << (Uint32)vRows*vColumns*vSamplesPerPixel*vBitsAllocated/8
+		    << dec << endl;
+	}
+
+	if (vNumberOfFrames > 1) {
+		log << "Multiple frames not supported" << endl;
+		success=false;
+	}
+
+	if (din.getTransferSyntaxToReadDataSet()->isEncapsulated()) {
+		log << "Encapsulated (compressed) input data not supported" << endl;
+		success=false;
+	}
+
+/*
+       PGX is a trivial monochrome file format defined just
+       to enable simple testing of JPEG2000 with image data having unusual
+       bit-depths. The file consists of a single text header line of the form
+       "PG <byte order> [+|-]<bit-depth> <cols> <rows>", with the binary data
+       appearing immediately after the newline character, packed into 1, 2 or
+       4 bytes per sample, depending upon the value of <bit-depth>. The <byte
+       order> field must be one of the fixed strings, "LM" (LSB's first) or
+       "ML" (MSB's first), while the optional `+' (default) or `-' character
+       preceding the <bit-depth> field indicates whether the data is signed
+       or not. Any bit-depth from 1 to 32 is acceptable.
+*/
+
+	const char *pgxstring=0;
+
+	if (vSamplesPerPixel == 1) {
+		pgxstring="PG";
+	}
+	else {
+		log << "Only single channel images supported" << endl;
+		success=false;
+	}
+
+	if (success) {
+		Assert(pgxstring);
+		out << pgxstring << " "
+		    << (din.getEndian() == BigEndian ? "ML" : "LM") << " "
+		    << (vPixelRepresentation > 0 ? "-" : " ")
+		    << ((vBitsAllocated > 8 && vBitsStored < 8) ? 9 : vBitsStored) << " "
+		    << vColumns << " " << vRows << "\n";
+	}
+
+
+	Attribute *apixeldata=list[TagFromName(PixelData)];
+	if (!apixeldata) {
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+		success=false;
+	}
+	else if (!apixeldata->isOtherData()) {
+		log << EMsgDC(PixelDataIncorrectVR) << endl;
+		success=false;
+	}
+
+	if (success) {
+		OtherUnspecifiedLargeAttributeBase *
+			opixeldata = apixeldata->castToOtherData();
+		Assert(opixeldata);
+
+		if (!quiet) log << "Writing ..." << endl;
+
+		opixeldata->writeRaw(out);
+
+		if (!out.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dctopgx.man b/appsrc/dcfile/dctopgx.man
new file mode 100755
index 0000000..c496b73
--- /dev/null
+++ b/appsrc/dcfile/dctopgx.man
@@ -0,0 +1,74 @@
+.TH DCTOPGX 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM image to PGX file"
+.SH NAME
+dctopgx \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM image to PGX file
+.SH SYNOPSIS
+.HP 10
+.B dctopgx
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-quiet|silent
+]
+.so man1/optin.so
+.so man1/binout.so
+.SH DESCRIPTION
+.LP
+.B dctopgx
+reads the named dicom or acr-nema single channel (grayscale or palette color; the photometric interpretation is not checked) input file and copies the raw image
+pixel data to a PGX file as used for the JPEG 2000 Verification Model.
+.LP
+A PGX file contains of a single text header line of the form
+"PG <byte order> [+|-]<bit-depth> <cols> <rows>\n", followed
+immediately by the raw binary data. There may be 1, 2 or
+4 bytes per sample corresponding to bit depths from 1 to 32.
+Byte order is "LM" (little endian) or "ML" (big endian). The
+signed or unsigned pixel representation is indicated by '+'
+or '-' character before the bit depth. If the '+' is omitted,
+unsigned is implied.
+.LP
+The input file must be unencapsulated.
+.LP
+PGX supports big or little endian
+byte order in the case of > 8 bit data. The output byte order is always 
+in the same as the input, since the raw bytes
+are copied from input to output without any conversion. Use dccp(1)
+first to change the encoding if necessary.
+.LP
+PGX also supports signed data, so the Pixel Representation of the
+input is used to specify whether the output is signed or unsigned.
+.LP
+.SH OPTIONS
+The PGX output goes where it is specified or standard out.
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-quiet|silent
+.RS
+Suppress the normal description of image parameters.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR pnmtodc(1) ,
+.BR dctopnm(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dctopnm.cc b/appsrc/dcfile/dctopnm.cc
new file mode 100644
index 0000000..f74f21a
--- /dev/null
+++ b/appsrc/dcfile/dctopnm.cc
@@ -0,0 +1,268 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dctopnm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+#include "transyn.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 			options(argc,argv);
+	DicomInputOptions 			dicom_input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	if (vNumberOfFrames == 0) {
+		vNumberOfFrames = 1;	// need to treat it as 1 if missing for later byteCount calculation
+	}
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Uint32 byteCount = ((Uint32)vRows) * vColumns * vNumberOfFrames * vSamplesPerPixel * ((vBitsAllocated-1)/8 + 1);
+
+	if (!quiet) {
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRows*Columns*vNumberOfFrames*SamplesPerPixel*((vBitsAllocated-1)/8+1) = "
+		    << hex << byteCount
+		    << dec << " (" << byteCount << " dec)" << endl;
+	}
+
+	if (vNumberOfFrames > 1) {
+		log << "Error - Multiple frames not supported" << endl;
+		success=false;
+	}
+
+	if (din.getTransferSyntaxToReadDataSet()->isEncapsulated()) {
+		log << "Error - Encapsulated (compressed) input data not supported" << endl;
+		success=false;
+	}
+
+	if (vBitsAllocated > 8) {
+		if (output_options.byteorder == ByteEndian || output_options.byteorder == NoEndian) {
+			log << "Error - Need to specify output byte order for > 8 bit data" << endl;
+			success=false;
+		}
+		else if (din.getEndian() != output_options.byteorder) {
+			log << "Error - Need to specify same byte order as input for > 8 bit data" << endl;
+			success=false;
+		}
+	}
+
+	const char *pnmstring=0;
+
+	if (vSamplesPerPixel == 1) {
+		pnmstring="P5";
+	}
+	else if (vSamplesPerPixel == 3
+		&& vPhotometricInterpretation && strcmp(vPhotometricInterpretation,"RGB") == 0
+		&& vPlanarConfiguration == 0) {
+		pnmstring="P6";
+	}
+	else {
+		log << "Error - Only single channel or 3 channel RGB interleaved images supported" << endl;
+		success=false;
+	}
+
+	if (success) {
+		Assert(pnmstring);
+		out << pnmstring << "\n";
+		out << vColumns << " " << vRows << "\n";
+		out << ((vBitsAllocated > 8 && vBitsStored < 8) ? 256 : (1<<vBitsStored)-1) << "\n";
+	}
+
+
+	Attribute *apixeldata=list[TagFromName(PixelData)];
+	if (!apixeldata) {
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+		success=false;
+	}
+	else if (!apixeldata->isOtherData()) {
+		log << EMsgDC(PixelDataIncorrectVR) << endl;
+		success=false;
+	}
+
+	if (success) {
+		OtherUnspecifiedLargeAttributeBase *
+			opixeldata = apixeldata->castToOtherData();
+		Assert(opixeldata);
+
+
+		// do NOT want to write all available bytes, since odd number will have ab even padding byte
+		// and netpbm utilities freak if this is present with "Error reading magic number from Netpbm image stream.  Most often, this means your input file is empty." ...
+		
+		if (byteCount == 0) {
+			// do it the "old" way, if for some reason we could not find a suitable value for something that contributes to the desired count; should never happen
+			if (!quiet) log << "Writing VL " << dec << opixeldata->getVL() << " (dec) bytes ..." << endl;
+			opixeldata->writeRaw(out);
+		}
+		else {
+			if (!quiet) log << "Writing unpadded " << dec << byteCount << " (dec) bytes ..." << endl;
+			opixeldata->writeRaw(out,0/*byte offset*/,byteCount);
+		}
+		
+		if (!out.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dctopnm.cc.firstgo b/appsrc/dcfile/dctopnm.cc.firstgo
new file mode 100755
index 0000000..d49c370
--- /dev/null
+++ b/appsrc/dcfile/dctopnm.cc.firstgo
@@ -0,0 +1,635 @@
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+
+class PnmImage {
+private:
+	SupplySource *supplysource;
+protected:
+	Uint16 columns;
+	Uint16 rows;
+	Uint16 frames;
+	Uint16 planes;
+	Uint16 bitsneeded;
+	Uint16 bitsallocated;
+	Uint16 bitsstored;
+	Uint16 highbit;
+	bool issigned;
+
+	class SourceBase<Uint16> *getSource(void);
+	virtual Uint16 mapPixel(const Uint16 src) = 0;
+public:
+	PnmImage(
+		SupplySource *s,Uint16 c,Uint16 r,Uint16 f,Uint16 p,
+		Uint16 bn,Uint16 ba,Uint16 bs,Uint16 hb,
+		bool issgn=false);
+
+	virtual ~PnmImage();
+
+	virtual bool writeImage(ostream &out) = 0;
+};
+
+class SourceBase<Uint16> *
+PnmImage::getSource(void)
+{
+	Assert(supplysource);
+	return supplysource->getSource();
+}
+
+PnmImage::PnmImage(
+	SupplySource *s,Uint16 c,Uint16 r,Uint16 f,Uint16 p,
+	Uint16 bn,Uint16 ba,Uint16 bs,Uint16 hb,bool issgn)
+{
+	supplysource=s;
+	columns=c;
+	rows=r;
+	frames=f;
+	planes=p;
+	bitsneeded=bn;
+	bitsallocated=ba;
+	bitsstored=bs;
+	highbit=hb;
+	issigned=issgn;
+	Assert(supplysource);
+	Assert(columns);
+	Assert(rows);
+	Assert(frames);
+	Assert(planes);
+	Assert(bitsneeded);
+	Assert(bitsallocated);
+	Assert(bitsstored);
+	Assert(highbit);
+}
+
+PnmImage::~PnmImage()
+{}
+
+class PnmWindowed8BitGrayImage : public PnmImage {
+	bool inverted;
+	Uint16 signxor;
+	Uint32 ngrays;
+
+	Uint16 mapPixel(const Uint16 src);
+public:
+	PnmWindowed8BitGrayImage(SupplySourceFromAttribute *sPixelData,
+			Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+			Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+			Uint16 vPixelRepresentation,bool invertedgrayscale)
+		: PnmImage(sPixelData,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,
+			vPixelRepresentation)
+		{
+	Assert(vBitsStored);
+	inverted=invertedgrayscale;
+	Uint16 mingray=0;
+	Uint32 mx=(Uint32(1)<<vBitsStored)-1;
+	Assert(mx <= Uint16_MAX);
+	Uint16 maxgray=Uint16(mx);
+	Assert(maxgray >= mingray);
+	ngrays=maxgray-mingray+1;
+
+	signxor=issigned
+		? 1<<(bits-1)
+		: 0;
+
+
+		}
+
+	bool writeImage(ostream &out);
+
+
+};
+
+Uint16
+PnmWindowed8BitGrayImage::mapPixel(const Uint16 src)
+{
+	return (inverted ? (ngrays-src-1) : src)^signxor;
+}
+
+bool
+PnmWindowed8BitGrayImage::writeImage(ostream &out)
+{
+	Assert(rows);
+	Assert(columns);
+	Assert(planes==1);
+
+	class SourceBase<Uint16> *source = getSource();
+	if (!source) return false;
+
+	unsigned row=0;
+	unsigned column=0;
+	while (row < rows*frames && source->read()) {
+		size_t n=source->getBufferCount();
+		Assert(n);
+		const Uint16 *buffer=source->getBuffer();
+		Assert(buffer);
+		while (n-- && row < rows*frames) {
+			out << (unsigned char)mapPixel(*buffer);
+			buffer++;
+		}
+	}
+	Assert(column == 0 && row == rows*frames);
+	return ostream && row >= rows*frames;	// stream ok and read enough
+}
+
+class PnmFromWindowed16BitGrayImage: public PnmImage {
+
+public:
+	PnmFromWindowed16BitGrayImage(SupplySourceFromAttribute *sPixelData,
+			Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+			Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+			Uint16 vPixelRepresentation,bool invertedgrayscale)
+		: PnmImage(sPixelData,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,
+			vPixelRepresentation)
+		{
+		}
+
+};
+
+class PnmFromInterleaved24BitRGBImage: public PnmImage {
+
+public:
+	PnmFromInterleaved24BitRGBImage(SupplySourceFromAttribute *sPixelData,
+			Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+			Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: PnmImage(sPixelData,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,false)
+		{
+		}
+
+};
+
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	OutputOptions		output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener);
+	ostream out(output_opener);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+		//return 1;	// Press on regardless ...
+	}
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Float32 vRescaleIntercept = 0;
+	Attribute *aRescaleIntercept = list[TagFromName(RescaleIntercept)];
+	if (aRescaleIntercept)	// optional
+		vRescaleIntercept=AttributeValue(aRescaleIntercept);
+
+	Float32 vRescaleSlope = 0;
+	Attribute *aRescaleSlope = list[TagFromName(RescaleSlope)];
+	if (aRescaleSlope)	// optional
+		vRescaleSlope=AttributeValue(aRescaleSlope);
+
+	Attribute *aPixelData = list[TagFromName(PixelData)];
+
+	if (!aPixelData) {
+		if (!noattributes)
+			log << "\tPixeldata not in normal place ... checking for ImageLocation attribute" << endl;
+		Uint16 groupstart;
+		Uint16 groupend;
+		Attribute *aImageLocation=list[TagFromName(ImageLocation)];
+		if (aImageLocation) {
+			Uint16 vImageLocation=AttributeValue(aImageLocation);
+			if (!noattributes)
+				log << "\tImageLocation = " << hex << vImageLocation << dec << endl;
+			groupstart=vImageLocation;
+			groupend=vImageLocation;
+		}
+		else {
+			groupstart=0x7fe0;
+			groupend=0x7ffd;
+		}
+		if (!noattributes)
+			log << "\tNow searching for Pixeldata" << endl;
+		Uint16 group;
+		for (group=groupstart; !aPixelData && group <= groupend; ++group) {
+			Uint32 owner;
+			for (owner=((group&0x0001) ? 0x0100 : 0x0000);
+					!aPixelData && owner <= ((group&0x0001) ? 0xff00 : 0x0000); owner+=0x0100) {
+				if ((aPixelData=list[Tag(group,Uint16(owner|0x0010))]) && aPixelData->isOtherData()) {
+					if (!noattributes)
+						log << "\tFound Pixeldata in ";
+						aPixelData->getTag().write(log);
+						log << endl;
+					break;
+				}
+				aPixelData=0;
+			}
+		}
+	}
+
+	if (!aPixelData) {
+		log << EMsgDC(MissingAttribute)
+		    << " - \"PixelData\""
+		    << endl;
+		log << EMsgDC(NothingToDisplay) << endl;
+		return 1;
+	}
+
+	Uint32 length=aPixelData->getVL();
+
+	if (!noattributes) {
+		log << "Read ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tPixelData Value Length = " << hex << length << dec << endl;
+	}
+
+	// Try to guess some missing attributes ...
+
+	if (vRescaleSlope*vRescaleSlope < 0.00001) vRescaleSlope=1;
+
+	if (vPixelRepresentation == 0xffff) vPixelRepresentation=0;
+	if (forceunsigned) vPixelRepresentation=0;
+	if (forcesigned) vPixelRepresentation=1;
+
+	if (!vNumberOfFrames) vNumberOfFrames=1;
+
+	if (!vSamplesPerPixel && !vPhotometricInterpretation) {
+		vSamplesPerPixel=1;
+		vPhotometricInterpretation=StrDup("MONOCHROME2");
+	}
+	else if (!vSamplesPerPixel && vPhotometricInterpretation) {
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0
+		 || strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0
+		 || strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0
+		) {
+			vSamplesPerPixel=1;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"RGB") == 0
+		 || strcmp(vPhotometricInterpretation,"HSV") == 0
+		) {
+			vSamplesPerPixel=3;
+		}
+		else if (
+		    strcmp(vPhotometricInterpretation,"ARGB") == 0
+		 || strcmp(vPhotometricInterpretation,"CMYK") == 0
+		) {
+			vSamplesPerPixel=4;
+		}
+	}
+	else if (!vPhotometricInterpretation && vSamplesPerPixel) {
+		switch (vSamplesPerPixel) {
+			case 1:	// could check for presence of palette
+				vPhotometricInterpretation=StrDup("MONOCHROME2");
+				break;
+			case 3:	vPhotometricInterpretation=StrDup("RGB");
+				break;
+			case 4:	vPhotometricInterpretation=StrDup("ARGB");
+				break;
+		}
+	}
+
+	if (!vBitsAllocated && length && length != 0xffffffff
+	 && (vRows && vColumns && vNumberOfFrames && vSamplesPerPixel)) {
+		vBitsAllocated=Uint16(length/((Uint32)vRows*vColumns*vNumberOfFrames*vSamplesPerPixel)*8);
+	}
+
+	if (!vBitsAllocated && vBitsStored)
+		vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+
+	if (!vBitsAllocated) {
+		if (strcmp(aPixelData->getVR(),"OW") == 0)
+			vBitsAllocated=16;
+		else
+			vBitsAllocated=8;
+	}
+
+	Assert(vBitsAllocated <= 16);
+
+	if (!vBitsStored) vBitsStored=vBitsAllocated;
+	if (!vHighBit) vHighBit=vBitsStored-1;
+
+	Uint32 framelengthinwords=length/vNumberOfFrames*8/vBitsAllocated;
+
+	if (!vRows) {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vRows=Uint16(sqrt(framelengthinwords));
+				vColumns=Uint16(length/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				Uint32 left=framelengthinwords/vSamplesPerPixel;
+				vRows=Uint16(sqrt(left));
+				vColumns=Uint16(left/vRows);
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				Uint32 left=framelengthinwords/vColumns;
+				vRows=Uint16(sqrt(length));
+				vSamplesPerPixel=1;
+			}
+			else {
+				vRows=Uint16(framelengthinwords/(vColumns*vSamplesPerPixel));
+			}
+		}
+	}
+	else {
+		if (!vColumns) {
+			if (!vSamplesPerPixel) {
+				vColumns=Uint16(framelengthinwords/vRows);
+				vSamplesPerPixel=1;
+			}
+			else {
+				vColumns=Uint16(framelengthinwords/(vRows*vSamplesPerPixel));
+			}
+		}
+		else {
+			if (!vSamplesPerPixel) {
+				vSamplesPerPixel=Uint16(framelengthinwords/(vRows*vColumns));
+			}
+			// else we know all three
+		}
+	}
+
+	if (!noattributes) {
+		log << "Using ..." << endl;
+		log << "\tRows = " << dec << vRows << endl;
+		log << "\tColumns = " << dec << vColumns << endl;
+		log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+		log << "\tPhotometricInterpretation = "
+		    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+		    << endl;
+		log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+		log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+		log << "\tBitsStored = " << dec << vBitsStored << endl;
+		log << "\tHighBit = " << dec << vHighBit << endl;
+		log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+		log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+		log << "\tRescaleIntercept = " << dec << vRescaleIntercept << endl;
+		log << "\tRescaleSlope = " << dec << vRescaleSlope << endl;
+		log << "\tRows*Columns*SamplesPerPixel*BitsAllocated/8 = "
+		    << hex << (Uint32)vRows*vColumns*vSamplesPerPixel*vBitsAllocated/8
+		    << dec << endl;
+	}
+
+	Assert((Uint32)vRows*vColumns*vSamplesPerPixel <= framelengthinwords);
+
+	if (!vRows || !vColumns
+	 || !vPhotometricInterpretation || !vSamplesPerPixel
+	 || !vBitsAllocated
+	 || (vSamplesPerPixel > 1 && vPlanarConfiguration == 0xffff)) {
+		log << EMsgDC(MissingMandatoryAttributes) << endl;
+		return 1;
+	}
+
+	PnmImage *image = 0;
+	SupplySourceFromAttribute sPixelData(aPixelData);
+
+	// The standard doesn't say it, but what could a
+	// signed PixelRepresentation mean for other than grayscale ?
+
+	bool pixelrepresentationok = (vPixelRepresentation == 0);
+	bool windowlevelwidthok = !windowlevelset && !windowwidthset;
+
+	if (vSamplesPerPixel == 1) {
+		bool monochrome=false;
+		bool invertedgrayscale=false;
+		bool palettecolor=false;
+		if (strcmp(vPhotometricInterpretation,"MONOCHROME1") == 0) {
+			monochrome=true;
+			invertedgrayscale=true;
+		}
+		else if (strcmp(vPhotometricInterpretation,"MONOCHROME2") == 0) {
+			monochrome=true;
+			invertedgrayscale=false;
+		}
+		else if (strcmp(vPhotometricInterpretation,"PALETTE COLOR") == 0) {
+			palettecolor=true;
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+
+		if (invertedgrayscaleoption) invertedgrayscale=!invertedgrayscale;
+
+		if (vBitsStored <= 8) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				image=new PnmWindowed8BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale);
+			}
+			else {
+				log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+				    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+				    << "\" - BitsStored = " << vBitsStored
+				    << endl;
+				return 1;
+			}
+		}
+		else if (vBitsStored <= 16) {
+			if (monochrome) {
+				pixelrepresentationok=true;	// Not required to be unsigned
+				windowlevelwidthok=true;	// allowed to specify width & level on command line
+				image=new PnmFromWindowed16BitGrayImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit,
+						vPixelRepresentation,invertedgrayscale);
+			}
+			else {
+				log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+				    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+				    << "\" - BitsStored = " << vBitsStored
+				    << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - BitsStored = " << vBitsStored << endl;
+			return 1;
+		}
+	}
+	else if (vSamplesPerPixel == 3) {
+		if (strcmp(vPhotometricInterpretation,"RGB") == 0) {
+			if (vPlanarConfiguration == 0)
+				image=new PnmFromInterleaved24BitRGBImage(&sPixelData,vColumns,vRows,vNumberOfFrames,
+						vBitsAllocated,vBitsStored,vHighBit);
+			else {
+				log << EMsgDC(Unsupported) << " - PlanarConfiguration = " << vPlanarConfiguration << endl;
+				return 1;
+			}
+		}
+		else {
+			log << EMsgDC(Unsupported) << " - PhotometricInterpretation = \""
+			    << (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+			    << "\"" << endl;
+			return 1;
+		}
+	}
+	else {
+		log << EMsgDC(Unsupported) << " - SamplesPerPixel = " << vSamplesPerPixel << endl;
+		return 1;
+	}
+
+	if (!pixelrepresentationok) {
+		log << WMsgDC(NonMonochromeSignedPixelRepresentation) << endl;
+	}
+	if (!windowlevelwidthok) {
+		log << WMsgDC(NoNeedForWindowLevelWidth) << endl;
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dctopnm.man b/appsrc/dcfile/dctopnm.man
new file mode 100755
index 0000000..3be4439
--- /dev/null
+++ b/appsrc/dcfile/dctopnm.man
@@ -0,0 +1,122 @@
+.TH DCTOPNM 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM image to PNM file"
+.SH NAME
+dctopnm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM image to PNM file
+.SH SYNOPSIS
+.HP 10
+.B dctopnm
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-quiet|silent
+]
+.so man1/optin.so
+.so man1/binout.so
+.SH DESCRIPTION
+.LP
+.B dctopnm
+reads the named dicom or acr-nema input file and copies the raw image
+pixel data to a PNM file after adding a PGM or PPM header.
+.LP
+The input file must be unencapsulated, single channel (grayscale or palette color; the photometric interpretation is not checked for single channel), or three channel interleaved RGB, and in the case of > 8 bit data,
+in the same byte order as desired in the output, since the raw bytes
+are copied from input to output without any conversion. Use dccp(1)
+first to change the encoding if necessary.
+.LP
+Only the necessary number of bytes
+to encode the pixel data will be written (based on rows, columns, number of
+frames, samples per pixel and bits allocated); this means that for an odd number
+of bytes the extra DICOM padding byte will not be copied to the raw output. This
+prevents netpbm utilities freaking out with an error "reading magic number" if the padding byte is
+present. If
+any of the necessary attributes to calculate
+the correct pixel data length are missing, all encoded bytes will be written.
+.LP
+.SH OPTIONS
+The PNM output goes where it is specified or standard out.
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-quiet|silent
+.RS
+Suppress the normal description of image parameters.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcfile big.dc3
+.RE
+Meta: UID		1.2.840.10008.1.2.1
+.RE
+Meta: Description	"Explicit VR Little Endian"
+.RE
+Meta: ByteOrder	Little
+.RE
+Meta: VR		Explicit
+.RE
+Meta: Encapsulated	No
+.RE
+Data: UID		1.2.840.10008.1.2.2
+.RE
+Data: Description	"Explicit VR Big Endian"
+.RE
+Data: ByteOrder	Big
+.RE
+Data: VR		Explicit
+.RE
+Data: Encapsulated	No
+.RE
+\ 
+.RE
+% dctopnm big.dc3 big.pgm -endian big
+.RE
+ Rows = 512
+.RE
+ Columns = 512
+.RE
+ NumberOfFrames = 0
+.RE
+ PhotometricInterpretation = MONOCHROME2
+.RE
+ SamplesPerPixel = 1
+.RE
+ BitsAllocated = 16
+.RE
+ BitsStored = 16
+.RE
+ HighBit = 15
+.RE
+ PixelRepresentation = 1
+.RE
+ PlanarConfiguration = 0x0
+.RE
+ Rows*Columns*SamplesPerPixel*BitsAllocated/8 = 0x80000
+.RE
+Writing ...
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dctopgm8(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+It would be desirable to be able to expand palette color images to produce RGB output, and to handle color-by-plane rather than interleaved RGB, but for now, these are not supported.
diff --git a/appsrc/dcfile/dctoraw.cc b/appsrc/dcfile/dctoraw.cc
new file mode 100644
index 0000000..8f9d40a
--- /dev/null
+++ b/appsrc/dcfile/dctoraw.cc
@@ -0,0 +1,254 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dctoraw.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "elmconst.h"
+#include "transynd.h"
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	OutputOptions		output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool quiet=options.get("quiet") || options.get("silent");
+
+	dicom_input_options.done();
+	output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-quiet|-silent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+	ostream out(output_opener);
+
+	ManagedAttributeList list;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+	if (!list.good()) {
+		log << EMsgDC(DatasetReadFailed) << endl;
+		success=false;
+	}
+	
+	// Most of this is copied from dctopnm ... should refactor :(
+
+	Uint16 vRows = 0;
+	Attribute *aRows = list[TagFromName(Rows)];
+	if (!aRows)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Rows\""
+		    << endl;
+	else
+		vRows=AttributeValue(aRows);
+
+	Uint16 vColumns = 0;
+	Attribute *aColumns = list[TagFromName(Columns)];
+	if (!aColumns)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"Columns\""
+		    << endl;
+	else
+		vColumns=AttributeValue(aColumns);
+
+	Uint16 vNumberOfFrames = 0;
+	Attribute *aNumberOfFrames = list[TagFromName(NumberOfFrames)];
+	if (aNumberOfFrames)	// optional
+		vNumberOfFrames=AttributeValue(aNumberOfFrames);
+
+	if (vNumberOfFrames == 0) {
+		vNumberOfFrames = 1;	// need to treat it as 1 if missing for later byteCount calculation
+	}
+
+	char *vPhotometricInterpretation = 0;
+	Attribute *aPhotometricInterpretation = list[TagFromName(PhotometricInterpretation)];
+	if (!aPhotometricInterpretation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PhotometricInterpretation\""
+		    << endl;
+	else
+		vPhotometricInterpretation=AttributeValue(aPhotometricInterpretation);
+
+	Uint16 vSamplesPerPixel = 0;
+	Attribute *aSamplesPerPixel = list[TagFromName(SamplesPerPixel)];
+	if (!aSamplesPerPixel)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"SamplesPerPixel\""
+		    << endl;
+	else
+		vSamplesPerPixel=AttributeValue(aSamplesPerPixel);
+
+	Uint16 vBitsAllocated = 0;
+	Attribute *aBitsAllocated = list[TagFromName(BitsAllocated)];
+	if (!aBitsAllocated)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsAllocated\""
+		    << endl;
+	else
+		vBitsAllocated=AttributeValue(aBitsAllocated);
+
+	Uint16 vBitsStored = 0;
+	Attribute *aBitsStored = list[TagFromName(BitsStored)];
+	if (!aBitsStored)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"BitsStored\""
+		    << endl;
+	else
+		vBitsStored=AttributeValue(aBitsStored);
+
+	Uint16 vHighBit = 0;
+	Attribute *aHighBit = list[TagFromName(HighBit)];
+	if (!aHighBit)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"HighBit\""
+		    << endl;
+	else
+		vHighBit=AttributeValue(aHighBit);
+
+	Uint16 vPixelRepresentation = 0xffff;
+	Attribute *aPixelRepresentation = list[TagFromName(PixelRepresentation)];
+	if (!aPixelRepresentation)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PixelRepresentation\""
+		    << endl;
+	else
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+
+	Uint16 vPlanarConfiguration = 0xffff;
+	Attribute *aPlanarConfiguration = list[TagFromName(PlanarConfiguration)];
+	if (vSamplesPerPixel > 1 && !aPlanarConfiguration)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"PlanarConfiguration\""
+		    << endl;
+	else
+		vPlanarConfiguration=AttributeValue(aPlanarConfiguration);
+
+	Uint32 byteCount = ((Uint32)vRows) * vColumns * vNumberOfFrames * vSamplesPerPixel * ((vBitsAllocated-1)/8 + 1);
+
+	TransferSyntax *ts=din.getTransferSyntaxToReadDataSet();
+	Assert(ts);
+
+	Attribute *apixeldata=list[TagFromName(PixelData)];
+	if (!apixeldata) {
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+		success=false;
+	}
+	else if (!apixeldata->isOtherData()) {
+		log << EMsgDC(PixelDataIncorrectVR) << endl;
+		success=false;
+	}
+	else {
+		if (!quiet) {
+			// this is now redundant with the explicit retrieval of values above, but keep this redundant dump in case anyone used these in scripts ...
+			log << "******** Parameters ... ********" << endl; 
+			ElementDictionary *dict=list.getDictionary();
+			Attribute *a;
+			a=list[TagFromName(NumberOfFrames)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(Rows)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(Columns)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(SamplesPerPixel)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(PixelRepresentation)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(PhotometricInterpretation)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(PlanarConfiguration)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(BitsAllocated)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(BitsStored)];
+			if (a) { a->write(log,dict); log << endl; }
+			a=list[TagFromName(HighBit)];
+			if (a) { a->write(log,dict); log << endl; }
+
+			log << "\tRows = " << dec << vRows << endl;
+			log << "\tColumns = " << dec << vColumns << endl;
+			log << "\tNumberOfFrames = " << dec << vNumberOfFrames << endl;
+			log << "\tPhotometricInterpretation = "
+				<< (vPhotometricInterpretation ? vPhotometricInterpretation : "")
+				<< endl;
+			log << "\tSamplesPerPixel = " << dec << vSamplesPerPixel << endl;
+			log << "\tBitsAllocated = " << dec << vBitsAllocated << endl;
+			log << "\tBitsStored = " << dec << vBitsStored << endl;
+			log << "\tHighBit = " << dec << vHighBit << endl;
+			log << "\tPixelRepresentation = " << dec << vPixelRepresentation << endl;
+			log << "\tPlanarConfiguration = " << hex << vPlanarConfiguration << dec << endl;
+			log << "\tRows*Columns*vNumberOfFrames*SamplesPerPixel*((vBitsAllocated-1)/8+1) = "
+				<< hex << byteCount
+				<< dec << " (" << byteCount << " dec)" << endl;
+
+			dumpTransferSyntaxEncapsulation(ts);
+			dumpTransferSyntaxByteOrder(ts);
+		}
+
+		OtherUnspecifiedLargeAttributeBase *
+			opixeldata = apixeldata->castToOtherData();
+		Assert(opixeldata);
+
+		if (ts->isEncapsulated()) {
+			if (!quiet) log << "Writing encapsulated Transfer Syntax ..." << endl;
+			opixeldata->writeRaw(out);
+		}
+		else if (byteCount == 0) {
+			// do it the "old" way, if for some reason we could not find a suitable value for something that contributes to the desired count; should never happen
+			if (!quiet) log << "Writing VL " << dec << opixeldata->getVL() << " (dec) bytes ..." << endl;
+			opixeldata->writeRaw(out);
+		}
+		else {
+			if (!quiet) log << "Writing unpadded " << dec << byteCount << " (dec) bytes ..." << endl;
+			opixeldata->writeRaw(out,0/*byte offset*/,byteCount);
+		}
+		
+		if (!out.good()) {
+			log << EMsgDC(Writefailed) << endl;
+			success=false;
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dctoraw.man b/appsrc/dcfile/dctoraw.man
new file mode 100755
index 0000000..758470b
--- /dev/null
+++ b/appsrc/dcfile/dctoraw.man
@@ -0,0 +1,90 @@
+.TH DCTORAW 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - DICOM image to raw file"
+.SH NAME
+dctoraw \- ACR/NEMA DICOM PS3 ... DICOM PS3 - DICOM image to raw file
+.SH SYNOPSIS
+.HP 10
+.B dctoraw
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+[
+.B \-quiet|silent
+]
+.so man1/optin.so
+.so man1/genout.so
+.SH DESCRIPTION
+.LP
+.B dctoraw
+reads the named dicom or acr-nema input file and copies the raw image
+pixel data to a raw binary file without a header of any kind.
+.LP
+The byte order, packing or encapsulation of the raw result is dependent only
+on the encoding of the input file and cannot be changed. Use dccp(1)
+first to change the encoding if necessary.
+.LP
+If the transfer syntax is not encapsulated, only the necessary number of bytes
+to encode the pixel data will be written (based on rows, columns, number of
+frames, samples per pixel and bits allocated); this means that for an odd number
+of bytes the extra DICOM padding byte will not be copied to the raw output. If
+the transfer syntax is encapsulated, or any of the necessary attributes to calculate
+the correct pixel data length are missing, all encoded bytes will be written.
+.LP
+.SH OPTIONS
+The raw output goes where it is specified or standard out.
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-quiet|silent
+.RS
+Suppress the normal description of image parameters.
+.RE
+.TP
+.B \-verbose
+.RS
+Display byte offset from file start and message start, in hexadecimal, and dump contents while reading, once read, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dctoraw expmeta.dc3 expmeta.raw
+.RE
+******** Parameters ... ********
+.RE
+(0x0028,0x0010) US Rows                       [0x0100] 
+.RE
+(0x0028,0x0011) US Columns                    [0x0100] 
+.RE
+(0x0028,0x0002) US Samples per Pixel          [0x0001] 
+.RE
+(0x0028,0x0103) US Pixel Representation       [0x0000] 
+.RE
+(0x0028,0x0004) CS Photometric Interpretation <MONOCHROME2> 
+.RE
+(0x0028,0x0100) US Bits Allocated             [0x0010] 
+.RE
+(0x0028,0x0101) US Bits Stored                [0x0010] 
+.RE
+(0x0028,0x0102) US High Bit                   [0x000f] 
+.RE
+Encapsulated    No
+.RE
+ByteOrder       Little
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcuidchg.cc b/appsrc/dcfile/dcuidchg.cc
new file mode 100644
index 0000000..17a8b24
--- /dev/null
+++ b/appsrc/dcfile/dcuidchg.cc
@@ -0,0 +1,423 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcuidchg.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrseq.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "elmconst.h"
+
+#include "hash.h"
+#include "uidgen.h"
+
+class UIDEntryString {
+	HashKeyString key;
+	const char *value;
+public:
+	UIDEntryString(void)		{}
+	UIDEntryString(const char *s,const char *v)
+					{ key=HashKeyString(s); value=v; }
+	UIDEntryString(UIDEntryString *e)
+					{ key=e->key; value=e->value; }
+
+	HashKeyString	getKey(void) const	{ return key; }
+	const char *	getValue(void) const	{ return value; }
+
+	bool operator==(UIDEntryString e)
+					{ return key == e.getKey(); }
+};
+
+class UIDEntryStringList : public SimpleList<UIDEntryString>
+{
+public:
+	~UIDEntryStringList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class UIDEntryStringListIterator : public SimpleListIterator<UIDEntryString>
+{
+public:
+	UIDEntryStringListIterator(void)
+		: SimpleListIterator<UIDEntryString>() {}
+	UIDEntryStringListIterator(UIDEntryStringList& list)
+		: SimpleListIterator<UIDEntryString>(list) {}
+};
+
+class UIDHashMap : public OpenHashTable <UIDEntryString,
+					HashKeyString,
+					UIDEntryStringList,
+					UIDEntryStringListIterator>
+{
+public:
+	UIDHashMap(unsigned long size)
+		: OpenHashTable<UIDEntryString,
+				HashKeyString,
+				UIDEntryStringList,
+				UIDEntryStringListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long	hash(const HashKeyString &key,unsigned long size)
+		{
+			const unsigned nchars = 10;
+			const unsigned shift  = 4;
+
+			unsigned n=nchars;
+			unsigned long value=0;
+			const char *s=key.getString();
+			while (n-- && *s) {
+				value=(value<<shift)|*s++;
+			}
+			return value%size; 
+		}
+
+	HashKeyString key(const UIDEntryString &e)	{ return e.getKey(); }
+};
+
+static bool
+isAttributeToBeReplaced(Attribute *a) {
+		Tag tag = a->getTag();
+		return tag != TagFromName(SOPClassUID)
+			&& tag != TagFromName(AffectedSOPClassUID)
+			&& tag != TagFromName(MediaStorageSOPClassUID)
+			&& tag != TagFromName(OriginalSpecializedSOPClassUID)
+			&& tag != TagFromName(ReferencedRelatedGeneralSOPClassUIDInFile)
+			&& tag != TagFromName(ReferencedSOPClassUID)
+			&& tag != TagFromName(ReferencedSOPClassUIDInFile)
+			&& tag != TagFromName(RelatedGeneralSOPClassUID)
+			&& tag != TagFromName(RequestedSOPClassUID)
+			&& tag != TagFromName(RelatedGeneralSOPClassUID)
+			&& tag != TagFromName(SOPClassesInStudy)
+			&& tag != TagFromName(SOPClassesSupported)
+			&& tag != TagFromName(TransferSyntaxUID)
+			&& tag != TagFromName(EncryptedContentTransferSyntaxUID)
+			&& tag != TagFromName(MACCalculationTransferSyntaxUID)
+			&& tag != TagFromName(ReferencedTransferSyntaxUIDInFile)
+			&& tag != TagFromName(CodingSchemeUID)
+			&& tag != TagFromName(ContextGroupExtensionCreatorUID)
+			&& tag != TagFromName(PrivateInformationCreatorUID)
+			&& tag != TagFromName(PrivateRecordUID);
+}
+
+static bool
+loopOverListsInSequences(Attribute *a,UIDHashMap *uidHashMap,const char *uidstamp,ofstream *mapfstr,TextOutputStream &log,
+		bool (*func)(AttributeList &,UIDHashMap *,const char *uidstamp,ofstream *mapfstr,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],uidHashMap,uidstamp,mapfstr,log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+class OurGeneratedUID : public GeneratedUID {
+public:
+	OurGeneratedUID
+			(const char *s,unsigned counter)
+		: GeneratedUID(s)
+		{
+			setUnsigned(counter);
+		}
+};
+
+static int uidcounter = 0;
+
+static bool
+changeUIDs(AttributeList& list,UIDHashMap *uidHashMap,const char *uidstamp,ofstream *mapfstr,TextOutputStream &log)
+{
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequences(a,uidHashMap,uidstamp,mapfstr,log,&::changeUIDs))
+			succeeded=false;
+		const char *vr = a->getVR();
+		if (vr && strcmp(vr,"UI") == 0) {
+			int n = a->getVM();
+			int i;
+			for (int i=0; i<n; ++i) {
+				char *originalUID;
+				if (a->getValue(i,originalUID) && originalUID && strlen(originalUID) && isAttributeToBeReplaced(a)) {
+//cerr << "Original UID = " << originalUID << endl;
+					const char *replacementUID = NULL;
+					UIDEntryString *entry = (*uidHashMap)[originalUID];
+					if (entry) {
+//cerr << "Found entry = " << entry->getKey().getString() << ", " << entry->getValue() << endl;
+						replacementUID = entry->getValue();
+					}
+					else {
+						replacementUID = StrDup(OurGeneratedUID(uidstamp,uidcounter++));
+//cerr << "Add entry = " << originalUID << ", " << replacementUID << endl;
+						(*uidHashMap)+=new UIDEntryString(StrDup(originalUID),replacementUID);
+						if (mapfstr) {
+							(*mapfstr) << "\"" << originalUID << "\" \"" << replacementUID << "\"" << endl;
+						}
+					}
+//cerr << "Replacement UID = " << replacementUID << endl;
+					a->setValue(i,replacementUID);
+				}
+			}
+		}
+		//	succeeded=false;
+		++listi;
+	}
+	return succeeded;
+}
+
+static void addUIDChangedToDeidentificationMethod(AttributeList& list)
+{
+	const char *newvalue = "replace uids (dcuidchg)";
+	Attribute *aDeidentificationMethod = list[TagFromName(DeidentificationMethod)];
+	if (aDeidentificationMethod) {
+		aDeidentificationMethod->addValue(newvalue);
+	}
+	else {
+		aDeidentificationMethod = new LongStringAttribute(TagFromName(DeidentificationMethod),newvalue);
+		list+=aDeidentificationMethod;
+	}
+}
+
+static const char *
+makeNewFileName(const char *outdir,const char *filename) {
+	Assert(outdir);
+	Assert(filename);
+	size_t outdirLength = strlen(outdir);
+	size_t filenameLength = strlen(filename);
+	const char *filenameLastSeparator = strrchr(filename,'/');
+	if (filenameLastSeparator != NULL) {
+		filename = filenameLastSeparator+1;
+		filenameLength = strlen(filename);
+//cerr << "makeNewFileName(): found last component " << filename << endl;
+	}
+	size_t length = outdirLength + 1 + filenameLength;
+	char *string=new char[length+1];
+	strcpy(string,outdir);
+	strcat(string,"/");
+	strcat(string,filename);
+	string[length]=0;
+	return string;
+}
+
+static void handleOneFile(UIDHashMap *uidHashMap,const char *outdir,const char *filename,
+			DicomInputOptions &dicom_input_options,
+			DicomOutputOptions &dicom_output_options,
+			bool listnames,bool updatedescriptor,bool success,bool verbose,
+			ofstream *mapfstr,
+			TextOutputStream &log) {
+
+		Assert(filename);
+		if (listnames) log << "Reading \"" << filename << "\"" << endl;
+
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *ifstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *ifstr=new ifstream(filename);
+#endif
+		if (!ifstr || !*ifstr || !ifstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filename) cerr <<" - \"" << filename << "\"";
+			cerr << endl;
+			success=false;
+			return;
+		}
+
+		DicomInputStream din(*(istream *)ifstr,
+			dicom_input_options.transfersyntaxuid,
+			dicom_input_options.usemetaheader);
+
+		ManagedAttributeList list;
+
+		if (verbose) log << "******** While reading ... " << filename << " ... ********" << endl;
+		list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+
+		if (!list.good()) {
+			log << list.errors()
+			    << EMsgDC(DatasetReadFailed) << endl;
+			success=false;
+			return;
+		}
+
+		// do NOT close input file yet, else deferred pixel data read for write will fail
+		
+		changeUIDs(list,uidHashMap,dicom_output_options.stamp,mapfstr,log);
+
+		if (updatedescriptor) {
+			addUIDChangedToDeidentificationMethod(list);
+		}
+
+		const char *outfilename = makeNewFileName(outdir,filename);
+		Assert(outfilename);
+		if (listnames) log << "Writing \"" << outfilename << "\"" << endl;
+		
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+		ofstream *ofstr=new ofstream(outfilename,
+			ios::out|ios::trunc|ios::binary);
+#else
+		ofstream *ofstr=new ofstream(outfilename,ios::out|ios::trunc);
+#endif
+		if (!ofstr || !*ofstr || !ofstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileWriteOpenFailed);
+			if (outfilename) cerr <<" - \"" << outfilename << "\"";
+			cerr << endl;
+			success=false;
+			return;
+		}
+		
+		DicomOutputStream dout(*(ostream *)ofstr,
+			dicom_output_options.transfersyntaxuid,
+			dicom_output_options.usemetaheader,
+			dicom_output_options.useimplicitmetaheader,
+			dicom_output_options.addtiff);
+
+		if (!usualManagedAttributeListWrite(list,dout,
+			dicom_output_options,log,verbose)) success=false;
+		
+		if (ofstr) {
+			ofstr->close();
+			delete ofstr;
+		}
+		if (outfilename) {
+			delete outfilename;
+		}
+		// Now can close input file
+		if (ifstr) {
+			ifstr->close();
+			delete ifstr;
+		}
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool listnames=options.get("l");
+	bool updatedescriptor=options.get("descriptor");
+
+	const char *outdir=0;
+	bad = !options.get("outdir",outdir) || bad;
+
+	dicom_input_options.done();
+	Assert(!dicom_input_options.filename);
+
+	dicom_output_options.done();
+
+	const char *filelistfile=0;
+	(void)(options.get("filelist",filelistfile) || options.get("f",filelistfile));
+
+	const char *mapfile=0;
+	(void)(options.get("map",mapfile));
+
+	int numberofinputfiles=!options;
+
+	const char **listoffilenames = new const char * [numberofinputfiles];
+	const char **ptr = listoffilenames;
+	const char *filename;
+
+	while(!options && (filename=options())) {
+		++options;
+		*ptr++=filename;
+	}
+
+	options.done();
+
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << output_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -outdir dirname"
+			<< " [-v|-verbose]"
+			<< " [-l]"
+			<< " [-f|-filelist filename]"
+			<< " [-map filenametowriteuidmap]"
+			<< " [-descriptor]"
+			<< " " << MMsgDC(InputFile) << " ["<< MMsgDC(InputFile) << " ...]"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (!dicom_output_options.transfersyntaxuid)
+		dicom_output_options.transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	UIDHashMap *uidHashMap = new UIDHashMap(1000);
+
+	ofstream *mapfstr=NULL;
+	if (mapfile) {
+		mapfstr=new ofstream(mapfile,ios::out|ios::trunc);
+		Assert(mapfstr);
+	}
+	
+	int i;
+	for (i=0; i < numberofinputfiles; ++i) {
+		handleOneFile(uidHashMap,outdir,listoffilenames[i],dicom_input_options,dicom_output_options,listnames,updatedescriptor,success,verbose,mapfstr,log);
+	}
+
+	if (filelistfile) {
+		ifstream *flfstr=new ifstream(filelistfile);
+		if (!flfstr || !*flfstr || !flfstr->rdbuf()->is_open()) {
+			cerr << AMsgDC(FileReadOpenFailed);
+			if (filelistfile) cerr <<" - \"" << filename << "\"";
+			cerr << endl;
+			bad=true;
+		}
+		else {
+			while (flfstr->peek() != istream::traits_type::eof()) {
+				const int lineBufferSize=2048;
+				char lineBuffer[lineBufferSize];
+				flfstr->getline(lineBuffer,2048);
+				if (strlen(lineBuffer))
+					handleOneFile(uidHashMap,outdir,lineBuffer,dicom_input_options,dicom_output_options,listnames,updatedescriptor,success,verbose,mapfstr,log);
+				// else skip blank lines
+			}
+		}
+	}
+	
+	if (mapfstr) {
+		mapfstr->close();
+		delete mapfstr;
+	}
+
+	if (numberofinputfiles && listoffilenames) delete[] listoffilenames;
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/dcfile/dcuidchg.man b/appsrc/dcfile/dcuidchg.man
new file mode 100755
index 0000000..0b91385
--- /dev/null
+++ b/appsrc/dcfile/dcuidchg.man
@@ -0,0 +1,115 @@
+.TH DCUIDCHG 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Change UIDs"
+.SH NAME
+dcuidchg \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Change UIDs consistently
+.SH SYNOPSIS
+.HP 10
+.B dcuidchg
+" inputfile1 [ inputfile2 ... ]"
+.so man1/gen.so
+.B \-outdir " dirname"
+[
+.B \-v|verbose|vv|veryverbose
+]
+[
+.B \-l
+]
+[
+.B \-f|-filelist " filename"
+]
+[
+.B \-descriptor
+]
+[
+.B \-map " filename"
+]
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcuidchg
+reads all the named dicom input files (and/or the files listed in the specified
+file) and copies them to the specified directory, changing all the instance-related UIDs
+in a consistent manner throughout the set of files.
+.LP
+Fixed UIDs such as SOP Classes and Transfer Syntaxes are not affected.
+.LP
+The UIDs obtained by two separate invocations of this utility will be different, so
+the action needs to be performed on a set of files simultaneously in order
+to maintain consistency across studies, series, frames of reference and
+in explicit references to other instances.
+.LP
+Note that the basename of the original file is used for the output file, and is
+not changed, so if the basename was derived from the SOP Instance UID, as is common
+practice, then that name would need to be changed subsequently if the UID replacement
+was being performed to prevent identity leakage.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-outdir dirname
+.RS
+The directory, which must already exist, to which the copied files are written, using
+the basename of the original filename.
+.RE
+.TP
+.B \-v|verbose
+.RS
+Display attributes as they are read and written.
+.RE
+.TP
+.B \-l
+.RS
+List filenames as they are read and written.
+.RE
+.TP
+.B \-f|filelist filename
+.RS
+A file containing a list of DICOM input files (one filename per line).
+.RE
+.TP
+.B \-descriptor
+.RS
+Add (or extend) DeidentificationMethod attribute with description of UID removal.
+.RE
+.TP
+.B \-map filename
+.RS
+A file to which is written the map of original to replacement UID values.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% ls -1 IMAGES/[0-9]*
+.RE
+IMAGES/IM0001
+.RE
+IMAGES/IM0002
+.RE
+% mkdir /tmp/IMAGES
+.RE
+% dcuidchg IMAGES/[0-9]* -outdir /tmp/NEWIMAGES
+.RE
+% ls -1 /tmp/NEWIMAGES
+.RE
+/tmp/NEWIMAGES/IM0001
+.RE
+/tmp/NEWIMAGES/IM0002
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), 
+.BR dcdtchg(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+There is a fixed length of buffer used for reading each line from the list of filenames file.
+.LP
diff --git a/appsrc/dcfile/dcunbzip2.man b/appsrc/dcfile/dcunbzip2.man
new file mode 100755
index 0000000..aa78890
--- /dev/null
+++ b/appsrc/dcfile/dcunbzip2.man
@@ -0,0 +1,31 @@
+.TH dcunbzip2 1 "23 Feb 2003" "DICOM PS3" "DICOM PS3 - Decompress deflated DICOM file"
+.SH NAME
+dcunbzip2 \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Decompress deflated DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcunbzip2 "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcunbzip2
+reads the named dicom or acr-nema input file that is compressed using the bzip2
+transfer syntax, and copies the information and pixel data to a new dicom file,
+in the explicit VR little endian uncompressed transfer syntax with a meta information
+header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcbzip2(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcunbzip2.script b/appsrc/dcfile/dcunbzip2.script
new file mode 100755
index 0000000..5368f24
--- /dev/null
+++ b/appsrc/dcfile/dcunbzip2.script
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# usage: dcunbzip2 infile outfile
+#
+#
+TMPROOT=/tmp/`basename $0`.$$
+
+DCCP=dccp
+DCRMMETA=dcrmmeta
+BZIP2=bzip2
+
+$DCRMMETA $1 $TMPROOT.0.tmp
+echo -n 'BZ' | cat - $TMPROOT.0.tmp >$TMPROOT.1.tmp
+rm $TMPROOT.0.tmp
+$BZIP2 -d < $TMPROOT.1.tmp > $TMPROOT.2.tmp
+rm $TMPROOT.1.tmp
+$DCCP $TMPROOT.2.tmp $2
+rm $TMPROOT.2.tmp
diff --git a/appsrc/dcfile/dcuncat.cc b/appsrc/dcfile/dcuncat.cc
new file mode 100644
index 0000000..6817312
--- /dev/null
+++ b/appsrc/dcfile/dcuncat.cc
@@ -0,0 +1,893 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcuncat.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrmxls.h"
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "attrseq.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+#include "uidgen.h"
+#include "sopclu.h"
+
+// The following are copied unchanged from dcmulti.cc
+
+// Define a funky derived OX class to be able to writeBase() and not activateSource() ...
+
+class OtherUnspecifiedLargeAttributeDummy : public OtherUnspecifiedLargeAttributeBase {
+public:
+	OtherUnspecifiedLargeAttributeDummy(Tag t,
+			Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+			TransferSyntax *transfersyntax,
+			Uint16 bytesinword,
+			Uint16 bitsallocated,
+			Uint16 bitsstored,
+			Uint16 highbit,
+			Uint32 length=0xffffffff)
+		: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+		{
+			srcpixeldata=0;
+
+			srcbitsallocated=bitsallocated;
+			srcbitsstored=bitsstored;
+			srchighbit=highbit;
+
+			Assert(transfersyntax);
+			setOutputEncoding(
+				transfersyntax,
+				bytesinword,bitsallocated,
+				bitsstored,highbit,length);
+		}
+
+	virtual ~OtherUnspecifiedLargeAttributeDummy()
+		{
+		}
+
+	bool activateSource(void)
+		{
+			Assert(0);	// only here to make concrete ... pixel data is actually written manually
+			return true;
+		}
+
+	bool activateSourceWithoutUnpacking(void)
+		{
+			Assert(0);	// only here to make concrete ... pixel data is actually written manually
+			return true;
+		}
+
+	DicomOutputStream& writeBase(DicomOutputStream& dout)
+		{
+			return OtherUnspecifiedLargeAttributeBase::writeBase(dout);	//protected method
+		}
+
+	TextOutputStream& writeBase(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false)
+		{
+			return OtherUnspecifiedLargeAttributeBase::writeBase(stream,dict,verbose);	//protected method
+		}
+};
+
+static Attribute *
+isValuePresentElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Assert(label);
+	Assert(filename);
+	Attribute *a=list[tag];
+	if (a && a->getVM())
+		return a;
+	else {
+		log << filename << ": " 
+		    << EMsgDC(MissingAttribute)
+		    << " - " << label
+		    << endl;
+		return 0;
+	}
+}
+
+static Uint16
+getIntegerValueElseError(AttributeList &list,Tag tag,const char *label,const char *filename,TextOutputStream &log)
+{
+	Attribute *a=isValuePresentElseError(list,tag,label,filename,log);
+	Uint16 value=AttributeValue(a);
+	return value;
+}
+
+// end of copy from dcmulti.cc
+
+static void
+removeAllPerFrameFunctionalGroupSequenceItemsExcept(AttributeList &list,SequenceAttribute *aOldPerFrameFunctionalGroupSequence,int firstFrame,int lastFrame) {
+	list-=TagFromName(PerFrameFunctionalGroupsSequence);
+	SequenceAttribute *aNewPerFrameFunctionalGroupSequence = new SequenceAttribute(TagFromName(PerFrameFunctionalGroupsSequence));
+	list+=aNewPerFrameFunctionalGroupSequence;
+	if (aOldPerFrameFunctionalGroupSequence) {
+		AttributeList **oldItems;
+		int nOldItems = aOldPerFrameFunctionalGroupSequence->getLists(&oldItems);
+		if (nOldItems) {
+			Assert(firstFrame >= 0);		// firstFrame,lastFrame begin at 0, not 1
+			Assert(firstFrame <= lastFrame);
+			Assert(lastFrame < nOldItems);
+			Assert(oldItems);
+			int i;
+			for (i=firstFrame; i<=lastFrame; ++i) {
+				Assert(oldItems[i]);
+				(*aNewPerFrameFunctionalGroupSequence)+=oldItems[i];
+			}
+		}
+	}
+}
+
+static void addFunctionalGroupContentsToTopLevel(AttributeList &list,AttributeList *functionalGroupAttributeList,bool noPrivateSequences,bool noPrivateAttributes) {
+	if (functionalGroupAttributeList) {
+		AttributeListIterator functionalGroupAttributeListIterator(*functionalGroupAttributeList);
+		while (!functionalGroupAttributeListIterator) {
+			Attribute *functionalGroupSequenceAttribute = functionalGroupAttributeListIterator();
+			if (functionalGroupSequenceAttribute && strcmp(functionalGroupSequenceAttribute->getVR(),"SQ") == 0 && (!functionalGroupSequenceAttribute->getTag().isPrivateGroup() || !noPrivateSequences)) {
+				AttributeList **functionalGroupSequenceAttributeItems;
+				int nFunctionalGroupSequenceAttributeItems = functionalGroupSequenceAttribute->getLists(&functionalGroupSequenceAttributeItems);
+				if (nFunctionalGroupSequenceAttributeItems > 0) {
+					// we will only do the first item (there is normally only one), since can't twice to the top level dataset
+					AttributeList *functionalGroupSequenceAttributeFirstItemContentList = functionalGroupSequenceAttributeItems[0];
+					if (functionalGroupSequenceAttributeFirstItemContentList) {
+						AttributeListIterator functionalGroupSequenceAttributeFirstItemContentListIterator(*functionalGroupSequenceAttributeFirstItemContentList);
+						while (!functionalGroupSequenceAttributeFirstItemContentListIterator) {
+							Attribute *a = functionalGroupSequenceAttributeFirstItemContentListIterator();
+							if (a && (!a->getTag().isPrivateGroup() || !noPrivateAttributes)) {
+								list-=a->getTag();	// remove any previous instance
+								list+=a;
+							}
+							++functionalGroupSequenceAttributeFirstItemContentListIterator;
+						}
+					}
+				}
+			}
+			++functionalGroupAttributeListIterator;
+		}
+	}
+}
+
+static void
+moveRelevantPerFrameAndSharedFunctionalGroupSequenceItemsContentsToTopLevel(AttributeList &list,SequenceAttribute *aPerFrameFunctionalGroupSequence,SequenceAttribute *aSharedFunctionalGroupsSequence,int frameNumber,bool noPrivateSequences,bool noPrivateAttributes) {
+	if (aPerFrameFunctionalGroupSequence) {
+		list-=TagFromName(PerFrameFunctionalGroupsSequence);
+		AttributeList **items;
+		int nItems = aPerFrameFunctionalGroupSequence->getLists(&items);
+		if (nItems) {
+			Assert(frameNumber >= 0);		// frameNumber begins at 0, not 1
+			Assert(frameNumber < nItems);
+			Assert(items);
+			addFunctionalGroupContentsToTopLevel(list,items[frameNumber],noPrivateSequences,noPrivateAttributes);
+		}
+	}
+
+	if (aSharedFunctionalGroupsSequence) {
+		list-=TagFromName(SharedFunctionalGroupsSequence);
+		AttributeList **items;
+		int nItems = aSharedFunctionalGroupsSequence->getLists(&items);
+		if (nItems) {
+			Assert(nItems == 1);
+			Assert(items);
+			addFunctionalGroupContentsToTopLevel(list,items[0],noPrivateSequences,noPrivateAttributes);
+		}
+	}
+}
+
+static void
+changeSOPClassToUnenhanced(AttributeList &list) {
+	char *sopClassUID = AttributeValue(list[TagFromName(SOPClassUID)]);
+	const char *newSOPClassUID = sopClassUID;
+	if (sopClassUID) {
+		if (strcmp(sopClassUID,EnhancedCTImageStorageSOPClassUID) == 0) {
+			newSOPClassUID = CTImageStorageSOPClassUID;
+		}
+		else if (strcmp(sopClassUID,EnhancedMRImageStorageSOPClassUID) == 0) {
+			newSOPClassUID = MRImageStorageSOPClassUID;
+		}
+	}
+	if (newSOPClassUID) {
+		list-=TagFromName(SOPClassUID);
+		list+=new UIStringAttribute(TagFromName(SOPClassUID),newSOPClassUID);
+
+	}
+}
+
+static bool
+isCT(AttributeList &list) {
+	char *sopClassUID = AttributeValue(list[TagFromName(SOPClassUID)]);
+	return sopClassUID && (strcmp(sopClassUID,CTImageStorageSOPClassUID) == 0 || strcmp(sopClassUID,EnhancedCTImageStorageSOPClassUID) == 0);
+}
+
+static bool
+isMR(AttributeList &list) {
+	char *sopClassUID = AttributeValue(list[TagFromName(SOPClassUID)]);
+	return sopClassUID && (strcmp(sopClassUID,MRImageStorageSOPClassUID) == 0 || strcmp(sopClassUID,EnhancedMRImageStorageSOPClassUID) == 0);
+}
+
+static bool
+isMultiFrameSOPClass(AttributeList &list) {
+	char *sopClassUID = AttributeValue(list[TagFromName(SOPClassUID)]);
+	return sopClassUID && (strcmp(sopClassUID,UltrasoundMultiframeImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,EnhancedUSVolumeStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,MultiframeSingleBitSecondaryCaptureImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,MultiframeGrayscaleByteSecondaryCaptureImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,MultiframeGrayscaleWordSecondaryCaptureImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,MultiframeTrueColorSecondaryCaptureImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,XRayAngiographicImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,EnhancedXAImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,XRayRadioFluoroscopicImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,EnhancedXRFImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,XRayAngiographicBiplaneImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,XRay3DAngiographicImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,XRay3DCraniofacialImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,BreastTomosynthesisImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,NuclearMedicineImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,VideoEndoscopicImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,VideoMicroscopicImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,VideoPhotographicImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,OphthalmicPhotography8BitImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,OphthalmicPhotography16BitImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,VLWholeSlideMicroscopyImageStorageSOPClassUID) == 0
+						|| strcmp(sopClassUID,RTImageStorageSOPClassUID) == 0
+			);
+}
+
+static void
+fixupUnenhanced(AttributeList &list) {
+	if (isMR(list)) {
+		{
+			Attribute *aScanningSequence = list[TagFromName(ScanningSequence)];
+			if (!aScanningSequence) {
+				aScanningSequence=new CodeStringAttribute(TagFromName(ScanningSequence));
+				Assert(aScanningSequence);
+			
+				char *echoPulseSequence = AttributeValue(list[TagFromName(EchoPulseSequence)]);
+				if (echoPulseSequence) {
+					if (strcmp(echoPulseSequence,"SPIN") == 0) {
+						aScanningSequence->addValue("SE");
+					}
+					else if (strcmp(echoPulseSequence,"GRADIENT") == 0) {
+						aScanningSequence->addValue("GR");
+					}
+					else if (strcmp(echoPulseSequence,"BOTH") == 0) {
+						aScanningSequence->addValue("SE");
+						aScanningSequence->addValue("GR");
+					}
+				}
+			
+				char *echoPlanarPulseSequence = AttributeValue(list[TagFromName(EchoPlanarPulseSequence)]);
+				if (echoPlanarPulseSequence) {
+					if (strcmp(echoPlanarPulseSequence,"YES") == 0) {
+						aScanningSequence->addValue("EP");
+					}
+				}
+			
+				char *inversionRecovery = AttributeValue(list[TagFromName(InversionRecovery)]);
+				if (inversionRecovery) {
+					if (strcmp(inversionRecovery,"YES") == 0) {
+						aScanningSequence->addValue("IR");
+					}
+				}
+			
+				char *contentQualification = AttributeValue(list[TagFromName(ContentQualification)]);
+				if (contentQualification) {
+					if (strcmp(contentQualification,"RESEARCH") == 0) {
+						aScanningSequence->addValue("RM");
+					}
+				}
+			
+				list+=aScanningSequence;
+			}
+		}
+		{
+			Attribute *aSequenceVariant = list[TagFromName(SequenceVariant)];
+			if (!aSequenceVariant) {
+				aSequenceVariant=new CodeStringAttribute(TagFromName(SequenceVariant));
+				Assert(aSequenceVariant);
+
+				char *steadyStatePulseSequence = AttributeValue(list[TagFromName(SteadyStatePulseSequence)]);
+				if (steadyStatePulseSequence) {
+					if (strcmp(steadyStatePulseSequence,"TIME_REVERSED") == 0) {
+						aSequenceVariant->addValue("TRSS");
+					}
+					else if (strcmp(steadyStatePulseSequence,"NONE") != 0) {
+						aSequenceVariant->addValue("SS");
+					}
+				}
+			
+				char *segmentedKSpaceTraversal = AttributeValue(list[TagFromName(SegmentedKSpaceTraversal)]);
+				if (segmentedKSpaceTraversal) {
+					if (strcmp(segmentedKSpaceTraversal,"PARTIAL") == 0) {
+						aSequenceVariant->addValue("SK");
+					}
+				}
+			
+				char *magnetizationTransfer = AttributeValue(list[TagFromName(MagnetizationTransfer)]);
+				if (magnetizationTransfer) {
+					if (strcmp(magnetizationTransfer,"NONE") != 0) {
+						aSequenceVariant->addValue("MTC");
+					}
+				}
+			
+				char *spoiling = AttributeValue(list[TagFromName(Spoiling)]);
+				if (spoiling) {
+					if (strcmp(spoiling,"NONE") != 0) {
+						aSequenceVariant->addValue("SP");
+					}
+				}
+			
+				char *t2Preparation = AttributeValue(list[TagFromName(T2Preparation)]);
+				if (t2Preparation) {
+					if (strcmp(t2Preparation,"NO") != 0) {
+						aSequenceVariant->addValue("MP");
+					}
+				}
+			
+				char *oversamplingPhase = AttributeValue(list[TagFromName(OversamplingPhase)]);
+				if (oversamplingPhase) {
+					if (strcmp(oversamplingPhase,"NONE") != 0) {
+						aSequenceVariant->addValue("OSP");
+					}
+				}
+			
+				if (aSequenceVariant->getVM() == 0) {
+					aSequenceVariant->addValue("NONE");
+				}
+
+				list+=aSequenceVariant;
+			}
+		}
+		{
+			Attribute *aScanOptions = list[TagFromName(ScanOptions)];
+			if (!aScanOptions) {
+				aScanOptions=new CodeStringAttribute(TagFromName(ScanOptions));
+			
+				char *rectilinearPhaseEncodeReordering = AttributeValue(list[TagFromName(RectilinearPhaseEncodeReordering)]);
+//cerr << "rectilinearPhaseEncodeReordering = " << rectilinearPhaseEncodeReordering << endl;
+				if (rectilinearPhaseEncodeReordering) {
+					if (!(strcmp(rectilinearPhaseEncodeReordering,"UNKNOWN") == 0 || strcmp(rectilinearPhaseEncodeReordering,"NONE") == 0)) {	// neither of these are defined terms in the standard, but type 1 :(
+						aScanOptions->addValue("PER");
+					}
+				}
+				
+				char *respiratoryMotionCompensationTechnique = AttributeValue(list[TagFromName(RespiratoryMotionCompensationTechnique)]);
+				if (respiratoryMotionCompensationTechnique) {
+					if (strcmp(respiratoryMotionCompensationTechnique,"NONE") != 0) {
+						aScanOptions->addValue("RG");
+					}
+				}
+				
+				char *cardiacSynchronizationTechnique = AttributeValue(list[TagFromName(CardiacSynchronizationTechnique)]);
+				if (cardiacSynchronizationTechnique) {
+					if (strcmp(cardiacSynchronizationTechnique,"NONE") != 0) {
+						char *cardiacSignalSource = AttributeValue(list[TagFromName(CardiacSignalSource)]);
+						if (cardiacSignalSource && strcmp(cardiacSignalSource,"PP") == 0) {
+							aScanOptions->addValue("PPG");
+						}
+						else {
+							aScanOptions->addValue("CG");
+						}
+					}
+				}
+	
+				char *flowCompensation = AttributeValue(list[TagFromName(FlowCompensation)]);
+				if (flowCompensation) {
+					if (strcmp(flowCompensation,"NONE") != 0) {
+						aScanOptions->addValue("FC");
+					}
+				}
+				
+				char *partialFourier = AttributeValue(list[TagFromName(PartialFourier)]);
+				if (partialFourier && strcmp(partialFourier,"YES") == 0) {
+					char *partialFourierDirection = AttributeValue(list[TagFromName(PartialFourierDirection)]);		// may be present even if PartialFourier == NO, so check first
+					if (partialFourierDirection) {
+						if (strcmp(partialFourierDirection,"FREQUENCY") == 0) {
+							aScanOptions->addValue("PFF");
+						}
+						else if (strcmp(partialFourierDirection,"PHASE") == 0) {
+							aScanOptions->addValue("PFP");
+						}
+						else if (strcmp(partialFourierDirection,"COMBINATION") == 0) {
+							aScanOptions->addValue("PFF");
+							aScanOptions->addValue("PFP");
+						}
+					}
+				}
+				
+				char *spatialPresaturation = AttributeValue(list[TagFromName(SpatialPresaturation)]);
+				if (spatialPresaturation) {
+					if (strcmp(spatialPresaturation,"NONE") != 0) {
+						aScanOptions->addValue("SP");
+					}
+				}
+	
+				char *spectrallySelectedSuppression = AttributeValue(list[TagFromName(SpectrallySelectedSuppression)]);
+				if (spectrallySelectedSuppression) {
+					if (strcmp(spectrallySelectedSuppression,"FAT") == 0) {		// there are many other defined terms for other substances and combinations :(
+						aScanOptions->addValue("FS");
+					}
+				}
+	
+				list+=aScanOptions;
+			}
+		}
+		{
+			char *inPlanePhaseEncodingDirection = AttributeValue(list[TagFromName(InPlanePhaseEncodingDirection)]);
+			if (inPlanePhaseEncodingDirection && strcmp(inPlanePhaseEncodingDirection,"COLUMN") == 0) {
+				list-=TagFromName(InPlanePhaseEncodingDirection);
+				list+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),"COL");	// gratuitious difference between old and new MR objects that is too late to fix with a CP. since enumerated values :(
+			}
+		}
+		{
+			Attribute *aEchoTime = list[TagFromName(EchoTime)];
+			if (!aEchoTime) {
+				Float32 effectiveEchoTime = AttributeValue(list[TagFromName(EffectiveEchoTime)]);
+				list+=new DecimalStringAttribute(TagFromName(EchoTime),effectiveEchoTime);
+			}
+		}
+		{
+			Attribute *aInversionTime = list[TagFromName(InversionTime)];
+			if (!aInversionTime) {
+				Attribute *aInversionTimes = list[TagFromName(InversionTimes)];
+				if (aInversionTimes && aInversionTimes->getVM() > 0) {
+					Float32 inversionTime = AttributeValue(aInversionTimes);		// use 1st value only, even if multiple
+					list+=new DecimalStringAttribute(TagFromName(InversionTime),inversionTime);
+				}
+			}
+		}
+		{
+			Attribute *aTriggerTime = list[TagFromName(TriggerTime)];
+			if (!aTriggerTime) {
+				Attribute *aNominalCardiacTriggerDelayTime = list[TagFromName(NominalCardiacTriggerDelayTime)];
+				if (aNominalCardiacTriggerDelayTime && aNominalCardiacTriggerDelayTime->getVM() > 0) {
+					Float32 nominalCardiacTriggerDelayTime = AttributeValue(aNominalCardiacTriggerDelayTime);
+					list+=new DecimalStringAttribute(TagFromName(TriggerTime),nominalCardiacTriggerDelayTime);
+				}
+			}
+		}
+	}
+	else if (isCT(list)) {
+	}
+	
+	if (isCT(list) || isMR(list)) {
+		{
+			Attribute *aSliceThickness = list[TagFromName(SliceThickness)];
+			if (!aSliceThickness) {
+				list+=new DecimalStringAttribute(TagFromName(SliceThickness));		// Type 2
+			}
+		}
+		{
+			Attribute *aLaterality = list[TagFromName(Laterality)];
+			if (!aLaterality || aLaterality->getVM() == 0) {
+				Attribute *aFrameLaterality = list[TagFromName(FrameLaterality)];
+				if (aFrameLaterality && aFrameLaterality->getVM() > 0) {
+					char *frameLaterality = AttributeValue(aFrameLaterality);
+					const char *laterality = frameLaterality;
+					if (frameLaterality) {
+						if (strcmp(frameLaterality,"U") == 0 || strcmp(frameLaterality,"B") == 0) {
+							laterality="";
+						}
+					}
+					list-=TagFromName(Laterality);
+					list+=new CodeStringAttribute(TagFromName(Laterality),laterality);
+				}
+			}
+		}
+	}
+	
+	if (isMultiFrameSOPClass) {
+		list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),Uint16(1));
+	}
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	DicomInputOptions 	dicom_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+	
+	if (!dicom_output_options.filename) {
+		cerr << "Must explicitly specify output file prefix using -of option" << endl;
+		bad=true;
+	}
+	
+	bool verbose=options.get("verbose") || options.get("v");
+	bool ignorereaderrors=options.get("ignorereaderrors");
+	bool replaceSeriesNumberAndUID=!options.get("sameseries");
+	bool insertConcatenationAttributes=!options.get("noconcat");
+	
+	int instanceNumberOffset = 0;
+	bool replaceInstanceNumber=options.get("instancenumber");
+	if (options.get("instancenumberstart",instanceNumberOffset)) {
+		--instanceNumberOffset;		// if want to actually start from 1 as specified, offset needs to be 0
+		replaceInstanceNumber=true;
+	}
+	
+	bool replaceFrameIncrementPointerWithInstanceNumber=options.get("frameincrementpointerinstancenumber");
+	bool replaceVectors=options.get("vectorupdate");
+	bool unenhance=options.get("unenhance");
+	bool noPrivateSequences=options.get("noprivateseq");
+	bool noPrivateAttributes=options.get("noprivateattr");
+	
+	if ((noPrivateSequences || noPrivateAttributes) && !unenhance) {
+		cerr << "Cannot specify \"noprivateseq\" or \"noprivateattr\" without \"unenhance\"" << endl;
+		bad=true;
+	}
+	
+	int framesPerEachInstanceOfConcatenation = 1;
+	if (!options.get("framesper",framesPerEachInstanceOfConcatenation) && !unenhance) {
+		cerr << "Must specify \"framesper\" - number of frames per each instance of the concatentation, if not unenhancing" << endl;
+		bad=true;
+	}
+	else {
+		if (unenhance && framesPerEachInstanceOfConcatenation != 1) {
+			cerr << "Must specify \"framesper\" of exactly one frame when unenhance option specified " << dec << framesPerEachInstanceOfConcatenation << endl;
+			bad=true;
+		}
+		else if (framesPerEachInstanceOfConcatenation < 0) {
+			cerr << "Must specify \"framesper\" with more than one frame - got " << dec << framesPerEachInstanceOfConcatenation << endl;
+			bad=true;
+		}
+	}
+
+	if (replaceFrameIncrementPointerWithInstanceNumber && !replaceInstanceNumber) {
+		cerr << "Cannot specify \"frameincrementpointerinstancenumber\" without \"instancenumber\"" << endl;
+		bad=true;
+	}
+	
+	if (replaceFrameIncrementPointerWithInstanceNumber && replaceVectors) {
+		cerr << "Cannot specify \"frameincrementpointerinstancenumber\" and \"vectorupdate\"" << endl;
+		bad=true;
+	}
+	
+	dicom_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	DicomInputOpenerFromOptions input_opener(
+		options,dicom_input_options.filename,cin);
+
+	cerr << dicom_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!dicom_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< dicom_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -framesper n"
+			<< " [-unenhance [-noprivateseq] [-noprivateattr]]"
+			<< " [-instancenumber|[-instancenumberstart n]]"
+			<< " [-frameincrementpointerinstancenumber|vectorupdate]"
+			<< " [-sameseries]"
+			<< " [-noconcat]"
+			<< " [-v|-verbose]"
+			<< " [-ignorereaderrors]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+	
+	bool success=true;
+	TextOutputStream log(cerr);
+
+	// Strategy is to keep reading the same file over again, writing it each time
+	// such that only the frames relevant to that part of the concatenation are
+	// written on each occasion
+	
+	DicomInputStream din(*(istream *)input_opener,
+		dicom_input_options.transfersyntaxuid,
+		dicom_input_options.usemetaheader);
+
+	const char *inputFilename = dicom_input_options.filename ? dicom_input_options.filename : "";
+	ManagedAttributeList list;
+	if (verbose) log << "******** While reading ... ********" << endl; 
+	list.read(din,&log,verbose,0xffffffff,true,dicom_input_options.uselengthtoend,dicom_input_options.ignoreoutofordertags,dicom_input_options.useUSVRForLUTDataIfNotExplicit);
+	if (!list.good()) {
+		if (!ignorereaderrors) {
+			log << list.errors();
+			return 1;
+		}
+		log << EMsgDC(DatasetReadFailed) << endl;
+	}
+	// Get pixel data attribute for later use, then remove it from the list ...
+	Attribute *apixeldata=list[TagFromName(PixelData)];
+	if (!apixeldata) {
+		log << EMsgDC(MissingAttribute) << " - \"PixelData\"" << endl;
+		return 1;
+	}
+	else {
+		list-=TagFromName(PixelData);
+	}
+
+	int numberOfFrames = getIntegerValueElseError(list,TagFromName(NumberOfFrames),"Number of Frames",inputFilename,log);
+	if (numberOfFrames < 1) {
+		log << "Number of frames in input must be > 0" << endl;
+		return 1;
+	}
+	Uint16  inConcatenationTotalNumber = (numberOfFrames-1)/framesPerEachInstanceOfConcatenation+1;
+
+	Uint16 vSeriesNumber = Uint16(AttributeValue(list[TagFromName(SeriesNumber)],1)) + (replaceSeriesNumberAndUID ? 7000 : 0);
+	char *studystring = AttributeValue(list[TagFromName(StudyID)]);
+	Uint16 studyNumber = studystring ? atoi(studystring) : 0;
+	char *vSeriesInstanceUID = replaceSeriesNumberAndUID ? StrDup(GeneratedSeriesInstanceUID(dicom_output_options.stamp,studyNumber,vSeriesNumber)) : AttributeValue(list[TagFromName(SeriesInstanceUID)]);
+//cerr << "vSeriesInstanceUID=" << vSeriesInstanceUID << endl;
+	Uint16 vInstanceNumber = Uint16(AttributeValue(list[TagFromName(InstanceNumber)],double(0)));
+	char *vConcatenationUID = StrDup(GeneratedConcatenationUID(dicom_output_options.stamp,studyNumber,vSeriesNumber,vInstanceNumber));
+	//cerr << "vConcatenationUID=" << vConcatenationUID << endl;
+	char *vSOPInstanceUIDOfConcatenationSource = StrDup(AttributeValue(list[TagFromName(SOPInstanceUID)]));
+	//cerr << "vSOPInstanceUIDOfConcatenationSource=" << vSOPInstanceUIDOfConcatenationSource << endl;
+
+	SequenceAttribute *aPerFrameFunctionalGroupSequence = (SequenceAttribute *)list[TagFromName(PerFrameFunctionalGroupsSequence)];
+	list-=TagFromName(PerFrameFunctionalGroupsSequence);
+	SequenceAttribute *aSharedFunctionalGroupsSequence = (SequenceAttribute *)list[TagFromName(SharedFunctionalGroupsSequence)];
+	list-=TagFromName(PerFrameFunctionalGroupsSequence);
+
+	//if (unenhance) {										// why not leave them ? If not, should also remove DimensionIndexValues :(
+	//	list-=TagFromName(DimensionOrganizationSequence);
+	//	list-=TagFromName(DimensionIndexSequence);
+	//}
+	
+	Uint16            rows=getIntegerValueElseError(list,TagFromName(Rows),"Rows",inputFilename,log);
+	Uint16         columns=getIntegerValueElseError(list,TagFromName(Columns),"Columns",inputFilename,log);
+	Uint16 samplesPerPixel=getIntegerValueElseError(list,TagFromName(SamplesPerPixel),"Samples per Pixel",inputFilename,log);
+	Uint16   bitsAllocated=getIntegerValueElseError(list,TagFromName(BitsAllocated),"Bits Allocated",inputFilename,log);
+	Uint16      bitsStored=getIntegerValueElseError(list,TagFromName(BitsStored),"Bits Stored",inputFilename,log);
+	Uint16         highBit=getIntegerValueElseError(list,TagFromName(HighBit),"High Bit",inputFilename,log);
+	
+	AttributeList cacheOfFrameIncrementPointerVectors;
+
+	int concatenationFrameOffsetNumber;
+	int inConcatenationNumber;
+	for (concatenationFrameOffsetNumber=0,inConcatenationNumber=1;
+			concatenationFrameOffsetNumber < numberOfFrames;
+			concatenationFrameOffsetNumber+=framesPerEachInstanceOfConcatenation,++inConcatenationNumber) {
+		
+		// Figure out how many frames to copy this time around ...
+		int firstFrame = concatenationFrameOffsetNumber;
+		int lastFrame = firstFrame + framesPerEachInstanceOfConcatenation - 1;
+		if (lastFrame >= numberOfFrames) lastFrame=numberOfFrames-1;
+		int frameCountThisInstance = lastFrame-firstFrame+1;
+//cerr << "concatenationFrameOffsetNumber=" << dec << concatenationFrameOffsetNumber << endl;
+//cerr << "firstFrame=" << dec << firstFrame << endl;
+//cerr << "lastFrame=" << dec << lastFrame << endl;
+//cerr << "frameCountThisInstance=" << dec << frameCountThisInstance << endl;
+//cerr << "numberOfFrames=" << dec << numberOfFrames << endl;
+
+		Uint16 inConcatenationNumber = firstFrame/framesPerEachInstanceOfConcatenation+1;
+//cerr << "adding InConcatenationNumber=" << dec << inConcatenationNumber << endl;
+		{
+			list-=TagFromName(InConcatenationNumber);
+			list-=TagFromName(InConcatenationTotalNumber);
+			list-=TagFromName(ConcatenationFrameOffsetNumber);
+			list-=TagFromName(ConcatenationUID);
+			list-=TagFromName(SOPInstanceUIDOfConcatenationSource);
+		}
+		if (insertConcatenationAttributes) {
+			list+=new UnsignedShortAttribute(TagFromName(InConcatenationNumber),inConcatenationNumber);
+			list+=new UnsignedShortAttribute(TagFromName(InConcatenationTotalNumber),inConcatenationTotalNumber);
+			list+=new UnsignedLongAttribute(TagFromName(ConcatenationFrameOffsetNumber),firstFrame);
+			list+=new UIStringAttribute(TagFromName(ConcatenationUID),vConcatenationUID);
+			list+=new UIStringAttribute(TagFromName(SOPInstanceUIDOfConcatenationSource),vSOPInstanceUIDOfConcatenationSource);
+		}
+		
+		if (replaceSeriesNumberAndUID) {
+			list-=TagFromName(SeriesNumber);
+			list+=new IntegerStringAttribute(TagFromName(SeriesNumber),vSeriesNumber);
+			list-=TagFromName(SeriesInstanceUID);
+			list+=new UIStringAttribute(TagFromName(SeriesInstanceUID),vSeriesInstanceUID);
+		}
+		
+		if (replaceInstanceNumber) {
+			list-=TagFromName(InstanceNumber);
+			list+=new IntegerStringAttribute(TagFromName(InstanceNumber),Uint32(instanceNumberOffset + inConcatenationNumber));	// will increment by from 1 for degenerate case of framesPerEachInstanceOfConcatenation == 1
+		}
+		
+		Attribute *aFrameIncrementPointer = list[TagFromName(FrameIncrementPointer)];
+		if (replaceFrameIncrementPointerWithInstanceNumber) {
+			list-=TagFromName(FrameIncrementPointer);
+			list+=new AttributeTagAttribute(TagFromName(FrameIncrementPointer),TagFromName(InstanceNumber));
+			
+			// remove vectors that might previously have been referenced and now do not match frames ...
+			list-=TagFromName(EnergyWindowVector);
+			list-=TagFromName(DetectorVector);
+			list-=TagFromName(PhaseVector);
+			list-=TagFromName(RotationVector);
+			list-=TagFromName(RRIntervalVector);
+			list-=TagFromName(TimeSlotVector);
+			list-=TagFromName(SliceVector);
+			list-=TagFromName(AngularViewVector);
+			list-=TagFromName(TimeSliceVector);
+			
+			list-=TagFromName(NumberOfPhases);
+			list-=TagFromName(NumberOfRotations);
+			list-=TagFromName(NumberOfRRIntervals);
+			list-=TagFromName(NumberOfTimeSlots);
+			list-=TagFromName(NumberOfSlices);
+
+			list-=TagFromName(FrameTimeVector);
+			
+			list-=TagFromName(PageNumberVector);
+			list-=TagFromName(FrameLabelVector);
+			list-=TagFromName(FramePrimaryAngleVector);
+			list-=TagFromName(FrameSecondaryAngleVector);
+			list-=TagFromName(SliceLocationVector);
+			list-=TagFromName(DisplayWindowLabelVector);
+			
+			list-=TagFromName(GridFrameOffsetVector);
+		}
+		else if (replaceVectors && frameCountThisInstance == 1 && aFrameIncrementPointer && aFrameIncrementPointer->isTag() && aFrameIncrementPointer->getVM() > 0) {
+			int n = aFrameIncrementPointer->getVM();
+			for (unsigned i=0; i<n; ++i) {
+				Tag tag;
+				if (aFrameIncrementPointer->getValue(i,tag)) {
+					Attribute *aVector = cacheOfFrameIncrementPointerVectors[tag];
+					if (aVector == NULL) {
+//cerr << "lazy instantiation of copy of vector (" << hex << tag.getGroup() << "," << tag.getElement() << ")" << dec << endl;
+						aVector = list[tag];
+						if (aVector != NULL) {
+							cacheOfFrameIncrementPointerVectors+=aVector;
+						}
+					}
+					list-=tag;	// remove from  output regardless
+					if (aVector && aVector->getVM() > 0) {
+//cerr << "doing vector (" << hex << tag.getGroup() << "," << tag.getElement() << ")" << dec << endl;
+						if (aVector->getVM() >= inConcatenationNumber) {
+							int vectorIndex = inConcatenationNumber-1;
+							const char *vr = aVector->getVR();
+							if (strcmp(vr,"US") == 0) {
+								Uint16 valueForFrame;
+								if (aVector->getValue(vectorIndex,valueForFrame)) {
+//cerr << "doing vector (" << hex << tag.getGroup() << "," << tag.getElement() << ") frame[" << dec << inConcatenationNumber << "] vr = " <<  vr << " value = " << valueForFrame << endl;
+									list+=new UnsignedShortAttribute(tag,valueForFrame);
+								}
+							}
+							else if (strcmp(vr,"IS") == 0) {
+								Int32 valueForFrame;
+								if (aVector->getValue(vectorIndex,valueForFrame)) {
+//cerr << "doing vector (" << hex << tag.getGroup() << "," << tag.getElement() << ") frame[" << dec << inConcatenationNumber << "] vr = " <<  vr << " value = " << valueForFrame << endl;
+									list+=new IntegerStringAttribute(tag,valueForFrame);
+								}
+							}
+							else if (strcmp(vr,"DS") == 0) {
+								Float64 valueForFrame;
+								if (aVector->getValue(vectorIndex,valueForFrame)) {
+//cerr << "doing vector (" << hex << tag.getGroup() << "," << tag.getElement() << ") frame[" << dec << inConcatenationNumber << "] vr = " <<  vr << " value = " << valueForFrame << endl;
+									list+=new DecimalStringAttribute(tag,valueForFrame);
+								}
+							}
+							else if (strcmp(vr,"SH") == 0) {
+								char *valueForFrame;
+								if (aVector->getValue(vectorIndex,valueForFrame)) {
+//cerr << "doing vector (" << hex << tag.getGroup() << "," << tag.getElement() << ") frame[" << dec << inConcatenationNumber << "] vr = " <<  vr << " value = " << valueForFrame << endl;
+									list+=new ShortStringAttribute(tag,valueForFrame);
+								}
+							}
+
+						}
+					}
+				}
+			}
+		}
+		
+		// For the following, new ones are added automatically during list write ...
+//cerr << "removing UIDs" << endl;
+		list-=TagFromName(SOPInstanceUID);
+		list-=TagFromName(InstanceCreationDate);
+		list-=TagFromName(InstanceCreationTime);
+		
+		// Select out only the per-frame items we want
+		
+		list-=TagFromName(NumberOfFrames);
+		if (unenhance) {
+			Assert(firstFrame == lastFrame);
+			moveRelevantPerFrameAndSharedFunctionalGroupSequenceItemsContentsToTopLevel(list,aPerFrameFunctionalGroupSequence,aSharedFunctionalGroupsSequence,firstFrame,noPrivateSequences,noPrivateAttributes);
+			changeSOPClassToUnenhanced(list);
+			fixupUnenhanced(list);		// will add value of 1 for NumberOfFrames only if required for SOP Class
+		}
+		else {
+			list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),Uint16(frameCountThisInstance));
+			removeAllPerFrameFunctionalGroupSequenceItemsExcept(list,aPerFrameFunctionalGroupSequence,firstFrame,lastFrame);
+		}
+		
+		// Start writing, first the list, then the pixel data base, then the selected pixel data frames
+		
+		const char *outputFileName;
+		{
+			ostrstream ostr;
+			if (dicom_output_options.filename) ostr << dicom_output_options.filename;
+			ostr << (instanceNumberOffset + inConcatenationNumber) << ends;				// include offset to match instance number
+			outputFileName=ostr.str();
+		}
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+		ofstream out(outputFileName,ios::out|ios::trunc|ios::binary);
+#else
+		ofstream out(outputFileName,ios::out|ios::trunc);
+#endif
+		if (!out || !out.rdbuf()->is_open()) {
+			log << EMsgDC(FileWriteOpenFailed)
+				<< " - \"" << outputFileName << "\"" << endl;
+			return false;
+		}
+		DicomOutputStream dout(out,
+			dicom_output_options.transfersyntaxuid,
+			dicom_output_options.usemetaheader,
+			dicom_output_options.useimplicitmetaheader,
+			dicom_output_options.addtiff);
+
+//cerr << "Calling usualManagedAttributeListWrite for file " << outputFileName << endl;
+		if (!usualManagedAttributeListWrite(list,dout,dicom_output_options,log,verbose)) {
+			success=false;
+			break;
+		}
+//cerr << "Finished usualManagedAttributeListWrite" << endl;
+		
+		OtherUnspecifiedLargeAttributeDummy *dummyPixelData = new
+			OtherUnspecifiedLargeAttributeDummy(TagFromName(PixelData),
+				rows,columns,frameCountThisInstance,samplesPerPixel,
+				dout.getTransferSyntaxToWriteDataSet(),
+				0 /* let encoding rules calculate bytesinword */,
+				bitsAllocated,bitsStored,highBit,
+				0xffffffff /* let encoding rules calculate length */);
+		Assert(dummyPixelData);
+		dummyPixelData->writeBase(dout);
+
+		Assert(apixeldata);
+		if (!apixeldata->isOtherData()) {
+			log << EMsgDC(PixelDataIncorrectVR) << endl;
+			success=false;
+			break;
+		}
+		else {
+			// Check for compatible transfer syntax and append to pixel data ...
+			TransferSyntax *its=din.getTransferSyntaxToReadDataSet();
+			Assert(its);
+			TransferSyntax *ots=dout.getTransferSyntaxToWriteDataSet();
+			Assert(ots);
+
+			if (its->isEncapsulated()) {
+				log << "Can't read encapsulated transfer syntax from file <" << inputFilename << ">" << endl;
+				success=false;
+				break;
+			}
+			else if (its->getEndian() != ots->getEndian()) {
+				log << "Input byte order in input file <" << inputFilename << "> differs from output - not supported" << endl;
+				success=false;
+				break;
+			}
+			else {
+				OtherUnspecifiedLargeAttributeBase *opixeldata = apixeldata->castToOtherData();
+				Assert(opixeldata);
+				Uint32 bytesPerFrame = opixeldata->getDestinationBytesPerFrame();
+				Uint32 offset = bytesPerFrame*firstFrame;
+				Uint32 length = bytesPerFrame*frameCountThisInstance;
+//cerr << "offset=" << dec << offset << " length=" << length << endl;
+				opixeldata->writeRaw(dout,offset,length);
+			}
+		}
+
+	}
+
+	return success ? 0 : 1;
+}
+
+	
diff --git a/appsrc/dcfile/dcuncat.man b/appsrc/dcfile/dcuncat.man
new file mode 100755
index 0000000..8b3ca36
--- /dev/null
+++ b/appsrc/dcfile/dcuncat.man
@@ -0,0 +1,133 @@
+.TH DCUNCAT 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Split into concatenation instances"
+.SH NAME
+dcuncat \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Split multiframe image into concatenation
+.SH SYNOPSIS
+.HP 10
+.B dcuncat
+.so man1/gen.so
+.B \-framesper " n "
+[
+.B \-unenhance
+]
+[
+.B \-noprivateseq
+]
+[
+.B \-noprivateattr
+]
+[
+.B \-sameseries
+]
+[
+.B \-instancenumber
+]
+[
+.B \-instancenumberstart " n "
+]
+[
+.B \-frameincrementpointerinstancenumber
+]
+[
+.B \-noconcat
+]
+[
+.B \-v|verbose
+]
+[
+.B \-ignorereaderrors
+]
+" inputfile1 "
+.B \-of " outputprefix "
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B dcuncat
+reads the named dicom multi frame input file, and splits it into a concatenation
+of smaller instances, which will be written to files in the specified output path with the
+InstanceNumber or InConcatenationNumber appended.
+.LP
+The concatenation instances will be placed in a new series generated from the old
+series number plus 7000, unless specified otherwise.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-v|verbose
+.RS
+List sort order and which file contributes to which frame as it is written.
+.RE
+.TP
+.B \-framesper n
+.RS
+Required. Specifies the number of frames per concatenation instance.
+.RE
+.TP
+.B \-unenhance
+.RS
+Convert enhanced IODs to old unenhanced by removing per-frame and shared functional group sequences and moving their contents to the top level dataset. Implies framesper of 1.
+Also adds NumberOfFrames based on SOP Class. May be specified even if source not enhanced, to avoid (empty) functional group sequences being added.
+.RE
+.TP
+.B \-noprivateseq
+.RS
+When unenhancing, do not examine private functional group sequences. If not specified, default is to copy all attributes (standard or private) from within private functional group sequences,
+which in the case of some vendors who hide "fallback" unenhanced object attributes in private functional groups may give better results.
+.RE
+.TP
+.B \-noprivateattr
+.RS
+When unenhancing, do not copy private attributes from within functional groups (private or standard). Does not suppress examination of private functional groups. Note that
+the use of \-removeprivate may also be required, if any existing top level private attributes are to be removed as well.
+.RE
+.TP
+.B \-sameseries
+.RS
+Do not create a new series but rather add to the existing series.
+.RE
+.TP
+.B \-instancenumber
+.RS
+Replace InstanceNumber with an incrementing value starting with 1.
+.RE
+.TP
+.B \-instancenumberstart n
+.RS
+Replace InstanceNumber with an incrementing value starting with n (do not need to specify \-instancenumber); will be reflected in the output filename as well.
+.RE
+.TP
+.B \-frameincrementpointerinstancenumber
+.RS
+Replace FrameIncrementPointer with a value pointing to InstanceNumber, removing any related vectors.
+.RE
+.TP
+.B \-vectorupdate
+.RS
+If FrameIncrementPointer is present in source and output is one frame per instance, extract single frame-specific vector value for all
+vectors referenced by FrameIncrementPointer and replace those vectors.
+.RE
+.TP
+.B \-noconcat
+.RS
+Do not insert concatenation related attributes (always removes old ones whether this option is specified or not).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1), 
+.BR dcmulti(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+The unehance option is supported for copying of CT and MR attributes only at this time.
+.LP
+Only MR objects are currently "cleaned up" to populate missing or incomplete required attributes at this time.
diff --git a/appsrc/dcfile/dcunjls.man b/appsrc/dcfile/dcunjls.man
new file mode 100755
index 0000000..daa5f3d
--- /dev/null
+++ b/appsrc/dcfile/dcunjls.man
@@ -0,0 +1,31 @@
+.TH DCUNJLS 1 "10 August 2006" "DICOM PS3" "DICOM PS3 - Decompress JPEG-LS DICOM file"
+.SH NAME
+dcunjls \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Decompress JPEG-LS DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcunjls "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcunjls
+reads the named dicom input file that is compressed using a lossless or near-lossless JPEG-LS (14495-1)
+transfer syntax, and copies the information and pixel data to a new dicom file,
+in the explicit VR little endian uncompressed transfer syntax with a meta information
+header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcjls(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/dcunjls.script b/appsrc/dcfile/dcunjls.script
new file mode 100755
index 0000000..5ab97c4
--- /dev/null
+++ b/appsrc/dcfile/dcunjls.script
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# usage: dcunjls infile outfile
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+ANCREATE=ancreate
+DCCP=dccp
+DCDUMP=dcdump
+DCTORAW=dctoraw
+DCKEY=dckey
+JLS=rawnjl2
+
+infile="$1"
+shift
+outfile="$1"
+shift
+
+dccpoptions=" -nodisclaimer"
+
+transfersyntaxuid=`"$DCKEY" -k TransferSyntaxUID "$infile" 2>&1 | egrep -v 'Error|Warning'`
+
+bits=`"$DCKEY" -decimal -k BitsAllocated "$infile" 2>&1 | egrep -v 'Error|Warning'`
+#echo "bits=$bits"
+
+# note that we used dcdump and not andump to make $TMPROOT.pixelhead, because it computes the right VL !!
+if [ $bits = 8 ]
+then
+	# leave pixel data as OB
+	"$DCDUMP" "$infile" 2>&1 | grep '10) OX Pixel Data' | sed -e 's/$/ []/' | "$ANCREATE" -e > "$TMPROOT.pixelhead"
+else
+	# make pixel data OW
+	"$DCDUMP" "$infile" 2>&1 | grep '10) OX Pixel Data' | sed -e 's/$/ []/' -e 's/VR=<OB>/VR=<OW>/' | "$ANCREATE" -e > "$TMPROOT.pixelhead"
+fi
+ 
+"$DCTORAW" -quiet "$infile" "$TMPROOT.jls" 2>/dev/null
+
+"$JLS" -d -output-endian little "$TMPROOT.jls" "$TMPROOT.raw.littleendian"
+rm "$TMPROOT.jls"
+
+"$DCCP" "$infile" "$TMPROOT.nopixels" -d PixelData $dccpoptions 2>&1 | egrep -v 'Error|Warning'
+cat "$TMPROOT.nopixels" "$TMPROOT.pixelhead" "$TMPROOT.raw.littleendian" > "$outfile"
+rm "$TMPROOT.nopixels" "$TMPROOT.pixelhead" "$TMPROOT.raw.littleendian"
+
+exit 0
diff --git a/appsrc/dcfile/dcunjpeg.20000802 b/appsrc/dcfile/dcunjpeg.20000802
new file mode 100755
index 0000000..6e4a5f9
--- /dev/null
+++ b/appsrc/dcfile/dcunjpeg.20000802
@@ -0,0 +1 @@
+#!/bin/sh

# usage: dcunjpeg infile outfile
#
# only works for 16 not 8 bits due to hardwired OW

TMPROOT=/tmp/`basename $0`.$$

ANCREATE=ancreate
DCCP=dccp
DCDUMP=dcdump
DCTORAW=dctoraw
JPEG=jpeg

bitsallocatedhex=`dckey -k BitsAllocated "$1" 2>&1`
bitsallocatedhigh=`echo "$bitsallocatedhex" | sed -e 's/0[xX][0-9aAbBcCdDeEfF]*\([0-9aAbBcCdDeEfF]\)[0-9aAbBcCdDeEfF]$/\1/' | sed -e 's/[aA]/10/' -e 's/[bB]/11/' -e 's/[cC]/12/' -e 's/[dD]/13/' -e 's/[eE]/14/' -e 's/[fF]/15/'`
bitsallocatedlow=`echo "$bitsallocatedhex" | sed -e 's/0[xX][0-9aAbBcCdDeEfF]*\([0-9aAbBcCdDeEfF]\)$/\1/' | sed -e 's/[aA]/10/' -e 's/[bB]/11/' -e 's/[cC]/12/' -e 's/[dD]/13/' -e 's/[eE]/14/' -e 's/[fF]/15/'`
bitsallocated=`expr "$bitsallocatedhigh" '*' 16 + "$bitsallocatedlow"`

if [ "$bitsallocated" -le 8 ]
then
	oborowsed='s/VR=<O[BW]>/VR=<OB>/'
else
	oborowsed='s/VR=<O[BW]>/VR=<OW>/'
fi

$DCDUMP $1 2>&1 | grep '10) OX Pixel Data' | sed -e 's/$/ []/' -e "$oborowsed" | $ANCREATE -e > $TMPROOT.pixelhead
$DCTORAW -quiet $1 $TMPROOT.jpg
$JPEG -d $TMPROOT
dd if=$TMPROOT of=$TMPROOT.raw.littleendian conv=swab
$DCCP $1 $TMPROOT.nopixels -d PixelData
cat $TMPROOT.nopixels $TMPROOT.pixelhead $TMPROOT.raw.littleendian > $2

rm -f $TMPROOT*

exit 0
\ No newline at end of file
diff --git a/appsrc/dcfile/dcunjpeg.all.man b/appsrc/dcfile/dcunjpeg.all.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dcfile/dcunjpeg.all.script b/appsrc/dcfile/dcunjpeg.all.script
new file mode 100755
index 0000000..90ef4f8
--- /dev/null
+++ b/appsrc/dcfile/dcunjpeg.all.script
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Usage: dcunjpeg.all dirname
+#
+# where dirname is the directory name where images are
+#
+# decompresses files in place and adds .dcm extension
+#
+
+DCMSUFFIX="dcm"
+
+STAMP=`date +%Y%m%d%H%M%S`.$$
+
+DCUNJPEG="dcunjpeg"
+
+if [ ! $# = 1 ]
+then
+	echo 1>&2 "Usage: `basename $0` dirname"
+	exit 1
+fi
+
+for i in `find "$1" -type f -print`
+do
+	if [ -f "$i" ]
+	then
+		echo "Converting $i to $i.$DCMSUFFIX"
+
+		$DCUNJPEG "$i" "$i.$DCMSUFFIX"
+	fi
+done
+
+exit 0
diff --git a/appsrc/dcfile/dcunjpeg.man b/appsrc/dcfile/dcunjpeg.man
new file mode 100755
index 0000000..05ce622
--- /dev/null
+++ b/appsrc/dcfile/dcunjpeg.man
@@ -0,0 +1,32 @@
+.TH DCUNJPEG 1 "11 June 2008" "DICOM PS3" "DICOM PS3 - Decompress JPEG DICOM file"
+.SH NAME
+dcunjpeg \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Decompress JPEG DICOM file
+.SH SYNOPSIS
+.HP 10
+.B dcunjpeg "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcunjpeg
+reads the named dicom input file that is compressed using a lossless or lossy JPEG (10918-1)
+or JPEG 2000 transfer syntax, and copies the information and pixel data to a new dicom file,
+in the explicit VR little endian uncompressed transfer syntax with a meta information
+header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcjpeg(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Requires that jpeg, djpeg and kdu_expand are installed and in the PATH.
diff --git a/appsrc/dcfile/dcunjpeg.script b/appsrc/dcfile/dcunjpeg.script
new file mode 100755
index 0000000..a077e60
--- /dev/null
+++ b/appsrc/dcfile/dcunjpeg.script
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+# usage: dcunjpeg infile outfile
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+ANCREATE=ancreate
+DCCP=dccp
+DCDUMP=dcdump
+DCTORAW=dctoraw
+DCKEY=dckey
+PNMTORAW=pnmtoraw
+JPEG=jpeg
+DJPEG=djpeg
+KDUEXPAND=kdu_expand
+
+dccpoptions=" -nodisclaimer -ignorereaderrors -ignoreoutofordertags"
+
+if [ ! -f "$1" ]
+then
+	echo 1>&2 "Input file does not exist - $1"
+	exit 1
+fi
+
+transfersyntaxuid=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -k TransferSyntaxUID "$1" 2>&1 | egrep -v 'Error|Warning'`
+
+bits=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k BitsAllocated "$1" 2>&1 | egrep -v 'Error|Warning'`
+#echo "bits=$bits"
+if [ -z "$bits" ]; then bits=16; fi
+
+samplesperpixel=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k SamplesPerPixel "$1" 2>&1 | egrep -v 'Error|Warning'`
+#echo "samplesperpixel=$samplesperpixel"
+if [ -z "$samplesperpixel" ]; then samplesperpixel=1; fi
+
+if [ "$transfersyntaxuid" = "1.2.840.10008.1.2.4.90" -o "$transfersyntaxuid" = "1.2.840.10008.1.2.4.91" ]
+then
+	usecodec="KDU"
+elif [ "$transfersyntaxuid" = "1.2.840.10008.1.2.4.50" ]
+then
+	if [ $samplesperpixel -gt 1 -a $bits = 8 ]
+	then
+		# we need to use the IJG codec because the PVRG codec does not undo the YCrBr color space transform and chrominance downsampling
+		usecodec="IJG"
+	else
+		usecodec="PVRG"
+	fi
+else
+	usecodec="PVRG"
+fi
+
+if [ $samplesperpixel -eq 3 ]
+then
+	# regardless of whether JPEG or JPEG 2000
+	dccpoptions="$dccpoptions -r PhotometricInterpretation RGB"
+fi
+
+# note that we used dcdump and not andump to make $TMPROOT.pixelhead, because it computes the right VL !!
+# take care to grep out only the main dataset pixel data (and not that in any icon image sequence, which will be indented by dcdump
+if [ $bits = 8 ]
+then
+	# leave pixel data as OB
+	"$DCDUMP" -ignoreoutofordertags "$1" 2>&1 | grep '^(0x7fe0,0x0010) OX Pixel Data' | sed -e 's/$/ []/' | "$ANCREATE" -e > "$TMPROOT.pixelhead"
+else
+	# make pixel data OW
+	"$DCDUMP" -ignoreoutofordertags "$1" 2>&1 | grep '^(0x7fe0,0x0010) OX Pixel Data' | sed -e 's/$/ []/' -e 's/VR=<OB>/VR=<OW>/' | "$ANCREATE" -e > "$TMPROOT.pixelhead"
+fi
+ 
+"$DCTORAW" -quiet "$1" "$TMPROOT.jpg" 2>/dev/null
+
+if [ "$usecodec" = "PVRG" ]
+then
+	#echo 1>&2 "Decompressing lossless color or any grayscale using PVRG codec"
+
+	# The JPEG codec produces a file with a name based on the component
+	# and lists that on a line flagged ">>" with the component indicated by "C:n" and a field "N:name" ...
+
+	"$JPEG" -d "$TMPROOT" | grep '>>[ ]*C:' | awk '{print $3;}' | sed 's/N://' | sort >"$TMPROOT.stdout"
+	#ls -l $TMPROOT.*
+	rm "$TMPROOT.jpg"
+	
+	rm -f "$TMPROOT.rawl"
+
+	# the component naming can be wierd, and may start from 0 or 1, and increment by 1, or increment in odd ways ... we have already sorted it in case not encoded in component number order
+	filefornextcomponent=`head -1 "$TMPROOT.stdout"`
+	while [ ! -z  "${filefornextcomponent}" ]
+	do
+		mv "${TMPROOT}.stdout" "${TMPROOT}.bak"
+		sed '1d' <"${TMPROOT}.bak" >"${TMPROOT}.stdout"
+		rm "${TMPROOT}.bak"
+		
+		if [ $bits = 8 ]
+		then
+			cat "${filefornextcomponent}" >>"$TMPROOT.rawl"
+		else
+			dd if="${filefornextcomponent}" of="$TMPROOT.rawl.$component" conv=swab 2>/dev/null
+			cat "$TMPROOT.rawl.$component" >>"$TMPROOT.rawl"
+			rm "$TMPROOT.rawl.$component"
+		fi
+	
+		rm "${filefornextcomponent}"
+		filefornextcomponent=`head -1 "$TMPROOT.stdout"`
+	done
+
+	rm "$TMPROOT.stdout"
+
+	# components are concatenated successively rather than interleaved
+	if [ $samplesperpixel -gt 1 ]; then dccpoptions="$dccpoptions -r PlanarConfiguration 1"; fi
+elif [ "$usecodec" = "IJG" ]
+then
+	#echo 1>&2 "Decompressing lossy color 8 bit using IJG codec"
+	
+	"$DJPEG" "$TMPROOT.jpg" >"$TMPROOT.pnm"
+	rm "$TMPROOT.jpg"
+	"$PNMTORAW" "$TMPROOT.pnm" "$TMPROOT.rawl"
+	rm "$TMPROOT.pnm"
+	
+	# pnmtoraw interleaves components
+	if [ $samplesperpixel -gt 1 ]; then dccpoptions="$dccpoptions -r PlanarConfiguration 0"; fi
+elif [ "$usecodec" = "KDU" ]
+then
+	if [ $samplesperpixel -gt 1 -a $bits = 8 ]
+	then
+		#echo 1>&2 "Decompressing JPEG 2000 using J2K codec for multicomponent 8 bit"
+		"$KDUEXPAND" -quiet -i "$TMPROOT.jpg" -o "$TMPROOT.ppm"			# does not mind ".jpg" extension on input
+		"$PNMTORAW" "$TMPROOT.ppm"  "$TMPROOT.rawl"
+		rm "$TMPROOT.ppm"
+		# pnmtoraw interleaves components
+		dccpoptions="$dccpoptions -r PlanarConfiguration 0"
+	else
+		#echo 1>&2 "Decompressing JPEG 2000 using J2K codec"
+		"$KDUEXPAND" -quiet -i "$TMPROOT.jpg" -o "$TMPROOT.rawl"		# output extension ".rawl" requests little endian output; does not mind ".jpg" extension on input
+	fi
+	rm "$TMPROOT.jpg"
+fi
+
+if [ -f "$TMPROOT.rawl" ]
+then
+	"$DCCP" "$1" "$TMPROOT.nopixels" -d PixelData -d DataSetTrailingPadding -d DigitalSignaturesSequence $dccpoptions
+	cat "$TMPROOT.nopixels" "$TMPROOT.pixelhead" "$TMPROOT.rawl" > "$2"
+	rm "$TMPROOT.nopixels" "$TMPROOT.pixelhead" "$TMPROOT.rawl"
+	exit 0
+else
+	echo 1>&2 "Could not find suitable codec or codec failed for Transfer Syntax $transfersyntaxuid"
+	exit 1
+fi
\ No newline at end of file
diff --git a/appsrc/dcfile/dcunrgb.man b/appsrc/dcfile/dcunrgb.man
new file mode 100755
index 0000000..2081a1f
--- /dev/null
+++ b/appsrc/dcfile/dcunrgb.man
@@ -0,0 +1,32 @@
+.TH DCUNRGB 1 "13 January 2011" "DICOM PS3" "DICOM PS3 - Convert RGB to grayscale file"
+.SH NAME
+dcunrgb \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Convert RGB to grayscale file
+.SH SYNOPSIS
+.HP 10
+.B dcunrgb "infile" "outfile"
+.SH DESCRIPTION
+.LP
+.B dcunrgb
+reads the named dicom input file that has 3 sample per pixel 8 bit per component RGB pixel data,
+and copies the header information and pixel data converted to a single channel 8 bit grayscale MONOCHROME2 to a new dicom file,
+in the explicit VR little endian uncompressed transfer syntax with a meta information
+header prepended.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+There are no options.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcunjpeg(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Requires that netpbm utilities, and in particular ppmtopgm, are installed and in the PATH.
diff --git a/appsrc/dcfile/dcunrgb.script b/appsrc/dcfile/dcunrgb.script
new file mode 100755
index 0000000..9cc884d
--- /dev/null
+++ b/appsrc/dcfile/dcunrgb.script
@@ -0,0 +1,125 @@
+#!/bin/sh
+
+# usage: dcunrgb infile outfile
+#
+
+TMPROOT=/tmp/`basename $0`.$$
+
+ANCREATE=ancreate
+DC=dc
+DCCP=dccp
+DCDUMP=dcdump
+DCTOPNM=dctopnm
+DCKEY=dckey
+PNMTORAW=pnmtoraw
+PPMTOPGM=ppmtopgm
+
+dccpoptions=" -nodisclaimer -noadddicom -ignorereaderrors -ignoreoutofordertags"
+
+if [ ! -f "$1" ]
+then
+	echo 1>&2 "Input file does not exist - $1"
+	exit 1
+fi
+
+transfersyntaxuid=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -k TransferSyntaxUID "$1" 2>&1 | egrep -v 'Error|Warning'`
+
+if [ "$transfersyntaxuid" != "1.2.840.10008.1.2" -a "$transfersyntaxuid" != "1.2.840.10008.1.2.1" -a "$transfersyntaxuid" != "1.2.840.10008.1.2.2" ]
+then
+	echo 1>&2 "Only uncompressed RGB 8 bit per pixel input supported"
+	exit 1
+fi
+
+bits=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k BitsAllocated "$1" 2>&1 | egrep -v 'Error|Warning'`
+
+if [ $bits -ne 8 ]
+then
+	echo 1>&2 "Only uncompressed RGB 8 bit per pixel input supported"
+	exit 1
+fi
+
+samplesperpixel=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k SamplesPerPixel "$1" 2>&1 | egrep -v 'Error|Warning'`
+
+if [ $samplesperpixel -ne 3 ]
+then
+	echo 1>&2 "Only uncompressed RGB 8 bit per pixel input supported"
+	exit 1
+fi
+
+rows=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k Rows "$1" 2>&1 | egrep -v 'Error|Warning'`
+columns=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k Columns "$1" 2>&1 | egrep -v 'Error|Warning'`
+frames=`"$DCKEY" -noerror -ignorereaderrors -ignoreoutofordertags -decimal -k NumberOfFrames "$1" 2>&1 | egrep -v 'Error|Warning'`
+if [ -z "$frames" ]; then frames=1; fi
+
+#echo 1>&2 "rows=$rows"
+#echo 1>&2 "columns=$columns"
+#echo 1>&2 "frames=$frames"
+
+#numberOfPixels may be odd
+numberOfPixels=`$DC <<EOF
+16
+o
+$rows
+$columns
+$frames
+*
+*
+p
+EOF`
+#echo 1>&2 "numberOfPixels(hex)=$numberOfPixels"
+
+# VL is rounded up to next even number if odd ...
+vl=`$DC <<EOF
+16
+o
+$rows
+$columns
+$frames
+*
+*
+1
++
+2
+/
+2
+*
+p
+EOF`
+#echo 1>&2 "vl(hex)=$vl"
+
+#isOdd will be 0 if even, 1 if odd
+isOdd=`$DC <<EOF
+16
+i
+$vl
+$numberOfPixels
+-
+p
+EOF`
+#echo 1>&2 "isOdd=$isOdd"
+
+echo "(0x7fe0,0x0010) OX Pixel Data 	 VR=<OB>   VL=<0x$vl> []" | "$ANCREATE" -e > "$TMPROOT.pixelhead"
+ 
+"$DCTOPNM" -quiet "$1" "$TMPROOT.ppm"
+
+# Note that ppmtopgm is documented (“http://netpbm.sourceforge.net/doc/ppmtopgm.html”) to use “gray = .299 r + .587 g + .114 b” as the conversion formula
+# (NTSC luminance weighting “http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC11”), but the net effect
+# is to produce the same value of gray when r, g and b are the same value
+
+"$PPMTOPGM" "$TMPROOT.ppm" > "$TMPROOT.pgm"
+rm "$TMPROOT.ppm"
+"$PNMTORAW" "$TMPROOT.pgm" > "$TMPROOT.raw"
+rm "$TMPROOT.pgm"
+
+"$DCCP" "$1" "$TMPROOT.nopixels" -d PixelData -d DataSetTrailingPadding -d DigitalSignaturesSequence $dccpoptions -r PhotometricInterpretation MONOCHROME2 -r SamplesPerPixel 1 -d PlanarConfiguration
+cat "$TMPROOT.nopixels" "$TMPROOT.pixelhead" "$TMPROOT.raw" > "$2"
+
+if [ ${isOdd} = 1 ]
+then
+	# add single padding byte to make even and match VL
+	dd if=/dev/zero bs=1 count=1 >>"$2" 2>/dev/null
+fi
+
+rm "$TMPROOT.nopixels" "$TMPROOT.pixelhead" "$TMPROOT.raw"
+
+exit 0
diff --git a/appsrc/dcfile/makedcdtchgheader.sh b/appsrc/dcfile/makedcdtchgheader.sh
new file mode 100755
index 0000000..95baaa9
--- /dev/null
+++ b/appsrc/dcfile/makedcdtchgheader.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+dictionary="${1}"
+outfile="${2}"
+
+echo "// Automatically generated from template - EDITS WILL BE LOST" > "${outfile}"
+echo "// Generated by makedcdtchgheader.sh" >> "${outfile}"
+echo "static Tag mapDateTagToTimeTag[] = {" >> "${outfile}"
+egrep 'VR="(DA)"' "${dictionary}" \
+	| sed -e 's/^.*Keyword="\([^"]*\).*$/\1/' \
+	| sed -e 's/Date/Time/' \
+	| xargs -L 1 -I % grep 'Keyword="%"' "${dictionary}" \
+	| sed -e 's/^.*Keyword="\([^"]*\).*$/\1/' \
+	| sed -e 's/^\(.*\)Time\(.*\)$/    TagFromName(\1Date\2), TagFromName(\1Time\2),/' \
+	>> "${outfile}"
+echo "    0,0 };" >> "${outfile}"
+
diff --git a/appsrc/dcfile/pbmtoovl.cc b/appsrc/dcfile/pbmtoovl.cc
new file mode 100644
index 0000000..bef9bb8
--- /dev/null
+++ b/appsrc/dcfile/pbmtoovl.cc
@@ -0,0 +1,207 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pbmtoovl.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "sopclu.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+	bool standalone=options.get("standalone");
+
+	int overlaygroup = 0;
+	(void)options.get("overlaygroup",overlaygroup);
+
+	Assert(overlaygroup <= 0x1e && overlaygroup%2 == 0);
+			
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-standalone]"
+			<< " [-overlaygroup 0x6000+n]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	BinaryInputStream bin(in,LittleEndian);
+
+	char magic=pnm_getc(bin);
+	char format;
+	bin.get(format);
+
+	if (!bin || magic != 'P') {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	switch (format) {
+		case '1':
+		case '2':
+		case '3':
+		case '5':
+		case '6':
+			cerr << EMsgDC(Unsupported) << " - P" << format << endl;
+			return 1;
+		case '4':		// only raw bitmap (PBM) supported
+			break;
+		default:
+			cerr << EMsgDC(UnrecognizedFormat) << endl;
+			return 1;
+	}
+
+	int cols = pnm_getu(bin);
+	int rows = pnm_getu(bin);
+
+	// Last whitespace absorbed ... at start of raw data
+
+	long offset=bin.tellg();
+
+	if (!bin || cols == -1 || rows == -1) {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	list+=new UnsignedShortAttribute(Tag(0x6000+overlaygroup,OverlayBitsAllocated_ELEMENT),1);
+	list+=new UnsignedShortAttribute(Tag(0x6000+overlaygroup,OverlayBitPosition_ELEMENT),0);
+	list+=new UnsignedShortAttribute(Tag(0x6000+overlaygroup,OverlayRows_ELEMENT),rows);
+	list+=new UnsignedShortAttribute(Tag(0x6000+overlaygroup,OverlayColumns_ELEMENT),cols);
+	{
+		SignedShortAttribute *a=new SignedShortAttribute(Tag(0x6000+overlaygroup,OverlayOrigin_ELEMENT));
+		Assert(a); a->addValue(Int16(1)); a->addValue(Int16(1));
+		list+=a;
+	}
+	list+=new CodeStringAttribute(Tag(0x6000+overlaygroup,OverlayType_ELEMENT),"G");
+
+	if (standalone) {
+		list+=new IntegerStringAttribute(TagFromName(OverlayNumber));
+
+		list+=new UIStringAttribute(TagFromName(SOPClassUID),StandaloneOverlayStorageSOPClassUID);
+
+		// What is necessary to make a valid instance ...
+		// (this also triggers the default make DICOM procedures in attmxls.cc
+		// to recognize as Composite, and file in UIDs etc.)
+
+		list+=new PersonNameAttribute(TagFromName(PatientName));
+		list+=new LongStringAttribute(TagFromName(PatientID));
+		list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+		list+=new CodeStringAttribute(TagFromName(PatientSex));
+		list+=new DateStringAttribute(TagFromName(StudyDate));
+		list+=new TimeStringAttribute(TagFromName(StudyTime));
+		list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName));
+		list+=new ShortStringAttribute(TagFromName(StudyID));
+		list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+		list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+		list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+		list+=new LongStringAttribute(TagFromName(Manufacturer));
+	}
+
+	OtherWordLargeNonPixelAttribute *overlayData=
+		new OtherWordLargeNonPixelAttribute(Tag(0x6000+overlaygroup,OverlayData_ELEMENT),bin,offset);
+	Assert(overlayData);
+	overlayData->read(bin,((cols*rows-1)/16+1)*2);		// Actually just sets VL and skips
+	list+=overlayData;
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/pbmtoovl.man b/appsrc/dcfile/pbmtoovl.man
new file mode 100755
index 0000000..25fbe06
--- /dev/null
+++ b/appsrc/dcfile/pbmtoovl.man
@@ -0,0 +1,68 @@
+.TH PBMTOOVL 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Create DICOM Overlay from PBM file"
+.SH NAME
+pbmtoovl \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create DICOM Overlay from PBM file
+.SH SYNOPSIS
+.HP 10
+.B pbmtoovl
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.so man1/genin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B pbmtoovl
+reads the named raw PBM input file and copies the information and
+pixel data to a new dicom file, creating a Standalone Overlay SOP
+Class instance.
+.LP
+The output encoding of the file will be the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options. The byte order of the pixel data will be changed as necessary.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-standalone
+.RS
+Create complete Composite Standalone Overlay SOP Instance rather than just
+overlay attributes.
+.RE
+.TP
+.B \-verbose
+.RS
+Display contents after creation, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctoraw(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dciodvfy(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+Only raw grayscale PBM files are supported.
+.LP
+If the standalone option is not specified, the metainformation header must be
+supressed, or an error will be generated, since SOP Class and
+Instance UIDs are mandatory in the metainformation header.
diff --git a/appsrc/dcfile/pdftodc.cc b/appsrc/dcfile/pdftodc.cc
new file mode 100644
index 0000000..58c934f
--- /dev/null
+++ b/appsrc/dcfile/pdftodc.cc
@@ -0,0 +1,196 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pdftodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isspace()
+#else
+#include <ctype.h>	// for isspace()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "sopclu.h"
+
+// addCodeSequenceItemToItemList() is copied from appsrc/dcfile/dcmulti.cc and probably should be factored out somewhere
+
+static void addCodeSequenceItemToItemList(
+	AttributeList *i,
+	const char *csd,
+	const char *cv,
+	const char *cm,
+	const char *csvn)
+{
+	Assert(i);
+	//cm = lookUpAndFillInCodeMeaning(csd,cv,cm,csvn);
+	if (csd  && strlen(csd))  (*i)+=new ShortStringAttribute(TagFromName(CodingSchemeDesignator),csd);
+	if (cv   && strlen(cv))   (*i)+=new ShortStringAttribute(TagFromName(CodeValue),cv);
+	if (cm   && strlen(cm))   (*i)+=new  LongStringAttribute(TagFromName(CodeMeaning),cm);
+	if (csvn && strlen(csvn)) (*i)+=new ShortStringAttribute(TagFromName(CodingSchemeVersion),csvn);
+}
+
+// removeLeadingSpaces() is copied from libsrc/src/attrtyps.cc and probably should be factored out somewhere
+
+static const char*
+removeLeadingSpaces(const char *from)
+{
+	if (from) while (*from && isspace(*from)) ++from;
+	return from;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	bool addConceptNameCodeSequence = false;
+	const char *addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodingSchemeDesignator;
+	const char *addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodeValue;
+	const char *addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodeMeaning;
+	const char *addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodingSchemeVersion;
+	{
+		const char *addConceptNameCodeSequenceArgs[4];
+		int n = options.get("conceptname",addConceptNameCodeSequenceArgs,4);
+//cerr << "addConceptNameCodeSequence returns " << dec << n << endl;
+		if (n > 0) {
+			if (n == 4) {
+//cerr << "option: addConceptNameCodeSequence: addConceptNameCodeSequenceArgs[0] " << addConceptNameCodeSequenceArgs[0] << endl;
+//cerr << "option: addConceptNameCodeSequence: addConceptNameCodeSequenceArgs[1] " << addConceptNameCodeSequenceArgs[1] << endl;
+//cerr << "option: addConceptNameCodeSequence: addConceptNameCodeSequenceArgs[2] " << addConceptNameCodeSequenceArgs[2] << endl;
+//cerr << "option: addConceptNameCodeSequence: addConceptNameCodeSequenceArgs[3] " << addConceptNameCodeSequenceArgs[3] << endl;
+				addConceptNameCodeSequence=true;
+				addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodingSchemeDesignator = removeLeadingSpaces(addConceptNameCodeSequenceArgs[0]);
+				             addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodeValue = removeLeadingSpaces(addConceptNameCodeSequenceArgs[1]);
+				           addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodeMeaning = removeLeadingSpaces(addConceptNameCodeSequenceArgs[2]);
+				   addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodingSchemeVersion = removeLeadingSpaces(addConceptNameCodeSequenceArgs[3]);
+			}
+			else {
+				cerr << "addreferenced needs 4 arguments, not " << dec << n << endl;
+				bad=true;
+			}
+		}
+	}
+
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-conceptname scheme code meaning version]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	OurStreamPos pdfFileLength = OurStreamPos(0);
+	in.seekg(0,ios::end);
+	pdfFileLength = in.tellg();
+	in.seekg(0,ios::beg);
+	
+	BinaryInputStream bin(in,NoEndian);
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	// various Type 1 and Type 2 attributes for mandatory Encapsulated Document modules ...
+
+	list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+	list+=new LongStringAttribute(TagFromName(PatientID));
+	list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+	list+=new CodeStringAttribute(TagFromName(PatientSex));
+	list+=new ShortStringAttribute(TagFromName(StudyID));
+	list+=new DateStringAttribute(TagFromName(StudyDate));
+	list+=new TimeStringAttribute(TagFromName(StudyTime));
+	list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+	list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+	list+=new IntegerStringAttribute(TagFromName(SeriesNumber),Int32(1));
+	list+=new IntegerStringAttribute(TagFromName(InstanceNumber),Int32(1));
+	list+=new DateStringAttribute(TagFromName(ContentDate));
+	list+=new TimeStringAttribute(TagFromName(ContentTime));
+	list+=new DateTimeStringAttribute(TagFromName(AcquisitionDateTime));
+
+	list+=new UIStringAttribute(TagFromName(SOPClassUID),EncapsulatedPDFStorageSOPClassUID);
+	list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+	list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+	list+=new CodeStringAttribute(TagFromName(BurnedInAnnotation),"YES");
+
+	list+=new LongStringAttribute(TagFromName(Manufacturer));
+	
+	list+=new ShortTextAttribute(TagFromName(DocumentTitle));
+	
+	SequenceAttribute *aConceptNameCodeSequence = new SequenceAttribute(TagFromName(ConceptNameCodeSequence));
+	Assert(aConceptNameCodeSequence);
+	list+=aConceptNameCodeSequence;
+	if (addConceptNameCodeSequence) {
+		AttributeList *iConceptNameCodeSequence = new AttributeList();
+		Assert(iConceptNameCodeSequence);
+		(*aConceptNameCodeSequence)+=iConceptNameCodeSequence;
+
+		addCodeSequenceItemToItemList(iConceptNameCodeSequence,
+			addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodingSchemeDesignator,
+			addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodeValue,
+			addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodeMeaning,
+			addConceptNameCodeSequence_purposeOfReferenceCodeSequenceCodingSchemeVersion);
+	}
+
+	list+=new LongStringAttribute(TagFromName(MIMETypeOfEncapsulatedDocument),"application/pdf");
+	list+=new OtherByteLargeNonPixelAttributeBase(TagFromName(EncapsulatedDocument),bin,OurStreamPos(0),pdfFileLength);		// pdfFileLength may be odd length; will be handled
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/pdftodc.man b/appsrc/dcfile/pdftodc.man
new file mode 100644
index 0000000..4c57fcb
--- /dev/null
+++ b/appsrc/dcfile/pdftodc.man
@@ -0,0 +1,61 @@
+.TH PDFTODC 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Encapsulate PDF in DICOM"
+.SH NAME
+pdftodc \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Encapsulate PDF in DICOM
+.SH SYNOPSIS
+.HP 10
+.B pdftodc
+.so man1/gen.so
+[
+.B \-conceptname scheme code meaning version
+]
+[
+.B \-v|verbose
+]
+.so man1/genin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B pdftodc
+reads the named PDF input file and encapsulates in a new dicom file, creating an Encapsulated PDF Storage SOP
+Class instance.
+.LP
+The output encoding of the file will be the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful Encapsulated PDF instance.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display contents after creation, during replacement, and before writing.
+.RE
+.TP
+.B \-conceptname scheme code meaning version
+.RS
+Fill in the ConceptNameCodeSequence attribute with the supplied values.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dctopdf(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+
diff --git a/appsrc/dcfile/pgxtodc.cc b/appsrc/dcfile/pgxtodc.cc
new file mode 100644
index 0000000..54016f3
--- /dev/null
+++ b/appsrc/dcfile/pgxtodc.cc
@@ -0,0 +1,268 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pgxtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "rawsrc.h"
+
+static
+char
+pgx_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+//cerr << "pgx_getc: returns " << c << endl;
+	return c;
+}
+
+static
+int
+pgx_getu(istream &istr,int pushedBackChar)		// get unsigned value, -1 on failure
+{
+//cerr << "pgx_getu: pushedBackChar " << pushedBackChar << " " << char(pushedBackChar) << endl;
+	char c = pushedBackChar == -1
+		? pgx_getc(istr)			// skips comments and whitespace
+		: pushedBackChar;			// skipping already done ... start with this character
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+//cerr << "pgx_getu: returns " << value << endl;
+	return value;
+}
+
+static
+int
+pgx_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	return pgx_getu(istr,-1);
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+
+/*
+       PGX is a trivial monochrome file format defined just
+       to enable simple testing of JPEG2000 with image data having unusual
+       bit-depths. The file consists of a single text header line of the form
+       "PG <byte order> [+|-]<bit-depth> <cols> <rows>", with the binary data
+       appearing immediately after the newline character, packed into 1, 2 or
+       4 bytes per sample, depending upon the value of <bit-depth>. The <byte
+       order> field must be one of the fixed strings, "LM" (LSB's first) or
+       "ML" (MSB's first), while the optional `+' (default) or `-' character
+       preceding the <bit-depth> field indicates whether the data is signed
+       or not. Any bit-depth from 1 to 32 is acceptable.
+*/
+
+	char magic=pgx_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P' || format != 'G') {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	char endian1=pgx_getc(in);
+	char endian2;
+	in.get(endian2);
+
+	bool littleendian=false;
+	bool bigendian=false;
+
+	if (!in) {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+	else if (endian1 == 'L' && endian2 == 'M') {
+		littleendian=true;
+	}
+	else if (endian1 == 'M' && endian2 == 'L') {
+		bigendian=true;
+	}
+	else {
+		cerr << EMsgDC(UnrecognizedFormat) << " - endian not LM or ML, was " << endian1 << endian2 << endl;
+		return 1;
+	}
+	
+	char sign=pgx_getc(in);
+	int bits=-1;
+	if (!in) {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+	else if (sign == '+' || sign == '-') {
+		bits = pgx_getu(in);		// skip to and fetch the bit depth
+	}
+	else if (isdigit(sign)) {
+		bits = pgx_getu(in,sign);	// use what we thought was the sign as the start of the bit depth
+		sign='+';			// when sign is missing it is assumed to be + (i.e. always +ve, not signed)
+	}
+	else {
+		cerr << EMsgDC(UnrecognizedFormat) << " - sign not + or - or start of bit depth, was " << sign << endl;
+		return 1;
+	}
+
+	int cols = pgx_getu(in);
+	int rows = pgx_getu(in);
+
+	unsigned samples = 1;
+	const char *photometricInterpretation ="MONOCHROME2";
+
+	// Last whitespace absorbed ... at start of raw pixel data
+
+	long offset=in.tellg();
+
+	if (!in || cols == -1 || rows == -1 || bits == -1) {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	Uint16 bitsAllocated=((bits-1u)/8u+1u)*8u;
+	Uint16 bitsStored=bits;
+	Uint16 highBit=bits-1;
+	Uint16 frames=1;
+
+	list+=new UnsignedShortAttribute(TagFromName(BitsAllocated),bitsAllocated);
+	list+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsStored);
+	list+=new UnsignedShortAttribute(TagFromName(HighBit),highBit);
+	list+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	list+=new UnsignedShortAttribute(TagFromName(Columns),cols);
+	list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),frames);
+	list+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),samples);
+	list+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),sign == '-' ? 1u : 0u);
+	list+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),photometricInterpretation);
+
+	// various Type 1 and Type 2 attributes for mandatory SC modules ...
+
+	list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+	list+=new LongStringAttribute(TagFromName(PatientID));
+	list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+	list+=new CodeStringAttribute(TagFromName(PatientSex));
+	list+=new ShortStringAttribute(TagFromName(StudyID));
+	list+=new DateStringAttribute(TagFromName(StudyDate));
+	list+=new TimeStringAttribute(TagFromName(StudyTime));
+	list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+	list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+	list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+	list+=new IntegerStringAttribute(TagFromName(InstanceNumber));
+
+	list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+	list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+
+	list+=new LongStringAttribute(TagFromName(Manufacturer));
+	list+=new CodeStringAttribute(TagFromName(PatientOrientation));
+
+	Raw_PixelDataSourceBase *pixeldatasrc=0;
+	if (bits <= 8) {
+		pixeldatasrc=new Raw_PixelDataSource_Byte(in,offset,rows,cols,frames,samples);
+	}
+	else if (littleendian) {
+		pixeldatasrc=new Raw_PixelDataSource_LittleEndian(in,offset,rows,cols,frames,samples);
+	}
+	else if (bigendian) {
+		pixeldatasrc=new Raw_PixelDataSource_BigEndian(in,offset,rows,cols,frames,samples);
+	}
+	Assert(pixeldatasrc);
+
+	list+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		frames,
+		samples,
+		&transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/pgxtodc.man b/appsrc/dcfile/pgxtodc.man
new file mode 100755
index 0000000..b6b522a
--- /dev/null
+++ b/appsrc/dcfile/pgxtodc.man
@@ -0,0 +1,63 @@
+.TH PGXTODC 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Create DICOM from PGX file"
+.SH NAME
+pgxtodc \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create DICOM from PGX file
+.SH SYNOPSIS
+.HP 10
+.B pgxtodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.so man1/genin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B pgxtodc
+reads the named PGX input file and copies the information and
+pixel data to a new dicom file, creating a Secondary Capture SOP
+Class instance.
+.LP
+The output encoding of the file will be the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options. The byte order of the pixel data will be changed from that
+in the PGX file as necessary.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.LP
+Photometric Interpretation will be MONOCHROME2.
+images.
+.LP
+Pixel Representation will be unsigned or signed as specified in
+the PGX file.
+.LP
+Bits Stored will depend on the bit depth specified in the PGX file.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.B \-verbose
+.RS
+Display contents after creation, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dxtopgx(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+
diff --git a/appsrc/dcfile/pnmtodc.cc b/appsrc/dcfile/pnmtodc.cc
new file mode 100644
index 0000000..2a03a2d
--- /dev/null
+++ b/appsrc/dcfile/pnmtodc.cc
@@ -0,0 +1,257 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pnmtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "rawsrc.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	bool littleendian=options.get("little") || options.get("l");
+	bool bigendian=options.get("big") || options.get("b");
+
+	bool imagepixelmoduleonly=options.get("imagepixelmoduleonly");
+
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-little|-l|-big|-b]"
+			<< " [-imagepixelmoduleonly]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+
+	char magic=pnm_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P') {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	unsigned samples;
+	const char *photometricInterpretation;
+	unsigned planarConfiguration;
+
+	switch (format) {
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+			cerr << EMsgDC(Unsupported) << " - P" << format << endl;
+			return 1;
+		case '5':
+			samples=1;
+			photometricInterpretation="MONOCHROME2";
+			break;
+		case '6':
+			samples=3;
+			photometricInterpretation="RGB";
+			planarConfiguration=0;	// color by pixel (RGB order)
+			break;
+		default:
+			cerr << EMsgDC(UnrecognizedFormat) << endl;
+			return 1;
+	}
+
+	int cols = pnm_getu(in);
+	int rows = pnm_getu(in);
+	int maxval = pnm_getu(in);
+
+	// Last whitespace absorbed ... at start of raw pixel data
+
+	long offset=in.tellg();
+
+	if (!in || cols == -1 || rows == -1 || maxval == -1) {
+		cerr << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	unsigned bits;
+	unsigned test;
+	for (test=maxval,bits=0; test; test=test>>1,++bits);
+	if (bits < 1 || bits > 16) {
+		cerr << EMsgDC(Unsupported) << " - bits = " << dec << bits << endl;
+		return 1;
+	}
+
+	if (bits > 8 && !(littleendian || bigendian)) {
+		cerr << EMsgDC(OptionsIncompatible) << " - bits > 8 && !(little|big)" << endl;
+		return 1;
+	}
+	else if (bits <= 8 && (littleendian || bigendian)) {
+		cerr << EMsgDC(OptionsIncompatible) << " - bits <= 8 & (little|big)" << endl;
+		return 1;
+	}
+	else if (bits <= 8) {
+		littleendian = true;
+		// bigendian already false
+	}
+
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	Uint16 bitsAllocated=((bits-1u)/8u+1u)*8u;
+	Uint16 bitsStored=bits;
+	Uint16 highBit=bits-1;
+	Uint16 frames=1;
+
+	list+=new UnsignedShortAttribute(TagFromName(BitsAllocated),bitsAllocated);
+	list+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsStored);
+	list+=new UnsignedShortAttribute(TagFromName(HighBit),highBit);
+	list+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	list+=new UnsignedShortAttribute(TagFromName(Columns),cols);
+	list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),frames);
+	list+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),samples);
+	list+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),0u);
+	list+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),photometricInterpretation);
+	if (samples > 1) list+=new UnsignedShortAttribute(TagFromName(PlanarConfiguration),planarConfiguration);
+
+	if (!imagepixelmoduleonly) {
+		// various Type 1 and Type 2 attributes for mandatory SC modules ...
+
+		list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+		list+=new LongStringAttribute(TagFromName(PatientID));
+		list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+		list+=new CodeStringAttribute(TagFromName(PatientSex));
+		list+=new ShortStringAttribute(TagFromName(StudyID));
+		list+=new DateStringAttribute(TagFromName(StudyDate));
+		list+=new TimeStringAttribute(TagFromName(StudyTime));
+		list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+		list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+		list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+		list+=new IntegerStringAttribute(TagFromName(InstanceNumber));
+
+		list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+		list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+
+		list+=new LongStringAttribute(TagFromName(Manufacturer));
+		list+=new CodeStringAttribute(TagFromName(PatientOrientation));
+	}
+	
+	Raw_PixelDataSourceBase *pixeldatasrc=0;
+	if (bits <= 8) {
+		pixeldatasrc=new Raw_PixelDataSource_Byte(in,offset,rows,cols,frames,samples);
+	}
+	else if (littleendian) {
+		pixeldatasrc=new Raw_PixelDataSource_LittleEndian(in,offset,rows,cols,frames,samples);
+	}
+	else if (bigendian) {
+		pixeldatasrc=new Raw_PixelDataSource_BigEndian(in,offset,rows,cols,frames,samples);
+	}
+	Assert(pixeldatasrc);
+
+	list+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		frames,
+		samples,
+		&transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/pnmtodc.man b/appsrc/dcfile/pnmtodc.man
new file mode 100755
index 0000000..eb7778d
--- /dev/null
+++ b/appsrc/dcfile/pnmtodc.man
@@ -0,0 +1,199 @@
+.TH PNMTODC 1 "6 March 2014" "DICOM PS3" "DICOM PS3 - Create DICOM from PNM file"
+.SH NAME
+pnmtodc \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Create DICOM from PNM file
+.SH SYNOPSIS
+.HP 10
+.B pnmtodc
+.so man1/gen.so
+[
+.B \-little|\-l|\-big|\-b
+]
+[
+.B \-imagepixelmoduleonly
+]
+[
+.B \-v|verbose
+]
+.so man1/genin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B pnmtodc
+reads the named PNM input file and copies the information and
+pixel data to a new dicom file, creating a Secondary Capture SOP
+Class instance.
+.LP
+The output encoding of the file will be the default or explicitly
+requested transfer syntax, as described in dcintro(1) under output
+options. The byte order of the pixel data will be changed as necessary.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.LP
+Photometric Interpretation will be MONOCHROME2 for PGM and RGB for PPM
+images.
+.LP
+Pixel Representation will always be unsigned.
+.LP
+Bits Stored will depend on maxval, and may be less than 8 or 16.
+.SH OPTIONS
+The verbose output goes to standard error.
+.LP
+The basic input switches are described in dcintro(1). Options specific to this program are:
+.TP
+.BI \-little|\-big
+.RS
+Required if the maxval in the input file is greater than 255 (bit depth is greater than 8).
+Originally the PGM and PPM binary formats did not support more than one byte; in earlier
+versions of the dicom3tools the non-standard convention of using little endian two byte
+raw binary values was supported, but later the maintainers of netpbm added the same
+capability, but using big-endian. In order to force the issue in case one behavior or
+the other is assumed, it is now mandatory to specify this on the command line whenever
+more than 8 bits are used.
+.RE
+.TP
+.BI \-imagepixelmoduleonly
+.RS
+Write only the image pixel data module and not the basic mandatory secondary capture and composite IOD modules as well
+(e.g., prior to dcmerge'ing with an existing SOP instance that has its pixel data deleted); use the -nodisclaimer switch
+to avoid generating Image Comments and the -n switch to avoid adding a meta-information header (will fail if you do not
+since there is no SOP Class UID to use in the meta-information header).
+.RE
+.TP
+.B \-verbose
+.RS
+Display contents after creation, during replacement, and before writing.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% head gray.256.256.12.pgm
+.RE
+P5
+.RE
+256 256
+.RE
+4095
+.RE
+% pnmtodc -v -little -r PatientName "Smith^Harry^^^"
+.RE
+        gray.256.256.12.pgm gray.dc3
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0020) DA Study Date ...
+.RE
+ ...
+.RE
+(0x0010,0x0010) PN Patient's Name <^^^^>
+.RE
+ ...
+.RE
+(0x0028,0x0002) US Samples per Pixel          [0x0001] 
+.RE
+(0x0028,0x0004) CS Photometric Interpretation <MONOCHROME2> 
+.RE
+(0x0028,0x0008) IS Number of Frames           <1 > 
+.RE
+(0x0028,0x0010) US Rows                       [0x0100] 
+.RE
+(0x0028,0x0011) US Columns                    [0x0100] 
+.RE
+(0x0028,0x0100) US Bits Allocated             [0x0010] 
+.RE
+(0x0028,0x0101) US Bits Stored                [0x000c] 
+.RE
+(0x0028,0x0102) US High Bit                   [0x000b] 
+.RE
+(0x0028,0x0103) US Pixel Representation       [0x0000]
+.RE
+ ...
+.RE
+******** After replace before... ********
+.RE
+ ...
+.RE
+(0x0010,0x0010) PN Patient's Name <Smith^Harry^^^>
+.RE
+ ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0000) UL Meta Element Group Length ...
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.RE
+\ 
+.RE
+% dciodvfy gray.dc3
+.RE
+SCImage
+.RE
+\ 
+.RE
+% head rgb.256.256.8.ppm
+.RE
+P6
+.RE
+256 256
+.RE
+255
+.RE
+% pnmtodc -v rgb.256.256.8.ppm rgb.dc3
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+ ...
+.RE
+(0x0028,0x0002) US Samples per Pixel          [0x0003] 
+.RE
+(0x0028,0x0004) CS Photometric Interpretation <RGB> 
+.RE
+(0x0028,0x0008) IS Number of Frames           <1 > 
+.RE
+(0x0028,0x0010) US Rows                       [0x0100] 
+.RE
+(0x0028,0x0011) US Columns                    [0x0100] 
+.RE
+(0x0028,0x0100) US Bits Allocated             [0x0008] 
+.RE
+(0x0028,0x0101) US Bits Stored                [0x0008] 
+.RE
+(0x0028,0x0102) US High Bit                   [0x0007] 
+.RE
+(0x0028,0x0103) US Pixel Representation       [0x0000]
+.RE
+ ...
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctoraw(1) ,
+.BR rawtodc(1) ,
+.BR dciodvfy(1) ,
+.BR dcintro(1) ,
+.BR dcmerge(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Only raw grayscale PGM (P5) and RGB PPM (P6) PNM files are supported, not
+text or PBM files.
+.LP
+The number of Columns (horizontal pixels) must be an even number.
diff --git a/appsrc/dcfile/rawftodc.cc b/appsrc/dcfile/rawftodc.cc
new file mode 100644
index 0000000..0cfd7ad
--- /dev/null
+++ b/appsrc/dcfile/rawftodc.cc
@@ -0,0 +1,445 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawftodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "srcsink.h"
+#include "convtype.h"
+#include "fltype.h"
+
+class RawFloat_PixelDataSourceBase : public SourceBase<Uint16> {
+protected:
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 frames;
+	Uint16 samples;
+	double scaleFactor;
+	Uint16 componentOffset;
+	Uint16 componentNumber;
+
+	Uint32 totalrows;
+	Uint32 row;
+	Uint16 col;
+	Uint16 frame;
+	Uint16 *buffer;
+public:
+	RawFloat_PixelDataSourceBase(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s,double scf,Uint16 cOffset,Uint16 cNumber)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			frames=f;
+			Assert(frames);
+			samples=s;
+			Assert(samples);
+			scaleFactor=scf;
+			componentOffset=cOffset;
+			componentNumber=cNumber;
+
+			totalrows=((Uint32)rows)*frames;
+			row=0;
+			col=0;
+			frame=0;
+			buffer=new Uint16[c*s];
+			Assert(buffer);
+		}
+
+	virtual ~RawFloat_PixelDataSourceBase()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	virtual size_t read(void) = 0;
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+
+	size_t getBufferCount(void) const	{ return col*samples; }
+
+	int good(void) const	{ return istr && istr->good() && row < totalrows; }
+};
+
+class RawFloat_PixelDataSource_LittleEndian : public RawFloat_PixelDataSourceBase {
+public:
+	RawFloat_PixelDataSource_LittleEndian(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s,double scf,Uint16 cOffset,Uint16 cNumber)
+			: RawFloat_PixelDataSourceBase(i,off,r,c,f,s,scf,cOffset,cNumber)
+		{}
+
+	size_t read(void)
+		{
+			if (row == 0 && frame == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= totalrows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				Uint16 sample=0;
+				while (sample < samples) {
+					int component;
+					IEEE_Float32_L value;
+					unsigned char *bytes = (unsigned char *)(&value);
+					for (component=0; component<componentOffset; ++component) {		// skip components before the one we want
+						istr->read((char *)bytes,4);
+						if (!istr->good()) return 0;
+					}
+					istr->read((char *)bytes,4);
+					if (!istr->good()) return 0;
+					Uint16 pixel = (Uint16)(value * scaleFactor);
+//cerr << value << ",";
+					*ptr++=pixel; ++sample;
+					for (component=componentOffset+1; component<componentNumber; ++component) {	// skip components after the one we want
+						istr->read((char *)bytes,4);
+						if (!istr->good()) return 0;
+					}
+				}
+				++col;
+			}
+//cerr << endl;
+			return col*samples;
+		}
+};
+
+class RawFloat_PixelDataSource_BigEndian : public RawFloat_PixelDataSourceBase {
+public:
+	RawFloat_PixelDataSource_BigEndian(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s,double scf,Uint16 cOffset,Uint16 cNumber)
+			: RawFloat_PixelDataSourceBase(i,off,r,c,f,s,scf,cOffset,cNumber)
+		{}
+
+	size_t read(void)
+		{
+			if (row == 0 && frame == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= totalrows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				Uint16 sample=0;
+				while (sample < samples) {
+					int component;
+					IEEE_Float32_B value;
+					unsigned char *bytes = (unsigned char *)(&value);
+					for (component=0; component<componentOffset; ++component) {		// skip components before the one we want
+						istr->read((char *)bytes,4);
+						if (!istr->good()) return 0;
+					}
+					istr->read((char *)bytes,4);
+					if (!istr->good()) return 0;
+					Uint16 pixel = (Uint16)(value * scaleFactor);
+//cerr << value << ",";
+					*ptr++=pixel; ++sample;
+					for (component=componentOffset+1; component<componentNumber; ++component) {	// skip components after the one we want
+						istr->read((char *)bytes,4);
+						if (!istr->good()) return 0;
+					}
+				}
+				++col;
+			}
+//cerr << endl;
+			return col*samples;
+		}
+};
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	long offset=0;
+	(void)options.get("offset",offset);
+
+	unsigned rows=0;
+	if (!options.get("rows",rows) && !options.get("height",rows) && !options.get("h",rows)) {
+		cerr << EMsgDC(NeedOption) << " - rows" << endl;
+		bad=true;
+	}
+	
+	unsigned cols=0;
+	if (!options.get("columns",cols) && !options.get("width",cols) && !options.get("w",cols)) {
+		cerr << EMsgDC(NeedOption) << " - columns" << endl;
+		bad=true;
+	}
+	
+	unsigned frames=1;
+	options.get("frames",frames);
+	
+	// e.g. for real of real and imaginary pair, componentOffset=0,componentNumber=2
+	
+	unsigned componentOffset=0;
+	options.get("componentoffset",componentOffset);
+	
+	unsigned componentNumber=1;
+	options.get("componentnumber",componentNumber);
+	
+	double scaleFactor=1;
+	options.get("scale",scaleFactor);	// use 65535 to convert 0.0-1.0 to 16 but unsigned
+	
+	unsigned bits=16;
+
+	bool littleendian=options.get("little") || options.get("l");
+	bool bigendian=options.get("big") || options.get("b");
+
+	if (littleendian && bigendian) {
+		cerr << EMsgDC(OptionsIncompatible) << " - big & little" << endl;
+		bad=true;
+	}
+
+	unsigned samples;
+	bool samplespresent=options.get("samples",samples);
+
+	const char *photometricInterpretation=0;
+
+	int graypresent=(options.get("gray") || options.get("grey")) ? 1 : 0;
+	int rgbpresent=options.get("rgb") ? 1 : 0;
+	int argbpresent=options.get("argb") ? 1 : 0;
+	int hsvpresent=options.get("hsv") ? 1 : 0;
+	int cmykpresent=options.get("cmyk") ? 1 : 0;
+	int photometricpresent=options.get("photometric-interpretation",photometricInterpretation) ? 1 : 0;
+
+	int sumofphotometric=graypresent+rgbpresent+argbpresent+hsvpresent+cmykpresent+photometricpresent;
+
+	if (sumofphotometric == 0) {
+		if (samplespresent) {
+			if (samples == 1) {
+				photometricInterpretation="MONOCHROME2";
+			}
+			else if (samples == 3) {
+				photometricInterpretation="RGB";
+			}
+		}
+		else {
+			photometricInterpretation="MONOCHROME2";
+			samples=1;
+		}
+	}
+	else if (sumofphotometric > 1) {
+		cerr << EMsgDC(OptionsIncompatible) << " - gray,rgb,argb,hsv,cmyk,photometric-interpretation" << endl;
+		bad=true;
+	}
+	else {
+		if (graypresent) {
+			if (samplespresent && samples != 1) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 1 & gray" << endl;
+				bad=true;
+			}
+			else
+				samples=1;
+			photometricInterpretation="MONOCHROME2";
+		}
+		else if (rgbpresent) {
+			if (samplespresent && samples != 3) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 3 & rgb" << endl;
+				bad=true;
+			}
+			else
+				samples=3;
+			photometricInterpretation="RGB";
+		}
+		else if (argbpresent) {
+			if (samplespresent && samples != 4) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 4 & argb" << endl;
+				bad=true;
+			}
+			else
+				samples=4;
+			photometricInterpretation="ARGB";
+		}
+		else if (hsvpresent) {
+			if (samplespresent && samples != 3) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 3 & hsv" << endl;
+				bad=true;
+			}
+			else
+				samples=3;
+			photometricInterpretation="HSV";
+		}
+		else if (cmykpresent) {
+			if (samplespresent && samples != 4) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 4 & cmyk" << endl;
+				bad=true;
+			}
+			else
+				samples=4;
+			photometricInterpretation="CMYK";
+		}
+		else if (photometricpresent) {
+			if (!samplespresent) {
+				cerr << EMsgDC(OptionRequired) << " - samples" << endl;
+				bad=true;
+			}
+		}
+	}
+
+	Assert(photometricInterpretation);
+	Assert(samples);
+
+	bool bypixelpresent=options.get("color-by-pixel");
+	bool byplanepresent=options.get("color-by-plane");
+
+	unsigned planarConfiguration;
+
+	if (bypixelpresent && byplanepresent) {
+		cerr << EMsgDC(OptionsIncompatible) << " - color-by-pixel & color-by-plane" << endl;
+		bad=true;
+	}
+	if (samples == 1) {
+		if (bypixelpresent || byplanepresent) {
+			cerr << EMsgDC(OptionsIncompatible) << " - (color-by-pixel|color-by-plane) & samples = 1" << endl;
+			bad=true;
+		}
+	}
+	else {
+		if (bypixelpresent)
+			planarConfiguration=0;
+		else if (byplanepresent)
+			planarConfiguration=1;
+		else {
+			cerr << EMsgDC(OptionRequired) << " - color-by-pixel | color-by-plane" << endl;
+			bad=true;
+		}
+	}
+			
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -rows|-height|-h rows"
+			<< " -columns|-width|-w columns"
+			<< " [-frames frames]"
+			<< " [-scale scalefactor]"
+			<< " [-componentoffset 0|1]"
+			<< " [-componentnumber 2]"
+			<< " [-little|-l|-big]"
+			<< " [-samples n]"
+			<< " [-offset bytes]"
+			<< " [[-gray|-grey|-rgb|-argb|-hsv|-cmyk]|[-photometric-interpretation xxx]]"
+			<< " [-color-by-pixel|-color-by-plane]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	Uint16 bitsAllocated=((bits-1)/8+1)*8;
+	Uint16 bitsStored=bits;
+	Uint16 highBit=bits-1;
+	//Uint16 frames=1;
+
+	list+=new UnsignedShortAttribute(TagFromName(BitsAllocated),bitsAllocated);
+	list+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsStored);
+	list+=new UnsignedShortAttribute(TagFromName(HighBit),highBit);
+	list+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	list+=new UnsignedShortAttribute(TagFromName(Columns),cols);
+	list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),(Uint16)frames);
+	list+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),samples);
+	list+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),0u);
+	list+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),photometricInterpretation);
+	if (samples > 1) list+=new UnsignedShortAttribute(TagFromName(PlanarConfiguration),planarConfiguration);
+
+	// various Type 1 and Type 2 attributes for mandatory SC modules ...
+
+	list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+	list+=new LongStringAttribute(TagFromName(PatientID));
+	list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+	list+=new CodeStringAttribute(TagFromName(PatientSex));
+	list+=new ShortStringAttribute(TagFromName(StudyID));
+	list+=new DateStringAttribute(TagFromName(StudyDate));
+	list+=new TimeStringAttribute(TagFromName(StudyTime));
+	list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+	list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+	list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+	list+=new IntegerStringAttribute(TagFromName(InstanceNumber));
+
+	list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+	list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+
+	list+=new LongStringAttribute(TagFromName(Manufacturer));
+	list+=new CodeStringAttribute(TagFromName(PatientOrientation));
+
+	RawFloat_PixelDataSourceBase *pixeldatasrc=0;
+	if (littleendian) {
+		pixeldatasrc=new RawFloat_PixelDataSource_LittleEndian(in,offset,rows,cols,frames,samples,scaleFactor,componentOffset,componentNumber);
+	}
+	else if (bigendian) {
+		pixeldatasrc=new RawFloat_PixelDataSource_BigEndian(in,offset,rows,cols,frames,samples,scaleFactor,componentOffset,componentNumber);
+	}
+	Assert(pixeldatasrc);
+
+	list+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		frames,
+		samples,
+		&transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/rawftodc.man b/appsrc/dcfile/rawftodc.man
new file mode 100755
index 0000000..b89f4b1
--- /dev/null
+++ b/appsrc/dcfile/rawftodc.man
@@ -0,0 +1,137 @@
+.TH RAWFTODC 1 "6 March 2014" "DICOM PS3" "Create DICOM from raw float file"
+.SH NAME
+rawftodc \- ACR/NEMA DICOM PS3 ... Create DICOM from raw float file
+.SH SYNOPSIS
+.HP 10
+.B rawftodc
+.so man1/gen.so
+.B \-rows|\-height|\-h " rows"
+.B \-columns|\-width|\-w " cols"
+[
+.B \-frames " frames"
+]
+[
+.B \-scale " scalefactor"
+]
+[
+.B \-componentoffset " 0|1"
+]
+[
+.B \-componentnumber " 2"
+]
+[
+.B \-little|\-l|\-big
+]
+[
+.B \-samples " samples"
+]
+[
+.B \-gray|\-grey|\-rgb|\-argb|\-hsv|\-cmyk
+]
+[
+.B \-photometric-interpretation " xxx"
+]
+[
+.B \-color-by-pixel|\-color-by-plane
+]
+[
+.B \-v|verbose
+]
+.so man1/genin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B rawftodc
+reads the named raw input file and converts it to a 16-bit DICOM Secondary Capture Image Storage SOP Class instance stored in a DICOM file. Only uncompressed raw images with one sample per byte or word are supported, though multiple samples per pixel are allowed. The planar configuration can be specified but not re-ordered.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+.PP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.BI \-rows|\-height|\-h " rows"
+.RS
+Required.
+.RE
+.TP
+.BI \-columns|\-width|\-w " cols"
+.RS
+Required.
+.RE
+.TP
+.BI \-little|\-big
+.RS
+Required.
+.RE
+.TP
+.BI \-frames " frames"
+.RS
+Defaults to 1.
+.RE
+.TP
+.BI \-scale " scalefactor"
+.RS
+Normally the floating point values are truncated to 16 bit integers to create pixel 
+values. A scale factor may be specified by which to multiply them before truncation.
+Defaults to 1.
+.RE
+.TP
+.BI \-componentoffset " 0|1"
+.RS
+Normally it is assumed there is one floating point value per pixel. When more than one
+component is specified by -componentnumber, then which component (first, second etc.)
+may be specified. Usually the first component of a complex pair is real, and the
+second imaginary. Defaults to 0 (first component).
+.RE
+.TP
+.BI \-componentnumber " 2"
+.RS
+Specifies that there is more than one floating point value per pixel, e.g. a complex pair
+of two components. Defaults to 1 (one component).
+.RE
+.TP
+.BI \-samples " samples"
+.RS
+Defaults to appropriate value for photometric interpretation, or 1 if none specified. Only needs to be specified for unusual photometric interpretations.
+.RE
+.TP
+.BI \-gray|\-grey|\-rgb|\-argb|\-hsv|\-cmyk
+.RS
+Recognized photometric interpretations, defaults to gray if no samples specified or samples is 1, and rgb if samples is 3.
+.RE
+.TP
+.BI \-photometric-interpretation " xxx"
+.RS
+Explicitly specify string value for photometric interpretation attribute; will need value for samples.
+.RE
+.TP
+.BI \-color-by-pixel|\-color-by-plane
+.RS
+Specifies the planar configuration. Required if samples not 1 (explicitly or deduced from photometric interpretation). No default.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctoraw(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dciodvfy(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/rawtodc.cc b/appsrc/dcfile/rawtodc.cc
new file mode 100644
index 0000000..349689e
--- /dev/null
+++ b/appsrc/dcfile/rawtodc.cc
@@ -0,0 +1,310 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrothr.h"
+#include "attrmxls.h"
+#include "transynu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "ioopt.h"
+#include "dcopt.h"
+#include "rawsrc.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	bool imagepixelmoduleonly=options.get("imagepixelmoduleonly");
+
+	long offset=0;
+	(void)options.get("offset",offset);
+
+	unsigned rows=0;
+	if (!options.get("rows",rows) && !options.get("height",rows) && !options.get("h",rows)) {
+		cerr << EMsgDC(NeedOption) << " - rows" << endl;
+		bad=true;
+	}
+	
+	unsigned cols=0;
+	if (!options.get("columns",cols) && !options.get("width",cols) && !options.get("w",cols)) {
+		cerr << EMsgDC(NeedOption) << " - columns" << endl;
+		bad=true;
+	}
+	
+	unsigned frames=1;
+	options.get("frames",frames);
+	
+	unsigned bits=0;
+	if (!options.get("bits",bits) && !options.get("depth",bits) && !options.get("d",bits)) {
+		cerr << EMsgDC(NeedOption) << " - bits" << endl;
+		bad=true;
+	}
+
+	bool littleendian=options.get("little") || options.get("l");
+	bool bigendian=options.get("big") || options.get("b");
+
+	if (littleendian && bigendian) {
+		cerr << EMsgDC(OptionsIncompatible) << " - big & little" << endl;
+		bad=true;
+	}
+	else if (bits > 8 && !(littleendian || bigendian)) {
+		cerr << EMsgDC(OptionsIncompatible) << " - bits > 8 && !(little|big)" << endl;
+		bad=true;
+	}
+	else if (bits <= 8 && (littleendian || bigendian)) {
+		cerr << EMsgDC(OptionsIncompatible) << " - bits <= 8 & (little|big)" << endl;
+		bad=true;
+	}
+
+	if (bits < 1 || bits > 16) {
+		cerr << EMsgDC(OptionUnsupported) << " - bits = " << dec << bits << endl;
+		bad=true;
+	}
+
+	unsigned samples;
+	bool samplespresent=options.get("samples",samples);
+
+	const char *photometricInterpretation=0;
+
+	int graypresent=(options.get("gray") || options.get("grey")) ? 1 : 0;
+	int rgbpresent=options.get("rgb") ? 1 : 0;
+	int argbpresent=options.get("argb") ? 1 : 0;
+	int hsvpresent=options.get("hsv") ? 1 : 0;
+	int cmykpresent=options.get("cmyk") ? 1 : 0;
+	int photometricpresent=options.get("photometric-interpretation",photometricInterpretation) ? 1 : 0;
+
+	int sumofphotometric=graypresent+rgbpresent+argbpresent+hsvpresent+cmykpresent+photometricpresent;
+
+	if (sumofphotometric == 0) {
+		if (samplespresent) {
+			if (samples == 1) {
+				photometricInterpretation="MONOCHROME2";
+			}
+			else if (samples == 3) {
+				photometricInterpretation="RGB";
+			}
+		}
+		else {
+			photometricInterpretation="MONOCHROME2";
+			samples=1;
+		}
+	}
+	else if (sumofphotometric > 1) {
+		cerr << EMsgDC(OptionsIncompatible) << " - gray,rgb,argb,hsv,cmyk,photometric-interpretation" << endl;
+		bad=true;
+	}
+	else {
+		if (graypresent) {
+			if (samplespresent && samples != 1) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 1 & gray" << endl;
+				bad=true;
+			}
+			else
+				samples=1;
+			photometricInterpretation="MONOCHROME2";
+		}
+		else if (rgbpresent) {
+			if (samplespresent && samples != 3) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 3 & rgb" << endl;
+				bad=true;
+			}
+			else
+				samples=3;
+			photometricInterpretation="RGB";
+		}
+		else if (argbpresent) {
+			if (samplespresent && samples != 4) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 4 & argb" << endl;
+				bad=true;
+			}
+			else
+				samples=4;
+			photometricInterpretation="ARGB";
+		}
+		else if (hsvpresent) {
+			if (samplespresent && samples != 3) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 3 & hsv" << endl;
+				bad=true;
+			}
+			else
+				samples=3;
+			photometricInterpretation="HSV";
+		}
+		else if (cmykpresent) {
+			if (samplespresent && samples != 4) {
+				cerr << EMsgDC(OptionsIncompatible) << " - samples != 4 & cmyk" << endl;
+				bad=true;
+			}
+			else
+				samples=4;
+			photometricInterpretation="CMYK";
+		}
+		else if (photometricpresent) {
+			if (!samplespresent) {
+				cerr << EMsgDC(OptionRequired) << " - samples" << endl;
+				bad=true;
+			}
+		}
+	}
+
+	Assert(photometricInterpretation);
+	Assert(samples);
+
+	bool bypixelpresent=options.get("color-by-pixel");
+	bool byplanepresent=options.get("color-by-plane");
+
+	unsigned planarConfiguration;
+
+	if (bypixelpresent && byplanepresent) {
+		cerr << EMsgDC(OptionsIncompatible) << " - color-by-pixel & color-by-plane" << endl;
+		bad=true;
+	}
+	if (samples == 1) {
+		if (bypixelpresent || byplanepresent) {
+			cerr << EMsgDC(OptionsIncompatible) << " - (color-by-pixel|color-by-plane) & samples = 1" << endl;
+			bad=true;
+		}
+	}
+	else {
+		if (bypixelpresent)
+			planarConfiguration=0;
+		else if (byplanepresent)
+			planarConfiguration=1;
+		else {
+			cerr << EMsgDC(OptionRequired) << " - color-by-pixel | color-by-plane" << endl;
+			bad=true;
+		}
+	}
+			
+	input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< dicom_output_options.usage()
+			<< " -rows|-height|-h rows"
+			<< " -columns|-width|-w columns"
+			<< " -bits|-depth|-d bits"
+			<< " [-frames frames]"
+			<< " [-little|-l|-big|-b]"
+			<< " [-samples n]"
+			<< " [-offset bytes]"
+			<< " [[-gray|-grey|-rgb|-argb|-hsv|-cmyk]|[-photometric-interpretation xxx]]"
+			<< " [-color-by-pixel|-color-by-plane]"
+			<< " [-imagepixelmoduleonly]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	Uint16 bitsAllocated=((bits-1)/8+1)*8;
+	Uint16 bitsStored=bits;
+	Uint16 highBit=bits-1;
+
+	list+=new UnsignedShortAttribute(TagFromName(BitsAllocated),bitsAllocated);
+	list+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsStored);
+	list+=new UnsignedShortAttribute(TagFromName(HighBit),highBit);
+	list+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	list+=new UnsignedShortAttribute(TagFromName(Columns),cols);
+	list+=new IntegerStringAttribute(TagFromName(NumberOfFrames),(Uint16)frames);
+	list+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),samples);
+	list+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),0u);
+	list+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),photometricInterpretation);
+	if (samples > 1) list+=new UnsignedShortAttribute(TagFromName(PlanarConfiguration),planarConfiguration);
+
+	if (!imagepixelmoduleonly) {
+		// various Type 1 and Type 2 attributes for mandatory SC modules ...
+
+		list+=new PersonNameAttribute(TagFromName(PatientName),"^^^^");
+		list+=new LongStringAttribute(TagFromName(PatientID));
+		list+=new DateStringAttribute(TagFromName(PatientBirthDate));
+		list+=new CodeStringAttribute(TagFromName(PatientSex));
+		list+=new ShortStringAttribute(TagFromName(StudyID));
+		list+=new DateStringAttribute(TagFromName(StudyDate));
+		list+=new TimeStringAttribute(TagFromName(StudyTime));
+		list+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),"^^^^");
+		list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+		list+=new IntegerStringAttribute(TagFromName(SeriesNumber));
+		list+=new IntegerStringAttribute(TagFromName(InstanceNumber));
+
+		list+=new CodeStringAttribute(TagFromName(Modality),"OT");
+		list+=new CodeStringAttribute(TagFromName(ConversionType),"WSD");
+
+		list+=new LongStringAttribute(TagFromName(Manufacturer));
+		list+=new CodeStringAttribute(TagFromName(PatientOrientation));
+	}
+	
+	Raw_PixelDataSourceBase *pixeldatasrc=0;
+	if (bits <= 8) {
+		pixeldatasrc=new Raw_PixelDataSource_Byte(in,offset,rows,cols,frames,samples);
+	}
+	else if (littleendian) {
+		pixeldatasrc=new Raw_PixelDataSource_LittleEndian(in,offset,rows,cols,frames,samples);
+	}
+	else if (bigendian) {
+		pixeldatasrc=new Raw_PixelDataSource_BigEndian(in,offset,rows,cols,frames,samples);
+	}
+	Assert(pixeldatasrc);
+
+	list+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		frames,
+		samples,
+		&transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dcfile/rawtodc.man b/appsrc/dcfile/rawtodc.man
new file mode 100755
index 0000000..dc86fd7
--- /dev/null
+++ b/appsrc/dcfile/rawtodc.man
@@ -0,0 +1,318 @@
+.TH RAWTODC 1 "6 March 2014" "DICOM PS3" "Create DICOM from raw file"
+.SH NAME
+rawtodc \- ACR/NEMA DICOM PS3 ... Create DICOM from raw file
+.SH SYNOPSIS
+.HP 10
+.B rawtodc
+.so man1/gen.so
+.B \-rows|\-height|\-h " rows"
+.B \-columns|\-width|\-w " cols"
+.B \-bits|\-depth|\-d " bits"
+[
+.B \-frames " frames"
+]
+[
+.B \-little|\-l|\-big|\-b
+]
+[
+.B \-samples " samples"
+]
+[
+.B \-gray|\-grey|\-rgb|\-argb|\-hsv|\-cmyk
+]
+[
+.B \-photometric-interpretation " xxx"
+]
+[
+.B \-color-by-pixel|\-color-by-plane
+]
+[
+.B \-imagepixelmoduleonly
+]
+[
+.B \-v|verbose
+]
+.so man1/genin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+.B rawtodc
+reads the named raw input file and converts it to a DICOM Secondary Capture Image Storage SOP Class instance stored in a DICOM file. Only uncompressed raw images with one sample per byte or word are supported, though multiple samples per pixel are allowed. The planar configuration can be specified but not re-ordered.
+.LP
+During the translation, specific attributes may be deleted, added or
+replaced, class and instance unique identifiers generated or removed,
+group lengths added, or private attributes removed, as specified by
+the replacement options described in dcintro(1). This allows the
+specification of additional DICOM attributes, such as the patient's
+name, necessary to make a complete and useful SC instance.
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+.PP
+The basic switches are described in dcintro(1). Options specific to this program are:
+.TP
+.BI \-rows|\-height|\-h " rows"
+.RS
+Required.
+.RE
+.TP
+.BI \-columns|\-width|\-w " cols"
+.RS
+Required.
+.RE
+.TP
+.BI \-bits|\-depth|\-d " bits"
+.RS
+Required.
+.RE
+.TP
+.BI \-little|\-big
+.RS
+Required if bit depth is greater than 8.
+.RE
+.TP
+.BI \-frames " frames"
+.RS
+Defaults to 1.
+.RE
+.TP
+.BI \-samples " samples"
+.RS
+Defaults to appropriate value for photometric interpretation, or 1 if none specified. Only needs to be specified for unusual photometric interpretations.
+.RE
+.TP
+.BI \-gray|\-grey|\-rgb|\-argb|\-hsv|\-cmyk
+.RS
+Recognized photometric interpretations, defaults to gray if no samples specified or samples is 1, and rgb if samples is 3.
+.RE
+.TP
+.BI \-photometric-interpretation " xxx"
+.RS
+Explicitly specify string value for photometric interpretation attribute; will need value for samples.
+.RE
+.TP
+.BI \-color-by-pixel|\-color-by-plane
+.RS
+Specifies the planar configuration. Required if samples not 1 (explicitly or deduced from photometric interpretation). No default.
+.RE
+.TP
+.BI \-imagepixelmoduleonly
+.RS
+Write only the image pixel data module and not the basic mandatory secondary capture and composite IOD modules as well
+(e.g., prior to dcmerge'ing with an existing SOP instance that has its pixel data deleted); use the -nodisclaimer switch
+to avoid generating Image Comments and the -n switch to avoid adding a meta-information header (will fail if you do not
+since there is no SOP Class UID to use in the meta-information header).
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+# Create a gray image from 16 bit big-endian ...
+.RE
+% rawtodc -rows 256 -columns 256 -bits 16 -big \\
+.RE
+          /tmp/test.big /tmp/test.dc3
+.RE
+
+.RE
+# Create a gray image from 8 bit ...
+.RE
+% rawtodc -rows 256 -columns 256 -bits 8 \\
+.RE
+          /tmp/test.byte /tmp/test.dc3
+.RE
+\ 
+.RE
+# Create an rgb color-by-pixel image from 8 bit ...
+.RE
+% rawtodc -v -rows 256 -columns 256 -bits 8 \\
+.RE
+             -rgb -color-by-pixel \\
+.RE
+          /tmp/test.byte3 /tmp/test.dc3
+.RE
+ ...
+.RE
+(0x0028,0x0002) US Samples per Pixel [0x0003] 
+.RE
+(0x0028,0x0004) CS Photometric Interpretation <RGB > 
+.RE
+(0x0028,0x0006) US Planar Configuration [0x0000] 
+.RE
+ ...
+.RE
+\ 
+.RE
+# Create a gray image from 12 bit little endian ...
+.RE
+% rawtodc -v -rows 256 -columns 256 -bits 12 -little \\
+.RE
+          /tmp/test.little /tmp/test.dc3
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0020) DA Study Date <> 
+.RE
+(0x0008,0x0030) TM Study Time <> 
+.RE
+(0x0008,0x0050) SH Accession Number <> 
+.RE
+(0x0008,0x0060) CS Modality <OT> 
+.RE
+(0x0008,0x0064) CS Conversion Type <WSD > 
+.RE
+(0x0008,0x0070) LO Manufacturer <> 
+.RE
+(0x0008,0x0090) PN Referring Physician's Name <^^^^> 
+.RE
+(0x0010,0x0010) PN Patient's Name <^^^^>
+.RE
+(0x0010,0x0020) LO Patient's ID <> 
+.RE
+(0x0010,0x0030) DA Patient's Birth Date <> 
+.RE
+(0x0010,0x0040) CS Patient's Sex <> 
+.RE
+(0x0020,0x0010) SH Study ID <> 
+.RE
+(0x0020,0x0011) IS Series Number <> 
+.RE
+(0x0020,0x0013) IS Image Number <> 
+.RE
+(0x0020,0x0020) CS Patient Orientation <> 
+.RE
+(0x0028,0x0002) US Samples per Pixel [0x0001] 
+.RE
+(0x0028,0x0004) CS Photometric Interpretation <MONOCHROME2> 
+.RE
+(0x0028,0x0008) IS Number of Frames <1 > 
+.RE
+(0x0028,0x0010) US Rows [0x0100] 
+.RE
+(0x0028,0x0011) US Columns [0x0100] 
+.RE
+(0x0028,0x0100) US Bits Allocated [0x0010] 
+.RE
+(0x0028,0x0101) US Bits Stored [0x000c] 
+.RE
+(0x0028,0x0102) US High Bit [0x000b] 
+.RE
+(0x0028,0x0103) US Pixel Representation [0x0000] 
+.RE
+(0x7fe0,0x0010) OX Pixel Data VR=<OW>   VL=<0x20000>  
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0000) UL Meta Element Group Length [0x000000a4] 
+.RE
+(0x0002,0x0001) OB File Meta Information Version \\
+.RE
+                   [0x00,0x01] 
+.RE
+(0x0002,0x0002) UI Media Storage SOP Class UID \\
+.RE
+                   <1.2.840.10008.5.1.4.1.1.7> 
+.RE
+(0x0002,0x0003) UI Media Storage SOP Instance UID \\
+.RE
+                   <0.0.0.0.1.0.0.0.830260380> 
+.RE
+(0x0002,0x0010) UI Transfer Syntax UID \\
+.RE
+                   <1.2.840.10008.1.2> 
+.RE
+(0x0002,0x0012) UI Implementation Class UID  <0.0.0.0> 
+.RE
+(0x0002,0x0013) SH Implementation Version Name \\
+.RE
+                   <NOTSPECIFIED> 
+.RE
+(0x0002,0x0016) AE Source Application Entity Title \\
+.RE
+                   <NOTSPECIFIED> 
+.RE
+(0x0008,0x0016) UI SOP Class UID \\
+.RE
+                   <1.2.840.10008.5.1.4.1.1.7> 
+.RE
+(0x0008,0x0018) UI SOP Instance UID \\
+.RE
+                   <0.0.0.0.1.0.0.0.830260380> 
+.RE
+(0x0008,0x0020) DA Study Date <> 
+.RE
+(0x0008,0x0030) TM Study Time <> 
+.RE
+(0x0008,0x0050) SH Accession Number <> 
+.RE
+(0x0008,0x0060) CS Modality <OT> 
+.RE
+(0x0008,0x0064) CS Conversion Type <WSD > 
+.RE
+(0x0008,0x0070) LO Manufacturer <> 
+.RE
+(0x0008,0x0090) PN Referring Physician's Name <^^^^> 
+.RE
+(0x0010,0x0010) PN Patient's Name 			<^^^^> 
+.RE
+(0x0010,0x0020) LO Patient's ID <> 
+.RE
+(0x0010,0x0030) DA Patient's Birth Date <> 
+.RE
+(0x0010,0x0040) CS Patient's Sex <> 
+.RE
+(0x0020,0x000d) UI Study Instance UID \\
+.RE
+                   <0.0.0.0.2.0.830260380> 
+.RE
+(0x0020,0x000e) UI Series Instance UID \\
+.RE
+                   <0.0.0.0.3.0.0.830260380> 
+.RE
+(0x0020,0x0010) SH Study ID <> 
+.RE
+(0x0020,0x0011) IS Series Number <> 
+.RE
+(0x0020,0x0013) IS Image Number <> 
+.RE
+(0x0020,0x0020) CS Patient Orientation <> 
+.RE
+(0x0028,0x0002) US Samples per Pixel [0x0001] 
+.RE
+(0x0028,0x0004) CS Photometric Interpretation <MONOCHROME2> 
+.RE
+(0x0028,0x0008) IS Number of Frames <1 > 
+.RE
+(0x0028,0x0010) US Rows [0x0100] 
+.RE
+(0x0028,0x0011) US Columns [0x0100] 
+.RE
+(0x0028,0x0100) US Bits Allocated [0x0010] 
+.RE
+(0x0028,0x0101) US Bits Stored [0x000c] 
+.RE
+(0x0028,0x0102) US High Bit [0x000b] 
+.RE
+(0x0028,0x0103) US Pixel Representation [0x0000] 
+.RE
+(0x7fe0,0x0010) OX Pixel Data VR=<OW>   VL=<0x20000>  
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctoraw(1) ,
+.BR pnmtodc(1) ,
+.BR dciodvfy(1) ,
+.BR dcintro(1) ,
+.BR dcmerge(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dcfile/testdcdirmkorder.sh b/appsrc/dcfile/testdcdirmkorder.sh
new file mode 100755
index 0000000..5883ff6
--- /dev/null
+++ b/appsrc/dcfile/testdcdirmkorder.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+IMGDIR="../../images/dicom/forjpeg2000/discimg"
+OUTDIR="/tmp"
+
+US=`pwd`
+cd $IMGDIR
+
+for i in pcs psc scp spc csp cps
+do
+	echo '================================' $i '================================'
+	$US/dcdirmk [CN-Z]* > "$OUTDIR/DICOMDIR.$i" -dirrecorder $i
+	$US/dciodvfy "$OUTDIR/DICOMDIR.$i"
+	$US/dcdirdmp "$OUTDIR/DICOMDIR.$i" >"$OUTDIR/DICOMDIR.$i.dirdump" 2>&1
+	$US/dcdirdmp "$OUTDIR/DICOMDIR.$i" -showrecordinfo >"$OUTDIR/DICOMDIR.$i.dirdumpvv" 2>&1
+	$US/dcdump "$OUTDIR/DICOMDIR.$i" 2>&1 | grep 'Directory Record Type' >"$OUTDIR/DICOMDIR.$i.dumprectype"
+	if [ $i != "pcs" ]
+	then
+		echo "Should be no differences ..."
+		diff "$OUTDIR/DICOMDIR.pcs.dirdump" "$OUTDIR/DICOMDIR.$i.dirdump"
+		echo "Should be different record offsets ..."
+		diff "$OUTDIR/DICOMDIR.pcs.dirdumpvv" "$OUTDIR/DICOMDIR.$i.dirdumpvv"
+		echo "Should be different orders ..."
+		cmp "$OUTDIR/DICOMDIR.pcs.dumprectype" "$OUTDIR/DICOMDIR.$i.dumprectype"
+	fi
+done
+
diff --git a/appsrc/dcfile/testy2k.antodc.sh b/appsrc/dcfile/testy2k.antodc.sh
new file mode 100755
index 0000000..5689b2e
--- /dev/null
+++ b/appsrc/dcfile/testy2k.antodc.sh
@@ -0,0 +1,317 @@
+#!/bin/sh
+
+DCCREATEY2K="./dcsmpte -rows 256 -columns 256 -bits 8 -minval 0 -maxval 255"
+DCDUMP=./dcdump
+ANTODC=./antodc
+DCIODVFY=./dciodvfy
+
+createwithnewstyledate() {	# usage: makegenctwithnewdate dstfile yyyy mm dd hh min ss
+
+	$DCCREATEY2K "$1" -r StudyDate "$2$3$4" -r StudyTime "$5$6$7" -r PatientBirthDate "$2$3$4"
+}
+
+createwitholdstyledate() {	# usage: makegenctwithnewdate dstfile yyyy mm dd hh min ss
+
+	$DCCREATEY2K "$1" -r StudyDate "$2.$3.$4" -r StudyTime "$5:$6:$7" -r PatientBirthDate "$2.$3.$4"
+}
+
+
+TMPROOT=/tmp/`basename $0`.$$
+
+if [ "$#" != 2 ]
+then
+	bad="true"
+else
+	testlogdir="$1"	# eg. $(TOPDIR)/test/$(CURRENT_DIR)
+	mode="$2"	# eg. create|compare
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	elif [ ! -d "$testlogdir" -a "$mode" = "create" ]
+	then
+		echo "$0: making test log directory \"$testlogdir\"" 1>&2
+		mkdirhier "$testlogdir"
+		#echo "$0: no such test log directory as \"$testlogdir\"" 1>&2
+		#bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 testlogdir create|compare" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	if [ ! -d "$testlogdir" ]
+	then
+		mkdirhier "$testlogdir"
+	fi
+fi
+
+baseappname="antodc.y2k"
+comparename="$testlogdir/$baseappname.log"
+
+if [ "$mode" = "compare" ]
+then
+	dst="$TMPROOT.$baseappname.log"
+else
+	dst="$comparename"
+fi
+
+rm -f "$dst"
+
+echo "test of valid dates: ============================================" >>"$dst"
+
+for datea in \
+	19700101.000000 \
+	19700101.000059 \
+	19700101.000100 \
+	19700101.005959 \
+	19700101.015959 \
+	19700101.020000 \
+	19700101.235959 \
+	19700102.000000 \
+	19700227.235959 \
+	19700228.235959 \
+	19700301.000000 \
+	19710227.235959 \
+	19710228.235959 \
+	19710301.000000 \
+	19720227.235959 \
+	19720228.235959 \
+	19720229.235959 \
+	19720301.000000 \
+	19981231.235959 \
+	19990101.000000 \
+	19990227.235959 \
+	19990228.235959 \
+	19990301.000000 \
+	19990909.101010 \
+	19991231.235959 \
+	20000101.000000 \
+	20000227.235959 \
+	20000228.235959 \
+	20000229.235959 \
+	20000301.000000 \
+	20001231.235959 \
+	20010101.000000 \
+	20010228.235959 \
+	20010301.000000 \
+	20040228.235959 \
+	20040229.235959 \
+	20040301.000000
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9][0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[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]\).*$/\1/'`
+
+	echo "New style" >>"$dst"
+
+	createwithnewstyledate "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$ANTODC "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+
+	echo "Old style" >>"$dst"
+
+	createwitholdstyledate "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$ANTODC "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+done
+
+echo "test of invalid dates: ============================================" >>"$dst"
+
+for datea in \
+	19700229.235959 \
+	19980431.235959 \
+	19990229.000000 \
+	20000230.235959 \
+	20010229.235959 \
+	20040230.235959
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9][0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[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]\).*$/\1/'`
+
+	echo "New style" >>"$dst"
+
+	createwithnewstyledate "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$ANTODC "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+
+	echo "Old style" >>"$dst"
+
+	createwitholdstyledate "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$ANTODC "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+done
+
+
+echo "test of ambiguous dates: ============================================" >>"$dst"
+
+for datea in \
+	000101.101010 \
+	990101.101010
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+
+	echo "New style" >>"$dst"
+
+	createwithnewstyledate "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$ANTODC "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+
+	echo "Old style" >>"$dst"
+
+	createwitholdstyledate "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$ANTODC "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'patient|study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+done
+
+
+if [ "$mode" = "compare" ]
+then
+	if [ -f "$comparename" ]
+	then
+		echo "$baseappname:   comparing"
+		cmp "$dst" "$comparename"
+	else
+		echo "$baseappname:     nothing stored  to compare"
+		cat "$dst"
+	fi
+	rm "$dst"
+fi
diff --git a/appsrc/dcfile/testy2k.sh b/appsrc/dcfile/testy2k.sh
new file mode 100755
index 0000000..8d49288
--- /dev/null
+++ b/appsrc/dcfile/testy2k.sh
@@ -0,0 +1,317 @@
+#!/bin/sh
+
+DCCREATEY2K="./dcsmpte -rows 256 -columns 256 -bits 8 -minval 0 -maxval 255"
+DCDUMP=./dcdump
+DCCP=./dccp
+DCIODVFY=./dciodvfy
+
+createwithnewstyledate() {	# usage: makegenctwithnewdate dstfile yyyy mm dd hh min ss
+
+	$DCCREATEY2K "$1" -r StudyDate "$2$3$4" -r StudyTime "$5$6$7"
+}
+
+createwitholdstyledate() {	# usage: makegenctwithnewdate dstfile yyyy mm dd hh min ss
+
+	$DCCREATEY2K "$1" -r StudyDate "$2.$3.$4" -r StudyTime "$5:$6:$7"
+}
+
+
+TMPROOT=/tmp/`basename $0`.$$
+
+if [ "$#" != 2 ]
+then
+	bad="true"
+else
+	testlogdir="$1"	# eg. $(TOPDIR)/test/$(CURRENT_DIR)
+	mode="$2"	# eg. create|compare
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	elif [ ! -d "$testlogdir" -a "$mode" = "create" ]
+	then
+		echo "$0: making test log directory \"$testlogdir\"" 1>&2
+		mkdirhier "$testlogdir"
+		#echo "$0: no such test log directory as \"$testlogdir\"" 1>&2
+		#bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 testlogdir create|compare" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	if [ ! -d "$testlogdir" ]
+	then
+		mkdirhier "$testlogdir"
+	fi
+fi
+
+baseappname="dcfile.y2k"
+comparename="$testlogdir/$baseappname.log"
+
+if [ "$mode" = "compare" ]
+then
+	dst="$TMPROOT.$baseappname.log"
+else
+	dst="$comparename"
+fi
+
+rm -f "$dst"
+
+echo "test of valid dates: ============================================" >>"$dst"
+
+for datea in \
+	19700101.000000 \
+	19700101.000059 \
+	19700101.000100 \
+	19700101.005959 \
+	19700101.015959 \
+	19700101.020000 \
+	19700101.235959 \
+	19700102.000000 \
+	19700227.235959 \
+	19700228.235959 \
+	19700301.000000 \
+	19710227.235959 \
+	19710228.235959 \
+	19710301.000000 \
+	19720227.235959 \
+	19720228.235959 \
+	19720229.235959 \
+	19720301.000000 \
+	19981231.235959 \
+	19990101.000000 \
+	19990227.235959 \
+	19990228.235959 \
+	19990301.000000 \
+	19990909.101010 \
+	19991231.235959 \
+	20000101.000000 \
+	20000227.235959 \
+	20000228.235959 \
+	20000229.235959 \
+	20000301.000000 \
+	20001231.235959 \
+	20010101.000000 \
+	20010228.235959 \
+	20010301.000000 \
+	20040228.235959 \
+	20040229.235959 \
+	20040301.000000
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9][0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[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]\).*$/\1/'`
+
+	echo "New style" >>"$dst"
+
+	createwithnewstyledate "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$DCCP "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+
+	echo "Old style" >>"$dst"
+
+	createwitholdstyledate "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$DCCP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+done
+
+echo "test of invalid dates: ============================================" >>"$dst"
+
+for datea in \
+	19700229.235959 \
+	19980431.235959 \
+	19990229.000000 \
+	20000230.235959 \
+	20010229.235959 \
+	20040230.235959
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9][0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[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]\).*$/\1/'`
+
+	echo "New style" >>"$dst"
+
+	createwithnewstyledate "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$DCCP "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+
+	echo "Old style" >>"$dst"
+
+	createwitholdstyledate "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$DCCP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+done
+
+
+echo "test of ambiguous dates: ============================================" >>"$dst"
+
+for datea in \
+	000101.101010 \
+	990101.101010
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+
+	echo "New style" >>"$dst"
+
+	createwithnewstyledate "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$DCCP "$TMPROOT.test.newstyle.y2k.$datea.dcm" "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.newstyle.y2k.$datea.copy.dcm"
+
+	echo "Old style" >>"$dst"
+
+	createwitholdstyledate "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	echo "dcdump of created file" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of created file" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	$DCCP "$TMPROOT.test.oldstyle.y2k.$datea.dcm" "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+	echo "dcdump of copy" >>"$dst"
+	$DCDUMP "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	echo "dciodvfy of copy" >>"$dst"
+	$DCIODVFY "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm" 2>&1 \
+		| grep -v SCImage \
+			>>"$dst"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.dcm"
+	rm "$TMPROOT.test.oldstyle.y2k.$datea.copy.dcm"
+done
+
+
+if [ "$mode" = "compare" ]
+then
+	if [ -f "$comparename" ]
+	then
+		echo "$baseappname:   comparing"
+		cmp "$dst" "$comparename"
+	else
+		echo "$baseappname:     nothing stored  to compare"
+		cat "$dst"
+	fi
+	rm "$dst"
+fi
diff --git a/appsrc/dcintro/Imakefile b/appsrc/dcintro/Imakefile
new file mode 100755
index 0000000..0f0e9da
--- /dev/null
+++ b/appsrc/dcintro/Imakefile
@@ -0,0 +1,14 @@
+MANSUFFIX = 1
+
+all::
+
+InstallManPage(dcintro,$(INSTALLMANDIR)/man1)
+
+InstallManSource(optin,$(INSTALLMANDIR)/man1)
+InstallManSource(optout,$(INSTALLMANDIR)/man1)
+InstallManSource(gen,$(INSTALLMANDIR)/man1)
+InstallManSource(genin,$(INSTALLMANDIR)/man1)
+InstallManSource(genout,$(INSTALLMANDIR)/man1)
+InstallManSource(binin,$(INSTALLMANDIR)/man1)
+InstallManSource(binout,$(INSTALLMANDIR)/man1)
+
diff --git a/appsrc/dcintro/binin.so b/appsrc/dcintro/binin.so
new file mode 100755
index 0000000..0272fd2
--- /dev/null
+++ b/appsrc/dcintro/binin.so
@@ -0,0 +1,6 @@
+[
+.B \-if|\-input-file|< " name"
+]
+[
+.B \-input-byteorder|-input-endian " big|little"
+]
diff --git a/appsrc/dcintro/binout.so b/appsrc/dcintro/binout.so
new file mode 100755
index 0000000..19cc76d
--- /dev/null
+++ b/appsrc/dcintro/binout.so
@@ -0,0 +1,6 @@
+[
+.B \-of|\-output-file|> " name"
+]
+[
+.B \-byteorder|-endian|output-byteorder|-output-endian " big|little"
+]
diff --git a/appsrc/dcintro/dcintro.man b/appsrc/dcintro/dcintro.man
new file mode 100755
index 0000000..cdd2e1f
--- /dev/null
+++ b/appsrc/dcintro/dcintro.man
@@ -0,0 +1,296 @@
+.TH DCINTRO 1 "6 Mar 2014" "DICOM PS3" "DICOM PS3 - Introduction and Options"
+.SH NAME
+dcintro \- ACR/NEMA DICOM PS3 ... Introduction and options
+.SH SYNOPSIS
+.HP 10
+.B dcxxxx
+.so man1/gen.so
+.so man1/optin.so
+.so man1/optout.so
+.SH DESCRIPTION
+.LP
+The options described are common to all tools and conversions as necessary when either DICOM input or output or both are supported.
+.LP
+Though input may be redirected from standard input or standard output, in general the ability to seek is required on input, and if this is not supported, as in input from a pipe, the operation will fail.
+.LP
+Under normal circumstances, utilities that read DICOM or older ACR/NEMA
+input files, whether a meta-information header is present or not, should
+be able to automatically determine the appropriate Transfer Syntax.
+.LP
+For utilities that write DICOM output,  the default
+behaviour is to write a meta-information header and preamble, and
+hence produce files that are compliant with DICOM PS 3.10. No other files
+can claim conformance to the standard, and even then compliance with a
+specific Media Application Profile is still required. It may be useful
+to suppress the meta-header if it is required to construct datasets
+contained temporarily within files prior to exchange using the DICOM
+network protocol.
+.LP
+For utilities that write DICOM output, various attributes may be manually
+deleted or replaced after the initial DICOM dataset is read or generated.
+Various options exist to replace such attributes before or after the image
+pixel data encoding is established, hence either incorrect attributes can
+be corrected, or the encoding can be changed.
+.SH OPTIONS
+.LP
+Input options are:
+.TP
+.BI \-if|\-input-file|< " name"
+.RS
+.RE
+.TP
+.B \-input-nometa
+.RS
+Input does not contain a meta-information header and preamble.
+Needed only when the automatic determination of input Transfer Syntax fails.
+When specified, suppresses check for the presence of a meta-information
+header and will use either the transfer syntax specified by \-input-ts " uid"
+or the byte order and implicit or explicit vr, otherwise these are automatically
+determined from the dataset (guessed).
+.RE
+.TP
+.B \-input-nolengthtoend
+.RS
+Ignore the length to end value, if present. Normally the reading stops
+after length to end bytes have been read and any trailing padding present
+is ignored.
+.RE
+.TP
+.B \-ignoreoutofordertags
+.RS
+Ignore tags that are incorrectly out of order and keep reading the dataset.
+Useful for debugging invalid data sets, but may cause parser to get lost if
+problem is not really out of order tags. Also enables parsing past various
+other encoding issues that are not related to tag order.
+.RE
+.TP
+.B \-usvrlutdata
+.RS
+If the VR for the LUT Data attribute is not explicitly specified, then a US
+(rather than the default OW) VR will be used; can be used to convert one
+form to another by converting to implicit first and then using this option .
+.RE
+.TP
+.BI \-input-ts " uid"
+.RS
+Use the input Transfer Syntax specified by the UID.
+Needed only when the automatic determination of input Transfer Syntax fails.
+Will be used to set the transfer syntax for the meta-header (if present) rather
+than the dataset unless \-input-nometa is also specified.
+.RE
+.TP
+.B \-input-default
+.RS
+Use the default Implicit VR Little Endian Transfer Syntax for input.
+Needed only when the automatic determination of input Transfer Syntax fails.
+.RE
+.TP
+.B \-input-byteorder|-input-endian " big|little"
+.RS
+Select an uncompressed input Transfer Syntax that uses the specified
+byteorder. Requires that the input Value Representation also be
+specified.
+Needed only when the automatic determination of input Transfer Syntax fails.
+.RE
+.TP
+.B \-input-vr " implicit|explicit"
+.RS
+Select an uncompressed input Transfer Syntax that uses the specified
+Value Representation. Requires that the input byteorder also be
+specified.
+Needed only when the automatic determination of input Transfer Syntax fails.
+.RE
+.LP
+Output options are:
+.TP
+.BI \-of|\-output-file|> " name"
+.RS
+.RE
+.TP
+.B \-n|\-nometa|\-output-nometa
+.RS
+Don't write an output meta-information header and preamble.
+.RE
+.TP
+.B \-n|\-justmeta|\-output-justmeta
+.RS
+Write only a meta-information header and preamble, and not the
+data set itself.
+.RE
+.TP
+.B \-implicitmeta|\-output-implicitmeta
+.RS
+Use the obsolete pre-standard draft Implicit VR Little Endian
+Transfer Syntax for the meta-information header.
+.RE
+.TP
+.BI \-ts|\-output-ts|\-output-transfersyntax " uid"
+.RS
+Use the output Transfer Syntax specified by the UID.
+.RE
+.TP
+.B \-output-default
+.RS
+Use the default Implicit VR Little Endian Transfer Syntax for output.
+This is the default mode anyway, and the option is redundant.
+.RE
+.TP
+.B \-output\-byteorder|\-output\-endian " big|little"
+.RS
+Select an uncompressed output Transfer Syntax that uses the specified
+byteorder. Requires that the output Value Representation also be
+specified.
+.RE
+.TP
+.B \-output-vr " implicit|explicit"
+.RS
+Select an uncompressed output Transfer Syntax that uses the specified
+Value Representation. Requires that the output byteorder also be
+specified.
+.RE
+.TP
+.BI \-s|\-stamp " uiddatetimestamp"
+.RS
+When UIDs are automatically generated, they incorporate the current
+date and time to ensure uniqueness. If two invocations of a utility
+are to generate the same UIDs, for example for two images of a series
+to share a common SeriesInstanceUID, then the current date and time
+may be replaced in the generated uid by the explicitly specified
+value. This option is also useful for regression testing to ensure
+that the output matches that of a previous invocation, without being
+affected by the current date and time. A typical value to use for
+a stamp shared between multiple images in the same study would
+be "`date '+%Y%m%d%H%M%S'`.$$".
+.RE
+.TP
+.B \-addlengths
+.RS
+Add group length attributes to every group.
+Normally the group length is only generated for the meta-information
+header group, where it is mandatory. These have been retired by DICOM
+3.0 but are often checked by applications, and are sometimes required
+by older ACR/NEMA applications. Note that
+LengthToEnd is not added by this option unless \-addlengthtoend is
+also specified.
+.RE
+.TP
+.B \-addlengthtoend
+.RS
+Add the LengthToEnd attribute. This has been retired by DICOM
+3.0 but are often checked by applications, and are sometimes required
+by older ACR/NEMA applications.
+.RE
+.TP
+.B \-tiff|\-tif
+.RS
+Add a TIFF header in the DICOM Meta-information preamble, which points
+to a TIFF Image File Directory (IFD) at the end of the dataset in the
+DataSetTrailingPadding Attribute after the PixelData attribute. This
+allows the DICOM file to be a 'dual-personality' file, sharing the
+pixel data with two formats, and allowing both TIFF and DICOM readers
+to handle the image.
+.RE
+.TP
+.B \-removeprivate
+.RS
+Remove any private attributes present, ie. all those in odd groups.
+.RE
+.TP
+.B \-removeinstanceuid
+.RS
+Remove any existing SOPInstanceUID. This is generally a prelude to
+automatically generating a new one, which will happen unless
+\-noadddicom is also specified.
+.RE
+.TP
+.B \-noadddicom
+.RS
+Suppress the automatic insertion of SOP Instance UIDs and SOP Class
+UIDs where they are missing and can be meaningfully guessed at given
+the presence and values of other attributes. For a composite image
+object instance, the StudyID, SeriesNumber and ImageNumber will be
+used together with the date and time or explicit stamp (see \-stamp)
+to generate StudyInstanceUID, SeriesInstanceUID and SOPInstanceUID.
+The SOPClassUID will be guessed at from Modality if not ambiguous.
+There is no guarantee that a complete IOD will be generated in this
+manner, it is just a best effort when required attributes are
+missing, and has no effect on an exisiting complete IOD.
+.RE
+.TP
+.B \-nodisclaimer
+.RS
+Suppress insertion of the 'for investigational use only'
+disclaimer in the ImageComments attribute.
+.RE
+.TP
+.B \-disambiguateseriesbydescription
+.RS
+When inserting Series Instance UIDs, use not just the Series Number but also the characters in the Series
+Description to (try to) build a value that disambiguates series with the same number but different descriptions.
+.RE
+.TP
+.BI \-d|\-delete " deletekeyword"
+.RS
+Delete the named attribute after the data set has been cleaned of old
+metaheader attributes, UIDs (if requested) and private attributes (if
+requested), but before automatic DICOM attributes (if not suppressed),
+disclaimers (if not suppressed) and new metaheader (if not suppressed)
+attributes have been added.
+.RE
+.TP
+.BI \-r|\-replace|\-rb|\-replace\-before " replacekeyword values"
+.RS
+Replace or add the named attribute after the data set has been cleaned of old
+metaheader attributes, UIDs (if requested) and private attributes (if
+requested), but BEFORE automatic DICOM attributes (if not suppressed),
+disclaimers (if not suppressed) and new metaheader attributes (if not
+suppressed) have been added, and the output encoding transformations
+have been established. Note that attributes related to image pixel encoding
+changed at this point WILL affect actual image pixel data transformations,
+and hence may be specified here to cause such transformations,
+based on BitsAllocated, BitsStored and HighBit. Note that in order to
+replace a value with a string that starts with a leading hyphen ('-')
+that might otherwise be interpreted as another option, enter the value in
+single quotes and preceded the hyphen with a space (which will later
+be elided), eg. "-r Rescale Intercept ' -1024'".
+.RE
+.TP
+.BI \-ra|\-replace\-after " replacekeyword values"
+.RS
+Replace or add the named attribute after 
+automatic DICOM attributes (if not suppressed),
+disclaimers (if not suppressed) and new metaheader attributes (if not
+suppressed) have been added, but before group lengths (if requested)
+have been added. Note that attributes related to image pixel encoding
+changed at this point will have no effect on actual image pixel data
+transformations, and hence may be specified here to correct such
+attributes.
+.RE
+.TP
+.BI \-version
+.RS
+Print a version string to stderr, and exit if there are no other arguments.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.TP
+\n 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+\ 
+.SH AUTHOR
+.LP
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+Though redirection from a file on standard input should work, certain libraries give incorrect results, rather than actually failing with a seek error ... this has been observed with libg++ 2.7.0 and is a bit worrying. The use of standard input redirection has not been removed however, for use in those environments in which it does work.
+.LP
+One cannot specify a zero length string value for replacements on the
+command line. One can specify a string with a single space byte, which
+then gets removed as trailing zeroes are removed, so one can make zero
+length type 2 attributes.
diff --git a/appsrc/dcintro/gen.so b/appsrc/dcintro/gen.so
new file mode 100755
index 0000000..802fdd0
--- /dev/null
+++ b/appsrc/dcintro/gen.so
@@ -0,0 +1,3 @@
+[
+.B \-version
+]
diff --git a/appsrc/dcintro/genin.so b/appsrc/dcintro/genin.so
new file mode 100755
index 0000000..514ec2b
--- /dev/null
+++ b/appsrc/dcintro/genin.so
@@ -0,0 +1,3 @@
+[
+.B \-if|\-input-file|< " name"
+]
diff --git a/appsrc/dcintro/genout.so b/appsrc/dcintro/genout.so
new file mode 100755
index 0000000..c395dc2
--- /dev/null
+++ b/appsrc/dcintro/genout.so
@@ -0,0 +1,3 @@
+[
+.B \-of|\-output-file|> " name"
+]
diff --git a/appsrc/dcintro/optin.so b/appsrc/dcintro/optin.so
new file mode 100755
index 0000000..0b1e4d6
--- /dev/null
+++ b/appsrc/dcintro/optin.so
@@ -0,0 +1,18 @@
+[
+.B \-if|\-input-file|< " name"
+]
+[
+.B \-input-byteorder|-input-endian " big|little"
+]
+[
+.B \-input-nolengthtoend
+]
+[
+.B \-input-nometa
+]
+[
+.B \-ignoreoutofordertags
+]
+[
+.B \-input-ts|\-input-transfersyntax " uid"|-input-default
+]
diff --git a/appsrc/dcintro/optout.so b/appsrc/dcintro/optout.so
new file mode 100755
index 0000000..ff74b85
--- /dev/null
+++ b/appsrc/dcintro/optout.so
@@ -0,0 +1,68 @@
+[
+.B \-d|\-delete " deletekeyword"
+] ...
+[
+.B \-r|\-replace|\-rb|\-replace\-before " replacekeyword values"
+] ...
+[
+.B \-ra|\-replace\-after " replacekeyword values"
+] ...
+[
+.B \-of|\-output-file|> " name"
+]
+[
+.B \-n|\-nometa|\-output-nometa
+]
+[
+.B \-n|\-justmeta|\-output-justmeta
+]
+[
+.B \-n|\-implicitmeta|\-output-implicitmeta
+]
+[
+.B \-ts|\-output-ts|\-output-transfersyntax " uid"
+]
+[
+.B \-output-default
+]
+[
+.B \-output-byteorder|-output-endian " big|little"
+]
+[
+.B \-output-vr " implicit|explicit"
+]
+[
+.B \-s|\-stamp " uiddatetimestamp"
+]
+[
+.B \-instancecreationdate " date"
+]
+[
+.B \-instancecreationtime " time"
+]
+[
+.B \-timezoneoffsetfromutc " offset"
+]
+[
+.B \-addlengths
+]
+[
+.B \-addlengthtoend
+][
+.B \-tiff|tif
+]
+[
+.B \-removeprivate
+]
+[
+.B \-removeinstanceuid
+]
+[
+.B \-noadddicom
+]
+[
+.B \-nodisclaimer
+]
+[
+.B \-disambiguateseriesbydescription
+]
diff --git a/appsrc/dconvert/Imakefile b/appsrc/dconvert/Imakefile
new file mode 100755
index 0000000..aeba036
--- /dev/null
+++ b/appsrc/dconvert/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = support xxxx pace imtn gen gaw shim somp himr pq toshiba signa ge9800
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/appsrc/dconvert/gaw/Imakefile b/appsrc/dconvert/gaw/Imakefile
new file mode 100755
index 0000000..f28d32e
--- /dev/null
+++ b/appsrc/dconvert/gaw/Imakefile
@@ -0,0 +1,37 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = gawtodc.cc
+OBJSTODC = gawtodc.o
+
+SRCSDUMP = gawdump.cc
+OBJSDUMP = gawdump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(gawtodc)
+NormalCCProgramTarget(gawtodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdgaw.a $(PROJECTDCONVERTDEPLIBS),-ldgaw $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(gawtodc,$(INSTALLBINDIR))
+InstallManPage(gawtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(gawdump)
+NormalCCProgramTarget(gawdump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdgaw.a $(PROJECTDCONVERTDEPLIBS),-ldgaw $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(gawdump,$(INSTALLBINDIR))
+InstallManPage(gawdump,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./gawdump "-awct" $(TOP)/images/genaw/ct $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./gawtodc "-awct -v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/genaw/ct $(TOP)/test/$(CURRENT_DIR) compare todc
+	@$(TOP)/support/testapp testlist ./gawdump "-awmr" $(TOP)/images/genaw/mr $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./gawtodc "-awmr -v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/genaw/mr $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./gawdump "-awct" $(TOP)/images/genaw/ct $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./gawtodc "-awct -v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/genaw/ct $(TOP)/test/$(CURRENT_DIR) create todc
+	@$(TOP)/support/testapp testlist ./gawdump "-awmr" $(TOP)/images/genaw/mr $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./gawtodc "-awmr -v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/genaw/mr $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/gaw/gawdump.cc b/appsrc/dconvert/gaw/gawdump.cc
new file mode 100644
index 0000000..61bc646
--- /dev/null
+++ b/appsrc/dconvert/gaw/gawdump.cc
@@ -0,0 +1,112 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "gaw.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+
+	BinaryInputOptions 	binary_input_options(options);
+
+	int useoptioncount=0;
+
+	bool useawct=options.get("awct");
+	if (useawct) ++useoptioncount;
+
+	bool useawmr=options.get("awmr");
+	if (useawmr) ++useoptioncount;
+
+	int noffset;
+	Uint32 offsetargs[5];
+	if ((noffset=options.get("offset",offsetargs,5)) != -1 && noffset != 5) {
+		cerr << EMsgDC(OptionIncomplete)
+		     << " - offset"
+		     << endl;
+		bad=true;
+	}
+
+	bool lengthpresent=options.get("lengthpresent");
+
+	if (useoptioncount && (lengthpresent || noffset != -1)) {
+		cerr << EMsgDC(OptionsIncompatible) << endl;
+		bad=true; 
+	}
+
+	// there is no default ...
+
+	if (!useoptioncount && noffset == -1) {
+		cerr << EMsgDC(NeedOption) << " -awct|-awmr|-offset" << endl;
+		bad=true; 
+	}
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " -awct|-awmr"
+			<< "|[-offset file suite exam series image [-lengthpresent]]]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	GAW_Conversion *convertor=0;
+	if (noffset == 5)
+		convertor=new GAW_Conversion(bin,cerr,
+			true,
+			lengthpresent,
+			offsetargs[0],
+			offsetargs[1],
+			offsetargs[2],
+			offsetargs[3],
+			offsetargs[4]);
+	else if (useawct)
+		convertor=new GAW_Conversion(bin,cerr,
+			true,	// explicit
+			false,	// length field
+			3240,	// file header
+			0,	// suite header
+			116,	// exam header
+			1156,	// series header
+			2184);	// image header
+	else if (useawmr)
+		convertor=new GAW_Conversion(bin,cerr,
+			true,	// explicit
+			false,	// length field
+			3228,	// file header
+			0,	// suite header
+			116,	// exam header
+			1156,	// series header
+			2184);	// image header
+	Assert(convertor);
+
+	convertor->dumpCommon(cout);
+	convertor->dumpSelectedImage(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/gaw/gawdump.man b/appsrc/dconvert/gaw/gawdump.man
new file mode 100755
index 0000000..dbffe4b
--- /dev/null
+++ b/appsrc/dconvert/gaw/gawdump.man
@@ -0,0 +1,71 @@
+.TH GAWDUMP 1 "06 March 2014" "DICOM PS3" "GE Advantage Windows to DICOM"
+.SH NAME
+gawdump \- ACR/NEMA DICOM PS3 ... GE Advantage Windows to DICOM
+.SH SYNOPSIS
+.HP 10
+.B gawdump
+.so man1/gen.so
+[
+.B \-awmr|\-awct|\-offset " filehdr suitehdr examhdr serieshdr imghdr [\-lengthpresent]"
+]
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B gawdump
+reads the named GE Advantage Windows input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.LP
+The options that select the header layout of the Advantage Windows file are as follows. Note that one must be specified and there is no default.
+.TP
+.BI \-awct
+.RS
+The input file is a CT.
+.RE
+.TP
+.BI \-awmr
+.RS
+The input file is an MR.
+.RE
+.TP
+.BI \-offset " filehdr suitehdr examhdr serieshdr imghdr"
+.RS
+The input file layout is explicitly specified by the byte offsets from 0 to the corresponding header.
+.RE
+.TP
+.BI \-lengthpresent
+.RS
+The image pixel data is preceded by a 4 byte length field that should be skipped. This is only usually encountered with Genesis DAT and tape formats, and hasn't been encountered with Advantage Windows formats. Only valid when the offsets are explicitly specified.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% gawdump -awct test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR gawtodc(1) ,
+.BR gendump(1) ,
+.BR gentodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+The header layout was derived by guesswork by comparing the known Genesis layout to the similar Advantage Windows layout, but may not be reliable.
diff --git a/appsrc/dconvert/gaw/gawtodc.cc b/appsrc/dconvert/gaw/gawtodc.cc
new file mode 100644
index 0000000..6de8b1f
--- /dev/null
+++ b/appsrc/dconvert/gaw/gawtodc.cc
@@ -0,0 +1,140 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "gaw.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	int useoptioncount=0;
+
+	bool useawct=options.get("awct");
+	if (useawct) ++useoptioncount;
+
+	bool useawmr=options.get("awmr");
+	if (useawmr) ++useoptioncount;
+
+	int noffset;
+	Uint32 offsetargs[5];
+	if ((noffset=options.get("offset",offsetargs,5)) != -1 && noffset != 5) {
+		cerr << EMsgDC(OptionIncomplete)
+		     << " - offset"
+		     << endl;
+		bad=true;
+	}
+
+	bool lengthpresent=options.get("lengthpresent");
+
+	if (useoptioncount && (lengthpresent || noffset != -1)) {
+		cerr << EMsgDC(OptionsIncompatible) << endl;
+		bad=true; 
+	}
+
+	// there is no default ...
+
+	if (!useoptioncount && noffset == -1) {
+		cerr << EMsgDC(NeedOption) << " -awct|-awmr|-offset" << endl;
+		bad=true; 
+	}
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " -awct|-awmr"
+			<< "|-offset file suite exam series image [-lengthpresent]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	GAW_Conversion *convertor=0;
+	if (noffset == 5)
+		convertor=new GAW_Conversion(bin,cerr,
+			true,
+			lengthpresent,
+			offsetargs[0],
+			offsetargs[1],
+			offsetargs[2],
+			offsetargs[3],
+			offsetargs[4]);
+	else if (useawct)
+		convertor=new GAW_Conversion(bin,cerr,
+			true,	// explicit
+			false,	// length field
+			3240,	// file header
+			0,	// suite header
+			116,	// exam header
+			1156,	// series header
+			2184);	// image header
+	else if (useawmr)
+		convertor=new GAW_Conversion(bin,cerr,
+			true,	// explicit
+			false,	// length field
+			3228,	// file header
+			0,	// suite header
+			116,	// exam header
+			1156,	// series header
+			2184);	// image header
+	Assert(convertor);
+
+	convertor->convertAll(&list,&transfersyntax);
+
+	return usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose) ? 0 : 1;
+}
+
diff --git a/appsrc/dconvert/gaw/gawtodc.man b/appsrc/dconvert/gaw/gawtodc.man
new file mode 100755
index 0000000..79234b6
--- /dev/null
+++ b/appsrc/dconvert/gaw/gawtodc.man
@@ -0,0 +1,81 @@
+.TH GAWTODC 1 "06 March 2014" "DICOM PS3" "GE Advantage Windows to DICOM"
+.SH NAME
+gawtodc \- ACR/NEMA DICOM PS3 ... GE Advantage Windows to DICOM
+.SH SYNOPSIS
+.HP 10
+.B gawtodc
+.so man1/gen.so
+[
+.B \-awmr|\-awct|\-offset " filehdr suitehdr examhdr serieshdr imghdr [\-lengthpresent]"
+]
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B gawtodc
+reads the named GE Advantage Windows input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.LP
+The options that select the header layout of the Advantage Windows file are as follows. Note that one must be specified and there is no default.
+.TP
+.BI \-awct
+.RS
+The input file is a CT.
+.RE
+.TP
+.BI \-awmr
+.RS
+The input file is an MR.
+.RE
+.TP
+.BI \-offset " filehdr suitehdr examhdr serieshdr imghdr"
+.RS
+The input file layout is explicitly specified by the byte offsets from 0 to the corresponding header.
+.RE
+.TP
+.BI \-lengthpresent
+.RS
+The image pixel data is preceded by a 4 byte length field that should be skipped. This is only usually encountered with Genesis DAT and tape formats, and hasn't been encountered with Advantage Windows formats. Only valid when the offsets are explicitly specified.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% gawtodc \-v \-awct test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR gawdump(1) ,
+.BR gendump(1) ,
+.BR gentodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+The header layout was derived by guesswork by comparing the known Genesis layout to the similar Advantage Windows layout, but may not be reliable.
diff --git a/appsrc/dconvert/ge9800/Imakefile b/appsrc/dconvert/ge9800/Imakefile
new file mode 100755
index 0000000..c09b586
--- /dev/null
+++ b/appsrc/dconvert/ge9800/Imakefile
@@ -0,0 +1,33 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = ge9800todc.cc
+OBJSTODC = ge9800todc.o
+
+SRCSDUMP = ge9800dump.cc
+OBJSDUMP = ge9800dump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(ge9800todc)
+NormalCCProgramTarget(ge9800todc,$(OBJSTODC),$(TOP)/libsrc/lib/libdge9800.a $(PROJECTDCONVERTDEPLIBS),-ldge9800 $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(ge9800todc,$(INSTALLBINDIR))
+InstallManPage(ge9800todc,$(INSTALLMANDIR)/man1)
+
+AllTarget(ge9800dump)
+NormalCCProgramTarget(ge9800dump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdge9800.a $(PROJECTDCONVERTDEPLIBS),-ldge9800 $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(ge9800dump,$(INSTALLBINDIR))
+InstallManPage(ge9800dump,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./ge9800dump "" $(TOP)/images/ge9800 $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./ge9800todc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/ge9800 $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./ge9800dump "" $(TOP)/images/ge9800 $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./ge9800todc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/ge9800 $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/ge9800/ge9800dump.cc b/appsrc/dconvert/ge9800/ge9800dump.cc
new file mode 100644
index 0000000..6a853e7
--- /dev/null
+++ b/appsrc/dconvert/ge9800/ge9800dump.cc
@@ -0,0 +1,46 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800dump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "ge9800.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	GE9800_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout,0);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/ge9800/ge9800dump.man b/appsrc/dconvert/ge9800/ge9800dump.man
new file mode 100755
index 0000000..9cb8e4d
--- /dev/null
+++ b/appsrc/dconvert/ge9800/ge9800dump.man
@@ -0,0 +1,43 @@
+.TH GE9800DUMP 1 "06 March 2014" "DICOM PS3" "ge9800 dump"
+.SH NAME
+ge9800dump \- ACR/NEMA DICOM PS3 ... ge9800 dump contents
+.SH SYNOPSIS
+.HP 10
+.B ge9800dump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B ge9800dump
+reads the named GE CT 9800 input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% ge9800dump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR ge9800todc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/ge9800/ge9800todc.cc b/appsrc/dconvert/ge9800/ge9800todc.cc
new file mode 100644
index 0000000..5d7fe92
--- /dev/null
+++ b/appsrc/dconvert/ge9800/ge9800todc.cc
@@ -0,0 +1,77 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800todc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "ge9800.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	GE9800_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax,0);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/ge9800/ge9800todc.man b/appsrc/dconvert/ge9800/ge9800todc.man
new file mode 100755
index 0000000..58b7c6e
--- /dev/null
+++ b/appsrc/dconvert/ge9800/ge9800todc.man
@@ -0,0 +1,53 @@
+.TH GE9800TODC 1 "06 March 2014" "DICOM PS3" "ge9800 to DICOM"
+.SH NAME
+ge9800todc \- ACR/NEMA DICOM PS3 ... ge9800 to DICOM
+.SH SYNOPSIS
+.HP 10
+.B ge9800todc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B ge9800todc
+reads the named ge9800 input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% ge9800todc \-v test.YV test.dcm
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR ge9800dump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/gen/Imakefile b/appsrc/dconvert/gen/Imakefile
new file mode 100755
index 0000000..a6e9e37
--- /dev/null
+++ b/appsrc/dconvert/gen/Imakefile
@@ -0,0 +1,38 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = gentodc.cc
+OBJSTODC = gentodc.o
+
+SRCSDUMP = gendump.cc
+OBJSDUMP = gendump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(gentodc)
+NormalCCProgramTarget(gentodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdgen.a $(PROJECTDCONVERTDEPLIBS),-ldgen $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(gentodc,$(INSTALLBINDIR))
+InstallManPage(gentodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(gendump)
+NormalCCProgramTarget(gendump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdgen.a $(PROJECTDCONVERTDEPLIBS),-ldgen $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(gendump,$(INSTALLBINDIR))
+InstallManPage(gendump,$(INSTALLMANDIR)/man1)
+
+InstallScript(gentodc.dat.all,$(INSTALLBINDIR))
+InstallManPage(gentodc.dat.all,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	./testy2k.sh $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) compare
+	@$(TOP)/support/testapp testlist ./gendump "" $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./gentodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	./testy2k.sh $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) create
+	@$(TOP)/support/testapp testlist ./gendump "" $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./gentodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/gen/gendump.cc b/appsrc/dconvert/gen/gendump.cc
new file mode 100644
index 0000000..10a837f
--- /dev/null
+++ b/appsrc/dconvert/gen/gendump.cc
@@ -0,0 +1,103 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gendump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "gen.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+
+	BinaryInputOptions 	binary_input_options(options);
+
+	int useoptioncount=0;
+
+	bool useximg=options.get("ximg");
+	if (useximg) ++useoptioncount;
+
+	bool usedat=options.get("dat");
+	if (options.get("tape")) usedat=true;
+	if (usedat) ++useoptioncount;
+
+	int noffset;
+	Uint32 offsetargs[5];
+	if ((noffset=options.get("offset",offsetargs,5)) != -1 && noffset != 5) {
+		cerr << EMsgDC(OptionIncomplete)
+		     << " - offset"
+		     << endl;
+		bad=true;
+	}
+
+	bool lengthpresent=options.get("lengthpresent");
+
+	if (useoptioncount && (lengthpresent || noffset != -1)) {
+		cerr << EMsgDC(OptionsIncompatible) << endl;
+		bad=true; 
+	}
+
+	// the default if no options is to read ximg format ...
+
+	if (!useoptioncount && noffset == -1) useximg=true;
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [-ximg|-dat|-tape"
+			<< "|[-offset file suite exam series image [-lengthpresent]]]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	GEN_Conversion *convertor=0;
+	if (noffset == 5)
+		convertor=new GEN_Conversion(bin,cerr,
+			true,
+			lengthpresent,
+			offsetargs[0],
+			offsetargs[1],
+			offsetargs[2],
+			offsetargs[3],
+			offsetargs[4]);
+	else if (usedat)
+		convertor=new GEN_Conversion(bin,cerr,
+			true,	// explicit
+			true,	// length field
+			3180,	// file header
+			0,	// suite header
+			114,	// exam header
+			1138,	// series header
+			2158);	// image header
+	else if (useximg)
+		convertor=new GEN_Conversion(bin,cerr);
+	Assert(convertor);
+
+	convertor->dumpCommon(cout);
+	convertor->dumpSelectedImage(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/gen/gendump.man b/appsrc/dconvert/gen/gendump.man
new file mode 100755
index 0000000..791fe1d
--- /dev/null
+++ b/appsrc/dconvert/gen/gendump.man
@@ -0,0 +1,70 @@
+.TH GENDUMP 1 "06 March 2014" "DICOM PS3" "Genesis dump"
+.SH NAME
+gendump \- ACR/NEMA DICOM PS3 ... Genesis dump contents
+.SH SYNOPSIS
+.HP 10
+.B gendump
+.so man1/gen.so
+[
+.B \-ximg|\-dat|\-tape|\-offset " filehdr suitehdr examhdr serieshdr imghdr [\-lengthpresent]"
+]
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B gendump
+reads the named GE Genesis input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.LP
+The options that select the header layout of the Advantage Windows file are as follows. Note that one must be specified and there is no default.
+.TP
+.BI \-ximg
+.RS
+The input file is the output of the "ximg" extraction tool used to extract an image from the Genesis database. This is the "generic" form of the genesis file, with an initial file header that provides the locations of the other headers. This is the default if no format option is specified.
+.RE
+.TP
+.BI \-dat|\-tape
+.RS
+The input file is from a tape or DAT archive. The Genesis database headers have been prepended to the file in the order suite/exam/series/image, then a file header (without valid pointers), and finally the pixel data. Note that the pixel data is preceded by a 4 byte length value that is skipped when this option is selected.
+.RE
+.TP
+.BI \-offset " filehdr suitehdr examhdr serieshdr imghdr"
+.RS
+The input file layout is explicitly specified by the byte offsets from 0 to the corresponding header.
+.RE
+.TP
+.BI \-lengthpresent
+.RS
+The image pixel data is preceded by a 4 byte length field that should be skipped. Only valid when the offsets are explicitly specified.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% gendump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR gentodc(1) ,
+.BR gawtodc(1) ,
+.BR gawdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/gen/gentodc.all.script b/appsrc/dconvert/gen/gentodc.all.script
new file mode 100755
index 0000000..4221835
--- /dev/null
+++ b/appsrc/dconvert/gen/gentodc.all.script
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# convert a whole tree of images, making sure to use 
+# shared Study and Series instance UIDs by using stamp
+
+stamp="`date '+%Y%m%d%H%M%S'`.$$"
+for i in `find . -type f -name 'I.[0-9][0-9][0-9]' -print`
+do
+	echo $i
+	gentodc -stamp "$stamp" -output-endian little -output-vr explicit $i $i.dcm
+done
diff --git a/appsrc/dconvert/gen/gentodc.cc b/appsrc/dconvert/gen/gentodc.cc
new file mode 100644
index 0000000..98cb89c
--- /dev/null
+++ b/appsrc/dconvert/gen/gentodc.cc
@@ -0,0 +1,131 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gentodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "gen.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	int useoptioncount=0;
+
+	bool useximg=options.get("ximg");
+	if (useximg) ++useoptioncount;
+
+	bool usedat=options.get("dat");
+	if (options.get("tape")) usedat=true;
+	if (usedat) ++useoptioncount;
+
+	int noffset;
+	Uint32 offsetargs[5];
+	if ((noffset=options.get("offset",offsetargs,5)) != -1 && noffset != 5) {
+		cerr << EMsgDC(OptionIncomplete)
+		     << " - offset"
+		     << endl;
+		bad=true;
+	}
+
+	bool lengthpresent=options.get("lengthpresent");
+
+	if (useoptioncount && (lengthpresent || noffset != -1)) {
+		cerr << EMsgDC(OptionsIncompatible) << endl;
+		bad=true; 
+	}
+
+	// the default if no options is to read ximg format ...
+
+	if (!useoptioncount && noffset == -1) useximg=true;
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-ximg|-dat|-tape"
+			<< "|[-offset file suite exam series image [-lengthpresent]]]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	GEN_Conversion *convertor=0;
+	if (noffset == 5)
+		convertor=new GEN_Conversion(bin,cerr,
+			true,
+			lengthpresent,
+			offsetargs[0],
+			offsetargs[1],
+			offsetargs[2],
+			offsetargs[3],
+			offsetargs[4]);
+	else if (usedat)
+		convertor=new GEN_Conversion(bin,cerr,
+			true,	// explicit
+			true,	// length field
+			3180,	// file header
+			0,	// suite header
+			114,	// exam header
+			1138,	// series header
+			2158);	// image header
+	else if (useximg)
+		convertor=new GEN_Conversion(bin,cerr);
+	Assert(convertor);
+
+	convertor->convertAll(&list,&transfersyntax);
+
+	return usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose) ? 0 : 1;
+}
+
diff --git a/appsrc/dconvert/gen/gentodc.dat.all.man b/appsrc/dconvert/gen/gentodc.dat.all.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dconvert/gen/gentodc.dat.all.script b/appsrc/dconvert/gen/gentodc.dat.all.script
new file mode 100755
index 0000000..839b8ec
--- /dev/null
+++ b/appsrc/dconvert/gen/gentodc.dat.all.script
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Usage: gentodc.dat.all dirname
+#
+# where dirname is the directory name where images are
+#
+# converts files in place and adds .dcm extension
+#
+
+DCMSUFFIX="dcm"
+
+STAMP=`date +%Y%m%d%H%M%S`.$$
+
+GENTODC="gentodc"
+GENTODCOPTS="-dat"
+
+if [ ! $# = 1 ]
+then
+	echo 1>&2 "Usage: `basename $0` dirname"
+	exit 1
+fi
+
+for i in `find "$1" -type f -print`
+do
+	if [ -f "$i" ]
+	then
+		echo "Converting $i to $i.$DCMSUFFIX"
+
+		$GENTODC $GENTODCOPTS -output-vr explicit -output-endian little -stamp "$STAMP" \
+			"$i" "$i.$DCMSUFFIX"
+	fi
+done
+
+exit 0
diff --git a/appsrc/dconvert/gen/gentodc.man b/appsrc/dconvert/gen/gentodc.man
new file mode 100755
index 0000000..87d4ce1
--- /dev/null
+++ b/appsrc/dconvert/gen/gentodc.man
@@ -0,0 +1,80 @@
+.TH GENTODC 1 "06 March 2014" "DICOM PS3" "Genesis to DICOM"
+.SH NAME
+gentodc \- ACR/NEMA DICOM PS3 ... Genesis to DICOM
+.SH SYNOPSIS
+.HP 10
+.B gentodc
+.so man1/gen.so
+[
+.B \-ximg|\-dat|\-tape|\-offset " filehdr suitehdr examhdr serieshdr imghdr [\-lengthpresent]"
+]
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B gentodc
+reads the named gen input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.LP
+The options that select the header layout of the Advantage Windows file are as follows. Note that one must be specified and there is no default.
+.TP
+.BI \-ximg
+.RS
+The input file is the output of the "ximg" extraction tool used to extract an image from the Genesis database. This is the "generic" form of the genesis file, with an initial file header that provides the locations of the other headers. This is the default if no format option is specified.
+.RE
+.TP
+.BI \-dat|\-tape
+.RS
+The input file is from a tape or DAT archive. The Genesis database headers have been prepended to the file in the order suite/exam/series/image, then a file header (without valid pointers), and finally the pixel data. Note that the pixel data is preceded by a 4 byte length value that is skipped when this option is selected.
+.RE
+.TP
+.BI \-offset " filehdr suitehdr examhdr serieshdr imghdr"
+.RS
+The input file layout is explicitly specified by the byte offsets from 0 to the corresponding header.
+.RE
+.TP
+.BI \-lengthpresent
+.RS
+The image pixel data is preceded by a 4 byte length field that should be skipped. Only valid when the offsets are explicitly specified.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% gentodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR gendump(1) ,
+.BR gawtodc(1) ,
+.BR gawdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/gen/testy2k.sh b/appsrc/dconvert/gen/testy2k.sh
new file mode 100755
index 0000000..0a5ae91
--- /dev/null
+++ b/appsrc/dconvert/gen/testy2k.sh
@@ -0,0 +1,183 @@
+#!/bin/sh
+
+MKTIME=../../../support/mktime
+GENDUMP=./gendump
+GENTODC=./gentodc
+DCDUMP=../../dcfile/dcdump
+BINPATCH=../../misc/binpatch
+
+TMPROOT=/tmp/`basename $0`.$$
+
+makegenctwithnewdate() {	# usage: makegenctwithnewdate srcfile dstfile yyyy mm dd hh min ss
+
+	unixdate=`$MKTIME "$3" "$4" "$5" "$6" "$7" "$8" | awk '{print $4;}'`
+
+	"$BINPATCH" "$1" "$2" \
+		-i 1442 4 "$unixdate" b \
+		-i 1562 4 "$unixdate" b \
+		-i 2270 4 "$unixdate" b \
+		-i 2274 4 "$unixdate" b \
+		-i 2408 4 "$unixdate" b \
+		-i 3292 4 "$unixdate" b \
+		-i 3296 4 "$unixdate" b \
+		-i 3832 4 "$unixdate" b
+}
+
+makegenmrwithnewdate() {	# usage: makegenctwithnewdate srcfile dstfile yyyy mm dd hh min ss
+
+	unixdate=`$MKTIME "$3" "$4" "$5" "$6" "$7" "$8" | awk '{print $4;}'`
+
+	"$BINPATCH" "$1" "$2" \
+		-i 2754 4 "$unixdate" b \
+		-i 2874 4 "$unixdate" b \
+		-i 3582 4 "$unixdate" b \
+		-i 3586 4 "$unixdate" b \
+		-i 3720 4 "$unixdate" b \
+		-i 4604 4 "$unixdate" b \
+		-i 4608 4 "$unixdate" b \
+		-i 4932 4 "$unixdate" b \
+		-i 5110 4 "$unixdate" b
+}
+
+if [ "$#" != 3 ]
+then
+	bad="true"
+else
+	imagedir="$1"	# eg. $(TOPDIR)/images/genesis
+	testlogdir="$2"	# eg. $(TOPDIR)/test/$(CURRENT_DIR)
+	mode="$3"	# eg. create|compare
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	elif [ ! -d "$imagedir" -o ! -f "$imagedir/test.ct" -o ! -f "$imagedir/test.mr" ]
+	then
+		echo "$0: no such image directory as \"$imagedir\" or test.ct or test.mr missing" 1>&2
+		bad="true"
+	elif [ ! -d "$testlogdir" -a "$mode" = "create" ]
+	then
+		echo "$0: making test log directory \"$testlogdir\"" 1>&2
+		mkdirhier "$testlogdir"
+		#echo "$0: no such test log directory as \"$testlogdir\"" 1>&2
+		#bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 testlogdir create|compare" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	if [ ! -d "$testlogdir" ]
+	then
+		mkdirhier "$testlogdir"
+	fi
+fi
+
+baseappname="genesis.y2k"
+comparename="$testlogdir/$baseappname.log"
+
+if [ "$mode" = "compare" ]
+then
+	dst="$TMPROOT.$baseappname.log"
+else
+	dst="$comparename"
+fi
+
+rm -f "$dst"
+
+# test of valid dates:
+
+for datea in \
+	19700101.000000 \
+	19700101.000059 \
+	19700101.000100 \
+	19700101.005959 \
+	19700101.015959 \
+	19700101.020000 \
+	19700101.235959 \
+	19700102.000000 \
+	19700227.235959 \
+	19700228.235959 \
+	19700301.000000 \
+	19710227.235959 \
+	19710228.235959 \
+	19710301.000000 \
+	19720227.235959 \
+	19720228.235959 \
+	19720229.235959 \
+	19720301.000000 \
+	19981231.235959 \
+	19990101.000000 \
+	19990227.235959 \
+	19990228.235959 \
+	19990301.000000 \
+	19990909.101010 \
+	19991231.235959 \
+	20000101.000000 \
+	20000227.235959 \
+	20000228.235959 \
+	20000229.235959 \
+	20000301.000000 \
+	20001231.235959 \
+	20010101.000000 \
+	20010228.235959 \
+	20010301.000000 \
+	20040228.235959 \
+	20040229.235959 \
+	20040301.000000
+do
+	echo "$datea"
+	echo "$datea" >>"$dst"
+	yyyy=`echo "$datea" | sed 's/^\([0-9][0-9][0-9][0-9]\).*$/\1/'`
+	mm=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	dd=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	hh=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.]\([0-9][0-9]\).*$/\1/'`
+	min=`echo "$datea" | sed 's/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][.][0-9][0-9]\([0-9][0-9]\).*$/\1/'`
+	ss=`echo "$datea" | sed 's/^[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]\).*$/\1/'`
+
+	echo "CT" >>"$dst"
+
+	makegenctwithnewdate "$imagedir/test.ct" "$TMPROOT.test.ct.y2k.$datea" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	$GENDUMP "$TMPROOT.test.ct.y2k.$datea" 2>&1 \
+		| egrep -i 'date/time' \
+			>>"$dst"
+	$GENTODC "$TMPROOT.test.ct.y2k.$datea" "$TMPROOT.test.ct.y2k.$datea.dcm"
+	$DCDUMP "$TMPROOT.test.ct.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	rm "$TMPROOT.test.ct.y2k.$datea.dcm"
+	rm "$TMPROOT.test.ct.y2k.$datea"
+
+	echo "MR" >>"$dst"
+
+	makegenmrwithnewdate "$imagedir/test.mr" "$TMPROOT.test.mr.y2k.$datea" "$yyyy" "$mm" "$dd" "$hh" "$min" "$ss"
+	$GENDUMP "$TMPROOT.test.mr.y2k.$datea" 2>&1 \
+		| egrep -i 'date/time' \
+			>>"$dst"
+	$GENTODC "$TMPROOT.test.mr.y2k.$datea" "$TMPROOT.test.mr.y2k.$datea.dcm"
+	$DCDUMP "$TMPROOT.test.mr.y2k.$datea.dcm" 2>&1 \
+		| egrep -i 'date|time' \
+		| egrep -i 'study|series|image|acquisition' \
+			>>"$dst"
+	rm "$TMPROOT.test.mr.y2k.$datea.dcm"
+	rm "$TMPROOT.test.mr.y2k.$datea"
+done
+
+if [ "$mode" = "compare" ]
+then
+	if [ -f "$comparename" ]
+	then
+		echo "$baseappname:   comparing"
+		cmp "$dst" "$comparename"
+	else
+		echo "$baseappname:     nothing stored  to compare"
+		cat "$dst"
+	fi
+	rm "$dst"
+fi
diff --git a/appsrc/dconvert/himr/Imakefile b/appsrc/dconvert/himr/Imakefile
new file mode 100755
index 0000000..136a95d
--- /dev/null
+++ b/appsrc/dconvert/himr/Imakefile
@@ -0,0 +1,36 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = himrtodc.cc
+OBJSTODC = himrtodc.o
+
+SRCSDUMP = himrdump.cc
+OBJSDUMP = himrdump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(himrtodc)
+NormalCCProgramTarget(himrtodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdhimr.a $(PROJECTDCONVERTDEPLIBS),-ldhimr $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(himrtodc,$(INSTALLBINDIR))
+InstallManPage(himrtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(himrdump)
+NormalCCProgramTarget(himrdump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdhimr.a $(PROJECTDCONVERTDEPLIBS),-ldhimr $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(himrdump,$(INSTALLBINDIR))
+InstallManPage(himrdump,$(INSTALLMANDIR)/man1)
+
+InstallScript(himrunid,$(INSTALLBINDIR))
+InstallManPage(himrunid,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./himrdump "" $(TOP)/images/himr $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./himrtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/himr $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./himrdump "" $(TOP)/images/himr $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./himrtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/himr $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/himr/himrdump.cc b/appsrc/dconvert/himr/himrdump.cc
new file mode 100644
index 0000000..22b349e
--- /dev/null
+++ b/appsrc/dconvert/himr/himrdump.cc
@@ -0,0 +1,46 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "himr.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	HIMR_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/himr/himrdump.man b/appsrc/dconvert/himr/himrdump.man
new file mode 100755
index 0000000..398a45b
--- /dev/null
+++ b/appsrc/dconvert/himr/himrdump.man
@@ -0,0 +1,43 @@
+.TH HIMRDUMP 1 "06 March 2014" "DICOM PS3" "himr dump"
+.SH NAME
+himrdump \- ACR/NEMA DICOM PS3 ... himr dump contents
+.SH SYNOPSIS
+.HP 10
+.B himrdump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B himrdump
+reads the named himr input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% himrdump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR himrtodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/himr/himrtodc.cc b/appsrc/dconvert/himr/himrtodc.cc
new file mode 100644
index 0000000..d24051d
--- /dev/null
+++ b/appsrc/dconvert/himr/himrtodc.cc
@@ -0,0 +1,77 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "himr.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	HIMR_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/himr/himrtodc.man b/appsrc/dconvert/himr/himrtodc.man
new file mode 100755
index 0000000..fe4d551
--- /dev/null
+++ b/appsrc/dconvert/himr/himrtodc.man
@@ -0,0 +1,53 @@
+.TH HIMRTODC 1 "06 March 2014" "DICOM PS3" "himr to DICOM"
+.SH NAME
+himrtodc \- ACR/NEMA DICOM PS3 ... himr to DICOM
+.SH SYNOPSIS
+.HP 10
+.B himrtodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B himrtodc
+reads the named himr input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% himrtodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR himrdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/himr/himrunid.man b/appsrc/dconvert/himr/himrunid.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dconvert/himr/himrunid.script b/appsrc/dconvert/himr/himrunid.script
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dconvert/imtn/Imakefile b/appsrc/dconvert/imtn/Imakefile
new file mode 100755
index 0000000..5735304
--- /dev/null
+++ b/appsrc/dconvert/imtn/Imakefile
@@ -0,0 +1,33 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = imtntodc.cc
+OBJSTODC = imtntodc.o
+
+SRCSDUMP = imtndump.cc
+OBJSDUMP = imtndump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(imtntodc)
+NormalCCProgramTarget(imtntodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdimtn.a $(PROJECTDCONVERTDEPLIBS),-ldimtn $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(imtntodc,$(INSTALLBINDIR))
+InstallManPage(imtntodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(imtndump)
+NormalCCProgramTarget(imtndump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdimtn.a $(PROJECTDCONVERTDEPLIBS),-ldimtn $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(imtndump,$(INSTALLBINDIR))
+InstallManPage(imtndump,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./imtndump "" $(TOP)/images/imatron $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./imtntodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/imatron $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./imtndump "" $(TOP)/images/imatron $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./imtntodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/imatron $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/imtn/imtndump.cc b/appsrc/dconvert/imtn/imtndump.cc
new file mode 100644
index 0000000..cca0116
--- /dev/null
+++ b/appsrc/dconvert/imtn/imtndump.cc
@@ -0,0 +1,50 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtndump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "imtn.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	int imagenumber;
+	if (!options.get("image",imagenumber)) imagenumber=0;
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [-image imagenumberfrom0]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	IMTN_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout,imagenumber);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/imtn/imtndump.man b/appsrc/dconvert/imtn/imtndump.man
new file mode 100755
index 0000000..f6df54b
--- /dev/null
+++ b/appsrc/dconvert/imtn/imtndump.man
@@ -0,0 +1,43 @@
+.TH IMTNDUMP 1 "06 March 2014" "DICOM PS3" "Imatron dump"
+.SH NAME
+imtndump \- ACR/NEMA DICOM PS3 ... Imatron dump contents
+.SH SYNOPSIS
+.HP 10
+.B imtndump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B imtndump
+reads the named Imatron input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% imtndump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR imtntodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/imtn/imtntodc.cc b/appsrc/dconvert/imtn/imtntodc.cc
new file mode 100644
index 0000000..f6281ca
--- /dev/null
+++ b/appsrc/dconvert/imtn/imtntodc.cc
@@ -0,0 +1,81 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtntodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "imtn.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	int imagenumber;
+	if (!options.get("image",imagenumber)) imagenumber=0;
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-image imagenumberfrom0]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	IMTN_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax,imagenumber);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/imtn/imtntodc.man b/appsrc/dconvert/imtn/imtntodc.man
new file mode 100755
index 0000000..bc5b531
--- /dev/null
+++ b/appsrc/dconvert/imtn/imtntodc.man
@@ -0,0 +1,53 @@
+.TH IMTNTODC 1 "06 March 2014" "DICOM PS3" "Imatron to DICOM"
+.SH NAME
+imtntodc \- ACR/NEMA DICOM PS3 ... Imatron to DICOM
+.SH SYNOPSIS
+.HP 10
+.B imtntodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B imtntodc
+reads the named Imatron input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% imtntodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR imtndump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/pace/Imakefile b/appsrc/dconvert/pace/Imakefile
new file mode 100755
index 0000000..9cc3841
--- /dev/null
+++ b/appsrc/dconvert/pace/Imakefile
@@ -0,0 +1,36 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = pacetodc.cc
+OBJSTODC = pacetodc.o
+
+SRCSDUMP = pacedump.cc
+OBJSDUMP = pacedump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(pacetodc)
+NormalCCProgramTarget(pacetodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdpace.a $(PROJECTDCONVERTDEPLIBS),-ldpace $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(pacetodc,$(INSTALLBINDIR))
+InstallManPage(pacetodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(pacedump)
+NormalCCProgramTarget(pacedump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdpace.a $(PROJECTDCONVERTDEPLIBS),-ldpace $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(pacedump,$(INSTALLBINDIR))
+InstallManPage(pacedump,$(INSTALLMANDIR)/man1)
+
+InstallScript(paceunid,$(INSTALLBINDIR))
+InstallManPage(paceunid,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./pacedump "" $(TOP)/images/pace $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./pacetodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/pace $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./pacedump "" $(TOP)/images/pace $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./pacetodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/pace $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/pace/pacedump.cc b/appsrc/dconvert/pace/pacedump.cc
new file mode 100644
index 0000000..6be22f2
--- /dev/null
+++ b/appsrc/dconvert/pace/pacedump.cc
@@ -0,0 +1,46 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacedump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "pace.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	PACE_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/pace/pacedump.man b/appsrc/dconvert/pace/pacedump.man
new file mode 100755
index 0000000..998658c
--- /dev/null
+++ b/appsrc/dconvert/pace/pacedump.man
@@ -0,0 +1,43 @@
+.TH PACEDUMP 1 "06 March 2014" "DICOM PS3" "pace dump"
+.SH NAME
+pacedump \- ACR/NEMA DICOM PS3 ... GE PACE dump contents
+.SH SYNOPSIS
+.HP 10
+.B pacedump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B pacedump
+reads the named GE PACE input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% pacedump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR pacetodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/pace/pacetodc.cc b/appsrc/dconvert/pace/pacetodc.cc
new file mode 100644
index 0000000..5e66f84
--- /dev/null
+++ b/appsrc/dconvert/pace/pacetodc.cc
@@ -0,0 +1,77 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacetodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "pace.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	PACE_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/pace/pacetodc.man b/appsrc/dconvert/pace/pacetodc.man
new file mode 100755
index 0000000..4acc50f
--- /dev/null
+++ b/appsrc/dconvert/pace/pacetodc.man
@@ -0,0 +1,51 @@
+.TH PACETODC 1 "06 March 2014" "DICOM PS3" "GE PACE to DICOM"
+.SH NAME
+pacetodc \- ACR/NEMA DICOM PS3 ... GE PACE to DICOM
+.SH SYNOPSIS
+.HP 10
+.B pacetodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.SH DESCRIPTION
+.LP
+.B pacetodc
+reads the named GE PACE input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% pacetodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR pacedump(1) ,
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/pace/paceunid.man b/appsrc/dconvert/pace/paceunid.man
new file mode 100755
index 0000000..75d4496
--- /dev/null
+++ b/appsrc/dconvert/pace/paceunid.man
@@ -0,0 +1,30 @@
+.TH PACEUNID 1 "18 November 1995" "Vendor Archives" "PACE remove identification"
+.SH NAME
+paceunid \- PACE remove identification
+.SH SYNOPSIS
+.HP 10
+.B paceunid
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B paceunid
+reads the named pace input file and copies it to a pace output file, replacing identifying information with something innocuous.
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+\
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/pace/paceunid.script b/appsrc/dconvert/pace/paceunid.script
new file mode 100755
index 0000000..87ce810
--- /dev/null
+++ b/appsrc/dconvert/pace/paceunid.script
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# replace identifying information in pace file
+
+# Usage: paceunid infile outfile
+
+if [ $# != 2 ]
+then
+	echo "Usage: `basename $0` infile outfile" 1>&2
+	exit 1
+fi
+
+#	256+38	12	SPATID
+#	256+54	12	SPATNAME
+#	256+144	32	SHOSP
+#	256+256	250	SDESC ...
+#	768+576	42	ISRDESC ...
+#	768+618	25	IIMDESC ...
+#	768+644	340	IEXDESC ...
+
+
+binpatch -v -r 294  12  "12345678" " " \
+            -r 310  12  "CITIZEN DOE" " " \
+            -r 400  32  "ST. ELSEWHERE" " " \
+            -r 512  250 "THIS IS A STUDY DESCRIPTION" " " \
+            -r 1344 42  "THIS IS A SERIES DESCRIPTION" " " \
+            -r 1386 25  "THIS IS AN IMAGE " " " \
+            -r 1412 340 "THIS IS AN EXTENSION DESCRIPTION" " " \
+         $1 $2
+
+exit $?
diff --git a/appsrc/dconvert/pq/Imakefile b/appsrc/dconvert/pq/Imakefile
new file mode 100755
index 0000000..0418fd8
--- /dev/null
+++ b/appsrc/dconvert/pq/Imakefile
@@ -0,0 +1,41 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = pqtodc.cc
+OBJSTODC = pqtodc.o
+
+SRCSDUMP = pqdump.cc
+OBJSDUMP = pqdump.o
+
+SRCSSPLIT = pqsplit.cc
+OBJSSPLIT = pqsplit.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(pqtodc)
+NormalCCProgramTarget(pqtodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdpq.a $(PROJECTDCONVERTDEPLIBS),-ldpq $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(pqtodc,$(INSTALLBINDIR))
+InstallManPage(pqtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(pqdump)
+NormalCCProgramTarget(pqdump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdpq.a $(PROJECTDCONVERTDEPLIBS),-ldpq $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(pqdump,$(INSTALLBINDIR))
+InstallManPage(pqdump,$(INSTALLMANDIR)/man1)
+
+AllTarget(pqsplit)
+NormalCCProgramTarget(pqsplit,$(OBJSSPLIT), , ,-lm)
+InstallProgram(pqsplit,$(INSTALLBINDIR))
+InstallManPage(pqsplit,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./pqdump "" $(TOP)/images/pq $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./pqtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/pq $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./pqdump "" $(TOP)/images/pq $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./pqtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/pq $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/pq/pqdump.cc b/appsrc/dconvert/pq/pqdump.cc
new file mode 100644
index 0000000..d2522b7
--- /dev/null
+++ b/appsrc/dconvert/pq/pqdump.cc
@@ -0,0 +1,46 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "pq.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	PQ_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/pq/pqdump.man b/appsrc/dconvert/pq/pqdump.man
new file mode 100755
index 0000000..91187dd
--- /dev/null
+++ b/appsrc/dconvert/pq/pqdump.man
@@ -0,0 +1,43 @@
+.TH PQDUMP 1 "06 March 2014" "DICOM PS3" "pq dump"
+.SH NAME
+pqdump \- ACR/NEMA DICOM PS3 ... pq dump contents
+.SH SYNOPSIS
+.HP 10
+.B pqdump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B pqdump
+reads the named pq input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% pqdump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR pqtodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/pq/pqsplit.cc b/appsrc/dconvert/pq/pqsplit.cc
new file mode 100644
index 0000000..9b0463b
--- /dev/null
+++ b/appsrc/dconvert/pq/pqsplit.cc
@@ -0,0 +1,400 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqsplit.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <fstream>
+#include <cassert>
+#include <cstdlib>	// for atoi()
+#else
+#include <iostream.h>
+#include <fstream.h>
+#include <assert.h>
+#include <stdlib.h>
+#endif
+
+#include <string.h>	// need regardless of USESTANDARDHEADERSWITHOUTEXTENSION
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+int
+main(int argc,char **argv)
+{
+	long file_offset = 0;
+	char initialhdr[512];
+	while (cin.read(initialhdr,512)
+	    && cin.gcount() == 512
+	    && initialhdr[0] != 0) {		// seems to end with a null 512 bytes
+
+		file_offset+=cin.gcount();
+//cerr << "filename: " << initialhdr << endl;
+
+		char textline1[512];
+		cin.getline(textline1,512,'\n');
+		file_offset+=cin.gcount();
+//cerr << "textline1: " << textline1 << endl;
+		char textline2[512];
+		cin.getline(textline2,512,'\n');
+		file_offset+=cin.gcount();
+//cerr << "textline2: " << textline2 << endl;
+		char textline3[512];
+		cin.getline(textline3,512,'\n');
+		file_offset+=cin.gcount();
+//cerr << "textline3: " << textline3 << endl;
+		char textline4[512];
+		cin.getline(textline4,512,'\n');
+		file_offset+=cin.gcount();
+//cerr << "textline4: " << textline4 << endl;
+		char textline5[512];
+		cin.getline(textline5,512,'\n');
+		file_offset+=cin.gcount();
+//cerr << "textline5: " << textline5 << endl;
+
+		// istrstream only works with CC not g++ :( , so use strtok() instead ...
+
+		// e.g. "dbrec recsz:  32 nrecs: 193"
+
+		int dbrec_recsz = 0;
+		int dbrec_nrec = 0;
+
+		//istrstream istr_textline3(textline3);
+		//istr_textline3 >> "dbrec" >> "recsz:" >> dbrec_recsz >> "nrecs:" >> dbrec_nrec;
+
+		char *ptr;
+		char *newptr;
+
+		newptr=strdup(textline3);
+		assert(newptr);
+		if ((ptr=strtok(newptr," ")) && strncmp(ptr,"dbrec",strlen("dbrec")) == 0
+		 && (ptr=strtok(0," ")) && strncmp(ptr,"recsz:",strlen("recsz:")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			dbrec_recsz=atoi(ptr);
+		}
+		if ((ptr=strtok(0," ")) && strncmp(ptr,"nrecs:",strlen("nrecs:")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			dbrec_nrec=atoi(ptr);
+		}
+
+//cerr << "dbrec_recsz: " << dbrec_recsz << endl;
+//cerr << "dbrec_nrec: " << dbrec_nrec << endl;
+
+		if (newptr) free(newptr);
+
+		// e.g. "rdb   recsz:  64 nrecs:  25"
+
+		int rdb_recsz = 0;
+		int rdb_nrec = 0;
+
+		//istrstream istr_textline4(textline4);
+		//istr_textline4 >> "rdb" >> "recsz:" >> rdb_recsz >> "nrecs:" >> rdb_nrec;
+
+		newptr=strdup(textline4);
+		assert(newptr);
+		if ((ptr=strtok(newptr," ")) && strncmp(ptr,"rdb",strlen("rdb")) == 0
+		 && (ptr=strtok(0," ")) && strncmp(ptr,"recsz:",strlen("recsz:")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			rdb_recsz=atoi(ptr);
+		}
+		if ((ptr=strtok(0," ")) && strncmp(ptr,"nrecs:",strlen("nrecs:")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			rdb_nrec=atoi(ptr);
+		}
+
+//cerr << "rdb_recsz: " << rdb_recsz << endl;
+//cerr << "rdb_nrec: " << rdb_nrec << endl;
+
+		if (newptr) free(newptr);
+
+		int data_offset = 0;
+		int data_offset_actual = 0;
+		int magic_num_data_dict = 0;
+		int num_sdr_fields = 0;
+
+		// e.g. "8192 =data_offset  8056 =actual; 877355679 =magic_#_data_dict; 83 =#_sdr_flds"
+
+		//istrstream istr_textline5(textline5);
+		//istr_textline5 >> data_offset >> " =data_offset" >> data_offset_actual >> " =actual;"
+		//	       >> magic_num_data_dict >> " =magic_#_data_dict;" >> num_sdr_fields >> " =#_sdr_flds;";
+
+		newptr=strdup(textline5);
+		assert(newptr);
+		if ((ptr=strtok(newptr," "))
+		) {
+			data_offset=atoi(ptr);
+		}
+
+		if ((ptr=strtok(0," ")) && strncmp(ptr,"=data_offset",strlen("=data_offset")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			data_offset_actual=atoi(ptr);
+		}
+		if ((ptr=strtok(0," ")) && strncmp(ptr,"=actual;",strlen("=actual;")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			magic_num_data_dict=atoi(ptr);
+		}
+		if ((ptr=strtok(0," ")) && strncmp(ptr,"=magic_#_data_dict;",strlen("=magic_#_data_dict;")) == 0
+		 && (ptr=strtok(0," "))
+		) {
+			num_sdr_fields=atoi(ptr);
+		}
+		// don't bother checking for trailing "=#_sdr_flds;"
+
+//cerr << "data_offset: " << data_offset << endl;
+//cerr << "data_offset_actual: " << data_offset_actual << endl;
+//cerr << "magic_num_data_dict: " << magic_num_data_dict << endl;
+//cerr << "num_sdr_fields: " << num_sdr_fields << endl;
+
+		if (newptr) free(newptr);
+
+		// read the db records, i.e. the table of attributes and their names/offsets/lengths/types
+
+		char **db_fieldname = new char *[dbrec_nrec];
+		unsigned *db_offset = new unsigned[dbrec_nrec];
+		unsigned *db_length = new unsigned[dbrec_nrec];
+		unsigned *db_vtype  = new unsigned[dbrec_nrec];
+		char **db_value     = new char *[dbrec_nrec];
+
+		assert(db_fieldname);
+		assert(db_offset);
+		assert(db_length);
+		assert(db_vtype);
+		assert(db_value);
+
+		int i;
+		for (i=0; i < dbrec_nrec; ++i) {
+			char s_fieldname[9];
+			unsigned char s_offset[2];
+			unsigned char s_length[2];
+			unsigned char s_field3[2];
+			unsigned char s_field4[2];
+			unsigned char s_vtype[2];
+			char s_filler[64];		// actually only need dbrec_recsz-18 (should be 14)
+
+			cin.read(s_fieldname,8); s_fieldname[8]=0;
+			file_offset+=cin.gcount();
+			cin.read((char *)s_offset,2);
+			file_offset+=cin.gcount();
+			cin.read((char *)s_length,2);
+			file_offset+=cin.gcount();
+			cin.read((char *)s_field3,2);
+			file_offset+=cin.gcount();
+			cin.read((char *)s_field4,2);
+			file_offset+=cin.gcount();
+			cin.read((char *)s_vtype,2);
+			file_offset+=cin.gcount();
+			cin.read(s_filler,dbrec_recsz-18);
+			file_offset+=cin.gcount();
+
+			db_fieldname[i]=new char[strlen(s_fieldname)+1];
+			strcpy(db_fieldname[i],s_fieldname);
+
+			db_offset[i]=((unsigned)s_offset[0]<<8)+s_offset[1];
+			db_length[i]=((unsigned)s_length[0]<<8)+s_length[1];
+			db_vtype[i]=((unsigned)s_vtype[0] <<8)+s_vtype[1];
+#ifdef CRAP
+			char *vtype_label;
+			switch (db_vtype[i]) {
+				case 0:	vtype_label="asc"; break;
+				case 1:	vtype_label="int"; break;
+				case 2:	vtype_label="dat"; break;
+				case 3:	vtype_label="tim"; break;
+				case 4:	vtype_label="fil"; break;
+				case 5:	vtype_label="flg"; break;
+				case 6:	vtype_label="flt"; break;
+				default:
+					vtype_label="???"; break;
+			}
+
+			cerr << "<" << db_fieldname[i] << ">"
+			     << "\t = " << db_offset[i]
+			     << " [" << db_length[i] << "]"
+			     << " [" << db_vtype[i] << "]" << " " << vtype_label
+			     << endl;
+#endif
+		}
+
+		// read the rdb records (i.e. the actual values of the attributes) ...
+
+		int rdb_length = rdb_recsz*rdb_nrec;
+		char *rdb_values = new char[rdb_length];
+		assert(rdb_values);
+		cin.read(rdb_values,rdb_length);
+		assert(cin.gcount() == rdb_length);
+		file_offset+=rdb_length;
+
+		// fill in the attribute table with values ...
+
+		for (i=0; i < dbrec_nrec; ++i) {
+			char *vtype_label;
+			switch (db_vtype[i]) {
+				case 0:	vtype_label="asc"; break;
+				case 1:	vtype_label="int"; break;
+				case 2:	vtype_label="dat"; break;
+				case 3:	vtype_label="tim"; break;
+				case 4:	vtype_label="fil"; break;
+				case 5:	vtype_label="flg"; break;
+				case 6:	vtype_label="flt"; break;
+				default:
+					vtype_label="???"; break;
+			}
+
+			char *value=new char[db_length[i]+1];
+			assert(value);
+			assert(db_offset[i]+db_length[i] <= rdb_length);
+			strncpy(value,rdb_values+db_offset[i],db_length[i]);
+			value[db_length[i]]=0;
+
+			db_value[i]=value;
+#ifdef CRAP
+			cerr << "<" << db_fieldname[i] << ">"
+			     << "\t = " << db_offset[i]
+			     << " [" << db_length[i] << "]"
+			     << " [" << db_vtype[i] << "]" << " " << vtype_label
+			     << "\t = <" << db_value[i] << ">" << endl;
+#endif
+		}
+
+		// Find various useful attribute values ...
+
+		int image_file_size=0;
+		int image_file_offset=0;
+		const char *image_file_name=0;
+		const char *patient_name=0;
+		const char *patient_id=0;
+		int study_num=0;
+		int study_num_extended=0;
+		for (i=0; i < dbrec_nrec; ++i) {
+			if (strcmp(db_fieldname[i],"IMFISIZ") == 0) {
+				assert(db_vtype[i] == 1);
+				assert(db_value[i] != 0);
+				image_file_size=atoi(db_value[i]);
+			}
+			else if (strcmp(db_fieldname[i],"IMFIOFS") == 0) {
+				assert(db_vtype[i] == 1);
+				assert(db_value[i] != 0);
+				image_file_offset=atoi(db_value[i]);
+			}
+			else if (strcmp(db_fieldname[i],"IMFILE") == 0) {
+				assert(db_vtype[i] == 4);
+				assert(db_value[i] != 0);
+				image_file_name=db_value[i];
+			}
+			else if (strcmp(db_fieldname[i],"PATNAM") == 0) {
+				assert(db_vtype[i] == 0);
+				assert(db_value[i] != 0);
+				patient_name=db_value[i];
+			}
+			else if (strcmp(db_fieldname[i],"PATID") == 0) {
+				assert(db_vtype[i] == 0);
+				assert(db_value[i] != 0);
+				patient_id=db_value[i];
+			}
+			else if (strcmp(db_fieldname[i],"STNUM") == 0) {
+				assert(db_vtype[i] == 1);
+				assert(db_value[i] != 0);
+				study_num=atoi(db_value[i]);
+			}
+			else if (strcmp(db_fieldname[i],"STNUM_X") == 0) {
+				assert(db_vtype[i] == 1);
+				assert(db_value[i] != 0);
+				study_num_extended=atoi(db_value[i]);
+			}
+		}
+
+//cerr << "image_file_size = " << image_file_size << endl;
+//cerr << "image_file_offset = " << image_file_offset << endl;
+
+		cerr << "image_file_name = " << image_file_name << endl;
+
+//cerr << "patient_name = " << patient_name << endl;
+//cerr << "patient_id = " << patient_id << endl;
+//cerr << "study_num = " << study_num << endl;
+//cerr << "study_num_extended = " << study_num_extended << endl;
+
+		if (image_file_name && strncmp(image_file_name,"IM.",3) == 0 && image_file_size) {
+			// is a real image file so write it ...
+
+			ofstream out(image_file_name);
+			assert(out);
+
+			out.write(initialhdr,512);
+//cerr << "textline1: " << textline1 << endl;
+			out.write(textline1,strlen(textline1)); out.put('\n');
+//cerr << "textline2: " << textline2 << endl;
+			out.write(textline2,strlen(textline2)); out.put('\n');
+//cerr << "textline3: " << textline3 << endl;
+			out.write(textline3,strlen(textline3)); out.put('\n');
+//cerr << "textline4: " << textline4 << endl;
+			out.write(textline4,strlen(textline4)); out.put('\n');
+//cerr << "textline5: " << textline5 << endl;
+			out.write(textline5,strlen(textline5)); out.put('\n');
+
+			for (i=0; i < dbrec_nrec; ++i) {
+				char s_fieldname[8];
+				int j;
+				for (j=0; j<8; ++j) s_fieldname[j]=0;
+				strncpy(s_fieldname,db_fieldname[i],8);
+				out.write(s_fieldname,8);
+				out.put(char((db_offset[i]>>8)&0xff)); out.put(char(db_offset[i]&0xff));
+				out.put(char((db_length[i]>>8)&0xff)); out.put(char(db_length[i]&0xff));
+				out.put(char(0)); out.put(char(0));
+				out.put(char(0)); out.put(char(0));
+				out.put(char((db_vtype[i]>>8)&0xff)); out.put(char(db_vtype[i]&0xff));
+				for (j=18; j < dbrec_recsz; ++j) out.put(char(0));
+			}
+
+			out.write(rdb_values,rdb_length);
+
+			//long copy_size = image_file_size-image_file_offset+8;	// include the "\nEND=\n--" as well
+
+			long copy_size = (image_file_size-image_file_offset)+(data_offset-data_offset_actual);
+
+//cerr << "copy size = " << copy_size << endl;
+
+			char buffer[8192];
+
+//cerr << "file_offset before copy: " << file_offset << endl;
+			while (copy_size > 0 && cin) {
+				cin.read(buffer,copy_size < 8192 ? copy_size : 8192);
+				int count = cin.gcount();
+				assert(count);
+				file_offset+=count;
+				out.write(buffer,count);
+				copy_size-=count;
+			}
+//cerr << "file_offset after copy: " << file_offset << endl;
+
+			out.close();
+		}
+		else {		// not an image file so skip it ...
+
+
+			long skip_size = image_file_size == 0
+				? (8192-(file_offset%8192))		// e.g. a TP.FHEAD
+				:  image_file_size-image_file_offset+8;	// skip the "\nEND=\n--" as well
+
+//cerr << "data size to skip = " << skip_size << endl;
+//cerr << "data size to skip%8192 = " << (skip_size%8192) << endl;
+
+			char buffer[8192];
+
+//cerr << "file_offset before skip: " << file_offset << endl;
+			while (skip_size > 0 && cin) {
+				cin.read(buffer,skip_size < 8192 ? skip_size : 8192);
+				int count = cin.gcount();
+				assert(count);
+				file_offset+=count;
+				skip_size-=count;
+			}
+//cerr << "file_offset after skip: " << file_offset << endl;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/pq/pqsplit.man b/appsrc/dconvert/pq/pqsplit.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dconvert/pq/pqtodc.cc b/appsrc/dconvert/pq/pqtodc.cc
new file mode 100644
index 0000000..fed0550
--- /dev/null
+++ b/appsrc/dconvert/pq/pqtodc.cc
@@ -0,0 +1,77 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "pq.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	PQ_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/pq/pqtodc.man b/appsrc/dconvert/pq/pqtodc.man
new file mode 100755
index 0000000..ecc2978
--- /dev/null
+++ b/appsrc/dconvert/pq/pqtodc.man
@@ -0,0 +1,53 @@
+.TH PQTODC 1 "06 March 2014" "DICOM PS3" "pq to DICOM"
+.SH NAME
+pqtodc \- ACR/NEMA DICOM PS3 ... pq to DICOM
+.SH SYNOPSIS
+.HP 10
+.B pqtodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B pqtodc
+reads the named pq input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% pqtodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR pqdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/shim/Imakefile b/appsrc/dconvert/shim/Imakefile
new file mode 100755
index 0000000..d94aede
--- /dev/null
+++ b/appsrc/dconvert/shim/Imakefile
@@ -0,0 +1,33 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = shimtodc.cc
+OBJSTODC = shimtodc.o
+
+SRCSDUMP = shimdump.cc
+OBJSDUMP = shimdump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(shimtodc)
+NormalCCProgramTarget(shimtodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdshim.a $(PROJECTDCONVERTDEPLIBS),-ldshim $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(shimtodc,$(INSTALLBINDIR))
+InstallManPage(shimtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(shimdump)
+NormalCCProgramTarget(shimdump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdshim.a $(PROJECTDCONVERTDEPLIBS),-ldshim $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(shimdump,$(INSTALLBINDIR))
+InstallManPage(shimdump,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./shimdump "" $(TOP)/images/shimadzu $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./shimtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/shimadzu $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./shimdump "" $(TOP)/images/shimadzu $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./shimtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/shimadzu $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/shim/shimdump.cc b/appsrc/dconvert/shim/shimdump.cc
new file mode 100644
index 0000000..4c727bf
--- /dev/null
+++ b/appsrc/dconvert/shim/shimdump.cc
@@ -0,0 +1,50 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "shim.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	int imagenumber;
+	if (!options.get("image",imagenumber)) imagenumber=0;
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [-image imagenumberfrom0]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	SHIM_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout,imagenumber);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/shim/shimdump.man b/appsrc/dconvert/shim/shimdump.man
new file mode 100755
index 0000000..f0b5685
--- /dev/null
+++ b/appsrc/dconvert/shim/shimdump.man
@@ -0,0 +1,43 @@
+.TH SHIMDUMP 1 "06 March 2014" "DICOM PS3" "Imatron dump"
+.SH NAME
+shimdump \- ACR/NEMA DICOM PS3 ... Imatron dump contents
+.SH SYNOPSIS
+.HP 10
+.B shimdump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B shimdump
+reads the named Imatron input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% shimdump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR shimtodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/shim/shimtodc.cc b/appsrc/dconvert/shim/shimtodc.cc
new file mode 100644
index 0000000..c012137
--- /dev/null
+++ b/appsrc/dconvert/shim/shimtodc.cc
@@ -0,0 +1,81 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "shim.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	int imagenumber;
+	if (!options.get("image",imagenumber)) imagenumber=0;
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-image imagenumberfrom0]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	SHIM_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax,imagenumber);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/shim/shimtodc.man b/appsrc/dconvert/shim/shimtodc.man
new file mode 100755
index 0000000..dede14a
--- /dev/null
+++ b/appsrc/dconvert/shim/shimtodc.man
@@ -0,0 +1,53 @@
+.TH SHIMTODC 1 "06 March 2014" "DICOM PS3" "Imatron to DICOM"
+.SH NAME
+shimtodc \- ACR/NEMA DICOM PS3 ... Imatron to DICOM
+.SH SYNOPSIS
+.HP 10
+.B shimtodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B shimtodc
+reads the named Imatron input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% shimtodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR shimdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/signa/Imakefile b/appsrc/dconvert/signa/Imakefile
new file mode 100755
index 0000000..b1c7990
--- /dev/null
+++ b/appsrc/dconvert/signa/Imakefile
@@ -0,0 +1,35 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = sgntodc.cc
+OBJSTODC = sgntodc.o
+
+SRCSDUMP = sgndump.cc
+OBJSDUMP = sgndump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(sgntodc)
+NormalCCProgramTarget(sgntodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdsgn.a $(PROJECTDCONVERTDEPLIBS),-ldsgn $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(sgntodc,$(INSTALLBINDIR))
+InstallManPage(sgntodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(sgndump)
+NormalCCProgramTarget(sgndump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdsgn.a $(PROJECTDCONVERTDEPLIBS),-ldsgn $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(sgndump,$(INSTALLBINDIR))
+InstallManPage(sgndump,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	#./testy2k.sh $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) compare
+	@$(TOP)/support/testapp testlist ./sgndump "" $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./sgntodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	#./testy2k.sh $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) create
+	@$(TOP)/support/testapp testlist ./sgndump "" $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./sgntodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/signa/sgndump.cc b/appsrc/dconvert/signa/sgndump.cc
new file mode 100644
index 0000000..8786eb5
--- /dev/null
+++ b/appsrc/dconvert/signa/sgndump.cc
@@ -0,0 +1,54 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgndump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "signa.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+
+	BinaryInputOptions 	binary_input_options(options);
+
+	int useoptioncount=0;
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	SGN_Conversion *convertor = new SGN_Conversion(bin,cerr);
+	Assert(convertor);
+
+	convertor->dumpCommon(cout);
+	convertor->dumpSelectedImage(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/signa/sgndump.man b/appsrc/dconvert/signa/sgndump.man
new file mode 100755
index 0000000..a696dad
--- /dev/null
+++ b/appsrc/dconvert/signa/sgndump.man
@@ -0,0 +1,32 @@
+.TH SGNDUMP 1 "06 March 2014" "DICOM PS3" "Signa dump"
+.SH NAME
+sgndump \- ACR/NEMA DICOM PS3 ... Signa dump contents
+.SH SYNOPSIS
+.HP 10
+.B sgndump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B sgndump
+reads the named GE MR Signa input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.LP
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR sgntodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/signa/sgntodc.cc b/appsrc/dconvert/signa/sgntodc.cc
new file mode 100644
index 0000000..47874cd
--- /dev/null
+++ b/appsrc/dconvert/signa/sgntodc.cc
@@ -0,0 +1,111 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgntodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "signa.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	int useoptioncount=0;
+
+	bool useximg=options.get("ximg");
+	if (useximg) ++useoptioncount;
+
+	bool usedat=options.get("dat");
+	if (options.get("tape")) usedat=true;
+	if (usedat) ++useoptioncount;
+
+	int noffset;
+	Uint32 offsetargs[5];
+	if ((noffset=options.get("offset",offsetargs,5)) != -1 && noffset != 5) {
+		cerr << EMsgDC(OptionIncomplete)
+		     << " - offset"
+		     << endl;
+		bad=true;
+	}
+
+	bool lengthpresent=options.get("lengthpresent");
+
+	if (useoptioncount && (lengthpresent || noffset != -1)) {
+		cerr << EMsgDC(OptionsIncompatible) << endl;
+		bad=true; 
+	}
+
+	// the default if no options is to read ximg format ...
+
+	if (!useoptioncount && noffset == -1) useximg=true;
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-ximg|-dat|-tape"
+			<< "|[-offset file suite exam series image [-lengthpresent]]]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	SGN_Conversion *convertor = new SGN_Conversion(bin,cerr);
+	Assert(convertor);
+
+	convertor->convertAll(&list,&transfersyntax);
+
+	return usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose) ? 0 : 1;
+}
+
diff --git a/appsrc/dconvert/signa/sgntodc.man b/appsrc/dconvert/signa/sgntodc.man
new file mode 100755
index 0000000..fdd491c
--- /dev/null
+++ b/appsrc/dconvert/signa/sgntodc.man
@@ -0,0 +1,31 @@
+.TH SGNTODC 1 "06 March 2014" "DICOM PS3" "Signa to DICOM"
+.SH NAME
+sgntodc \- ACR/NEMA DICOM PS3 ... Signa to DICOM
+.SH SYNOPSIS
+.HP 10
+.B sgntodc
+.so man1/gen.so
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B sgntodc
+reads the named GE Signa MR input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.LP
+.SH ENVIRONMENT
+.LP
+.SH FILES
+.LP
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR sgndump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/somp/Imakefile b/appsrc/dconvert/somp/Imakefile
new file mode 100755
index 0000000..6a6ab39
--- /dev/null
+++ b/appsrc/dconvert/somp/Imakefile
@@ -0,0 +1,33 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = somptodc.cc
+OBJSTODC = somptodc.o
+
+SRCSDUMP = sompdump.cc
+OBJSDUMP = sompdump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(somptodc)
+NormalCCProgramTarget(somptodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdsomp.a $(PROJECTDCONVERTDEPLIBS),-ldsomp $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(somptodc,$(INSTALLBINDIR))
+InstallManPage(somptodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(sompdump)
+NormalCCProgramTarget(sompdump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdsomp.a $(PROJECTDCONVERTDEPLIBS),-ldsomp $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(sompdump,$(INSTALLBINDIR))
+InstallManPage(sompdump,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./sompdump "" $(TOP)/images/somplus $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./somptodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/somplus $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./sompdump "" $(TOP)/images/somplus $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./somptodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/somplus $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/somp/sompdump.cc b/appsrc/dconvert/somp/sompdump.cc
new file mode 100644
index 0000000..203ff79
--- /dev/null
+++ b/appsrc/dconvert/somp/sompdump.cc
@@ -0,0 +1,45 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "somp.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	SOMP_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/somp/sompdump.man b/appsrc/dconvert/somp/sompdump.man
new file mode 100755
index 0000000..ad1bb53
--- /dev/null
+++ b/appsrc/dconvert/somp/sompdump.man
@@ -0,0 +1,43 @@
+.TH SOMPDUMP 1 "06 March 2014" "DICOM PS3" "somp dump"
+.SH NAME
+sompdump \- ACR/NEMA DICOM PS3 ... somp dump contents
+.SH SYNOPSIS
+.HP 10
+.B sompdump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B sompdump
+reads the named somp input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% sompdump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR somptodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/somp/somptodc.cc b/appsrc/dconvert/somp/somptodc.cc
new file mode 100644
index 0000000..b4602af
--- /dev/null
+++ b/appsrc/dconvert/somp/somptodc.cc
@@ -0,0 +1,77 @@
+static const char *CopyrightIdentifier(void) { return "@(#)somptodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "somp.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	SOMP_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/somp/somptodc.man b/appsrc/dconvert/somp/somptodc.man
new file mode 100755
index 0000000..0719828
--- /dev/null
+++ b/appsrc/dconvert/somp/somptodc.man
@@ -0,0 +1,53 @@
+.TH SOMPTODC 1 "06 March 2014" "DICOM PS3" "somp to DICOM"
+.SH NAME
+somptodc \- ACR/NEMA DICOM PS3 ... somp to DICOM
+.SH SYNOPSIS
+.HP 10
+.B somptodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B somptodc
+reads the named somp input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% somptodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR sompdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/support/Imakefile b/appsrc/dconvert/support/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dconvert/toshiba/Imakefile b/appsrc/dconvert/toshiba/Imakefile
new file mode 100755
index 0000000..6d3f630
--- /dev/null
+++ b/appsrc/dconvert/toshiba/Imakefile
@@ -0,0 +1,5 @@
+MANSUFFIX = 1
+
+InstallScript(toshtodc,$(INSTALLBINDIR))
+InstallManPage(toshtodc,$(INSTALLMANDIR)/man1)
+
diff --git a/appsrc/dconvert/toshiba/toshtodc.man b/appsrc/dconvert/toshiba/toshtodc.man
new file mode 100755
index 0000000..a0e0afc
--- /dev/null
+++ b/appsrc/dconvert/toshiba/toshtodc.man
@@ -0,0 +1,32 @@
+.TH toshtodc 1 "18 March 2007" "DICOM PS3" "Convert separate Toshiba files to DICOM"
+.SH NAME
+toshtodc \- ACR/NEMA DICOM PS3 ... Convert separate Toshiba ACR-NEMA header and raw pixel data files to DICOM
+.SH SYNOPSIS
+.HP 10
+.B toshtodc
+.B imagefilenames
+.SH DESCRIPTION
+.LP
+.B toshtodc
+reads a list of Toshiba ACR-NEMA raw pixel data image filenames (.img) from the command line, searches for the
+corresponding ACR-NEMA header files (.zlc), combines them and converts them to DICOM using antodc, creating corresponding
+filenames with a .dcm extension.
+.SH OPTIONS
+.LP
+\ 
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR antodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+.LP
+The search for the corresponding header file expects the extension to be lower case.
diff --git a/appsrc/dconvert/toshiba/toshtodc.script b/appsrc/dconvert/toshiba/toshtodc.script
new file mode 100755
index 0000000..09a0e3b
--- /dev/null
+++ b/appsrc/dconvert/toshiba/toshtodc.script
@@ -0,0 +1,68 @@
+#!/bin/sh
+#
+# Usage: toshtodc imagefilenames
+
+#TMPFILE="/tmp/`basename $0`.$$.tmp"
+STAMP=`date +%Y%m%d%H%M%S`.$$
+
+for i in $*
+do
+	#basefilename=`basename "${i}" "${rawpixeldataextension}"`
+	basefilename=`echo "${i}" | sed -e 's/[.][Ii][Mm][Gg]$//'`
+	rawpixeldatafile="${i}"
+	acrnemaheaderfile="${basefilename}.zlc"
+	dicomfile="${basefilename}.dcm"
+
+	if [ ! -f "${rawpixeldatafile}" ]
+	then
+		echo 1>&2 "Error: cannot find filename ${rawpixeldatafile}"
+		exit 1
+	fi
+
+	if [ ! -f "${acrnemaheaderfile}" ]
+	then
+		echo 1>&2 "Error: cannot find filename ${acrnemaheaderfile}"
+		exit 1
+	fi
+
+	rawfilelength=`ls -l "${i}" | awk '{print $5}'`
+	#echo "rawfilelength=${rawfilelength}"
+	
+	# need to removeprivate, since some of them (7ff1) come after 7fe0 and not worth the effort to split and re-merge them
+	# definitely need to delete CommandLengthToEnd, since it is group 0x0000, which is illegal
+	# delete RevolutionTime since it comes out as 0
+	# delete others that are retired or not part of the CT IOD
+	# insert ImageType since none is present and default is ugly
+
+	antodc "${acrnemaheaderfile}" "${dicomfile}" \
+		-stamp "$STAMP" \
+		-d CommandLengthToEnd \
+		-d RecognitionCode \
+		-d OldDataSetType \
+		-d OldDataSetSubtype \
+		-d AcquisitionComments \
+		-d Location \
+		-d SmallestValidPixelValue \
+		-d LargestValidPixelValue \
+		-d ScanningSequence \
+		-d RevolutionTime \
+		-d PatientOrientation \
+		-d ImagePosition \
+		-d ImageOrientation \
+		-r ImageType "ORIGINAL\PRIMARY" \
+		-removeprivate \
+		-nodisclaimer
+	
+	echo "(0x7fe0,0x0010) OW Pixel Data VR=<OW> VL=<${rawfilelength}> []" | ancreate -e >>"${dicomfile}"
+	
+	# need to swab the bytes, since want little endian for dicom but raw image file is big endian
+	
+	dd if="${rawpixeldatafile}" conv=swab >>"${dicomfile}" 2>/dev/null
+	
+	#ls -l "${dicomfile}"
+	#echo "Validating ${dicomfile}"
+	#dciodvfy "${dicomfile}"
+	
+	#echo "Comparing ${acrnemaheaderfile} with ${dicomfile}"
+	#andiff "${acrnemaheaderfile}" "${dicomfile}"
+done
diff --git a/appsrc/dconvert/xxxx/Imakefile b/appsrc/dconvert/xxxx/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/dconvert/xxxx/Imakefile.tmpl b/appsrc/dconvert/xxxx/Imakefile.tmpl
new file mode 100755
index 0000000..b7797cf
--- /dev/null
+++ b/appsrc/dconvert/xxxx/Imakefile.tmpl
@@ -0,0 +1,36 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPDCONVERTEXTRAINCLUDES)
+
+SRCSTODC = xxxxtodc.cc
+OBJSTODC = xxxxtodc.o
+
+SRCSDUMP = xxxxdump.cc
+OBJSDUMP = xxxxdump.o
+
+CPLUSPLUS_SRCS = $(SRCSDUMP) $(SRCSTODC)
+OBJS = $(OBJSDUMP) $(OBJSTODC)
+
+AllTarget(xxxxtodc)
+NormalCCProgramTarget(xxxxtodc,$(OBJSTODC),$(TOP)/libsrc/lib/libdxxxx.a $(PROJECTDCONVERTDEPLIBS),-ldxxxx $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(xxxxtodc,$(INSTALLBINDIR))
+InstallManPage(xxxxtodc,$(INSTALLMANDIR)/man1)
+
+AllTarget(xxxxdump)
+NormalCCProgramTarget(xxxxdump,$(OBJSDUMP),$(TOP)/libsrc/lib/libdxxxx.a $(PROJECTDCONVERTDEPLIBS),-ldxxxx $(PROJECTDCONVERTLIBS),-lm)
+InstallProgram(xxxxdump,$(INSTALLBINDIR))
+InstallManPage(xxxxdump,$(INSTALLMANDIR)/man1)
+
+InstallScript(xxxxunid,$(INSTALLBINDIR))
+InstallManPage(xxxxunid,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./xxxxdump "" $(TOP)/images/xxxx $(TOP)/test/$(CURRENT_DIR) compare dump
+	@$(TOP)/support/testapp testlist ./xxxxtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/xxxx $(TOP)/test/$(CURRENT_DIR) compare todc
+
+test.create::
+	@$(TOP)/support/testapp testlist ./xxxxdump "" $(TOP)/images/xxxx $(TOP)/test/$(CURRENT_DIR) create dump
+	@$(TOP)/support/testapp testlist ./xxxxtodc "-v -stamp 9999 -instancecreationdate 20030314 -instancecreationtime 145912 -timezoneoffsetfromutc +0100" $(TOP)/images/xxxx $(TOP)/test/$(CURRENT_DIR) create todc
+
diff --git a/appsrc/dconvert/xxxx/replacexxxxwithinfiles.sh b/appsrc/dconvert/xxxx/replacexxxxwithinfiles.sh
new file mode 100755
index 0000000..32fa404
--- /dev/null
+++ b/appsrc/dconvert/xxxx/replacexxxxwithinfiles.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Usage: find . -name '*.h'   -exec ./replacexxxxwithinfiles.sh '{}' ';'
+# Usage: find . -name '*.cc'  -exec ./replacexxxxwithinfiles.sh '{}' ';'
+# Usage: find . -name '*.tpl' -exec ./replacexxxxwithinfiles.sh '{}' ';'
+# Usage: find . -name 'Imakefile' -exec ./replacexxxxwithinfiles.sh '{}' ';'
+#
+# (using -o in same find fails to exec)
+
+filename="${1}"
+backupfilename="${filename}.bak"
+
+rm -f "${backupfilename}"
+mv "${filename}" "${backupfilename}"
+
+sed -e 's/xxxx/yyyy/g' -e 's/XXXX/YYYY/g' <"${backupfilename}" >"${filename}"
+
+rm "${backupfilename}"
diff --git a/appsrc/dconvert/xxxx/xxxxdump.cc b/appsrc/dconvert/xxxx/xxxxdump.cc
new file mode 100644
index 0000000..e245b9b
--- /dev/null
+++ b/appsrc/dconvert/xxxx/xxxxdump.cc
@@ -0,0 +1,46 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+
+#include "xxxx.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+
+	binary_input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+
+	cerr << binary_input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+
+	XXXX_Conversion convertor(bin,cerr);
+	convertor.dumpCommon(cout);
+	convertor.dumpSelectedImage(cout,imagenumber);
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/xxxx/xxxxdump.man b/appsrc/dconvert/xxxx/xxxxdump.man
new file mode 100755
index 0000000..4ae4b22
--- /dev/null
+++ b/appsrc/dconvert/xxxx/xxxxdump.man
@@ -0,0 +1,43 @@
+.TH XXXXDUMP 1 "06 March 2014" "DICOM PS3" "xxxx dump"
+.SH NAME
+xxxxdump \- ACR/NEMA DICOM PS3 ... xxxx dump contents
+.SH SYNOPSIS
+.HP 10
+.B xxxxdump
+.so man1/gen.so
+.I inputfilename
+.SH DESCRIPTION
+.LP
+.B xxxxdump
+reads the named xxxx input file and dumps its contents.
+.LP
+.SH OPTIONS
+The dump output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% xxxxdump test
+.RE
+\ 
+.RE
+[block:offset] Description        <value>
+.RE
+\ 
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR xxxxtodc(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/dconvert/xxxx/xxxxtodc.cc b/appsrc/dconvert/xxxx/xxxxtodc.cc
new file mode 100644
index 0000000..1081c70
--- /dev/null
+++ b/appsrc/dconvert/xxxx/xxxxtodc.cc
@@ -0,0 +1,77 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxtodc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "transynu.h"
+#include "mesgtext.h"
+#include "bnopt.h"
+#include "dcopt.h"
+
+#include "xxxx.h"
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	BinaryInputOptions 	binary_input_options(options);
+	DicomOutputOptions 	dicom_output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	binary_input_options.done();
+	dicom_output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,binary_input_options.filename,cin);
+	DicomOutputOpenerFromOptions output_opener(
+		options,dicom_output_options.filename,cout);
+
+	cerr << binary_input_options.errors();
+	cerr << dicom_output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!binary_input_options.good()
+	 || !dicom_output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< binary_input_options.usage()
+			<< dicom_output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream bin(*(istream *)input_opener);
+	DicomOutputStream dout(*(ostream *)output_opener,
+		dicom_output_options.transfersyntaxuid,
+		dicom_output_options.usemetaheader,
+		dicom_output_options.useimplicitmetaheader,
+		dicom_output_options.addtiff);
+
+	ManagedAttributeList list;
+
+	TransferSyntax transfersyntax(
+		dicom_output_options.transfersyntaxuid
+		? dicom_output_options.transfersyntaxuid
+		: DefaultTransferSyntaxUID);
+
+	TextOutputStream log (cerr);
+	if (verbose) log << "Converting ..." << endl;
+
+	XXXX_Conversion convertor(bin,cerr);
+	convertor.convertAll(&list,&transfersyntax,imagenumber);
+
+	if (!usualManagedAttributeListWrite(list,dout,
+		dicom_output_options,log,verbose)) return 1;
+
+	return 0;
+}
+
diff --git a/appsrc/dconvert/xxxx/xxxxtodc.man b/appsrc/dconvert/xxxx/xxxxtodc.man
new file mode 100755
index 0000000..27c1898
--- /dev/null
+++ b/appsrc/dconvert/xxxx/xxxxtodc.man
@@ -0,0 +1,53 @@
+.TH XXXXTODC 1 "06 March 2014" "DICOM PS3" "xxxx to DICOM"
+.SH NAME
+xxxxtodc \- ACR/NEMA DICOM PS3 ... xxxx to DICOM
+.SH SYNOPSIS
+.HP 10
+.B xxxxtodc
+.so man1/gen.so
+[
+.B \-v|verbose
+]
+.I inputfilename
+.I outputfilename
+.SH DESCRIPTION
+.LP
+.B xxxxtodc
+reads the named xxxx input file and converts it to a dicom output file.
+.LP
+.SH OPTIONS
+The verbose output goes to standard error.
+.PP
+The basic switches are described in dcintro(1).
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% xxxxtodc \-v test test.dc3
+.RE
+\ 
+.RE
+Converting ...
+.RE
+******** As read ... ********
+.RE
+(0x0008,0x0008) CS Image Type ...
+.RE
+******** As written ... ********
+.RE
+(0x0002,0x0001) OB File Meta Information Version ...
+.RE
+ ...
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcintro(1) ,
+.BR xxxxdump(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/misc/Imakefile b/appsrc/misc/Imakefile
new file mode 100755
index 0000000..c34ff2d
--- /dev/null
+++ b/appsrc/misc/Imakefile
@@ -0,0 +1,156 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTAPPMISCEXTRAINCLUDES)
+
+SRCSDUMPWHAT = dumpwhat.cc
+OBJSDUMPWHAT = dumpwhat.o
+
+SRCSBINPATCH = binpatch.cc
+OBJSBINPATCH = binpatch.o
+
+SRCSDCUNMETA = dcunmeta.cc
+OBJSDCUNMETA = dcunmeta.o
+
+SRCSJPEGDUMP = jpegdump.cc
+OBJSJPEGDUMP = jpegdump.o
+
+SRCSJPEGSPLIT = jpegsplit.cc
+OBJSJPEGSPLIT = jpegsplit.o
+
+SRCSPBMSWBIT = pbmswbit.cc
+OBJSPBMSWBIT = pbmswbit.o
+
+SRCSPNMPRED = pnmpred.cc
+OBJSPNMPRED = pnmpred.o
+
+SRCSPNMTORAW = pnmtoraw.cc
+OBJSPNMTORAW = pnmtoraw.o
+
+SRCSRAWARITH = rawarith.cc
+OBJSRAWARITH = rawarith.o
+
+SRCSRAWDIFF = rawdiff.cc
+OBJSRAWDIFF = rawdiff.o
+
+SRCSRAWMASK = rawmask.cc
+OBJSRAWMASK = rawmask.o
+
+SRCSRAWNJL = rawnjl.cc
+OBJSRAWNJL = rawnjl.o
+
+SRCSRAWNJL2 = rawnjl2.cc
+OBJSRAWNJL2 = rawnjl2.o
+
+SRCSDUMPTIFF = dumptiff.cc
+OBJSDUMPTIFF = dumptiff.o
+
+/* SRCSPPMTRCLR = ppmtrclr.cc */
+/* OBJSPPMTRCLR = ppmtrclr.o */
+
+SRCSPGMTOBMP = pgmtobmp.cc
+OBJSPGMTOBMP = pgmtobmp.o
+
+SRCSBMPDUMP = bmpdump.cc
+OBJSBMPDUMP = bmpdump.o
+
+CPLUSPLUS_SRCS = $(SRCSBMPDUMP) $(SRCSPGMTOBMP) $(SRCSDUMPWHAT) $(SRCSBINPATCH) $(SRCSJPEGDUMP) $(SRCSJPEGSPLIT) $(SRCSPBMSWBIT) $(SRCSPNMPRED) $(SRCSPNMTORAW) $(SRCSRAWARITH) $(SRCSRAWDIFF) $(SRCSRAWMASK) $(SRCSRAWNJL) $(SRCSRAWNJL2) $(SRCSDUMPTIFF)
+OBJS           = $(OBJSBMPDUMP) $(OBJSPGMTOBMP) $(OBJSDUMPWHAT) $(OBJSBINPATCH) $(OBJSJPEGDUMP) $(OBJSJPEGSPLIT) $(OBJSPBMSWBIT) $(OBJSPNMPRED) $(OBJSPNMTORAW) $(OBJSRAWARITH) $(OBJSRAWDIFF) $(OBJSRAWMASK) $(OBJSRAWNJL) $(OBJSRAWNJL2) $(OBJSDUMPTIFF)
+
+AllTarget(bmpdump)
+NormalCCProgramTarget(bmpdump,$(OBJSBMPDUMP),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(bmpdump,$(INSTALLBINDIR))
+InstallManPage(bmpdump,$(INSTALLMANDIR)/man1)
+
+AllTarget(pgmtobmp)
+NormalCCProgramTarget(pgmtobmp,$(OBJSPGMTOBMP),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(pgmtobmp,$(INSTALLBINDIR))
+InstallManPage(pgmtobmp,$(INSTALLMANDIR)/man1)
+
+/* this utility fails because cannot work within 8 bits; also round() not present on Solaris */
+/* AllTarget(ppmtrclr) */
+/* NormalCCProgramTarget(ppmtrclr,$(OBJSPPMTRCLR),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm) */
+/* InstallProgram(ppmtrclr,$(INSTALLBINDIR)) */
+/* InstallManPage(ppmtrclr,$(INSTALLMANDIR)/man1) */
+
+AllTarget(dumpwhat)
+NormalCCProgramTarget(dumpwhat,$(OBJSDUMPWHAT),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(dumpwhat,$(INSTALLBINDIR))
+InstallManPage(dumpwhat,$(INSTALLMANDIR)/man1)
+
+AllTarget(dcunmeta)
+NormalCCProgramTarget(dcunmeta,$(OBJSDCUNMETA),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(dcunmeta,$(INSTALLBINDIR))
+InstallManPage(dcunmeta,$(INSTALLMANDIR)/man1)
+
+AllTarget(binpatch)
+NormalCCProgramTarget(binpatch,$(OBJSBINPATCH),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(binpatch,$(INSTALLBINDIR))
+InstallManPage(binpatch,$(INSTALLMANDIR)/man1)
+
+AllTarget(jpegdump)
+NormalCCProgramTarget(jpegdump,$(OBJSJPEGDUMP),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(jpegdump,$(INSTALLBINDIR))
+InstallManPage(jpegdump,$(INSTALLMANDIR)/man1)
+
+AllTarget(jpegsplit)
+NormalCCProgramTarget(jpegsplit,$(OBJSJPEGSPLIT),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(jpegsplit,$(INSTALLBINDIR))
+InstallManPage(jpegsplit,$(INSTALLMANDIR)/man1)
+
+AllTarget(pbmswbit)
+NormalCCProgramTarget(pbmswbit,$(OBJSPBMSWBIT),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(pbmswbit,$(INSTALLBINDIR))
+InstallManPage(pbmswbit,$(INSTALLMANDIR)/man1)
+
+AllTarget(pnmpred)
+NormalCCProgramTarget(pnmpred,$(OBJSPNMPRED),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(pnmpred,$(INSTALLBINDIR))
+InstallManPage(pnmpred,$(INSTALLMANDIR)/man1)
+
+AllTarget(pnmtoraw)
+NormalCCProgramTarget(pnmtoraw,$(OBJSPNMTORAW),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(pnmtoraw,$(INSTALLBINDIR))
+InstallManPage(pnmtoraw,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawarith)
+NormalCCProgramTarget(rawarith,$(OBJSRAWARITH),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(rawarith,$(INSTALLBINDIR))
+InstallManPage(rawarith,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawdiff)
+NormalCCProgramTarget(rawdiff,$(OBJSRAWDIFF),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(rawdiff,$(INSTALLBINDIR))
+InstallManPage(rawdiff,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawmask)
+NormalCCProgramTarget(rawmask,$(OBJSRAWMASK),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(rawmask,$(INSTALLBINDIR))
+InstallManPage(rawmask,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawnjl)
+NormalCCProgramTarget(rawnjl,$(OBJSRAWNJL),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(rawnjl,$(INSTALLBINDIR))
+InstallManPage(rawnjl,$(INSTALLMANDIR)/man1)
+
+AllTarget(rawnjl2)
+NormalCCProgramTarget(rawnjl2,$(OBJSRAWNJL2),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(rawnjl2,$(INSTALLBINDIR))
+InstallManPage(rawnjl2,$(INSTALLMANDIR)/man1)
+
+AllTarget(dumptiff)
+NormalCCProgramTarget(dumptiff,$(OBJSDUMPTIFF),$(PROJECTMISCDEPLIBS),$(PROJECTMISCLIBS),-lm)
+InstallProgram(dumptiff,$(INSTALLBINDIR))
+InstallManPage(dumptiff,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::	testbinpatch
+
+test.create::	testbinpatch.create
+
+testbinpatch:
+	./binpatch.test.sh $(TOP)/test/$(CURRENT_DIR) compare
+
+testbinpatch.create:
+	./binpatch.test.sh $(TOP)/test/$(CURRENT_DIR) create
+
diff --git a/appsrc/misc/binpatch.cc b/appsrc/misc/binpatch.cc
new file mode 100644
index 0000000..cefda6c
--- /dev/null
+++ b/appsrc/misc/binpatch.cc
@@ -0,0 +1,350 @@
+static const char *CopyrightIdentifier(void) { return "@(#)binpatch.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>          // for listsimp.h
+#include <iomanip>           // for listsimp.h
+#include <fstream>
+#include <cstdlib>            // for atoi()
+#include <cctype>             // for isdigit()
+#else
+#include <iostream.h>          // for listsimp.h
+#include <iomanip.h>           // for listsimp.h
+#include <fstream.h>
+#include <stdlib.h>            // for atoi()
+#include <ctype.h>             // for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "listsort.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+class Patch {
+	unsigned	offset;
+	unsigned	length;
+	const char *	string;
+	const char *	Padstring;
+	char *		binarystring;
+	unsigned	binarystringlength;
+	char *		binarypadstring;
+	unsigned long	binaryvalue;
+
+	bool		isstring;
+
+	char getEscape(const char * & str)
+		{
+			unsigned char rval;
+			++str;	// skip "\"
+			switch (*str) {
+				case 'r':
+					rval='\r'; ++str; break;
+				case 'n':
+					rval='\n'; ++str; break;
+				case 't':
+					rval='\t'; ++str; break;
+				case 'f':
+					rval='\f'; ++str; break;
+				case 'b':
+					rval='\b'; ++str; break;
+				default:	
+					if (isdigit(*str)) {
+						char *term;
+						rval=(unsigned char)
+							strtol(str,&term,0);
+						str=term;
+					}
+					else
+						rval=*str++;
+					break;
+			}
+			return (char)rval;
+		}
+public:
+	Patch(unsigned o,unsigned l,const char *s,const char *p)
+		{
+			isstring=true;
+			offset=o;
+			length=l;
+			string=s;
+			Padstring=p;
+			binarystring=new char[strlen(string)+1];
+			Assert(binarystring);
+			const char *from=string;
+			char *to=binarystring;
+			while (*from) {
+				if (*from == '\\') *to=getEscape(from);
+				else *to=*from++;
+				++to;
+			}
+			*to='\0';
+			binarystringlength=strlen(binarystring);
+
+			binarypadstring=new char[strlen(Padstring)+1];
+			Assert(binarypadstring);
+			from=Padstring;
+			to=binarypadstring;
+			while (*from) {
+				if (*from == '\\') *to=getEscape(from);
+				else *to=*from++;
+				++to;
+			}
+			*to='\0';
+		}
+
+	Patch(unsigned o,unsigned l,unsigned long v,char endian)	// unsigned variety
+		{
+			isstring=false;
+			offset=o;
+			length=l;
+			binaryvalue=v;
+
+			string=0;
+			Padstring=0;
+
+			Assert(length <= sizeof(binaryvalue));
+			Assert(endian == 'l' || endian == 'b');
+
+			binarystring=new char[length];
+			Assert(binarystring);
+			int i;
+			char *ptr;
+			for (i=0,ptr=binarystring; i < length; ++i) {
+				if (endian == 'l')
+					*ptr++=(binaryvalue>>(8*i))&0xff;		// little endian
+				else
+					*ptr++=(binaryvalue>>(8*(length-1-i)))&0xff;	// big endian
+			}
+			binarystringlength=length;
+		}
+
+	void		put(ostream& stream)
+		{
+			if (isstring) {
+				stream << dec << "@" << offset
+					      << "\t[" << length
+					      << "]\t<" << string
+					      << ">\t<" << Padstring
+					      << ">";
+			}
+			else {
+				stream << dec << "@" << offset
+					      << "\t[" << length
+					      << "]\t<" << binaryvalue
+					      << ">";
+			}
+		}
+
+	unsigned	getOffset(void)		{ return offset; }
+	unsigned	getLength(void)		{ return length; }
+	unsigned	getStringLength(void)	{ return binarystringlength; }
+	const char *	getString(void)		{ return binarystring; }
+	const char *	getPadString(void)	{ return binarypadstring; }
+};
+	
+// In order for the sorted list template to know how to sort one needs
+// to define a type that can order itself, hence this ...
+
+class PatchPtr {
+	Patch *p;
+public:
+	PatchPtr(void)				{ p=0; }
+	PatchPtr(Patch *ptr)			{ p=ptr; }
+
+	PatchPtr(const PatchPtr& t)		{ p=t.p; }
+	void operator=(const PatchPtr& t)	{ p=t.p; }
+	operator Patch *(void)			{ return p; }
+
+	Patch * operator->(void)		{ return p; }
+
+	int operator==(const PatchPtr& p2)	{ return p->getOffset() == p2.p->getOffset(); }
+	int operator<(const PatchPtr& p2)	{ return p->getOffset() <  p2.p->getOffset(); }
+	int operator<=(const PatchPtr& p2)	{ return p->getOffset() <= p2.p->getOffset(); }
+	int operator>(const PatchPtr& p2)	{ return p->getOffset() >  p2.p->getOffset(); }
+	int operator>=(const PatchPtr& p2)	{ return p->getOffset() >= p2.p->getOffset(); }
+};	
+
+static bool
+checkPatchList(SortedList<PatchPtr>& patchlist)
+{
+	SortedListIterator<PatchPtr> pi(patchlist);
+	bool bad=false;
+	PatchPtr last = 0;
+	while (!pi) {
+		bool bothbad=false;
+		PatchPtr current=pi();
+		if (last && last > current) {
+			cerr << EMsgDC(PatchesNotInOrder) << endl;
+			bothbad=true;
+		}
+		if (last && last == current) {
+			cerr << EMsgDC(PatchesSameOffset) << endl;
+			bothbad=true;
+		}
+		if (last
+		 &&  last->getOffset()
+		   + last->getLength()
+		   > current->getOffset()
+		) {
+			cerr << EMsgDC(PatchesOverlap) << endl;
+			bothbad=true;
+		}
+		if (bothbad) {
+			last->put(cerr);
+			cerr << " cf. ";
+			current->put(cerr);
+			cerr << endl;
+			bad=true;
+		}
+		bool currentbad=false;
+		if (current->getLength() < current->getStringLength()) {
+			cerr << EMsgDC(PatchStringTooLong) << endl;
+			currentbad=true;
+		}
+		if (currentbad) {
+			current->put(cerr);
+			cerr << endl;
+			bad=true;
+		}
+		last=current;
+		++pi;
+	}
+	return bad;
+}
+
+int
+main(int argc, char *argv[])
+{
+	GetNamedOptions options(argc,argv);
+	InputOptions    input_options(options);
+	OutputOptions   output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	bool bad=false;
+	SortedList<PatchPtr> patchlist;
+	const char *args[4];
+	int n;
+
+	while ((n=options.get("r",args,4)) != -1) {
+		if (n == 4) {
+			unsigned offset=(unsigned)strtol(args[0],0,0);
+			unsigned length=(unsigned)strtol(args[1],0,0);
+			const char *string=args[2];
+			const char *pad=args[3];
+			patchlist+=new Patch(offset,length,string,pad);
+		}
+		else {
+			cerr << "-r: "
+			     << EMsgDC(WrongNumberOfArguments)
+			     << endl;
+			bad=true;
+		}
+	}
+
+	while ((n=options.get("i",args,4)) != -1) {
+		if (n == 4) {
+			unsigned offset=(unsigned)strtol(args[0],0,0);
+			unsigned length=(unsigned)strtol(args[1],0,0);
+			unsigned long value=strtoul(args[2],0,0);
+			char endian=*(args[3]);
+			patchlist+=new Patch(offset,length,value,endian);
+		}
+		else {
+			cerr << "-i: "
+			     << EMsgDC(WrongNumberOfArguments)
+			     << endl;
+			bad=true;
+		}
+	}
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	InputOpenerFromOptions  input_opener(options,input_options.filename,cin,true);
+	OutputOpenerFromOptions output_opener(options,output_options.filename,cout,true);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [-r offset length string padvalue]"
+			<< " [-i offset length integervalue l|b]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	if (verbose) {
+		SortedListIterator<PatchPtr> pi(patchlist);
+		while (!pi) {
+			pi()->put(cerr);
+			cerr << endl;
+			++pi;
+		}
+	}
+
+	if (checkPatchList(patchlist)) {
+		cerr << EMsgDC(BadPatches) << endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	ostream out(output_opener);
+
+	SortedListIterator<PatchPtr> pi(patchlist);
+	Patch *patch=!pi ? (Patch *)pi() : 0;
+	unsigned offset=0;
+	while (in.good() && in.peek() != istream::traits_type::eof()) {
+		char c;
+		in.read(&c,1);
+		if (!in.good()) {
+			cerr << EMsgDC(ReadFailed) << endl;
+			exit(1);
+		}
+		if (patch
+		 && offset >= patch->getOffset()
+		 && offset <  patch->getOffset()+patch->getLength()) {
+			unsigned index=offset-patch->getOffset();
+			if (index < patch->getStringLength()) {
+				out.write(patch->getString()+index,1);
+			}
+			else {
+				out.write(patch->getPadString(),1);
+			}
+			if (++offset >= patch->getOffset()+patch->getLength()) {
+				++pi;
+				patch=!pi ? (Patch *)pi() : 0;
+			}
+		}
+		else {
+			out.write(&c,1);
+			++offset;
+		}
+	}
+	if (!out.good()) {
+		cerr << EMsgDC(WriteFailed) << endl;
+		exit(1);
+	}
+	return 0;
+}
+
diff --git a/appsrc/misc/binpatch.man b/appsrc/misc/binpatch.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/binpatch.test.sh b/appsrc/misc/binpatch.test.sh
new file mode 100755
index 0000000..afabad5
--- /dev/null
+++ b/appsrc/misc/binpatch.test.sh
@@ -0,0 +1,111 @@
+#!/bin/sh
+
+TMPROOT=/tmp/`basename $0`.$$
+
+if [ "$#" != 2 ]
+then
+	bad="true"
+else
+	testlogdir="$1"	# eg. $(TOPDIR)/test/$(CURRENT_DIR)
+	mode="$2"	# eg. create|compare
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	elif [ ! -d "$testlogdir" -a "$mode" = "create" ]
+	then
+		echo "$0: making test log directory \"$testlogdir\"" 1>&2
+		mkdirhier "$testlogdir"
+		#echo "$0: no such test log directory as \"$testlogdir\"" 1>&2
+		#bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 testlogdir create|compare" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	if [ ! -d "$testlogdir" ]
+	then
+		mkdirhier "$testlogdir"
+	fi
+fi
+
+baseappname=binpatch
+
+
+echo "hello world" > "$TMPROOT.src"
+
+for v in \
+	1.16 \
+	2.16 \
+	3.16 \
+	4.16 \
+	1.-16 \
+	2.-16 \
+	3.-16 \
+	4.-16 \
+	1.0x7f \
+	1.0xff \
+	1.0x7fff \
+	2.0x7fff \
+	3.0x7fff \
+	4.0x7fff \
+	1.0xffff \
+	2.0xffff \
+	3.0xffff \
+	4.0xffff \
+	4.0x7fffff \
+	4.0xffffff \
+	4.0x7fffffff \
+	4.0xffffffff
+do
+	for endian in l b
+	do
+
+		comparename="$testlogdir/$baseappname.$v.$endian.dst"
+
+		if [ "$mode" = "compare" ]
+		then
+			dst="$TMPROOT.$v.$endian.dst"
+		else
+			dst="$comparename"
+		fi
+
+		length=`echo "$v" | sed 's/^\([0-9]*\)[.].*$/\1/'`
+		value=`echo "$v" | sed 's/^[0-9]*[.]\(.*\)$/ \1/'`
+
+		echo binpatch "$length" "$value" "$endian"
+		./binpatch "$TMPROOT.src" "$dst" -i 1 "$length" "$value" "$endian"
+		od -x "$dst" >"$dst.od"
+
+		if [ "$mode" = "compare" ]
+		then
+			if [ -f "$comparename" ]
+			then
+				echo "$baseappname:   comparing binary"
+				cmp "$dst" "$comparename"
+			else
+				echo "$baseappname:     nothing stored  to compare binary"
+			fi
+			rm "$dst"
+
+			if [ -f "$comparename.od" ]
+			then
+				echo "$baseappname:   comparing od"
+				diff "$dst.od" "$comparename.od"
+			else
+				echo "$baseappname:     nothing stored  to compare od"
+				cat "$dst.od"
+			fi
+			rm "$dst.od"
+		fi
+	done
+done
+
+rm -f "$TMPROOT.src"
diff --git a/appsrc/misc/bmpdump.cc b/appsrc/misc/bmpdump.cc
new file mode 100644
index 0000000..5397b4a
--- /dev/null
+++ b/appsrc/misc/bmpdump.cc
@@ -0,0 +1,119 @@
+static const char *CopyrightIdentifier(void) { return "@(#)bmpdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "bnstream.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+#include "txstream.h"
+
+static bool
+bmp_readAndDumpHeader(BinaryInputStream &in,TextOutputStream &log)
+{
+	// See amongst other references "http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html"
+	
+	char c1,c2;
+	in.get(c1);
+	if (!in) return false;
+	in.get(c2);
+	if (!in) return false;
+	if (c1 != 'B' || c2 != 'M') {
+		log << EMsgDC(NoBMPMagicNumber)
+			<< endl;
+		return false;
+	}
+	log << "magic       = " << c1 << c2 << endl;
+	
+	Uint32 bfSize = in.read32();
+	if (!in) return false;
+	log << "bfSize      = " << hex << bfSize << dec << "\t(" << bfSize << " dec)" << endl;
+	
+	Uint16 bfReserved1 = in.read16();
+	if (!in) return false;
+	log << "bfReserved1 = " << hex << bfReserved1 << dec << "\t(" << bfReserved1 << " dec)" << endl;
+	
+	Uint16 bfReserved2 = in.read16();
+	if (!in) return false;
+	log << "bfReserved2 = " << hex << bfReserved2 << dec << "\t(" << bfReserved2 << " dec)" << endl;
+	
+	Uint32 bfOffBits = in.read32();
+	if (!in) return false;
+	log << "bfOffBits   = " << hex << bfOffBits << dec << "\t(" << bfOffBits << " dec)" << endl;
+	
+	Uint32 biSize = in.read32();
+	if (!in) return false;
+	log << "biSize   = " << hex << biSize << dec << "\t(" << biSize << " dec)" << endl;
+	
+	Uint32 biWidth = in.read32();
+	if (!in) return false;
+	log << "biWidth   = " << hex << biWidth << dec << "\t(" << biWidth << " dec)" << endl;
+	
+	Uint32 biHeight = in.read32();
+	if (!in) return false;
+	log << "biHeight   = " << hex << biHeight << dec << "\t(" << biHeight << " dec)" << endl;
+
+	Uint16 biPlanes = in.read16();
+	if (!in) return false;
+	log << "biPlanes = " << hex << biPlanes << dec << "\t(" << biPlanes << " dec)" << endl;
+	
+	Uint16 biBitCount = in.read16();
+	if (!in) return false;
+	log << "biBitCount = " << hex << biBitCount << dec << "\t(" << biBitCount << " dec)" << endl;
+	
+	Uint32 biCompression = in.read32();
+	if (!in) return false;
+	log << "biCompression   = " << hex << biCompression << dec << "\t(" << biCompression << " dec)" << endl;
+	
+	Uint32 biSizeImage = in.read32();
+	if (!in) return false;
+	log << "biSizeImage   = " << hex << biSizeImage << dec << "\t(" << biSizeImage << " dec)" << endl;
+	
+	Uint32 biXPelsPerMeter = in.read32();
+	if (!in) return false;
+	log << "biXPelsPerMeter   = " << hex << biXPelsPerMeter << dec << "\t(" << biXPelsPerMeter << " dec)" << endl;
+	
+	Uint32 biYPelsPerMeter = in.read32();
+	if (!in) return false;
+	log << "biYPelsPerMeter   = " << hex << biYPelsPerMeter << dec << "\t(" << biYPelsPerMeter << " dec)" << endl;
+	
+	Uint32 biClrUsed = in.read32();
+	if (!in) return false;
+	log << "biClrUsed   = " << hex << biClrUsed << dec << "\t(" << biClrUsed << " dec)" << endl;
+	
+	Uint32 biClrImportant = in.read32();
+	if (!in) return false;
+	log << "biClrImportant   = " << hex << biClrImportant << dec << "\t(" << biClrImportant << " dec)" << endl;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions options(argc,argv);
+	BinaryInputOptions input_options(options);
+
+	input_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(options,input_options.filename,cin);
+
+	cerr << input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< " [" << MMsgDC(InputFile)
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream in(*(istream *)input_opener,LittleEndian);
+	TextOutputStream log (cerr);
+	bmp_readAndDumpHeader(in,log);
+}
+
diff --git a/appsrc/misc/bmpdump.man b/appsrc/misc/bmpdump.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/misc/dcunmeta.cc b/appsrc/misc/dcunmeta.cc
new file mode 100644
index 0000000..764ee7d
--- /dev/null
+++ b/appsrc/misc/dcunmeta.cc
@@ -0,0 +1,174 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcunmeta.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+#ifndef LOCALBUFSIZE
+#define LOCALBUFSIZE 16384
+#endif
+
+void
+readLE16(istream &stream,Uint16 &u)
+{
+	unsigned char buffer[2];
+	stream.read((char *)buffer,2);
+	u =  (Uint16)buffer[1];
+	u <<= 8;
+	u |= (Uint16)buffer[0];
+}
+
+void
+readLE32(istream &stream,Uint32 &u)
+{
+	unsigned char buffer[4];
+	stream.read((char *)buffer,4);
+	u =  (Uint32)buffer[3];
+	u <<= 8;
+	u |= (Uint32)buffer[2];
+	u <<= 8;
+	u |= (Uint32)buffer[1];
+	u <<= 8;
+	u |= (Uint32)buffer[0];
+}
+
+void
+writeLE16(ostream &stream,Uint16 u)
+{
+	char buffer[2];
+	buffer[1]=(unsigned char)(u>>8);
+	buffer[0]=(unsigned char)u;
+	stream.write(buffer,2);
+}
+
+int
+main(int argc,char **argv)
+{
+	(void)argc; (void)argv;
+
+	char preamble[128];
+	cin.read(preamble,128);
+	if (cin.fail()) {
+		cerr << EMsgDC(ReadFailed) << endl;
+		return false;
+	}
+
+	char magic[4];
+	cin.read(magic,4);
+	if (cin.fail()) {
+		cerr << EMsgDC(ReadFailed) << endl;
+		return false;
+	}
+
+	if (strncmp(magic,"DICM",4) != 0) {
+		cerr << EMsgDC(NotDICOMMessage)
+		     << " " << MMsgDC(Or) << " "
+		     << MMsgDC(MissingMetaheader) 
+		     << endl;
+		return false;
+	}
+
+	Uint16 group;
+	readLE16(cin,group);
+	Uint16 element;
+	readLE16(cin,element);
+	if (cin.fail()) {
+		cerr << EMsgDC(TagReadFailed) << endl;
+		return false;
+	}
+
+	if (group != 0x0002 || element != 0x0000) {
+		cerr << EMsgDC(MissingAttribute)
+		     << " - File Meta Information Group Length"
+		     << endl;
+		return false;
+	}
+
+	char VR[3];
+	cin.read(VR,2);
+	if (cin.fail() || strncmp(VR,"UL",2) != 0) {
+		cerr << EMsgDC(BadValueRepresentation)
+		     << " - File Meta Information Group Length";
+		if (!cin.fail()) {
+			VR[2]=0;
+			cerr << " = \"" << VR << "\"";
+		}
+		cerr << endl;
+		return false;
+	}
+
+	Uint16 VL;
+	readLE16(cin,VL);
+	if (cin.fail() || VL != 4) {
+		cerr << EMsgDC(BadValueLength)
+		     << " - File Meta Information Group Length";
+		if (!cin.fail())
+			cerr << " = \"" << VL << "\"";
+		cerr << endl;
+		return false;
+	}
+
+	Uint32 grouplength;
+	readLE32(cin,grouplength);
+	if (cin.fail()) {
+		cerr << EMsgDC(BadAttributeValue)
+		     << " - File Meta Information Group Length"
+		     << endl;
+		return false;
+	}
+
+	cin.seekg(grouplength,ios::cur);
+	if (cin.fail()) {
+		cerr << EMsgDC(MissingMetaheader)
+		     << " - " << MMsgDC(SeekFailed)
+		     << endl;
+		return false;
+	}
+
+#ifdef CRAP
+	// default ANSI cin/cout is unbuffered, slow, so ...
+
+	streambuf *isbuf  = cin.rdbuf();
+	istream *istr=new istream(isbuf);
+	if (istr) {
+		char *ibuf=new char[REPLACESTANDARDIOBUFSIZE];
+		if (ibuf) isbuf->setbuf(ibuf,REPLACESTANDARDIOBUFSIZE);
+	}
+	else {
+		istr=&cin;
+	}
+
+	streambuf *osbuf  = cout.rdbuf();
+	ostream *ostr=new ostream(osbuf);
+	if (ostr) {
+		char *obuf=new char[REPLACESTANDARDIOBUFSIZE];
+		if (obuf) osbuf->setbuf(obuf,REPLACESTANDARDIOBUFSIZE);
+	}
+	else {
+		ostr=&cout;
+	}
+	// Be careful not to use cin and cout beyond this point
+#else
+	istream *istr=&cin;
+	ostream *ostr=&cout;
+#endif
+
+	while (istr && !istr->eof()) {
+		char buffer[LOCALBUFSIZE];
+		istr->read(buffer,LOCALBUFSIZE);
+		ostr->write(buffer,istr->gcount());
+	}
+
+}
diff --git a/appsrc/misc/dcunmeta.man b/appsrc/misc/dcunmeta.man
new file mode 100755
index 0000000..7d3ddff
--- /dev/null
+++ b/appsrc/misc/dcunmeta.man
@@ -0,0 +1,73 @@
+.TH DCUNMETA 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - Remove DICOM Metaheader"
+.SH NAME
+dcunmeta \- DICOM PS3 ... Remove DICOM Metaheader
+.SH SYNOPSIS
+.HP 10
+.B dcunmeta
+.SH DESCRIPTION
+.LP
+.B dcunmeta
+reads a DICOM PS 3.10 style file with a Meta Information Header from the standard input and writes the raw contents of the DICOM message beyond the Meta Information Header to the standard output.
+.LP
+Note that there is no processing of the DICOM message beyond the Meta Information Header - it is copied byte for byte without additions or deletions or attention to the specific Transfer Syntax present.
+.SH OPTIONS
+Input comes from standard in and output goes to standard out. Errors go to standard error.
+.LP
+There are no command line options.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+.RE
+\ 
+.RE
+% dcfile test.metaheader
+.RE
+Meta: UID		1.2.840.10008.1.2.1
+.RE
+Meta: Description	"Explicit VR Little Endian"
+.RE
+Meta: ByteOrder	Little
+.RE
+Meta: VR		Explicit
+.RE
+Meta: Encapsulated	No
+.RE
+Data: UID		1.2.840.10008.1.2
+.RE
+Data: Description	"Implicit VR Little Endian"
+.RE
+Data: ByteOrder	Little
+.RE
+Data: VR		Implicit
+.RE
+Data: Encapsulated	No
+.RE
+\ 
+.RE
+% dcunmeta <test.metaheader >test.implicit
+.RE
+\ 
+.RE
+% dcfile test.implicit
+.RE
+Data: UID		1.2.840.10008.1.2
+.RE
+Data: Description	"Implicit VR Little Endian"
+.RE
+Data: ByteOrder	Little
+.RE
+Data: VR		Implicit
+.RE
+Data: Encapsulated	No
+.RE
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dcfile(1), dcrmmeta(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/misc/dumptiff.cc b/appsrc/misc/dumptiff.cc
new file mode 100644
index 0000000..7b0ba4c
--- /dev/null
+++ b/appsrc/misc/dumptiff.cc
@@ -0,0 +1,139 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dumptiff.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "bnstream.h"
+#include "errclass.h"
+#include "mesgtext.h"
+
+class TIFF_Reader : public ErrorsInClass {
+private:
+	BinaryInputStream *bin;
+
+	Uint32 nextIFDOffset;
+	bool nextIFDOffsetIsGood;
+
+	bool readImageFileHeader(istream &in);
+	bool readNextIFD(void);
+public:
+	TIFF_Reader(istream &in);
+};
+
+TIFF_Reader::TIFF_Reader(istream &in)
+{
+	nextIFDOffsetIsGood=false;
+	if (!readImageFileHeader(in)) {
+		errorstream << EMsgDC(FileHeaderReadFailed) << endl;
+		good_flag=false;
+	}
+	while (readNextIFD()) {
+	}
+}
+
+bool
+TIFF_Reader::readImageFileHeader(istream &in)
+{
+	char Identifier[2];
+	in.read(Identifier,2);
+	if (!in) {
+		errorstream
+			<< EMsgDC(ReadFailed)
+			<< " - TIFF Identifier"
+			<< endl;
+		good_flag=false;
+		return false;
+	}
+	Endian endian;
+	if (strncmp(Identifier,"II",2) == 0)
+		endian=LittleEndian;
+	else if (strncmp(Identifier,"II",2) == 0)
+		endian=BigEndian;
+	else {
+		errorstream
+			<< EMsgDC(UnrecognizedFormat)
+			<< " - TIFF Identifier - \""
+			<< Identifier[0] << Identifier[1]
+			<< "\""
+			<< endl;
+		good_flag=false;
+		return false;
+	}
+
+	bin=new BinaryInputStream(in.rdbuf(),endian);
+	Assert(bin);
+
+	Uint16 Version;
+	(*bin) >> Version;
+	if (bin->fail()) {
+		errorstream
+			<< EMsgDC(ReadFailed)
+			<< " - TIFF Version"
+			<< endl;
+		good_flag=false;
+		return false;
+	}
+	if (Version != 0x002a) {
+		errorstream
+			<< EMsgDC(UnrecognizedFormat)
+			<< " - TIFF Version - "
+			<< Version
+			<< endl;
+		good_flag=false;
+		return false;
+	}
+
+	(*bin) >> nextIFDOffset;
+	if (bin->fail()) {
+		errorstream
+			<< EMsgDC(ReadFailed)
+			<< " - TIFF ImageFileHeader IFDOffset"
+			<< endl;
+		good_flag=false;
+		return false;
+	}
+
+	nextIFDOffsetIsGood=true;
+
+cerr << "TIFF_Reader::readImageFileHeader"
+     << " Identifier = " << Identifier[0] << Identifier[1]
+     << " (endian = " << (endian == LittleEndian ? "little" : "big") << ")"
+     << " Version = " << Version
+     << " ImageFileHeader IFDOffset = " << nextIFDOffset
+     << endl;
+	return true;
+}
+
+bool
+TIFF_Reader::readNextIFD(void)
+{
+	if (!nextIFDOffsetIsGood) return false;
+
+	bin->seekg(nextIFDOffset,ios::beg);
+	if (bin->fail()) {
+		errorstream << EMsgDC(SeekFailed) << endl;
+		good_flag=0;
+		return false;
+	}
+
+	//(*bin) >> NumDirEntries;
+	
+}
+
+int
+main(int,char **)
+{
+	TIFF_Reader reader(cin);
+
+cerr << "Not implemented yet ..." << endl;
+
+	return 0;
+}
+
diff --git a/appsrc/misc/dumptiff.man b/appsrc/misc/dumptiff.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/dumpwhat.cc b/appsrc/misc/dumpwhat.cc
new file mode 100644
index 0000000..b951c72
--- /dev/null
+++ b/appsrc/misc/dumpwhat.cc
@@ -0,0 +1,1281 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dumpwhat.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <cstdlib>            // for atoi()
+#include <cctype>
+#else
+#include <iostream.h>
+#include <fstream.h>
+#include <iomanip.h>
+#include <stdlib.h>            // for atoi()
+#include <ctype.h>
+//#include <string.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+const unsigned 	DefaultBufferSizeIncrement	= 1024;
+const double 	ReasonableMinimumFloatToShow 	= 0.01;
+	
+
+inline unsigned char *
+CopyOverlapping(unsigned char *to,const unsigned char *from,unsigned long n)
+{
+	while (n--) *to++=*from++;
+	return to;
+}
+
+class Buffer {
+	unsigned char *buffer;
+	unsigned long bufsize;
+	unsigned long bufincr;
+	unsigned long length;
+	unsigned long bytesread;
+	unsigned long total;
+	istream *istr;
+	unsigned long offset;
+	int over;
+
+	void extendBuffer(void)
+		{
+			//cerr << "extendBuffer: start\n" << flush;
+			//putState(cerr);
+			unsigned char *oldbuf=buffer;
+			unsigned long oldsize=bufsize;
+			bufsize+=bufincr;
+			buffer=new unsigned char[bufsize];
+			if (length) memcpy(buffer,oldbuf,(int)length);
+			if (oldsize) delete[] oldbuf;
+			//cerr << "extendBuffer: done\n" << flush;
+			//putState(cerr);
+		}
+	void cleanBuffer(void)
+		{
+			//cerr << "cleanBuffer: start\n" << flush;
+			//putState(cerr);
+			length-=bytesread;
+			CopyOverlapping(buffer,buffer+bytesread,length);
+			bytesread=0;
+			//cerr << "cleanBuffer: done\n" << flush;
+			//putState(cerr);
+		}
+	void putState(ostream& ostr)
+		{
+			ostr << "    putState:\n" << flush;
+			ostr << "        bufsize   =" 
+			     << bufsize << "\n" << flush;
+			ostr << "        bufincr   =" 
+			     << bufincr << "\n" << flush;
+			ostr << "        length    =" 
+			     << length << "\n" << flush;
+			ostr << "        bytesread ="
+			     << bytesread << "\n" << flush;
+			ostr << "        offset    ="
+			     << offset << "\n" << flush;
+			ostr << "        total    ="
+			     << total << "\n" << flush;
+		}
+public:
+	Buffer(istream *str,unsigned long skip,unsigned long t)
+		{
+			//cerr << "Buffer(istream *str): start\n" << flush;
+			buffer=0;
+			bufsize=0;
+			length=0;
+			bytesread=0;
+			istr=str;
+			offset=0;
+			total=t;
+			over=0;
+			bufincr=DefaultBufferSizeIncrement;
+
+			// must be properly initialized by this point ...
+
+			if (skip && read(skip) == 0) {
+				cerr << "Error skipping first "
+				     << dec << skip << " bytes\n" << flush;
+				exit(1);
+			}
+
+			//cerr << "Buffer(istream *str): done\n" << flush;
+			//putState(cerr);
+		}
+
+	const unsigned char * readLookAhead(unsigned long n)
+		{
+			//cerr << "readLookAhead: start(" << n << ")\n"
+			//     << flush;
+			//putState(cerr);
+			if (over || (total && offset+n > total)) return 0;
+			if (bufsize-bytesread < n)    cleanBuffer();
+			while (bufsize-bytesread < n) extendBuffer();
+
+			if (length-bytesread < n) 
+				length+=istr->rdbuf()->sgetn(
+					(char *)buffer+length,
+					(int)(bufsize-length));
+
+			const unsigned char *ptr;
+			if (length-bytesread < n)
+				ptr=0;			// failure
+			else
+				ptr=buffer+bytesread;
+
+			//cerr << "readLookAhead: done returns "
+			//     << (ptr ? ptr : (const unsigned char *)"<Null>")
+			//     << "\n" << flush;
+			//putState(cerr);
+			return ptr;
+		}
+
+	const unsigned char *read(unsigned long n)
+		{
+			//cerr << "read: start(" << n << ")\n" << flush;
+			//putState(cerr);
+			const unsigned char *ptr = readLookAhead(n);
+			if (ptr) {
+				bytesread+=n;
+				offset+=n;
+			}
+			else {
+				// Attempt to read past end shuts us down.
+				cerr << "read: attempt to read past end\n";
+				over=1;
+			}
+			//cerr << "read: done returns "
+			//     << (ptr ? ptr : (const unsigned char *)"<Null>")
+			//     << "\n" << flush;
+			return ptr;
+		}
+
+	int isMore(void)
+		{
+			//cerr << "isMore: start\n" << flush;
+			return readLookAhead(1) ? 1 : 0;
+		}
+
+	unsigned long getOffset(void)	{ return offset; }
+};
+
+class Parameters {
+public:
+	bool usecerr;
+	bool bigendian;
+	bool littleendian;
+	bool showhex;
+	bool showdec;
+	bool showoct;
+	bool showieeefloat;
+	bool showvaxfloat;
+	bool showstrings;
+	bool showstringcontents;
+	bool showchars;
+	bool showtype;
+	bool showkey;
+	bool shownegative;
+	bool showaddress;
+	bool show1;
+	bool show2;
+	bool show4;
+	bool elidezeroes;
+	bool elidespaces;
+	bool elidereport;
+	bool restricted;
+	unsigned long restrictionvalue;
+	unsigned long maxbytes;
+	unsigned long jumpbytes;
+	unsigned long stringlength;
+
+	Parameters(void)
+		{
+			usecerr=false;
+			bigendian=false;
+			littleendian=false;
+			showhex=false;
+			showdec=false;
+			showoct=false;
+			showieeefloat=false;
+			showvaxfloat=false;
+			showstrings=false;
+			showstringcontents=false;
+			showchars=false;
+			showtype=false;
+			showkey=false;
+			shownegative=false;
+			showaddress=false;
+			show1=false;
+			show2=false;
+			show4=false;
+			elidezeroes=true;
+			elidespaces=true;
+			elidereport=true;
+			restricted=0;
+			maxbytes=0;
+			jumpbytes=0;
+			stringlength=40;
+		}
+
+	void dump(ostream& o) const
+		{
+			o << "usecerr = " << usecerr << endl;
+			o << "bigendian = " << bigendian << endl;
+			o << "littleendian = " << littleendian << endl;
+			o << "showhex = " << showhex << endl;
+			o << "showdec = " << showdec << endl;
+			o << "showoct = " << showoct << endl;
+			o << "showieeefloat = " << showieeefloat << endl;
+			o << "showvaxfloat = " << showvaxfloat << endl;
+			o << "showstrings = " << showstrings << endl;
+			o << "showstringcontents = " << showstringcontents << endl;
+			o << "showchars = " << showchars << endl;
+			o << "showtype = " << showtype << endl;
+			o << "showkey = " << showkey << endl;
+			o << "shownegative = " << shownegative << endl;
+			o << "showaddress = " << showaddress << endl;
+			o << "show1 = " << show1 << endl;
+			o << "show2 = " << show2 << endl;
+			o << "show4 = " << show4 << endl;
+			o << "elidezeroes = " << elidezeroes << endl;
+			o << "elidespaces = " << elidespaces << endl;
+			o << "elidereport = " << elidereport << endl;
+			o << "restricted = " << restricted << endl;
+			o << "restrictionvalue = " << restrictionvalue << endl;
+			o << "maxbytes = " << maxbytes << endl;
+			o << "jumpbytes = " << jumpbytes << endl;
+			o << "stringlength = " << stringlength << endl;
+		}
+};
+
+typedef unsigned char  Uint8;
+typedef unsigned short Uint16;
+typedef unsigned long  Uint32;
+typedef signed char    Int8;
+typedef short          Int16;
+typedef long           Int32;
+
+Int32
+SignExtended(Uint32 value,unsigned short length)
+{
+	Uint32 vmask;
+	Uint32 smask;
+	switch (length) {
+		case 1:	vmask=0x7f; smask=0x80; break;
+		case 2:	vmask=0x7fff; smask=0x8000; break;
+		case 4:
+		default:
+			vmask=0x7fffffff; smask=0x80000000; break;
+	}
+	return (value&smask)
+		? (((Int32)(-1)^vmask)|value)
+		: (Int32)(value&vmask);
+
+}
+
+void
+putHexInteger(ostream& ostr,Parameters& params,unsigned short length,Uint32 value,char pad)
+{
+	(void)params;
+	unsigned short width = (length*8-1)/4u+1;
+	unsigned short padding = (4*8-1)/4+1 - width;
+	while (pad && padding--) ostr << pad;
+	ostr << hex << "0x" << setfill('0') << setw(width) << value;
+}
+
+void
+putOctInteger(ostream& ostr,Parameters& params,unsigned short length,Uint32 value,char pad)
+{
+	(void)params;
+	unsigned short width = (length*8-1)/3u+1;
+	unsigned short padding = (4*8-1)/3+1 - width;
+	while (pad && padding--) ostr << pad;
+	ostr << oct << "0" << setfill('0') << setw(width) << value;
+}
+
+void
+putDecInteger(ostream& ostr,Parameters& params,unsigned short length,Uint32 value,char pad)
+{
+	unsigned short width = (length*8-1)/3u+1;
+	const unsigned short maxwidth = (4*8-1)/3+1+1;
+
+	ostrstream os;
+	if (params.shownegative) {
+		Int32 i = SignExtended(value,length);
+		os << dec << setfill(' ') << setw(width) << i << ends;
+	}
+	else {
+		os << dec << setfill(' ') << setw(width) << value << ends;
+	}
+	char *s = os.str();
+	int padding=maxwidth-strlen(s);
+	while (pad && padding-- > 0) ostr << pad;
+	ostr << s;
+	if (s) delete[] s;
+}
+
+void
+putBinaryInteger(ostream& ostr,Parameters& params,unsigned short length,Uint32 value,char pad)
+{
+	if (params.showhex) {
+		putHexInteger(ostr,params,length,value,pad);
+		if (params.showdec || params.showoct) ostr << " ";
+	}
+	if (params.showdec) {
+		putDecInteger(ostr,params,length,value,pad);
+		if (params.showoct) ostr << " ";
+	}
+	if (params.showoct) putOctInteger(ostr,params,length,value,pad);
+}
+
+void
+putOffset(ostream& ostr,Parameters& params,Uint32 value)
+{
+	if (params.showaddress | params.showhex
+	  | params.showdec     | params.showoct) {
+		if (params.showkey) ostr << "offset=\"";
+		else ostr << "[";
+		if (params.showaddress) {
+			putDecInteger(ostr,params,2,value,'\0');
+		}
+		else {
+			putBinaryInteger(ostr,params,2,value,'\0');
+		}
+		if (params.showkey) ostr << "\"";
+		else ostr << "]";
+		ostr << " ";
+	}
+}
+
+void
+putOffsetRange(ostream& ostr,Parameters& params,Uint32 offset1,Uint32 offset2)
+{
+	if (params.showaddress | params.showhex
+	  | params.showdec     | params.showoct) {
+		putOffset(ostr,params,offset1);
+		ostr << "to ";
+		putOffset(ostr,params,offset2);
+	}
+}
+
+void
+putDescriptor(ostream& ostr,Parameters& params,
+		char byteorder,unsigned long offset,char *desc)
+{
+	putOffset(ostr,params,offset);
+	if (params.showtype) {
+		if (params.showkey) ostr << "type=\"";
+		if (byteorder)
+			ostr << (byteorder == 'B' ? "B" : "L") << "_";
+		ostr << desc;
+		if (params.showkey) ostr << "\"";
+		if (!byteorder)      ostr << "   ";
+		ostr << " ";
+	}
+}
+
+void
+putBinaryDescriptor(ostream& ostr,Parameters& params,
+		char byteorder,unsigned long offset,unsigned short length)
+{
+	ostrstream os;
+	os << "int_" << dec << length*8 << ends;
+	char *desc=os.str();
+	putDescriptor(ostr,params,byteorder,offset,desc);
+	if (desc) delete[] desc;
+	ostr << "    ";
+}
+
+void
+putBinaryIntegerWithDescription(ostream& ostr,Parameters& params,
+		char byteorder,unsigned long offset,
+		unsigned short length,Uint32 value)
+{
+	int show;
+
+	if (params.restricted) {
+		if (params.shownegative) {
+			show = value < params.restrictionvalue
+			   || (Uint32)(-SignExtended(value,length))
+			    < params.restrictionvalue;
+		}
+		else {
+			show = value < params.restrictionvalue;
+		}
+	}
+	else
+		show=1;
+
+	if (show) {
+		putBinaryDescriptor(ostr,params,byteorder,offset,length);
+		putBinaryInteger(ostr,params,length,value,' ');
+		ostr << "\n";
+	}
+}
+
+void
+putChar(ostream& ostr,Parameters& params,Uint8 value,char pad,char fill)
+{
+	(void)params;
+	const unsigned short maxwidth = 3;
+
+	ostrstream os;
+	char c = isprint((char)value) ? (char)value : fill;
+	os << "\'" << c << "\'" << ends;
+
+	char *s = os.str();
+	int padding=maxwidth-strlen(s);
+	while (pad && padding-- > 0) ostr << pad;
+	ostr << s;
+	if (s) delete[] s;
+}
+
+void
+putCharWithDescription(ostream& ostr,Parameters& params,
+		unsigned long offset,Uint8 value,char fill)
+{
+	if (!params.restricted || isprint((char)value)) {
+		putDescriptor(ostr,params,'\0',offset,"char");
+		putChar(ostr,params,value,' ',fill);
+		ostr << "\n";
+	}
+}
+
+
+int
+tryUint64(Buffer& buffer,char byteorder,Uint32& rvaluehigh,Uint32& rvaluelow)
+{
+	const unsigned char *start=buffer.readLookAhead(8);
+	if (start) {
+		int increment = (byteorder == 'B' ? 1 : -1);
+		int count;
+		const unsigned char *ptr = (byteorder == 'B' ? start : start+7);
+
+		count=4;
+		rvaluehigh=0;
+		while (count--) {
+			rvaluehigh<<=8;
+			rvaluehigh|=*ptr;
+			ptr+=increment;
+		}
+		count=4;
+		rvaluelow=0;
+		while (count--) {
+			rvaluelow<<=8;
+			rvaluelow|=*ptr;
+			ptr+=increment;
+		}
+		return 1;
+	}
+	else
+		return 0;
+}
+
+int
+tryUint32(Buffer& buffer,char byteorder,Uint32& rvalue)
+{
+	const unsigned char *start=buffer.readLookAhead(4);
+	if (start) {
+		int increment = (byteorder == 'B' ? 1 : -1);
+		int count = 4;
+		const unsigned char *ptr = (byteorder == 'B' ? start : start+3);
+
+		rvalue=0;
+		while (count--) {
+			rvalue<<=8;
+			rvalue|=*ptr;
+			ptr+=increment;
+		}
+		return 1;
+	}
+	else
+		return 0;
+}
+
+int
+tryUint16(Buffer& buffer,char byteorder,Uint16& rvalue)
+{
+	const unsigned char *start=buffer.readLookAhead(2);
+	if (start) {
+		int increment = (byteorder == 'B' ? 1 : -1);
+		int count = 2;
+		const unsigned char *ptr = (byteorder == 'B' ? start : start+1);
+
+		rvalue=0;
+		while (count--) {
+			rvalue<<=8;
+			rvalue|=*ptr;
+			ptr+=increment;
+		}
+		return 1;
+	}
+	else
+		return 0;
+}
+
+int
+tryUint8(Buffer& buffer,Uint8& rvalue)
+{
+	const unsigned char *start=buffer.readLookAhead(2);
+	if (start) {
+		rvalue=*start;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+void
+checkbinary(Buffer& buffer,ostream& ostr,char byteorder,Parameters& params)
+{
+	unsigned long offset=buffer.getOffset();
+
+	if (params.show4 && offset%4 == 0) {
+		Uint32 uvalue;
+		if (tryUint32(buffer,byteorder,uvalue)) {
+			putBinaryIntegerWithDescription(
+				ostr,params,byteorder,offset,4,uvalue);
+		}
+	}
+
+	if (params.show2 && offset%2 == 0) {
+		Uint16 uvalue;
+		if (tryUint16(buffer,byteorder,uvalue)) {
+			putBinaryIntegerWithDescription(
+				ostr,params,byteorder,offset,2,uvalue);
+		}
+	}
+}
+
+void
+checkbinarybyte(Buffer& buffer,ostream& ostr,Parameters& params)
+{
+	unsigned long offset=buffer.getOffset();
+
+	{
+		Uint8 uvalue;
+		if (tryUint8(buffer,uvalue)) {
+			putBinaryIntegerWithDescription(
+				ostr,params,'\0',offset,1,uvalue);
+		}
+	}
+}
+
+void
+checkchars(Buffer& buffer,ostream& ostr,Parameters& params,char fill)
+{
+	unsigned long offset=buffer.getOffset();
+
+	{
+		Uint8 uvalue;
+		if (tryUint8(buffer,uvalue)) {
+			putCharWithDescription(
+				ostr,params,offset,uvalue,fill);
+		}
+	}
+}
+
+class IeeeFloat32 {
+	enum IeeeFloat32Class { IeeeFloat32Zero,
+		IeeeFloat32Normal, IeeeFloat32NotNormal,
+		IeeeFloat32NotANumber,
+		IeeeFloat32PlusInfinity, IeeeFloat32MinusInfinity } cl;
+	double value;
+public:
+	IeeeFloat32(void) { cl=IeeeFloat32Zero; value=0; }
+
+	IeeeFloat32(Uint32 binary) {
+		Int16 sign	=(Int16)((binary&0x80000000)>>31);
+		Int16 exponent	=(Int16)((binary&0x7f800000)>>23);
+		Uint32 mantissa	= binary&0x007fffff;
+
+		if (exponent == 0) {
+			if (mantissa == 0) {
+				cl=IeeeFloat32Zero;
+				value=0;
+			}
+			else {
+				value=((double)mantissa/
+					(1<<23))*pow(2.0,(long)-126);
+				value = (sign == 0) ? value : -value;
+				cl=IeeeFloat32NotNormal;
+			}
+		}
+		else if (exponent == 255) {
+			if (mantissa) {
+				cl=IeeeFloat32NotANumber;
+			}
+			else {
+				cl=sign ? IeeeFloat32MinusInfinity
+					   : IeeeFloat32PlusInfinity;
+			}
+		}
+		else {
+			value=(1.0+(double)mantissa/
+				(1<<23))*pow(2.0,(long)(exponent)-127);
+			value = (sign == 0) ? value : -value;
+			cl=IeeeFloat32Normal;
+		}
+	}
+
+	double getValue(void) { return value; }
+
+	int isNumber(void)
+		{ return isZero() | isNormalized() | isNotNormalized(); }
+	int isInfinity(void)
+		{ return isPlusInfinity() | isMinusInfinity(); }
+
+	int isZero(void)
+		{ return cl==IeeeFloat32Zero; }
+	int isNormalized(void)
+		{ return cl==IeeeFloat32Normal; }
+	int isNotNormalized(void)
+		{ return cl==IeeeFloat32NotNormal; }
+	int isNotANumber(void)
+		{ return cl==IeeeFloat32NotANumber; }
+	int isPlusInfinity(void)
+		{ return cl==IeeeFloat32PlusInfinity; }
+	int isMinusInfinity(void)
+		{ return cl==IeeeFloat32MinusInfinity; }
+
+	const char *describe(void) {
+		const char *desc;
+		switch (cl) {
+			case IeeeFloat32Zero:
+				desc="Zero"; break;
+			case IeeeFloat32Normal:
+				desc="Normalized"; break;
+			case IeeeFloat32NotNormal:
+				desc="Not Normalized"; break;
+			case IeeeFloat32NotANumber:
+				desc="Not A Number"; break;
+			case IeeeFloat32PlusInfinity:
+				desc="+Infinity"; break;
+			case IeeeFloat32MinusInfinity:
+				desc="-Infinity"; break;
+			default:
+				desc="Bad"; break;
+		}
+		return desc;
+	}
+};
+
+class IeeeFloat64 {
+	enum IeeeFloat64Class { IeeeFloat64Zero,
+		IeeeFloat64Normal, IeeeFloat64NotNormal,
+		IeeeFloat64NotANumber,
+		IeeeFloat64PlusInfinity, IeeeFloat64MinusInfinity } cl;
+	double value;
+public:
+	IeeeFloat64(void) { cl=IeeeFloat64Zero; value=0; }
+
+	IeeeFloat64(Uint32 high,Uint32 low) {
+		Int16 sign	=(Int16)((high&0x80000000)>>31);
+		Int16 exponent	=(Int16)((high&0x7ff00000)>>20);
+		Uint32 mantissahigh = high&0x000fffff;
+		Uint32 mantissalow  = low;
+		double mantissavalue = (double)mantissahigh * pow(2.0,(long)32)
+				     + (double)mantissalow;
+
+		if (exponent == 0) {
+			if (mantissahigh == 0 && mantissalow == 0) {
+				cl=IeeeFloat64Zero;
+				value=0;
+			}
+			else {
+				value=(mantissavalue/pow(2.0,(long)52))
+					*pow(2.0,(long)-1022);
+				value = (sign == 0) ? value : -value;
+				cl=IeeeFloat64NotNormal;
+			}
+		}
+		else if (exponent == 2047) {
+			if (mantissahigh || mantissalow) {
+				cl=IeeeFloat64NotANumber;
+			}
+			else {
+				cl=sign ? IeeeFloat64MinusInfinity
+					   : IeeeFloat64PlusInfinity;
+			}
+		}
+		else {
+			value=(1.0+mantissavalue/pow(2.0,(long)52))
+				*pow(2.0,(long)(exponent)-1023);
+			value = (sign == 0) ? value : -value;
+			cl=IeeeFloat64Normal;
+		}
+	}
+
+	double getValue(void) { return value; }
+
+	int isNumber(void)
+		{ return isZero() | isNormalized() | isNotNormalized(); }
+	int isInfinity(void)
+		{ return isPlusInfinity() | isMinusInfinity(); }
+
+	int isZero(void)
+		{ return cl==IeeeFloat64Zero; }
+	int isNormalized(void)
+		{ return cl==IeeeFloat64Normal; }
+	int isNotNormalized(void)
+		{ return cl==IeeeFloat64NotNormal; }
+	int isNotANumber(void)
+		{ return cl==IeeeFloat64NotANumber; }
+	int isPlusInfinity(void)
+		{ return cl==IeeeFloat64PlusInfinity; }
+	int isMinusInfinity(void)
+		{ return cl==IeeeFloat64MinusInfinity; }
+
+	const char *describe(void) {
+		const char *desc;
+		switch (cl) {
+			case IeeeFloat64Zero:
+				desc="Zero"; break;
+			case IeeeFloat64Normal:
+				desc="Normalized"; break;
+			case IeeeFloat64NotNormal:
+				desc="Not Normalized"; break;
+			case IeeeFloat64NotANumber:
+				desc="Not A Number"; break;
+			case IeeeFloat64PlusInfinity:
+				desc="+Infinity"; break;
+			case IeeeFloat64MinusInfinity:
+				desc="-Infinity"; break;
+			default:
+				desc="Bad"; break;
+		}
+		return desc;
+	}
+};
+
+class VaxFloat_F {
+	enum VaxFloat_FClass { VaxFloat_F_Zero,VaxFloat_F_Number } cl;
+	double value;
+public:
+	VaxFloat_F(void) { cl=VaxFloat_F_Zero; value=0; }
+
+	VaxFloat_F(Uint32 binary) {
+		Uint32 mantissalow	= (binary&0xffff0000)>>16;
+		Int16 sign		=(Int16)((binary&0x00008000)>>15);
+		Int16 exponent		=(Int16)((binary&0x00007f80)>>7);
+		Uint32 mantissahigh	= binary&0x0000007f;
+		double mantissavalue    = (double)mantissahigh *
+			pow(2.0,(long)16) + (double)mantissalow;
+		double mantissafraction = mantissavalue/pow(2.0,(long)23);
+
+		if (exponent == 0&& mantissalow == 0 && mantissahigh == 0) {
+			cl=VaxFloat_F_Zero;
+			value=0;
+		}
+		else {
+		// Always normalized ... the 1.0 is the "hidden" bit in VaxSpeak
+		// the exponent is excess 128, eg 10000010 is +2
+		// but refers to a binary point to the LEFT of the hidden bit
+		// hence the -129 rather than -128
+
+			value=(1.0+mantissafraction)
+				*pow(2.0,(long)(exponent)-129);
+			value = (sign == 0) ? value : -value;
+			cl=VaxFloat_F_Number;
+		}
+	}
+
+	double getValue(void) { return value; }
+
+	int isNumber(void)
+		{ return cl==VaxFloat_F_Number; }
+	int isZero(void)
+		{ return cl==VaxFloat_F_Zero; }
+
+	const char *describe(void) {
+		const char *desc;
+		switch (cl) {
+			case VaxFloat_F_Zero:
+				desc="Zero"; break;
+			case VaxFloat_F_Number:
+				desc="Number"; break;
+			default:
+				desc="Bad"; break;
+		}
+		return desc;
+	}
+};
+
+void
+putIeeeFloat32(ostream& ostr,Parameters& params,IeeeFloat32 value,char pad)
+{
+	(void)params;
+	unsigned short width = 8;
+	const unsigned short maxwidth = 14;
+
+	ostrstream os;
+	if (value.isNumber()) {
+		os << dec << setfill(' ') << setw(width)
+		   << value.getValue() << ends;
+	}
+	else {
+		os << value.describe() << ends;
+	}
+	char *s = os.str();
+	int padding=maxwidth-strlen(s);
+	while (pad && padding-- > 0) ostr << pad;
+	ostr << s;
+	if (s) delete[] s;
+}
+
+void
+putIeeeFloat64(ostream& ostr,Parameters& params,IeeeFloat64 value,char pad)
+{
+	(void)params;
+	unsigned short width = 8;
+	const unsigned short maxwidth = 14;
+
+	ostrstream os;
+	if (value.isNumber()) {
+		os << dec << setfill(' ') << setw(width)
+		   << value.getValue() << ends;
+	}
+	else {
+		os << value.describe() << ends;
+	}
+	char *s = os.str();
+	int padding=maxwidth-strlen(s);
+	while (pad && padding-- > 0) ostr << pad;
+	ostr << s;
+	if (s) delete[] s;
+}
+
+void
+putVaxFloat_F(ostream& ostr,Parameters& params,VaxFloat_F value,char pad)
+{
+	(void)params;
+	unsigned short width = 8;
+	const unsigned short maxwidth = 14;
+
+	ostrstream os;
+	if (value.isNumber()) {
+		os << dec << setfill(' ') << setw(width)
+		   << value.getValue() << ends;
+	}
+	else {
+		os << value.describe() << ends;
+	}
+	char *s = os.str();
+	int padding=maxwidth-strlen(s);
+	while (pad && padding-- > 0) ostr << pad;
+	ostr << s;
+	if (s) delete[] s;
+}
+
+void
+putIeeeFloat32WithDescription(ostream& ostr,Parameters& params,
+		char byteorder,unsigned long offset,IeeeFloat32 value)
+{
+	int show;
+
+	if (params.restricted) {
+		if (value.isZero()) {
+			show=1;
+		}
+		else if (value.isNumber()) {
+			double avalue = fabs(value.getValue());
+			show = avalue < (double)params.restrictionvalue
+			    && avalue > ReasonableMinimumFloatToShow;
+		}
+		else
+			show=0;
+	}
+	else
+		show=1;
+
+	if (show) {
+		putDescriptor(ostr,params,byteorder,offset,"f_ieee32");
+		putIeeeFloat32(ostr,params,value,' ');
+		ostr << "\n";
+	}
+}
+
+void
+putIeeeFloat64WithDescription(ostream& ostr,Parameters& params,
+		char byteorder,unsigned long offset,IeeeFloat64 value)
+{
+	int show;
+
+	if (params.restricted) {
+		if (value.isZero()) {
+			show=1;
+		}
+		else if (value.isNumber()) {
+			double avalue = fabs(value.getValue());
+			show = avalue < (double)params.restrictionvalue
+			    && avalue > ReasonableMinimumFloatToShow;
+		}
+		else
+			show=0;
+	}
+	else
+		show=1;
+
+	if (show) {
+		putDescriptor(ostr,params,byteorder,offset,"f_ieee64");
+		putIeeeFloat64(ostr,params,value,' ');
+		ostr << "\n";
+	}
+}
+
+void
+putVaxFloat_FWithDescription(ostream& ostr,Parameters& params,
+		char byteorder,unsigned long offset,VaxFloat_F value)
+{
+	int show;
+
+	if (params.restricted) {
+		if (value.isZero()) {
+			show=1;
+		}
+		else if (value.isNumber()) {
+			double avalue = fabs(value.getValue());
+			show = avalue < (double)params.restrictionvalue
+			    && avalue > ReasonableMinimumFloatToShow;
+		}
+		else
+			show=0;
+	}
+	else
+		show=1;
+
+	if (show) {
+		putDescriptor(ostr,params,byteorder,offset,"f_vax_f ");
+		putVaxFloat_F(ostr,params,value,' ');
+		ostr << "\n";
+	}
+}
+
+int
+tryIeeeFloat32(Buffer& buffer,char byteorder,IeeeFloat32& rvalue)
+{
+	Uint32 binary;
+	if (tryUint32(buffer,byteorder,binary)) {
+		IeeeFloat32 value(binary);
+		rvalue=value;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+int
+tryIeeeFloat64(Buffer& buffer,char byteorder,IeeeFloat64& rvalue)
+{
+	Uint32 high,low;
+	if (tryUint64(buffer,byteorder,high,low)) {
+		IeeeFloat64 value(high,low);
+		rvalue=value;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+int
+tryVaxFloat_F(Buffer& buffer,char byteorder,VaxFloat_F& rvalue)
+{
+	Uint32 binary;
+	if (tryUint32(buffer,byteorder,binary)) {
+		VaxFloat_F value(binary);
+		rvalue=value;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+void
+checkieeefloat(Buffer& buffer,ostream& ostr,char byteorder,Parameters& params)
+{
+	unsigned long offset=buffer.getOffset();
+
+	if (offset%8 == 0) {
+		IeeeFloat64 value;
+		if (tryIeeeFloat64(buffer,byteorder,value)) {
+			putIeeeFloat64WithDescription(
+				ostr,params,byteorder,offset,value);
+		}
+	}
+	if (offset%4 == 0) {
+		IeeeFloat32 value;
+		if (tryIeeeFloat32(buffer,byteorder,value)) {
+			putIeeeFloat32WithDescription(
+				ostr,params,byteorder,offset,value);
+		}
+	}
+}
+
+void
+checkvaxfloat(Buffer& buffer,ostream& ostr,char byteorder,Parameters& params)
+{
+	unsigned long offset=buffer.getOffset();
+
+	if (offset%4 == 0) {
+		VaxFloat_F value;
+		if (tryVaxFloat_F(buffer,byteorder,value)) {
+			putVaxFloat_FWithDescription(
+				ostr,params,byteorder,offset,value);
+		}
+	}
+}
+
+int
+checkstrings(Buffer& buffer,ostream& ostr,Parameters& params,
+	unsigned minstrlen,unsigned maxstrlen)
+{
+	static unsigned lengthleft=0;	// remember state between calls
+
+	if (lengthleft) --lengthleft;
+
+	if (!lengthleft) {
+		unsigned test;
+		for (test=0; test < maxstrlen; ++test) {
+			const unsigned char *ptr=buffer.readLookAhead(test+1);
+			if (!ptr || !isprint(ptr[test])) break;
+		}
+		if (test >= minstrlen) {
+			lengthleft=test;
+
+			unsigned long offset=buffer.getOffset();
+			putOffsetRange(ostr,params,offset,offset+test-1);
+			if (params.showtype) {
+				if (params.showkey) ostr << "type=\"";
+				ostr << "string";
+				if (params.showkey) ostr << "\"";
+				ostr << " ";
+			}
+
+			if (params.showkey) ostr << "length=\"";
+			else ostr << "(";
+			putDecInteger(ostr,params,2,test,'\0');
+			if (params.showkey) ostr << "\"";
+			else ostr << ")";
+			ostr << " ";
+
+			const unsigned char *ptr=buffer.readLookAhead(test);
+			if (ptr) {
+				char *s = new char [test+1];
+				strncpy(s,(const char *)ptr,test); s[test]=0;
+				ostr << "\"" << s << "\"\n";
+			}
+			else {
+				cerr << "checkstrings: Assertion failed"
+				     << "ptr should not be zero\n" << flush;
+				exit(1);
+			}
+		}
+		else {
+			lengthleft=0;
+		}
+	}
+	return lengthleft;
+}
+
+int
+elide(Buffer& buffer,ostream& ostr,
+	Parameters& params,unsigned char value,char *desc,
+	unsigned minrunlength)
+{
+	const unsigned char *ptr=buffer.readLookAhead(minrunlength);
+
+	if (ptr) {
+		while (minrunlength--)
+			if (ptr[minrunlength] != value) return 0;
+		unsigned long count=0;
+		unsigned long startposn=buffer.getOffset();
+		while ((ptr=buffer.readLookAhead(1)) && *ptr == value) {
+			buffer.read(1);
+			++count;
+		}
+		if (params.elidereport) {
+			putOffsetRange(ostr,params,
+				startposn,buffer.getOffset()-1);
+
+			if (params.showkey) ostr << "type=\"";
+			ostr << desc;
+			if (params.showkey) ostr << "\"";
+			ostr << " ";
+
+			if (params.showkey) ostr << "length=\"";
+			else ostr << "(";
+			putDecInteger(ostr,params,2,count,'\0');
+			if (params.showkey) ostr << "\"";
+			else ostr << ")";
+			ostr << "\n";
+		}
+	}
+	else
+		return 0;
+}
+
+int
+main(int argc,char **argv)
+{
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+
+	Parameters params;	// sets up some default values also
+
+	bool foundoption=false;
+
+	// should be more selective about when foundoption gets set
+
+	if (options.get("all") || options.get("a")) {
+		foundoption=true;
+		params.bigendian=true;
+		params.littleendian=true;
+		params.showhex=true;
+		params.showdec=true;
+		params.showoct=true;
+		params.showieeefloat=true;
+		params.showvaxfloat=true;
+		params.showstrings=true;
+		params.showchars=true;
+		params.show1=true;
+		params.show2=true;
+		params.show4=true;
+		params.showtype=true;
+	}
+
+	foundoption=(params.bigendian		=options.get("big") 		|| options.get("b")) || foundoption;
+	foundoption=(params.littleendian	=options.get("little") 		|| options.get("l")) || foundoption;
+	foundoption=(params.showchars		=options.get("chars") 		|| options.get("c")) || foundoption;
+	foundoption=(params.showdec		=options.get("dec") 		|| options.get("d")) || foundoption;
+	foundoption=(params.showoct		=options.get("oct") 		|| options.get("o")) || foundoption;
+	foundoption=(params.showieeefloat	=options.get("float") 		|| options.get("f")) || foundoption;
+	foundoption=(params.showvaxfloat	=options.get("vax") 		|| options.get("v")) || foundoption;
+	foundoption=(params.showhex		=options.get("hex") 		|| options.get("h") || options.get("x")) || foundoption;
+	foundoption=(params.showkey		=options.get("key") 		|| options.get("k")) || foundoption;
+	foundoption=(params.shownegative	=options.get("neg") 		|| options.get("n")) || foundoption;
+	foundoption=(params.showaddress		=options.get("position") 	|| options.get("p")) || foundoption;
+	foundoption=(params.showstrings		=options.get("strings") 	|| options.get("s")) || foundoption;
+	foundoption=(params.showstringcontents	=options.get("stringcontent") 	|| options.get("w")) || foundoption;
+	foundoption=(params.showtype		=options.get("type") 		|| options.get("t")) || foundoption;
+	foundoption=(params.show1		=options.get("byte") 		|| options.get("1")) || foundoption;
+	foundoption=(params.show2		=options.get("short") 		|| options.get("2")) || foundoption;
+	foundoption=(params.show4		=options.get("long") 		|| options.get("4")) || foundoption;
+
+	foundoption=(params.usecerr		=options.get("cerr") 		|| options.get("e")) || foundoption;
+
+	if (options.get("noreport") || options.get("n")) {
+		foundoption=true;
+		params.elidereport=false;
+	}
+
+	if (options.get("showzeroes") || options.get("z")) {
+		foundoption=true;
+		params.elidezeroes=false;
+		params.elidespaces=false;
+	}
+
+	foundoption=(options.get("jump",params.jumpbytes) || options.get("j",params.jumpbytes)) || foundoption;
+	foundoption=(options.get("max",params.maxbytes) || options.get("m",params.maxbytes)) || foundoption;
+	foundoption=(params.restricted=options.get("restrict",params.restrictionvalue) || options.get("r",params.restrictionvalue)) || foundoption;
+	foundoption=(options.get("stringlength",params.stringlength) || options.get("y",params.stringlength)) || foundoption;
+
+	if (!foundoption) {		// default behaviour
+		params.showdec=1;
+		params.showchars=1;
+		params.show1=1;
+		params.showaddress=1;
+	}
+
+	bool bad=false;
+
+	if ((params.show2 || params.show4 || params.showieeefloat) && !(params.littleendian || params.bigendian)) {
+		cerr << "Must specify byte order -l or -b for -2,-4,-f" << endl;
+		bad=true;
+	}
+
+	if ( (params.show1 || params.show2 || params.show4) && !(params.showdec || params.showoct || params.showhex)
+	 || !(params.show1 || params.show2 || params.show4) &&  (params.showdec || params.showoct || params.showhex)) {
+		cerr << "Must specify -o,-d or -h for -1,-2 or -4" << endl;
+		bad=true;
+	}
+
+	params.dump(cerr);
+
+	input_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(options,input_options.filename,cin);
+
+	cerr << input_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+
+	if (!input_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< " [-a -b -c -d -e -f -h -j skipbytes"
+			<< " -k -l -m maxbytes -n -o -p -r restrictvalue"
+			<< " -s -t -v -w -x -y -z -1 -2 -4]"
+			<< " [" << MMsgDC(InputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream instream(input_opener);
+
+	ostream *outstream=params.usecerr ? &cerr : &cout;
+
+	// *************** Actually do something ***************
+
+	Buffer buffer(&instream,params.jumpbytes,params.maxbytes);
+
+	while (buffer.isMore()) {
+		if (params.elidezeroes
+		 && elide(buffer,*outstream,params,0,"zeroes",params.stringlength))
+			continue;
+		if (params.elidespaces
+		 && elide(buffer,*outstream,params,' ',"spaces",params.stringlength))
+			continue;
+
+		if (!params.showstrings
+		 || !checkstrings(buffer,*outstream,params,4,params.stringlength)
+		 || params.showstringcontents) {
+			if (params.bigendian) {
+				checkbinary(buffer,*outstream,'B',params);
+				if (params.showieeefloat)
+					checkieeefloat(buffer,
+						*outstream,'B',params);
+				if (params.showvaxfloat)
+					checkvaxfloat(buffer,
+						*outstream,'B',params);
+			}
+			if (params.littleendian) {
+				checkbinary(buffer,*outstream,'L',params);
+				if (params.showieeefloat)
+					checkieeefloat(buffer,
+						*outstream,'L',params);
+				if (params.showvaxfloat)
+					checkvaxfloat(buffer,
+						*outstream,'L',params);
+			}
+			if (params.show1)
+				checkbinarybyte(buffer,*outstream,params);
+			if (params.showchars)
+				checkchars(buffer,*outstream,params,'.');
+		}
+		buffer.read(1);
+	}
+
+	return 0;
+}
diff --git a/appsrc/misc/dumpwhat.man b/appsrc/misc/dumpwhat.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/gethttp.cc b/appsrc/misc/gethttp.cc
new file mode 100644
index 0000000..f3af14e
--- /dev/null
+++ b/appsrc/misc/gethttp.cc
@@ -0,0 +1,283 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gethttp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>
+#else
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "ntstream.h"
+#include "getoptns.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static void
+choptrailing(char *p)
+{
+//cerr << "choptrailing: start <" << p << ">" << endl;
+	char *end;
+	for (end=p+strlen(p)-1;
+		end >= p && (*end == 0
+			|| *end == '\n'
+			|| *end == '\r'
+			|| *end == '\t'
+			|| *end == ' ')
+			; --end) {
+//cerr << "choptrailing: chopping <" << *end << ">" << endl;
+		*end=0;
+	}
+//cerr << "choptrailing: end <" << p << ">" << endl;
+}
+
+static bool
+statusparse(char *src,char *&version,char *&code,char *&reason)
+{
+	bool success=false;
+
+	// HTTP 1.0: Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
+	// HTTP 1.0: "HTTP/" 1*DIGIT "." 1*DIGIT SP 3DIGIT SP
+	if (strstr(src,"HTTP/") == src && isdigit(src[5]) && src[6] == '.' && isdigit(src[7])) {
+		success=true;
+		version=src+5;
+		src[8]=0;
+
+		code=src+9;
+		char *p=code;
+		while (isdigit(*p)) ++p;
+		reason=p;
+		while (*reason == ' ' || *reason == '\t') ++reason;
+		*p=0;	// terminate code AFTER finding start of reason
+	}
+	// else HTTP 1.0: May be HTTP 0.9 simple response
+
+	if (!success) {
+		version=0;
+		code=0;
+		reason=0;
+	}
+	return success;
+}
+
+static char *
+trtolower(char *p)
+{
+	char *self=p;
+	if (p) {
+		--p;
+		while (*++p) if (isupper(*p)) *p=tolower(*p);
+	}
+	return self;
+}
+
+static bool
+headerparse(char *src,char *&key,char *&args)
+{
+	bool success=false;
+
+	key=src;
+	while (*key == ' ' || *key == '\t') ++key;
+	char *p=key;
+	while (*p && (isalpha(*p) || *p == '-')) ++p;
+	if (*p == ':') {
+		success=true;
+
+		*p=0;
+		args=p+1;
+		while (*args == ' ' || *args == '\t') ++args;
+	}
+
+	if (!success) {
+		key=0;
+		args=0;
+	}
+	return success;
+}
+
+static char *
+nextword(char *start,char **next=0)
+{
+	while (*start == ' ' || *start == '\t') ++start;
+	char *end=start;
+	while (*end && *end != ' ' && *end != '\t') ++end;
+	if (next) *next=*end ? end+1 : 0;
+	*end=0;
+	return start;
+}
+
+int
+main(int argc, char *argv[])
+{
+	bool bad=false;
+
+	GetNamedOptions options(argc,argv);
+	bool verbose=options.get("verbose") || options.get("v");
+	bool progress=options.get("progress") || options.get("p");
+
+	const char *host;
+	const char *port;
+	const char *path;
+
+	if (!options == 3) {
+		host=options[0];
+		port=options[1];
+		path=options[2];
+	}
+	else
+		bad=true;
+
+	options.done();
+	cerr << options.errors();
+
+	if (!options.good() || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< " [-v|-verbose]"
+			<< " [-p|-progress]"
+			<< " host port path"
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		return 1;
+	}
+
+	const size_t netbuflng=REPLACESTANDARDIOBUFSIZE;
+	char *netbuf=new char[netbuflng];
+	Assert(netbuf);
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+	inetstream in(host,port,"tcp",ios::in|ios::binary);
+#else
+	inetstream in(host,port,"tcp");
+#endif
+	in.setbuf(netbuf,netbuflng);
+	// There is no netstream class that does bidirectional i/o ...
+	ostream out(in.rdbuf());
+	in.tie(&out);		// this is necessary if interactive
+
+	if (!in.good()) {
+		cerr << "Read open failed" << endl;
+		return 1;
+	}
+	if (!out.good()) {
+		cerr << "Write open failed" << endl;
+		return 1;
+	}
+
+	out << "GET " << (path ? path : "/") << " HTTP/1.0\r\n\r" << endl;
+
+	// HHTP 1.0: the length of a line is not limited :(
+	const size_t buflng=REPLACESTANDARDIOBUFSIZE;
+	char *buffer=new char[buflng];
+	Assert(buffer);
+
+	unsigned lines=0;
+	char *statusversion,*statuscode,*statusreason;
+	char *contenttype=0;
+	char *contentlength=0;
+	char *contentencoding=0;
+	while (1) {
+		if (!in.getline(buffer,buflng,'\n')) {
+			cerr << "Error - End of input in Head" << endl;
+			return 1;
+		}
+		choptrailing(buffer);
+		char *headerkey,*headerargs;
+
+		if (!strlen(buffer)) {
+			// HHTP 1.0: Empty line ends head
+			if (lines) {
+				if (verbose) cerr << "End of Head" << endl;
+				break;	// Only good way out of loop
+			}
+			else {
+				cerr << "Error - Empty Head :(" << endl;
+				return 1;
+			}
+		}
+		else if (++lines == 1) {
+			// HHTP 1.0: Must be status line
+			char *sversion,*scode,*sreason;
+			if (statusparse(buffer,sversion,scode,sreason)) {
+				statusversion=strdup(sversion);
+				statuscode=strdup(scode);
+				statusreason=strdup(sreason);
+				if (verbose) cerr << "Full Response Status: version=<" << statusversion << "> code=<" << statuscode << "> reason=<" << statusreason << ">" << endl;
+			}
+			else {
+				if (verbose) cerr << "Simple Response: <" << buffer << ">" << endl;
+			}
+		}
+		else if (*buffer == ' ' || *buffer == '\t') {
+			// HHTP 1.0: continuation lines not implemented :(
+			if (verbose) cerr << "Continue: <" << buffer << ">" << endl;
+		}
+		else if (headerparse(buffer,headerkey,headerargs)) {
+			trtolower(headerkey);
+			if (verbose) cerr << "Header: key=<" << headerkey << "> args=<" << headerargs << ">" << endl;
+			if      (strcmp(headerkey,"content-type") == 0) contenttype=strdup(trtolower(nextword(headerargs)));
+			else if (strcmp(headerkey,"content-length") == 0) contentlength=strdup(nextword(headerargs));
+			else if (strcmp(headerkey,"content-encoding") == 0) contentencoding=strdup(trtolower(nextword(headerargs)));
+		}
+		else {
+			cerr << "Other:  <" << buffer << ">" << endl;
+		}
+	}
+
+	if (verbose) cerr << "statusversion <" << (statusversion ? statusversion : "-NONE-") << ">" << endl;
+	if (verbose) cerr << "statuscode <" << (statuscode ? statuscode : "-NONE-") << ">" << endl;
+	if (verbose) cerr << "statusreason <" << (statusreason ? statusreason : "-NONE-") << ">" << endl;
+	if (verbose) cerr << "contenttype <" << (contenttype ? contenttype : "-NONE-") << ">" << endl;
+	if (verbose) cerr << "contentlength <" << (contentlength ? contentlength : "-NONE-") << ">" << endl;
+	if (verbose) cerr << "contentencoding <" << (contentencoding ? contentencoding : "-NONE-") << ">" << endl;
+
+	if (!statuscode || atoi(statuscode) != 200) {
+		cerr << "Error - bad status code <"
+		     << (statuscode ? statuscode : "-NONE-") << "> reason <"
+		     << (statusreason ? statusreason : "-NONE-") << "> for path <"
+		     << (path ? path : "-NONE-") << ">"
+		     << endl;
+		return 1;
+	}
+
+	long length;
+	if (!contentlength || !(length=atol(contentlength))) {
+		cerr << "Error - bad Content-length <" << (contentlength ? contentlength : "-NONE-") << ">" << endl;
+		return 1;
+	}
+
+	while (length > 0) {
+		int wanted=int(length > buflng ? buflng : length);
+		in.read(buffer,wanted);
+		int got=in.gcount();
+		if (got) in.clear();	// blech :( Don't ask !
+		if (progress)
+			cerr << "length=" << length << " wanted=" << wanted << " got=" << got << "          \r" << flush;
+		if (in.fail()) {
+			if (progress) cerr << endl;
+			cerr << "Error - premature EOF - " << length << " remaining" << endl;
+			return 1;
+		}
+		cout.write(buffer,got);
+		length-=got;
+	}
+	if (progress) cerr << endl;
+	if (verbose) cerr << "Done" << endl;
+
+	if (buffer) delete[] buffer;
+	if (netbuf) delete[] netbuf;
+
+	// strdup() probably uses malloc/free(rather than new[]/delete[] ...
+	if (statusversion) free(statusversion);
+	if (statuscode) free(statuscode);
+	if (statusreason) free(statusreason);
+	if (contenttype) free(contenttype);
+	if (contentlength) free(contentlength);
+	if (contentencoding) free(contentencoding);
+
+	return 0;
+}
+
diff --git a/appsrc/misc/gethttp.man b/appsrc/misc/gethttp.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/gethttp.test.sh b/appsrc/misc/gethttp.test.sh
new file mode 100755
index 0000000..3b64ec7
--- /dev/null
+++ b/appsrc/misc/gethttp.test.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+HTTPSERVER=flash
+HTTPPORT=80
+HTTPPATH=pub
+LOCALPATH=/usr1/ftp
+
+for i in `(cd $LOCALPATH; find $HTTPPATH -type f -print)`
+do
+	if gethttp $* $HTTPSERVER $HTTPPORT /$i >/tmp/crap
+	then
+		cmp $LOCALPATH/$i /tmp/crap
+		if [ ! $? ]
+		then
+			echo "$0: compare failed on $i"
+		fi
+	else
+		echo "$0: gethttp failed on $i"
+	fi
+done
diff --git a/appsrc/misc/jpegdump.cc b/appsrc/misc/jpegdump.cc
new file mode 100644
index 0000000..a49e591
--- /dev/null
+++ b/appsrc/misc/jpegdump.cc
@@ -0,0 +1,1168 @@
+static const char *CopyrightIdentifier(void) { return "@(#)jpegdump.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "txstream.h"
+
+const Uint16 JPEG_MARKER_APP0 = 0xffe0;
+const Uint16 JPEG_MARKER_APP1 = 0xffe1;
+const Uint16 JPEG_MARKER_APP2 = 0xffe2;
+const Uint16 JPEG_MARKER_APP3 = 0xffe3;
+const Uint16 JPEG_MARKER_APP4 = 0xffe4;
+const Uint16 JPEG_MARKER_APP5 = 0xffe5;
+const Uint16 JPEG_MARKER_APP6 = 0xffe6;
+const Uint16 JPEG_MARKER_APP7 = 0xffe7;
+const Uint16 JPEG_MARKER_APP8 = 0xffe8;
+const Uint16 JPEG_MARKER_APP9 = 0xffe9;
+const Uint16 JPEG_MARKER_APPA = 0xffea;
+const Uint16 JPEG_MARKER_APPB = 0xffeb;
+const Uint16 JPEG_MARKER_APPC = 0xffec;
+const Uint16 JPEG_MARKER_APPD = 0xffed;
+const Uint16 JPEG_MARKER_APPE = 0xffee;
+const Uint16 JPEG_MARKER_APPF = 0xffef;
+
+const Uint16 JPEG_MARKER_COM = 0xfffe;
+const Uint16 JPEG_MARKER_DAC = 0xffcc;
+const Uint16 JPEG_MARKER_DHP = 0xffde;
+const Uint16 JPEG_MARKER_DHT = 0xffc4;
+const Uint16 JPEG_MARKER_DNL = 0xffdc;
+const Uint16 JPEG_MARKER_DQT = 0xffdb;
+const Uint16 JPEG_MARKER_DRI = 0xffdd;
+const Uint16 JPEG_MARKER_EOI = 0xffd9;          // also JPEG 2000 "EOC"
+const Uint16 JPEG_MARKER_EXP = 0xffdf;
+
+const Uint16 JPEG_MARKER_JPG = 0xffc8;
+
+// left out reserved JPGn and RES
+// (especially those with first bit (not just byte) zero ... new LS 0 stuffing)
+
+const Uint16 JPEG_MARKER_RST0 = 0xffd0;
+const Uint16 JPEG_MARKER_RST1 = 0xffd1;
+const Uint16 JPEG_MARKER_RST2 = 0xffd2;
+const Uint16 JPEG_MARKER_RST3 = 0xffd3;
+const Uint16 JPEG_MARKER_RST4 = 0xffd4;
+const Uint16 JPEG_MARKER_RST5 = 0xffd5;
+const Uint16 JPEG_MARKER_RST6 = 0xffd6;
+const Uint16 JPEG_MARKER_RST7 = 0xffd7;
+
+const Uint16 JPEG_MARKER_SOF0 = 0xffc0;
+const Uint16 JPEG_MARKER_SOF1 = 0xffc1;
+const Uint16 JPEG_MARKER_SOF2 = 0xffc2;
+const Uint16 JPEG_MARKER_SOF3 = 0xffc3;
+
+const Uint16 JPEG_MARKER_SOF5 = 0xffc5;
+const Uint16 JPEG_MARKER_SOF6 = 0xffc6;
+const Uint16 JPEG_MARKER_SOF7 = 0xffc7;
+
+const Uint16 JPEG_MARKER_SOF9 = 0xffc9;
+const Uint16 JPEG_MARKER_SOFA = 0xffca;
+const Uint16 JPEG_MARKER_SOFB = 0xffcb;
+
+const Uint16 JPEG_MARKER_SOFD = 0xffcd;
+const Uint16 JPEG_MARKER_SOFE = 0xffce;
+const Uint16 JPEG_MARKER_SOFF = 0xffcf;
+
+const Uint16 JPEG_MARKER_SOI = 0xffd8;
+const Uint16 JPEG_MARKER_SOS = 0xffda;
+const Uint16 JPEG_MARKER_TEM = 0xff01;
+
+// New for JPEG-LS (14495-1:1997)
+
+const Uint16 JPEG_MARKER_SOF55 = 0xfff7;
+const Uint16 JPEG_MARKER_LSE   = 0xfff8;
+
+const unsigned char JPEG_LSE_ID_L1   = 0x01;
+const unsigned char JPEG_LSE_ID_L2   = 0x02;
+const unsigned char JPEG_LSE_ID_L3   = 0x03;
+const unsigned char JPEG_LSE_ID_L4   = 0x04;
+
+// New for JPEG 2000 (15444-1:2000)
+
+const Uint16 JPEG_MARKER_SOC = 0xff4f;
+const Uint16 JPEG_MARKER_SOT = 0xff90;
+const Uint16 JPEG_MARKER_SOD = 0xff93;
+//const Uint16 JPEG_MARKER_EOC = 0xffd9;        // same as JPEG EOI
+const Uint16 JPEG_MARKER_SIZ = 0xff51;
+const Uint16 JPEG_MARKER_COD = 0xff52;
+const Uint16 JPEG_MARKER_COC = 0xff53;
+const Uint16 JPEG_MARKER_RGN = 0xff5e;
+const Uint16 JPEG_MARKER_QCD = 0xff5c;
+const Uint16 JPEG_MARKER_QCC = 0xff5d;
+const Uint16 JPEG_MARKER_POC = 0xff5f;
+const Uint16 JPEG_MARKER_TLM = 0xff55;
+const Uint16 JPEG_MARKER_PLM = 0xff57;
+const Uint16 JPEG_MARKER_PLT = 0xff58;
+const Uint16 JPEG_MARKER_PPM = 0xff60;
+const Uint16 JPEG_MARKER_PPT = 0xff61;
+const Uint16 JPEG_MARKER_SOP = 0xff91;
+const Uint16 JPEG_MARKER_EPH = 0xff92;
+const Uint16 JPEG_MARKER_CRG = 0xff63;
+const Uint16 JPEG_MARKER_COM2K = 0xff64;
+
+const Uint16 JPEG_MARKER_FF30 = 0xff30;
+const Uint16 JPEG_MARKER_FF31 = 0xff31;
+const Uint16 JPEG_MARKER_FF32 = 0xff32;
+const Uint16 JPEG_MARKER_FF33 = 0xff33;
+const Uint16 JPEG_MARKER_FF34 = 0xff34;
+const Uint16 JPEG_MARKER_FF35 = 0xff35;
+const Uint16 JPEG_MARKER_FF36 = 0xff36;
+const Uint16 JPEG_MARKER_FF37 = 0xff37;
+const Uint16 JPEG_MARKER_FF38 = 0xff38;
+const Uint16 JPEG_MARKER_FF39 = 0xff39;
+const Uint16 JPEG_MARKER_FF3A = 0xff3a;
+const Uint16 JPEG_MARKER_FF3B = 0xff3b;
+const Uint16 JPEG_MARKER_FF3C = 0xff3c;
+const Uint16 JPEG_MARKER_FF3D = 0xff3d;
+const Uint16 JPEG_MARKER_FF3E = 0xff3e;
+const Uint16 JPEG_MARKER_FF3F = 0xff3f;
+
+
+Uint16 isFixedLengthJPEGSegment(Uint16 marker)
+{
+	Uint16 length;
+	switch (marker) {
+		case JPEG_MARKER_EXP:
+			length=3; break;
+		default:
+			length=0; break;
+	}
+	return length;
+}
+
+bool isNoLengthJPEGSegment(Uint16 marker)
+{
+	bool nolength;
+	switch (marker) {
+	case JPEG_MARKER_SOI:
+	case JPEG_MARKER_EOI:
+	case JPEG_MARKER_TEM:
+	case JPEG_MARKER_RST0:
+	case JPEG_MARKER_RST1:
+	case JPEG_MARKER_RST2:
+	case JPEG_MARKER_RST3:
+	case JPEG_MARKER_RST4:
+	case JPEG_MARKER_RST5:
+	case JPEG_MARKER_RST6:
+	case JPEG_MARKER_RST7:
+        case JPEG_MARKER_FF30:
+        case JPEG_MARKER_FF31:
+        case JPEG_MARKER_FF32:
+        case JPEG_MARKER_FF33:
+        case JPEG_MARKER_FF34:
+        case JPEG_MARKER_FF35:
+        case JPEG_MARKER_FF36:
+        case JPEG_MARKER_FF37:
+        case JPEG_MARKER_FF38:
+        case JPEG_MARKER_FF39:
+        case JPEG_MARKER_FF3A:
+        case JPEG_MARKER_FF3B:
+        case JPEG_MARKER_FF3C:
+        case JPEG_MARKER_FF3D:
+        case JPEG_MARKER_FF3E:
+        case JPEG_MARKER_FF3F:
+        case JPEG_MARKER_SOC:
+        case JPEG_MARKER_SOD:
+        //case JPEG_MARKER_EOC:         // same as JPEG EOI
+        case JPEG_MARKER_EPH:
+				nolength=true; break;
+	default:
+				nolength=false; break;
+	}
+	return nolength;
+}
+
+bool isVariableLengthJPEGSegment(Uint16 marker)
+{
+	return !isNoLengthJPEGSegment(marker) && !isFixedLengthJPEGSegment(marker);
+}
+
+struct JPEGMarkerDictionaryEntry {
+	Uint16 markercode;
+	const char *abbreviation;
+	const char *description;
+} JPEGMarkerDictionaryTable[] = {
+	JPEG_MARKER_APP0, "APP0", "Reserved for Application Use",
+	JPEG_MARKER_APP1, "APP1", "Reserved for Application Use",
+	JPEG_MARKER_APP2, "APP2", "Reserved for Application Use",
+	JPEG_MARKER_APP3, "APP3", "Reserved for Application Use",
+	JPEG_MARKER_APP4, "APP4", "Reserved for Application Use",
+	JPEG_MARKER_APP5, "APP5", "Reserved for Application Use",
+	JPEG_MARKER_APP6, "APP6", "Reserved for Application Use",
+	JPEG_MARKER_APP7, "APP7", "Reserved for Application Use",
+	JPEG_MARKER_APP8, "APP8", "Reserved for Application Use",
+	JPEG_MARKER_APP9, "APP9", "Reserved for Application Use",
+	JPEG_MARKER_APPA, "APPA", "Reserved for Application Use",
+	JPEG_MARKER_APPB, "APPB", "Reserved for Application Use",
+	JPEG_MARKER_APPC, "APPC", "Reserved for Application Use",
+	JPEG_MARKER_APPD, "APPD", "Reserved for Application Use",
+	JPEG_MARKER_APPE, "APPE", "Reserved for Application Use",
+	JPEG_MARKER_APPF, "APPF", "Reserved for Application Use",
+
+	JPEG_MARKER_COM, "COM", "Comment",
+	JPEG_MARKER_DAC, "DAC", "Define Arithmetic Conditioning Table(s)",
+	JPEG_MARKER_DHP, "DHP", "Define Hierarchical Progression",
+	JPEG_MARKER_DHT, "DHT", "Define Huffman Table(s)",
+	JPEG_MARKER_DNL, "DNL", "Define Number of Lines",
+	JPEG_MARKER_DQT, "DQT", "Define Quantization Table(s)",
+	JPEG_MARKER_DRI, "DRI", "Define Restart Interval",
+	JPEG_MARKER_EOI, "EOI", "End of Image (JPEG 2000 EOC End of codestream)",
+	JPEG_MARKER_EXP, "EXP", "Expand Reference Image(s)",
+
+	JPEG_MARKER_JPG, "JPG", "Reserved for JPEG extensions",
+
+	JPEG_MARKER_RST0, "RST0", "Restart with modulo 8 counter 0",
+	JPEG_MARKER_RST1, "RST1", "Restart with modulo 8 counter 1",
+	JPEG_MARKER_RST2, "RST2", "Restart with modulo 8 counter 2",
+	JPEG_MARKER_RST3, "RST3", "Restart with modulo 8 counter 3",
+	JPEG_MARKER_RST4, "RST4", "Restart with modulo 8 counter 4",
+	JPEG_MARKER_RST5, "RST5", "Restart with modulo 8 counter 5",
+	JPEG_MARKER_RST6, "RST6", "Restart with modulo 8 counter 6",
+	JPEG_MARKER_RST7, "RST7", "Restart with modulo 8 counter 7",
+
+	JPEG_MARKER_SOF0, "SOF0", "Huffman Baseline DCT",
+	JPEG_MARKER_SOF1, "SOF1", "Huffman Extended Sequential DCT",
+	JPEG_MARKER_SOF2, "SOF2", "Huffman Progressive DCT",
+	JPEG_MARKER_SOF3, "SOF3", "Huffman Lossless Sequential",
+	JPEG_MARKER_SOF5, "SOF5", "Huffman Differential Sequential DCT",
+	JPEG_MARKER_SOF6, "SOF6", "Huffman Differential Progressive DCT",
+	JPEG_MARKER_SOF7, "SOF7", "Huffman Differential Lossless",
+	JPEG_MARKER_SOF9, "SOF9", "Arithmetic Extended Sequential DCT",
+	JPEG_MARKER_SOFA, "SOFA", "Arithmetic Progressive DCT",
+	JPEG_MARKER_SOFB, "SOFB", "Arithmetic Lossless Sequential",
+	JPEG_MARKER_SOFD, "SOFD", "Arithmetic Differential Sequential DCT",
+	JPEG_MARKER_SOFE, "SOFE", "Arithmetic Differential Progressive DCT",
+	JPEG_MARKER_SOFF, "SOFF", "Arithmetic Differential Lossless",
+
+	JPEG_MARKER_SOF55, "SOF55", "LS",
+
+	JPEG_MARKER_SOI, "SOI", "Start of Image",
+	JPEG_MARKER_SOS, "SOS", "Start of Scan",
+	JPEG_MARKER_TEM, "TEM", "Temporary use with Arithmetic Encoding",
+
+        JPEG_MARKER_SOC, "SOC", "Start of codestream",
+        JPEG_MARKER_SOT, "SOT", "Start of tile-part",
+        JPEG_MARKER_SOD, "SOD", "Start of data",
+        //JPEG_MARKER_EOC, "EOC", "End of codestream",          // same as JPEG EOI
+        JPEG_MARKER_SIZ, "SIZ", "Image and tile size",
+        JPEG_MARKER_COD, "COD", "Coding style default",
+        JPEG_MARKER_COC, "COC", "Coding style component",
+        JPEG_MARKER_RGN, "RGN", "Rgeion-of-interest",
+        JPEG_MARKER_QCD, "QCD", "Quantization default",
+        JPEG_MARKER_QCC, "QCC", "Quantization component",
+        JPEG_MARKER_POC, "POC", "Progression order change",
+        JPEG_MARKER_TLM, "TLM", "Tile-part lengths",
+        JPEG_MARKER_PLM, "PLM", "Packet length, main header",
+        JPEG_MARKER_PLT, "PLT", "Packet length, tile-part header",
+        JPEG_MARKER_PPM, "PPM", "Packet packer headers, main header",
+        JPEG_MARKER_PPT, "PPT", "Packet packer headers, tile-part header",
+        JPEG_MARKER_SOP, "SOP", "Start of packet",
+        JPEG_MARKER_EPH, "EPH", "End of packet header",
+        JPEG_MARKER_CRG, "CRG", "Component registration",
+        JPEG_MARKER_COM2K, "COM", "Comment (JPEG 2000)",
+
+        JPEG_MARKER_FF30, "FF30", "Reserved",
+        JPEG_MARKER_FF31, "FF31", "Reserved",
+        JPEG_MARKER_FF32, "FF32", "Reserved",
+        JPEG_MARKER_FF33, "FF33", "Reserved",
+        JPEG_MARKER_FF34, "FF34", "Reserved",
+        JPEG_MARKER_FF35, "FF35", "Reserved",
+        JPEG_MARKER_FF36, "FF36", "Reserved",
+        JPEG_MARKER_FF37, "FF37", "Reserved",
+        JPEG_MARKER_FF38, "FF38", "Reserved",
+        JPEG_MARKER_FF39, "FF39", "Reserved",
+        JPEG_MARKER_FF3A, "FF3A", "Reserved",
+        JPEG_MARKER_FF3B, "FF3B", "Reserved",
+        JPEG_MARKER_FF3C, "FF3C", "Reserved",
+        JPEG_MARKER_FF3D, "FF3D", "Reserved",
+        JPEG_MARKER_FF3E, "FF3E", "Reserved",
+        JPEG_MARKER_FF3F, "FF3F", "Reserved",
+
+        0, 0, 0
+};
+
+class JPEGMarkerDictionary {
+public:
+	JPEGMarkerDictionary() {}
+
+	bool getEntry(Uint16 code,const char * &abbreviation,const char * &description) const
+		{
+			JPEGMarkerDictionaryEntry *ptr=JPEGMarkerDictionaryTable;
+			while (ptr && ptr->abbreviation) {
+				if (code == ptr->markercode) {
+					abbreviation=ptr->abbreviation;
+					description =ptr->description;
+					return true;
+				}
+				++ptr;
+			}
+			return false;
+		}
+};
+
+
+
+class JPEG_APP0_JFIF_Parameters {
+	unsigned short version;
+	unsigned short units;
+	unsigned short Xdensity;
+	unsigned short Ydensity;
+	unsigned short Xthumbnail;
+	unsigned short Ythumbnail;
+public:
+	JPEG_APP0_JFIF_Parameters(const unsigned char *buffer,size_t length)
+		{
+			// identifier is 4 bytes plus a zero byte
+			version=(buffer[5]<<8)+buffer[6];
+			units=buffer[7];
+			Xdensity=(buffer[8]<<8)+buffer[9];
+			Ydensity=(buffer[10]<<8)+buffer[11];
+			Xthumbnail=buffer[12];
+			Ythumbnail=buffer[13];
+
+			dump(cerr);
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_APP0_JFIF_Parameters:" << endl;
+			out << "\t\t Version = ";
+			writeZeroPaddedHexNumber(out,version,2);
+			out << endl;
+			out << "\t\t Units for the X and Y densities = " << units << endl;
+			out << "\t\t Horizontal pixel density = " << Xdensity << endl;
+			out << "\t\t Vertical pixel density = " << Ydensity << endl;
+			out << "\t\t Thumbnail horizontal pixel count = " << Xthumbnail << endl;
+			out << "\t\t Thumbnail vertical pixel count = " << Ythumbnail << endl;
+		}
+};
+
+class JPEG_SOS_Parameters {
+	unsigned  nComponentsPerScan;
+	unsigned *ScanComponentSelector;
+	unsigned *DCEntropyCodingTableSelector;
+	unsigned *ACEntropyCodingTableSelector;
+	unsigned *MappingTableSelector;			// LS
+	unsigned StartOfSpectralOrPredictorSelection;
+	unsigned EndOfSpectralSelection;
+	unsigned SuccessiveApproximationBitPositionHigh;
+	unsigned SuccessiveApproximationBitPositionLowOrPointTransform;
+public:
+	JPEG_SOS_Parameters(const unsigned char *buffer,size_t length)
+		{
+			nComponentsPerScan=buffer[0];
+			Assert(length == 1+nComponentsPerScan*2+3);
+			ScanComponentSelector       =new unsigned[nComponentsPerScan];
+			DCEntropyCodingTableSelector=new unsigned[nComponentsPerScan];
+			ACEntropyCodingTableSelector=new unsigned[nComponentsPerScan];
+			MappingTableSelector        =new unsigned[nComponentsPerScan];	// LS
+			unsigned short i;
+			for (i=0; i<nComponentsPerScan; ++i) {
+				ScanComponentSelector[i]       =buffer[1+i*2];
+				DCEntropyCodingTableSelector[i]=buffer[1+i*2+1] >> 4;
+				ACEntropyCodingTableSelector[i]=buffer[1+i*2+1] & 0x0f;
+				MappingTableSelector[i]=buffer[1+i*2+1];	// LS
+			}
+			StartOfSpectralOrPredictorSelection                  =buffer[1+nComponentsPerScan*2];
+			EndOfSpectralSelection                               =buffer[1+nComponentsPerScan*2+1];
+			SuccessiveApproximationBitPositionHigh               =buffer[1+nComponentsPerScan*2+2] >> 4;
+			SuccessiveApproximationBitPositionLowOrPointTransform=buffer[1+nComponentsPerScan*2+2] & 0x0f;
+
+			dump(cerr);
+		}
+
+	~JPEG_SOS_Parameters()
+		{
+			if (nComponentsPerScan && ScanComponentSelector)        delete[] ScanComponentSelector;
+			if (nComponentsPerScan && DCEntropyCodingTableSelector) delete[] DCEntropyCodingTableSelector;
+			if (nComponentsPerScan && ACEntropyCodingTableSelector) delete[] ACEntropyCodingTableSelector;
+			if (nComponentsPerScan && MappingTableSelector) 	delete[] MappingTableSelector;	// LS
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_SOS_Parameters:" << endl;
+			out << "\t\t nComponentsPerScan = " << nComponentsPerScan << endl;
+			unsigned short i;
+			for (i=0; i<nComponentsPerScan; ++i) {
+				out << "\t\t component " << i << endl;
+				out << "\t\t\t ScanComponentSelector = " << ScanComponentSelector[i] << endl;
+				out << "\t\t\t DCEntropyCodingTableSelector = " << DCEntropyCodingTableSelector[i] << endl;
+				out << "\t\t\t ACEntropyCodingTableSelector = " << ACEntropyCodingTableSelector[i] << endl;
+				out << "\t\t\t MappingTableSelector(LS) = " << MappingTableSelector[i] << endl;	// LS
+			}
+
+			out << "\t\t StartOfSpectralOrPredictorSelection/NearLosslessDifferenceBound(LS) = " << StartOfSpectralOrPredictorSelection << endl;
+			out << "\t\t EndOfSpectralSelection/InterleaveMode(LS) = " << EndOfSpectralSelection << endl;
+			out << "\t\t SuccessiveApproximationBitPositionHigh = " << SuccessiveApproximationBitPositionHigh << endl;
+			out << "\t\t SuccessiveApproximationBitPositionLowOrPointTransform = " << SuccessiveApproximationBitPositionLowOrPointTransform;
+		}
+};
+
+class JPEG_SOF_Parameters {
+	unsigned  SamplePrecision;
+	unsigned  nLines;
+	unsigned  nSamplesPerLine;
+	unsigned  nComponentsInFrame;
+	unsigned *ComponentIdentifier;
+	unsigned *HorizontalSamplingFactor;
+	unsigned *VerticalSamplingFactor;
+	unsigned *QuantizationTableDestinationSelector;
+public:
+	JPEG_SOF_Parameters(const unsigned char *buffer,size_t length)
+		{
+			SamplePrecision    = buffer[0];
+			nLines             =(buffer[1]<<8)+buffer[2];
+			nSamplesPerLine    =(buffer[3]<<8)+buffer[4];
+			nComponentsInFrame = buffer[5];
+			Assert(length == 6+nComponentsInFrame*3);
+			ComponentIdentifier                 = new unsigned[nComponentsInFrame];
+			HorizontalSamplingFactor            = new unsigned[nComponentsInFrame];
+			VerticalSamplingFactor              = new unsigned[nComponentsInFrame];
+			QuantizationTableDestinationSelector= new unsigned[nComponentsInFrame];
+			unsigned short i;
+			for (i=0; i<nComponentsInFrame; ++i) {
+				ComponentIdentifier[i]                  = buffer[6+i*3];
+				HorizontalSamplingFactor[i]             = buffer[6+i*3+1] >> 4;
+				VerticalSamplingFactor[i]               = buffer[6+i*3+1] & 0x0f;
+				QuantizationTableDestinationSelector[i] = buffer[6+i*3+2];
+			}
+
+			dump(cerr);
+		}
+
+	~JPEG_SOF_Parameters()
+		{
+			if (nComponentsInFrame && ComponentIdentifier)                  delete[] ComponentIdentifier;
+			if (nComponentsInFrame && HorizontalSamplingFactor)             delete[] HorizontalSamplingFactor;
+			if (nComponentsInFrame && VerticalSamplingFactor)               delete[] VerticalSamplingFactor;
+			if (nComponentsInFrame && QuantizationTableDestinationSelector) delete[] QuantizationTableDestinationSelector;
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_SOF_Parameters:" << endl;
+			out << "\t\t SamplePrecision = "	<< SamplePrecision << endl;
+			out << "\t\t nLines = "             << nLines << endl;
+			out << "\t\t nSamplesPerLine = "    << nSamplesPerLine << endl;
+			out << "\t\t nComponentsInFrame = " << nComponentsInFrame << endl;
+			unsigned short i;
+			for (i=0; i<nComponentsInFrame; ++i) {
+				out << "\t\t component " << i << endl;
+				out << "\t\t\t ComponentIdentifier = "                  << ComponentIdentifier[i] << endl;
+				out << "\t\t\t HorizontalSamplingFactor = "             << HorizontalSamplingFactor[i] << endl;
+				out << "\t\t\t VerticalSamplingFactor = "               << VerticalSamplingFactor[i] << endl;
+				out << "\t\t\t QuantizationTableDestinationSelector = " << QuantizationTableDestinationSelector[i] << endl;
+			}
+		}
+};
+
+class JPEG_DHT_Parameters {
+	unsigned  nTables;
+
+	unsigned   *TableClass;
+	unsigned   *HuffmanTableIdentifier;
+	unsigned  **nHuffmanCodesOfLengthI;
+	unsigned ***ValueOfHuffmanCodeIJ;
+public:
+	JPEG_DHT_Parameters(const unsigned char *buffer,size_t length)
+		{
+			TableClass             = new unsigned   [4];
+			HuffmanTableIdentifier = new unsigned   [4];
+			nHuffmanCodesOfLengthI = new unsigned  *[4];
+			ValueOfHuffmanCodeIJ   = new unsigned **[4];
+
+			Assert(TableClass);
+			Assert(HuffmanTableIdentifier);
+			Assert(nHuffmanCodesOfLengthI);
+			Assert(ValueOfHuffmanCodeIJ);
+
+			nTables=0;
+			while (length > 0) {
+				Assert(nTables<4);
+				TableClass[nTables]             = buffer[0] >> 4;
+				HuffmanTableIdentifier[nTables] = buffer[0] & 0x0f;
+				nHuffmanCodesOfLengthI[nTables] = new unsigned[16];
+				Assert(nHuffmanCodesOfLengthI[nTables]);
+				++buffer; --length;
+				unsigned i;
+				for (i=0; i<16; ++i) {
+					Assert(length > 0);
+					nHuffmanCodesOfLengthI[nTables][i] = *buffer++; --length;
+				}
+				ValueOfHuffmanCodeIJ[nTables] = new unsigned *[16];
+				Assert(nHuffmanCodesOfLengthI[nTables]);
+				for (i=0; i<16; ++i) {
+					ValueOfHuffmanCodeIJ[nTables][i] = new unsigned[nHuffmanCodesOfLengthI[nTables][i]];
+					Assert(ValueOfHuffmanCodeIJ[nTables][i]);
+					unsigned j;
+					for (j=0; j<nHuffmanCodesOfLengthI[nTables][i]; ++j) {
+						Assert(length > 0);
+						ValueOfHuffmanCodeIJ[nTables][i][j] = *buffer++; --length;
+					}
+				}
+				++nTables;
+			}
+			Assert(length == 0);
+
+			dump(cerr);
+		}
+
+	~JPEG_DHT_Parameters()
+		{
+			if (TableClass)             delete[] TableClass;
+			if (HuffmanTableIdentifier) delete[] HuffmanTableIdentifier;
+
+			if (nHuffmanCodesOfLengthI) {
+				unsigned t;
+				for (t=0; t<nTables; ++t) {
+					if (nHuffmanCodesOfLengthI[t]) delete[] nHuffmanCodesOfLengthI[t];
+				}
+				delete[] nHuffmanCodesOfLengthI;
+			}
+
+			if (ValueOfHuffmanCodeIJ) {
+				unsigned t;
+				for (t=0; t<nTables; ++t) {
+					unsigned i;
+					for (i=0; i<16; ++i) {
+						if (ValueOfHuffmanCodeIJ[t][i]) delete[] ValueOfHuffmanCodeIJ[t][i];
+					}
+					if (ValueOfHuffmanCodeIJ[t]) delete[] ValueOfHuffmanCodeIJ[t];
+				}
+				delete[] ValueOfHuffmanCodeIJ;
+			}
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_DHT_Parameters:" << endl;
+			unsigned t;
+			for (t=0; t<nTables; ++t) {
+				out << "\t\t TableClass = "             << TableClass[t] << endl;
+				out << "\t\t HuffmanTableIdentifier = " << HuffmanTableIdentifier[t] << endl;
+				unsigned i;
+				for (i=0; i<16; ++i) {
+					out << "\t\t\t nHuffmanCodesOfLength " << i << " = " << nHuffmanCodesOfLengthI[t][i] << endl;
+					unsigned j;
+					for (j=0; j<nHuffmanCodesOfLengthI[t][i];++j) {
+						out << "\t\t\t\t ValueOfHuffmanCode " << j << " = " << ValueOfHuffmanCodeIJ[t][i][j] << endl;
+					}
+				}
+			}
+		}
+};
+
+class JPEG_DQT_Parameters {
+	unsigned  nTables;
+
+	unsigned   *QuantizationTableElementPrecision;
+	unsigned   *QuantizationTableIdentifier;
+	unsigned  **QuantizationTableElement;
+public:
+	JPEG_DQT_Parameters(const unsigned char *buffer,size_t length)
+		{
+			QuantizationTableElementPrecision = new unsigned   [4];
+			QuantizationTableIdentifier       = new unsigned   [4];
+			QuantizationTableElement          = new unsigned  *[4];
+
+			Assert(QuantizationTableElementPrecision);
+			Assert(QuantizationTableIdentifier);
+			Assert(QuantizationTableElement);
+
+			nTables=0;
+			while (length > 0) {
+				Assert(nTables<4);
+				QuantizationTableElementPrecision[nTables] = buffer[0] >> 4;
+				QuantizationTableIdentifier[nTables]       = buffer[0] & 0x0f;
+				QuantizationTableElement[nTables]          = new unsigned[64];
+				Assert(QuantizationTableElement[nTables]);
+				++buffer; --length;
+
+				unsigned i;
+				for (i=0; i<64; ++i) {
+					if (QuantizationTableElementPrecision[nTables]) {
+						Assert(length > 1);
+						QuantizationTableElement[nTables][i] = (buffer[0]<<8)+buffer[1];
+						buffer+=2; length-=2;
+					}
+					else {
+						Assert(length > 0);
+						QuantizationTableElement[nTables][i] = *buffer++; --length;
+					}
+				}
+				++nTables;
+			}
+			Assert(length == 0);
+
+			dump(cerr);
+		}
+
+	~JPEG_DQT_Parameters()
+		{
+			if (QuantizationTableElementPrecision) delete[] QuantizationTableElementPrecision;
+			if (QuantizationTableIdentifier)       delete[] QuantizationTableIdentifier;
+
+			if (QuantizationTableElement) {
+				unsigned t;
+				for (t=0; t<nTables; ++t) {
+					if (QuantizationTableElement[t]) delete[] QuantizationTableElement[t];
+				}
+				delete[] QuantizationTableElement;
+			}
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_DQT_Parameters:" << endl;
+			unsigned t;
+			for (t=0; t<nTables; ++t) {
+				out << "\t\t QuantizationTableElementPrecision = " << QuantizationTableElementPrecision[t] << endl;
+				out << "\t\t QuantizationTableIdentifier = "       << QuantizationTableIdentifier[t] << endl;
+				unsigned i;
+				for (i=0; i<64; ++i) {
+					out << "\t\t\t QuantizationTableElement " << i << " = " << QuantizationTableElement[t][i] << endl;
+				}
+			}
+		}
+};
+
+class JPEG_LSE_Parameters {
+	unsigned char id;
+
+	Uint16 Maxval;
+	Uint16 T1;
+	Uint16 T2;
+	Uint16 T3;
+	Uint16 Reset;
+public:
+	JPEG_LSE_Parameters(const unsigned char *buffer,size_t length)
+		{
+			// L1 parameter (the length has already been read
+
+			id=*buffer++; --length;
+			switch (id) {
+				case JPEG_LSE_ID_L1:	// Coding parameters
+					Assert(length == 10);
+					Maxval=(buffer[0]<<8)+buffer[1];
+					T1    =(buffer[2]<<8)+buffer[3];
+					T2    =(buffer[4]<<8)+buffer[5];
+					T3    =(buffer[6]<<8)+buffer[7];
+					Reset =(buffer[8]<<8)+buffer[9];
+					break;
+				case JPEG_LSE_ID_L2:	// Mapping table
+					break;
+				case JPEG_LSE_ID_L3:	// Mapping table continuation
+					break;
+				case JPEG_LSE_ID_L4:	// > 16 bit X and Y parameters
+					break;
+				default:
+					Assert(0);
+					break;
+			}
+
+			dump(cerr);
+		}
+
+	~JPEG_LSE_Parameters()
+		{
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_LSE_Parameters - ID " << ios::dec << (unsigned)id << " ";
+			switch (id) {
+				case JPEG_LSE_ID_L1:
+					out << "Coding parameters";
+					break;
+				case JPEG_LSE_ID_L2:
+					out << "Mapping table";
+					break;
+				case JPEG_LSE_ID_L3:
+					out << "Mapping table continuation";
+					break;
+				case JPEG_LSE_ID_L4:
+					out << "> 16 bit X and Y parameters";
+					break;
+				default:
+					Assert(0);
+					break;
+			}
+			out << ":" << endl;
+
+			switch (id) {
+				case JPEG_LSE_ID_L1:	// Coding parameters
+					out << "\t\t Maxval = " << Maxval << endl;
+					out << "\t\t T1 = " << T1 << endl;
+					out << "\t\t T2 = " << T2 << endl;
+					out << "\t\t T3 = " << T3 << endl;
+					out << "\t\t Reset = " << Reset << endl;
+					break;
+				case JPEG_LSE_ID_L2:	// Mapping table
+					break;
+				case JPEG_LSE_ID_L3:	// Mapping table continuation
+					break;
+				case JPEG_LSE_ID_L4:	// > 16 bit X and Y parameters
+					break;
+				default:
+					Assert(0);
+			}
+		}
+};
+
+// ISO/IEC 15444-1:2002 Table A.16 Progression order for the SGcod, SPcoc, and Ppoc parameters
+const char *getDescriptionOfProgressionOrder(unsigned char progressionOrder) {
+	const char *descriptionOfProgressionOrder = "Reserved";
+	switch (progressionOrder) {
+		case 0x00:
+			descriptionOfProgressionOrder = "Layer-resolution level-component-position";
+			break;
+		case 0x01:
+			descriptionOfProgressionOrder = "Resolution level-layer-component-position";
+			break;
+		case 0x02:
+			descriptionOfProgressionOrder = "Resolution level-position-component-layer";
+			break;
+		case 0x03:
+			descriptionOfProgressionOrder = "Position-component-resolution level-layer";
+			break;
+		case 0x04:
+			descriptionOfProgressionOrder = "Component-position-resolution level-layer";
+			break;
+	}
+	return descriptionOfProgressionOrder;
+}
+
+// ISO/IEC 15444-1:2002 Table A.17 Multiple component transformation for the SGcod parameters
+const char *getDescriptionOfMultipleComponentTransformation(unsigned char multipleComponentTransformation) {
+	const char *descriptionOfMultipleComponentTransformation = "Reserved";
+	switch (multipleComponentTransformation) {
+		case 0x00:
+			descriptionOfMultipleComponentTransformation = "None";
+			break;
+		case 0x01:
+			descriptionOfMultipleComponentTransformation = "Part 1 Annex G2 transformation of components 0,1,2";
+			break;
+	}
+	return descriptionOfMultipleComponentTransformation;
+}
+
+// ISO/IEC 15444-1:2002 Table A.20 - Transformation for the SPcod and SPcoc parameters
+const char *getDescriptionOfWaveletTransformation(unsigned char waveletTransformation) {
+	const char *descriptionOfWaveletTransformation = "Reserved";
+	switch (waveletTransformation) {
+		case 0x00:
+			descriptionOfWaveletTransformation = "9-7 irreversible filter";
+			break;
+		case 0x01:
+			descriptionOfWaveletTransformation = "5-3 reversible filter";
+			break;
+	}
+	return descriptionOfWaveletTransformation;
+}
+
+class JPEG_COD_Parameters {
+	unsigned char Scod;
+	bool VariablePrecinctSize;
+	bool SOPMarkerSegments;
+	bool EPHPMarkerSegments;
+	
+	unsigned char ProgressionOrder;
+	const char *descriptionOfProgressionOrder;
+	
+	unsigned NumberOfLayers;
+
+	unsigned char MultipleComponentTransformation;
+	const char *descriptionOfMultipleComponentTransformation;
+	
+	unsigned NumberOfDecompositionLevels;
+
+	unsigned char CodeBlockWidth;
+	unsigned char CodeBlockHeight;
+	
+	unsigned char CodeBlockStyle;
+	bool SelectiveArithmeticCodingBypass;
+	bool ResetContextProbabilitiesOnCodingPassBoundaries;
+	bool TerminationOnEachCodingPass;
+	bool VerticallyCausalContext;
+	bool PredictableTermination;
+	bool SegmentationSymbolsAreUsed;
+	
+	unsigned char WaveletTransformation;
+	const char *descriptionOfWaveletTransformation;
+
+public:
+	JPEG_COD_Parameters(const unsigned char *buffer,size_t length)
+		{
+			Scod = buffer[0];
+			VariablePrecinctSize = (Scod & 0x01) != 0;
+			SOPMarkerSegments    = (Scod & 0x02) != 0;
+			EPHPMarkerSegments   = (Scod & 0x04) != 0;
+
+			ProgressionOrder = buffer[1];
+			descriptionOfProgressionOrder = getDescriptionOfProgressionOrder(ProgressionOrder);
+			
+			NumberOfLayers  = (buffer[2]<<8)+buffer[3];
+
+			MultipleComponentTransformation = buffer[4];
+			descriptionOfMultipleComponentTransformation = getDescriptionOfMultipleComponentTransformation(MultipleComponentTransformation);
+			
+			NumberOfDecompositionLevels = buffer[5];
+			CodeBlockWidth              = buffer[6];
+			CodeBlockHeight             = buffer[7];
+			
+			CodeBlockStyle				= buffer[8];
+			// Table A.19 - Code-block style for the SPcod and SPcoc parameters 
+			SelectiveArithmeticCodingBypass                 = (Scod & 0x01) != 0;
+			ResetContextProbabilitiesOnCodingPassBoundaries = (Scod & 0x02) != 0;
+			TerminationOnEachCodingPass                     = (Scod & 0x04) != 0;
+			VerticallyCausalContext                         = (Scod & 0x08) != 0;
+			PredictableTermination                          = (Scod & 0x10) != 0;
+			SegmentationSymbolsAreUsed                      = (Scod & 0x20) != 0;
+
+			WaveletTransformation = buffer[9];
+			descriptionOfWaveletTransformation = getDescriptionOfWaveletTransformation(WaveletTransformation);
+			
+			// if (VariablePrecinctSize) { ... } should extract precint size table
+
+			dump(cerr);
+		}
+
+	~JPEG_COD_Parameters()
+		{
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_COD_Parameters:" << endl;
+			out << "\t\t Scod = "; writeZeroPaddedHexNumber(out,Scod,1); out << endl;
+
+			out << "\t\t\t Precinct size "          << (VariablePrecinctSize ? "defined for each resolution level" : "PPx = 15 and PPy = 15") << endl;
+			out << "\t\t\t SOPMarkerSegments = "	<< (SOPMarkerSegments    ? "may be"   : "not") << " used" << endl;
+			out << "\t\t\t EPHPMarkerSegments = "	<< (EPHPMarkerSegments   ? "shall be" : "not") << " used" << endl;
+
+			out << "\t\t ProgressionOrder = "; writeZeroPaddedHexNumber(out,ProgressionOrder,1); out << " (" << descriptionOfProgressionOrder << " progression)" << endl;
+			out << "\t\t NumberOfLayers = "			<< NumberOfLayers << endl;
+
+			out << "\t\t MultipleComponentTransformation = "; writeZeroPaddedHexNumber(out,MultipleComponentTransformation,1); out << " (" << descriptionOfMultipleComponentTransformation << ")" << endl;
+
+			out << "\t\t NumberOfDecompositionLevels = "			<< NumberOfDecompositionLevels << endl;
+
+			out << "\t\t CodeBlockWidth = ";  writeZeroPaddedHexNumber(out,CodeBlockWidth,1);  out << endl;
+			out << "\t\t CodeBlockHeight = "; writeZeroPaddedHexNumber(out,CodeBlockHeight,1); out << endl;
+
+			out << "\t\t CodeBlockStyle = "; writeZeroPaddedHexNumber(out,CodeBlockStyle,1); out << endl;
+			out << "\t\t\t " << (SelectiveArithmeticCodingBypass                  ? "Selective"    : "No selective")    << " arithmetic coding bypass" << endl;
+			out << "\t\t\t " << (ResetContextProbabilitiesOnCodingPassBoundaries  ? "Reset"        : "No reset of")     << " context probabilities on coding pass boundaries" << endl;
+			out << "\t\t\t " << (TerminationOnEachCodingPass                      ? "Termination"  : "No termination")  << " on each coding pass" << endl;
+			out << "\t\t\t " << (VerticallyCausalContext                          ? "Vertically"   : "No vertically")   << " causal context" << endl;
+			out << "\t\t\t " << (PredictableTermination                           ? "Predictable"  : "No predictable")  << " termination" << endl;
+			out << "\t\t\t " << (SegmentationSymbolsAreUsed                       ? "Segmentation" : "No segmentation") << " symbols are used" << endl;
+
+			out << "\t\t WaveletTransformation = "; writeZeroPaddedHexNumber(out,WaveletTransformation,1); out << " (" << descriptionOfWaveletTransformation << ")" << endl;
+			
+			// if (VariablePrecinctSize) { ... } should dump precint size table
+		}
+};
+
+Uint16 read8(istream &istr)
+{
+	unsigned char b;
+	istr.read((char *)&b,1);
+	return (Uint16)b;
+}
+
+Uint16 read16(istream &istr)	// big-endian
+{
+	Uint16 u;
+	unsigned char b[2];
+	istr.read((char *)b,2);
+	u =  (Uint16)b[0];
+	u <<= 8;
+	u |= (Uint16)b[1];
+	return u;
+}
+
+int
+main(int,char **)
+{
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+//	streambuf *sbuf  = cin.rdbuf();
+//	// default ANSI cin/cout is unbuffered, slow, so ...
+//	char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//	if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+
+	JPEGMarkerDictionary dict;
+
+        bool doing_jpegls=false;
+        bool doing_jpeg2k_tilepart=false;
+
+	unsigned long offset=0;
+	Uint16 markerprefix=read8(cin);
+	while (1) {
+		if (!cin) {
+			cerr << "End of file" << endl;
+			break;
+		}
+		if (markerprefix != 0xff) {		// byte of entropy-coded segment
+			++offset;
+			markerprefix=read8(cin);
+			continue;
+		}
+		Uint16 marker=read8(cin);
+		if (!cin) {
+			cerr << "End of file immediately after marker flag 0xff ... presumably was padding" << endl;
+			break;
+		}
+		else if (marker == 0xff) {	// 0xff byte of padding
+			cerr << "Offset ";
+			writeZeroPaddedHexNumber(cerr,offset,4);
+			cerr << " "
+			     << "Fill byte 0xfff"
+			     << endl;
+			++offset;
+			markerprefix=marker;	// the first 0xff is padding, the 2nd may be the start of a marker
+			continue;
+		}
+                else if (doing_jpeg2k_tilepart) {
+                        marker|=0xff00;
+                        if (marker == JPEG_MARKER_EOI /* J2K EOC */ || marker == JPEG_MARKER_SOT) {
+                                doing_jpeg2k_tilepart=false;
+                              // fall through
+                        }
+                        else if (marker == JPEG_MARKER_SOP || marker == JPEG_MARKER_EPH) {
+                               // fall through
+                         }
+                        else {
+                                ++offset;               // not a marker in tile-part
+                                markerprefix=marker;
+                                continue;
+                        }
+                }
+                else if (marker == 0) {		// 0xff byte of entropy-coded segment ... ignore following zero byte
+			cerr << "Offset ";
+			writeZeroPaddedHexNumber(cerr,offset,4);
+			cerr << " "
+			     << "Encoded 0xff in entropy-coded segment followed by stuffed zero byte"
+			     << endl;
+			markerprefix=read8(cin);
+			offset+=2;
+			continue;
+		}
+
+                if (doing_jpegls && (marker & 0x80) == 0) {
+                                                                        // 0xff byte of JPEG-LS entropy-coded segment ... ignore following zero BIT (not byte)
+                                                                        // but don't activate this mode until sure we are doing JPEG-LS, else
+                                                                        // will not pick up JPEG 2000 markers, which don't have high bit set
+			cerr << "Offset ";
+			writeZeroPaddedHexNumber(cerr,offset,4);
+			cerr << " "
+			     << "Encoded 0xff in entropy-coded segment followed by stuffed zero bit (JPEG-LS)"
+			     << endl;
+			markerprefix=read8(cin);
+			offset+=2;		// the dump doesn't need to look at the remaining 7 entropy coded segment bits
+			continue;
+		}
+
+		// Definitely have a marker ...
+
+		marker|=0xff00;			// convention is to express them with the leading ff
+
+                if (marker == JPEG_MARKER_SOF55) doing_jpegls=true;
+                else if (marker == JPEG_MARKER_SOD) doing_jpeg2k_tilepart=true;
+
+		cerr << "Offset ";
+		writeZeroPaddedHexNumber(cerr,offset,4);
+		cerr << " ";
+		offset+=2;
+		cerr << "Marker ";
+		writeZeroPaddedHexNumber(cerr,marker,2);
+		cerr << " ";
+		const char *desc;
+		const char *abbrev;
+		if (dict.getEntry(marker,abbrev,desc)) {
+			cerr << abbrev << " " << desc << " ";
+		}
+		if (isVariableLengthJPEGSegment(marker)) {
+			Uint16 length=read16(cin);
+			if (cin) {
+				offset+=2;
+				cerr << "length variable ";
+				writeZeroPaddedHexNumber(cerr,length,2);
+				cerr << " ";
+			}
+			else {
+				cerr << "Error - variable length marker without length" << endl;
+				return 1;
+			}
+	
+			// NB. the length includes itself (but not the marker)
+
+			if (length > 2) {
+				unsigned char *buffer=new unsigned char[length-2];
+				cin.read((char *)buffer,length-2);
+				if (!cin || cin.gcount() != length-2) {
+					cerr << "Error - couldn't read variable length parameter sequence" << endl;
+					return 1;
+				}
+				else {
+					switch (marker) {
+					case JPEG_MARKER_SOS:
+						(void)new JPEG_SOS_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_SOF0:
+					case JPEG_MARKER_SOF1:
+					case JPEG_MARKER_SOF2:
+					case JPEG_MARKER_SOF3:
+					case JPEG_MARKER_SOF5:
+					case JPEG_MARKER_SOF6:
+					case JPEG_MARKER_SOF7:
+					case JPEG_MARKER_SOF9:
+					case JPEG_MARKER_SOFA:
+					case JPEG_MARKER_SOFB:
+					case JPEG_MARKER_SOFD:
+					case JPEG_MARKER_SOFE:
+					case JPEG_MARKER_SOFF:
+					case JPEG_MARKER_SOF55:
+						(void)new JPEG_SOF_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_DHT:
+						(void)new JPEG_DHT_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_DQT:
+						(void)new JPEG_DQT_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_LSE:						// LS
+						(void)new JPEG_LSE_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_DRI:
+						unsigned long restartinterval;
+						if (length == 4) {
+							restartinterval=((unsigned long)buffer[0]<<8)+buffer[1];
+						}
+						else if (length == 5) {
+							restartinterval=((unsigned long)buffer[0]<<16)
+								       +((unsigned long)buffer[1]<<8)
+								       +buffer[2];
+						}
+						else if (length == 6) {
+							restartinterval=((unsigned long)buffer[0]<<24)
+								       +((unsigned long)buffer[1]<<16)
+								       +((unsigned long)buffer[2]<<8)
+								       +buffer[3];
+						}
+						else {
+							Assert(0);
+						}
+						cerr << endl << "\tJPEG_DRI_Parameters - Define Restart Interval = ";
+						writeZeroPaddedHexNumber(cerr,restartinterval,4);
+						cerr << endl;
+						break;
+					case JPEG_MARKER_DNL:
+						unsigned long numberoflines;
+						if (length == 4) {
+							numberoflines=((unsigned long)buffer[0]<<8)+buffer[1];
+						}
+						else if (length == 5) {
+							numberoflines=((unsigned long)buffer[0]<<16)
+								     +((unsigned long)buffer[1]<<8)
+								     +buffer[2];
+						}
+						else if (length == 6) {
+							numberoflines=((unsigned long)buffer[0]<<24)
+								     +((unsigned long)buffer[1]<<16)
+								     +((unsigned long)buffer[2]<<8)
+								     +buffer[3];
+						}
+						else {
+							Assert(0);
+						}
+						cerr << endl << "\tJPEG_DNL_Parameters - Define Number of Lines = ";
+						writeZeroPaddedHexNumber(cerr,numberoflines,4);
+						cerr << endl;
+						break;
+					case JPEG_MARKER_COD:
+						(void)new JPEG_COD_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_APP0:
+						if (length >= 16 && strncmp((char*)(buffer),"JFIF",4) == 0) {
+							(void)new JPEG_APP0_JFIF_Parameters(buffer,length-2);
+							break;
+						}
+					}
+				}
+			}
+			else {
+				cerr << "Warning - variable length marker without \"zero\" length (really 2)";
+			}
+                        offset+=(length-2);
+#ifdef CRAP
+			while (length > 2) {
+				(void)read8(cin);
+				if (cin) {
+					++offset;
+					--length;
+				}
+				else {
+					cerr << "Error - couldn't skip header structure" << endl;
+					return 1;
+				}
+			}
+#endif
+		}
+		else {
+			Uint16 length=isFixedLengthJPEGSegment(marker);
+			switch (length) {
+			case 0:
+				break;
+			case 3: {
+					unsigned char value;
+					cin.read((char *)&value,1);
+					if (cin) {
+						offset+=1;
+						cerr << "length fixed 3 value ";
+						writeZeroPaddedHexNumber(cerr,(Uint16)value,2);
+						cerr << " ";
+					}
+					else {
+						cerr << "Error - fixed length 3 marker without value" << endl;
+						return 1;
+					}
+				}
+				break;
+			case 4: {
+					Uint16 value=read16(cin);
+					if (cin) {
+						offset+=2;
+						cerr << "length fixed 4 value ";
+						writeZeroPaddedHexNumber(cerr,value,2);
+						cerr << " ";
+					}
+					else {
+						cerr << "Error - fixed length 4 marker without value" << endl;
+						return 1;
+					}
+				}
+				break;
+			default:
+				Assert(0);
+				break;
+			}
+		}
+		cerr << endl;
+		markerprefix=read8(cin);
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/jpegdump.cc.pre2000 b/appsrc/misc/jpegdump.cc.pre2000
new file mode 100755
index 0000000..6a6f400
--- /dev/null
+++ b/appsrc/misc/jpegdump.cc.pre2000
@@ -0,0 +1,816 @@
+#include <iostream.h>
+
+#include "basetype.h"
+
+const Uint16 JPEG_MARKER_APP0 = 0xffe0;
+const Uint16 JPEG_MARKER_APP1 = 0xffe1;
+const Uint16 JPEG_MARKER_APP2 = 0xffe2;
+const Uint16 JPEG_MARKER_APP3 = 0xffe3;
+const Uint16 JPEG_MARKER_APP4 = 0xffe4;
+const Uint16 JPEG_MARKER_APP5 = 0xffe5;
+const Uint16 JPEG_MARKER_APP6 = 0xffe6;
+const Uint16 JPEG_MARKER_APP7 = 0xffe7;
+const Uint16 JPEG_MARKER_APP8 = 0xffe8;
+const Uint16 JPEG_MARKER_APP9 = 0xffe9;
+const Uint16 JPEG_MARKER_APPA = 0xffea;
+const Uint16 JPEG_MARKER_APPB = 0xffeb;
+const Uint16 JPEG_MARKER_APPC = 0xffec;
+const Uint16 JPEG_MARKER_APPD = 0xffed;
+const Uint16 JPEG_MARKER_APPE = 0xffee;
+const Uint16 JPEG_MARKER_APPF = 0xffef;
+
+const Uint16 JPEG_MARKER_COM = 0xfffe;
+const Uint16 JPEG_MARKER_DAC = 0xffcc;
+const Uint16 JPEG_MARKER_DHP = 0xffde;
+const Uint16 JPEG_MARKER_DHT = 0xffc4;
+const Uint16 JPEG_MARKER_DNL = 0xffdc;
+const Uint16 JPEG_MARKER_DQT = 0xffdb;
+const Uint16 JPEG_MARKER_DRI = 0xffdd;
+const Uint16 JPEG_MARKER_EOI = 0xffd9;
+const Uint16 JPEG_MARKER_EXP = 0xffdf;
+
+const Uint16 JPEG_MARKER_JPG = 0xffc8;
+
+// left out reserved JPGn and RES
+// (especially those with first bit (not just byte) zero ... new LS 0 stuffing)
+
+const Uint16 JPEG_MARKER_RST0 = 0xffd0;
+const Uint16 JPEG_MARKER_RST1 = 0xffd1;
+const Uint16 JPEG_MARKER_RST2 = 0xffd2;
+const Uint16 JPEG_MARKER_RST3 = 0xffd3;
+const Uint16 JPEG_MARKER_RST4 = 0xffd4;
+const Uint16 JPEG_MARKER_RST5 = 0xffd5;
+const Uint16 JPEG_MARKER_RST6 = 0xffd6;
+const Uint16 JPEG_MARKER_RST7 = 0xffd7;
+
+const Uint16 JPEG_MARKER_SOF0 = 0xffc0;
+const Uint16 JPEG_MARKER_SOF1 = 0xffc1;
+const Uint16 JPEG_MARKER_SOF2 = 0xffc2;
+const Uint16 JPEG_MARKER_SOF3 = 0xffc3;
+
+const Uint16 JPEG_MARKER_SOF5 = 0xffc5;
+const Uint16 JPEG_MARKER_SOF6 = 0xffc6;
+const Uint16 JPEG_MARKER_SOF7 = 0xffc7;
+
+const Uint16 JPEG_MARKER_SOF9 = 0xffc9;
+const Uint16 JPEG_MARKER_SOFA = 0xffca;
+const Uint16 JPEG_MARKER_SOFB = 0xffcb;
+
+const Uint16 JPEG_MARKER_SOFD = 0xffcd;
+const Uint16 JPEG_MARKER_SOFE = 0xffce;
+const Uint16 JPEG_MARKER_SOFF = 0xffcf;
+
+const Uint16 JPEG_MARKER_SOI = 0xffd8;
+const Uint16 JPEG_MARKER_SOS = 0xffda;
+const Uint16 JPEG_MARKER_TEM = 0xff01;
+
+// New for JPEG-LS (14495-1:1997)
+
+const Uint16 JPEG_MARKER_SOF55 = 0xfff7;
+const Uint16 JPEG_MARKER_LSE   = 0xfff8;
+
+const unsigned char JPEG_LSE_ID_L1   = 0x01;
+const unsigned char JPEG_LSE_ID_L2   = 0x02;
+const unsigned char JPEG_LSE_ID_L3   = 0x03;
+const unsigned char JPEG_LSE_ID_L4   = 0x04;
+
+
+Uint16 isFixedLengthJPEGSegment(Uint16 marker)
+{
+	Uint16 length;
+	switch (marker) {
+		case JPEG_MARKER_EXP:
+			length=3; break;
+		default:
+			length=0; break;
+	}
+	return length;
+}
+
+bool isNoLengthJPEGSegment(Uint16 marker)
+{
+	bool nolength;
+	switch (marker) {
+	case JPEG_MARKER_SOI:
+	case JPEG_MARKER_EOI:
+	case JPEG_MARKER_TEM:
+	case JPEG_MARKER_RST0:
+	case JPEG_MARKER_RST1:
+	case JPEG_MARKER_RST2:
+	case JPEG_MARKER_RST3:
+	case JPEG_MARKER_RST4:
+	case JPEG_MARKER_RST5:
+	case JPEG_MARKER_RST6:
+	case JPEG_MARKER_RST7:
+				nolength=true; break;
+	default:
+				nolength=false; break;
+	}
+	return nolength;
+}
+
+bool isVariableLengthJPEGSegment(Uint16 marker)
+{
+	return !isNoLengthJPEGSegment(marker) && !isFixedLengthJPEGSegment(marker);
+}
+
+struct JPEGMarkerDictionaryEntry {
+	Uint16 markercode;
+	const char *abbreviation;
+	const char *description;
+} JPEGMarkerDictionaryTable[] = {
+	JPEG_MARKER_APP0, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP1, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP2, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP3, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP4, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP5, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP6, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP7, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP8, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APP9, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APPA, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APPB, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APPC, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APPD, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APPE, "APP", "Reserved for Application Use",
+	JPEG_MARKER_APPF, "APP", "Reserved for Application Use",
+
+	JPEG_MARKER_COM, "COM", "Comment",
+	JPEG_MARKER_DAC, "DAC", "Define Arithmetic Conditioning Table(s)",
+	JPEG_MARKER_DHP, "DHP", "Define Hierarchical Progression",
+	JPEG_MARKER_DHT, "DHT", "Define Huffman Table(s)",
+	JPEG_MARKER_DNL, "DNL", "Define Number of Lines",
+	JPEG_MARKER_DQT, "DQT", "Define Quantization Table(s)",
+	JPEG_MARKER_DRI, "DRI", "Define Restart Interval",
+	JPEG_MARKER_EOI, "EOI", "End of Image",
+	JPEG_MARKER_EXP, "EXP", "Expand Reference Image(s)",
+
+	JPEG_MARKER_JPG, "JPG", "Reserved for JPEG extensions",
+
+	JPEG_MARKER_RST0, "RST0", "Restart with modulo 8 counter 0",
+	JPEG_MARKER_RST1, "RST1", "Restart with modulo 8 counter 1",
+	JPEG_MARKER_RST2, "RST2", "Restart with modulo 8 counter 2",
+	JPEG_MARKER_RST3, "RST3", "Restart with modulo 8 counter 3",
+	JPEG_MARKER_RST4, "RST4", "Restart with modulo 8 counter 4",
+	JPEG_MARKER_RST5, "RST5", "Restart with modulo 8 counter 5",
+	JPEG_MARKER_RST6, "RST6", "Restart with modulo 8 counter 6",
+	JPEG_MARKER_RST7, "RST7", "Restart with modulo 8 counter 7",
+
+	JPEG_MARKER_SOF0, "SOF0", "Huffman Baseline DCT",
+	JPEG_MARKER_SOF1, "SOF1", "Huffman Extended Sequential DCT",
+	JPEG_MARKER_SOF2, "SOF2", "Huffman Progressive DCT",
+	JPEG_MARKER_SOF3, "SOF3", "Huffman Lossless Sequential",
+	JPEG_MARKER_SOF5, "SOF5", "Huffman Differential Sequential DCT",
+	JPEG_MARKER_SOF6, "SOF6", "Huffman Differential Progressive DCT",
+	JPEG_MARKER_SOF7, "SOF7", "Huffman Differential Lossless",
+	JPEG_MARKER_SOF9, "SOF9", "Arithmetic Extended Sequential DCT",
+	JPEG_MARKER_SOFA, "SOFA", "Arithmetic Progressive DCT",
+	JPEG_MARKER_SOFB, "SOFB", "Arithmetic Lossless Sequential",
+	JPEG_MARKER_SOFD, "SOFD", "Arithmetic Differential Sequential DCT",
+	JPEG_MARKER_SOFE, "SOFE", "Arithmetic Differential Progressive DCT",
+	JPEG_MARKER_SOFF, "SOFF", "Arithmetic Differential Lossless",
+
+	JPEG_MARKER_SOF55, "SOF55", "LS",
+
+	JPEG_MARKER_SOI, "SOI", "Start of Image",
+	JPEG_MARKER_SOS, "SOS", "Start of Scan",
+	JPEG_MARKER_TEM, "TEM", "Temporary use with Arithmetic Encoding",
+
+	0, 0, 0
+};
+
+class JPEGMarkerDictionary {
+public:
+	JPEGMarkerDictionary() {}
+
+	bool getEntry(Uint16 code,const char * &abbreviation,const char * &description) const
+		{
+			JPEGMarkerDictionaryEntry *ptr=JPEGMarkerDictionaryTable;
+			while (ptr && ptr->abbreviation) {
+				if (code == ptr->markercode) {
+					abbreviation=ptr->abbreviation;
+					description =ptr->description;
+					return true;
+				}
+				++ptr;
+			}
+			return false;
+		}
+};
+
+class JPEG_SOS_Parameters {
+	unsigned  nComponentsPerScan;
+	unsigned *ScanComponentSelector;
+	unsigned *DCEntropyCodingTableSelector;
+	unsigned *ACEntropyCodingTableSelector;
+	unsigned *MappingTableSelector;			// LS
+	unsigned StartOfSpectralOrPredictorSelection;
+	unsigned EndOfSpectralSelection;
+	unsigned SuccessiveApproximationBitPositionHigh;
+	unsigned SuccessiveApproximationBitPositionLowOrPointTransform;
+public:
+	JPEG_SOS_Parameters(const unsigned char *buffer,size_t length)
+		{
+			nComponentsPerScan=buffer[0];
+			Assert(length == 1+nComponentsPerScan*2+3);
+			ScanComponentSelector       =new unsigned[nComponentsPerScan];
+			DCEntropyCodingTableSelector=new unsigned[nComponentsPerScan];
+			ACEntropyCodingTableSelector=new unsigned[nComponentsPerScan];
+			MappingTableSelector        =new unsigned[nComponentsPerScan];	// LS
+			unsigned short i;
+			for (i=0; i<nComponentsPerScan; ++i) {
+				ScanComponentSelector[i]       =buffer[1+i*2];
+				DCEntropyCodingTableSelector[i]=buffer[1+i*2+1] >> 4;
+				ACEntropyCodingTableSelector[i]=buffer[1+i*2+1] & 0x0f;
+				MappingTableSelector[i]=buffer[1+i*2+1];	// LS
+			}
+			StartOfSpectralOrPredictorSelection                  =buffer[1+nComponentsPerScan*2];
+			EndOfSpectralSelection                               =buffer[1+nComponentsPerScan*2+1];
+			SuccessiveApproximationBitPositionHigh               =buffer[1+nComponentsPerScan*2+2] >> 4;
+			SuccessiveApproximationBitPositionLowOrPointTransform=buffer[1+nComponentsPerScan*2+2] & 0x0f;
+
+			dump(cerr);
+		}
+
+	~JPEG_SOS_Parameters()
+		{
+			if (nComponentsPerScan && ScanComponentSelector)        delete[] ScanComponentSelector;
+			if (nComponentsPerScan && DCEntropyCodingTableSelector) delete[] DCEntropyCodingTableSelector;
+			if (nComponentsPerScan && ACEntropyCodingTableSelector) delete[] ACEntropyCodingTableSelector;
+			if (nComponentsPerScan && MappingTableSelector) 	delete[] MappingTableSelector;	// LS
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_SOS_Parameters:" << endl;
+			out << "\t\t nComponentsPerScan = " << nComponentsPerScan << endl;
+			unsigned short i;
+			for (i=0; i<nComponentsPerScan; ++i) {
+				out << "\t\t component " << i << endl;
+				out << "\t\t\t ScanComponentSelector = " << ScanComponentSelector[i] << endl;
+				out << "\t\t\t DCEntropyCodingTableSelector = " << DCEntropyCodingTableSelector[i] << endl;
+				out << "\t\t\t ACEntropyCodingTableSelector = " << ACEntropyCodingTableSelector[i] << endl;
+				out << "\t\t\t MappingTableSelector(LS) = " << MappingTableSelector[i] << endl;	// LS
+			}
+
+			out << "\t\t StartOfSpectralOrPredictorSelection/NearLosslessDifferenceBound(LS) = " << StartOfSpectralOrPredictorSelection << endl;
+			out << "\t\t EndOfSpectralSelection/InterleaveMode(LS) = " << EndOfSpectralSelection << endl;
+			out << "\t\t SuccessiveApproximationBitPositionHigh = " << SuccessiveApproximationBitPositionHigh << endl;
+			out << "\t\t SuccessiveApproximationBitPositionLowOrPointTransform = " << SuccessiveApproximationBitPositionLowOrPointTransform;
+		}
+};
+
+class JPEG_SOF_Parameters {
+	unsigned  SamplePrecision;
+	unsigned  nLines;
+	unsigned  nSamplesPerLine;
+	unsigned  nComponentsInFrame;
+	unsigned *ComponentIdentifier;
+	unsigned *HorizontalSamplingFactor;
+	unsigned *VerticalSamplingFactor;
+	unsigned *QuantizationTableDestinationSelector;
+public:
+	JPEG_SOF_Parameters(const unsigned char *buffer,size_t length)
+		{
+			SamplePrecision    = buffer[0];
+			nLines             =(buffer[1]<<8)+buffer[2];
+			nSamplesPerLine    =(buffer[3]<<8)+buffer[4];
+			nComponentsInFrame = buffer[5];
+			Assert(length == 6+nComponentsInFrame*3);
+			ComponentIdentifier                 = new unsigned[nComponentsInFrame];
+			HorizontalSamplingFactor            = new unsigned[nComponentsInFrame];
+			VerticalSamplingFactor              = new unsigned[nComponentsInFrame];
+			QuantizationTableDestinationSelector= new unsigned[nComponentsInFrame];
+			unsigned short i;
+			for (i=0; i<nComponentsInFrame; ++i) {
+				ComponentIdentifier[i]                  = buffer[6+i*3];
+				HorizontalSamplingFactor[i]             = buffer[6+i*3+1] >> 4;
+				VerticalSamplingFactor[i]               = buffer[6+i*3+1] & 0x0f;
+				QuantizationTableDestinationSelector[i] = buffer[6+i*3+2];
+			}
+
+			dump(cerr);
+		}
+
+	~JPEG_SOF_Parameters()
+		{
+			if (nComponentsInFrame && ComponentIdentifier)                  delete[] ComponentIdentifier;
+			if (nComponentsInFrame && HorizontalSamplingFactor)             delete[] HorizontalSamplingFactor;
+			if (nComponentsInFrame && VerticalSamplingFactor)               delete[] VerticalSamplingFactor;
+			if (nComponentsInFrame && QuantizationTableDestinationSelector) delete[] QuantizationTableDestinationSelector;
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_SOF_Parameters:" << endl;
+			out << "\t\t SamplePrecision = "           << SamplePrecision << endl;
+			out << "\t\t nLines = "             << nLines << endl;
+			out << "\t\t nSamplesPerLine = "    << nSamplesPerLine << endl;
+			out << "\t\t nComponentsInFrame = " << nComponentsInFrame << endl;
+			unsigned short i;
+			for (i=0; i<nComponentsInFrame; ++i) {
+				out << "\t\t component " << i << endl;
+				out << "\t\t\t ComponentIdentifier = "                  << ComponentIdentifier[i] << endl;
+				out << "\t\t\t HorizontalSamplingFactor = "             << HorizontalSamplingFactor[i] << endl;
+				out << "\t\t\t VerticalSamplingFactor = "               << VerticalSamplingFactor[i] << endl;
+				out << "\t\t\t QuantizationTableDestinationSelector = " << QuantizationTableDestinationSelector[i] << endl;
+			}
+		}
+};
+
+class JPEG_DHT_Parameters {
+	unsigned  nTables;
+
+	unsigned   *TableClass;
+	unsigned   *HuffmanTableIdentifier;
+	unsigned  **nHuffmanCodesOfLengthI;
+	unsigned ***ValueOfHuffmanCodeIJ;
+public:
+	JPEG_DHT_Parameters(const unsigned char *buffer,size_t length)
+		{
+			TableClass             = new unsigned   [4];
+			HuffmanTableIdentifier = new unsigned   [4];
+			nHuffmanCodesOfLengthI = new unsigned  *[4];
+			ValueOfHuffmanCodeIJ   = new unsigned **[4];
+
+			Assert(TableClass);
+			Assert(HuffmanTableIdentifier);
+			Assert(nHuffmanCodesOfLengthI);
+			Assert(ValueOfHuffmanCodeIJ);
+
+			nTables=0;
+			while (length > 0) {
+				Assert(nTables<4);
+				TableClass[nTables]             = buffer[0] >> 4;
+				HuffmanTableIdentifier[nTables] = buffer[0] & 0x0f;
+				nHuffmanCodesOfLengthI[nTables] = new unsigned[16];
+				Assert(nHuffmanCodesOfLengthI[nTables]);
+				++buffer; --length;
+				unsigned i;
+				for (i=0; i<16; ++i) {
+					Assert(length > 0);
+					nHuffmanCodesOfLengthI[nTables][i] = *buffer++; --length;
+				}
+				ValueOfHuffmanCodeIJ[nTables] = new unsigned *[16];
+				Assert(nHuffmanCodesOfLengthI[nTables]);
+				for (i=0; i<16; ++i) {
+					ValueOfHuffmanCodeIJ[nTables][i] = new unsigned[nHuffmanCodesOfLengthI[nTables][i]];
+					Assert(ValueOfHuffmanCodeIJ[nTables][i]);
+					unsigned j;
+					for (j=0; j<nHuffmanCodesOfLengthI[nTables][i]; ++j) {
+						Assert(length > 0);
+						ValueOfHuffmanCodeIJ[nTables][i][j] = *buffer++; --length;
+					}
+				}
+				++nTables;
+			}
+			Assert(length == 0);
+
+			dump(cerr);
+		}
+
+	~JPEG_DHT_Parameters()
+		{
+			if (TableClass)             delete[] TableClass;
+			if (HuffmanTableIdentifier) delete[] HuffmanTableIdentifier;
+
+			if (nHuffmanCodesOfLengthI) {
+				unsigned t;
+				for (t=0; t<nTables; ++t) {
+					if (nHuffmanCodesOfLengthI[t]) delete[] nHuffmanCodesOfLengthI[t];
+				}
+				delete[] nHuffmanCodesOfLengthI;
+			}
+
+			if (ValueOfHuffmanCodeIJ) {
+				unsigned t;
+				for (t=0; t<nTables; ++t) {
+					unsigned i;
+					for (i=0; i<16; ++i) {
+						if (ValueOfHuffmanCodeIJ[t][i]) delete[] ValueOfHuffmanCodeIJ[t][i];
+					}
+					if (ValueOfHuffmanCodeIJ[t]) delete[] ValueOfHuffmanCodeIJ[t];
+				}
+				delete[] ValueOfHuffmanCodeIJ;
+			}
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_DHT_Parameters:" << endl;
+			unsigned t;
+			for (t=0; t<nTables; ++t) {
+				out << "\t\t TableClass = "             << TableClass[t] << endl;
+				out << "\t\t HuffmanTableIdentifier = " << HuffmanTableIdentifier[t] << endl;
+				unsigned i;
+				for (i=0; i<16; ++i) {
+					out << "\t\t\t nHuffmanCodesOfLength " << i << " = " << nHuffmanCodesOfLengthI[t][i] << endl;
+					unsigned j;
+					for (j=0; j<nHuffmanCodesOfLengthI[t][i];++j) {
+						out << "\t\t\t\t ValueOfHuffmanCode " << j << " = " << ValueOfHuffmanCodeIJ[t][i][j] << endl;
+					}
+				}
+			}
+		}
+};
+
+class JPEG_DQT_Parameters {
+	unsigned  nTables;
+
+	unsigned   *QuantizationTableElementPrecision;
+	unsigned   *QuantizationTableIdentifier;
+	unsigned  **QuantizationTableElement;
+public:
+	JPEG_DQT_Parameters(const unsigned char *buffer,size_t length)
+		{
+			QuantizationTableElementPrecision = new unsigned   [4];
+			QuantizationTableIdentifier       = new unsigned   [4];
+			QuantizationTableElement          = new unsigned  *[4];
+
+			Assert(QuantizationTableElementPrecision);
+			Assert(QuantizationTableIdentifier);
+			Assert(QuantizationTableElement);
+
+			nTables=0;
+			while (length > 0) {
+				Assert(nTables<4);
+				QuantizationTableElementPrecision[nTables] = buffer[0] >> 4;
+				QuantizationTableIdentifier[nTables]       = buffer[0] & 0x0f;
+				QuantizationTableElement[nTables]          = new unsigned[64];
+				Assert(QuantizationTableElement[nTables]);
+				++buffer; --length;
+
+				unsigned i;
+				for (i=0; i<64; ++i) {
+					if (QuantizationTableElementPrecision[nTables]) {
+						Assert(length > 1);
+						QuantizationTableElement[nTables][i] = (buffer[0]<<8)+buffer[1];
+						buffer+=2; length-=2;
+					}
+					else {
+						Assert(length > 0);
+						QuantizationTableElement[nTables][i] = *buffer++; --length;
+					}
+				}
+				++nTables;
+			}
+			Assert(length == 0);
+
+			dump(cerr);
+		}
+
+	~JPEG_DQT_Parameters()
+		{
+			if (QuantizationTableElementPrecision) delete[] QuantizationTableElementPrecision;
+			if (QuantizationTableIdentifier)       delete[] QuantizationTableIdentifier;
+
+			if (QuantizationTableElement) {
+				unsigned t;
+				for (t=0; t<nTables; ++t) {
+					if (QuantizationTableElement[t]) delete[] QuantizationTableElement[t];
+				}
+				delete[] QuantizationTableElement;
+			}
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_DQT_Parameters:" << endl;
+			unsigned t;
+			for (t=0; t<nTables; ++t) {
+				out << "\t\t QuantizationTableElementPrecision = " << QuantizationTableElementPrecision[t] << endl;
+				out << "\t\t QuantizationTableIdentifier = "       << QuantizationTableIdentifier[t] << endl;
+				unsigned i;
+				for (i=0; i<64; ++i) {
+					out << "\t\t\t QuantizationTableElement " << i << " = " << QuantizationTableElement[t][i] << endl;
+				}
+			}
+		}
+};
+
+class JPEG_LSE_Parameters {
+	unsigned char id;
+
+	Uint16 Maxval;
+	Uint16 T1;
+	Uint16 T2;
+	Uint16 T3;
+	Uint16 Reset;
+public:
+	JPEG_LSE_Parameters(const unsigned char *buffer,size_t length)
+		{
+			// L1 parameter (the length has already been read
+
+			id=*buffer++; --length;
+			switch (id) {
+				case JPEG_LSE_ID_L1:	// Coding parameters
+					Assert(length == 10);
+					Maxval=(buffer[0]<<8)+buffer[1];
+					T1    =(buffer[2]<<8)+buffer[3];
+					T2    =(buffer[4]<<8)+buffer[5];
+					T3    =(buffer[6]<<8)+buffer[7];
+					Reset =(buffer[8]<<8)+buffer[9];
+					break;
+				case JPEG_LSE_ID_L2:	// Mapping table
+					break;
+				case JPEG_LSE_ID_L3:	// Mapping table continuation
+					break;
+				case JPEG_LSE_ID_L4:	// > 16 bit X and Y parameters
+					break;
+				default:
+					Assert(0);
+					break;
+			}
+
+			dump(cerr);
+		}
+
+	~JPEG_LSE_Parameters()
+		{
+		}
+
+	void dump(ostream &out) const
+		{
+			out << endl << "\tJPEG_LSE_Parameters - ID " << dec << (unsigned)id << " ";
+			switch (id) {
+				case JPEG_LSE_ID_L1:
+					out << "Coding parameters";
+					break;
+				case JPEG_LSE_ID_L2:
+					out << "Mapping table";
+					break;
+				case JPEG_LSE_ID_L3:
+					out << "Mapping table continuation";
+					break;
+				case JPEG_LSE_ID_L4:
+					out << "> 16 bit X and Y parameters";
+					break;
+				default:
+					Assert(0);
+					break;
+			}
+			out << ":" << endl;
+
+			switch (id) {
+				case JPEG_LSE_ID_L1:	// Coding parameters
+					out << "\t\t Maxval = " << Maxval << endl;
+					out << "\t\t T1 = " << T1 << endl;
+					out << "\t\t T2 = " << T2 << endl;
+					out << "\t\t T3 = " << T3 << endl;
+					out << "\t\t Reset = " << Reset << endl;
+					break;
+				case JPEG_LSE_ID_L2:	// Mapping table
+					break;
+				case JPEG_LSE_ID_L3:	// Mapping table continuation
+					break;
+				case JPEG_LSE_ID_L4:	// > 16 bit X and Y parameters
+					break;
+				default:
+					Assert(0);
+			}
+		}
+};
+
+Uint16 read8(istream &istr)
+{
+	unsigned char b;
+	istr.read(&b,1);
+	return (Uint16)b;
+}
+
+Uint16 read16(istream &istr)	// big-endian
+{
+	Uint16 u;
+	unsigned char b[2];
+	istr.read(b,2);
+	u =  (Uint16)b[0];
+	u <<= 8;
+	u |= (Uint16)b[1];
+	return u;
+}
+
+int
+main(int,char **)
+{
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+	streambuf *sbuf  = cin.rdbuf();
+	// default ANSI cin/cout is unbuffered, slow, so ...
+	char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+	if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+
+	JPEGMarkerDictionary dict;
+
+	unsigned long offset=0;
+	Uint16 markerprefix=read8(cin);
+	while (1) {
+		if (!cin) {
+			cerr << "End of file" << endl;
+			break;
+		}
+		if (markerprefix != 0xff) {		// byte of entropy-coded segment
+			++offset;
+			markerprefix=read8(cin);
+			continue;
+		}
+		Uint16 marker=read8(cin);
+		if (!cin) {
+			cerr << "End of file immediately after marker flag 0xff ... presumably was padding" << endl;
+			break;
+		}
+		if (marker == 0) {		// 0xff byte of entropy-coded segment ... ignore following zero byte
+			cerr << "Offset " << hex << offset << " "
+			     << "Encoded 0xff in entropy-coded segment followed by stuffed zero byte"
+			     << endl;
+			offset+=2;
+			markerprefix=read8(cin);
+			continue;
+		}
+		else if (marker == 0xff) {	// 0xff byte of padding
+			cerr << "Offset " << hex << offset << " "
+			     << "Fill byte 0xfff"
+			     << endl;
+			offset+=1;
+			markerprefix=marker;	// the first 0xff is padding, the 2nd may be the start of a marker
+			continue;
+		}
+		else if ((marker & 0x80) == 0) {	// 0xff byte of JPEG-LS entropy-coded segment ... ignore following zero BIT (not byte)
+			cerr << "Offset " << hex << offset << " "
+			     << "Encoded 0xff in entropy-coded segment followed by stuffed zero bit (JPEG-LS)"
+			     << endl;
+			offset+=2;		// the dump doesn't need too look at the remaining 7 entropy codeed segment bits
+			markerprefix=read8(cin);
+			continue;
+		}
+
+
+		// Definitely have a marker ...
+
+		marker|=0xff00;			// convention is to express them with the leading ff
+
+		cerr << "Offset " << hex << offset << " ";
+		offset+=2;
+		cerr << "Marker " << hex << marker << " ";
+		const char *desc;
+		const char *abbrev;
+		if (dict.getEntry(marker,abbrev,desc)) {
+			cerr << abbrev << " " << desc << " ";
+		}
+		if (isVariableLengthJPEGSegment(marker)) {
+			Uint16 length=read16(cin);
+			if (cin) {
+				offset+=2;
+				cerr << "length variable " << hex << length << " ";
+			}
+			else {
+				cerr << "Error - variable length marker without length" << endl;
+				return 1;
+			}
+	
+			// NB. the length includes itself (but not the marker)
+
+			if (length > 2) {
+				unsigned char *buffer=new unsigned char[length-2];
+				cin.read(buffer,length-2);
+				if (!cin || cin.gcount() != length-2) {
+					cerr << "Error - couldn't read variable length parameter sequence" << endl;
+					return 1;
+				}
+				else {
+					switch (marker) {
+					case JPEG_MARKER_SOS:
+						(void)new JPEG_SOS_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_SOF0:
+					case JPEG_MARKER_SOF1:
+					case JPEG_MARKER_SOF2:
+					case JPEG_MARKER_SOF3:
+					case JPEG_MARKER_SOF5:
+					case JPEG_MARKER_SOF6:
+					case JPEG_MARKER_SOF7:
+					case JPEG_MARKER_SOF9:
+					case JPEG_MARKER_SOFA:
+					case JPEG_MARKER_SOFB:
+					case JPEG_MARKER_SOFD:
+					case JPEG_MARKER_SOFE:
+					case JPEG_MARKER_SOFF:
+					case JPEG_MARKER_SOF55:
+						(void)new JPEG_SOF_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_DHT:
+						(void)new JPEG_DHT_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_DQT:
+						(void)new JPEG_DQT_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_LSE:						// LS
+						(void)new JPEG_LSE_Parameters(buffer,length-2);
+						break;
+					case JPEG_MARKER_DRI:
+						unsigned long restartinterval;
+						if (length == 4) {
+							restartinterval=((unsigned long)buffer[0]<<8)+buffer[1];
+						}
+						else if (length == 5) {
+							restartinterval=((unsigned long)buffer[0]<<16)
+								       +((unsigned long)buffer[1]<<8)
+								       +buffer[2];
+						}
+						else if (length == 6) {
+							restartinterval=((unsigned long)buffer[0]<<24)
+								       +((unsigned long)buffer[1]<<16)
+								       +((unsigned long)buffer[2]<<8)
+								       +buffer[3];
+						}
+						else {
+							Assert(0);
+						}
+						cerr << endl << "\tJPEG_DRI_Parameters - Define Restart Interval = " << dec << restartinterval << endl;
+						break;
+					case JPEG_MARKER_DNL:
+						unsigned long numberoflines;
+						if (length == 4) {
+							numberoflines=((unsigned long)buffer[0]<<8)+buffer[1];
+						}
+						else if (length == 5) {
+							numberoflines=((unsigned long)buffer[0]<<16)
+								     +((unsigned long)buffer[1]<<8)
+								     +buffer[2];
+						}
+						else if (length == 6) {
+							numberoflines=((unsigned long)buffer[0]<<24)
+								     +((unsigned long)buffer[1]<<16)
+								     +((unsigned long)buffer[2]<<8)
+								     +buffer[3];
+						}
+						else {
+							Assert(0);
+						}
+						cerr << endl << "\tJPEG_DNL_Parameters - Define Number of Lines = " << dec << restartinterval << endl;
+						break;
+
+					}
+				}
+			}
+			else {
+				cerr << "Warning - variable length marker without \"zero\" length (really 2)";
+			}
+#ifdef CRAP
+			while (length > 2) {
+				(void)read8(cin);
+				if (cin) {
+					++offset;
+					--length;
+				}
+				else {
+					cerr << "Error - couldn't skip header structure" << endl;
+					return 1;
+				}
+			}
+#endif
+		}
+		else {
+			Uint16 length=isFixedLengthJPEGSegment(marker);
+			switch (length) {
+			case 0:
+				break;
+			case 3: {
+					unsigned char value;
+					cin.read(&value,1);
+					if (cin) {
+						offset+=1;
+						cerr << "length fixed 3 value " << hex << ((Uint16)value) << " ";
+					}
+					else {
+						cerr << "Error - fixed length 3 marker without value" << endl;
+						return 1;
+					}
+				}
+				break;
+			case 4: {
+					Uint16 value=read16(cin);
+					if (cin) {
+						offset+=2;
+						cerr << "length fixed 3 value " << hex << value << " ";
+					}
+					else {
+						cerr << "Error - fixed length 4 marker without value" << endl;
+						return 1;
+					}
+				}
+				break;
+			default:
+				Assert(0);
+				break;
+			}
+		}
+		cerr << endl;
+		markerprefix=read8(cin);
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/jpegdump.man b/appsrc/misc/jpegdump.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/jpegsplit.cc b/appsrc/misc/jpegsplit.cc
new file mode 100644
index 0000000..ee564ee
--- /dev/null
+++ b/appsrc/misc/jpegsplit.cc
@@ -0,0 +1,312 @@
+static const char *CopyrightIdentifier(void) { return "@(#)jpegsplit.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <fstream>
+#else
+#include <iostream.h>
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "mesgtext.h"
+#include "getoptns.h"
+
+const Uint16 JPEG_MARKER_APP0 = 0xffe0;
+const Uint16 JPEG_MARKER_APP1 = 0xffe1;
+const Uint16 JPEG_MARKER_APP2 = 0xffe2;
+const Uint16 JPEG_MARKER_APP3 = 0xffe3;
+const Uint16 JPEG_MARKER_APP4 = 0xffe4;
+const Uint16 JPEG_MARKER_APP5 = 0xffe5;
+const Uint16 JPEG_MARKER_APP6 = 0xffe6;
+const Uint16 JPEG_MARKER_APP7 = 0xffe7;
+const Uint16 JPEG_MARKER_APP8 = 0xffe8;
+const Uint16 JPEG_MARKER_APP9 = 0xffe9;
+const Uint16 JPEG_MARKER_APPA = 0xffea;
+const Uint16 JPEG_MARKER_APPB = 0xffeb;
+const Uint16 JPEG_MARKER_APPC = 0xffec;
+const Uint16 JPEG_MARKER_APPD = 0xffed;
+const Uint16 JPEG_MARKER_APPE = 0xffee;
+const Uint16 JPEG_MARKER_APPF = 0xffef;
+
+const Uint16 JPEG_MARKER_COM = 0xfffe;
+const Uint16 JPEG_MARKER_DAC = 0xffcc;
+const Uint16 JPEG_MARKER_DHP = 0xffde;
+const Uint16 JPEG_MARKER_DHT = 0xffc4;
+const Uint16 JPEG_MARKER_DNL = 0xffdc;
+const Uint16 JPEG_MARKER_DQT = 0xffdb;
+const Uint16 JPEG_MARKER_DRI = 0xffdd;
+const Uint16 JPEG_MARKER_EOI = 0xffd9;
+const Uint16 JPEG_MARKER_EXP = 0xffdf;
+
+const Uint16 JPEG_MARKER_JPG = 0xffc8;
+
+// left out reserved JPGn and RES
+// (especially those with first bit (not just byte) zero ... new LS 0 stuffing)
+
+const Uint16 JPEG_MARKER_RST0 = 0xffd0;
+const Uint16 JPEG_MARKER_RST1 = 0xffd1;
+const Uint16 JPEG_MARKER_RST2 = 0xffd2;
+const Uint16 JPEG_MARKER_RST3 = 0xffd3;
+const Uint16 JPEG_MARKER_RST4 = 0xffd4;
+const Uint16 JPEG_MARKER_RST5 = 0xffd5;
+const Uint16 JPEG_MARKER_RST6 = 0xffd6;
+const Uint16 JPEG_MARKER_RST7 = 0xffd7;
+
+const Uint16 JPEG_MARKER_SOF0 = 0xffc0;
+const Uint16 JPEG_MARKER_SOF1 = 0xffc1;
+const Uint16 JPEG_MARKER_SOF2 = 0xffc2;
+const Uint16 JPEG_MARKER_SOF3 = 0xffc3;
+
+const Uint16 JPEG_MARKER_SOF5 = 0xffc5;
+const Uint16 JPEG_MARKER_SOF6 = 0xffc6;
+const Uint16 JPEG_MARKER_SOF7 = 0xffc7;
+
+const Uint16 JPEG_MARKER_SOF9 = 0xffc9;
+const Uint16 JPEG_MARKER_SOFA = 0xffca;
+const Uint16 JPEG_MARKER_SOFB = 0xffcb;
+
+const Uint16 JPEG_MARKER_SOFD = 0xffcd;
+const Uint16 JPEG_MARKER_SOFE = 0xffce;
+const Uint16 JPEG_MARKER_SOFF = 0xffcf;
+
+const Uint16 JPEG_MARKER_SOI = 0xffd8;
+const Uint16 JPEG_MARKER_SOS = 0xffda;
+const Uint16 JPEG_MARKER_TEM = 0xff01;
+
+// New for JPEG-LS (14495-1:1997)
+
+const Uint16 JPEG_MARKER_SOF55 = 0xfff7;
+const Uint16 JPEG_MARKER_LSE   = 0xfff8;
+
+const unsigned char JPEG_LSE_ID_L1   = 0x01;
+const unsigned char JPEG_LSE_ID_L2   = 0x02;
+const unsigned char JPEG_LSE_ID_L3   = 0x03;
+const unsigned char JPEG_LSE_ID_L4   = 0x04;
+
+
+Uint16 isFixedLengthJPEGSegment(Uint16 marker)
+{
+	Uint16 length;
+	switch (marker) {
+		case JPEG_MARKER_EXP:
+			length=3; break;
+		default:
+			length=0; break;
+	}
+	return length;
+}
+
+bool isNoLengthJPEGSegment(Uint16 marker)
+{
+	bool nolength;
+	switch (marker) {
+	case JPEG_MARKER_SOI:
+	case JPEG_MARKER_EOI:
+	case JPEG_MARKER_TEM:
+	case JPEG_MARKER_RST0:
+	case JPEG_MARKER_RST1:
+	case JPEG_MARKER_RST2:
+	case JPEG_MARKER_RST3:
+	case JPEG_MARKER_RST4:
+	case JPEG_MARKER_RST5:
+	case JPEG_MARKER_RST6:
+	case JPEG_MARKER_RST7:
+				nolength=true; break;
+	default:
+				nolength=false; break;
+	}
+	return nolength;
+}
+
+bool isVariableLengthJPEGSegment(Uint16 marker)
+{
+	return !isNoLengthJPEGSegment(marker) && !isFixedLengthJPEGSegment(marker);
+}
+
+
+static Uint16 read8(istream &istr)
+{
+	unsigned char b;
+	istr.read((char *)&b,1);
+	return (Uint16)b;
+}
+
+static Uint16 read16(istream &istr)	// big-endian
+{
+	Uint16 u;
+	unsigned char b[2];
+	istr.read((char *)b,2);
+	u =  (Uint16)b[0];
+	u <<= 8;
+	u |= (Uint16)b[1];
+	return u;
+}
+
+static void write(ostream *ostr,unsigned char b)
+{
+	unsigned char buf[1];
+	buf[0]=b;
+	ostr->write((char *)buf,1);
+}
+
+static void write16(ostream *ostr,Uint16 u)	// big-endian
+{
+	write(ostr,(unsigned char)((u>>8)&0xff));
+	write(ostr,(unsigned char)(u&0xff));
+}
+
+static char *makeNewFilename(int filecount,const char *outprefix,const char *outsuffix)
+{
+	ostrstream ostr;
+	if (outprefix) ostr << outprefix;
+	int zeropadcount=filecount;
+	int digits=1;
+	while (zeropadcount > 9) {
+		++digits;
+		zeropadcount=zeropadcount/10;
+	}
+	while (6-digits > 0) {
+		++digits;
+		ostr << "0";
+	}
+	ostr << filecount;
+	if (outsuffix) ostr << outsuffix;
+	ostr << ends;
+	return ostr.str();
+}
+
+
+int
+main(int argc,char *argv[])
+{
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+//	streambuf *sbuf  = cin.rdbuf();
+//	// default ANSI cin/cout is unbuffered, slow, so ...
+//	char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//	if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+
+	GetNamedOptions options(argc,argv);
+
+	const char *outprefix = 0;
+	(void) options.get("prefix",outprefix);
+	const char *outsuffix = 0;
+	(void) options.get("suffix",outsuffix);
+
+	bool verbose=options.get("v")||options.get("verbose");
+
+	options.done();
+
+	cerr << options.errors();
+
+	if (!options) {
+		cerr << MMsgDC(Usage) << ": " << options.command()
+		     << " [-prefix output_prefix]"
+		     << " [-suffix output_suffix]"
+		     << " [-v|verbose]"
+		     << endl;
+		exit(1);
+	}
+
+	bool writing = false;
+	int filecount = 0;
+	char *filename = 0;
+	ofstream *out = 0;
+
+	Uint16 markerprefix=read8(cin);		// will write later,prn.
+ 	while (1) {
+		if (!cin) {
+			//cerr << "End of file" << endl;
+			break;
+		}
+		if (markerprefix != 0xff) {	// byte of entropy-coded segment
+			if (writing) write(out,(unsigned char)markerprefix);
+			markerprefix=read8(cin);
+			continue;
+		}
+		Uint16 marker=read8(cin);
+		if (!cin) {
+			// End of file immediately after marker flag 0xff ... presumably was padding
+			break;
+		}
+		if (marker == 0) {		// 0xff byte of entropy-coded segment ... ignore following zero byte
+			if (writing) write16(out,marker|0xff00);
+			markerprefix=read8(cin);
+			continue;
+		}
+		else if (marker == 0xff) {	// 0xff byte of padding
+			if (writing) write(out,(unsigned char)0xff);
+			markerprefix=marker;	// the first 0xff is padding, the 2nd may be the start of a marker
+			continue;
+		}
+		else if ((marker & 0x80) == 0) {	// 0xff byte of JPEG-LS entropy-coded segment ... ignore following zero BIT (not byte)
+			if (writing) write16(out,marker|0xff00);	// doesn't need too look at the remaining 7 entropy coded segment bits
+			markerprefix=read8(cin);
+			continue;
+		}
+
+		// Definitely have a marker ...
+
+		marker|=0xff00;			// convention is to express them with the leading ff
+
+		//cerr << "Marker " << hex << marker << endl;
+
+		if (marker == JPEG_MARKER_SOI) {
+			//cerr << "SOI Marker" << endl;
+			++filecount;
+			filename=makeNewFilename(filecount,outprefix,outsuffix);
+		if (verbose) cerr << "Writing file = <" << filename << ">" << endl;
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+			out=new ofstream(filename,ios::out|ios::trunc|ios::binary);
+#else
+			out=new ofstream(filename,ios::out|ios::trunc);
+#endif
+			writing=true;
+			write16(out,marker);
+		}
+		else if (marker == JPEG_MARKER_EOI) {
+			//cerr << "EOI Marker" << endl;
+			if (out) {
+				if (writing) write16(out,marker);
+				out->close();
+				delete out;
+			}
+			writing=false;
+		}
+		else if (writing) write16(out,marker);
+
+		Uint16 length;
+		if (isVariableLengthJPEGSegment(marker)) {
+			length=read16(cin);
+			if (!cin) {
+				cerr << "Error - variable length marker without length" << endl;
+				return 1;
+			}
+			if (writing) write16(out,length);
+			length-=2;	// NB. the length includes itself(but not the marker)
+  		}
+ 		else {
+			length=isFixedLengthJPEGSegment(marker);
+		}
+		if (length > 0) {
+			unsigned char *buffer=new unsigned char[length];
+			cin.read((char *)buffer,length);
+			if (!cin || cin.gcount() != length) {
+				cerr << "Error - couldn't read parameter sequence" << endl;
+				return 1;
+			}
+			if (writing) out->write((char *)buffer,length);
+			if (buffer) delete[] buffer;
+		}
+		markerprefix=read8(cin);	// will write next loop prn.
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/jpegsplit.man b/appsrc/misc/jpegsplit.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/njlwork.history.tmp b/appsrc/misc/njlwork.history.tmp
new file mode 100755
index 0000000..7c19abe
--- /dev/null
+++ b/appsrc/misc/njlwork.history.tmp
@@ -0,0 +1,90 @@
+     1	cd ..
+     2	ls
+     3	more mailbox*
+     4	ls
+     5	ls -a clunie
+     6	ls -a /home/clunie | more
+     7	cat /home/clunie/.login
+     8	openwin
+     9	printenv
+    10	echo $PATH
+    11	ls /
+    12	ls /usr
+    13	ls /usr/openwin
+    14	ls -a
+    15	ls -a | more
+    16	man cde
+    17	ls /usr/openwin
+    18	ls /usr/openwin/bin
+    19	ls
+    20	man useraddd
+    21	man useradd
+    22	cat /etc/skel
+    23	ls /etc/skel
+    24	mv .cshrc gsao.cshrc
+    25	mv .login gsao.login
+    26	mv .profile gsao.profile
+    27	cp /etc/skel/local.cshrc .cshrc
+    28	cp /etc/skel/local.login .login
+    29	cp /etc/skel/local.profile .profile
+    30	logout
+    31	make rawnjl2
+    32	make rawnjl2
+    33	make rawnjl2
+    34	make rawnjl2
+    35	make rawnjl2
+    36	make rawnjl2
+    37	make rawnjl2
+    38	rawnjl2 -crap
+    39	./rawnjl2 -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.raw
+    40	make rawnjl2
+    41	history
+    42	./rawnjl2 -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.raw
+    43	make rawnjl2
+    44	history
+    45	./rawnjl2 -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.raw
+    46	ls -l /tmp/crap.raw
+    47	./rawnjl2 -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.raw
+    48	MAXVAL = 255
+    49	./rawnjl2 -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.myls
+    50	ls -l /tmp/crap*
+    51	history
+    52	./rawnjl2 -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.myls
+    53	50 ls -l /tmp/crap*
+    54	history
+    55	./rawnjl2 -d -rows 256 -columns 256 -depth 8 -input-endian little /tmp/crap.myls /tmp/crap.cmp
+    56	./rawnjl2 -d -rows 256 -columns 256 -depth 8 /tmp/crap.myls /tmp/crap.cmp
+    57	./rawnjl2 -d -rows 256 -columns 256 -depth 8 -output-endian little /tmp/crap.myls /tmp/crap.cmp
+    58	ls -l /tmp/crap*
+    59	cmp /tmp/crap.raw /tmp/crap.cmp
+    60	od -x /tmp/crap.raw | head 2
+    61	od -x /tmp/crap.raw | head -2
+    62	od -x /tmp/crap.cmp | head -2
+    63	cat > /tmp/crap.raw
+    64	mv /tmp/crap.raw /tmp/crap.pgm
+    65	pnmtoraw /tmp/crap.pgm /tmp/crap.raw
+    66	pnmnoraw /tmp/crap.pgm > /tmp/crap.pgmnoraw
+    67	pnmscale 1 /tmp/crap.pgm > /tmp/crap.pgmraw
+    68	textedit /tmp/crap.pgm &
+    69	pnmscale 1 /tmp/crap.pgm > /tmp/crap.pgmraw
+    70	cat /tmp/crap.pgmraw
+    71	pnmtoraw /tmp/crap.pgm /tmp/crap.raw
+    72	od -x pnmtoraw /tmp/crap.pgmraw /tmp/crap.raw
+    73	history
+    74	pnmtoraw /tmp/crap.pgmraw /tmp/crap.raw
+    75	ls -l /tmp/crap.raw
+    76	./rawnjl2 -rows 4 -columns 4 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.myls
+    77	./rawnjl2 -d -rows 4 -columns 4 -depth 8 -output-endian little /tmp/crap.myls /tmp/crap.cmp
+    78	cmp /tmp/crap.raw /tmp/crap.cmp
+    79	od -x /tmp/crap.raw
+    80	od -x /tmp/crap.cmp
+    81	0d -x /tmp/crap.myls
+    82	od -x /tmp/crap.myls
+    83	cp /tmp/crap.raw njltest.raw
+    84	make rawnjl2
+    85	make rawnjl2
+    86	history
+    87	./rawnjl2 -rows 4 -columns 4 -depth 8 -input-endian little /tmp/crap.raw /tmp/crap.myls
+    88	./rawnjl2 -d -rows 4 -columns 4 -depth 8 -output-endian little /tmp/crap.myls /tmp/crap.cmp
+    89	history
+    90	history > njlwork.history.tmp
diff --git a/appsrc/misc/pbmswbit.cc b/appsrc/misc/pbmswbit.cc
new file mode 100644
index 0000000..6e8044e
--- /dev/null
+++ b/appsrc/misc/pbmswbit.cc
@@ -0,0 +1,178 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pbmswbit.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "txstream.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	OutputOptions	 	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	ostream out(output_opener);
+
+	TextOutputStream log (cerr);
+
+	char magic=pnm_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P') {
+		log << EMsgDC(UnrecognizedFormat) << " - 'Pn' "
+		    << MMsgDC(NotFound) << endl;
+		return 1;
+	}
+
+	unsigned samplesperpixel;
+	switch (format) {
+		case '4':	// raw PBM
+			break;
+		case '1':	// text PBM
+		case '2':	// text PGM
+		case '3':	// text PPM
+		case '5':	// raw PGM
+		case '6':	// raw PPM
+			log << EMsgDC(Unsupported) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+		default:
+			log << EMsgDC(UnrecognizedFormat) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+	}
+
+	int width = pnm_getu(in);
+	int height = pnm_getu(in);
+
+	if (verbose) {
+		log << "format P" << format << endl;
+		log << "width " << dec << width << endl;
+		log << "height " << dec << height << endl;
+	}
+
+	if (!in || width == -1 || height == -1) {
+		log << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	out << "P" << format << endl;
+	out << width << " " << height << endl;
+
+	// Last whitespace discarded ... at start of data
+
+	unsigned char value;
+	long count = (long)width*height/8;
+
+	while (count--) {
+		in.read((char *)&value,1);
+		if (!in || in.gcount() != 1) {
+			log << EMsgDC(ReadFailed) << endl;
+			return 1;
+		}
+
+		// swap the bits order (MSB becomes LSB) ..
+
+		unsigned char newvalue=0;
+		int i;
+		for (i=0; i<8; ++i) {
+			newvalue=(newvalue<<1) | (value&0x01);
+			value=value>>1;
+		}
+			
+		out.write((char *)&newvalue,1);
+		if (!out) {
+			log << EMsgDC(WriteFailed) << endl;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/pbmswbit.man b/appsrc/misc/pbmswbit.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/pgmtobmp.cc b/appsrc/misc/pgmtobmp.cc
new file mode 100644
index 0000000..bb6c3fe
--- /dev/null
+++ b/appsrc/misc/pgmtobmp.cc
@@ -0,0 +1,268 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pgmtobmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "txstream.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+static void
+bmp_put8u(ostream &out,unsigned char byte)
+{
+	out.write((char *)&byte,1);
+}
+
+static void
+bmp_put16u(ostream &out,Uint16 word)
+{
+	// little endian
+	unsigned char byte;
+	byte=word;
+	out.write((char *)&byte,1);
+	byte=word>>8;
+	out.write((char *)&byte,1);
+}
+
+static void
+bmp_put32u(ostream &out,Uint32 word)
+{
+	// little endian
+	unsigned char byte;
+	byte=word;
+	out.write((char *)&byte,1);
+	byte=word>>8;
+	out.write((char *)&byte,1);
+	byte=word>>16;
+	out.write((char *)&byte,1);
+	byte=word>>24;
+	out.write((char *)&byte,1);
+}
+
+static void
+bmp_writeFixedGrayscaleIdentityColormapHeader(ostream &out,int width,int height,int padBytes)
+{
+	// See amongst other references "http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html"
+	
+	out.put('B'); out.put('M');
+	Uint32 pixelDataOffset
+		= 54				/* file header + info header fixed length */
+		+ 256 * 4;			/* 256 entry palette  of R G B and reserved (alpha) single byte values */
+	Uint32 fileLength
+		= pixelDataOffset
+		+ (width+padBytes) * height;	/* the uncompressed pixel data */
+	bmp_put32u(out,fileLength);
+	bmp_put16u(out,0);		/* reserved 1 */
+	bmp_put16u(out,0);		/* reserved 2 */
+	bmp_put32u(out,pixelDataOffset);
+	
+	bmp_put32u(out,40);		/* the fixed size of the info header that we are now writing */
+	bmp_put32u(out,width);
+	bmp_put32u(out,height);
+	bmp_put16u(out,1);		/* number of planes is 1 */
+	bmp_put16u(out,8);		/* number of bits is 8 */
+	bmp_put32u(out,0);		/* compression type is none */
+	bmp_put32u(out,0);		/* size of image in bytes (may be zero) */
+	bmp_put32u(out,0);		/* horizontal pixels per meter is unspecified */
+	bmp_put32u(out,0);		/* vertical pixels per meter is unspecified */
+	bmp_put32u(out,0);		/* colors used is unspecified (will be derived from bit count) */
+	bmp_put32u(out,0);		/* number of colors that are important (all) */
+	
+	/* write 256 entry identity grayscale palette (content same as index) */
+	int i;
+	for (i=0; i<256; ++i) {
+		bmp_put8u(out,i);	/* R value */
+		bmp_put8u(out,i);	/* G value */
+		bmp_put8u(out,i);	/* B value */
+		bmp_put8u(out,0);	/* reserved (alpha ?) value */
+	}
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	OutputOptions	 	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	ostream out(output_opener);
+
+	TextOutputStream log (cerr);
+
+	char magic=pnm_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P') {
+		log << EMsgDC(UnrecognizedFormat) << " - 'Pn' "
+		    << MMsgDC(NotFound) << endl;
+		return 1;
+	}
+
+	switch (format) {
+		case '1':	// text PBM
+		case '2':	// text PGM
+		case '3':	// text PPM
+		case '4':	// raw PBM
+		case '6':	// raw PPM
+			log << EMsgDC(Unsupported) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+		case '5':	// raw PGM
+			break;
+		default:
+			log << EMsgDC(UnrecognizedFormat) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+	}
+
+	int width = pnm_getu(in);
+	int height = pnm_getu(in);
+	int maxval = pnm_getu(in);
+
+	if (verbose) {
+		log << "format P" << format << endl;
+		log << "width " << dec << width << endl;
+		log << "height " << dec << height << endl;
+		log << "maxval " << dec << maxval << endl;
+	}
+
+	if (!in || width == -1 || height == -1 || maxval == -1) {
+		log << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+	
+	if (maxval > 255) {
+			log << EMsgDC(Unsupported) << " - maxval more than 256, is "
+			    << maxval
+			    << endl;
+			return 1;
+	}
+
+	int padBytes = 4 - (width % 4);		/* BMP file rows are encoded with zero padding to 4 byte boundaries */
+	if (padBytes == 4) padBytes = 0;
+	if (verbose) {
+		log << "padBytes " << dec << padBytes << endl;
+	}
+	
+	bmp_writeFixedGrayscaleIdentityColormapHeader(out,width,height,padBytes);
+
+	// Last whitespace discarded ... at start of data
+	
+	// BMP files are encoded bottom to top, not top to bottom
+	// so read all rows in and write in reverse order
+
+	char *buffer=new char[width*height];
+	Assert(buffer);
+
+	char *ptr = buffer;
+	int rowsLeft = height;
+	while (rowsLeft--) {
+		in.read(ptr,width);
+		if (!in || in.gcount() != width) {
+			log << EMsgDC(ReadFailed) << endl;
+			return 1;
+		}
+		ptr+=width;
+	}
+	
+	ptr = buffer + width*height;
+	rowsLeft = height;
+	while (rowsLeft--) {
+		ptr-=width;
+		out.write(ptr,width);
+		int i;
+		for (i=0; i<padBytes; ++i) {
+			bmp_put8u(out,0);		/* pad with 0 */
+		}
+		if (!out) {
+			log << EMsgDC(WriteFailed) << endl;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/pgmtobmp.man b/appsrc/misc/pgmtobmp.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/misc/pnmpred.cc b/appsrc/misc/pnmpred.cc
new file mode 100644
index 0000000..ddc386b
--- /dev/null
+++ b/appsrc/misc/pnmpred.cc
@@ -0,0 +1,237 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pnmpred.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "txstream.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+static
+Uint16
+pnm_geti(istream &istr,Uint16 wordlength)	// get image data value
+{
+	unsigned char c[2];
+	istr.read((char *)c,wordlength);
+	Uint16 value;
+	// PNM format is little-endian ...
+	if (wordlength == 2)
+		value=(c[1]<<8)+c[0];
+	else
+		value=c[0];
+	return value;
+}
+
+static
+void
+pnm_puti(ostream &ostr,Uint16 value,Uint16 wordlength)
+							// put image data value
+{
+	unsigned char c[2];
+	// PNM format is little-endian ...
+	if (wordlength == 2) {
+		c[0]=value&0xff;
+		c[1]=value>>8;
+	}
+	else
+		c[0]=value;
+	ostr.write((char *)c,wordlength);
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	OutputOptions	 	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	ostream out(output_opener);
+
+	TextOutputStream log (cerr);
+
+	char magic=pnm_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P') {
+		log << EMsgDC(UnrecognizedFormat) << " - 'Pn' "
+		    << MMsgDC(NotFound) << endl;
+		return 1;
+	}
+
+	unsigned samplesperpixel;
+	switch (format) {
+		case '1':	// text PBM
+		case '2':	// text PGM
+		case '3':	// text PPM
+		case '4':	// raw PBM
+			log << EMsgDC(Unsupported) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+		case '5':	// raw PGM
+			samplesperpixel=1;
+			break;
+		case '6':	// raw PPM
+			samplesperpixel=3;
+			break;
+		default:
+			log << EMsgDC(UnrecognizedFormat) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+	}
+
+	int width = pnm_getu(in);
+	int height = pnm_getu(in);
+	int maxval = pnm_getu(in);
+
+	if (verbose) {
+		log << "format P" << format << endl;
+		log << "width " << dec << width << endl;
+		log << "height " << dec << height << endl;
+		log << "maxval " << dec << maxval << endl;
+	}
+
+	if (!in || width == -1 || height == -1 || maxval == -1) {
+		log << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	// Write new PNM header ...
+
+	{
+		ostrstream ost;
+		ost << "P" << format << "\n" << width << " " << height << "\n"
+		    << ((maxval <= 0xff) ? 0xff : 0xffff) << "\n" << '\0';
+		char *str=ost.str();
+		out.write(str,strlen(str));
+		delete str;
+	}
+
+	// Last whitespace discarded ... at start of data
+
+	unsigned wordlength = (maxval <= 255) ? 1 : 2;
+	Uint16 signmask = (wordlength == 1) ? 0x80 : 0x8000;
+	unsigned rowlength=width*samplesperpixel;
+	Uint16 *buffer1=new Uint16[rowlength];
+	Uint16 *buffer2=new Uint16[rowlength];
+	Uint16 *obuffer=new Uint16[rowlength];
+	Assert(buffer1);
+	Assert(buffer2);
+	Assert(obuffer);
+
+	Uint16 *thisrow=buffer1;
+	Uint16 *lastrow=0;
+
+	while (height--) {
+		Uint16 *ptr;
+		unsigned i;
+		for (i=0,ptr=thisrow; i<rowlength; ++i) *ptr++=pnm_geti(in,wordlength);
+		if (!in) {
+			log << EMsgDC(ReadFailed) << endl;
+			return 1;
+		}
+
+		Uint16 *optr;
+		Uint16 *lptr;
+		for (i=0,ptr=thisrow,optr=obuffer,lptr=0; i<width; ++i) {
+			unsigned s;
+			for (s=0; s<samplesperpixel; ++s) {
+				optr[s]=(lptr ? ptr[s]-lptr[s] : ptr[s]) ^ signmask;
+			}
+			lptr=ptr;
+			ptr+=samplesperpixel;
+			optr+=samplesperpixel;
+		}
+
+		for (i=0,optr=obuffer; i<rowlength; ++i) pnm_puti(out,*optr++,wordlength);
+		if (!out) {
+			log << EMsgDC(WriteFailed) << endl;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/pnmpred.man b/appsrc/misc/pnmpred.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/pnmtoraw.cc b/appsrc/misc/pnmtoraw.cc
new file mode 100644
index 0000000..fe2b47a
--- /dev/null
+++ b/appsrc/misc/pnmtoraw.cc
@@ -0,0 +1,171 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pnmtoraw.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+#include "basetype.h"
+#include "txstream.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	OutputOptions	 	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	ostream out(output_opener);
+
+	TextOutputStream log (cerr);
+
+	char magic=pnm_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P') {
+		log << EMsgDC(UnrecognizedFormat) << " - 'Pn' "
+		    << MMsgDC(NotFound) << endl;
+		return 1;
+	}
+
+	unsigned samplesperpixel;
+	switch (format) {
+		case '1':	// text PBM
+		case '2':	// text PGM
+		case '3':	// text PPM
+		case '4':	// raw PBM
+			log << EMsgDC(Unsupported) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+		case '5':	// raw PGM
+			samplesperpixel=1;
+			break;
+		case '6':	// raw PPM
+			samplesperpixel=3;
+			break;
+		default:
+			log << EMsgDC(UnrecognizedFormat) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+	}
+
+	int width = pnm_getu(in);
+	int height = pnm_getu(in);
+	int maxval = pnm_getu(in);
+
+	if (verbose) {
+		log << "format P" << format << endl;
+		log << "width " << dec << width << endl;
+		log << "height " << dec << height << endl;
+		log << "maxval " << dec << maxval << endl;
+	}
+
+	if (!in || width == -1 || height == -1 || maxval == -1) {
+		log << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	// Last whitespace discarded ... at start of data
+
+	unsigned wordlength = (maxval <= 255) ? 1 : 2;
+	size_t rowlength=width*wordlength*samplesperpixel;
+	char *buffer=new char[rowlength];
+	Assert(buffer);
+
+	while (height--) {
+		in.read(buffer,rowlength);
+		if (!in || in.gcount() != rowlength) {
+			log << EMsgDC(ReadFailed) << endl;
+			return 1;
+		}
+		out.write(buffer,rowlength);
+		if (!out) {
+			log << EMsgDC(WriteFailed) << endl;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/pnmtoraw.man b/appsrc/misc/pnmtoraw.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/ppmtrclr.cc b/appsrc/misc/ppmtrclr.cc
new file mode 100644
index 0000000..e709a02
--- /dev/null
+++ b/appsrc/misc/ppmtrclr.cc
@@ -0,0 +1,239 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ppmtrclr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isdigit()
+#else
+#include <ctype.h>	// for isdigit()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "txstream.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+static
+char
+pnm_getc(istream &istr)		// 1st non-comment, non-whitespace, 0 on failure
+{
+	char c;
+	while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+	if (!istr) return 0;
+	if (c == '#') {		// skip comments
+		while (istr.get(c) && c != '\n');
+		if (!istr) return 0;
+		while (istr.get(c) && (c == ' ' || c == '\t' || c == '\n'));
+		if (!istr) return 0;
+	}
+	return c;
+}
+
+static
+int
+pnm_getu(istream &istr)		// get unsigned value, -1 on failure
+{
+	char c=pnm_getc(istr);	// skips comments and whitespace
+	if(!c || !isdigit(c)) return -1;
+	unsigned value=0;
+	while (c && isdigit(c)) {
+		value*=10;
+		value+=(c-'0');
+		istr.get(c);
+	}
+	// discards single trailing white space
+	return value;
+}
+
+int
+main(int argc,char **argv)
+{
+	Assert(0);	// this just doesn't work ... transformed Cb and Cr values will not fit into 8 bits
+
+	bool bad=false;
+
+	GetNamedOptions 	options(argc,argv);
+	InputOptions		input_options(options);
+	OutputOptions	 	output_options(options);
+
+	bool verbose = options.get("verbose") || options.get("v");
+	
+	bool transformInForwardDirection = options.get("forward") || !options.get("inverse");
+	
+	int transformChoice = 1;	// RCT
+	if (options.get("rct")) {
+		transformChoice = 1;	// RCT
+	}
+	else if (options.get("ict")) {
+		transformChoice = 2;	// ICT
+	}
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	InputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	OutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-rct|-ict]"
+			<< " [-forward|inverse]"
+			<< " [-v|-verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	istream in(input_opener);
+	ostream out(output_opener);
+
+	TextOutputStream log (cerr);
+
+	char magic=pnm_getc(in);
+	char format;
+	in.get(format);
+
+	if (!in || magic != 'P') {
+		log << EMsgDC(UnrecognizedFormat) << " - 'Pn' "
+		    << MMsgDC(NotFound) << endl;
+		return 1;
+	}
+
+	unsigned samplesperpixel;
+	switch (format) {
+		case '6':	// raw PPM
+			break;
+		default:
+			log << EMsgDC(UnrecognizedFormat) << " - 'P"
+			    << format << "'"
+			    << endl;
+			return 1;
+			//break;
+	}
+
+	int width = pnm_getu(in);
+	int height = pnm_getu(in);
+	int maxval = pnm_getu(in);
+
+	if (verbose) {
+		log << "format P" << format << endl;
+		log << "width " << dec << width << endl;
+		log << "height " << dec << height << endl;
+		log << "maxval " << dec << maxval << endl;
+	}
+
+	if (!in || width == -1 || height == -1 || maxval == -1) {
+		log << EMsgDC(UnrecognizedFormat) << endl;
+		return 1;
+	}
+
+	if (maxval > 255) {
+		log << EMsgDC(OnlyOneBytePerChannelSupported) << endl;
+		return 1;
+	}
+
+	out << "P6" << "\n";
+	out << width << " " << height << "\n";
+	out << 255 << "\n";
+
+	// Last whitespace discarded ... at start of data
+
+	size_t rowlength=width*3;		// always one byte per channel, 3 samples per pixel
+	char *buffer=new char[rowlength];
+	Assert(buffer);
+
+	while (height--) {
+		in.read(buffer,rowlength);
+		if (!in || in.gcount() != rowlength) {
+			log << EMsgDC(ReadFailed) << endl;
+			return 1;
+		}
+		char *ptr = buffer;
+		if (transformInForwardDirection) {
+			if (transformChoice == 1) {				// RCT
+				for (int column=0; column<width; ++column) {
+					short r = *ptr;
+					short g = *(ptr+1);
+					short b = *(ptr+2);
+					*ptr++ = (char)((r + 2*g + b)/4);
+					*ptr++ = (char)(b-g);
+					*ptr++ = (char)(r-g);
+				}
+			}
+			else if (transformChoice == 2) {		// ICT
+				for (int column=0; column<width; ++column) {
+					float r = *ptr;
+					float g = *(ptr+1);
+					float b = *(ptr+2);
+					*ptr++ = (char)( 0.29900*r + 0.58700*g + 0.11400*b);
+					*ptr++ = (char)(-0.16875*r - 0.33126*g + 0.50000*b);
+					*ptr++ = (char)( 0.50000*r - 0.41869*g - 0.08131*b);
+				}
+			}
+			else {
+				Assert(0);
+			}
+		}
+		else {
+			if (transformChoice == 1) {				// RCT
+				short signExtensionMask = (-1) << 8;	// since we do not know how long a short actually is
+				for (int column=0; column<width; ++column) {
+					short y = *ptr;
+					short cb = *(ptr+1);			// ? need to sign extend
+					if (cb&0x80) cb = cb | signExtensionMask;
+					short cr = *(ptr+2);			// ? need to sign extend
+					if (cr&0x80) cr|= cr | signExtensionMask;
+					//short g = y - (cr + cb)/4;
+					short floored = (cr + cb);
+					floored = (floored < 0 && (floored%4) != 0) ? (floored/4)-1 : (floored/4);	// i.e., -2.25 is -3, not -2
+					short g = y - floored;
+					*ptr++ = (char)(cr + g);
+					*ptr++ = (char)(g);
+					*ptr++ = (char)(cb + g);
+				}
+			}
+			else if (transformChoice == 2) {		// ICT
+				for (int column=0; column<width; ++column) {
+					float y = *ptr;
+					float cb = *(ptr+1);
+					float cr = *(ptr+2);
+					*ptr++ = (char)round(y + 1.40200*cr);
+					*ptr++ = (char)round(y - 0.34413*cb - 0.71414*cr);
+					*ptr++ = (char)round(y + 1.77200*cb);
+				}
+			}
+			else {
+				Assert(0);
+			}
+		}
+		out.write(buffer,rowlength);
+		if (!out) {
+			log << EMsgDC(WriteFailed) << endl;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/misc/ppmtrclr.man b/appsrc/misc/ppmtrclr.man
new file mode 100644
index 0000000..e69de29
diff --git a/appsrc/misc/rawarith.cc b/appsrc/misc/rawarith.cc
new file mode 100644
index 0000000..84a9b92
--- /dev/null
+++ b/appsrc/misc/rawarith.cc
@@ -0,0 +1,116 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawarith.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "bnstream.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions				options(argc,argv);
+	BinaryInputOptionsWithByteOrder		input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	bool usingsigned=options.get("signed");
+
+	int offset;
+	bool usingoffset=options.get("offset",offset);
+
+	int clipbelow;
+	bool usingclipbelow=options.get("clipbelow",clipbelow);
+
+	int clipabove;
+	bool usingclipabove=options.get("clipabove",clipabove);
+
+	int mask;
+	bool usingmask=options.get("mask",mask);
+
+	bool usingpredictor=options.get("predictor");
+	bool usingunpredictor=options.get("unpredictor");
+
+	if (!usingoffset && !clipbelow && !clipabove && !mask && !usingpredictor && !usingunpredictor) {
+		//cerr << EMsgDC(NeedOption) << " - offset, clipbelow, clipabove, mask or predictor" << endl;
+		bad=true;
+	}
+	
+	if (usingunpredictor) usingsigned=true;		// input is always a delta value
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	BinaryOutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< " -signed"
+			<< " -offset n"
+			<< " -clipbelow n"
+			<< " -clipabove n"
+			<< " -mask n"
+			<< " -predictor"
+			<< " -unpredictor"
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream in(*(istream *)input_opener,input_options.byteorder);
+	BinaryOutputStream out(*(ostream *)output_opener,output_options.byteorder);
+
+	bool success;
+	int predictor=0;
+	while (!in.eof()) {
+		Uint16 uvalue;
+		in >> uvalue;
+		if (in.eof()) { success=true; break; }
+		if (!in) { success=false; break; }
+
+		int value;
+
+		if (usingsigned)
+			value=Int16(uvalue);	// should sign extend 16 bit word
+		else
+			value=Uint16(uvalue);	// should not sign extend
+
+		if (usingoffset) value+=offset;
+		if (usingclipbelow && value < clipbelow) value=clipbelow;
+		if (usingclipabove && value > clipabove) value=clipabove;
+		if (usingmask) value&=mask;
+		if (usingpredictor) {
+			int delta=value-predictor;
+			predictor=value;
+			value=delta;
+		}
+		if (usingunpredictor) {
+			value=value+predictor;
+			predictor=value;
+		}
+		out << Uint16(value);
+		if (!out) { success=false; break; }
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/misc/rawarith.man b/appsrc/misc/rawarith.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/rawdiff.cc b/appsrc/misc/rawdiff.cc
new file mode 100644
index 0000000..aff26f7
--- /dev/null
+++ b/appsrc/misc/rawdiff.cc
@@ -0,0 +1,105 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawdiff.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "bnstream.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions				options(argc,argv);
+	BinaryInputOptionsWithByteOrder		input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	bool verbose=options.get("verbose") || options.get("v");
+
+	unsigned cols=0;
+	if (verbose &&
+	    !options.get("columns",cols) && !options.get("width",cols) && !options.get("w",cols)) {
+		cerr << EMsgDC(NeedOption) << " - columns" << endl;
+		bad=true;
+	}
+
+	bool just1stcol=options.get("just1stcol");
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener1(
+		options,input_options.filename,cin);
+	BinaryInputOpenerFromOptions input_opener2(
+		options,0,cin);
+
+	BinaryOutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener1.errors();
+	cerr << input_opener2.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener1.good()
+	 || !input_opener2.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< " -columns|-width|-w columns"
+			<< " [-v|-verbose [-just1stcol]"
+			<< input_options.usage()
+			<< output_options.usage()
+			<< "[" << MMsgDC(InputFile) << "]" << " " << MMsgDC(InputFile)
+			<< "[" << MMsgDC(OutputFile) << "]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream in1(*(istream *)input_opener1,input_options.byteorder);
+	BinaryInputStream in2(*(istream *)input_opener2,input_options.byteorder);
+	BinaryOutputStream out(*(ostream *)output_opener,output_options.byteorder);
+
+	if (verbose)
+		cerr << "[row,col]: file2 (hex) - file1 (hex) = diff (hex)" << endl;
+
+	long count=0;
+	bool success;
+	while (!in1.eof() && !in2.eof()) {
+		Uint16 value1,value2;
+		in1 >> value1;
+		in2 >> value2;
+		if (in1.eof() || in2.eof()) {
+			if (in1.eof() && in2.eof())
+				success=true;
+			else {
+				cerr << "Different length files" << endl;
+				success=false;
+			}
+			break;
+		}
+		if (!in1 || !in2) { success=false; break; }
+
+		Uint16 diff=value2-value1;
+		out << diff;
+		if (verbose && diff)
+			if (!just1stcol || count%cols == 0)
+				cerr << "[" << count/cols << "," << count%cols
+				     << "]: 0x" << hex << value2 << " - 0x" << value1
+				     << " = " << ((Int16(diff) < 0) ? "-" : "")
+				     << "0x" << ((Int16(diff) < 0) ? -Int16(diff) : Int16(diff))
+				     << dec << endl;
+		if (!out) { success=false; break; }
+		++count;
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/misc/rawdiff.man b/appsrc/misc/rawdiff.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/rawmask.cc b/appsrc/misc/rawmask.cc
new file mode 100644
index 0000000..8da67f8
--- /dev/null
+++ b/appsrc/misc/rawmask.cc
@@ -0,0 +1,86 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawmask.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "bnstream.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions				options(argc,argv);
+	BinaryInputOptionsWithByteOrder		input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	unsigned bits=0;
+	if (!options.get("bits",bits) && !options.get("depth",bits)) {
+		//cerr << EMsgDC(NeedOption) << " - bits" << endl;
+		bad=true;
+	}
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	BinaryOutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream in(*(istream *)input_opener,input_options.byteorder);
+	BinaryOutputStream out(*(ostream *)output_opener,output_options.byteorder);
+
+
+	bool success;
+
+	Assert(bits <= 16);
+	if (bits <= 8) {
+		unsigned char mask = (unsigned char)((Uint32(1)<<bits)-1u);
+		while (!in.eof()) {
+			unsigned char value;
+			in >> value;
+			if (in.eof()) { success=true; break; }
+			if (!in) { success=false; break; }
+			out << (unsigned char)(value&mask);
+			if (!out) { success=false; break; }
+		}
+	}
+	else {
+		Uint16 mask = Uint16((Uint32(1)<<bits)-1u);
+		while (!in.eof()) {
+			Uint16 value;
+			in >> value;
+			if (in.eof()) { success=true; break; }
+			if (!in) { success=false; break; }
+			out << Uint16(value&mask);
+			if (!out) { success=false; break; }
+		}
+	}
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/misc/rawmask.man b/appsrc/misc/rawmask.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/rawnjl.cc b/appsrc/misc/rawnjl.cc
new file mode 100644
index 0000000..1e429e3
--- /dev/null
+++ b/appsrc/misc/rawnjl.cc
@@ -0,0 +1,863 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawnjl.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "bnstream.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+// Test of new lossless JPEG proposal ISO/IEC WD 14495
+
+static inline Uint32 Maximum(Uint32 a,Uint32 b) { return (a > b) ? a : b; }
+static inline Uint16 Maximum(Uint16 a,Uint16 b) { return (a > b) ? a : b; }
+static inline Uint32 Minimum(Uint32 a,Uint32 b) { return (a > b) ? b : a; }
+static inline Uint16 Minimum(Uint16 a,Uint16 b) { return (a > b) ? b : a; }
+static inline Uint32 Abs(Int32 x) { return (Uint32)((x < 0) ? -x : x); }
+static inline Uint16 Abs(Int16 x) { return (Uint16)((x < 0) ? -x : x); }
+
+static Uint32
+readRow(BinaryInputStream &in, Uint16 *buffer, Uint32 n,Uint16 bpp)
+{
+	Uint32 count=0;
+	if (bpp <= 8) {
+		while (n-- && in) {
+			unsigned char value;
+			in >> value;
+			*buffer++=Uint16(value);
+			if (in || in.eof()) ++count;
+		}
+	}
+	else {
+		while (n-- && in) {
+			in >> *buffer++;
+			if (in || in.eof()) ++count;
+		}
+	}
+	return (in || in.eof()) ? count : 0;
+}
+
+static BinaryOutputStream &
+writeRow(BinaryOutputStream &out, Uint16 *buffer, Uint32 n,Uint16 bpp)
+{
+	if (bpp <= 8) {
+		while (n-- && out) out << (unsigned char)(*buffer++);
+	}
+	else {
+		while (n-- && out) out << *buffer++;
+	}
+	return out;
+}
+
+static Uint32 		readBitByteOffset=0;
+static Int16 		readBitCount=0;
+static unsigned char 	readBitByte=0;
+
+static BinaryInputStream &
+readBit(BinaryInputStream &in,Uint32 &bit)
+{
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		++readBitByteOffset;
+		in.read((char *)&readBitByte,1);
+		readBitCount=8;
+	}
+	bit=(readBitByte>>(--readBitCount)) & 1;
+//cerr << (bit ? "1" : "0");
+	return in;
+}
+
+static void
+dumpReadBitPosition(void)
+{
+	cerr << "dumpReadBitPosition: " << (readBitByteOffset-1+(readBitCount ? 0 : 1)) << "." << (readBitCount ? (8-readBitCount) : 0) << endl;
+}
+
+static Uint32 		writeBitByteOffset=0;
+static Uint16 		writeBitCount=0;
+static unsigned char 	writeBitByte=0;
+
+static BinaryOutputStream &
+writeBit(BinaryOutputStream &out,Uint32 bit)
+{
+	// first bits are written into msb of byte
+	Assert(writeBitCount<8);
+	writeBitByte=writeBitByte<<1;
+	if (bit) writeBitByte|=1;
+	if (++writeBitCount >= 8) {
+		++writeBitByteOffset;
+		out.write((char *)&writeBitByte,1);
+		writeBitByte=0;
+		writeBitCount=0;
+	}
+//cerr << (bit ? "1" : "0");
+	return out;
+}
+
+static BinaryOutputStream &
+writeBitFlush(BinaryOutputStream &out)
+{
+	Assert(writeBitCount<8);
+	writeBitByte=writeBitByte<<(8-writeBitCount);
+	out.write((char *)&writeBitByte,1);
+	writeBitByte=0;
+	writeBitCount=0;
+	return out;
+}
+
+static void
+dumpWriteBitPosition(void)
+{
+	cerr << "dumpWriteBitPosition: " << writeBitByteOffset << "." << writeBitCount << endl;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions				options(argc,argv);
+	BinaryInputOptionsWithByteOrder		input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	unsigned rows=0;
+	if (!options.get("rows",rows) && !options.get("height",rows) && !options.get("h",rows)) {
+		//cerr << EMsgDC(NeedOption) << " - rows" << endl;
+		bad=true;
+	}
+	unsigned cols=0;
+	if (!options.get("columns",cols) && !options.get("width",cols) && !options.get("w",cols)) {
+		//cerr << EMsgDC(NeedOption) << " - columns" << endl;
+		bad=true;
+	}
+	unsigned bits=0;
+	if (!options.get("bits",bits) && !options.get("depth",bits)) {
+		//cerr << EMsgDC(NeedOption) << " - bits" << endl;
+		bad=true;
+	}
+
+	Assert(bits <= 16);
+
+	bool decompressing=options.get("d") || options.get("decompress");
+	bool sendFirstValue=options.get("first");
+	bool useRunMode=options.get("run");
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	BinaryOutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	//cerr << input_options.errors();
+	//cerr << output_options.errors();
+	//cerr << options.errors();
+	//cerr << input_opener.errors();
+	//cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-d|decompress]"
+			<< " [-first]"
+			<< " [-run]"
+			<< " -rows|height|h n"
+			<< " -columns|width|w n"
+			<< " -bits|depth n"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream in(*(istream *)input_opener,input_options.byteorder);
+	BinaryOutputStream out(*(ostream *)output_opener,output_options.byteorder);
+
+	bool success=true;
+
+	// Fixed things
+
+	const Uint16 nContexts = 1215;	// Supposed to be 1092 but set quantization :(
+
+	// Set specified parameters (would be in syntax)
+
+	Uint32 ROWS = rows;
+	Uint32 COLUMNS = cols;
+	Uint16 bpp = bits;
+
+	Uint32 Max = (1l<<bpp)-1;	// maximum possible value
+
+//cerr << "Max = " << Max << endl;
+
+	Uint16 backGroundValue = 0;
+
+//cerr << "backGroundValue = " << backGroundValue << endl;
+
+	Uint16 RESET = 64;	// The value at which A, B, and N are halved
+	Uint16 near = 0;	// Lossless
+
+	// Thresholds for context gradients ...
+
+	Uint16 T1 = 3+3*near;				// eg. 3  for lossless
+	Uint16 T2 = 7+5*near;				// eg. 7  for lossless
+	Uint16 T3 = 21+7*near;				// eg. 21 for lossless
+	Uint16 T4 = Maximum(Uint16(5),(near+1));	// eg. 5  for lossless
+
+	if (bits != 8) {
+		Uint16 multipler8=1<<(bpp-8);		// eg. 256  for 16 bit
+		Uint16 multipler9=1<<(bpp-9);		// eg. 128  for 16 bit
+		T1=multipler8*(T1-2)+2;			// eg. 258  for 16 bit
+		T2=multipler8*(T2-3)+3;			// eg. 1027 for 16 bit
+		T3=multipler8*(T3-4)+4;			// eg. 4356 for 16 bit
+		T4=Maximum(5u,multipler9);		// eg. 128  for 16 bit
+	}
+
+//cerr << "T1 = " << T1 << endl;
+//cerr << "T2 = " << T2 << endl;
+//cerr << "T3 = " << T3 << endl;
+//cerr << "T4 = " << T4 << endl;
+
+	Int32 MIN_C = -128;	// Limits on values in bias correction array C
+	Int32 MAX_C =  127;
+
+
+	// Initialization of variables ...
+
+	Uint32	*A = new Uint32[nContexts];	// accumulated prediction error magnitude [0..nContexts-1]
+	Int32	*B = new Int32[nContexts];	// auxilliary counters for bias cancellation [0..nContexts-1]
+	Int32	*C = new Int32[nContexts];	// counters indicating bias correction value [0..nContexts-1]
+	Int32	*N = new Int32[nContexts];	// counters for context type occurence [0..nContexts-1]
+						// (never -ve but often used as -N[Q] so int not unsigned saves cast)
+
+	Assert(A);
+	Assert(B);
+	Assert(C);
+	Assert(N);
+	{
+		unsigned i;
+		for (i=0; i<nContexts; ++i) {
+			A[i]=4;
+			B[i]=C[i]=0;
+			N[i]=1;
+		}
+	}
+
+	// Range of prediction error representation ...
+	Int32 MODULO = (Max+2*near)/(2*near+1)+1;	// for lossless, is just Max+1
+							// int not unsigned to avoid need for cast when used
+
+//cerr << "MODULO = " << MODULO << endl;
+
+	if (decompressing) {
+		if (sendFirstValue) {
+			in >> backGroundValue;
+//cerr << "backGroundValue = " << backGroundValue << endl;
+		}
+	}
+
+	// The run variables seem to need to live beyond a single run or row !!!
+
+	unsigned RUNIndex = 0;
+
+	static Uint16 J[32] = {		// Order of run length codes
+		0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,7,8,9,10,11,12,13,14,15 };
+
+	Int32	EA[2]  = { 4,4 };	// Accummulated prediction error at end of run
+	Uint32	EN[2]  = { 1,1 };	// Occurrence counters for end of run
+	Int32	ENn[2] = { 0,0 };	// Negative prediction error for end of run
+
+//dumpReadBitPosition();
+//dumpWriteBitPosition();
+
+	Uint16 *rowA = new Uint16[COLUMNS];
+	Uint16 *rowB = new Uint16[COLUMNS];
+	Assert(rowA);
+	Assert(rowB);
+
+	Uint32 row=0;
+	Uint16 *thisRow=rowA;
+	Uint16 *prevRow=rowB;
+	for (row=0; row<ROWS; ++row) {
+//cerr << "Row " << row << endl;
+//bool traceOn = (row >= 84 && row <= 86);
+//bool traceOn = true;
+//if (decompressing)
+//	dumpReadBitPosition();
+//else
+//	dumpWriteBitPosition();
+		if (!decompressing)  {
+			Uint32 n=readRow(in,thisRow,COLUMNS,bpp);
+			Assert (n==COLUMNS);
+//cerr << "Row " << row << " read returns " << n << endl;
+			if (sendFirstValue && row == 0) {
+				backGroundValue=thisRow[0];
+				out << backGroundValue;
+//cerr << "backGroundValue = " << backGroundValue << endl;
+			}
+		}
+
+		Uint32 col=0;
+		for (col=0; col<COLUMNS; ++col) {
+
+//cerr << "\tcol = " << col << endl;
+
+			//	. c a d .
+			//	e b x . .
+			//	. . . . .
+
+			Int32 Rx;	// not Uint16 to allow overrange before clamping
+			if (!decompressing) {
+				Rx = thisRow[col];
+//cerr << "\t\tRx = " << Rx << endl;
+			}
+			Uint16 Rb = (col > 0)                    ? thisRow[col-1] : backGroundValue;
+			Uint16 Re = (col > 1)                    ? thisRow[col-2] : backGroundValue;
+			Uint16 Rc = (col > 0 && row > 0)         ? prevRow[col-1] : backGroundValue;
+			Uint16 Ra = (row > 0)                    ? prevRow[col]   : backGroundValue;
+			Uint16 Rd = (col+1 < COLUMNS && row > 0) ? prevRow[col+1] : backGroundValue;
+
+//cerr << "\t\tRa = " << Ra << endl;
+//cerr << "\t\tRb = " << Rb << endl;
+//cerr << "\t\tRc = " << Rc << endl;
+//cerr << "\t\tRd = " << Rd << endl;
+//cerr << "\t\tRe = " << Re << endl;
+
+			// NB. We want the Reconstructed values, which are the same
+			// in lossless mode, but if near != 0 take care to write back
+			// reconstructed values into the row buffers in previous positions
+
+			// Compute local gradient ...
+
+			Int32 D1=(Int32)Rd-Ra;
+			Int32 D2=(Int32)Ra-Rc;
+			Int32 D3=(Int32)Rc-Rb;
+			Int32 D4=(Int32)Rb-Re;
+
+//cerr << "\t\tD1 = " << D1 << endl;
+//cerr << "\t\tD2 = " << D2 << endl;
+//cerr << "\t\tD3 = " << D3 << endl;
+//cerr << "\t\tD4 = " << D4 << endl;
+
+			// Check for run mode ... (should check Abs() works ok for Int32)
+
+			if (useRunMode && Abs(D1) <= near && Abs(D2) <= near && Abs(D3) <= near) {
+				// Run mode
+
+//cerr << "Row at run start " << row << endl;
+//cerr << "\tcol at run start " << col << endl;
+				if (decompressing) {
+//dumpReadBitPosition();
+					// Why is RUNIndex not reset to 0 here ?
+					Uint32 R;
+					while (readBit(in,R)) {
+//cerr << "\tcol " << col << endl;
+						if (R == 0) {
+//cerr << "0" << endl;
+							Int32 rm=1<<J[RUNIndex];
+//cerr << "\tRUNIndex " << RUNIndex << endl;
+//cerr << "\trm " << rm << endl;
+							while (rm-- && col < COLUMNS) thisRow[col++]=Rb;
+							// This will match when exact count coincides with end of row ...
+							if (rm == -1 && RUNIndex < 32) {
+								++RUNIndex;
+//cerr << "\tRUNIndex incremented to " << RUNIndex << endl;
+							}
+							if (col >= COLUMNS) {
+//cerr << "\tFilled to end of row" << endl;
+//cerr << "\tAfter having found end of row " << endl;
+//dumpReadBitPosition();
+								break;
+							}
+						}
+						else {
+//cerr << "1" << endl;
+							// Read J[RUNIndex] bits
+							Uint16 bits=J[RUNIndex];
+//cerr << "\tRUNIndex " << RUNIndex << endl;
+//cerr << "\tReading bits " << bits << endl;
+							Uint32 nfill=0;
+							Uint32 bit;
+							// msb bit is read first
+							while (bits-- && readBit(in,bit)) {
+//cerr << (bit ? "1" : "0") << endl;
+								nfill=(nfill<<1) | bit;
+							}
+//cerr << "\tFill with " << nfill << endl;
+							// Fill with nfill values of Rb
+							while (nfill--) {
+//if (!(col<(COLUMNS-1))) {
+//	cerr << "Fail at line 367 ... !(col<(COLUMNS-1))" << endl;
+//	cerr << "\tstill to fill " << nfill+1 << endl;
+//	cerr << "\trow is " << row << endl;
+//	cerr << "\tcol is " << col << endl;
+//}
+								Assert(col<(COLUMNS-1));
+								thisRow[col++]=Rb;
+							}
+							if (RUNIndex > 0) {
+								--RUNIndex;
+//cerr << "\tRUNIndex decremented to " << RUNIndex << endl;
+							}
+
+							// Decode the end of run value
+//cerr << "\tcol at end of run " << col << endl;
+//cerr << "\tBefore decoding value that ends run " << endl;
+//dumpReadBitPosition();
+							{
+								Uint16 bits=16;
+								Uint16 value=0;
+								Uint32 bit;
+								// msb bit is read first
+								while (bits-- && readBit(in,bit)) value=(value<<1) | bit;
+//cerr << "\tValue that ends run " << value << endl;
+								Assert(col<COLUMNS);
+								thisRow[col]=value;
+							}
+//cerr << "\tBefore decoding value that ends run " << endl;
+//dumpReadBitPosition();
+							break;
+						}
+					}
+				}
+				else {
+//dumpWriteBitPosition();
+					// Scan to determine length of run ...
+//cerr << "\tRb is " << Rb << endl;
+					Int32 RUNCnt=0;
+					while (col < COLUMNS
+					    && (thisRow[col] == Rb || (near > 0 && Abs(Int32(thisRow[col])-Int32(Rb)) <= near) )
+					) {
+						++RUNCnt;
+						if (near > 0) thisRow[col]=Rb;
+						++col;
+					}
+//cerr << "\tRUNCnt " << RUNCnt << endl;
+					// Encode length of run ...
+					// NB. Could really precompute so-called "rm" rather than "rk" values in table :(
+					Uint32 rm;
+					// Why is RUNIndex not reset to 0 here ?
+					while (RUNCnt >= (rm=1<<J[RUNIndex])) {
+//cerr << "\tRUNIndex " << RUNIndex << endl;
+//cerr << "\trm " << rm << endl;
+						writeBit(out,0);
+//cerr << "0" << endl;
+						RUNCnt-=rm;
+//cerr << "\tRUNCnt decremented to " << RUNCnt << endl;
+						Assert(RUNCnt >= 0);	// is why int not unsigned
+						if (RUNIndex < 32) {
+							++RUNIndex;
+//cerr << "\tRUNIndex incremented to " << RUNIndex << endl;
+						}
+					}
+
+					if (col < COLUMNS) {	// Must have been terminated by different value
+								// the draft text and figure seem to conflict on how to
+								// test for end of row ... let's use col instead
+//cerr << "\tcol " << col << endl;
+//cerr << "\tDifferent value is " << thisRow[col] << endl;
+						writeBit(out,1);
+//cerr << "1" << endl;
+						// Append least significant J[RUNIndex] bits
+						Uint16 bits=J[RUNIndex];
+						Uint32 value=RUNCnt;
+						Assert(value < (1<<J[RUNIndex]));	// Does it really fit in this ? why should it ??
+//cerr << "\tRemaining RUNCnt " << RUNCnt << endl;
+//cerr << "\tEncoding in bits " << bits << endl;
+						// msb bit is written first
+						while (bits--) {
+							Uint32 bit=(value>>bits)&1;
+							writeBit(out,bit);  // use the decremented bits as shift
+//cerr << (bit ? "1" : "0") << endl;
+						}
+
+						if (RUNIndex > 0) {
+							--RUNIndex;
+//cerr << "\tRUNIndex decremented to " << RUNIndex << endl;
+						}
+
+						// Encode the end of run value
+//cerr << "\tcol at end of run " << col << endl;
+						Assert(col<COLUMNS);
+//cerr << "\tBefore encoding value that ends run " << endl;
+//dumpWriteBitPosition();
+//cerr << "\tValue that ends run " << thisRow[col] << endl;
+						{
+							Uint16 bits=16;
+							// msb bit is written first
+							while (bits--) {
+								writeBit(out,(thisRow[col]>>bits)&1);
+							}
+						}
+//cerr << "\tAfter encoding value that ends run " << endl;
+//dumpWriteBitPosition();
+					}
+					else {						// Aborted at end of row
+//cerr << "\tEnd of row" << endl;
+						if (RUNCnt > 0) {
+							writeBit(out,0);		// Append an extra 0
+											// decoder knows to stop at end of row
+											// though remainder can't be > 1<<J[RUNIndex]
+//cerr << "0 for end of row" << endl;
+//cerr << "\tAfter indicating end of row " << endl;
+//dumpWriteBitPosition();
+						}
+					}
+				}
+
+			}
+			else
+				{
+
+				// Regular mode
+
+				// Gradient quantization ...
+
+				Int16 Q1,Q2,Q3,Q4;
+
+				if      (D1 <= -T3)   Q1=-4;
+				else if (D1 <= -T2)   Q1=-3;
+				else if (D1 <= -T1)   Q1=-2;
+				else if (D1 <  -near) Q1=-1;
+				else if (D1 <=  near) Q1= 0;
+				else if (D1 <   T1)   Q1= 1;
+				else if (D1 <   T2)   Q1= 2;
+				else if (D1 <   T3)   Q1= 3;
+				else                  Q1= 4;
+
+				if      (D2 <= -T3)   Q2=-4;
+				else if (D2 <= -T2)   Q2=-3;
+				else if (D2 <= -T1)   Q2=-2;
+				else if (D2 <  -near) Q2=-1;
+				else if (D2 <=  near) Q2= 0;
+				else if (D2 <   T1)   Q2= 1;
+				else if (D2 <   T2)   Q2= 2;
+				else if (D2 <   T3)   Q2= 3;
+				else                  Q2= 4;
+
+				if      (D3 <= -T3)   Q3=-4;
+				else if (D3 <= -T2)   Q3=-3;
+				else if (D3 <= -T1)   Q3=-2;
+				else if (D3 <  -near) Q3=-1;
+				else if (D3 <=  near) Q3= 0;
+				else if (D3 <   T1)   Q3= 1;
+				else if (D3 <   T2)   Q3= 2;
+				else if (D3 <   T3)   Q3= 3;
+				else                  Q3= 4;
+
+				if      (D4 <= -T4)   Q4=-1;
+				else if (D4 <   T4)   Q4= 0;
+				else                  Q4= 1;
+
+//cerr << "\t\tQ1 = " << Q1 << endl;
+//cerr << "\t\tQ2 = " << Q2 << endl;
+//cerr << "\t\tQ3 = " << Q3 << endl;
+//cerr << "\t\tQ4 = " << Q4 << endl;
+
+				// Context merging and determination of sign ...
+
+				// Note that there are 3 missings contexts because of Run mode,
+				// ie. Q1 == 0 && Q2 == 0 && Q3 == 0 and Q4 == anything (-1,0,+1)
+
+				Int16 sign;
+
+				// "If the 1st non-zero component of vector (Q1,Q2,Q3) is negative" ...
+
+				if ( Q1 < 0
+				 || (Q1 == 0 && Q2 < 0)
+				 || (Q1 == 0 && Q2 == 0 && Q3 < 0) ) {
+					Q1=-Q1;
+					Q2=-Q2;
+					Q3=-Q3;
+					Q4=-Q4;
+					sign=-1;	// signifies -ve
+				}
+				else {
+					sign=1;		// signifies +ve
+				}
+
+//cerr << "\t\tsign= " << sign << endl;
+
+//cerr << "\t\tQ1 after sign = " << Q1 << endl;
+//cerr << "\t\tQ2 after sign = " << Q2 << endl;
+//cerr << "\t\tQ3 after sign = " << Q3 << endl;
+//cerr << "\t\tQ4 after sign = " << Q4 << endl;
+
+				// Q1 therefore always becomes +ve or is already 0
+
+				// The derivation of Q is not specified in the current draft :(
+
+				Uint16 Q = Q1*243 + (Q2+4)*27 + (Q3+4)*3 + (Q4+1);	// 0..1091 supposed to be
+				//         0..4      0..8        0..8       0..2	// 0..1214 ?
+
+//cerr << "\t\tQ itself = " << Q << endl;
+
+if (Q >= nContexts) {
+	//cerr << "\t\tQ1 after sign = " << Q1 << endl;
+	//cerr << "\t\tQ2 after sign = " << Q2 << endl;
+	//cerr << "\t\tQ3 after sign = " << Q3 << endl;
+	//cerr << "\t\tQ4 after sign = " << Q4 << endl;
+	//cerr << "\t\tQ itself = " << Q << endl;
+}
+				Assert(Q<nContexts);	// Just in case
+
+				// let's just forget the run contexts and go with 1215 for now :(
+
+				// Edge detecting predictor ...
+
+				Int32 Px;	// not Uint16 to allow overrange before clamping
+
+				if      (Rc >= Maximum(Ra,Rb)) Px = Minimum(Ra,Rb);
+				else if (Rc <= Minimum(Ra,Rb)) Px = Maximum(Ra,Rb);
+				else			   Px = Ra+Rb-Rc;
+
+//cerr << "\t\tPx = " << Px << endl;
+
+				// Prediction correction and clamping ...
+
+				Px = Px + ((sign > 0) ? C[Q] : -C[Q]);
+
+//cerr << "\t\tC[Q] = " << C[Q] << endl;
+//cerr << "\t\tPx corrected = " << Px << endl;
+
+				if      (Px > (Int32)Max) Px=Max;	// wanted signed comparison
+				else if (Px < 0)   Px=0;
+
+				// Compute prediction error ...
+//cerr << "\t\tPx clamped = " << Px << endl;
+
+
+				// Prediction error encoding and decoding...
+
+				// Golomb encoding ...
+
+				// Determine Golomb parameter k
+
+				Uint16 k;
+
+//cerr << "\t\tN[Q] = " << N[Q] << endl;
+//cerr << "\t\tA[Q] = " << A[Q] << endl;
+
+				Assert(N[Q]);				// Make sure we don't get out of control
+				for (k=0;(N[Q]<<k) < A[Q]; ++k)		// Number of occurrences vs accumulated error magnitude
+					Assert(k<32);	// not in draft, but need limit else possible infinite loop if A[Q] really big
+
+//cerr << "\t\tk = " << k << endl;
+
+				Uint32 Merror;
+				Int32 error;
+
+				if (decompressing) {
+					// Decode Golomb mapped error from input...
+
+					{
+						// Read least significant k bits
+						Uint16 bits=k;
+						Uint32 lsvalue=0;
+						Uint32 bit;
+						// msb bit is read first
+//cerr << "\t\t" << bits << " k bits" << endl;
+						while (bits-- && readBit(in,bit)) lsvalue=(lsvalue<<1) | bit;
+//cerr << ",";
+						// Read unary representation of remaining most significant bits
+						Uint32 msvalue=0;
+						while (readBit(in,bit) && !bit) ++msvalue;	// Stops after 1 bit
+//cerr << "\t\t" << msvalue << " msb bits" << endl;
+						Merror=msvalue<<k | lsvalue;
+					}
+
+//cerr << "\t\tMerror = " << Merror << endl;
+
+					// Unmap error from non-negative ...
+
+					// "In the near-lossless mode ... is independent of k." text of A.8.2
+					// conflicts with figure A.2 ... go with the figure.
+
+					if (near > 0 && k == 0 && B[Q] <= -N[Q]/2) {
+						if (Merror%2 != 0)
+							error=((Int32)Merror-1)/2;	//  1 becomes  0,  3 becomes  1,  5 becomes  2
+						else
+							error=-(Int32)Merror/2 - 1;	//  0 becomes -1,  2 becomes -2,  4 becomes -3
+					}
+					else {
+						if (Merror%2 == 0)
+							error=(Int32)Merror/2;		//  0 becomes  0, 2 becomes  1,  4 becomes  2
+						else
+							error=-((Int32)Merror + 1)/2;	//  1 becomes -1, 3 becomes -2
+					}
+
+					// Dequantize the error if in near-lossless mode ...
+
+//cerr << "\t\terror undequantized = " << error << endl;
+
+					if (near) error=error*(2*near+1);
+
+//cerr << "\t\terror sign uncorrected = " << error << endl;
+
+					if (sign < 0) error=-error;		// if "context type" was negative
+
+//cerr << "\t\terror result = " << error << endl;
+
+					Rx=(Px+error)%(MODULO*(2*near+1));	// watch this for bad unsigned->signed conversion :(
+										// ? should be sign * error ??? :(
+					if      (Rx > Max) Rx=Max;
+					else if (Rx < 0)   Rx=0;
+
+					thisRow[col]=(Uint16)Rx;
+				}
+				else {
+					error = Rx - Px;		// watch this for bad unsigned->signed conversion :(
+
+//cerr << "\t\terror start = " << error << endl;
+
+					if (sign < 0) error=-error;	// if "context type" was negative
+
+//cerr << "\t\terror sign corrected = " << error << endl;
+
+					// Quantize the error if in near-lossless mode ...
+
+					if (near) {
+						if (error > 0)
+							error=(error+near)/(2*near+1);
+						else
+							// error=(near-error)/(2*near+1);	// This must be wrong in A.7.4
+												// as it doesn't match decompress
+							error=(error-near)/(2*near+1);
+
+						// Replace with the reconstructed value the decoder will have
+						// (obviously if in lossless mode there will be no difference
+
+						Int32 newRx=Px+sign*error*(2*near+1);
+						if      (newRx > Max) newRx=Max;
+						else if (newRx < 0)   newRx=0;
+					
+						thisRow[col]=Rx=(Uint16)newRx;
+					}
+
+//cerr << "\t\terror quantized = " << error << endl;
+
+					// Modulo reduction of the prediction error
+
+					error=error%MODULO;	// make very sure everything is signed !!
+								// else generates huge errors :)
+
+//cerr << "\t\terror modulo " << MODULO << " = " << error << endl;
+
+					// Map error to non-negative ...
+
+					// "In the near-lossless mode ... is independent of k." text of A.8.2
+					// conflicts with figure A.2 ... go with the figure.
+
+					if (near > 0 && k == 0 && B[Q] <= -N[Q]/2) {
+						if (error >= 0)
+							Merror =  2*error + 1;	//  0 becomes 1,  1 becomes 3,  2 becomes 5
+						else
+							Merror = -2*(error+1);	// -1 becomes 0, -2 becomes 2, -3 becomes 4
+					}
+					else {
+						if (error >= 0)
+							Merror =  2*error;	//  0 becomes 0,  1 becomes 2,  2 becomes 4
+						else
+							Merror = -2*error - 1;	// -1 becomes 1, -2 becomes 3
+					}
+
+//cerr << "\t\tMerror = " << Merror << endl;
+
+					// Encode Golomb mapped error ...
+
+					{
+						// Append least significant k bits
+						Uint16 bits=k;
+//cerr << "\t\t" << bits << " k bits" << endl;
+						Uint32 value=Merror;
+						// msb bit is written first
+						while (bits--) { writeBit(out,(value>>bits)&1); }  // use the decremented bits as shift
+					}
+//cerr << ",";
+					{
+						// Append unary representation of remaining most significant bits
+						Uint32 value=Merror>>k;
+//cerr << "\t\t" << value << " msb bits" << endl;
+						while (value--) writeBit(out,0);
+					}
+					writeBit(out,1);	// Note that a 1 is always the last thing written
+								// so for k=0 and e=0 nothing is written but 1
+				}
+
+//cerr << "\t\tMerror = " << Merror << endl;
+//cerr << "\t\tRx = " << Rx << endl;
+
+				// Update parameters ...
+
+//cerr << "\t\tUse error (Rx - Px) = " << (Rx - Px) << endl;
+//cerr << "\t\tA[Q] old = " << A[Q] << endl;
+//cerr << "\t\tB[Q] old = " << B[Q] << endl;
+//cerr << "\t\tC[Q] old = " << C[Q] << endl;
+//cerr << "\t\tN[Q] old = " << N[Q] << endl;
+
+				// don't use the value of error because it is different at
+				// this point because of all the massaging ... recompute it
+				// based on the reconstructed value that is shared between
+				// both encoder and decoder
+
+				B[Q]=B[Q]+sign*(Rx - Px)*(2*near+1);
+				A[Q]=A[Q]+Abs(error);
+				if (N[Q] == RESET) {
+					A[Q]=A[Q]>>1;
+					B[Q]=B[Q]>>1;
+					N[Q]=N[Q]>>1;	// This isn't in the text at A.9.1 but seems necessary :(
+				}
+				++N[Q];
+
+//cerr << "\t\tA[Q] updated = " << A[Q] << endl;
+//cerr << "\t\tB[Q] updated = " << B[Q] << endl;
+//cerr << "\t\tC[Q] updated = " << C[Q] << endl;
+//cerr << "\t\tN[Q] updated = " << N[Q] << endl;
+
+				// Context dependent bias cancellation ...
+
+				if (B[Q] <= -N[Q]) {
+					if (C[Q] > MIN_C) --C[Q];
+					B[Q]+=N[Q];
+					if (B[Q] <= -N[Q]) B[Q]=-N[Q]+1;
+				}
+				else if (B[Q] > 0) {
+					if (C[Q] < MAX_C) ++C[Q];
+					B[Q]-=N[Q];
+					if (B[Q] > 0) B[Q]=0;
+				}
+
+//cerr << "\t\tA[Q] bias cancelled = " << A[Q] << endl;
+//cerr << "\t\tB[Q] bias cancelled = " << B[Q] << endl;
+//cerr << "\t\tC[Q] bias cancelled = " << C[Q] << endl;
+//cerr << "\t\tN[Q] bias cancelled = " << N[Q] << endl;
+
+			}
+		}
+		if (decompressing) {
+			if (!writeRow(out,thisRow,COLUMNS,bpp)) Assert(0);
+		}
+		Uint16 *tmpRow=thisRow;
+		thisRow=prevRow;
+		prevRow=tmpRow;
+	}
+
+	if (!decompressing) writeBitFlush(out);
+
+	if (rowA) delete[] rowA;
+	if (rowB) delete[] rowB;
+	if (A) delete[] A;
+	if (B) delete[] B;
+	if (C) delete[] C;
+	if (N) delete[] N;
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/misc/rawnjl.man b/appsrc/misc/rawnjl.man
new file mode 100755
index 0000000..e69de29
diff --git a/appsrc/misc/rawnjl2.cc b/appsrc/misc/rawnjl2.cc
new file mode 100644
index 0000000..62018cc
--- /dev/null
+++ b/appsrc/misc/rawnjl2.cc
@@ -0,0 +1,1538 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rawnjl2.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "bnstream.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+// Test of new lossless JPEG proposal ISO/IEC WD 14495
+
+static inline Uint32 Maximum(Uint32 a,Uint32 b) { return (a > b) ? a : b; }
+static inline Uint16 Maximum(Uint16 a,Uint16 b) { return (a > b) ? a : b; }
+static inline Uint32 Minimum(Uint32 a,Uint32 b) { return (a > b) ? b : a; }
+static inline Uint16 Minimum(Uint16 a,Uint16 b) { return (a > b) ? b : a; }
+
+static inline Uint32 Abs(Int32 x) { return (Uint32)((x < 0) ? -x : x); }
+static inline Uint16 Abs(Int16 x) { return (Uint16)((x < 0) ? -x : x); }
+
+static inline double Log(double x)	{ return (ourlog2(x)); }
+
+static inline Uint32 Floor(double x)	{ return Uint32(floor(x)); }
+static inline Uint32 Ceiling(double x)	{ return Uint32(ceil(x)); }
+static inline Uint32 FloorDivision(Uint32 n,Uint32 d)	{ return Uint32(floor(double(n)/double(d))); }
+static inline Uint32 CeilingDivision(Uint32 n,Uint32 d)	{ return Uint32(ceil(double(n)/double(d))); }
+
+// Constant tables for run length codes ...
+
+static const Uint16 J[32] = {		// Order of run length codes
+	0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,7,8,9,10,11,12,13,14,15
+};
+
+static const Uint16 J_rm[32] = {	// Length of run length codes (ie. 1<<J[n])
+	1u<<0,1u<<0,1u<<0,1u<<0,
+	1u<<1,1u<<1,1u<<1,1u<<1,
+	1u<<2,1u<<2,1u<<2,1u<<2,
+	1u<<3,1u<<3,1u<<3,1u<<3,
+	1u<<4,1u<<4,
+	1u<<5,1u<<5,
+	1u<<6,1u<<6,
+	1u<<7,1u<<7,
+	1u<<8,
+	1u<<9,
+	1u<<10,
+	1u<<11,
+	1u<<12,
+	1u<<13,
+	1u<<14,
+	1u<<15
+};
+
+static Uint32
+readRow(BinaryInputStream &in, Uint16 *buffer, Uint32 n,Uint16 bpp)
+{
+	Uint32 count=0;
+	if (bpp <= 8) {
+		while (n-- && in) {
+			unsigned char value;
+			in >> value;
+			*buffer++=Uint16(value);
+			if (in || in.eof()) ++count;
+		}
+	}
+	else {
+		while (n-- && in) {
+			in >> *buffer++;
+			if (in || in.eof()) ++count;
+		}
+	}
+	return (in || in.eof()) ? count : 0;
+}
+
+static BinaryOutputStream &
+writeRow(BinaryOutputStream &out, Uint16 *buffer, Uint32 n,Uint16 bpp)
+{
+	if (bpp <= 8) {
+		while (n-- && out) out << (unsigned char)(*buffer++);
+	}
+	else {
+		while (n-- && out) out << *buffer++;
+	}
+	return out;
+}
+
+static Uint32 		readBitByteOffset=0;
+static Int16 		readBitCount=0;
+static unsigned char 	readBitByte=0;
+static unsigned char 	readForwardByte;
+static bool		readHaveForwardByte=false;
+
+static BinaryInputStream &
+readBit(BinaryInputStream &in,Uint32 &bit)
+{
+	// first bits are read from msb of byte
+	Assert(readBitCount >= 0);
+	if (readBitCount < 1) {
+		++readBitByteOffset;
+		if (readHaveForwardByte) {
+			readHaveForwardByte=false;
+			readBitByte=readForwardByte;
+			readBitCount=7;			// skip the stuffed zero bit (otherwise would have been marker)(hence never 0xff)
+		}
+		else {
+			in.read((char *)&readBitByte,1);
+			if (readBitByte == 0xff) {	// could be marker segment or data 0xff with following stuffed zero bit
+				Assert(readHaveForwardByte == false);
+				//while (in.read((char *)&readForwardByte,1) && readForwardByte == 0xff);	// skip padding bytes (strings of 0xff)
+				in.read((char *)&readForwardByte,1);
+				if (in) {
+					if ((readForwardByte & 0x80) == 0) {	// stuffed zero bit after valid 0xff
+						readHaveForwardByte=true;
+						// the valid 0xff is already in readBitByte
+						readBitCount=8;
+					}
+					else {	// marker segment
+						// marker identifier is 0xff00+readForwardByte
+cerr << "readBitByte=" << hex << unsigned(readBitByte) << dec << endl;
+cerr << "readForwardByte=" << hex << unsigned(readForwardByte) << dec << endl;
+						Assert(0);	// for now
+					}
+				}
+				else {
+					readBitCount=0;	// just in case ... will trigger assertion next time
+					return in;	// failed miserably (ie. can't be valid JPEG syntax if have 0xff as last byte in file)
+				}
+			}
+			else
+				readBitCount=8;
+		}
+	}
+	bit=(readBitByte>>(--readBitCount)) & 1;
+//cerr << (bit ? "1" : "0");
+	return in;
+}
+
+static void
+dumpReadBitPosition(void)
+{
+	cerr << "dumpReadBitPosition: " << (readBitByteOffset-1+(readBitCount ? 0 : 1)) << "." << (readBitCount ? (8-readBitCount) : 0) << endl;
+}
+
+static Uint32 		writeBitByteOffset=0;
+static Uint16 		writeBitCount=0;
+static unsigned char 	writeBitByte=0;
+
+static BinaryOutputStream &
+writeBit(BinaryOutputStream &out,Uint32 bit)
+{
+	// first bits are written into msb of byte
+	Assert(writeBitCount<8);
+	writeBitByte=writeBitByte<<1;
+	if (bit) writeBitByte|=1;
+//cerr << (bit ? "1" : "0");
+	if (++writeBitCount >= 8) {
+		++writeBitByteOffset;
+		out.write((char *)&writeBitByte,1);
+		// need to stuff with a following zero bit to distinguish from JPEG marker
+		writeBitCount=(writeBitByte == 0xff) ? 1 : 0;
+		writeBitByte=0;
+	}
+	return out;
+}
+
+static BinaryOutputStream &
+writeBitFlush(BinaryOutputStream &out)
+{
+	Assert(writeBitCount<8);
+	writeBitByte=writeBitByte<<(8-writeBitCount);
+	out.write((char *)&writeBitByte,1);
+	writeBitByte=0;
+	writeBitCount=0;
+	return out;
+}
+
+static void
+dumpWriteBitPosition(void)
+{
+	cerr << "dumpWriteBitPosition: " << writeBitByteOffset << "." << writeBitCount << endl;
+}
+
+
+static BinaryOutputStream &
+write16BE(BinaryOutputStream &out,Uint16 word)
+{
+	unsigned char byte;
+	byte=word>>8;
+	out.write((char *)&byte,1);
+	byte=word&0xff;
+	out.write((char *)&byte,1);
+	return out;
+}
+
+static BinaryOutputStream &
+write8(BinaryOutputStream &out,unsigned char byte)
+{
+	out.write((char *)&byte,1);
+	return out;
+}
+
+static BinaryInputStream &
+read16BE(BinaryInputStream &in,Uint16 &value)
+{
+	unsigned char byte;
+	in.read((char *)&byte,1);
+	value=Uint16(byte)<<8;
+	in.read((char *)&byte,1);
+	value|=byte;
+	return in;
+}
+
+static BinaryInputStream &
+read8(BinaryInputStream &in,unsigned char &byte)
+{
+	in.read((char *)&byte,1);
+	return in;
+}
+
+// JPEG Syntax - Marker Segment stuff ....
+
+const Uint16 JPEG_MARKER_DNL = 0xffdc;
+const Uint16 JPEG_MARKER_EOI = 0xffd9;
+const Uint16 JPEG_MARKER_SOI = 0xffd8;
+const Uint16 JPEG_MARKER_SOS = 0xffda;
+
+// New for JPEG-LS (14495-1:1997)
+
+const Uint16 JPEG_MARKER_SOF55 = 0xfff7;
+const Uint16 JPEG_MARKER_LSE   = 0xfff8;
+
+const unsigned char JPEG_LSE_ID_L1   = 0x01;
+const unsigned char JPEG_LSE_ID_L2   = 0x02;
+const unsigned char JPEG_LSE_ID_L3   = 0x03;
+const unsigned char JPEG_LSE_ID_L4   = 0x04;
+
+static BinaryOutputStream &
+writeSOI(BinaryOutputStream &out)
+{
+	write16BE(out,JPEG_MARKER_SOI);
+	return out;
+}
+
+static BinaryOutputStream &
+writeSOF55(BinaryOutputStream &out,Uint16 P,Uint16 ROWS,Uint16 COLUMNS)
+{
+	write16BE(out,JPEG_MARKER_SOF55);
+	write16BE(out,11);			// length (inclusive of self)
+
+	Assert(P < 256);
+	write8(out,(unsigned char)P);		// sample precision
+	write16BE(out,ROWS);			// Y - number of lines
+	write16BE(out,COLUMNS);			// X - number of samples per line
+
+	write8(out,1);				// one component per frame only
+
+	write8(out,1);				// component identifier is 1
+	write8(out,0x11);			// no horizontal or vertical sampling factor
+	write8(out,0);				// no quantization table used in JPEG-LS
+
+	return out;
+}
+
+static BinaryOutputStream &
+writeSOS(BinaryOutputStream &out,Uint16 NEAR)
+{
+	write16BE(out,JPEG_MARKER_SOS);
+	write16BE(out,8);			// length (inclusive of self)
+
+	write8(out,1);				// one component per scan only
+
+	write8(out,1);				// select component 1
+	write8(out,0);				// no mapping table
+
+	Assert(NEAR < 256);
+	write8(out,(unsigned char)NEAR);	// in place of start of spectral selection
+	write8(out,0);				// ILV - interleave mode is 0 (none)
+
+	write8(out,0);				// not used in JPEG-LS
+
+	return out;
+}
+
+static BinaryOutputStream &
+writeLSE1(BinaryOutputStream &out,Uint16 MAXVAL,Uint16 T1,Uint16 T2,Uint16 T3,Uint16 RESET)
+{
+	write16BE(out,JPEG_MARKER_LSE);
+	write16BE(out,13);
+	write8(out,JPEG_LSE_ID_L1);
+	write16BE(out,MAXVAL);
+	write16BE(out,T1);
+	write16BE(out,T2);
+	write16BE(out,T3);
+	write16BE(out,RESET);
+
+	return out;
+}
+
+static BinaryOutputStream &
+writeEOI(BinaryOutputStream &out)
+{
+	write16BE(out,JPEG_MARKER_EOI);
+	return out;
+}
+
+static bool
+readJPEGMarker(BinaryInputStream &in,Uint16 &marker)
+{
+	return read16BE(in,marker) && (marker&0xff80) != 0;
+}
+
+static bool
+readSOI(BinaryInputStream &in,Uint16 marker)
+{
+	return marker == JPEG_MARKER_SOI;
+}
+
+static bool
+readSOF55(BinaryInputStream &in,Uint16 marker,Uint16 &P,Uint32 &ROWS,Uint32 &COLUMNS)
+{
+//cerr << "readSOF55:" << endl;
+	Uint16 length;
+	unsigned char precision;
+	Uint16 rows;
+	Uint16 columns;
+	unsigned char ncomponents;
+	unsigned char componentid;
+	unsigned char hvsampling;
+	unsigned char quanttable;
+	return marker == JPEG_MARKER_SOF55			// && (cerr << "readSOF55: JPEG_MARKER_SOF55" << endl)
+	    && read16BE(in,length) && length == 11		// && (cerr << "readSOF55: length = " << dec << length << endl)
+	    && read8(in,precision) && (P=precision,true)	// && (cerr << "readSOF55: P = " << dec << P << endl)
+	    && read16BE(in,rows) && (ROWS=rows,true)		// && (cerr << "readSOF55: ROWS = " << dec << ROWS << endl)
+	    && read16BE(in,columns) && (COLUMNS=columns,true)	// && (cerr << "readSOF55: COLUMNS = " << dec << COLUMNS << endl)
+	    && read8(in,ncomponents) && ncomponents == 1	// && (cerr << "readSOF55: ncomponents = " << dec << Uint16(ncomponents) << endl)
+	    && read8(in,componentid)				// && (cerr << "readSOF55: componentid = " << dec << Uint16(componentid) << endl)
+	    && read8(in,hvsampling)				// && (cerr << "readSOF55: hvsampling = " << dec << Uint16(hvsampling) << endl)
+	    && read8(in,quanttable)				// && (cerr << "readSOF55: quanttable = " << dec << Uint16(quanttable) << endl)
+	;
+}
+
+static bool
+readSOS(BinaryInputStream &in,Uint16 marker,Uint16 &NEAR)
+{
+	Uint16 length;
+	unsigned char ncomponents;
+	unsigned char componentid;
+	unsigned char mappingtable;
+	unsigned char near;
+	unsigned char ilv;
+	unsigned char dummy;
+	return marker == JPEG_MARKER_SOS
+	    && read16BE(in,length) && length == 8
+	    && read8(in,ncomponents) && ncomponents == 1
+	    && read8(in,componentid)
+	    && read8(in,mappingtable)
+	    && read8(in,near) && (NEAR=near,true)
+	    && read8(in,ilv)
+	    && read8(in,dummy);
+}
+
+static bool
+readLSE1(BinaryInputStream &in,Uint16 marker,Uint32 &MAXVAL,Uint16 &T1,Uint16 &T2,Uint16 &T3,Uint16 &RESET)
+{
+	Uint16 length;
+	unsigned char id;
+	Uint16 maxval;
+	return marker == JPEG_MARKER_LSE
+	    && read16BE(in,length) && length > 2
+	    && read8(in,id) && id == JPEG_LSE_ID_L1
+	    && length == 13
+	    && read16BE(in,maxval) && (MAXVAL=maxval,true)
+	    && read16BE(in,T1)
+	    && read16BE(in,T2)
+	    && read16BE(in,T3)
+	    && read16BE(in,RESET);
+}
+
+// JPEG-LS support routines ...
+
+static Uint16
+determineGolombParameter(Uint32 n,Uint32 a)
+{
+	Uint16 k;
+
+//cerr << "\t\tdetermineGolombParameter: n = " << n << endl;
+//cerr << "\t\tdetermineGolombParameter: a = " << a << endl;
+
+	Assert(n);			// Make sure we don't get out of control
+	for (k=0;(n<<k) < a; ++k)	// Number of occurrences vs accumulated error magnitude
+		Assert(k<31);		// ... internal limit ... don't exceed width of Uint32
+
+//cerr << "\t\tdetermineGolombParameter: k = " << k << endl;
+	return k;
+}
+
+static BinaryInputStream &
+decodeMappedErrvalWithGolomb(Uint16 k,Uint16 glimit,Uint16 qbpp,Uint32 &value,BinaryInputStream &in)
+{
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: k = " << k << endl;
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: glimit = " << glimit << endl;
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: qbpp = " << qbpp << endl;
+
+	// Read unary representation of remaining most significant bits
+
+	Uint32 bit;
+	Uint32 unarycode=0;
+	while (readBit(in,bit) && !bit) ++unarycode;	// stops after bit is 1 (having read and discared trailing 1 bit)
+//cerr << endl;
+
+	Uint32 offset;
+	Uint16 bitstoread;
+	Assert(glimit > qbpp+1);
+	Uint16 limit=glimit-qbpp-1;
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: unarycode = " << unarycode << endl;
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: limit = " << limit << endl;
+	if (unarycode < limit) {		// use it to form most significant bits
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: not limited, read " << unarycode << " zero bits (as value) followed by 1 then will read remaining " << k << " bits" << endl;
+		value=unarycode;		// will later get shifted into ms bits
+		bitstoread=k;
+		offset=0;
+	}
+	else {
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: limited, read " << unarycode << " zero bits followed by 1 then will read remaining " << qbpp << " bits of value-1" << endl;
+		value=0;			// no contribution from unary code ... whole value is next
+		bitstoread=qbpp;
+		offset=1;
+	}
+
+	// Read least significant k bits
+
+	while (bitstoread-- && readBit(in,bit)) value=(value<<1) | bit;	// msb bit is read first
+//cerr << endl;
+	value+=offset;				// correct for limited case 
+
+//cerr << "\t\tdecodeMappedErrvalWithGolomb: value = " << value << endl;
+	return in;
+}
+
+static BinaryOutputStream &
+encodeMappedErrvalWithGolomb(Uint16 k,Uint16 glimit,Uint16 qbpp,Uint32 value,BinaryOutputStream &out)
+{
+//cerr << "\t\tencodeMappedErrvalWithGolomb: k = " << k << " value = " << value << endl;
+//cerr << "\t\tencodeMappedErrvalWithGolomb: glimit = " << glimit << endl;
+//cerr << "\t\tencodeMappedErrvalWithGolomb: qbpp = " << qbpp << endl;
+
+	// A.5.3 Mapped-error encoding
+
+	Uint32 unarycode=value>>k;					// Most significant bits go into unary code
+
+	Assert(glimit > qbpp+1);
+	Uint16 limit=glimit-qbpp-1;
+
+//cerr << "\t\tencodeMappedErrvalWithGolomb: unarycode = " << unarycode << endl;
+//cerr << "\t\tencodeMappedErrvalWithGolomb: limit = " << limit << endl;
+
+	if (unarycode < limit) {
+//cerr << "\t\tencodeMappedErrvalWithGolomb: not limited, writing " << unarycode << " zero bits followed by 1 then remaining " << k << " bits" << endl;
+		while (unarycode--) writeBit(out,0);			// Append unary representation of remaining most significant bits
+		writeBit(out,1);					// Flag the end of the unary code
+		Uint16 bits=k;						// Append least significant k bits
+		while (bits--) { writeBit(out,(value>>bits)&1); } 	// msb bit is written first & use the decremented bits as shift
+	}
+	else {
+//cerr << "\t\tencodeMappedErrvalWithGolomb: limited, writing " << limit << " zero bits followed by 1 then remaining " << qbpp << " bits of value-1" << endl;
+		while (limit--) writeBit(out,0);			// Append limit 0 bits
+		writeBit(out,1);					// Flag the end of the unary code
+		value-=1;
+		while (qbpp--) { writeBit(out,(value>>qbpp)&1); } 	// write whole value (always of length qbpp)
+	}
+//cerr << endl;
+	return out;
+}
+
+static void
+quantizeErrval(Uint16 NEAR,Int32 &Errval)
+{
+//cerr << "\t\tquantizeErrval: before Errval = " << Errval << endl;
+
+	if (NEAR) {
+		if (Errval > 0)
+			Errval=(Errval+NEAR)/(2*NEAR+1);
+		else
+			Errval=(Errval-NEAR)/(2*NEAR+1);		// in A.4.4 it is actually -(NEAR-Errval)/(2*NEAR+1)
+	}
+	// else leave Errval as it is for lossless mode
+
+//cerr << "\t\tquantizeErrval: after Errval = " << Errval << endl;
+}
+
+static void
+deQuantizeErrval(Uint16 NEAR,Int32 &Errval)
+{
+//cerr << "\t\tdeQuantizeErrval: before Errval = " << Errval << endl;
+
+	if (NEAR) Errval=Errval*(2*NEAR+1);
+
+//cerr << "\t\tdeQuantizeErrval: after Errval = " << Errval << endl;
+}
+
+static inline void
+clampPredictedValue(Int32 &X,Int32 MAXVAL)
+{
+//cerr << "\t\tclampPredictedValue: before value = " << X << endl;
+
+	if      (X > MAXVAL)	X=MAXVAL;
+	else if (X < 0)		X=0;
+
+//cerr << "\t\tclampPredictedValue: after value = " << X << endl;
+}
+
+static void
+codecRunEndSample(Uint16 &Ix,Int32 Ra,Int32 Rb,Int32 RANGE,Uint16 NEAR,Uint32 MAXVAL,Uint16 RESET,
+		Uint16 LIMIT,Uint16 qbpp,Uint16 rk,
+		Uint32 *A,Int32 *N,Int32 *Nn,
+		BinaryInputStream &in,BinaryOutputStream &out,bool decompressing)
+{
+//cerr << "\t\tcodecRunEndSample: " << (decompressing ? "decoding" : "encoding") << endl;
+//if (!decompressing) cerr << "\t\tcodecRunEndSample: value = " << Ix << endl;
+
+	bool RItype = (Ra == Rb || Abs(Ra-Rb) <= NEAR);
+
+	Int16 SIGN = (!RItype && Ra > Rb) ? -1 : 1;
+
+	Int32 Px = RItype ? Ra : Rb;
+
+//cerr << "\t\tcodecRunEndSample: Ra = " << Ra << endl;
+//cerr << "\t\tcodecRunEndSample: Rb = " << Rb << endl;
+//cerr << "\t\tcodecRunEndSample: RItype = " << (RItype ? "1":"0") << endl;
+//cerr << "\t\tcodecRunEndSample: SIGN = " << SIGN << endl;
+//cerr << "\t\tcodecRunEndSample: Px = " << Px << endl;
+
+	Uint32 TEMP = RItype ? A[366]+(N[366]>>1) : A[365];
+
+	Uint16 Q = 365 + (RItype ? 1 : 0);
+
+//cerr << "\t\tcodecRunEndSample: TEMP = " << TEMP << endl;
+//cerr << "\t\tcodecRunEndSample: Q = " << Q << endl;
+
+	Uint16 k = determineGolombParameter(N[Q],TEMP);
+
+//cerr << "\t\tcodecRunEndSample: k = " << k << endl;
+
+	Int32  Errval;
+	Int32  updateErrval;
+	Uint32 EMErrval;
+
+	if (decompressing) {
+		decodeMappedErrvalWithGolomb(k,LIMIT-rk-1,qbpp,EMErrval,in);	// needs work :(
+
+//cerr << "\t\tcodecRunEndSample: EMErrval = " << EMErrval << endl;
+
+		Uint32 tEMErrval = EMErrval + (RItype ? 1 : 0);		// use local copy to leave original for parameter update later
+
+//cerr << "\t\tcodecRunEndSample: tEMErrval = " << tEMErrval << endl;
+
+		if (tEMErrval == 0) {
+			Errval = 0;
+		}
+		else if (k == 0) {
+			if (2*Nn[Q-365] < N[Q]) {
+				if (tEMErrval%2 == 0) {
+					Errval = -Int32(tEMErrval>>1);		// "map = 0"	2 becomes -1, 4 becomes -2, 6 becomes -3
+				}
+				else {
+					Errval = (tEMErrval+1)>>1;		// "map = 1"	1 becomes 1, 3 becomes 2, 5 becomes 3
+				}
+			}
+			else {	// 2*Nn[Q-365] >= N[Q]
+				if (tEMErrval%2 == 0) {
+					Errval = tEMErrval>>1;			// "map = 0"	2 becomes 1, 4 becomes 2, 6 becomes 3
+				}
+				else {
+					Errval = -Int32((tEMErrval+1)>>1);	// "map = 1"	1 becomes -1, 3 becomes -2, 5 becomes -3
+				}
+			}
+		}
+		else {
+			if (tEMErrval%2 == 0) {
+				Errval = tEMErrval>>1;				// "map = 0"	2 becomes  1, 4 becomes  2, 6 becomes 3
+			}
+			else {
+				Errval = -Int32((tEMErrval+1)>>1);		// "map = 1"	1 becomes -1, 3 becomes -2, 5 becomes -3
+			}
+		}
+
+
+//cerr << "\t\tcodecRunEndSample: Errval after sign unmapping = " << Errval << endl;
+
+		updateErrval=Errval;
+
+		if (NEAR > 0) deQuantizeErrval(NEAR,Errval);
+
+//cerr << "\t\tcodecRunEndSample: Errval SIGN uncorrected = " << Errval << endl;
+
+		if (SIGN < 0) Errval=-Errval;		// if "context type" was negative
+
+//cerr << "\t\tcodecRunEndSample: Errval result = " << Errval << endl;
+
+		Int32 Rx = Px+Errval;
+
+		// modulo(RANGE*(2*NEAR+1)) as per F.1 Item 14
+
+		// (NB. Is this really the reverse of the encoding procedure ???)
+
+		if (Rx < -NEAR)
+			Rx+=RANGE*(2*NEAR+1);
+		else if (Rx > MAXVAL+NEAR)
+			Rx-=RANGE*(2*NEAR+1);
+
+		clampPredictedValue(Rx,MAXVAL);
+
+		// Apply inverse point transform and mapping table when implemented
+
+		Ix=(Uint16)Rx;
+	}
+	else {
+//cerr << "\t\tIx " << Ix << endl;
+		Errval = Int32(Ix) - Px;
+//cerr << "\t\tErrval " << Errval << endl;
+
+		if (SIGN < 0) Errval=-Errval;		// if "context type" was negative
+
+//cerr << "\t\tErrval sign corrected " << Errval << endl;
+
+		// Figure out sign to later correct Errval (Figure A.19) ...
+
+		if (NEAR > 0) {	// For near-lossless, quantize Errval and derive reconstructed value (A.4.4)
+
+			quantizeErrval(NEAR,Errval);
+
+//cerr << "\t\tErrval quantized " << Errval << endl;
+
+			// Replace with the reconstructed value the decoder will have
+			// (obviously if in lossless mode there will be no difference)
+
+			Int32 Rx=Px+SIGN*Errval*(2*NEAR+1);
+			clampPredictedValue(Rx,MAXVAL);
+					
+			Ix=(Uint16)Rx;
+//cerr << "\t\tReplaced Rx " << Rx << endl;
+		}
+
+		// Modulo reduction of the prediction error (A.4.5)
+
+		if (Errval < 0)			Errval=Errval+RANGE;
+		if (Errval >= (RANGE+1)/2)	Errval=Errval-RANGE;
+
+//cerr << "\t\tErrval modulo " << RANGE << " = " << Errval << endl;
+
+		updateErrval=Errval;
+
+		// Golomb stuff is outside decompress/compress decision since same
+
+		// Map error to non-negative ...
+
+		// Int16 map = ((k == 0 && Errval > 0 && 2*Nn[Q-365] < N[Q]) || (Errval < 0 && (2*Nn[Q-365] >= N[Q] || k != 0)) ? 1 : 0;
+		// EMErrval = 2*Abs(Errval) - RItype - map;
+
+		if (k == 0) {
+			if (Errval > 0) {
+				if (2*Nn[Q-365] < N[Q]) {
+					EMErrval = 2*Errval - 1;		// "map = 1"	1 becomes 1, 2 becomes 3, 3 becomes 5
+				}
+				else {	// 2*Nn[Q-365] >= N[Q]
+					EMErrval = 2*Errval;			// "map = 0"	1 becomes 2, 2 becomes 4, 3 becomes 6
+				}
+			}
+			else if (Errval < 0) {
+				if (2*Nn[Q-365] < N[Q]) {
+					EMErrval = -2*Errval;			// "map = 0"	-1 becomes 2, -2 becomes 4, -3 becomes 6
+				}
+				else {	// 2*Nn[Q-365] >= N[Q]
+					EMErrval = -2*Errval - 1;		// "map = 1"	-1 becomes 1, -2 becomes 3, -3 becomes 5
+				}
+			}
+			else { // Errval == 0
+				EMErrval = 0;					// "map = 0"	0 stays 0
+			}
+		}
+		else {	// k != 0
+			if (Errval > 0) {
+				EMErrval = 2*Errval;				// "map = 0"	1 becomes 2, 2 becomes 4, 3 becomes 6
+			}
+			else if (Errval < 0) {
+				EMErrval = -2*Errval - 1;			// "map = 1"	-1 becomes 1, -2 becomes 3, -3 becomes 5
+			}
+			else { // Errval == 0
+				EMErrval = 0;					// "map = 0"	0 stays 0
+			}
+		}
+
+//cerr << "\t\tcodecRunEndSample: EMErrval before subtraction of RItype = " << EMErrval << endl;
+
+		EMErrval-=(RItype ? 1 : 0);
+
+//cerr << "\t\tcodecRunEndSample: EMErrval after subtraction of RItype = " << EMErrval << endl;
+
+		encodeMappedErrvalWithGolomb(k,LIMIT-rk-1,qbpp,EMErrval,out);
+	}
+
+	// Update parameters ...
+
+//cerr << "\t\tcodecRunEndSample: Update parameters ... updateErrval used = " << updateErrval << endl;
+//cerr << "\t\tcodecRunEndSample: Update parameters ... EMErrval used = " << EMErrval << endl;
+
+//cerr << "\t\tcodecRunEndSample: A[" << Q << "]  before = " << A[Q]  << endl;
+//cerr << "\t\tcodecRunEndSample: N[" << Q << "]  before = " << N[Q]  << endl;
+//cerr << "\t\tcodecRunEndSample: Nn[" << (Q-365) << "] before = " << Nn[Q-365] << endl;
+
+	if (updateErrval < 0) ++Nn[Q-365];
+	A[Q]+=(EMErrval+1-(RItype ? 1 : 0))>>1;
+	if (N[Q] == RESET) {
+		A[Q]=A[Q]>>1;
+		N[Q]=N[Q]>>1;
+		Nn[Q-365]=Nn[Q-365]>>1;
+	}
+	++N[Q];
+
+//cerr << "\t\tcodecRunEndSample: A[" << Q << "]  updated = " << A[Q]  << endl;
+//cerr << "\t\tcodecRunEndSample: N[" << Q << "]  updated = " << N[Q]  << endl;
+//cerr << "\t\tcodecRunEndSample: Nn[" << (Q-365) << "] updated = " << Nn[Q-365] << endl;
+
+//if (decompressing) cerr << "\t\tcodecRunEndSample: value = " << Ix << endl;
+}
+
+int
+main(int argc,char **argv)
+{
+	bool bad=false;
+
+	GetNamedOptions				options(argc,argv);
+	BinaryInputOptionsWithByteOrder		input_options(options);
+	BinaryOutputOptionsWithByteOrder	output_options(options);
+
+	bool verbose=options.get("v") || options.get("verbose");
+
+	bool decompressing=options.get("d") || options.get("decompress");
+	bool useJPEGmarkers=!options.get("nomarkers");
+	bool useRunMode=!options.get("noruns");
+
+	unsigned rows=0;
+	if ((!decompressing || !useJPEGmarkers) && !options.get("rows",rows) && !options.get("height",rows) && !options.get("h",rows)) {
+		cerr << EMsgDC(NeedOption) << " - rows" << endl;
+		bad=true;
+	}
+	unsigned cols=0;
+	if ((!decompressing || !useJPEGmarkers) && !options.get("columns",cols) && !options.get("width",cols) && !options.get("w",cols)) {
+		cerr << EMsgDC(NeedOption) << " - columns" << endl;
+		bad=true;
+	}
+	unsigned bits=0;
+	if ((!decompressing || !useJPEGmarkers) && !options.get("bits",bits) && !options.get("depth",bits)) {
+		cerr << EMsgDC(NeedOption) << " - bits" << endl;
+		bad=true;
+	}
+	Assert(bits <= 16);
+
+	Uint16 NEAR=0;		// Lossless if zero
+	Uint16 T1=0;
+	Uint16 T2=0;
+	Uint16 T3=0;
+	Uint16 RESET=0;
+	if ((!decompressing || !useJPEGmarkers)) {
+		unsigned near;	if (options.get("near",near))				NEAR=near;
+		unsigned t1;	if (options.get("T1",t1) || options.get("Ta",t1))	T1=t1;
+		unsigned t2;	if (options.get("T2",t2) || options.get("Tb",t2))	T2=t2;
+		unsigned t3;	if (options.get("T3",t3) || options.get("Tc",t3))	T3=t3;
+		unsigned reset;	if (options.get("reset",reset))				RESET=reset;
+	}
+
+	input_options.done();
+	output_options.done();
+	options.done();
+
+	BinaryInputOpenerFromOptions input_opener(
+		options,input_options.filename,cin);
+	BinaryOutputOpenerFromOptions output_opener(
+		options,output_options.filename,cout);
+
+	cerr << input_options.errors();
+	cerr << output_options.errors();
+	cerr << options.errors();
+	cerr << input_opener.errors();
+	cerr << output_opener.errors();
+
+	if (!input_options.good()
+	 || !output_options.good()
+	 || !options.good()
+	 || !input_opener.good()
+	 || !output_opener.good()
+	 || !options
+	 || bad) {
+		cerr 	<< MMsgDC(Usage) << ": " << options.command()
+			<< input_options.usage()
+			<< output_options.usage()
+			<< " [-d|decompress]"
+			<< " -rows|height|h n"
+			<< " -columns|width|w n"
+			<< " -bits|depth n"
+			<< " [-near n]"
+			<< " [-T1|Ta n]"
+			<< " [-T2|Tb n]"
+			<< " [-T3|Tc n]"
+			<< " [-reset n]"
+			<< " [-nomarkers]"
+			<< " [-noruns]"
+			<< " [-v|verbose]"
+			<< " [" << MMsgDC(InputFile)
+				<< "[" << MMsgDC(OutputFile) << "]]"
+			<< " <" << MMsgDC(InputFile)
+			<< " >" << MMsgDC(OutputFile)
+			<< endl;
+		exit(1);
+	}
+
+	BinaryInputStream in(*(istream *)input_opener,input_options.byteorder);
+	BinaryOutputStream out(*(ostream *)output_opener,output_options.byteorder);
+
+	bool success=true;
+
+	Uint32 ROWS;
+	Uint32 COLUMNS;
+	Uint16 P;		// Sample precision
+	Uint32 MAXVAL;
+
+	bool haveLSE1=false;
+
+	if (decompressing && useJPEGmarkers) {
+		bool readrequiredmarkers=false;
+		Uint16 marker;
+		if (readJPEGMarker(in,marker) && readSOI(in,marker)) {
+			if (readJPEGMarker(in,marker) && readSOF55(in,marker,P,ROWS,COLUMNS)
+			 || (haveLSE1=readLSE1(in,marker,MAXVAL,T1,T2,T3,RESET)) && readJPEGMarker(in,marker) && readSOF55(in,marker,P,ROWS,COLUMNS)) {
+				if (readJPEGMarker(in,marker) && readSOS(in,marker,NEAR)
+				 || !haveLSE1 && (haveLSE1=readLSE1(in,marker,MAXVAL,T1,T2,T3,RESET)) && readJPEGMarker(in,marker) && readSOS(in,marker,NEAR)) {
+
+					readrequiredmarkers=true;
+				}
+				else {
+					cerr << "Corrupt JPEG stream ... expected SOS Marker" << endl;
+				}
+			}
+			else {
+				cerr << "Corrupt JPEG stream ... expected SOF55 Marker" << endl;
+			}
+		}
+		else {
+			cerr << "Corrupt JPEG stream ... expected SOI Marker" << endl;
+		}
+
+		if (!readrequiredmarkers) {
+			exit(1);
+		}
+	}
+	else {
+		P=bits;
+		ROWS=rows;
+		COLUMNS=cols;
+	}
+
+	if (!decompressing || !useJPEGmarkers || !haveLSE1) {	// Note that the LSE ID 1 marker is optional
+		MAXVAL=(1ul<<P)-1;
+
+		if (!RESET) RESET=64;		// May have been set on command line
+
+		// Initialization of default parameters as per A.1 reference to C.2.4.1.1.1
+
+		// Thresholds for context gradients ...
+
+		const Uint32 BASIC_T1 = 3;
+		const Uint32 BASIC_T2 = 7;
+		const Uint32 BASIC_T3 = 21;
+
+#define CLAMP_1(i)	((i > MAXVAL || i < NEAR+1) ? NEAR+1 : i)
+#define CLAMP_2(i)	((i > MAXVAL || i < T1) ? T1 : i)
+#define CLAMP_3(i)	((i > MAXVAL || i < T2) ? T2 : i)
+
+		// Only replace T1, T2, T3 if not set on command line ...
+
+		if (MAXVAL >= 128) {
+			Uint32 FACTOR=FloorDivision(Minimum(MAXVAL,4095)+128,256);
+			if (verbose) cerr << "MAXVAL >= 128" << endl;
+			if (verbose) cerr << "FACTOR = " << dec << FACTOR << endl;
+			if (!T1) T1=CLAMP_1(FACTOR*(BASIC_T1-2)+2+3*NEAR);
+			if (!T2) T2=CLAMP_2(FACTOR*(BASIC_T2-3)+3+5*NEAR);
+			if (!T3) T3=CLAMP_3(FACTOR*(BASIC_T3-4)+4+7*NEAR);
+		}
+		else {
+			Uint32 FACTOR=FloorDivision(256,MAXVAL+1);
+			if (verbose) cerr << "MAXVAL < 128" << endl;
+			if (verbose) cerr << "FACTOR = " << dec << FACTOR << endl;
+			if (!T1) T1=CLAMP_1(Maximum(2,BASIC_T1/FACTOR+3*NEAR));	// ? should these calculations be float since we are dividing ? :(
+			if (!T2) T2=CLAMP_2(Maximum(3,BASIC_T2/FACTOR+5*NEAR));
+			if (!T3) T3=CLAMP_3(Maximum(4,BASIC_T3/FACTOR+7*NEAR));
+		}
+
+	}
+
+	if (verbose) cerr << "NEAR = " << NEAR << endl;
+	if (verbose) cerr << "ROWS = " << ROWS << endl;
+	if (verbose) cerr << "COLUMNS = " << COLUMNS << endl;
+	if (verbose) cerr << "P = " << P << endl;
+	if (verbose) cerr << "MAXVAL = " << MAXVAL << endl;
+	if (verbose) cerr << "RESET = " << RESET << endl;
+	if (verbose) cerr << "T1 = " << T1 << endl;
+	if (verbose) cerr << "T2 = " << T2 << endl;
+	if (verbose) cerr << "T3 = " << T3 << endl;
+
+	Assert(ROWS);
+	Assert(COLUMNS);
+	Assert(P);
+	Assert(T1 == 0 || (NEAR+1 <= T1 && T1 <= MAXVAL));
+	Assert(T2 == 0 || (T1 <= T2 && T2 <= MAXVAL));
+	Assert(T3 == 0 || (T2 <= T3 && T3 <= MAXVAL));
+
+	// Initialization as per Annex A.2.1
+
+	Int32 RANGE = FloorDivision(MAXVAL+2*NEAR,2*NEAR+1)+1;	// int not unsigned to avoid need for cast when used
+
+	if (verbose) cerr << "RANGE = " << RANGE << endl;
+
+	Assert(MAXVAL == 0 || (1 <= MAXVAL && MAXVAL < 1ul<<P));
+	if (NEAR == 0) Assert(RANGE == MAXVAL+1);
+
+	Uint16 bpp = Maximum(2,Ceiling(Log(MAXVAL+1)));	// Number of bits needed to represent MAXVAL with a minumum of 2
+	Uint16 qbpp = Ceiling(Log(RANGE));		// Number of bits needed to represent a mapped error value
+	Uint16 LIMIT = 2*(bpp+Maximum(8,bpp));		// the value of glimit for a sample encoded in regular mode
+
+	if (verbose) cerr << "bpp = " << bpp << endl;
+	if (verbose) cerr << "qbpp = " << qbpp << endl;
+	if (verbose) cerr << "LIMIT = " << LIMIT << endl;
+
+	Assert(bpp >= 2);
+	Assert(LIMIT > qbpp);			// Else LIMIT-qbpp-1 will fail (see A.5.3)
+
+	if (!decompressing && useJPEGmarkers)  {
+		writeSOI(out);
+		writeSOF55(out,P,ROWS,COLUMNS);
+		writeLSE1(out,MAXVAL,T1,T2,T3,RESET);
+		writeSOS(out,NEAR);
+	}
+
+	// Fixed constants
+
+	const Uint16 nContexts = 365;	// plus two more run mode interruption contexts
+
+	const Int32 MIN_C = -128;	// Limits on values in bias correction array C
+	const Int32 MAX_C =  127;
+
+	// Initialization of variables ...
+
+	Int32	*N = new Int32[nContexts+2];	// counters for context type occurence [0..nContexts+2-1]
+						// [nContexts],[nContexts+1] for run mode interruption
+	Uint32	*A = new Uint32[nContexts+2];	// accumulated prediction error magnitude [0..nContexts-1]
+						// [nContexts],[nContexts+1] for run mode interruption
+	Int32	*B = new Int32[nContexts];	// auxilliary counters for bias cancellation [0..nContexts-1]
+	Int32	*C = new Int32[nContexts];	// counters indicating bias correction value [0..nContexts-1]
+						// (never -ve but often used as -N[Q] so int not unsigned saves cast)
+
+	Int32	*Nn = new Int32[2];		// negative prediction error for run interruption [365..366]
+
+	Assert(N);
+	Assert(A);
+	Assert(B);
+	Assert(C);
+	Assert(Nn);
+
+	{
+		Uint32 A_Init_Value=Maximum(2,FloorDivision(RANGE+(1lu<<5),(1lu<<6)));
+		if (verbose) cerr << "A_Init_Value = " << A_Init_Value << endl;
+		unsigned i;
+		for (i=0; i<nContexts; ++i) {
+			N[i]=1;
+			A[i]=A_Init_Value;
+			B[i]=C[i]=0;
+		}
+		N[nContexts]=1;
+		N[nContexts+1]=1;
+		A[nContexts]=A_Init_Value;
+		A[nContexts+1]=A_Init_Value;
+	}
+
+	Nn[365-365]=Nn[366-365]=0;
+
+	// The run variables seem to need to live beyond a single run or row !!!
+
+	unsigned RUNIndex = 0;
+
+	Uint16 *rowA = new Uint16[COLUMNS];
+	Uint16 *rowB = new Uint16[COLUMNS];
+	Assert(rowA);
+	Assert(rowB);
+
+	Uint32 row=0;
+	Uint16 *thisRow=rowA;
+	Uint16 *prevRow=rowB;
+	for (row=0; row<ROWS; ++row) {
+//cerr << "Row " << row << endl;
+		if (!decompressing)  {
+			Uint32 n=readRow(in,thisRow,COLUMNS,bpp);
+//cerr << "Row " << row << " read returns " << n << endl;
+			Assert (n==COLUMNS);
+		}
+
+		Uint32 col=0;
+		Uint16 prevRa0;
+		for (col=0; col<COLUMNS; ++col) {
+
+//cerr << "\tcol = " << col << endl;
+
+			//	c b d .
+			//	a x . .
+			//	. . . .
+
+			Int32 Rx;	// Reconstructed value - not Uint16 to allow overrange before clamping
+
+			// value at edges (first row and first col is zero) ...
+
+			Uint16 Ra;
+			Uint16 Rb;
+			Uint16 Rc;
+			Uint16 Rd;
+
+			if (row > 0) {
+				Rb=prevRow[col];
+				Rc=(col > 0) ? prevRow[col-1] : prevRa0;
+				Ra=(col > 0) ? thisRow[col-1] : (prevRa0=Rb);
+				Rd=(col+1 < COLUMNS) ? prevRow[col+1] : Rb;
+			}
+			else {
+				Rb=Rc=Rd=0;
+				Ra=(col > 0) ? thisRow[col-1] : (prevRa0=0);
+			}
+				
+//cerr << "\t\tRa = " << Ra << endl;
+//cerr << "\t\tRb = " << Rb << endl;
+//cerr << "\t\tRc = " << Rc << endl;
+//cerr << "\t\tRd = " << Rd << endl;
+
+			// NB. We want the Reconstructed values, which are the same
+			// in lossless mode, but if NEAR != 0 take care to write back
+			// reconstructed values into the row buffers in previous positions
+
+			// Compute local gradient ...
+
+			Int32 D1=(Int32)Rd-Rb;
+			Int32 D2=(Int32)Rb-Rc;
+			Int32 D3=(Int32)Rc-Ra;
+
+//cerr << "\t\tD1 = " << D1 << endl;
+//cerr << "\t\tD2 = " << D2 << endl;
+//cerr << "\t\tD3 = " << D3 << endl;
+
+			// Check for run mode ... (should check Abs() works ok for Int32)
+
+			if (Abs(D1) <= NEAR && Abs(D2) <= NEAR && Abs(D3) <= NEAR && useRunMode) {
+				// Run mode
+
+//cerr << "Row at run start " << row << endl;
+//cerr << "\tcol at run start " << col << endl;
+				if (decompressing) {
+//dumpReadBitPosition();
+					// Why is RUNIndex not reset to 0 here ?
+					Uint32 R;
+					while (readBit(in,R)) {
+//cerr << "\tcol " << col << endl;
+						if (R == 1) {
+							// Fill image with 2^J[RUNIndex] samples of Ra or till EOL
+							Int32 rm=J_rm[RUNIndex];
+//cerr << "\tRUNIndex " << RUNIndex << endl;
+//cerr << "\tFilling with " << rm << " samples of Ra " << Ra << endl;
+							while (rm-- && col < COLUMNS) {
+								thisRow[col]=Ra;
+//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+								++col;
+							}
+							// This will match when exact count coincides with end of row ...
+							if (rm == -1 && RUNIndex < 31) {
+								++RUNIndex;
+//cerr << "\tRUNIndex incremented to " << RUNIndex << endl;
+							}
+							if (col >= COLUMNS) {
+//cerr << "\tFilled to end of row" << endl;
+//cerr << "\tAfter having found end of row " << endl;
+//dumpReadBitPosition();
+								break;
+							}
+						}
+						else {
+							// Read J[RUNIndex] bits and fill image with that number of samples of Ra
+							Uint16 bits=J[RUNIndex];
+//cerr << "\tRUNIndex " << RUNIndex << endl;
+//cerr << "\tReading bits " << bits << endl;
+							Uint32 nfill=0;
+							Uint32 bit;
+							// msb bit is read first
+							while (bits-- && readBit(in,bit)) {
+								nfill=(nfill<<1) | bit;
+							}
+//cerr << "\tFill with " << nfill << " samples of Ra " << Ra << endl;
+							// Fill with nfill values of Ra
+							while (nfill--) {
+//if (!(col<(COLUMNS-1))) {
+//	cerr << "Fail at line 367 ... !(col<(COLUMNS-1))" << endl;
+//	cerr << "\tstill to fill " << nfill+1 << endl;
+//	cerr << "\trow is " << row << endl;
+//	cerr << "\tcol is " << col << endl;
+//}
+								Assert(col<(COLUMNS-1));
+								thisRow[col]=Ra;
+//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+								++col;
+							}
+							// Decode the run interruption sample ...
+//cerr << "\tcol at end of run " << col << endl;
+//cerr << "\tBefore decoding value that ends run " << endl;
+//dumpReadBitPosition();
+
+							// First update local context for interrupting sample, since weren't kept updated during run
+
+							if (row > 0) {
+								Rb=prevRow[col];
+								Ra=(col > 0) ? thisRow[col-1] : Rb;
+							}
+							else {
+								Rb=0;
+								Ra=(col > 0) ? thisRow[col-1] : 0;
+							}
+//cerr << "\t\tRa = " << Ra << endl;
+//cerr << "\t\tRb = " << Rb << endl;
+							codecRunEndSample(thisRow[col],Ra,Rb,RANGE,NEAR,MAXVAL,RESET,LIMIT,qbpp,J[RUNIndex],A,N,Nn,in,out,decompressing);
+//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+//cerr << "\tValue that ends run " << thisRow[col] << endl;
+//dumpReadBitPosition();
+							if (RUNIndex > 0) {
+								--RUNIndex;	// NB. Do this AFTER J[RUNIndex] used in the limited length Golomb coding
+//cerr << "\tRUNIndex decremented to " << RUNIndex << endl;
+							}
+
+							break;
+						}
+					}
+				}
+				else {
+//dumpWriteBitPosition();
+					// Scan to determine length of run (A.7.1.1) ...
+//cerr << "\tScan to determine length of run" << endl;
+//cerr << "\tRa is " << Ra << endl;
+					Int32 RUNval=Ra;
+					Int32 RUNcnt=0;
+					while (col < COLUMNS && (thisRow[col] == RUNval || (NEAR > 0 && Abs(Int32(thisRow[col])-RUNval) <= NEAR) ) ) {
+//cerr << "\tpixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+						++RUNcnt;
+						if (NEAR > 0) thisRow[col]=RUNval;	// Replace with "reconstructed value"
+						++col;
+					}
+//cerr << "\tAt end of run, thisRow[" << row << "," << col << "] = " << thisRow[col] << " and RUNval = " << RUNval << endl;
+//cerr << "\tAbs(Int32(thisRow[col])-RUNval) = " << Abs(Int32(thisRow[col])-RUNval) << endl;
+//cerr << "\tNEAR = " << NEAR << endl;
+//cerr << "\tRUNcnt " << RUNcnt << endl;
+					// Encode length of run (A.7.1.2) ...
+
+					Uint16 rm;
+					while (RUNcnt >= (rm=J_rm[RUNIndex])) {
+//cerr << "\tRUNIndex " << RUNIndex << endl;
+//cerr << "\trm " << rm << endl;
+						writeBit(out,1);
+						RUNcnt-=rm;
+//cerr << "\tRUNcnt decremented to " << RUNcnt << endl;
+						Assert(RUNcnt >= 0);	// is why int not unsigned
+						if (RUNIndex < 31) {	// ie. value ranges from 0..31
+							++RUNIndex;
+//cerr << "\tRUNIndex incremented to " << RUNIndex << endl;
+						}
+					}
+
+					if (col < COLUMNS) {	// Must have been terminated by different value
+//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+//cerr << "\tcol " << col << endl;
+//cerr << "\tDifferent value is " << thisRow[col] << endl;
+						writeBit(out,0);
+						// Append least significant J[RUNIndex] bits
+						Uint16 bits=J[RUNIndex];
+						Uint32 value=RUNcnt;
+						Assert(value < J_rm[RUNIndex]);	// Does it really fit in this ? It should else would have been coded by J_rm[RUNIndex]
+//cerr << "\tRemaining RUNcnt " << RUNcnt << endl;
+//cerr << "\tEncoding in bits " << bits << endl;
+						// msb bit is written first
+						while (bits--) {
+							Uint32 bit=(value>>bits)&1;
+							writeBit(out,bit);  // use the decremented bits as shift
+						}
+
+						// Encode run interruption sample (A.7.2) ...
+//cerr << "\tcol at end of run " << col << endl;
+						Assert(col<COLUMNS);
+//cerr << "\tBefore encoding value that ends run " << endl;
+//dumpWriteBitPosition();
+//cerr << "\tValue that ends run " << thisRow[col] << endl;
+
+						// First update local context for interrupting sample, since weren't kept updated during run
+
+						if (row > 0) {
+							Rb=prevRow[col];
+							Ra=(col > 0) ? thisRow[col-1] : Rb;
+						}
+						else {
+							Rb=0;
+							Ra=(col > 0) ? thisRow[col-1] : 0;
+						}
+//cerr << "\t\tUpdated Ra = " << Ra << endl;
+//cerr << "\t\tUpdated Rb = " << Rb << endl;
+
+						codecRunEndSample(thisRow[col],Ra,Rb,RANGE,NEAR,MAXVAL,RESET,LIMIT,qbpp,J[RUNIndex],A,N,Nn,in,out,decompressing);
+
+//cerr << "\tAfter encoding value that ends run " << endl;
+//dumpWriteBitPosition();
+						if (RUNIndex > 0) {
+							--RUNIndex;	// NB. Do this AFTER J[RUNIndex] used in the limited length Golomb coding
+//cerr << "\tRUNIndex decremented to " << RUNIndex << endl;
+						}
+					}
+					else {						// Aborted at end of row
+//cerr << "\tEnd of row" << endl;
+						if (RUNcnt > 0) {
+							writeBit(out,1);		// Append an extra 1
+											// decoder knows to stop at end of row
+											// though remainder can't be > 1<<J[RUNIndex]
+//cerr << "1 for end of row" << endl;
+//cerr << "\tAfter indicating end of row " << endl;
+//dumpWriteBitPosition();
+						}
+					}
+				}
+
+			}
+			else
+				{
+
+				// Regular mode
+
+				// Gradient quantization ... (A.3.3)
+
+				Int16 Q1,Q2,Q3;
+
+				if      (D1 <= -T3)   Q1=-4;
+				else if (D1 <= -T2)   Q1=-3;
+				else if (D1 <= -T1)   Q1=-2;
+				else if (D1 <  -NEAR) Q1=-1;
+				else if (D1 <=  NEAR) Q1= 0;
+				else if (D1 <   T1)   Q1= 1;
+				else if (D1 <   T2)   Q1= 2;
+				else if (D1 <   T3)   Q1= 3;
+				else                  Q1= 4;
+
+				if      (D2 <= -T3)   Q2=-4;
+				else if (D2 <= -T2)   Q2=-3;
+				else if (D2 <= -T1)   Q2=-2;
+				else if (D2 <  -NEAR) Q2=-1;
+				else if (D2 <=  NEAR) Q2= 0;
+				else if (D2 <   T1)   Q2= 1;
+				else if (D2 <   T2)   Q2= 2;
+				else if (D2 <   T3)   Q2= 3;
+				else                  Q2= 4;
+
+				if      (D3 <= -T3)   Q3=-4;
+				else if (D3 <= -T2)   Q3=-3;
+				else if (D3 <= -T1)   Q3=-2;
+				else if (D3 <  -NEAR) Q3=-1;
+				else if (D3 <=  NEAR) Q3= 0;
+				else if (D3 <   T1)   Q3= 1;
+				else if (D3 <   T2)   Q3= 2;
+				else if (D3 <   T3)   Q3= 3;
+				else                  Q3= 4;
+
+//cerr << "\t\tQ1 = " << Q1 << endl;
+//cerr << "\t\tQ2 = " << Q2 << endl;
+//cerr << "\t\tQ3 = " << Q3 << endl;
+
+				// Context merging and determination of SIGN ... (A.3.4)
+
+				Int16 SIGN;
+
+				// "If the 1st non-zero component of vector (Q1,Q2,Q3) is negative" ...
+
+				if ( Q1 < 0
+				 || (Q1 == 0 && Q2 < 0)
+				 || (Q1 == 0 && Q2 == 0 && Q3 < 0) ) {
+					Q1=-Q1;
+					Q2=-Q2;
+					Q3=-Q3;
+					SIGN=-1;	// signifies -ve
+				}
+				else {
+					SIGN=1;		// signifies +ve
+				}
+
+//cerr << "\t\tSIGN= " << SIGN << endl;
+
+//cerr << "\t\tQ1 after SIGN = " << Q1 << endl;
+//cerr << "\t\tQ2 after SIGN = " << Q2 << endl;
+//cerr << "\t\tQ3 after SIGN = " << Q3 << endl;
+
+				// The derivation of Q is not specified in the standard :(
+
+				// Let's try this approach ....
+
+				// Q1 can be 0 to 4 only
+				// Q1 1 to 4 and Q2 -4 to 4 and Q3 -4 to 4	= 4*9*9 = 324
+				// Q1 0 and Q2 1 to 4 only and Q3 -4 to 4	= 1*4*9 = 36
+				// Q1 0 and Q2 0 and Q3 0 to 4			= 1*1*5 = 5
+				// total of 365
+				// and 0,0,0 (Q == 360) only occurs for run mode or regular mode with sample interleaved
+
+				Uint16 Q;
+
+				if (Q1 == 0) {
+					if (Q2 == 0) {
+						Q=360+Q3;		// fills 360..364
+					}
+					else {	// Q2 is 1 to 4
+						Q=324+(Q2-1)*9+(Q3+4);	// fills 324..359
+					}
+				}
+				else {		// Q1 is 1 to 4
+					Q=(Q1-1)*81+(Q2+4)*9+(Q3+4);	// fills 0..323
+				}
+
+//cerr << "\t\tQ = " << Q << endl;
+
+//if (Q >= nContexts) {
+//	cerr << "\t\tQ1 after SIGN = " << Q1 << endl;
+//	cerr << "\t\tQ2 after SIGN = " << Q2 << endl;
+//	cerr << "\t\tQ3 after SIGN = " << Q3 << endl;
+//	cerr << "\t\tQ itself = " << Q << endl;
+//}
+				Assert(Q<nContexts);	// Just in case
+
+				// Figure A.5 Edge detecting predictor ...
+
+				Int32 Px;	// Predicted value - not Uint16 to allow overrange before clamping
+
+				if      (Rc >= Maximum(Ra,Rb))	Px = Minimum(Ra,Rb);
+				else if (Rc <= Minimum(Ra,Rb))	Px = Maximum(Ra,Rb);
+				else				Px = (Int32)Ra+Rb-Rc;
+
+//cerr << "\t\tPx = " << Px << endl;
+
+				// Figure A.6 Prediction correction and clamping ...
+
+				Px = Px + ((SIGN > 0) ? C[Q] : -C[Q]);
+
+//cerr << "\t\tC[Q] = " << C[Q] << endl;
+//cerr << "\t\tPx corrected = " << Px << endl;
+
+				clampPredictedValue(Px,MAXVAL);
+
+//cerr << "\t\tPx clamped = " << Px << endl;
+
+				// Figure A.10 Prediction error Golomb encoding and decoding...
+
+				Uint16 k = determineGolombParameter(N[Q],A[Q]);
+				
+				Uint32 MErrval;
+				Int32 Errval;
+				Int32 updateErrval;
+
+				if (decompressing) {
+					// Decode Golomb mapped error from input...
+					decodeMappedErrvalWithGolomb(k,LIMIT,qbpp,MErrval,in);
+
+//cerr << "\t\tMErrval = " << MErrval << endl;
+
+					// Unmap error from non-negative (inverse of A.5.2 Figure A.11) ...
+
+					if (NEAR == 0 && k == 0 && 2*B[Q] <= -N[Q]) {
+						if (MErrval%2 != 0)
+							Errval=((Int32)MErrval-1)/2;	//  1 becomes  0,  3 becomes  1,  5 becomes  2
+						else
+							Errval=-(Int32)MErrval/2 - 1;	//  0 becomes -1,  2 becomes -2,  4 becomes -3
+					}
+					else {
+						if (MErrval%2 == 0)
+							Errval=(Int32)MErrval/2;	//  0 becomes  0, 2 becomes  1,  4 becomes  2
+						else
+							Errval=-((Int32)MErrval + 1)/2;	//  1 becomes -1, 3 becomes -2
+					}
+
+					updateErrval=Errval;			// NB. Before dequantization and sign correction
+
+					deQuantizeErrval(NEAR,Errval);
+
+//cerr << "\t\tErrval SIGN uncorrected = " << Errval << endl;
+
+					if (SIGN < 0) Errval=-Errval;		// if "context type" was negative
+
+//cerr << "\t\tErrval result = " << Errval << endl;
+
+					Rx=Px+Errval;
+
+					// modulo(RANGE*(2*NEAR+1)) as per F.1 Item 14
+
+					// (NB. Is this really the reverse of the encoding procedure ???)
+
+					if (Rx < -NEAR)
+						Rx+=RANGE*(2*NEAR+1);
+					else if (Rx > MAXVAL+NEAR)
+						Rx-=RANGE*(2*NEAR+1);
+
+					clampPredictedValue(Rx,MAXVAL);
+
+					// Apply inverse point transform and mapping table when implemented
+
+					thisRow[col]=(Uint16)Rx;
+//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+				}
+				else {	// compressing ...
+
+					Int32 Ix = thisRow[col];	// Input value - not Uint16 to allow overrange before clamping
+//cerr << "pixel[" << row << "," << col << "] = " << thisRow[col] << endl;
+
+					Errval = Ix - Px;		// watch this for bad unsigned->signed conversion :(
+
+//cerr << "\t\tErrval start = " << Errval << endl;
+
+					if (SIGN < 0) Errval=-Errval;	// if "context type" was negative
+
+//cerr << "\t\tErrval SIGN corrected = " << Errval << endl;
+
+					if (NEAR > 0) {	// For near-lossless, quantize Errval and derive reconstructed value (A.4.4)
+
+						quantizeErrval(NEAR,Errval);
+
+						// Replace with the reconstructed value the decoder will have
+						// (obviously if in lossless mode there will be no difference)
+
+						Rx=Px+SIGN*Errval*(2*NEAR+1);
+						clampPredictedValue(Rx,MAXVAL);
+					
+						thisRow[col]=(Uint16)Rx;
+					}
+
+					// Modulo reduction of the prediction error (A.4.5)
+
+					if (Errval < 0)			Errval=Errval+RANGE;
+					if (Errval >= (RANGE+1)/2)	Errval=Errval-RANGE;
+
+//cerr << "\t\tErrval modulo " << RANGE << " = " << Errval << endl;
+
+					updateErrval=Errval;			// NB. After sign correction but before mapping
+
+					// Prediction error encoding (A.5)
+
+					// Golomb k parameter determined already outside decompress/compress test
+
+					// Map Errval to non-negative (A.5.2) ...
+
+					if (NEAR == 0 && k == 0 && 2*B[Q] <= -N[Q]) {
+						if (Errval >= 0)
+							MErrval =  2*Errval + 1;	//  0 becomes 1,  1 becomes 3,  2 becomes 5
+						else
+							MErrval = -2*(Errval+1);	// -1 becomes 0, -2 becomes 2, -3 becomes 4
+					}
+					else {
+						if (Errval >= 0)
+							MErrval =  2*Errval;		//  0 becomes 0,  1 becomes 2,  2 becomes 4
+						else
+							MErrval = -2*Errval - 1;	// -1 becomes 1, -2 becomes 3
+					}
+
+//cerr << "\t\tMErrval = " << MErrval << endl;
+
+					encodeMappedErrvalWithGolomb(k,LIMIT,qbpp,MErrval,out);
+				}
+
+				// Update variables (A.6) ...
+
+//cerr << "\t\tUpdate variables with error updateErrval = " << updateErrval << endl;
+//cerr << "\t\tA[Q] old = " << A[Q] << endl;
+//cerr << "\t\tB[Q] old = " << B[Q] << endl;
+//cerr << "\t\tC[Q] old = " << C[Q] << endl;
+//cerr << "\t\tN[Q] old = " << N[Q] << endl;
+
+				// A.6.1 Use the signed error after modulo reduction (figure A.12 note). which is updateErrval
+
+				B[Q]=B[Q]+updateErrval*(2*NEAR+1);
+				A[Q]=A[Q]+Abs(updateErrval);
+				if (N[Q] == RESET) {
+					A[Q]=A[Q]>>1;
+					B[Q]=B[Q]>>1;
+					N[Q]=N[Q]>>1;
+				}
+				++N[Q];
+
+//cerr << "\t\tA[Q] updated = " << A[Q] << endl;
+//cerr << "\t\tB[Q] updated = " << B[Q] << endl;
+//cerr << "\t\tC[Q] updated = " << C[Q] << endl;
+//cerr << "\t\tN[Q] updated = " << N[Q] << endl;
+
+				// A.6.2 Context dependent bias cancellation ...
+
+				if (B[Q] <= -N[Q]) {
+					B[Q]+=N[Q];
+					if (C[Q] > MIN_C) --C[Q];
+					if (B[Q] <= -N[Q]) B[Q]=-N[Q]+1;
+				}
+				else if (B[Q] > 0) {
+					B[Q]-=N[Q];
+					if (C[Q] < MAX_C) ++C[Q];
+					if (B[Q] > 0) B[Q]=0;
+				}
+
+//cerr << "\t\tA[Q] bias cancelled = " << A[Q] << endl;
+//cerr << "\t\tB[Q] bias cancelled = " << B[Q] << endl;
+//cerr << "\t\tC[Q] bias cancelled = " << C[Q] << endl;
+//cerr << "\t\tN[Q] bias cancelled = " << N[Q] << endl;
+
+			}
+		}
+		if (decompressing) {
+			if (!writeRow(out,thisRow,COLUMNS,bpp)) Assert(0);
+		}
+		Uint16 *tmpRow=thisRow;
+		thisRow=prevRow;
+		prevRow=tmpRow;
+	}
+
+	if (!decompressing) writeBitFlush(out);
+
+	if (!decompressing && useJPEGmarkers)  {
+		writeEOI(out);
+	}
+
+	if (rowA) delete[] rowA;
+	if (rowB) delete[] rowB;
+	if (A) delete[] A;
+	if (B) delete[] B;
+	if (C) delete[] C;
+	if (N) delete[] N;
+
+	return success ? 0 : 1;
+}
+
diff --git a/appsrc/misc/rawnjl2.man b/appsrc/misc/rawnjl2.man
new file mode 100755
index 0000000..8cfb66b
--- /dev/null
+++ b/appsrc/misc/rawnjl2.man
@@ -0,0 +1,133 @@
+.TH RAWNJL2 1 "05 April 98" "DICOM PS3" "JPEG-LS codec"
+.SH NAME
+rawnjl2 \- JPEG-LS compress/decompress from raw file
+.SH SYNOPSIS
+.HP 10
+.B rawnjl2
+.B \-rows|\-height|\-h " rows"
+.B \-columns|\-width|\-w " cols"
+.B \-bits|\-depth " bits"
+[
+.B \-d|\-decompress
+]
+[
+.B \-near " n"
+]
+[
+.B \-T1|\-Ta " n"
+]
+[
+.B \-T2|\-Tb " n"
+]
+[
+.B \-T3|\-Tc " n"
+]
+[
+.B \-reset " n"
+]
+[
+.B \-nomarkers
+]
+[
+.B \-noruns
+]
+.so man1/binin.so
+.so man1/binout.so
+.SH DESCRIPTION
+.LP
+.B rawnjl2
+either reads the named raw input file and compresses it per the JPEG-LS
+(ISO DIS 14495-1) standard, or reads a compressed file and decompresses
+it into a raw output file (when the \-d option is specified).
+.LP
+The default compression is lossless, though near-lossless compression
+can be selected by specifying a pixel value error with the \-near option.
+.SH OPTIONS
+Error messages go to standard error.
+.PP
+.PP
+Options specific to this program are:
+.TP
+.BI \-rows|\-height|\-h " rows"
+.RS
+Required for compression.
+.RE
+.TP
+.BI \-columns|\-width|\-w " cols"
+.RS
+Required for compression.
+.RE
+.TP
+.BI \-bits|\-depth|\-d " bits"
+.RS
+Required for compression.
+.RE
+.TP
+.BI \-d|\-decompress
+.RS
+Selects decompression rather than compression (the default).
+.RE
+.TP
+.BI \-near " n"
+.RS
+If not zero (the default), selects near\-lossless compression. The
+value specified is the amount of error allowed in the reconstructed
+pixel value realtive to the original pixel value.
+.RE
+.TP
+.BI \-T1|\-Ta " n"
+.TP
+.BI \-T2|\-Tb " n"
+.TP
+.BI \-T3|\-Tc " n"
+.TP
+.BI \-reset " n"
+.RS
+Specify values other than the defaults for various compression
+parameters (see the standard for explanation).
+.RE
+.TP
+.BI \-nomarkers
+.RS
+Turns off writing (and reading) JPEG markers in the compressed output.
+Useful for examining the coompressed bitstream, though zero bit stuffing
+after 0xff bytes is still performed (and expected on decompression). Implies
+that the image parameters and non-default compression parameters need to be
+specified on the command line during decompression.
+.RE
+.TP
+.BI \-noruns
+.RS
+Turns off run mode during compression (and also needs to be specified for
+decompression). Thgis creates a non-standard bitstream bit is interesting
+to test the additional effectiveness the low entropy (less than one bit per
+pixel) run mode.
+.RE
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.RE
+% rawnjl2 -h 4 -e 4 -bits 8 -input-endian little 1.raw 1.jls
+.RE
+% rawnjl2 -d -output-endian little 1.jls 1.cmp
+.RE
+% cmp 1.raw 1.cmp
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.LP
+http://www.jpeg.org/
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+The near-lossless mode may trigger a bug that cause mapped error values
+to go negative and lead to a failed assertion. The standard seems unlcear
+on this point.
+.LP
+The compressed datastream does not seem to match the HP LOCO 0.90 implementation
+for some images, though the tiny example file in the standard compresses to
+match the standard and the HP implementation.
diff --git a/appsrc/simple/Imakefile b/appsrc/simple/Imakefile
new file mode 100755
index 0000000..d70ddaa
--- /dev/null
+++ b/appsrc/simple/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = ge9800 genesis pace signa somatom sytec vision
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/appsrc/simple/README b/appsrc/simple/README
new file mode 100755
index 0000000..7389ffb
--- /dev/null
+++ b/appsrc/simple/README
@@ -0,0 +1,47 @@
+These applications are the absolute minimal code required to extract
+the image pixel data from a proprietary format and create a pgm file.
+
+Each program stands alone and requires no libraries, templates, or header
+files from elsewhere in the package, other than basetype.h.
+
+The C define PNMBIGRAW should be set to 0 or 1 to disallow or allow the
+use of 'extended' 16 bit little-endian PGM format - this is the default,
+rather than the portable but huge text format.
+
+All programs are filters and read from standard in and write to standard
+out.
+
+To set maxval to the "real" maxval (not less than 256) ...
+
+	in="$1"
+	out="$2"
+	maxval=`pgmhist <$in | tail -1 | awk '{print $1}'`
+	if [ "$maxval" -le 255 ] ; then maxval=256; fi
+	pnmdepth "$maxval" <"$in" >"$out"
+
+To roughly scale the dynamic range to fit in 8 bits:
+
+	in="$1"
+	out="$2"
+	maxval=`pgmhist <$in | tail -1 | awk '{print $1}'`
+	if [ "$maxval" -gt 255 ]
+	then
+		maxval=`expr "$maxval" + 1`
+		gamma=`expr "$maxval" / 256`
+		pnmgamma "$gamma" <"$in"  | pnmdepth 255 >"$out"
+	fi
+
+To roughly scale the dynamic range to fit in 8 bits, except the top x%:
+
+	in="$1"
+	out="$2"
+	percent="$3"
+
+	grepstring="[ 	]$percent[.%][0-9]*[%]*\$"
+	maxval=`pgmhist <$in | grep "$grepstring" | tail -1 | awk '{print $1}'`
+	if [ "$maxval" -gt 255 ]
+	then
+		maxval=`expr "$maxval" + 1`
+		gamma=`expr "$maxval" / 256`
+		pnmgamma "$gamma" <"$in" | pnmdepth 255 >"$out"
+	fi
diff --git a/appsrc/simple/ge9800/Imakefile b/appsrc/simple/ge9800/Imakefile
new file mode 100755
index 0000000..3cbd39b
--- /dev/null
+++ b/appsrc/simple/ge9800/Imakefile
@@ -0,0 +1,31 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = ge98topgm.cc ge98id.cc
+OBJSTOPGM = ge98topgm.o  ge98id.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(ge98topgm)
+
+NormalCCProgramTarget(ge98topgm,ge98topgm.o,NullParameter,NullParameter,NullParameter)
+
+InstallProgram(ge98topgm,$(INSTALLBINDIR))
+InstallManPage(ge98topgm,$(INSTALLMANDIR)/man1)
+
+AllTarget(ge98id)
+
+NormalCCProgramTarget(ge98id,ge98id.o,NullParameter,NullParameter,NullParameter)
+
+InstallProgram(ge98id,$(INSTALLBINDIR))
+InstallManPage(ge98id,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./ge98topgm "" $(TOP)/images/ge9800 $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./ge98topgm "" $(TOP)/images/ge9800 $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/ge9800/ge98id.cc b/appsrc/simple/ge9800/ge98id.cc
new file mode 100644
index 0000000..8ee7188
--- /dev/null
+++ b/appsrc/simple/ge9800/ge98id.cc
@@ -0,0 +1,129 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge98id.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+// The following includes and definitions mirror libsrc/include/dctool/fltype.h ...
+
+#include <float.h>
+
+#ifdef POWINTEGEREXPONENTTYPE
+#define	powi(m,e)	pow(m,(POWINTEGEREXPONENTTYPE)(e))
+#else
+#define	powi(m,e)	pow(m,(long)(e))
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// DataGeneral is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static double
+readReal(istream& instream)
+{
+	double value;
+	typedef struct {
+		unsigned	sign : 1;
+		unsigned	exponent : 7;
+		unsigned	mantissa : 24;
+	} DG_FLOAT;
+	
+	DG_FLOAT number;
+
+	//unsigned char buffer[4];
+	char buffer[4];
+	instream.read(buffer,4);
+	// DataGeneral is a Big Endian machine
+	memcpy ((char *)(&number),buffer,4);
+
+	unsigned char	sign = number.sign;
+	Uint16		exponent = number.exponent;
+	Uint32		mantissa = number.mantissa;
+
+	value = (double) mantissa / (1 << 24) * powi (16.0, (long)(exponent) - 64);
+	value = (sign == 0) ? value : -value;
+	return value;
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned word)
+{
+	// 256 word blocks,16 bit words ...
+	const unsigned offset = (block*256+word)*2;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile\n" << flush;
+		return 1;
+	}
+
+	(void)seekword(cin,0,34);
+	unsigned examheaderblock=((unsigned)read16(cin)-1)/256;
+	(void)seekword(cin,0,35);
+	unsigned imageheaderblock=((unsigned)read16(cin)-1)/256;
+
+#define doascii(b,o,s,n)				\
+	{						\
+		char tmp[s+1];				\
+		(void)seekword(cin,b,o);		\
+		cin.read(tmp,s);			\
+		tmp[s]=0;				\
+		cout << n << "=\"" << tmp << "\"\n";	\
+	}
+
+#define doword(b,o,n)					\
+	{						\
+		(void)seekword(cin,b,o);		\
+		unsigned tmp=read16(cin);		\
+		cout << n << "=\"" << tmp << "\"\n";	\
+	}
+
+#define doreal(b,o,n)					\
+	{						\
+		(void)seekword(cin,b,o);		\
+		double tmp=readReal(cin);		\
+		cout << n << "=\"" << tmp << "\"\n";	\
+	}
+
+	doword (examheaderblock ,3    ,"StudyID");		// Exam Number
+	doascii(examheaderblock ,11,12,"PatientID");		// Patient ID
+	doascii(examheaderblock ,17,30,"PatientName");		// Patient Name
+	doascii(examheaderblock ,47,30,"InstitutionName");	// Hospital Name
+	doascii(examheaderblock ,76,30,"StudyDescription");	// Exam Description
+
+	doword (imageheaderblock,10   ,"SeriesNumber");		// Position (study) number
+	doword (imageheaderblock,46   ,"AcquisitionNumber");	// Scan Number
+	doword (imageheaderblock,47   ,"ImageNumber");		// Image Number
+
+	doreal (imageheaderblock,88   ,"SliceThickness");	// Aperture (1.5,3,5,10) (fp)
+	doword (imageheaderblock,90   ,"KVP");				// Generator KVP (80,120,140)
+	doword (imageheaderblock,91   ,"TubeCurrent");		// Tube current (10-360)
+	doreal (imageheaderblock,92   ,"GantryAngle");		// Gantry Angle 
+	doreal (imageheaderblock,94   ,"TableHeight");		// Table Height (mm) (fp)
+	doreal (imageheaderblock,96   ,"SlicePosition");	// Axial Table Location (fp)
+	doreal (imageheaderblock,98   ,"ScanTime");			// Scan time (1.4-9.4) (fp) 
+	doreal (imageheaderblock,215  ,"ReconPixelSize");	// actual image pixel size (mm,fp) (scout), standard pixel size/target factor (recon) 
+
+	return 0;
+}
diff --git a/appsrc/simple/ge9800/ge98id.man b/appsrc/simple/ge9800/ge98id.man
new file mode 100755
index 0000000..91598ab
--- /dev/null
+++ b/appsrc/simple/ge9800/ge98id.man
@@ -0,0 +1,46 @@
+.TH GE98ID 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - GE 9800 dump identifiers"
+.SH NAME
+ge98id \- ACR/NEMA DICOM PS3 ... DICOM PS3 - GE 9800 dump identifiers
+.SH SYNOPSIS
+.HP 10
+.B ge98id
+.B < " infile"
+.SH DESCRIPTION
+.LP
+.B ge98id
+reads the GE 9800 CT input file and dumps identifying attributes.
+.SH OPTIONS
+The descriptions of the identifiers go to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.RE
+% ge98id <test.YP
+.RE
+StudyID="8541"
+.RE
+PatientID="12345678"
+.RE
+PatientName="CITIZEN DOE"
+.RE
+InstitutionName="ST. ELSEWHERE"
+.RE
+StudyDescription="THIS IS A NON-STUDY DESCRIPTION"
+.RE
+SeriesNumber="1"
+.RE
+AcquisitionNumber="6"
+.RE
+ImageNumber="6"
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR ge98topgm(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/simple/ge9800/ge98topgm.cc b/appsrc/simple/ge9800/ge98topgm.cc
new file mode 100644
index 0000000..133c2ea
--- /dev/null
+++ b/appsrc/simple/ge9800/ge98topgm.cc
@@ -0,0 +1,255 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge98topgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// DataGeneral is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#if	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned word)
+{
+	// 256 word blocks,16 bit words ...
+	const unsigned offset = (block*256+word)*2;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+static void
+copy9800image(istream& instream,ostream& outstream,
+	      Uint16 width,Uint16 height,Uint16 *map)
+{
+	unsigned i;
+	Int16 last_pixel;
+
+	last_pixel=0;
+	for (i=0; i<height; ++i) {
+		unsigned start;
+		unsigned end;
+		unsigned j;
+
+		if (map) {
+			unsigned line	= map[i];
+			start	= width/2-line;
+			end	= start+line*2;
+		}
+		else {
+			start	= 0;
+			end	= width;
+		}
+
+		// Pad the first "empty" part of the line ...
+		for (j=0; j<start; j++) write16little(outstream,0);
+
+		// Copy the middle of the line (compressed or uncompressed)
+		while (start<end) {
+			unsigned char byte;
+			instream.read((char *)&byte,1);
+			if (!instream) {
+				cerr << "Premature EOF row " << i
+				     << " col " << start
+				     << "\n" << flush;
+				break;
+			}
+			if (byte & 0x80) {
+				signed char delta;
+				if (byte & 0x40) {
+					delta=byte;
+				}
+				else {
+		    			delta=byte & 0x3f;
+				}
+				last_pixel+=delta;
+			}
+			else {
+				last_pixel=byte << 8;
+				instream.read((char *)&byte,1);
+				if (!instream) break;
+				last_pixel+=byte;
+			}
+			write16little(outstream,(Uint16)last_pixel & 0x0fff);
+			++start;
+		}
+
+		// Pad the last "empty" part of the line ...
+		for (j=end; j<width; j++) write16little(outstream,0);
+	}
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	(void)seekword(cin,0,35);
+	unsigned imageheaderblock=read16(cin);
+
+	(void)seekword(cin,0,37);
+	unsigned mapblock=read16(cin);
+
+	(void)seekword(cin,0,38);
+	unsigned datablock=read16(cin);
+
+	if (imageheaderblock)
+		imageheaderblock=(imageheaderblock-1)/256;
+	else
+		imageheaderblock=2;
+
+	(void)seekword(cin,imageheaderblock,12);
+	unsigned grouptype=read16(cin);		// (2=scout,3=std,4=dyn,5=arr)
+
+	(void)seekword(cin,imageheaderblock,123);
+	unsigned imagesize=read16(cin);
+
+	(void)seekword(cin,imageheaderblock,131);
+	unsigned detectorsperview=read16(cin);	// detectors per view
+
+	(void)seekword(cin,imageheaderblock,136);
+	unsigned viewsperscan=read16(cin);	// views/scan
+
+	(void)seekword(cin,imageheaderblock,174);
+	unsigned usemap=read16(cin);		// 1=y,2=n
+
+	(void)seekword(cin,imageheaderblock,217);
+	unsigned filetype=read16(cin);		// (1=prospective,2=scout,
+						//  3=retrospective,4=segmented,
+						//  5=screensave,6=plot)
+
+	if (mapblock)
+		mapblock=(mapblock-1)/256;
+	else
+		mapblock=(grouptype == 5) ? 9 : 4;
+
+	if (datablock)
+		datablock=(datablock-1)/256;
+	else
+		datablock=(grouptype == 5) ? 11 : 6;
+
+	unsigned height;
+	unsigned width;
+
+	if (filetype == 2) {	// scout
+		width=detectorsperview;
+		height=viewsperscan;
+	}
+	else {
+		width=imagesize;
+		height=imagesize;
+	}
+
+#if	PNMBIGRAW
+	cout << "P5\n" << width << " " << height << "\n"
+		    << 4095 << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << width << " " << height << "\n"
+		    << 4095 << "\n";
+#endif /* PNMBIGRAW */
+
+	{
+		// Find the start of the perimeter encoding map ...
+
+		if (usemap == 1 && seekword(cin,mapblock,0) == OurStreamPos(istream::traits_type::eof())) {
+			cerr << "Map seek failed\n" << flush;
+			return 1;
+		}
+		else {
+			// Read in the map ...
+
+			Uint16 *map;
+			if (usemap == 1) {
+				if ((map=new Uint16[height]) == 0) {
+					cerr << "Can't create map\n" << flush;
+					return 1;
+				}
+				unsigned i;
+				for (i=0; i<height; ++i)
+					map[i]=read16(cin);
+				if (!cin) {
+					cerr << "Map read failed\n" << flush;
+					return 1;
+				}
+			}
+			else {
+				map=0;
+			}
+			{
+				// Decompress and output the image data ...
+
+				if (seekword(cin,datablock,0)
+				    == OurStreamPos(istream::traits_type::eof())) {
+					cerr << "Image seek failed\n" << flush;
+					return 1;
+				}
+				else {
+					copy9800image(cin,cout,
+					      width,height,map);
+					if (!cin) {
+						cerr
+						  << "Image read failed\n"
+						  << flush;
+						return 1;
+					}
+					if (!cout.good()) {
+						cerr
+						  << "Image write failed\n"
+						  << flush;
+						return 1;
+					}
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/ge9800/ge98topgm.man b/appsrc/simple/ge9800/ge98topgm.man
new file mode 100755
index 0000000..b2806d0
--- /dev/null
+++ b/appsrc/simple/ge9800/ge98topgm.man
@@ -0,0 +1,35 @@
+.TH GE98TOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - GE 9800 image to PGM file"
+.SH NAME
+ge98topgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - GE 9800 image to PGM file
+.SH SYNOPSIS
+.HP 10
+.B ge98topgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B ge98topgm
+reads the GE 9800 CT input file and copies the decompressed image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/simple/genesis/Imakefile b/appsrc/simple/genesis/Imakefile
new file mode 100755
index 0000000..8bc53d8
--- /dev/null
+++ b/appsrc/simple/genesis/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = gentopgm.cc
+OBJSTOPGM = gentopgm.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(gentopgm)
+
+NormalCCProgramTarget(gentopgm,$(OBJSTOPGM),NullParameter,NullParameter,NullParameter)
+
+InstallProgram(gentopgm,$(INSTALLBINDIR))
+InstallManPage(gentopgm,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./gentopgm "" $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./gentopgm "" $(TOP)/images/genesis $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/genesis/gentopgm.cc b/appsrc/simple/genesis/gentopgm.cc
new file mode 100644
index 0000000..a3ba6c9
--- /dev/null
+++ b/appsrc/simple/genesis/gentopgm.cc
@@ -0,0 +1,247 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gentopgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// Sparc is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static Uint32
+read32(istream& instream)
+{
+	Uint32 u;
+	unsigned char buffer[4];
+	instream.read((char *)buffer,4);
+	// Sparc is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	u <<= 8;
+	u |= (Uint16)buffer[2];
+	u <<= 8;
+	u |= (Uint16)buffer[3];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#if	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned byte)
+{
+	// byte displacements ...
+	const unsigned offset = block+byte;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+static void
+copygenesisimage(istream& instream,ostream& outstream,
+	Uint16 width,Uint16 height,Uint16 depth,Uint16 compress,
+	Uint16 *map_left,Uint16 *map_wide)
+{
+	(void)depth;
+	unsigned row;
+	Int16 last_pixel=0;
+	for (row=0; row<height; ++row) {
+		unsigned j;
+		unsigned start;
+		unsigned end;
+
+		if (compress == 2 || compress == 4) { // packed or compacked
+			start=map_left[row];
+			end=start+map_wide[row];
+		}
+		else {
+			start=0;
+			end=width;
+		}
+		// Pad the first "empty" part of the line ...
+		for (j=0; j<start; j++) write16little(outstream,0);
+
+		if (compress == 3 || compress == 4) { // compressed or compacked
+			while (start<end) {
+				unsigned char byte;
+				instream.read((char *)&byte,1);
+				if (!instream) return;
+				if (byte & 0x80) {
+					unsigned char byte2;
+					instream.read((char *)&byte2,1);
+					if (!instream) return;
+					if (byte & 0x40) {	// next word
+						instream.read((char *)&byte,1);
+						if (!instream) return;
+						last_pixel=
+						    (((Uint16)byte2<<8)+byte);
+					}
+					else {			// 14 bit delta
+						if (byte & 0x20) byte|=0xe0;
+						else byte&=0x1f;
+						last_pixel+=
+						    (((Int16)byte<<8)+byte2);
+					}
+				}
+				else {				// 7 bit delta
+					if (byte & 0x40) byte|=0xc0;
+					last_pixel+=(signed char)byte;
+				}
+				write16little(outstream,(Uint16)last_pixel);
+				++start;
+			}
+		}
+		else {
+			while (start<end) {
+				Uint16 u=read16(instream);
+				if (!instream) return;
+				write16little(outstream,u);
+				++start;
+			}
+		}
+
+		// Pad the last "empty" part of the line ...
+		for (j=end; j<width; j++) write16little(outstream,0);
+	}
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	const unsigned filehdrblock	= 0;
+
+	(void)seekword(cin,filehdrblock,4);
+	unsigned datablock=read32(cin);
+
+	(void)seekword(cin,filehdrblock,8);
+	unsigned width=read32(cin);
+
+	(void)seekword(cin,filehdrblock,12);
+	unsigned height=read32(cin);
+
+	(void)seekword(cin,filehdrblock,16);
+	unsigned depth=read32(cin);
+
+	(void)seekword(cin,filehdrblock,20);
+	unsigned compress=read32(cin);
+
+	(void)seekword(cin,filehdrblock,64);
+	unsigned mapblock=read32(cin) + filehdrblock;
+
+	(void)seekword(cin,filehdrblock,80);
+	unsigned histblock=read32(cin) + filehdrblock;
+	(void)seekword(cin,filehdrblock,84);
+	unsigned histlng=read32(cin) + filehdrblock;
+
+	unsigned int maxval=0;
+	if (histlng) {
+		(void)seekword(cin,histblock,12);
+		maxval=read16(cin);
+	}
+	if (maxval == 0) maxval=(1<<depth)-1;
+	if (maxval <= 255) maxval=256;	// force word not byte format
+
+#if	PNMBIGRAW
+	cout << "P5\n" << width << " " << height << "\n"
+		    << maxval << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << width << " " << height << "\n"
+		    << maxval << "\n";
+#endif /* PNMBIGRAW */
+
+	{
+		// Read the perimeter encoding map ...
+
+		Uint16 map_left[512];	// max resolution 512
+		Uint16 map_wide[512];
+
+		if (compress == 2 || compress == 4) { // packed or compacked
+			if (seekword(cin,mapblock,0) == OurStreamPos(istream::traits_type::eof())) {
+				cerr << "Map seek failed\n" << flush;
+				return 1;
+			}
+			else {
+				// Read the map ...
+
+				unsigned i;
+				for (i=0; i<height; ++i) {
+					map_left[i]=read16(cin);
+					map_wide[i]=read16(cin);
+				}
+				if (!cin) {
+					cerr << "Map read failed\n" << flush;
+					return 1;
+				}
+			}
+		}
+
+		// Decompress and output the image data ...
+
+		if (seekword(cin,datablock,0) == OurStreamPos(istream::traits_type::eof())) {
+			cerr << "Image seek failed\n" << flush;
+			return 1;
+		}
+		else {
+			copygenesisimage(cin,cout,
+				width,height,depth,compress,
+				map_left,map_wide);
+			if (!cin) {
+				cerr << "Image read failed\n" << flush;
+				return 1;
+			}
+			if (!cout.good()) {
+				cerr << "Image write failed\n" << flush;
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/genesis/gentopgm.man b/appsrc/simple/genesis/gentopgm.man
new file mode 100755
index 0000000..c4505e2
--- /dev/null
+++ b/appsrc/simple/genesis/gentopgm.man
@@ -0,0 +1,37 @@
+.TH GENTOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - Genesis image to PGM file"
+.SH NAME
+gentopgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Genesis ximg file to PGM file
+.SH SYNOPSIS
+.HP 10
+.B gentopgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B gentopgm
+reads the Genesis ximg CT or MR input file and copies the decompressed image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
+Only handles ximg format headers, not DAT or OD, and not AW
+(sun4) word alignment headers.
diff --git a/appsrc/simple/pace/Imakefile b/appsrc/simple/pace/Imakefile
new file mode 100755
index 0000000..21f1b85
--- /dev/null
+++ b/appsrc/simple/pace/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = pacetopgm.cc
+OBJSTOPGM = pacetopgm.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(pacetopgm)
+
+NormalCCProgramTarget(pacetopgm,$(OBJSTOPGM),NullParameter,NullParameter,NullParameter)
+
+InstallProgram(pacetopgm,$(INSTALLBINDIR))
+InstallManPage(pacetopgm,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./pacetopgm "" $(TOP)/images/pace $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./pacetopgm "" $(TOP)/images/pace $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/pace/pacetopgm.cc b/appsrc/simple/pace/pacetopgm.cc
new file mode 100644
index 0000000..8048a34
--- /dev/null
+++ b/appsrc/simple/pace/pacetopgm.cc
@@ -0,0 +1,161 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacetopgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// Pace is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#ifdef	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned offset,unsigned word)
+{
+	// byte offset from 0 ...
+	instream.seekg(offset+word,ios::beg);
+	return instream.tellg();
+}
+
+static void
+copypaceimage(istream& instream,ostream& outstream,
+	      Uint16 width,Uint16 height)
+{
+// NB. the exclusive or with 0x8000 makes the signed Pace values unsigned
+// which is what the PGM convention is ... just omit the ^0x8000
+// everywhere if you want the data left signed.
+
+	unsigned i;
+	Int16 pixel=0;
+	enum Mode { Difference, Reference } mode = Reference;
+	for (i=0; i<height*width;) {
+		unsigned char byte;
+		instream.read((char *)&byte,1);
+		if (!instream) break;
+		if (byte == 0x80) {		// Mode switch
+			if (mode == Difference)
+				mode=Reference;
+			else
+				mode=Difference;
+		}
+		else if (byte == 0x81) {	// Run length flag
+			instream.read((char *)&byte,1);
+			if (!instream) break;
+			unsigned repeat=byte;
+			i+=repeat;
+			while (repeat--) write16little(outstream,pixel^0x8000);
+		}
+		else {
+			if (mode == Difference) {
+				pixel+=(signed char)byte;
+			}
+			else {
+				pixel=byte<<8;
+				instream.read((char *)&byte,1);
+				if (!instream) break;
+				pixel|=byte;
+			}
+			write16little(outstream,pixel^0x8000);
+			++i;
+		}
+	}
+	if (!instream) cerr << "Premature EOF byte " << i << "\n" << flush;
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	unsigned imageheaderblock=768;
+	unsigned datablock=1792;
+
+	(void)seekword(cin,imageheaderblock,416);
+	unsigned width=read16(cin);
+
+	(void)seekword(cin,imageheaderblock,418);
+	unsigned height=read16(cin);
+
+	// Only use maxval of 4095 here if you leave the data signed,
+	// ie. didn't xor with 0x8000
+
+#ifdef	PNMBIGRAW
+	cout << "P5\n" << width << " " << height << "\n"
+		    << 65535 << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << width << " " << height << "\n"
+		    << 65535 << "\n";
+#endif /* PNMBIGRAW */
+
+	// Decompress and output the image data ...
+
+	if (seekword(cin,datablock,0) == OurStreamPos(istream::traits_type::eof())) {
+		cerr << "Image seek failed\n" << flush;
+		return 1;
+	}
+	else {
+		copypaceimage(cin,cout,width,height);
+		if (!cin) {
+			cerr
+			  << "Image read failed\n"
+			  << flush;
+			return 1;
+		}
+		if (!cout.good()) {
+			cerr
+			  << "Image write failed\n"
+			  << flush;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/pace/pacetopgm.man b/appsrc/simple/pace/pacetopgm.man
new file mode 100755
index 0000000..74de5a7
--- /dev/null
+++ b/appsrc/simple/pace/pacetopgm.man
@@ -0,0 +1,35 @@
+.TH PACETOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - GE Pace image to PGM file"
+.SH NAME
+pacetopgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - GE Pace image to PGM file
+.SH SYNOPSIS
+.HP 10
+.B pacetopgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B pacetopgm
+reads the GE Pace CT input file and copies the decompressed image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/simple/signa/Imakefile b/appsrc/simple/signa/Imakefile
new file mode 100755
index 0000000..ab2f188
--- /dev/null
+++ b/appsrc/simple/signa/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = sgntopgm.cc
+OBJSTOPGM = sgntopgm.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(sgntopgm)
+
+NormalCCProgramTarget(sgntopgm,$(OBJSTOPGM),NullParameter,NullParameter,NullParameter)
+
+InstallProgram(sgntopgm,$(INSTALLBINDIR))
+InstallManPage(sgntopgm,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./sgntopgm "" $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./sgntopgm "" $(TOP)/images/signa $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/signa/sgntopgm.cc b/appsrc/simple/signa/sgntopgm.cc
new file mode 100644
index 0000000..3ea4dbf
--- /dev/null
+++ b/appsrc/simple/signa/sgntopgm.cc
@@ -0,0 +1,112 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgntopgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// DataGeneral is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#if	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned word)
+{
+	// 256 word blocks,16 bit words ...
+	const unsigned offset = (block*256+word)*2;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	const unsigned imageheaderblock	= 10;
+	const unsigned datablock	= 28;
+
+	(void)seekword(cin,imageheaderblock,137);
+	unsigned rows=read16(cin);
+	(void)seekword(cin,imageheaderblock,138);
+	unsigned cols=read16(cin);
+
+#if	PNMBIGRAW
+	cout << "P5\n" << cols << " " << rows << "\n" << 4095 << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << cols << " " << rows << "\n" << 4095 << "\n";
+#endif /* PNMBIGRAW */
+
+	if (seekword(cin,datablock,0) == OurStreamPos(istream::traits_type::eof())) {
+		cerr << "Image seek failed\n" << flush;
+		return 1;
+	}
+	else {
+		unsigned row;
+		for (row=0; row<rows; ++row) {
+			unsigned col;
+			for (col=0; col<cols; ++col) {
+				Uint16 u=read16(cin);
+				write16little(cout,u&0x0fff);
+			}
+		}
+		if (!cin) {
+			cerr << "Image read failed\n" << flush;
+			return 1;
+		}
+		if (!cout.good()) {
+			cerr << "Image write failed\n" << flush;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/signa/sgntopgm.man b/appsrc/simple/signa/sgntopgm.man
new file mode 100755
index 0000000..33d3ac7
--- /dev/null
+++ b/appsrc/simple/signa/sgntopgm.man
@@ -0,0 +1,35 @@
+.TH SGNTOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - GE Signa image to PGM file"
+.SH NAME
+sgntopgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - GE Signa image to PGM file
+.SH SYNOPSIS
+.HP 10
+.B sgntopgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B sgntopgm
+reads the GE Signa MR input file and copies the image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/simple/somatom/Imakefile b/appsrc/simple/somatom/Imakefile
new file mode 100755
index 0000000..f9173c2
--- /dev/null
+++ b/appsrc/simple/somatom/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = somtopgm.cc
+OBJSTOPGM = somtopgm.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(somtopgm)
+
+NormalCCProgramTarget(somtopgm,$(OBJSTOPGM),NullParameter,NullParameter,NullParameter)
+
+InstallProgram(somtopgm,$(INSTALLBINDIR))
+InstallManPage(somtopgm,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./somtopgm "" $(TOP)/images/somatom $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./somtopgm "" $(TOP)/images/somatom $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/somatom/TODO b/appsrc/simple/somatom/TODO
new file mode 100755
index 0000000..5fc853b
--- /dev/null
+++ b/appsrc/simple/somatom/TODO
@@ -0,0 +1,3 @@
+Currently using all 16 bits and maxval of 65535 ... doesn't really matter
+but could one drop this depending on some header value ?
+
diff --git a/appsrc/simple/somatom/somtopgm.cc b/appsrc/simple/somatom/somtopgm.cc
new file mode 100644
index 0000000..d3c4287
--- /dev/null
+++ b/appsrc/simple/somatom/somtopgm.cc
@@ -0,0 +1,121 @@
+static const char *CopyrightIdentifier(void) { return "@(#)somtopgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// Vax is a Little Endian machine
+	u =  (Uint16)buffer[1];
+	u <<= 8;
+	u |= (Uint16)buffer[0];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#if	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned byte)
+{
+	// byte displacements ...
+	const unsigned offset = block+byte;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	const unsigned binhdrblock	= 0;
+	const unsigned datablock	= 2048;
+
+	(void)seekword(cin,binhdrblock,66);
+	char sizeflag;
+	(void)cin.get(sizeflag);
+
+	unsigned rows,cols;
+	switch (sizeflag) {
+		case 'B':	rows=cols=256; break;
+		case 'C':	rows=cols=512; break;
+		default:
+				cerr << "Bad size <" << sizeflag
+				     << ">\n" << flush;
+				return 1;
+	}
+
+#if	PNMBIGRAW
+	cout << "P5\n" << cols << " " << rows << "\n" << 65535 << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << cols << " " << rows << "\n" << 65535 << "\n";
+#endif /* PNMBIGRAW */
+
+	if (seekword(cin,datablock,0) == OurStreamPos(istream::traits_type::eof())) {
+		cerr << "Image seek failed\n" << flush;
+		return 1;
+	}
+	else {
+		unsigned row;
+		for (row=0; row<rows; ++row) {
+			unsigned col;
+			for (col=0; col<cols; ++col) {
+				Uint16 u=read16(cin);
+				write16little(cout,u);
+			}
+		}
+		if (!cin) {
+			cerr << "Image read failed\n" << flush;
+			return 1;
+		}
+		if (!cout.good()) {
+			cerr << "Image write failed\n" << flush;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/somatom/somtopgm.man b/appsrc/simple/somatom/somtopgm.man
new file mode 100755
index 0000000..c825237
--- /dev/null
+++ b/appsrc/simple/somatom/somtopgm.man
@@ -0,0 +1,35 @@
+.TH SOMTOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - Somatom image to PGM file"
+.SH NAME
+somtopgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Somatom image to PGM file
+.SH SYNOPSIS
+.HP 10
+.B somtopgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B somtopgm
+reads the Siemens Somatom CT input file and copies the image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/simple/sytec/Imakefile b/appsrc/simple/sytec/Imakefile
new file mode 100755
index 0000000..530c8df
--- /dev/null
+++ b/appsrc/simple/sytec/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = syttopgm.cc
+OBJSTOPGM = syttopgm.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(syttopgm)
+
+NormalCCProgramTarget(syttopgm,$(OBJSTOPGM),NullParameter,NullParameter,NullParameter)
+InstallManPage(syttopgm,$(INSTALLMANDIR)/man1)
+
+InstallProgram(syttopgm,$(INSTALLBINDIR))
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./syttopgm "" $(TOP)/images/sytec $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./syttopgm "" $(TOP)/images/sytec $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/sytec/syttopgm.cc b/appsrc/simple/sytec/syttopgm.cc
new file mode 100644
index 0000000..fcc0acb
--- /dev/null
+++ b/appsrc/simple/sytec/syttopgm.cc
@@ -0,0 +1,118 @@
+static const char *CopyrightIdentifier(void) { return "@(#)syttopgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// Sytec is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#if	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned byte)
+{
+	// byte displacements ...
+	const unsigned offset = block+byte;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	const unsigned binhdrblock	= 0;
+	const unsigned datablock	= 3752;
+
+	(void)seekword(cin,binhdrblock,2216);
+	unsigned cols = read16(cin);
+	(void)seekword(cin,binhdrblock,2218);
+	unsigned rows = read16(cin);
+
+#if	PNMBIGRAW
+	cout << "P5\n" << cols << " " << rows << "\n" << 65535 << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << cols << " " << rows << "\n" << 65535 << "\n";
+#endif /* PNMBIGRAW */
+
+	if (seekword(cin,datablock,0) == OurStreamPos(istream::traits_type::eof())) {
+		cerr << "Image seek failed\n" << flush;
+		return 1;
+	}
+	else {
+		unsigned row;
+		for (row=0; row<rows; ++row) {
+			unsigned col;
+			for (col=0; col<cols; ++col) {
+				Uint16 u=read16(cin);
+// -max = 8000	-> 0000
+// -1 =   ffff	-> 7fff
+// 0    = 0000	-> 8000
+// +max = 7fff	-> ffff
+				// u=(u&0x8000) ? u&0x7fff : u+0x8000;
+				u^=0x8000;
+				write16little(cout,u);
+			}
+		}
+		if (!cin) {
+			cerr << "Image read failed\n" << flush;
+			return 1;
+		}
+		if (!cout.good()) {
+			cerr << "Image write failed\n" << flush;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/sytec/syttopgm.man b/appsrc/simple/sytec/syttopgm.man
new file mode 100755
index 0000000..82d6b6b
--- /dev/null
+++ b/appsrc/simple/sytec/syttopgm.man
@@ -0,0 +1,35 @@
+.TH SYTTOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - GE Sytec image to PGM file"
+.SH NAME
+syttopgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - GE Sytec image to PGM file
+.SH SYNOPSIS
+.HP 10
+.B syttopgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B syttopgm
+reads the GE Sytec CT input file and copies the decompressed image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/appsrc/simple/vision/Imakefile b/appsrc/simple/vision/Imakefile
new file mode 100755
index 0000000..e1e5c71
--- /dev/null
+++ b/appsrc/simple/vision/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 1
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+SRCSTOPGM = vsntopgm.cc
+OBJSTOPGM = vsntopgm.o
+
+CPLUSPLUS_SRCS = $(SRCSTOPGM)
+OBJS = $(OBJSTOPGM)
+
+AllTarget(vsntopgm)
+
+NormalCCProgramTarget(vsntopgm,$(OBJSTOPGM),NullParameter,NullParameter,NullParameter)
+
+InstallProgram(vsntopgm,$(INSTALLBINDIR))
+InstallManPage(vsntopgm,$(INSTALLMANDIR)/man1)
+
+DependCCTarget()
+
+test::
+	@$(TOP)/support/testapp testlist ./vsntopgm "" $(TOP)/images/vision $(TOP)/test/$(CURRENT_DIR) compare filter
+
+test.create::
+	@$(TOP)/support/testapp testlist ./vsntopgm "" $(TOP)/images/vision $(TOP)/test/$(CURRENT_DIR) create filter
diff --git a/appsrc/simple/vision/TODO b/appsrc/simple/vision/TODO
new file mode 100755
index 0000000..d7f008b
--- /dev/null
+++ b/appsrc/simple/vision/TODO
@@ -0,0 +1,2 @@
+Currently using maxval of 4095 ... is this a good idea ?
+
diff --git a/appsrc/simple/vision/vsntopgm.cc b/appsrc/simple/vision/vsntopgm.cc
new file mode 100644
index 0000000..2924587
--- /dev/null
+++ b/appsrc/simple/vision/vsntopgm.cc
@@ -0,0 +1,128 @@
+static const char *CopyrightIdentifier(void) { return "@(#)vsntopgm.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+
+#ifndef PNMBIGRAW
+#define PNMBIGRAW 1
+#endif
+
+static Uint16
+read16(istream& instream)
+{
+	Uint16 u;
+	unsigned char buffer[2];
+	instream.read((char *)buffer,2);
+	// Sparc is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	return u;
+}
+
+static Uint32
+read32(istream& instream)
+{
+	Uint32 u;
+	unsigned char buffer[4];
+	instream.read((char *)buffer,4);
+	// Sparc is a Big Endian machine
+	u =  (Uint16)buffer[0];
+	u <<= 8;
+	u |= (Uint16)buffer[1];
+	u <<= 8;
+	u |= (Uint16)buffer[2];
+	u <<= 8;
+	u |= (Uint16)buffer[3];
+	return u;
+}
+
+static void
+write16little(ostream& outstream,Uint16 u)
+{
+#if	PNMBIGRAW
+	unsigned char buffer[2];
+	// Output is little endian
+	buffer[0]=(unsigned char)(u);
+	buffer[1]=(unsigned char)(u>>8);
+	outstream.write((char *)buffer,2);
+#else /* PNMBIGRAW */
+	outstream << u << "\n";
+#endif /* PNMBIGRAW */
+}
+
+static OurStreamPos
+seekword(istream& instream,unsigned block,unsigned byte)
+{
+	// byte displacements ...
+	const unsigned offset = block+byte;
+	instream.seekg(offset,ios::beg);
+	return instream.tellg();
+}
+
+int
+main(int argc,char *argv[])
+{
+	if (argc != 1) {
+		cerr << "Usage: " << argv[0] << " < infile > outfile\n" << flush;
+		return 1;
+	}
+
+	// default for some environments is unbuffered which is slow++
+	// the following improves performance 25 fold with libg++ ...
+
+//	const unsigned bufsize=4096;
+//	streambuf *in  = cin.rdbuf();
+//	streambuf *out = cout.rdbuf();
+//	static char inbuf[bufsize];
+//	static char outbuf[bufsize];
+//	in->setbuf(inbuf,sizeof(inbuf));
+//	out->setbuf(outbuf,sizeof(outbuf));
+
+	const unsigned hdrblock	= 0;
+	const unsigned datablock	= 6144;
+
+	(void)seekword(cin,hdrblock,2864);
+	Uint32 rows=read32(cin);
+	Uint32 cols=rows;
+
+#if	PNMBIGRAW
+	cout << "P5\n" << cols << " " << rows << "\n" << 4095 << "\n";
+#else /* PNMBIGRAW */
+	cout << "P2\n" << cols << " " << rows << "\n" << 4095 << "\n";
+#endif /* PNMBIGRAW */
+
+	if (seekword(cin,datablock,0) == OurStreamPos(istream::traits_type::eof())) {
+		cerr << "Image seek failed\n" << flush;
+		return 1;
+	}
+	else {
+		unsigned row;
+		for (row=0; row<rows; ++row) {
+			unsigned col;
+			for (col=0; col<cols; ++col) {
+				Uint16 u=read16(cin);
+				write16little(cout,u);
+			}
+		}
+		if (!cin) {
+			cerr << "Image read failed\n" << flush;
+			return 1;
+		}
+		if (!cout.good()) {
+			cerr << "Image write failed\n" << flush;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/appsrc/simple/vision/vsntopgm.man b/appsrc/simple/vision/vsntopgm.man
new file mode 100755
index 0000000..58df319
--- /dev/null
+++ b/appsrc/simple/vision/vsntopgm.man
@@ -0,0 +1,35 @@
+.TH VSNTOPGM 1 "05 April 1998" "DICOM PS3" "DICOM PS3 - Vision to PGM file"
+.SH NAME
+vsntopgm \- ACR/NEMA DICOM PS3 ... DICOM PS3 - Vision image to PGM file
+.SH SYNOPSIS
+.HP 10
+.B vsntopgm
+.B < " infile"
+.B > " outfile"
+.SH DESCRIPTION
+.LP
+.B vsntopgm
+reads the Siemens Magnetom Vision MR input file and copies the image
+pixel data to a PGM file after adding a PGM header.
+.SH OPTIONS
+The PGM output goes to standard out.
+Any error messages go to standard error.
+.SH ENVIRONMENT
+.LP
+\ 
+.SH EXAMPLES
+.LP
+\ 
+.SH FILES
+.LP
+\ 
+.SH SEE ALSO
+.BR dccp(1) ,
+.BR dctopnm(1) ,
+.BR pnmtodc(1) ,
+.BR rawtodc(1) ,
+.BR dctoraw(1) ,
+.BR dcintro(1)
+.SH AUTHOR
+Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+.SH BUGS
diff --git a/config/Configure b/config/Configure
new file mode 100755
index 0000000..44e5e91
--- /dev/null
+++ b/config/Configure
@@ -0,0 +1,952 @@
+
+#!/bin/sh
+
+TMPROOT="/tmp/$0.$$"
+
+if [ -f generic.cf ]; then mv generic.cf generic.cf.bak; fi
+
+echo  >generic.cf "/* Automagically generated - edits will be lost */"
+echo              '/* Configure last updated $Date: 2015/11/18 23:39:08 $ */' | sed -e 's/[$]//g' -e 's/Date: //' >>generic.cf
+echo >>generic.cf "/* This file created      "`date +'%Y/%m/%d %H:%M:%S'`" */"
+if [ ! -z "$BASH_VERSION" ]
+then
+	echo >>generic.cf "/* By                     $BASH version $BASH_VERSION */"
+fi
+echo >>generic.cf
+
+usegccifpresent="yes"
+
+while [ $# -ge 1 ]
+do
+	if [ "$1" = "notgcc" ]; then usegccifpresent="no"; fi
+	shift
+done
+
+# ----------------------- support functions -------------------------
+
+getIsPresent()		# getIsPresent "cmd"
+{
+	#echo 1>&2 "Configure: looking for $1"
+	rm -f $TMPROOT.getIsPresent
+	($1 </dev/null) >$TMPROOT.getIsPresent 2>&1
+	#echo 1>&2 "Configure: attempted to execute $1"
+	if grep -i "not found" <$TMPROOT.getIsPresent >/dev/null
+	then
+		#echo 1>&2 "Configure: not found $1"
+		rm -f $TMPROOT.getIsPresent
+		return 1
+	elif grep -i "no such" <$TMPROOT.getIsPresent >/dev/null
+	then
+		#echo 1>&2 "Configure: no such $1"
+		rm -f $TMPROOT.getIsPresent
+		return 1
+	else
+		#echo 1>&2 "Configure: found $1"
+		rm -f $TMPROOT.getIsPresent
+		return 0
+	fi
+}
+
+getVersion()		# getVersion "cmd"
+{
+	rm -f $TMPROOT.getVersion
+	($1 </dev/null) >$TMPROOT.getVersion 2>&1
+	if grep -i "not found" <$TMPROOT.getVersion >/dev/null
+	then
+		rm -f $TMPROOT.getVersion
+		return 1
+	elif grep -i "no such" <$TMPROOT.getVersion >/dev/null
+	then
+		rm -f $TMPROOT.getVersion
+		return 1
+	else
+		cat $TMPROOT.getVersion
+		rm -f $TMPROOT.getVersion
+		return 0
+	fi
+}
+
+SunProIncludePath()	# SunProIncludePath cmd extension definecmd defineflagsprefix defineflagssuffix definepath
+{
+	echo 1>&2 "Configure: find SunPro include path for $1"
+
+	cmd="$1"
+	language="$2"
+	extension="$3"
+	definecmd="$4"
+	defineflagsprefix="$5"
+	defineflagssuffix="$6"
+	definepath="$7"
+
+	touch $TMPROOT.testsp.$extension
+	rm -f $TMPROOT.testsp.o
+	if getIsPresent "$cmd -V -o $TMPROOT.testsp.o -c $TMPROOT.testsp.$extension"
+	then
+		echo 1>&2 "Configure: found $cmd"
+		sunproversion=`$cmd -V -o $TMPROOT.testsp.o \
+				-c $TMPROOT.testsp.$extension 2>&1 | \
+			grep ":" | head -1 | \
+			sed -e 's/\([0-9][.][0-9]\)[^0-9.].*$/\1/' \
+			    -e 's/^.*[^0-9.]\([0-9][.][0-9]\)/\1/'`
+		sunpromajorversion=`echo "$sunproversion" | sed 's/[^0-9].*$//'`
+
+		echo 1>&2 "Configure: found version $sunproversion"
+		echo 1>&2 "Configure: found major version $sunpromajorversion"
+
+		echo >>generic.cf "#ifndef $definecmd"
+		echo >>generic.cf "#define $definecmd $cmd"
+		echo >>generic.cf "#endif"
+
+		echo >>generic.cf "#ifndef YaccCmd"
+		echo >>generic.cf "#define YaccCmd yacc -l /* shuts up SunBrowser warnings about #line */"
+		echo >>generic.cf "#endif"
+
+		if [ "$sunpromajorversion" = 3 ]
+		then
+			echo >>generic.cf "#ifndef XarCmd"
+			echo >>generic.cf "#define XarCmd CPlusPlusCmd -xar -o"
+			echo >>generic.cf "#endif"
+		fi
+
+		if [ "$sunpromajorversion" = 2 ]
+		then
+			echo >>generic.cf "#ifndef $defineflagsprefix""SourceBrowser"
+			echo >>generic.cf "#define $defineflagsprefix""SourceBrowser -sb"
+			echo >>generic.cf "#endif"
+
+		fi
+
+		if [ "$sunpromajorversion" -ge 3 ]
+		then
+			echo >>generic.cf "#ifndef $defineflagsprefix""SourceBrowser"
+			echo >>generic.cf "#define $defineflagsprefix""SourceBrowser -xsb -xF"
+			echo >>generic.cf "#endif"
+		fi
+
+		echo >>generic.cf "#ifndef $defineflagsprefix""TmpPath"
+		echo >>generic.cf "#ifdef TmpPath"
+		echo >>generic.cf "#define $defineflagsprefix""TmpPath -temp=TmpPath"
+		echo >>generic.cf "#else"
+		echo >>generic.cf "#define $defineflagsprefix""TmpPath /**/"
+		echo >>generic.cf "#endif"
+		echo >>generic.cf "#endif"
+
+		echo >>generic.cf "#ifndef $defineflagsprefix""Optimized""$defineflagssuffix"
+		if [ "$sunpromajorversion" -ge 4 -a "$defineflagsprefix" = CPlusPlus ]
+		then
+			echo >>generic.cf "#define $defineflagsprefix""Optimized""$defineflagssuffix $defineflagsprefix""TmpPath $defineflagsprefix""SourceBrowser OptimizeLevel NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES -DNOGENERALINITIALIZERS -pto"
+		elif [ "$sunpromajorversion" -ge 2 ]
+		then
+			echo >>generic.cf "#define $defineflagsprefix""Optimized""$defineflagssuffix $defineflagsprefix""TmpPath $defineflagsprefix""SourceBrowser OptimizeLevel NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES -DNOGENERALINITIALIZERS"
+		else
+			echo >>generic.cf "#define $defineflagsprefix""Optimized""$defineflagssuffix $defineflagsprefix""TmpPath $defineflagsprefix""SourceBrowser OptimizeLevel NeedMissingPrototypes"
+		fi
+		echo >>generic.cf "#endif"
+
+		echo >>generic.cf "#ifndef $defineflagsprefix""Unoptimized""$defineflagssuffix"
+		if [ "$sunpromajorversion" -ge 4 -a "$defineflagsprefix" = CPlusPlus ]
+		then
+			echo >>generic.cf "#define $defineflagsprefix""Unoptimized""$defineflagssuffix $defineflagsprefix""TmpPath $defineflagsprefix""SourceBrowser NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES -DNOGENERALINITIALIZERS -pto"
+		elif [ "$sunpromajorversion" -ge 2 ]
+		then
+			echo >>generic.cf "#define $defineflagsprefix""Unoptimized""$defineflagssuffix $defineflagsprefix""TmpPath $defineflagsprefix""SourceBrowser NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES -DNOGENERALINITIALIZERS"
+		else
+			echo >>generic.cf "#define $defineflagsprefix""Unoptimized""$defineflagssuffix $defineflagsprefix""TmpPath $defineflagsprefix""SourceBrowser NeedMissingPrototypes"
+		fi
+		echo >>generic.cf "#endif"
+
+		rm -f $TMPROOT.testsp.o
+		extractedoptions=`$cmd -V -o $TMPROOT.testsp.o \
+						-c $TMPROOT.testsp.$extension 2>&1 | \
+					egrep '\-I' | head -1 | \
+					sed -e 's/^[^ 	]*//' \
+					    -e 's/-[^I][^ 	]*//g' \
+					    -e 's/[ 	][^-][^ 	]*//g'`
+
+		if [ -z "$extractedoptions" ]
+		then
+			if [ "$language" = CC ]
+			then
+				echo >>generic.cf "#ifndef $definepath"
+				echo >>generic.cf "#define $definepath -I\$(LANGHOME)/SC$sunproversion/include/CC" \
+					" -I\$(LANGHOME)/SC$sunproversion/include/cc"
+				echo >>generic.cf "#endif"
+			else
+				echo >>generic.cf "#ifndef $definepath"
+				echo >>generic.cf "#define $definepath -I\$(LANGHOME)/SC$sunproversion/include/cc"
+				echo >>generic.cf "#endif"
+			fi
+		else
+			echo >>generic.cf "#ifndef $definepath"
+			echo >>generic.cf "#define $definepath $extractedoptions"
+			echo >>generic.cf "#endif"
+		fi
+	fi
+	rm -f $TMPROOT.testsp.$extension $TMPROOT.testsp.o
+}
+
+OSFIncludePath()	# OSFIncludePath cmd extension definecmd defineflagsprefix defineflagssuffix definepath
+{
+	cmd="$1"
+	language="$2"
+	extension="$3"
+	definecmd="$4"
+	defineflags="$5"
+	definepath="$6"
+
+	touch $TMPROOT.testsp.$extension
+	rm -f $TMPROOT.testsp.o
+	if getIsPresent "$cmd -o $TMPROOT.testsp.o -c $TMPROOT.testsp.$extension"
+	then
+		echo >>generic.cf "#ifndef $definecmd"
+		echo >>generic.cf "#define $definecmd $cmd"
+		echo >>generic.cf "#endif"
+
+		echo >>generic.cf "#ifndef $defineflagsprefix""Unoptimized""$defineflagssuffix"
+		echo >>generic.cf "#define $defineflagsprefix""Unoptimized""$defineflagssuffix"
+		echo >>generic.cf "#endif"
+
+		echo >>generic.cf "#ifndef $defineflagsprefix""Optimized""$defineflagssuffix"
+		echo >>generic.cf "#define $defineflagsprefix""Optimized""$defineflagssuffix OptimizeLevel"
+		echo >>generic.cf "#endif"
+
+		if [ "$language" = CC ]
+		then
+			echo >>generic.cf "#ifndef $definepath"
+			echo >>generic.cf "#define $definepath -I/usr/include/cxx"
+			echo >>generic.cf "#endif"
+		else
+			echo >>generic.cf "#ifndef $definepath"
+			echo >>generic.cf "#define $definepath -I/usr/include"
+			echo >>generic.cf "#endif"
+		fi
+	fi
+	rm -f $TMPROOT.testsp.$extension $TMPROOT.testsp.o
+}
+
+# ----------------------- start of main routine -------------------------
+
+echo 1>&2 "Configure: begin"
+
+# --------------------- Before OS dependent stuff -----------------------
+
+osname=`uname -s`
+osnameforconfig="`uname -s` `uname -r`"
+leftover=`uname -r`
+osmajorversion=`echo "$leftover" | sed 's/[^0-9a-zA-Z].*$//'`
+leftover=`echo "$leftover" | sed 's/^[0-9a-zA-Z][0-9a-zA-Z]*[^0-9a-zA-Z]//'`
+osminorversion=`echo "$leftover" | sed 's/[^0-9a-zA-Z].*$//'`
+leftover=`echo "$leftover" | sed 's/^[0-9a-zA-Z][0-9a-zA-Z]*[^0-9a-zA-Z]//'`
+osteenyversion=`echo "$leftover" | sed 's/[^0-9a-zA-Z].*$//'`
+
+echo 1>&2 "Configure: we are on OS $osname"
+
+if [ "$osname" = "SunOS" -a "$osmajorversion" -le 4 ]
+then
+	hardware=`uname -m`	# -p isn't supported in SunOS uname - make do with machine architecture
+else
+	hardware=`uname -p`	# gets instruction set architecture not machine architecture
+fi
+
+echo 1>&2 "Configure: we are on instruction set architecture $hardware"
+
+platformnameforinstallpath=`echo "$osname.$osmajorversion.$osminorversion.$osteenyversion.$hardware" | tr -d -c '[0-9][a-z][A-Z].' | tr '[A-Z]' '[a-z]'`
+
+echo 1>&2 "Configure: make install use platform specific directory $platformnameforinstallpath"
+
+echo >>generic.cf "#ifndef OSName"
+echo >>generic.cf "#define OSName            $osnameforconfig"
+echo >>generic.cf "#endif"
+echo >>generic.cf "XCOMM hardware:              $hardware"
+echo >>generic.cf "XCOMM operating system:      $osnameforconfig"
+echo >>generic.cf "XCOMM operating system path: $platformnameforinstallpath"
+echo >>generic.cf "#ifndef OSMajorVersion"
+echo >>generic.cf "#define OSMajorVersion    $osmajorversion"
+echo >>generic.cf "#endif"
+echo >>generic.cf "#ifndef OSMinorVersion"
+echo >>generic.cf "#define OSMinorVersion    $osminorversion"
+echo >>generic.cf "#endif"
+echo >>generic.cf "#ifndef OSTeenyVersion"
+echo >>generic.cf "#define OSTeenyVersion    $osteenyversion"
+echo >>generic.cf "#endif"
+echo >>generic.cf "#ifndef PlatformNameForInstallPath"
+echo >>generic.cf "#define PlatformNameForInstallPath    $platformnameforinstallpath"
+echo >>generic.cf "#endif"
+
+if gawkversion=`getVersion "gawk -W version"`
+then
+        echo 1>&2 "Configure: using gawk"
+	echo >>generic.cf "#ifndef AwkCmd"
+	echo >>generic.cf "#define AwkCmd gawk"
+	echo >>generic.cf "#endif"
+else
+	if nawkversion=`getVersion "nawk </dev/null"`
+	then
+		echo 1>&2 "Configure: using nawk"
+		echo >>generic.cf "#ifndef AwkCmd"
+		echo >>generic.cf "#define AwkCmd nawk"
+		echo >>generic.cf "#endif"
+	fi
+fi
+
+if bisonversion=`getVersion "bison -V" | grep -i version`
+then
+	echo 1>&2 "Configure: using bison $bisonversion"
+	echo >>generic.cf "#ifndef YaccCmd"
+	echo >>generic.cf "#define YaccCmd bison -y"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef YaccLib"
+	echo >>generic.cf "#define YaccLib /**/"
+	echo >>generic.cf "#endif"
+fi
+
+if flexversion=`getVersion "flex -v" | grep -i version`
+then
+	echo 1>&2 "Configure: using flex $flexversion"
+	echo >>generic.cf "#ifndef LexCmd"
+	echo >>generic.cf "#define LexCmd flex"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef LexLib"
+	echo >>generic.cf "#define LexLib -lfl"
+	echo >>generic.cf "#endif"
+fi
+
+if bzip2version=`getVersion "bzip2 -V" | grep -i version`
+then
+	echo 1>&2 "Configure: using bzip2 $bzip2version"
+	echo >>generic.cf "#ifndef CompressCmd"
+	echo >>generic.cf "#define CompressCmd bzip2"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef UnCompressCmd"
+	echo >>generic.cf "#define UnCompressCmd bzip2 -d"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef CompressExtension"
+	echo >>generic.cf "#define CompressExtension bz2"
+	echo >>generic.cf "#endif"
+elif gzipversion=`getVersion "gzip -V" | grep -i gzip`
+then
+	echo 1>&2 "Configure: using gzip $gzipversion"
+	echo >>generic.cf "#ifndef CompressCmd"
+	echo >>generic.cf "#define CompressCmd gzip --best"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef UnCompressCmd"
+	echo >>generic.cf "#define UnCompressCmd gzip -d"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef CompressExtension"
+	echo >>generic.cf "#define CompressExtension gz"
+	echo >>generic.cf "#endif"
+fi
+
+if gnutarversion=`getVersion "gnutar --version" | grep -i tar`
+then
+	echo 1>&2 "Configure: using gnutar $gnutarversion"
+	echo >>generic.cf "#ifndef TarCmd"
+	echo >>generic.cf "#define TarCmd gnutar"
+	echo >>generic.cf "#endif"
+fi
+
+foundallgcc="no"
+if [ "$usegccifpresent" = "yes" ]
+then
+	echo 1>&2 "Configure: will try to use gcc"
+		usegcc="gcc"
+		usegpp="g++"
+	if gccversion=`getVersion "$usegcc -v" | grep -v 'Configured with:' | grep -i version`
+	then
+		echo 1>&2 "Configure: using $usegcc version $gccversion"
+		if gplusplusversion=`getVersion "$usegpp -v" | grep -v 'Configured with:' | grep -i version`
+		then
+			gplusplussubversion=`echo "$gplusplusversion" | sed -e 's/egcs-//' -e 's/Apple Computer.* based on //' -e 's/Apple LLVM version/LLVM version/'`
+			gplusplusmajorversion=`echo "$gplusplussubversion" | awk '{print $3}' | sed 's/[.]/ /g' | awk '{print $1}'`
+			gplusplusminorversion=`echo "$gplusplussubversion" | awk '{print $3}' | sed 's/[.]/ /g' | awk '{print $2}'`
+			gplusplustinyversion=` echo "$gplusplussubversion" | awk '{print $3}' | sed 's/[.]/ /g' | awk '{print $3}'`
+
+			echo 1>&2 "Configure: using $usegpp version $gplusplusversion ($gplusplusmajorversion.$gplusplusminorversion.$gplusplustinyversion)"
+
+			foundallgcc="yes"
+			echo >>generic.cf "#ifndef AnsiCCmd"
+			echo >>generic.cf "#define AnsiCCmd $usegcc"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef CPlusPlusCmd"
+			echo >>generic.cf "#define CPlusPlusCmd $usegpp"
+			echo >>generic.cf "#endif"
+
+			# cope with X11 includes screwing up g++ 2.95.x
+
+			if [ "$gplusplusmajorversion" -ge 2 -a "$gplusplusminorversion" -eq 95 ]
+			then
+				if [ "$gplusplustinyversion" -ge 2 ]
+				then
+					if [ "$osname" != "Darwin" ]
+					then
+						echo >>generic.cf "#ifndef SystemIncludeOption"
+						echo >>generic.cf "#define SystemIncludeOption -isystem" 
+						echo >>generic.cf "#endif"
+					fi
+				else
+					echo >>generic.cf "#ifndef CPlusPlusUnoptimizedDebugFlags"
+					echo >>generic.cf "#define CPlusPlusUnoptimizedDebugFlags NeedMissingPrototypes -fpermissive"
+					echo >>generic.cf "#endif"
+					echo >>generic.cf "#ifndef CPlusPlusOptimizedDebugFlags"
+					echo >>generic.cf "#define CPlusPlusOptimizedDebugFlags OptimizeLevel NeedMissingPrototypes -fpermissive"
+					echo >>generic.cf "#endif"
+				fi
+			fi
+
+			# cope with new standard C++ library in g++ 3.0 messing up streampos, etc.:
+
+			if [ "$gplusplusmajorversion" -ge 3 ]
+			then
+				echo >>generic.cf "#ifndef HasStdNameSpaceForStreamPos"
+				echo >>generic.cf "#define HasStdNameSpaceForStreamPos 1"
+				echo >>generic.cf "#endif"
+			fi
+
+			if [ "$gplusplusmajorversion" -gt 4 -o \( "$gplusplusmajorversion" -eq 4 -a "$gplusplusminorversion" -ge 3 \) ]
+			then
+				echo >>generic.cf "#ifndef UseStandardHeadersWithoutExtension"
+				echo >>generic.cf "#define UseStandardHeadersWithoutExtension 1"
+				echo >>generic.cf "#endif"
+				echo >>generic.cf "#ifndef EmitUsingStdNameSpace"
+				echo >>generic.cf "#define EmitUsingStdNameSpace 1"
+				echo >>generic.cf "#endif"
+			fi
+
+			echo >>generic.cf "#ifndef AnsiCUnoptimizedDebugFlags"
+			echo >>generic.cf "#define AnsiCUnoptimizedDebugFlags NeedMissingPrototypes"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef AnsiCOptimizedDebugFlags"
+			echo >>generic.cf "#define AnsiCOptimizedDebugFlags OptimizeLevel NeedMissingPrototypes"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef CPlusPlusUnoptimizedDebugFlags"
+			echo >>generic.cf "#define CPlusPlusUnoptimizedDebugFlags NeedMissingPrototypes -Wno-deprecated"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef CPlusPlusOptimizedDebugFlags"
+			echo >>generic.cf "#define CPlusPlusOptimizedDebugFlags OptimizeLevel NeedMissingPrototypes -Wno-deprecated"
+			echo >>generic.cf "#endif"
+
+			gccpath=`$usegcc -v 2>&1 \
+				| grep "Reading specs from" \
+				| awk '{print $4}' \
+				| sed 's/\/specs$//'`
+			
+			if [ ! -z "$gccpath" ]
+			then
+				cpptouse="$gccpath/cpp"
+				if [ ! -f "$cpptouse" ]
+				then
+					cpptouse="$gccpath/cpp0"
+				fi
+				if [ ! -f "$cpptouse" ]
+				then
+					cpptouse="$gccpath/cpp*"
+				fi
+				echo 1>&2 "Configure: using cpp to build include paths: $cpptouse"
+
+				echo >>generic.cf "#ifndef AnsiCDependIncludePath"
+				echo >>generic.cf "#define AnsiCDependIncludePath " \
+					`$cpptouse -v -lang-c 2>&1 </dev/null \
+					| sed -e '1,/#include </d' -e '/^End of search list/,$d' \
+					| sed -e 's/^[ 	]*/\"-I/' -e 's/$/\"/'`
+				echo >>generic.cf "#endif"
+		
+				echo >>generic.cf "#ifndef CPlusPlusDependIncludePath"
+				echo >>generic.cf "#define CPlusPlusDependIncludePath " \
+					`$cpptouse -v -lang-c++ 2>&1 </dev/null \
+					| sed -e '1,/#include </d' -e '/^End of search list/,$d' \
+					| sed -e 's/^[ 	]*/\"-I/' -e 's/$/\"/'`
+				echo >>generic.cf "#endif"
+			fi
+
+			if [ "$osname" = "SunOS" -a "$osmajorversion" = 4 ]
+			then
+				echo >>generic.cf "#ifndef NeedMissingPrototypes"
+				echo >>generic.cf "#define NeedMissingPrototypes -DNEEDMISSINGPROTOTYPES"
+				echo >>generic.cf "#endif"
+			fi
+		else
+			echo 1>&2 "Configure: g++ not available :("
+		fi
+	else
+		echo 1>&2 "Configure: gcc not available :("
+	fi
+fi
+
+# ----------------------- OS dependent stuff -------------------------
+
+# see also the GNU stuff ... some of it is OS dependent
+
+# always supress the Imake.tpl default of adding a dependency on static libraries
+# like libX11.a, which often are not present these days, regardless of OS (has
+# been a problem on Solaris 10 and Linux with X11 from Xorg V7
+
+echo >>generic.cf "#ifndef DisplayDependFlags"
+echo >>generic.cf "#define DisplayDependFlags"
+echo >>generic.cf "#endif"
+
+if [ "$osname" = "SunOS" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+	if [ "$osmajorversion" = "5" ]
+	then
+		echo 1>&2 "Configure: using Solaris network load flags"
+		echo >>generic.cf "#ifndef NetworkLoadFlags"
+		echo >>generic.cf "#define NetworkLoadFlags -lsocket -lnsl"
+		echo >>generic.cf "#endif"
+
+		echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+		echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+		echo >>generic.cf "#endif"
+		
+		if [ "$osminorversion" -lt 10 ]
+		then
+			echo >>generic.cf "#ifndef UseGlibcTimezone"
+			echo >>generic.cf "#define UseGlibcTimezone -1"	# use altzone as well as extern timezone (datetype.cc)
+			echo >>generic.cf "#endif"
+		else
+			echo >>generic.cf "#ifndef UseGlibcTimezone"
+			echo >>generic.cf "#define UseGlibcTimezone 0"	# altzone does not seem to exist on Solaris 5.10
+			echo >>generic.cf "#endif"
+		fi
+	fi
+
+	echo >>generic.cf "#ifndef HasGetHostID"
+	echo >>generic.cf "#define HasGetHostID 1"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef HasGetHostIDPrototype"
+	echo >>generic.cf "#define HasGetHostIDPrototype 1"	# in <unistd.h>; not true pre Solaris 2.6
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef X11LibraryPath"
+	echo >>generic.cf "#define X11LibraryPath /usr/openwin/lib"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef X11IncludePath"
+	echo >>generic.cf "#define X11IncludePath /usr/openwin/include"
+	echo >>generic.cf "#endif"
+
+	if [ "$osmajorversion" = "5" ]
+	then
+		echo 1>&2 "Configure: using Solaris display load flags"
+		echo >>generic.cf "#ifndef DisplayLoadFlags"
+		echo >>generic.cf "#define DisplayLoadFlags" \
+			" Concat(-L,\$(X11LIBRARYPATH))" \
+			" Concat(-R,\$(X11LIBRARYPATH)) -lX11 -lXext"
+		echo >>generic.cf "#endif"
+	fi
+
+	if [ $foundallgcc = "no" ]
+	then
+		if getIsPresent CC
+		then
+			echo 1>&2 "Configure: setting up for native CC (if g++ not used)"
+			SunProIncludePath CC  CC cc \
+				CPlusPlusCmd CPlusPlus DebugFlags \
+				CPlusPlusDependIncludePath
+		fi
+
+		if getIsPresent acc
+		then
+			echo 1>&2 "Configure: setting up for native acc (if g++ not used)"
+			SunProIncludePath acc cc c \
+				AnsiCCmd AnsiC DebugFlags \
+				AnsiCDependIncludePath
+		else
+			if getIsPresent cc
+			then
+				echo 1>&2 "Configure: setting up for native cc (if g++ not used)"
+				SunProIncludePath cc  cc c \
+					AnsiCCmd AnsiC DebugFlags \
+					AnsiCDependIncludePath
+			fi
+		fi
+	fi
+
+	if [ "$osmajorversion" = "5" ]
+	then
+		echo 1>&2 "Configure: Solaris has no ranlib"
+		echo >>generic.cf "#ifndef DoRanlibCmd"
+		echo >>generic.cf "#define DoRanlibCmd 0"
+		echo >>generic.cf "#endif"
+	fi
+
+	if [ "$osmajorversion" = "5" ]
+	then
+		echo 1>&2 "Configure: Solaris uses ucb install"
+		echo >>generic.cf "#ifndef InstallCmd"
+		echo >>generic.cf "#define InstallCmd /usr/ucb/install -c"
+		echo >>generic.cf "#endif"
+	fi
+
+	if [ "$osmajorversion" = "5" ]
+	then
+		echo 1>&2 "Configure: Solaris uses mkdir -p rather than mkdirhier"
+		echo >>generic.cf "#ifndef MkdirhierCmd"
+		echo >>generic.cf "#define MkdirhierCmd mkdir -p"
+		echo >>generic.cf "#endif"
+	fi
+
+	echo >>generic.cf "#ifndef RmCmd"
+	echo >>generic.cf "#define RmCmd rm -rf"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef ExtraFilesToClean"
+	echo >>generic.cf "#define ExtraFilesToClean *% *.old *.hold .nfs* ptrepository .sb"
+	echo >>generic.cf "#endif"
+fi
+
+if [ "$osname" = "Irix" -o "$osname" = "IRIX" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+	echo >>generic.cf "#ifndef X11LibraryPath"
+	echo >>generic.cf "#define X11LibraryPath /usr/lib"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef X11IncludePath"
+	echo >>generic.cf "#define X11IncludePath /usr/include"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef DoRanlibCmd"
+	echo >>generic.cf "#define DoRanlibCmd 0"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef InstallCmd"
+	echo >>generic.cf "#define InstallCmd /usr/bin/X11/bsdinst -c"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef WhatismanCmd"
+	echo >>generic.cf "#define WhatismanCmd makewhatis"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef CPlusPlusDependIncludePath"
+	echo >>generic.cf "#define CPlusPlusDependIncludePath  -I/usr/include/CC"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef AnsiCOptimizedDebugFlags"
+	echo >>generic.cf "#define AnsiCOptimizedDebugFlags OptimizeLevel NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef AnsiCUnoptimizedDebugFlags"
+	echo >>generic.cf "#define AnsiCUnoptimizedDebugFlags NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef CPlusPlusOptimizedDebugFlags"
+	echo >>generic.cf "#define CPlusPlusOptimizedDebugFlags OptimizeLevel NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES -woff 3115,3937,3262"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef CPlusPlusUnoptimizedDebugFlags"
+	echo >>generic.cf "#define CPlusPlusUnoptimizedDebugFlags NeedMissingPrototypes -DNOBOOLEANTYPE -DNOBOOLEANVALUES -woff 3115,3937,3262"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+fi
+
+if [ "$osname" = "HP-UX" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+	if [ -d /usr/include/X11R5 ]
+	then
+		echo >>generic.cf "#ifndef X11IncludePath"
+		echo >>generic.cf "#define X11IncludePath /usr/include/X11R5"
+		echo >>generic.cf "#endif"
+	fi
+
+	if [ -d /usr/lib/X11R5 ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/lib/X11R5"
+		echo >>generic.cf "#endif"
+	fi
+
+	echo >>generic.cf "#ifndef PowIntegerExponentType"
+	echo >>generic.cf "#define PowIntegerExponentType int"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+fi
+
+if [ "$osname" = "OSF1" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+	OSFIncludePath cxx  CC .cc \
+		CPlusPlusCmd CPlusPlus DebugFlags \
+		CPlusPlusDependIncludePath
+
+	OSFIncludePath cc  cc .c \
+		AnsiCCmd AnsiC DebugFlags \
+		AnsiCDependIncludePath
+
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef InstallCmd"
+	echo >>generic.cf "#define InstallCmd /usr/ucb/installbsd -c"
+	echo >>generic.cf "#endif"
+
+	if [ -f /usr/lib/libX11.a ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/lib"
+		echo >>generic.cf "#endif"
+	fi
+fi
+
+if [ "$osname" = "Linux" -o "$osname" = "GNU/kFreeBSD" -o "$osname" = "GNU" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+
+	# X11 is usually in /usr/include on Linux systems
+
+	# X11LibraryPath may already have been overridden, but ...
+
+	if [ -f /usr/lib64/libX11.a -o -f /usr/lib64/libX11.so ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/lib64"
+		echo >>generic.cf "#endif"
+		if [ ! -f /usr/lib64/libXext.a ]
+		then
+			echo >>generic.cf "#ifndef DisplayLoadFlags"
+			echo >>generic.cf "#define DisplayLoadFlags Concat(-L,\$(X11LIBRARYPATH)) -lX11"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef DisplayDependFlags"
+			echo >>generic.cf "#define DisplayDependFlags Concat(\$(X11LIBRARYPATH),/libX11.a)"
+			echo >>generic.cf "#endif"
+		fi
+	elif [ -f /usr/lib/libX11.a -o -f /usr/lib/libX11.so ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/lib"
+		echo >>generic.cf "#endif"
+		if [ ! -f /usr/lib/libXext.a ]
+		then
+			echo >>generic.cf "#ifndef DisplayLoadFlags"
+			echo >>generic.cf "#define DisplayLoadFlags Concat(-L,\$(X11LIBRARYPATH)) -lX11"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef DisplayDependFlags"
+			echo >>generic.cf "#define DisplayDependFlags Concat(\$(X11LIBRARYPATH),/libX11.a)"
+			echo >>generic.cf "#endif"
+		fi
+	elif [ -f /usr/lib/x86_64-linux-gnu/libX11.a -o -f /usr/lib/x86_64-linux-gnu/libX11.so ]	# Found on Ubuntu 14.04
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/lib/x86_64-linux-gnu"
+		echo >>generic.cf "#endif"
+		if [ ! -f /usr/lib/libXext.a ]
+		then
+			echo >>generic.cf "#ifndef DisplayLoadFlags"
+			echo >>generic.cf "#define DisplayLoadFlags Concat(-L,\$(X11LIBRARYPATH)) -lX11"
+			echo >>generic.cf "#endif"
+			echo >>generic.cf "#ifndef DisplayDependFlags"
+			echo >>generic.cf "#define DisplayDependFlags Concat(\$(X11LIBRARYPATH),/libX11.a)"
+			echo >>generic.cf "#endif"
+		fi
+	elif [ -d /usr/X11R6/lib64 ]		# Found on AMD x86_64 platforms eg. FC3
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/X11R6/lib64"
+		echo >>generic.cf "#endif"
+	elif [ -d /usr/X11R6/lib ]		# NOT /usr/lib/X11 which contains configuration files
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/X11R6/lib"
+		echo >>generic.cf "#endif"
+	elif [ -d /usr/X11/lib ]	# seen in XFree86
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/X11/lib"
+		echo >>generic.cf "#endif"
+	fi
+
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef HasGetHostID"
+	echo >>generic.cf "#define HasGetHostID 1"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef HasGetHostIDPrototype"
+	echo >>generic.cf "#define HasGetHostIDPrototype 1"	# in <unistd.h>
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef ExtraFilesToClean"
+	echo >>generic.cf "#define ExtraFilesToClean *core.*"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef UseGlibcTimezone"
+	echo >>generic.cf "#define UseGlibcTimezone 1"
+	echo >>generic.cf "#endif"
+fi
+
+isCygwin=`echo "$osname" | egrep -i '^cygwin_nt'`
+if [ ! -z "${isCygwin}" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef HasGetHostID"
+	echo >>generic.cf "#define HasGetHostID 1"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef HasGetHostIDPrototype"
+	echo >>generic.cf "#define HasGetHostIDPrototype 1"	# in <unistd.h>
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef UseGlibcTimezone"
+	echo >>generic.cf "#define UseGlibcTimezone -2"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef HasStdNameSpaceForStreamPos"
+	echo >>generic.cf "#define HasStdNameSpaceForStreamPos 1"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef ExecutableSuffix"
+	echo >>generic.cf "#define ExecutableSuffix .exe"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef X11LibraryPath"
+	echo >>generic.cf "#define X11LibraryPath /usr/X11R6/lib"
+	echo >>generic.cf "#endif"
+fi
+
+if [ "$osname" = "ULTRIX" ]
+then
+	echo 1>&2 "Configure: we are on $osname"
+	if [ -f /usr/lib/libX11.a ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/lib"
+		echo >>generic.cf "#endif"
+	fi
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+fi
+
+if [ "$osname" = "Darwin" ]
+then
+	echo 1>&2 "Configure: we are on $osname ($osmajorversion.$osminorversion)"
+
+	if [ -f /opt/X11/bin/makedepend ]
+	then
+		echo >>generic.cf "#ifndef MakedependCmd"
+		echo >>generic.cf "#define MakedependCmd /opt/X11/bin/makedepend"
+		echo >>generic.cf "#endif"
+	fi
+
+	if [ -d /opt/X11/lib ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /opt/X11/lib"
+		echo >>generic.cf "#endif"
+	elif [ -d /usr/X11R6/lib ]
+	then
+		echo >>generic.cf "#ifndef X11LibraryPath"
+		echo >>generic.cf "#define X11LibraryPath /usr/X11R6/lib"
+		echo >>generic.cf "#endif"
+	fi
+
+	if [ -d /opt/X11/include ]
+	then
+		echo >>generic.cf "#ifndef X11IncludePath"
+		echo >>generic.cf "#define X11IncludePath /opt/X11/include"
+		echo >>generic.cf "#endif"
+	elif [ -d /usr/X11R6/include ]
+	then
+		echo >>generic.cf "#ifndef X11IncludePath"
+		echo >>generic.cf "#define X11IncludePath /usr/X11R6/include"
+		echo >>generic.cf "#endif"
+	fi
+
+	echo >>generic.cf "#ifndef HasGetHostID"
+	echo >>generic.cf "#define HasGetHostID 1"
+	echo >>generic.cf "#endif"
+	echo >>generic.cf "#ifndef HasGetHostIDPrototype"
+	echo >>generic.cf "#define HasGetHostIDPrototype 1"	# in <unistd.h>
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef UseDumbInfinityAndNAN"
+	echo >>generic.cf "#define UseDumbInfinityAndNAN 1"
+	echo >>generic.cf "#endif"
+
+	echo >>generic.cf "#ifndef UseGlibcTimezone"
+	echo >>generic.cf "#define UseGlibcTimezone 1"
+	echo >>generic.cf "#endif"
+	
+	instructionsetarchitecture=`uname -p`
+	machinearchitecture=`uname -m`
+	if [ "$gplusplusmajorversion" -ge 4 -a $instructionsetarchitecture = 'i386' ]
+	then
+		echo 1>&2 "Configure: building Darwin for intel only"
+		echo >>generic.cf "#ifndef CPlusPlusDefaultOptions"
+		echo >>generic.cf "#define CPlusPlusDefaultOptions -force_cpusubtype_ALL -arch $machinearchitecture -mmacosx-version-min=10.0"
+		echo >>generic.cf "#endif"
+	
+		echo >>generic.cf "#ifndef AnsiCDefaultOptions"
+		echo >>generic.cf "#define AnsiCDefaultOptions -force_cpusubtype_ALL -arch $machinearchitecture -mmacosx-version-min=10.0"
+		echo >>generic.cf "#endif"
+	fi
+
+	cppVersionIsBadApple=`cpp -v < /dev/null 2>&1 | grep 'Apple LLVM version 5'`
+	if [ ! -z "$cppVersionIsBadApple" ]
+	then
+		echo 1>&2 "Configure: The default Apple LLVM version 5.x cpp will fail to execute imake"
+		if getIsPresent llvm-cpp-4.2
+		then
+			if [ -z "$IMAKECPP" ]
+			then
+				echo 1>&2 "Configure: Set the environment variable IMAKECPP to llvm-cpp-4.2 before running imake or make"
+			else
+				echo 1>&2 "Configure: Already have the correct environment variable IMAKECPP set to llvm-cpp-4.2"
+			fi
+		else
+			echo 1>&2 "Configure: You need to port install llvm-gcc42 before running imake"
+		fi
+	fi
+fi
+
+# ---------------------- After OS dependent stuff -----------------------
+
+# this should probably be elsewhere ...
+
+echo >>generic.cf "#ifndef NeedMissingPrototypes"
+echo >>generic.cf "#define NeedMissingPrototypes"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef UseXMitShmExtension"
+echo >>generic.cf "#define UseXMitShmExtension 0"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef HasGetHostID"
+echo >>generic.cf "#define HasGetHostID 0"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef HasStdNameSpaceForStreamPos"
+echo >>generic.cf "#define HasStdNameSpaceForStreamPos 0"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef UseStandardHeadersWithoutExtension"
+echo >>generic.cf "#define UseStandardHeadersWithoutExtension 0"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef EmitUsingStdNameSpace"
+echo >>generic.cf "#define EmitUsingStdNameSpace 0"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef SystemIncludeOption"
+echo >>generic.cf "#define SystemIncludeOption -I" 
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef UseGlibcTimezone"
+echo >>generic.cf "#define UseGlibcTimezone 0"
+echo >>generic.cf "#endif"
+
+echo >>generic.cf "#ifndef ExecutableSuffix"
+echo >>generic.cf "#define ExecutableSuffix"
+echo >>generic.cf "#endif"
diff --git a/config/Imake.p-rules b/config/Imake.p-rules
new file mode 100755
index 0000000..d0c24ae
--- /dev/null
+++ b/config/Imake.p-rules
@@ -0,0 +1,90 @@
+/* Rules specific to THIS particular project */
+
+/*
+ * ProjectToolLibraryHeaderTemplate - general translate template to
+ * header using awk script in support area and specifying multiple args
+ */
+#ifndef ProjectToolLibraryHeaderTemplate
+#define	ProjectToolLibraryHeaderTemplate(header,template,script,args)	@@\
+header.h: $(PROJECTLIBSTANDARDDIR)/template.tpl \			@@\
+			$(PROJECTLIBSUPPORTDIR)/script.awk		@@\
+	RemoveTargetProgram(header.h)					@@\
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/script.awk \			@@\
+		args <$(PROJECTLIBSTANDARDDIR)/template.tpl >header.h	@@\
+									@@\
+depend::	header.h						@@\
+									@@\
+clean::									@@\
+	$(RM) header.h
+#endif /* ProjectToolLibraryHeaderTemplate */
+
+/*
+ * ProjectConvertTemplate - general translate template to
+ * header using awk script in support area
+ */
+#ifndef ProjectConvertTemplate
+#define	ProjectConvertTemplate(file,template,script,args)		@@\
+file: template.tpl $(PROJECTLIBSUPPORTDIR)/script.awk			@@\
+	RemoveTargetProgram(file)					@@\
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/script.awk \			@@\
+		args <template.tpl >file				@@\
+									@@\
+depend::	file							@@\
+									@@\
+clean::									@@\
+	$(RM) file
+#endif /* ProjectConvertTemplate */
+
+/*
+ * ProjectInstallOnMakeUpdatedLibraryHeader
+ */
+#ifndef ProjectInstallOnMakeUpdatedLibraryHeader
+#define	ProjectInstallOnMakeUpdatedLibraryHeader(hdr,dest)		@@\
+all::	$(PROJECTINCLUDEDIR)/dest/hdr.h					@@\
+									@@\
+depend:: $(PROJECTINCLUDEDIR)/dest/hdr.h				@@\
+									@@\
+$(PROJECTINCLUDEDIR)/dest/hdr.h:	hdr.h				@@\
+	$(CP) hdr.h $(PROJECTINCLUDEDIR)/dest/hdr.h			@@\
+									@@\
+clean::									@@\
+	$(RM) $(PROJECTINCLUDEDIR)/dest/hdr.h
+#endif /* ProjectInstallOnDependUpdatedLibraryHeader */
+
+/*
+ * AllExecutableTarget - generate rules to build necessary executables during make all, accounting for executable filename extension on some platforms
+ */
+#ifndef AllExecutableTarget
+#define AllExecutableTarget(depends)						@@\
+all:: depends$(EXECUTABLESUFFIX)
+#endif /* AllExecutableTarget */
+
+/*
+ * NormalCCProgramTarget - generate rules to compile and link the indicated 
+ * program; since it does not use any default object files, it may be used for
+ * multiple programs in the same Imakefile.
+ * Accounting for executable filename extension on some platforms.
+ */
+#ifndef NormalCCProgramTarget
+#define	NormalCCProgramTarget(program,objects,deplibs,locallibs,syslibs) @@\
+program: objects deplibs						 @@\
+	RemoveTargetProgram($@$(EXECUTABLESUFFIX))		 @@\
+	$(CCC) -o $@ objects $(CPLUSPLUS_LDOPTIONS) locallibs \		 @@\
+		$(CPLUSPLUS_LDLIBS) syslibs \				 @@\
+		$(CPLUSPLUS_EXTRA_LOAD_FLAGS) 				 @@\
+	$(STRIP) $@$(EXECUTABLESUFFIX) 				 @@\
+									 @@\
+clean::									 @@\
+	$(RM) program$(EXECUTABLESUFFIX)
+#endif /* NormalCCProgramTarget */
+
+/*
+ * InstallProgram - generate rules to install an executable program using any
+ * special install flags set in $(INSTALLFLAGS).
+ * Accounting for executable filename extension on some platforms.
+ */
+#ifndef InstallProgram
+#define	InstallProgram(program,dest)					@@\
+InstallProgramWithFlags(program/**/$(EXECUTABLESUFFIX),dest,NullParameter)
+#endif /* InstallProgram */
+
diff --git a/config/Imake.rules b/config/Imake.rules
new file mode 100755
index 0000000..8a7c56e
--- /dev/null
+++ b/config/Imake.rules
@@ -0,0 +1,654 @@
+XCOMM -------------------------------------------------------------------------
+XCOMM Imake rules for building libraries, programs, scripts, and data files
+XCOMM rules:  $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+/*
+ *		   MACHINE-INDEPENDENT RULES; DO NOT MODIFY
+ *
+ * Warning, when defining rules: make sure you do not include both a trailing
+ * backslash and double ampersand backslash or else you will get an extra
+ * backslash in the Makefile.
+ * 
+ * The following macros are defined for the various templates and Imakefiles
+ * (for a list of the applicable make variables, see the template files):
+ * 
+ * RemoveTargetProgram		(program)
+ * MakeDir			(dir)
+ * NormalCProgramTarget		(program,objects,deplibs,locallibs,syslibs)
+ * NormalCCProgramTarget	(program,objects,deplibs,locallibs,syslibs)
+ * RanLibrary			(args)
+ * LibraryTarget		(libpathname,objlist)
+ * InstallLibrary		(libname,dest)
+ * InstallManPageLong		(file,destdir,dest)
+ * InstallManPage		(file,destdir)
+ * InstallManPageAliases	(file,destdir,aliases)
+ * InstallWhatis		()
+ * InstallNamedNonExec		(srcname,dstname,dest)
+ * InstallNonExecFile		(file,dest)
+ * InstallNonExec		(file,dest)
+ * InstallProgramWithFlags	(program,dest,flags)
+ * InstallProgram		(program,dest)
+ * InstallScript		(program,dest)
+ * InstallNamedProg		(srcname,dstname,dest)
+ * DependCTarget		()
+ * DependCCTarget		()
+ * CleanTarget			()
+ * BuildMakefileTarget		(notused,imakeflags)
+ * MakefileTarget		()
+ * MakeSubincludesForBuild	(step,dir,srclist)
+ * NamedTargetSubdirs		(name,dirs,verb,flags,subname)
+ * NamedMakeSubdirs		(name,dirs)
+ * MakeSubdirs			(dirs)
+ * DependSubdirs		(dirs)
+ * ForceSubdirs			(dirs)
+ * InstallSubdirs		(dirs)
+ * InstallManSubdirs		(dirs)
+ * IncludesSubdirs		(dirs)
+ * NamedCleanSubdirs		(name,dirs)
+ * CleanSubdirs			(dirs)
+ * MakeMakeSubdirs		(dirs,target)
+ * MakeNsubdirMakefiles		()
+ * MakefileSubdirs		(dirs)
+ * MakeDirectories		(step,dirs)
+ * AllTarget			(depends)
+ *
+ *
+ * The following are in Imake.tmpl:
+ *
+ * Concat			(a,b)
+ * Concat3			(a,b,c)
+ * 
+ */
+
+#define NullParameter
+
+/* if [ -d ] or [ ! -d ] causes make to fail, define this as - */
+#ifndef DirFailPrefix
+#define DirFailPrefix
+#endif
+
+#ifndef RemoveTargetProgram
+#if RemoveTargetProgramByMoving
+#define RemoveTargetProgram(program) \
+if [ -f program ]; then $(RM) Concat(program,~); $(MV) program Concat(program,~); fi
+#else
+#define RemoveTargetProgram(program) $(RM) program
+#endif
+#endif
+
+#ifndef MakeDir
+#define MakeDir(dir) DirFailPrefix at if [ -d dir ]; then set +x; \	@@\
+		else (set -x; $(MKDIRHIER) dir); fi
+#endif
+
+/*
+ * NormalCProgramTarget - generate rules to compile and link the indicated 
+ * program; since it does not use any default object files, it may be used for
+ * multiple programs in the same Imakefile.
+ */
+#ifndef NormalCProgramTarget
+#define	NormalCProgramTarget(program,objects,deplibs,locallibs,syslibs)	@@\
+program: objects deplibs						@@\
+	RemoveTargetProgram($@)						@@\
+	$(CC) -o $@ objects $(C_LDOPTIONS) locallibs \			@@\
+		$(C_LDLIBS) syslibs $(C_EXTRA_LOAD_FLAGS) 		@@\
+									@@\
+clean::									@@\
+	$(RM) program
+#endif /* NormalProgramTarget */
+
+
+/*
+ * NormalCCProgramTarget - generate rules to compile and link the indicated 
+ * program; since it does not use any default object files, it may be used for
+ * multiple programs in the same Imakefile.
+ */
+#ifndef NormalCCProgramTarget
+#define	NormalCCProgramTarget(program,objects,deplibs,locallibs,syslibs) @@\
+program: objects deplibs						 @@\
+	RemoveTargetProgram($@)						 @@\
+	$(CCC) -o $@ objects $(CPLUSPLUS_LDOPTIONS) locallibs \		 @@\
+		$(CPLUSPLUS_LDLIBS) syslibs \				 @@\
+		$(CPLUSPLUS_EXTRA_LOAD_FLAGS) 				 @@\
+	$(STRIP) $@ 							 @@\
+									 @@\
+clean::									 @@\
+	$(RM) program
+#endif /* NormalCCProgramTarget */
+
+#if DoRanlibCmd
+#define RanLibrary(args) $(RANLIB) args
+#else
+#define RanLibrary(args) /**/
+#endif
+
+/*
+ * LibraryTarget - generate rules to create a library.
+ */
+#ifndef LibraryTarget
+#define	LibraryTarget(libpathname,objlist)				@@\
+AllTarget(libpathname)							@@\
+									@@\
+libpathname: objlist							@@\
+	$(RM)  $@							@@\
+	$(AR)  $@ objlist						@@\
+	$(XAR) $@ objlist						@@\
+	RanLibrary($@)
+#endif /* LibraryTarget */
+
+/*
+ * LibraryAddTarget - generate rules to add to a library.
+ */
+#ifndef LibraryAddTarget
+#define	LibraryAddTarget(libpathname,objlist)				@@\
+AllTarget(libpathname)							@@\
+									@@\
+libpathname: objlist							@@\
+	$(AR)  $@ objlist						@@\
+	$(XAR) $@ objlist						@@\
+	RanLibrary($@)
+#endif /* LibraryAddTarget */
+
+/*
+ * InstallLibrary - generate rules to install the indicated library.
+ */
+#ifndef InstallLibrary
+#define	InstallLibrary(libname,dest)					@@\
+install:: Concat(lib,libname.a)						@@\
+	MakeDir($(DESTDIR)dest)						@@\
+	$(INSTALL) $(INSTLIBFLAGS) Concat(lib,libname.a) $(DESTDIR)dest @@\
+	RanLibrary($(RANLIBINSTFLAGS) Concat($(DESTDIR)dest/lib,libname.a))
+#endif /* InstallLibrary */
+
+/*
+ * InstallManPageLong - generate rules to install the indicated manual page,
+ * giving it an alternate name.  This is used for installing man pages whose
+ * base name without the .man suffix would normally be longer than 8 characters
+ * (the limit for using source code control systems on files systems with 
+ * short file names).
+ */
+#ifndef InstallManPageLong
+#define	InstallManPageLong(file,destdir,dest)				@@\
+install.man:: file.man							@@\
+	MakeDir($(DESTDIR)destdir)					@@\
+	$(INSTALL) $(INSTMANFLAGS) file.man $(DESTDIR)destdir/dest.$(MANSUFFIX)
+#endif /* InstallManPageLong */
+
+
+/*
+ * InstallManPage - generate rules to install the indicated manual page.
+ */
+#ifndef InstallManPage
+#define	InstallManPage(file,destdir)					@@\
+InstallManPageLong(file,destdir,file)
+#endif /* InstallManPage */
+
+
+/*
+ * InstallManPageAliases - generate rules to install manual page aliases.
+ */
+#ifndef InstallManPageAliases
+#define	InstallManPageAliases(file,destdir,aliases)			@@\
+install.man::								@@\
+	@(TMP=/tmp/tmp.$$$$; \						@@\
+	$(RM) $${TMP}; \						@@\
+	echo .so `basename destdir`/file.$(MANSUFFIX) > $${TMP}; \	@@\
+	for i in aliases; do (set -x; \					@@\
+	$(INSTALL) $(INSTMANFLAGS) $${TMP} $(DESTDIR)destdir/$$i.$(MANSUFFIX)); \ @@\
+	done; \								@@\
+	$(RM) $${TMP})
+#endif /* InstallManPageAliases */
+
+
+/*
+ * InstallManSource - generate rules to install the indicated manual source
+ * file (a file included in a man page with the .so macro).
+ */
+#ifndef InstallManSource
+#define	InstallManSource(file,destdir)					@@\
+install.man:: file.so							@@\
+	MakeDir($(DESTDIR)destdir)					@@\
+	$(INSTALL) $(INSTMANFLAGS) file.so $(DESTDIR)destdir/file.so
+#endif /* InstallManPage */
+
+
+/*
+ * InstallWhatis - update whatis database for man pages
+ */
+#ifndef InstallWhatis
+#define	InstallWhatis(NullParameter)					@@\
+install.whatis::							@@\
+	$(WHATISMAN) -M $(INSTALLMANDIR)					
+#endif /* InstallWhatis */
+
+
+/*
+ * InstallNamedNonExec - generate rules to install a data file
+ */
+#ifndef InstallNamedNonExec
+#define	InstallNamedNonExec(srcname,dstname,dest)			@@\
+install:: srcname							@@\
+	MakeDir($(DESTDIR)dest)						@@\
+	$(INSTALL) $(INSTDATFLAGS) srcname $(DESTDIR)dest/dstname
+#endif /* InstallNamedNonExec */
+
+
+/*
+ * InstallNonExecFile - generate rules to install a data file
+ */
+#ifndef InstallNonExecFile
+#define	InstallNonExecFile(file,dest)					@@\
+install:: file								@@\
+	MakeDir($(DESTDIR)dest)						@@\
+	$(INSTALL) $(INSTDATFLAGS) file $(DESTDIR)dest
+#endif /* InstallNonExecFile */
+
+
+/*
+ * InstallNonExec - generate rules to install a data file, but does not
+ * try to create the destination directory (deprecated)
+ */
+#ifndef InstallNonExec
+#define	InstallNonExec(file,dest)					@@\
+install:: file								@@\
+	$(INSTALL) $(INSTDATFLAGS) file $(DESTDIR)dest
+#endif /* InstallNonExec */
+
+
+/*
+ * InstallProgramWithFlags - generate rules to install an executable program
+ * using given install flags.
+ */
+#ifndef InstallProgramWithFlags
+#define InstallProgramWithFlags(program,dest,flags)			@@\
+install:: program							@@\
+	MakeDir($(DESTDIR)dest)						@@\
+	$(INSTALL) $(INSTPGMFLAGS) $(INSTBINFLAGS) flags program $(DESTDIR)dest
+#endif /* InstallProgramWithFlags */
+
+
+/*
+ * InstallProgram - generate rules to install an executable program using any
+ * special install flags set in $(INSTALLFLAGS).
+ */
+#ifndef InstallProgram
+#define	InstallProgram(program,dest)					@@\
+InstallProgramWithFlags(program,dest,NullParameter)
+#endif /* InstallProgram */
+
+
+
+/*
+ * InstallScript - install a shell script.
+ */
+#ifndef InstallScript
+#define	InstallScript(program,dest)					@@\
+install:: program.script						@@\
+	MakeDir($(DESTDIR)dest)						@@\
+	$(INSTALL) $(INSTBINFLAGS) program.script $(DESTDIR)dest/program
+#endif /* InstallScript */
+
+
+/*
+ * InstallNamedProg - install a program with renaming and no stripping.
+ */
+#ifndef InstallNamedProg
+#define	InstallNamedProg(srcname,dstname,dest)				@@\
+install:: srcname							@@\
+	MakeDir($(DESTDIR)dest)						@@\
+	$(INSTALL) $(INSTBINFLAGS) srcname $(DESTDIR)dest/dstname
+#endif /* InstallNamedProg */
+
+
+/*
+ * DependTargetFromFlagsAndFiles - generate rules to compute 
+ * dependencies for all sources listed using specified flags and defines
+ */
+#ifndef DependTargetFromFlagsDefinesSources
+#define	DependTargetFromFlagsDefinesSources(flags,defines,sources)	@@\
+depend::								@@\
+	$(DEPEND) flags  -s "# DO NOT DELETE"  -- defines -- sources
+#endif /* DependTarget */
+
+
+/*
+ * DependCTarget - generate rules to compute dependencies for all files listed
+ * in $(C_SRCS).
+ */
+#ifndef DependCTarget
+#define	DependCTarget() 			\
+	DependTargetFromFlagsDefinesSources( 	\
+		$(C_DEPENDFLAGS), 		\
+		$(C_ALLDEFINES), 		\
+		$(C_SRCS))
+#endif /* DependCTarget */
+
+/*
+ * AddDependCTarget - generate rules to add dependencies for all files listed
+ * in $(C_SRCS).
+ */
+#ifndef AddDependCTarget
+#define	AddDependCTarget() 			\
+	DependTargetFromFlagsDefinesSources( 	\
+		-a $(C_DEPENDFLAGS), 		\
+		$(C_ALLDEFINES), 		\
+		$(C_SRCS))
+#endif /* AddDependCTarget */
+
+
+/*
+ * DependCCTarget - generate rules to compute dependencies for all files listed
+ * in $(CPLUSPLUS_SRCS).
+ */
+#ifndef DependCCTarget
+#define	DependCCTarget() 			\
+	DependTargetFromFlagsDefinesSources( 	\
+		$(CPLUSPLUS_DEPENDFLAGS), 	\
+		$(CPLUSPLUS_ALLDEFINES), 	\
+		$(CPLUSPLUS_SRCS))
+#endif /* DependCCTarget */
+
+/*
+ * AddDependCCTarget - generate rules to add dependencies for all files listed
+ * in $(CPLUSPLUS_SRCS).
+ */
+#ifndef AddDependCCTarget
+#define	AddDependCCTarget() 			\
+	DependTargetFromFlagsDefinesSources( 	\
+		-a $(CPLUSPLUS_DEPENDFLAGS), 	\
+		$(CPLUSPLUS_ALLDEFINES), 	\
+		$(CPLUSPLUS_SRCS))
+#endif /* AddDependCCTarget */
+
+/*
+ * CleanTarget - generate rules to remove any garbage files; the #* is here
+ * instead of in the definition of RM_CMD because System V will treat the 
+ * pound sign in the RM_CMD variable as a comment.
+ */
+#ifndef CleanTarget
+#define	CleanTarget()							@@\
+clean::									@@\
+	$(RM_CMD) "#"*
+#endif /* CleanTarget */
+
+
+/*
+ * BuildMakefileTarget - generate rules to build a Makefile from an Imakefile
+ * and any special imake flags.  This is generally done automatically by the
+ * template or by any special Imakefiles.  The first argument exists just
+ * because imakeflags is usually empty and some preprocessors will complain
+ * if an empty argument is passed as the sole argument to a macro.
+ */
+#ifndef BuildMakefileTarget
+#define	BuildMakefileTarget(notused,imakeflags)				@@\
+Makefile:: 								@@\
+	- at if [ -f Makefile ]; then set -x; \				@@\
+		$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \	@@\
+	else exit 0; fi							@@\
+	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) imakeflags
+
+#endif /* BuildMakefileTarget */
+
+
+/*
+ * MakefileTarget - generate rules to build a normal Makefile.
+ *
+ * Our own version with same name is necessary to pass on Imakeflags
+ *
+ * Can't use IHaveSpecialMakefileTarget for Imake.tmpl because too late
+ * (ie. after #include INCLUDE_IMAKEFILE)
+ *
+ */
+#ifndef MakefileTarget
+#define MakefileTarget()						@@\
+BuildMakefileTarget(Imakefile,ImakeFlags)
+#endif /* MakefileTarget */
+
+#ifndef MakeSubincludesForBuild
+#define MakeSubincludesForBuild(step,dir,srclist)			@@\
+step::  dir srclist							@@\
+	@-(list=`echo srclist | sed -e 's/[^ ]*\///g'`; \		@@\
+		set -x; cd dir; $(RM) $$list)				@@\
+	@for i in srclist; do \						@@\
+		(set -x; cd dir; $(LN) ../$$i .); \			@@\
+	done								@@\
+									@@\
+dir::									@@\
+	$(MKDIRHIER) dir						@@\
+									@@\
+clean::									@@\
+	@-(if [ -d dir ]; then \					@@\
+		list=`echo srclist | sed -e 's/[^ ]*\///g'`; \		@@\
+		set -x; cd dir; $(RM) $$list; else exit 0; fi)
+#endif
+
+
+/*
+ * NamedTargetSubdirs - recursively make a series of steps
+ */
+#ifndef NamedTargetSubdirs
+#define NamedTargetSubdirs(name,dirs,verb,flags,subname)		@@\
+name::									@@\
+	@case '${MFLAGS}' in *[ik]*) set +e;; esac; \			@@\
+	for i in dirs ;\						@@\
+	do \								@@\
+		(cd $$i ; echo verb "in $(CURRENT_DIR)/$$i..."; \	@@\
+			$(MAKE) $(MFLAGS) flags subname); \		@@\
+	done
+#endif
+
+
+/*
+ * NamedMakeSubdirs - generate rules to do makes in the given subdirectories.
+ * If you want CDEBUGFLAGS passed along to subdirectories, provide a line like
+ * the following in the appropriate Imakefile
+ * 
+ *         #define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)'
+ */
+#ifndef NamedMakeSubdirs
+#define NamedMakeSubdirs(name,dirs) \
+NamedTargetSubdirs(name,dirs,"making" name,PassCDebugFlags,all)
+#endif /* NamedMakeSubdirs */
+
+#ifndef MakeSubdirs
+#define MakeSubdirs(dirs)						@@\
+NamedMakeSubdirs(all,dirs)
+#endif /* MakeSubdirs */
+
+
+/*
+ * DependSubdirs - generate rules to recursively compute dependencies as
+ * part of the make depend step.
+ */
+#ifndef DependSubdirs
+#define DependSubdirs(dirs) \
+NamedTargetSubdirs(depend,dirs,"depending",NullParameter,depend)
+#endif /* DependSubdirs */
+
+
+/*
+ * ForceSubdirs - force make to build subdirectories
+ */
+#ifndef ForceSubdirs
+#define ForceSubdirs(dirs)						@@\
+dirs: FRC								@@\
+	@cd $@ ; echo "making all in $(CURRENT_DIR)/$@..."; \		@@\
+	$(MAKE) $(MFLAGS) PassCDebugFlags all				@@\
+									@@\
+FRC:
+#endif /* ForceSubdirs */
+
+/*
+ * TestSubdirs - generate rules to recursively test.
+ */
+#ifndef TestSubdirs
+#define TestSubdirs(dirs) \
+NamedTargetSubdirs(test,dirs,"testing",DESTDIR='$(DESTDIR)',test)
+#endif /* TestSubdirs */
+
+
+/*
+ * TestCreateSubdirs - generate rules to recursively create tests.
+ */
+#ifndef TestCreateSubdirs
+#define TestCreateSubdirs(dirs) \
+NamedTargetSubdirs(test.create,dirs,"creating tests",DESTDIR='$(DESTDIR)',test.create)
+#endif /* TestCreateSubdirs */
+
+
+/*
+ * InstallSubdirs - generate rules to recursively install programs and files.
+ */
+#ifndef InstallSubdirs
+#define InstallSubdirs(dirs) \
+NamedTargetSubdirs(install,dirs,"installing",DESTDIR='$(DESTDIR)',install)
+#endif /* InstallSubdirs */
+
+
+/*
+ * InstallManSubdirs - generate rules to recursively install manual pages.
+ */
+#ifndef InstallManSubdirs
+#define InstallManSubdirs(dirs) \
+NamedTargetSubdirs(install.man,dirs,"installing man pages",DESTDIR='$(DESTDIR)',install.man)
+#endif /* InstallManSubdirs */
+
+/*
+ * IncludesSubdirs - generate rules to recursively put include files in build
+ */
+#ifndef IncludesSubdirs
+#define IncludesSubdirs(dirs) \
+NamedTargetSubdirs(includes,dirs,including,NullParameter,includes)
+#endif
+
+
+/*
+ * CleanSubdirs - generate rules to recursively clean out garbage files.
+ */
+#ifndef NamedCleanSubdirs
+#define NamedCleanSubdirs(name,dirs) \
+NamedTargetSubdirs(name,dirs,"cleaning",RM_CMD='$(RM_CMD)',clean)
+#endif /* NamedCleanSubdirs */
+
+#ifndef CleanSubdirs
+#define CleanSubdirs(dirs) \
+NamedCleanSubdirs(clean,dirs)
+#endif
+
+
+/*
+ * MakeMakeSubdirs - generate rules to recursively recreate Makefiles as part
+ * of the specified step in the build.  If $(TOP) is set to an absolute path, 
+ * do not prepend the ../ prefix.  This makes running things outside of the 
+ * source tree to be much easier.
+ */
+#ifndef MakeMakeSubdirs
+#define MakeMakeSubdirs(dirs,target)					@@\
+target::								@@\
+	@case '${MFLAGS}' in *[ik]*) set +e;; esac; \			@@\
+	for i in dirs ;\						@@\
+	do \								@@\
+		echo "making Makefiles in $(CURRENT_DIR)/$$i..."; \	@@\
+		case "$$i" in \						@@\
+		./?*/?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \	@@\
+		./?*/?*/?*) newtop=../../../ sub=subsubsub;; \		@@\
+		./?*/?*)    newtop=../../ sub=subsub;; \		@@\
+		./?*)       newtop=../ sub=sub;; \			@@\
+		*/?*/?*/?*)    newtop=../../../../ sub=subsubsubsub;; \	@@\
+		*/?*/?*)    newtop=../../../ sub=subsubsub;; \		@@\
+		*/?*)       newtop=../../ sub=subsub;; \		@@\
+		*)	    newtop=../ sub=sub;; \			@@\
+		esac; \							@@\
+		case "$(TOP)" in \					@@\
+		/?*) newtop=  upprefix=  ;; \				@@\
+		*) upprefix=../ ;; \					@@\
+		esac; \							@@\
+		$(MAKE) $${sub}dirMakefiles UPPREFIX=$$upprefix NEWTOP=$$newtop \		@@\
+		MAKEFILE_SUBDIR=$$i NEW_CURRENT_DIR=$(CURRENT_DIR)/$$i;\ @@\
+	done
+#endif /* MakeMakeSubdirs */
+
+
+/*
+ * MakeNsubdirMakefiles - generate rules to create sub Makefiles.
+ *
+ * Our own version with same name is necessary to pass on Imakeflags
+ *
+ */
+#ifndef MakeNsubdirMakefiles
+#define MakeNsubdirMakefiles()						@@\
+subdirMakefiles:							@@\
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak				@@\
+	- at if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \		@@\
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \ @@\
+	else exit 0; fi							@@\
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR) ImakeFlags; \	@@\
+	$(MAKE) $(MFLAGS) Makefiles 					@@\
+									@@\
+subsubdirMakefiles:							@@\
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak				@@\
+	- at if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \		@@\
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \ @@\
+	else exit 0; fi							@@\
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR) ImakeFlags; \	@@\
+	$(MAKE) $(MFLAGS) Makefiles 					@@\
+									@@\
+subsubsubdirMakefiles:							@@\
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak				@@\
+	- at if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \		@@\
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \ @@\
+	else exit 0; fi @@\
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR) ImakeFlags; \	@@\
+	$(MAKE) $(MFLAGS) Makefiles 					@@\
+									@@\
+subsubsubsubdirMakefiles:						@@\
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak				@@\
+	- at if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \		@@\
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \ @@\
+	else exit 0; fi 						@@\
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR) ImakeFlags; \	@@\
+	$(MAKE) $(MFLAGS) Makefiles
+#endif /* MakeNsubdirMakefiles */
+
+
+/*
+ * MakefileSubdirs - generate rules to create Makefiles.
+ */
+#ifndef MakefileSubdirs
+#define MakefileSubdirs(dirs)						@@\
+MakeMakeSubdirs(dirs,Makefiles)						@@\
+									@@\
+MakeNsubdirMakefiles()
+#endif /* MakefileSubdirs */
+
+/*
+ * Translate XCOMM into pound sign with sed, rather than passing -DXCOMM=XCOMM
+ * to cpp, because that trick does not work on all ANSI C preprocessors.
+ * Also delete line numbers from the cpp output (-P is not portable, I guess).
+ */
+#ifndef CppSedMagic
+#define CppSedMagic sed -e '/^#  *[0-9][0-9]*  *.*$$/d' \
+		    -e '/^XCOMM$$/s//#/' \
+		    -e '/^XCOMM[^a-zA-Z0-9_]/s/^XCOMM/#/'
+#endif /* CppSedMagic */
+
+/*
+ * MakeDirectories - generate rules to create a hierarchy of directories.
+ */
+#ifndef MakeDirectories
+#define MakeDirectories(step,dirs)					@@\
+step::									@@\
+	@case '${MFLAGS}' in *[i]*) set +e;; esac;			@@\
+	DirFailPrefix at for i in dirs; do if [ -d $(DESTDIR)$$i ]; then \	@@\
+		set +x; else (set -x; $(MKDIRHIER) $(DESTDIR)$$i); fi \	@@\
+	done
+#endif /* MakeDirectories */
+
+
+/*
+ * AllTarget - generate rules to build necessary things during make all.
+ */
+#ifndef AllTarget
+#define AllTarget(depends)						@@\
+all:: depends
+#endif /* AllTarget */
diff --git a/config/Imake.tmpl b/config/Imake.tmpl
new file mode 100755
index 0000000..8f105e2
--- /dev/null
+++ b/config/Imake.tmpl
@@ -0,0 +1,613 @@
+/*
+ * generic imake template
+ */
+
+#ifndef XCOMM
+#define XCOMM #
+#endif
+XCOMM -------------------------------------------------------------------------
+XCOMM Makefile generated from IMAKE_TEMPLATE and INCLUDE_IMAKEFILE
+XCOMM
+XCOMM Platform-specific parameters may be set in the appropriate <vendor>.cf
+XCOMM configuration files.  Site-specific parameters should be set in the file
+XCOMM site.def.  Full rebuilds are recommended if any parameters are changed.
+XCOMM
+
+#define	YES	1
+#define NO	0
+
+
+/* Started as imake -I./config -DTOP=. -DCURDIR=. SiteImakeFlags ProjectImakeFlags */
+
+#ifndef MacroIncludeFile
+#define ProjectMacroIncludeFile 	<generic.p-cf>
+#define MacroIncludeFile		<generic.cf>
+#endif
+
+/*****************************************************************************
+ *                                                                           *
+ *                       DO NOT MODIFY BELOW THIS LINE                       *
+ *                                                                           *
+ *****************************************************************************/
+
+
+XCOMM -------------------------------------------------------------------------
+XCOMM site-specific configuration parameters that need to come before
+XCOMM the platform-specific parameters - edit site.def to change
+#define BeforeVendorCF
+#include <site.p-def>
+#include <site.def>
+#undef BeforeVendorCF
+
+XCOMM -------------------------------------------------------------------------
+XCOMM platform-specific configuration parameters - edit MacroFile to change
+#include ProjectMacroIncludeFile
+#include MacroIncludeFile
+
+/* It is a kludge to put these two macros here,
+ * but Project.tmpl needs them and it is not clear there is a better place.
+ */
+
+/*
+ * Concat - concatenates two strings.
+ */
+#ifndef Concat
+#if __STDC__ && !defined(UnixCpp)
+#define Concat(a,b)a##b
+#else
+#define Concat(a,b)a/**/b
+#endif
+#endif
+
+/*
+ * Concat3 - concatenates three strings.
+ */
+#ifndef Concat3
+#if __STDC__ && !defined(UnixCpp)
+#define Concat3(a,b,c)a##b##c
+#else
+#define Concat3(a,b,c)a/**/b/**/c
+#endif
+#endif
+
+XCOMM -------------------------------------------------------------------------
+XCOMM site-specific configuration parameters that go after
+XCOMM the platform-specific parameters - edit site.def to change
+#define AfterVendorCF
+#include <site.p-def>
+#include <site.def>
+#undef AfterVendorCF
+
+/*
+ * defaults for various generic parameters; set in site.def if needed
+ */
+
+#ifndef OSName
+#define OSName            Unknown Operating System
+#endif
+#ifndef OSMajorVersion
+#define OSMajorVersion          0
+#endif
+#ifndef OSMinorVersion
+#define OSMinorVersion          0
+#endif
+#ifndef OSTeenyVersion
+#define OSTeenyVersion          0
+#endif
+
+#ifndef X11LibraryPath
+#define X11LibraryPath /usr/lib/X11
+#endif
+#ifndef X11IncludePath
+#define X11IncludePath /usr/include/X11
+#endif
+
+#ifndef PassCDebugFlags
+#define PassCDebugFlags 'C_DEBUGFLAGS=$(C_DEBUGFLAGS)' 'CPLUSPLUS_DEBUGFLAGS=$(CPLUSPLUS_DEBUGFLAGS)'
+#endif
+
+#ifndef AnsiCUnoptimizedDebugFlags
+#define AnsiCUnoptimizedDebugFlags -O
+#endif
+#ifndef AnsiCOptimizedDebugFlags
+#define AnsiCOptimizedDebugFlags -O
+#endif
+#ifndef AnsiCDebuggableDebugFlags
+#define AnsiCDebuggableDebugFlags -g
+#endif
+#ifndef AnsiCNoOpDebugFlags
+#define AnsiCNoOpDebugFlags
+#endif
+#ifndef AnsiCDefaultDebugFlags
+#define AnsiCDefaultDebugFlags AnsiCOptimizedDebugFlags
+#endif
+#ifndef AnsiCDefaultOptions
+#define AnsiCDefaultOptions
+#endif
+
+#ifndef AnsiCStandardIncludes
+#define AnsiCStandardIncludes			/* for platform-specifics */
+#endif
+#ifndef AnsiCStandardDefines
+#define AnsiCStandardDefines
+#endif
+#ifndef AnsiCExtraLibraries
+#define AnsiCExtraLibraries
+#endif
+#ifndef AnsiCExtraLoadFlags
+#define AnsiCExtraLoadFlags
+#endif
+#ifndef AnsiCDependIncludePath
+#define AnsiCDependIncludePath
+#endif
+#ifndef AnsiCDependFlags
+#define AnsiCDependFlags AnsiCDependIncludePath
+#endif
+
+#ifndef CPlusPlusUnoptimizedDebugFlags
+#define CPlusPlusUnoptimizedDebugFlags -O
+#endif
+#ifndef CPlusPlusOptimizedDebugFlags
+#define CPlusPlusOptimizedDebugFlags -O
+#endif
+#ifndef CPlusPlusDebuggableDebugFlags
+#define CPlusPlusDebuggableDebugFlags -g
+#endif
+#ifndef CPlusPlusNoOpDebugFlags
+#define CPlusPlusNoOpDebugFlags
+#endif
+#ifndef CPlusPlusDefaultDebugFlags
+#define CPlusPlusDefaultDebugFlags CPlusPlusOptimizedDebugFlags
+#endif
+#ifndef CPlusPlusDefaultOptions
+#define CPlusPlusDefaultOptions
+#endif
+
+#ifndef CPlusPlusStandardIncludes
+#define CPlusPlusStandardIncludes		/* for platform-specifics */
+#endif
+#ifndef CPlusPlusStandardDefines
+#define CPlusPlusStandardDefines
+#endif
+#ifndef CPlusPlusExtraLibraries
+#define CPlusPlusExtraLibraries
+#endif
+#ifndef CPlusPlusExtraLoadFlags
+#define CPlusPlusExtraLoadFlags
+#endif
+#ifndef CPlusPlusDependIncludePath
+#define CPlusPlusDependIncludePath
+#endif
+#ifndef CPlusPlusDependFlags
+#define CPlusPlusDependFlags CPlusPlusDependIncludePath
+#endif
+
+#ifndef DisplayIncludeFlags
+#define DisplayIncludeFlags Concat(-I,$(X11INCLUDEPATH)) 
+#endif
+#ifndef DisplayLoadFlags
+#define DisplayLoadFlags Concat(-L,$(X11LIBRARYPATH)) -lX11 -lXext
+#endif
+#ifndef DisplayDependFlags
+#define DisplayDependFlags Concat($(X11LIBRARYPATH),/libX11.a) Concat($(X11LIBRARYPATH),/libXext.a)
+#endif
+#ifndef NetworkLoadFlags
+#define NetworkLoadFlags
+#endif
+
+#ifndef AnsiCCmd
+#define AnsiCCmd	cc
+#endif
+#ifndef CPlusPlusCmd
+#define CPlusPlusCmd	CC
+#endif
+
+#ifndef InstPgmFlags
+#define InstPgmFlags -s
+#endif
+#ifndef InstBinFlags
+#define InstBinFlags -m 0755
+#endif
+#ifndef InstUidFlags
+#define InstUidFlags -m 4755
+#endif
+#ifndef InstLibFlags
+#define InstLibFlags -m 0644
+#endif
+#ifndef InstIncFlags
+#define InstIncFlags -m 0444
+#endif
+#ifndef InstManFlags
+#define InstManFlags -m 0444
+#endif
+#ifndef InstDatFlags
+#define InstDatFlags -m 0444
+#endif
+
+#ifndef BourneShell
+#define BourneShell /bin/sh
+#endif
+
+#ifndef ArCmd
+#define ArCmd ar rcv
+#endif
+#ifndef XarCmd
+#define XarCmd true
+#endif
+#ifndef AsCmd
+#define AsCmd as
+#endif
+#ifndef AwkCmd
+#define AwkCmd awk
+#endif
+#ifndef CompressCmd
+#define CompressCmd compress
+#endif
+#ifndef UnCompressCmd
+#define UnCompressCmd compress -d
+#endif
+#ifndef CompressExtension
+#define CompressExtension Z
+#endif
+#ifndef TarCmd
+#define TarCmd tar
+#endif
+#ifndef TarExtension
+#define TarExtension tar
+#endif
+
+#ifndef InstallCmd
+#define InstallCmd install -c
+#endif
+#ifndef StripCmd
+#define StripCmd strip
+#endif
+#ifndef LdCmd
+#define LdCmd ld
+#endif
+#ifndef CpCmd
+#define CpCmd cp
+#endif
+#ifndef LnCmd
+#define LnCmd ln -s
+#endif
+#ifndef MakeCmd
+#define MakeCmd make
+#endif
+#ifndef MvCmd
+#define MvCmd mv
+#endif
+#ifndef DoRanlibCmd
+#define DoRanlibCmd 1
+#endif
+#ifndef RanlibCmd
+#define RanlibCmd ranlib
+#endif
+#ifndef RanlibInstFlags
+#define RanlibInstFlags /**/
+#endif
+#ifndef RmCmd
+#define RmCmd rm -rf
+#endif
+#ifndef SortCmd
+#define SortCmd _POSIX2_VERSION=199209 sort
+#endif
+#ifndef WhatismanCmd
+#define WhatismanCmd catman -w
+#endif
+
+#ifndef ImakeCmd
+#define ImakeCmd imake
+#endif
+#ifndef MakedependCmd
+#define MakedependCmd makedepend
+#endif
+#ifndef MkdirhierCmd
+#define MkdirhierCmd mkdirhier
+#endif
+#ifndef MkdirCmd
+#define MkdirCmd MkdirhierCmd
+#endif
+
+#ifndef YaccCmd
+#define YaccCmd yacc
+#endif
+#ifndef YaccLib
+#define YaccLib -ly
+#endif
+#ifndef LexCmd
+#define LexCmd lex
+#endif
+#ifndef LexLib
+#define LexLib -ll
+#endif
+
+#ifndef DoxygenCmd
+#define DoxygenCmd doxygen
+#endif
+
+#ifndef ExecutableSuffix
+#define ExecutableSuffix
+#endif
+
+#ifndef TOPDIR
+#define TOPDIR .
+#endif
+#ifndef CURDIR
+#define CURDIR .
+#endif
+#ifndef ExtraFilesToClean
+#define ExtraFilesToClean /**/
+#endif
+#ifndef FilesToClean
+#define FilesToClean *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut a.out .sb ii_files Templates.DB mon.out gmon.out
+#endif
+
+            SHELL = BourneShell
+
+              TOP = TOPDIR
+      CURRENT_DIR = CURDIR
+     EXECUTABLESUFFIX = ExecutableSuffix
+
+               AR = ArCmd
+              XAR = XarCmd
+               AS = AsCmd
+              AWK = AwkCmd
+               CC = AnsiCCmd
+              CCC = CPlusPlusCmd
+         COMPRESS = CompressCmd
+       UNCOMPRESS = UnCompressCmd
+      COMPRESSEXT = CompressExtension
+              TAR = TarCmd
+           TAREXT = TarExtension
+          INSTALL = InstallCmd
+            STRIP = StripCmd
+               LD = LdCmd
+               LN = LnCmd
+             MAKE = MakeCmd
+               MV = MvCmd
+               CP = CpCmd
+#if DoRanlibCmd
+           RANLIB = RanlibCmd
+  RANLIBINSTFLAGS = RanlibInstFlags
+#endif
+               RM = RmCmd
+             SORT = SortCmd
+        WHATISMAN = WhatismanCmd
+
+            IMAKE = ImakeCmd
+           DEPEND = MakedependCmd
+        MKDIRHIER = MkdirhierCmd
+            MKDIR = MkdirCmd
+
+             YACC = YaccCmd
+          YACCLIB = YaccLib
+              LEX = LexCmd
+           LEXLIB = LexLib
+
+          DOXYGEN = DoxygenCmd
+
+
+     INSTPGMFLAGS = InstPgmFlags	/* install flags for programs */
+     INSTBINFLAGS = InstBinFlags	/* install flags for executables */
+     INSTUIDFLAGS = InstUidFlags	/* install flags for setuid programs */
+     INSTLIBFLAGS = InstLibFlags	/* install flags for libraries */
+     INSTINCFLAGS = InstIncFlags	/* install flags for headers */
+     INSTMANFLAGS = InstManFlags	/* install flags for man pages */
+     INSTDATFLAGS = InstDatFlags	/* install flags for data files */
+
+#ifdef ProjectRoot
+      PROJECTROOT = ProjectRoot
+#endif
+
+             C_STD_INCLUDES = AnsiCStandardIncludes
+              C_STD_DEFINES = AnsiCStandardDefines
+         C_EXTRA_LOAD_FLAGS = AnsiCExtraLoadFlags
+          C_EXTRA_LIBRARIES = AnsiCExtraLibraries
+           C_OPTIMIZEDFLAGS = AnsiCOptimizedDebugFlags
+         C_UNOPTIMIZEDFLAGS = AnsiCUnoptimizedDebugFlags
+               C_DEBUGFLAGS = AnsiCDefaultDebugFlags
+                  C_OPTIONS = AnsiCDefaultOptions
+
+     CPLUSPLUS_STD_INCLUDES = CPlusPlusStandardIncludes
+      CPLUSPLUS_STD_DEFINES = CPlusPlusStandardDefines
+ CPLUSPLUS_EXTRA_LOAD_FLAGS = CPlusPlusExtraLoadFlags
+  CPLUSPLUS_EXTRA_LIBRARIES = CPlusPlusExtraLibraries
+   CPLUSPLUS_OPTIMIZEDFLAGS = CPlusPlusOptimizedDebugFlags
+ CPLUSPLUS_UNOPTIMIZEDFLAGS = CPlusPlusUnoptimizedDebugFlags
+       CPLUSPLUS_DEBUGFLAGS = CPlusPlusDefaultDebugFlags
+          CPLUSPLUS_OPTIONS = CPlusPlusDefaultOptions
+
+            DISP_LOAD_FLAGS = DisplayLoadFlags
+            DISP_INCL_FLAGS = DisplayIncludeFlags
+             NET_LOAD_FLAGS = NetworkLoadFlags
+
+#ifdef HasStdNameSpaceForStreamPos
+     C_DEFINES_HASSTDNAMESPACEFORSTREAMPOS = -DHASSTDNAMESPACEFORSTREAMPOS=HasStdNameSpaceForStreamPos
+#endif
+
+#ifdef UseStandardHeadersWithoutExtension
+     C_DEFINES_USESTANDARDHEADERSWITHOUTEXTENSION = -DUSESTANDARDHEADERSWITHOUTEXTENSION=UseStandardHeadersWithoutExtension
+#endif
+
+#ifdef EmitUsingStdNameSpace
+     C_DEFINES_EMITUSINGSTDNAMESPACE = -DEMITUSINGSTDNAMESPACE=EmitUsingStdNameSpace
+#endif
+
+#ifdef HasGetHostID
+     C_DEFINES_HASGETHOSTID = -DHASGETHOSTID=HasGetHostID
+#endif
+
+#ifdef HasGetHostIDPrototype
+     C_DEFINES_HASGETHOSTIDPROTOTYPE = -DHASGETHOSTIDPROTOTYPE=HasGetHostIDPrototype
+#endif
+
+#ifdef PowIntegerExponentType
+     C_DEFINES_POWINTEGEREXPONENTTYPE = -DPOWINTEGEREXPONENTTYPE=PowIntegerExponentType
+#endif
+
+#ifdef UseDumbInfinityAndNAN
+     C_DEFINES_USEDUMBINFINITYANDNAN = -DUSEDUMBINFINITYANDNAN=UseDumbInfinityAndNAN
+#endif
+
+#ifdef UseGlibcTimezone
+     C_DEFINES_USEGLIBCTIMEZONE = -DUSEGLIBCTIMEZONE=UseGlibcTimezone
+#endif
+
+#ifdef UseXMitShmExtension
+     C_DEFINES_USEXMITSHMEXTENSION = -DUSEXMITSHMEXTENSION=UseXMitShmExtension
+#endif
+
+#ifdef DefaultGuessedDateOrder
+     C_DEFINES_DEFAULTGUESSEDDATEORDER = -DDEFAULTGUESSEDDATEORDER=DefaultGuessedDateOrder
+#endif
+
+#ifdef DefineBinaryIOFlags
+     C_DEFINES_BINARYIOFLAGS = -DUSEBINARYFLAGFORINPUTOPENMODE -DUSEBINARYFLAGFOROUTPUTOPENMODE
+#endif
+
+/*
+ * STD_INCLUDES contains system-specific includes
+ * EXTRA_INCLUDES contains project-specific includes set in project incfiles
+ * INCLUDES contains client-specific includes set in Imakefile
+ * LOCAL_LDFLAGS contains client-specific ld flags flags set in Imakefile
+ */
+            C_ALLINCLUDES = $(C_INCLUDES) $(C_EXTRA_INCLUDES) \
+                            $(C_TOP_INCLUDES) $(C_STD_INCLUDES)
+             C_ALLDEFINES = $(C_ALLINCLUDES) $(C_STD_DEFINES) \
+                            $(C_EXTRA_DEFINES) $(C_PROTO_DEFINES) \
+                            $(C_DEFINES) \
+                            $(C_DEFINES_POWINTEGEREXPONENTTYPE) \
+                            $(C_DEFINES_USEGLIBCTIMEZONE) \
+                            $(C_DEFINES_USEDUMBINFINITYANDNAN) \
+                            $(C_DEFINES_HASSTDNAMESPACEFORSTREAMPOS) \
+                            $(C_DEFINES_USESTANDARDHEADERSWITHOUTEXTENSION) \
+                            $(C_DEFINES_EMITUSINGSTDNAMESPACE) \
+                            $(C_DEFINES_HASGETHOSTID) \
+                            $(C_DEFINES_HASGETHOSTIDPROTOTYPE) \
+                            $(C_DEFINES_USEXMITSHMEXTENSION) \
+                            $(C_DEFINES_DEFAULTGUESSEDDATEORDER) \
+                            $(C_DEFINES_BINARYIOFLAGS)
+                   CFLAGS = $(C_DEBUGFLAGS) $(C_OPTIONS) $(C_ALLDEFINES) \
+                            $(C_UNOPTIMIZEDFLAGS)
+                 C_LDLIBS = $(C_SYS_LIBRARIES) $(C_EXTRA_LIBRARIES)
+              C_LDOPTIONS = $(C_DEBUGFLAGS) $(C_OPTIONS) $(C_LOCAL_LDFLAGS)
+            C_DEPENDFLAGS = AnsiCDependFlags
+
+    CPLUSPLUS_ALLINCLUDES = $(CPLUSPLUS_INCLUDES) $(CPLUSPLUS_EXTRA_INCLUDES) \
+                            $(CPLUSPLUS_TOP_INCLUDES) $(CPLUSPLUS_STD_INCLUDES)
+     CPLUSPLUS_ALLDEFINES = $(CPLUSPLUS_ALLINCLUDES) $(CPLUSPLUS_STD_DEFINES) \
+                            $(CPLUSPLUS_EXTRA_DEFINES) \
+                            $(CPLUSPLUS_PROTO_DEFINES) $(CPLUSPLUS_DEFINES) \
+                            $(C_DEFINES_POWINTEGEREXPONENTTYPE) \
+                            $(C_DEFINES_USEGLIBCTIMEZONE) \
+                            $(C_DEFINES_USEDUMBINFINITYANDNAN) \
+                            $(C_DEFINES_HASSTDNAMESPACEFORSTREAMPOS) \
+                            $(C_DEFINES_USESTANDARDHEADERSWITHOUTEXTENSION) \
+                            $(C_DEFINES_EMITUSINGSTDNAMESPACE) \
+                            $(C_DEFINES_HASGETHOSTID) \
+                            $(C_DEFINES_HASGETHOSTIDPROTOTYPE) \
+                            $(C_DEFINES_USEXMITSHMEXTENSION) \
+                            $(C_DEFINES_DEFAULTGUESSEDDATEORDER) \
+                            $(C_DEFINES_BINARYIOFLAGS)
+          CPLUSPLUS_FLAGS = $(CPLUSPLUS_DEBUGFLAGS) $(CPLUSPLUS_OPTIONS) \
+                            $(CPLUSPLUS_UNOPTIMIZEDFLAGS) \
+                            $(CPLUSPLUS_ALLDEFINES)
+         CPLUSPLUS_LDLIBS = $(CPLUSPLUS_SYS_LIBRARIES) \
+                            $(CPLUSPLUS_EXTRA_LIBRARIES)
+      CPLUSPLUS_LDOPTIONS = $(CPLUSPLUS_DEBUGFLAGS) $(CPLUSPLUS_OPTIONS) \
+                            $(CPLUSPLUS_LOCAL_LDFLAGS)
+    CPLUSPLUS_DEPENDFLAGS = CPlusPlusDependFlags
+
+                   RM_CMD = $(RM) FilesToClean ExtraFilesToClean
+  
+            IMAKE_DEFINES = /* leave blank, for command line use only */
+                IMAKE_CMD = $(IMAKE) \
+			-I$(NEWTOP)$(PRIVCONFIGDIR) \
+			$(IMAKE_DEFINES)
+
+           X11LIBRARYPATH = X11LibraryPath
+           X11INCLUDEPATH = X11IncludePath
+
+/* NB. Note the use of the traditional CFLAGS rather more consistent C_FLAGS */
+
+.SUFFIXES:	.c
+.c.o:	; $(CC) -c $(CFLAGS) $*.c
+
+.SUFFIXES:	.cc
+.cc.o:	; $(CCC) -c $(CPLUSPLUS_FLAGS) $*.cc
+
+/*
+ * get project-specific configuration and rules
+ */
+
+/* ImakeFlags is used in our replacement version of MakefileTarget() */
+
+#ifndef ImakeFlags
+#define ImakeFlags	SiteImakeFlags ProjectImakeFlags
+#endif
+
+#include <Project.p-tmpl>
+#include <Project.tmpl>
+
+#include <Imake.p-rules>
+#include <Imake.rules>
+
+XCOMM -------------------------------------------------------------------------
+XCOMM start of Imakefile
+#include INCLUDE_IMAKEFILE
+
+XCOMM -------------------------------------------------------------------------
+XCOMM common rules for all Makefiles - do not edit
+/*
+ * These need to be here so that rules in Imakefile occur first;  the blank
+ * all is to make sure that an empty Imakefile does not default to make clean.
+ */
+emptyrule::
+
+CleanTarget()
+
+#ifndef IHaveSpecialMakefileTarget
+MakefileTarget()
+#endif
+
+#ifdef IHaveSubdirs
+XCOMM -------------------------------------------------------------------------
+XCOMM rules for building in SUBDIRS - do not edit
+
+TestSubdirs($(SUBDIRS))
+TestCreateSubdirs($(SUBDIRS))
+InstallSubdirs($(SUBDIRS))
+InstallManSubdirs($(SUBDIRS))
+CleanSubdirs($(SUBDIRS))
+MakefileSubdirs($(SUBDIRS))
+IncludesSubdirs($(SUBDIRS))
+
+#else
+XCOMM -------------------------------------------------------------------------
+XCOMM empty rules for directories that do not have SUBDIRS - do not edit
+
+test::
+	@echo "test in $(CURRENT_DIR) done"
+
+test.create::
+	@echo "test.create in $(CURRENT_DIR) done"
+
+install::
+	@echo "install in $(CURRENT_DIR) done"
+
+install.man::
+	@echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+depend::
+
+all::
+
+#endif /* if subdirectory rules are needed */
+
+XCOMM -------------------------------------------------------------------------
+XCOMM dependencies generated by makedepend
diff --git a/config/Imakefile b/config/Imakefile
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/config/Imakefile
@@ -0,0 +1 @@
+
diff --git a/config/Project.p-tmpl b/config/Project.p-tmpl
new file mode 100755
index 0000000..ada8650
--- /dev/null
+++ b/config/Project.p-tmpl
@@ -0,0 +1,198 @@
+/* Put things specific to THIS project here */
+
+#ifndef ProjectIncludeDir
+#define ProjectIncludeDir      $(TOP)/libsrc/include
+#endif
+#ifndef ProjectLibsrcDir
+#define ProjectLibsrcDir       $(TOP)/libsrc/src
+#endif
+#ifndef ProjectLibDir
+#define ProjectLibDir          $(TOP)/libsrc/lib
+#endif
+#ifndef ProjectLibSupportDir
+#define ProjectLibSupportDir   $(TOP)/libsrc/support
+#endif
+#ifndef ProjectLibStandardDir
+#define ProjectLibStandardDir  $(TOP)/libsrc/standard
+#endif
+#ifndef ProjectSupportDir
+#define ProjectSupportDir      $(TOP)/support
+#endif
+
+#ifndef ProjectGenericIncludeDirName
+#define ProjectGenericIncludeDirName	generic
+#endif
+#ifndef ProjectDctoolIncludeDirName
+#define ProjectDctoolIncludeDirName	dctool
+#endif
+#ifndef ProjectDcdispIncludeDirName
+#define ProjectDcdispIncludeDirName	dcdisp
+#endif
+#ifndef ProjectOurdispIncludeDirName
+#define ProjectOurdispIncludeDirName	ourdisp
+#endif
+#ifndef ProjectPixeldatIncludeDirName
+#define ProjectPixeldatIncludeDirName	pixeldat
+#endif
+#ifndef ProjectDconvertIncludeDirName
+#define ProjectDconvertIncludeDirName	dconvert
+#endif
+#ifndef ProjectLocaleIncludeDirName
+#define ProjectLocaleIncludeDirName	locale
+#endif
+
+#ifndef ProjectGenericLibName
+#define ProjectGenericLibName   gener
+#endif
+#ifndef ProjectDctoolLibName
+#define ProjectDctoolLibName    dctl
+#endif
+#ifndef ProjectDcdispLibName
+#define ProjectDcdispLibName    ddply
+#endif
+#ifndef ProjectOurdispLibName
+#define ProjectOurdispLibName   odply
+#endif
+#ifndef ProjectDconvertLibName
+#define ProjectDconvertLibName  dconv
+#endif
+#ifndef ProjectLocaleLibName
+#define ProjectLocaleLibName    dlcl
+#endif
+
+#ifdef InstallInTopDir
+#ifndef InstallBinDir
+#define InstallBinDir $(TOP)/bin/$(PLATFORMNAME)
+#endif
+#ifndef InstallIncDir
+#define InstallIncDir $(TOP)/include
+#endif
+#ifndef InstallLibDir
+#define InstallLibDir $(TOP)/lib/$(PLATFORMNAME)
+#endif
+#ifndef InstallManDir
+#define InstallManDir $(TOP)/man
+#endif
+#endif
+
+                  PLATFORMNAME = PlatformNameForInstallPath
+
+             PROJECTINCLUDEDIR = ProjectIncludeDir
+              PROJECTLIBSRCDIR = ProjectLibsrcDir
+                 PROJECTLIBDIR = ProjectLibDir
+          PROJECTLIBSUPPORTDIR = ProjectLibSupportDir
+         PROJECTLIBSTANDARDDIR = ProjectLibStandardDir
+
+             PROJECTSUPPORTDIR = ProjectSupportDir
+
+         PROJECTGENERICLIBNAME = ProjectGenericLibName
+          PROJECTDCTOOLLIBNAME = ProjectDctoolLibName
+          PROJECTDCDISPLIBNAME = ProjectDcdispLibName
+         PROJECTOURDISPLIBNAME = ProjectOurdispLibName
+        PROJECTDCONVERTLIBNAME = ProjectDconvertLibName
+          PROJECTLOCALELIBNAME = ProjectLocaleLibName
+
+             PROJECTGENERICLIB = -l$(PROJECTGENERICLIBNAME)
+            PROJECTDCONVERTLIB = -l$(PROJECTDCONVERTLIBNAME)
+              PROJECTDCTOOLLIB = -l$(PROJECTDCTOOLLIBNAME)
+              PROJECTDCDISPLIB = -l$(PROJECTDCDISPLIBNAME)
+             PROJECTOURDISPLIB = -l$(PROJECTOURDISPLIBNAME)
+              PROJECTLOCALELIB = -l$(PROJECTLOCALELIBNAME)
+
+            PROJECTACRNEMALIBS = $(PROJECTDCTOOLLIB)   $(PROJECTLOCALELIB)  $(PROJECTGENERICLIB) 
+           PROJECTDCONVERTLIBS = $(PROJECTDCONVERTLIB) $(PROJECTDCTOOLLIB)  $(PROJECTLOCALELIB)  $(PROJECTGENERICLIB) 
+             PROJECTDCFILELIBS = $(PROJECTDCTOOLLIB)   $(PROJECTLOCALELIB)  $(PROJECTGENERICLIB) 
+             PROJECTDCDISPLIBS = $(PROJECTDCDISPLIB)   $(PROJECTOURDISPLIB) $(PROJECTDCTOOLLIB)  $(PROJECTLOCALELIB) $(PROJECTGENERICLIB) DisplayLoadFlags
+               PROJECTMISCLIBS = $(PROJECTLOCALELIB)   $(PROJECTGENERICLIB) 
+                PROJECTALLLIBS = $(PROJECTDCONVERTLIB) $(PROJECTDCDISPLIB)  $(PROJECTOURDISPLIB) $(PROJECTDCTOOLLIB) $(PROJECTLOCALELIB) $(PROJECTGENERICLIB) DisplayLoadFlags
+
+          PROJECTGENERICDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTGENERICLIBNAME).a
+         PROJECTDCONVERTDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTDCONVERTLIBNAME).a
+           PROJECTDCTOOLDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTDCTOOLLIBNAME).a
+           PROJECTDCDISPDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTDCDISPLIBNAME).a
+          PROJECTOURDISPDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTOURDISPLIBNAME).a
+           PROJECTLOCALEDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTLOCALELIBNAME).a
+
+         PROJECTACRNEMADEPLIBS = $(PROJECTDCTOOLDEPLIB)   $(PROJECTLOCALEDEPLIB)  $(PROJECTGENERICDEPLIB) 
+        PROJECTDCONVERTDEPLIBS = $(PROJECTDCONVERTDEPLIB) $(PROJECTDCTOOLDEPLIB)  $(PROJECTLOCALEDEPLIB)  $(PROJECTGENERICDEPLIB) 
+          PROJECTDCFILEDEPLIBS = $(PROJECTDCTOOLDEPLIB)   $(PROJECTLOCALEDEPLIB)  $(PROJECTGENERICDEPLIB) 
+          PROJECTDCDISPDEPLIBS = $(PROJECTDCDISPDEPLIB)   $(PROJECTOURDISPDEPLIB) $(PROJECTDCTOOLDEPLIB)  $(PROJECTLOCALEDEPLIB) $(PROJECTGENERICDEPLIB) DisplayDependFlags
+            PROJECTMISCDEPLIBS = $(PROJECTLOCALEDEPLIB)   $(PROJECTGENERICDEPLIB)
+             PROJECTALLDEPLIBS = $(PROJECTDCONVERTDEPLIB) $(PROJECTDCDISPDEPLIB)  $(PROJECTOURDISPDEPLIB) $(PROJECTDCTOOLDEPLIB) $(PROJECTLOCALEDEPLIB) $(PROJECTGENERICDEPLIB) DisplayDependFlags
+
+  PROJECTGENERICINCLUDEDIRNAME = ProjectGenericIncludeDirName
+   PROJECTLOCALEINCLUDEDIRNAME = ProjectLocaleIncludeDirName
+   PROJECTDCTOOLINCLUDEDIRNAME = ProjectDctoolIncludeDirName
+   PROJECTDCDISPINCLUDEDIRNAME = ProjectDcdispIncludeDirName
+  PROJECTOURDISPINCLUDEDIRNAME = ProjectOurdispIncludeDirName
+ PROJECTPIXELDATINCLUDEDIRNAME = ProjectPixeldatIncludeDirName
+ PROJECTDCONVERTINCLUDEDIRNAME = ProjectDconvertIncludeDirName
+
+ PROJECTLIBGENERICEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME)
+
+ PROJECTLIBOURDISPEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTOURDISPINCLUDEDIRNAME) \
+                                  SystemIncludeOption/**/$(X11INCLUDEPATH)
+
+PROJECTLIBDCONVERTEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCONVERTINCLUDEDIRNAME)
+
+  PROJECTLIBDCDISPEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTOURDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  SystemIncludeOption/**/$(X11INCLUDEPATH)
+
+  PROJECTLIBDCTOOLEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME)
+
+  PROJECTLIBLOCALEEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME)
+
+
+ PROJECTAPPACRNEMAEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME)
+
+  PROJECTAPPDCDISPEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTOURDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  SystemIncludeOption/**/$(X11INCLUDEPATH)
+
+  PROJECTAPPDCFILEEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME)
+
+PROJECTAPPDCONVERTEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCONVERTINCLUDEDIRNAME)
+
+    PROJECTAPPMISCEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME)
+
+
+        CPLUSPLUS_LOCAL_LDFLAGS = -L$(PROJECTLIBDIR)
+
+                      C_DEFINES = -DDEFAULTUIDROOT=\"DefaultUIDRoot\" -DDEFAULTINSTANCECREATORUID=\"DefaultInstanceCreatorUID\" -DDEFAULTIMPLEMENTATIONCLASSUID=\"DefaultImplementationClassUID\" -DDEFAULTIMPLEMENTATIONVERSIONNAME=\"DefaultImplementationVersionName\" -DDEFAULTSOURCEAPPLICATIONENTITYTITLE=\"DefaultSourceApplicationEntityTitle\"
+              CPLUSPLUS_DEFINES = -DDEFAULTUIDROOT=\"DefaultUIDRoot\" -DDEFAULTINSTANCECREATORUID=\"DefaultInstanceCreatorUID\" -DDEFAULTIMPLEMENTATIONCLASSUID=\"DefaultImplementationClassUID\" -DDEFAULTIMPLEMENTATIONVERSIONNAME=\"DefaultImplementationVersionName\" -DDEFAULTSOURCEAPPLICATIONENTITYTITLE=\"DefaultSourceApplicationEntityTitle\"
+
+
+.SUFFIXES:	.xbm .cbm
+.xbm.cbm:	;$(PROJECTSUPPORTDIR)/xbmtocbm $< $@
+
diff --git a/config/Project.p-tmpl.hold b/config/Project.p-tmpl.hold
new file mode 100755
index 0000000..e06b94d
--- /dev/null
+++ b/config/Project.p-tmpl.hold
@@ -0,0 +1,198 @@
+/* Put things specific to THIS project here */
+
+#ifndef ProjectIncludeDir
+#define ProjectIncludeDir      $(TOP)/libsrc/include
+#endif
+#ifndef ProjectLibsrcDir
+#define ProjectLibsrcDir       $(TOP)/libsrc/src
+#endif
+#ifndef ProjectLibDir
+#define ProjectLibDir          $(TOP)/libsrc/lib
+#endif
+#ifndef ProjectLibSupportDir
+#define ProjectLibSupportDir   $(TOP)/libsrc/support
+#endif
+#ifndef ProjectLibStandardDir
+#define ProjectLibStandardDir  $(TOP)/libsrc/standard
+#endif
+#ifndef ProjectSupportDir
+#define ProjectSupportDir      $(TOP)/support
+#endif
+
+#ifndef ProjectGenericIncludeDirName
+#define ProjectGenericIncludeDirName	generic
+#endif
+#ifndef ProjectDctoolIncludeDirName
+#define ProjectDctoolIncludeDirName	dctool
+#endif
+#ifndef ProjectDcdispIncludeDirName
+#define ProjectDcdispIncludeDirName	dcdisp
+#endif
+#ifndef ProjectOurdispIncludeDirName
+#define ProjectOurdispIncludeDirName	ourdisp
+#endif
+#ifndef ProjectPixeldatIncludeDirName
+#define ProjectPixeldatIncludeDirName	pixeldat
+#endif
+#ifndef ProjectDconvertIncludeDirName
+#define ProjectDconvertIncludeDirName	dconvert
+#endif
+#ifndef ProjectLocaleIncludeDirName
+#define ProjectLocaleIncludeDirName	locale
+#endif
+
+#ifndef ProjectGenericLibName
+#define ProjectGenericLibName   gener
+#endif
+#ifndef ProjectDctoolLibName
+#define ProjectDctoolLibName    dctl
+#endif
+#ifndef ProjectDcdispLibName
+#define ProjectDcdispLibName    ddply
+#endif
+#ifndef ProjectOurdispLibName
+#define ProjectOurdispLibName   odply
+#endif
+#ifndef ProjectDconvertLibName
+#define ProjectDconvertLibName  dconv
+#endif
+#ifndef ProjectLocaleLibName
+#define ProjectLocaleLibName    dlcl
+#endif
+
+#ifdef InstallInTopDir
+#ifndef InstallBinDir
+#define InstallBinDir $(TOP)/bin/$(PLATFORMNAME)
+#endif
+#ifndef InstallIncDir
+#define InstallIncDir $(TOP)/include
+#endif
+#ifndef InstallLibDir
+#define InstallLibDir $(TOP)/lib/$(PLATFORMNAME)
+#endif
+#ifndef InstallManDir
+#define InstallManDir $(TOP)/man
+#endif
+#endif
+
+                  PLATFORMNAME = PlatformNameForInstallPath
+
+             PROJECTINCLUDEDIR = ProjectIncludeDir
+              PROJECTLIBSRCDIR = ProjectLibsrcDir
+                 PROJECTLIBDIR = ProjectLibDir
+          PROJECTLIBSUPPORTDIR = ProjectLibSupportDir
+         PROJECTLIBSTANDARDDIR = ProjectLibStandardDir
+
+             PROJECTSUPPORTDIR = ProjectSupportDir
+
+         PROJECTGENERICLIBNAME = ProjectGenericLibName
+          PROJECTDCTOOLLIBNAME = ProjectDctoolLibName
+          PROJECTDCDISPLIBNAME = ProjectDcdispLibName
+         PROJECTOURDISPLIBNAME = ProjectOurdispLibName
+        PROJECTDCONVERTLIBNAME = ProjectDconvertLibName
+          PROJECTLOCALELIBNAME = ProjectLocaleLibName
+
+             PROJECTGENERICLIB = -l$(PROJECTGENERICLIBNAME)
+            PROJECTDCONVERTLIB = -l$(PROJECTDCONVERTLIBNAME)
+              PROJECTDCTOOLLIB = -l$(PROJECTDCTOOLLIBNAME)
+              PROJECTDCDISPLIB = -l$(PROJECTDCDISPLIBNAME)
+             PROJECTOURDISPLIB = -l$(PROJECTOURDISPLIBNAME)
+              PROJECTLOCALELIB = -l$(PROJECTLOCALELIBNAME)
+
+            PROJECTACRNEMALIBS = $(PROJECTDCTOOLLIB)   $(PROJECTLOCALELIB)  $(PROJECTGENERICLIB) 
+           PROJECTDCONVERTLIBS = $(PROJECTDCONVERTLIB) $(PROJECTDCTOOLLIB)  $(PROJECTLOCALELIB)  $(PROJECTGENERICLIB) 
+             PROJECTDCFILELIBS = $(PROJECTDCTOOLLIB)   $(PROJECTLOCALELIB)  $(PROJECTGENERICLIB) 
+             PROJECTDCDISPLIBS = $(PROJECTDCDISPLIB)   $(PROJECTOURDISPLIB) $(PROJECTDCTOOLLIB)  $(PROJECTLOCALELIB) $(PROJECTGENERICLIB) DisplayLoadFlags
+               PROJECTMISCLIBS = $(PROJECTLOCALELIB)   $(PROJECTGENERICLIB) 
+                PROJECTALLLIBS = $(PROJECTDCONVERTLIB) $(PROJECTDCDISPLIB)  $(PROJECTOURDISPLIB) $(PROJECTDCTOOLLIB) $(PROJECTLOCALELIB) $(PROJECTGENERICLIB) DisplayLoadFlags
+
+          PROJECTGENERICDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTGENERICLIBNAME).a
+         PROJECTDCONVERTDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTDCONVERTLIBNAME).a
+           PROJECTDCTOOLDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTDCTOOLLIBNAME).a
+           PROJECTDCDISPDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTDCDISPLIBNAME).a
+          PROJECTOURDISPDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTOURDISPLIBNAME).a
+           PROJECTLOCALEDEPLIB = $(PROJECTLIBDIR)/lib$(PROJECTLOCALELIBNAME).a
+
+         PROJECTACRNEMADEPLIBS = $(PROJECTDCTOOLDEPLIB)   $(PROJECTLOCALEDEPLIB)  $(PROJECTGENERICDEPLIB) 
+        PROJECTDCONVERTDEPLIBS = $(PROJECTDCONVERTDEPLIB) $(PROJECTDCTOOLDEPLIB)  $(PROJECTLOCALEDEPLIB)  $(PROJECTGENERICDEPLIB) 
+          PROJECTDCFILEDEPLIBS = $(PROJECTDCTOOLDEPLIB)   $(PROJECTLOCALEDEPLIB)  $(PROJECTGENERICDEPLIB) 
+          PROJECTDCDISPDEPLIBS = $(PROJECTDCDISPDEPLIB)   $(PROJECTOURDISPDEPLIB) $(PROJECTDCTOOLDEPLIB)  $(PROJECTLOCALEDEPLIB) $(PROJECTGENERICDEPLIB) DisplayDependFlags
+            PROJECTMISCDEPLIBS = $(PROJECTLOCALEDEPLIB)   $(PROJECTGENERICDEPLIB)
+             PROJECTALLDEPLIBS = $(PROJECTDCONVERTDEPLIB) $(PROJECTDCDISPDEPLIB)  $(PROJECTOURDISPDEPLIB) $(PROJECTDCTOOLDEPLIB) $(PROJECTLOCALEDEPLIB) $(PROJECTGENERICDEPLIB) DisplayDependFlags
+
+  PROJECTGENERICINCLUDEDIRNAME = ProjectGenericIncludeDirName
+   PROJECTLOCALEINCLUDEDIRNAME = ProjectLocaleIncludeDirName
+   PROJECTDCTOOLINCLUDEDIRNAME = ProjectDctoolIncludeDirName
+   PROJECTDCDISPINCLUDEDIRNAME = ProjectDcdispIncludeDirName
+  PROJECTOURDISPINCLUDEDIRNAME = ProjectOurdispIncludeDirName
+ PROJECTPIXELDATINCLUDEDIRNAME = ProjectPixeldatIncludeDirName
+ PROJECTDCONVERTINCLUDEDIRNAME = ProjectDconvertIncludeDirName
+
+ PROJECTLIBGENERICEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME)
+
+ PROJECTLIBOURDISPEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTOURDISPINCLUDEDIRNAME) \
+                                  SystemIncludeOption##$(X11INCLUDEPATH)
+
+PROJECTLIBDCONVERTEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCONVERTINCLUDEDIRNAME)
+
+  PROJECTLIBDCDISPEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTOURDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  SystemIncludeOption##$(X11INCLUDEPATH)
+
+  PROJECTLIBDCTOOLEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME)
+
+  PROJECTLIBLOCALEEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME)
+
+
+ PROJECTAPPACRNEMAEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME)
+
+  PROJECTAPPDCDISPEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTOURDISPINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  SystemIncludeOption##$(X11INCLUDEPATH)
+
+  PROJECTAPPDCFILEEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME)
+
+PROJECTAPPDCONVERTEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCTOOLINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTPIXELDATINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTDCONVERTINCLUDEDIRNAME)
+
+    PROJECTAPPMISCEXTRAINCLUDES = -I$(PROJECTINCLUDEDIR)/$(PROJECTGENERICINCLUDEDIRNAME) \
+                                  -I$(PROJECTINCLUDEDIR)/$(PROJECTLOCALEINCLUDEDIRNAME)
+
+
+        CPLUSPLUS_LOCAL_LDFLAGS = -L$(PROJECTLIBDIR)
+
+                      C_DEFINES = -DDEFAULTUIDROOT="DefaultUIDRoot"  -DDEFAULTINSTANCECREATORUID="DefaultInstanceCreatorUID" -DDEFAULTIMPLEMENTATIONCLASSUID="DefaultImplementationClassUID" -DDEFAULTIMPLEMENTATIONVERSIONNAME="DefaultImplementationVersionName" -DDEFAULTSOURCEAPPLICATIONENTITYTITLE="DefaultSourceApplicationEntityTitle"
+              CPLUSPLUS_DEFINES = -DDEFAULTUIDROOT="DefaultUIDRoot"  -DDEFAULTINSTANCECREATORUID="DefaultInstanceCreatorUID" -DDEFAULTIMPLEMENTATIONCLASSUID="DefaultImplementationClassUID" -DDEFAULTIMPLEMENTATIONVERSIONNAME="DefaultImplementationVersionName" -DDEFAULTSOURCEAPPLICATIONENTITYTITLE="DefaultSourceApplicationEntityTitle"
+
+
+.SUFFIXES:	.xbm .cbm
+.xbm.cbm:	;$(PROJECTSUPPORTDIR)/xbmtocbm $< $@
+
diff --git a/config/Project.tmpl b/config/Project.tmpl
new file mode 100755
index 0000000..018a256
--- /dev/null
+++ b/config/Project.tmpl
@@ -0,0 +1,38 @@
+/* Put things common to ALL projects here */
+
+XCOMM -------------------------------------------------------------------------
+
+/*****************************************************************************
+ *                                                                           *
+ *                            DEFAULT DEFINITONS                             *
+ *                                                                           *
+ * The following section contains defaults for things that can be overridden *
+ * in the various *.cf and site.def files.                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+#ifndef PrivConfigDir
+#define PrivConfigDir $(TOP)/config
+#endif
+
+   PRIVCONFIGDIR = PrivConfigDir
+
+#ifndef InstallBinDir
+#define InstallBinDir /usr/local/bin
+#endif
+#ifndef InstallIncDir
+#define InstallIncDir /usr/local/include
+#endif
+#ifndef InstallLibDir
+#define InstallLibDir /usr/local/lib
+#endif
+#ifndef InstallManDir
+#define InstallManDir /usr/local/man
+#endif
+
+          PATHSEP = /			/* for building filenames */
+    INSTALLBINDIR = InstallBinDir
+    INSTALLINCDIR = InstallIncDir
+    INSTALLLIBDIR = InstallLibDir
+    INSTALLMANDIR = InstallManDir
+
diff --git a/config/generic.p-cf b/config/generic.p-cf
new file mode 100755
index 0000000..e69de29
diff --git a/config/site.def b/config/site.def
new file mode 100755
index 0000000..3436e85
--- /dev/null
+++ b/config/site.def
@@ -0,0 +1,17 @@
+/* Put things specific to THIS site and common to ALL projects here */
+
+/* Setup to pass imake command line choices to sub-directories */
+
+/* Started as imake -I./config -DTOP=. -DCURDIR=.  ... [SiteImakeFlags] ... */
+
+#ifdef BeforeVendorCF
+
+#ifndef SiteImakeFlags
+#define SiteImakeFlags
+#endif	/* SiteImakeFlags */
+
+#endif /* BeforeVendorCF */
+
+#ifdef AfterVendorCF
+
+#endif /* AfterVendorCF */
diff --git a/config/site.p-def b/config/site.p-def
new file mode 100755
index 0000000..6a23af6
--- /dev/null
+++ b/config/site.p-def
@@ -0,0 +1,250 @@
+/* Put things specific to THIS site and THIS project here */
+
+/* Setup to pass imake command line choices to sub-directories */
+
+/* Started as imake -I./config -DTOP=. -DCURDIR=. ... [-DDefaultUIDRoot=0.0.0.0] [DefaultInstanceCreatorUID=0.0.0.0] [-DDefaultImplementationClassUID=0.0.0.0] [-DDefaultImplementationVersionName=NOTSPECIFIED] [-DDefaultSourceApplicationEntityTitle=NOTSPECIFIED] [-DInstallInTopDir] [-DTmpPath=/path] [-DOptimizeLevel=-On] */
+
+#ifdef AfterVendorCF
+
+/* Please DO NOT USE UseClunieID if you are not me ... */
+/* otherwise your SOP Instances will conflict with mine :( */
+
+#ifdef UseClunieID
+
+#ifndef DefaultUIDRoot
+#define DefaultUIDRoot 1.3.6.1.4.1.5962.1
+#endif
+
+#ifndef DefaultInstanceCreatorUID
+#define DefaultInstanceCreatorUID 1.3.6.1.4.1.5962.3
+#endif
+
+#ifndef DefaultImplementationClassUID
+#define DefaultImplementationClassUID 1.3.6.1.4.1.5962.2
+#endif
+
+#ifndef DefaultImplementationVersionName
+#define DefaultImplementationVersionName DCTOOL100
+#endif
+
+#ifndef DefaultSourceApplicationEntityTitle
+#define DefaultSourceApplicationEntityTitle CLUNIE1
+#endif
+
+#endif
+
+/* Please DO NOT USE UseClunieHL7ID if you are not me ... */
+/* otherwise your SOP Instances will conflict with mine :( */
+/* HL7 OID Root 2.16.840.1.113883.3.87, registration key 4319 */
+
+#ifdef UseClunieHL7ID
+
+#ifndef DefaultUIDRoot
+#define DefaultUIDRoot 2.16.840.1.113883.3.87.1
+#endif
+
+#ifndef DefaultInstanceCreatorUID
+#define DefaultInstanceCreatorUID 2.16.840.1.113883.3.87.3
+#endif
+
+#ifndef DefaultImplementationClassUID
+#define DefaultImplementationClassUID 2.16.840.1.113883.3.87.2
+#endif
+
+#ifndef DefaultImplementationVersionName
+#define DefaultImplementationVersionName DCTOOL100
+#endif
+
+#ifndef DefaultSourceApplicationEntityTitle
+#define DefaultSourceApplicationEntityTitle CLUNIE1
+#endif
+
+#endif
+
+/* Please DO NOT USE UseClunieRadPharmID if you are not RadPharm ... */
+/* otherwise your SOP Instances will conflict with mine :( */
+
+#ifdef UseClunieRadPharmID
+
+#ifndef DefaultUIDRoot
+#define DefaultUIDRoot 1.3.6.1.4.1.11144.1
+#endif
+
+#ifndef DefaultInstanceCreatorUID
+#define DefaultInstanceCreatorUID 1.3.6.1.4.1.11144.3
+#endif
+
+#ifndef DefaultImplementationClassUID
+#define DefaultImplementationClassUID 1.3.6.1.4.1.11144.2
+#endif
+
+#ifndef DefaultImplementationVersionName
+#define DefaultImplementationVersionName DCTOOL100
+#endif
+
+#ifndef DefaultSourceApplicationEntityTitle
+#define DefaultSourceApplicationEntityTitle RADPHARM
+#endif
+
+#endif
+
+/* Please DO NOT USE UseClunieGEID if you are not me at GE ... */
+/* otherwise your SOP Instances will conflict with mine :( */
+
+#ifdef UseClunieGEID
+
+#ifndef DefaultUIDRoot
+#define DefaultUIDRoot 1.2.840.113619.6.48.1
+#endif
+
+#ifndef DefaultInstanceCreatorUID
+#define DefaultInstanceCreatorUID 1.2.840.113619.6.48.3
+#endif
+
+#ifndef DefaultImplementationClassUID
+#define DefaultImplementationClassUID 1.2.840.113619.6.48.2
+#endif
+
+#ifndef DefaultImplementationVersionName
+#define DefaultImplementationVersionName DCTOOL100
+#endif
+
+#ifndef DefaultSourceApplicationEntityTitle
+#define DefaultSourceApplicationEntityTitle CLUNIE1
+#endif
+
+#endif
+
+/* Please DO NOT USE UseClunieQI2ID if you are not me at QI2 ... */
+/* otherwise your SOP Instances will conflict with mine :( */
+
+#ifdef UseClunieQI2ID
+
+#ifndef DefaultUIDRoot
+#define DefaultUIDRoot 1.2.826.0.1.3680043.2.87.2
+#endif
+
+#ifndef DefaultInstanceCreatorUID
+#define DefaultInstanceCreatorUID 1.2.826.0.1.3680043.2.87.4
+#endif
+
+#ifndef DefaultImplementationClassUID
+#define DefaultImplementationClassUID 1.2.826.0.1.3680043.2.87.3
+#endif
+
+#ifndef DefaultImplementationVersionName
+#define DefaultImplementationVersionName DCTOOL100
+#endif
+
+#ifndef DefaultSourceApplicationEntityTitle
+#define DefaultSourceApplicationEntityTitle CLUNIE1
+#endif
+
+#endif
+
+#ifndef DefineDefaultUIDRoot
+#ifdef    DefaultUIDRoot
+#define     DefineDefaultUIDRoot		-DDefaultUIDRoot=DefaultUIDRoot
+#else     /* DefaultUIDRoot */
+#define     DefineDefaultUIDRoot		/**/
+#endif    /* DefaultUIDRoot */
+#endif  /* DefineDefaultUIDRoot */
+
+#ifndef DefineDefaultInstanceCreatorUID
+#ifdef    DefaultInstanceCreatorUID
+#define     DefineDefaultInstanceCreatorUID		-DDefaultInstanceCreatorUID=DefaultInstanceCreatorUID
+#else     /* DefaultInstanceCreatorUID */
+#define     DefineDefaultInstanceCreatorUID		/**/
+#endif    /* DefaultInstanceCreatorUID */
+#endif  /* DefineDefaultInstanceCreatorUID */
+
+#ifndef DefineDefaultImplementationClassUID
+#ifdef    DefaultImplementationClassUID
+#define     DefineDefaultImplementationClassUID		-DDefaultImplementationClassUID=DefaultImplementationClassUID
+#else     /* DefaultImplementationClassUID */
+#define     DefineDefaultImplementationClassUID		/**/
+#endif    /* DefaultImplementationClassUID */
+#endif  /* DefineDefaultImplementationClassUID */
+
+#ifndef DefineDefaultImplementationVersionName
+#ifdef    DefaultImplementationVersionName
+#define     DefineDefaultImplementationVersionName		-DDefaultImplementationVersionName=DefaultImplementationVersionName
+#else     /* DefaultImplementationVersionName */
+#define     DefineDefaultImplementationVersionName		/**/
+#endif    /* DefaultImplementationVersionName */
+#endif  /* DefineDefaultImplementationVersionName */
+
+#ifndef DefineDefaultSourceApplicationEntityTitle
+#ifdef    DefaultSourceApplicationEntityTitle
+#define     DefineDefaultSourceApplicationEntityTitle		-DDefaultSourceApplicationEntityTitle=DefaultSourceApplicationEntityTitle
+#else     /* DefaultSourceApplicationEntityTitle */
+#define     DefineDefaultSourceApplicationEntityTitle		/**/
+#endif    /* DefaultSourceApplicationEntityTitle */
+#endif  /* DefineDefaultSourceApplicationEntityTitle */
+
+#ifndef DefineTmpPath
+#ifdef    TmpPath
+#define     DefineTmpPath		-DTmpPath=TmpPath
+#else     /* TmpPath */
+#define     DefineTmpPath		/**/
+#endif    /* TmpPath */
+#endif  /* DefineTmpPath */
+
+#ifndef DefineOptimizeLevel
+#ifdef    OptimizeLevel
+#define     DefineOptimizeLevel		-DOptimizeLevel=OptimizeLevel
+#else     /* OptimizeLevel */
+#define     DefineOptimizeLevel		/**/
+#endif    /* OptimizeLevel */
+#endif  /* DefineOptimizeLevel */
+
+#ifndef DefineInstallInTopDir
+#ifdef    InstallInTopDir
+#define     DefineInstallInTopDir	-DInstallInTopDir
+#else     /* InstallInTopDir */
+#define     DefineInstallInTopDir	/**/
+#endif    /* InstallInTopDir */
+#endif  /* DefineInstallInTopDir */
+
+#ifndef DefineSystemIncludeOption
+#ifdef    SystemIncludeOption
+#define     DefineSystemIncludeOption	-DSystemIncludeOption=SystemIncludeOption
+#else     /* SystemIncludeOption */
+#define     DefineSystemIncludeOption	/**/
+#endif    /* SystemIncludeOption */
+#endif  /* DefineSystemIncludeOption */
+
+/* ProjectImakeFlags will be added to ImakeFlags in Imake.tmpl */
+
+#ifndef ProjectImakeFlags
+#define ProjectImakeFlags	DefineDefaultUIDRoot DefineDefaultInstanceCreatorUID DefineDefaultImplementationClassUID DefineDefaultImplementationVersionName DefineDefaultSourceApplicationEntityTitle DefineTmpPath DefineOptimizeLevel DefineInstallInTopDir DefineSystemIncludeOption
+#endif	/* ProjectImakeFlags */
+
+/* Defaults */
+
+#ifndef OptimizeLevel
+#define OptimizeLevel -O
+#endif
+
+#ifndef DefaultUIDRoot
+#define DefaultUIDRoot 0.0.0.0
+#endif
+
+#ifndef DefaultInstanceCreatorUID
+#define DefaultInstanceCreatorUID 0.0.0.0
+#endif
+
+#ifndef DefaultImplementationClassUID
+#define DefaultImplementationClassUID 0.0.0.0
+#endif
+
+#ifndef DefaultImplementationVersionName
+#define DefaultImplementationVersionName NOTSPECIFIED
+#endif
+
+#ifndef DefaultSourceApplicationEntityTitle
+#define DefaultSourceApplicationEntityTitle NOTSPECIFIED
+#endif
+
+#endif /* AfterVendorCF */
+ 
diff --git a/libsrc/Imakefile b/libsrc/Imakefile
new file mode 100755
index 0000000..2d5c981
--- /dev/null
+++ b/libsrc/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = standard include lib src support docs
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/libsrc/docs/Imakefile b/libsrc/docs/Imakefile
new file mode 100755
index 0000000..21490d6
--- /dev/null
+++ b/libsrc/docs/Imakefile
@@ -0,0 +1,8 @@
+all::	modtype.txt
+
+modtype.txt:	../standard/module.tpl ../support/modtype.awk
+	$(AWK) -f ../support/modtype.awk <../standard/module.tpl \
+		| $(SORT) -b +1 -2 +0 -1 >modtype.txt
+
+clean::
+	$(RM) modtype.txt
diff --git a/libsrc/include/Imakefile b/libsrc/include/Imakefile
new file mode 100755
index 0000000..9f35330
--- /dev/null
+++ b/libsrc/include/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = dcdisp dconvert dctool generic locale ourdisp pixeldat
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/libsrc/include/dcdisp/Imakefile b/libsrc/include/dcdisp/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/include/dcdisp/NOTES b/libsrc/include/dcdisp/NOTES
new file mode 100755
index 0000000..151363c
--- /dev/null
+++ b/libsrc/include/dcdisp/NOTES
@@ -0,0 +1,73 @@
+SamplesPerPixel == 1
+
+	PhotometricInterpretation == MONOCHROME1
+
+		minimum value displayed as white after VOI grayscale transform		--> ReadableWindowed{8,12,16}BitGrayImage
+
+	PhotometricInterpretation == MONOCHROME2
+
+		minimum value displayed as black after VOI grayscale transform		--> ReadableWindowed{8,12,16}BitGrayImage
+
+	PhotometricInterpretation == PALETTE COLOR
+
+		use RGB LUT which must be present
+
+		BitsAllocated == 8							--> Readable8BitIndexedPaletteColorImage
+
+		BitsAllocated == 16							--> Readable16BitIndexedPaletteColorImage
+
+SamplesPerPixel == 3
+
+	PhotometricInterpretation == RGB
+
+		minimum sample value displayed as minimum intensity color
+
+		PlanarConfiguration == 0						--> ReadableInterleaved24BitRGBTrueColorImage
+
+			R1,G1,B1,R2,G2,B2,...,Rn,Gn,Bn
+
+		PlanarConfiguration == 1						--> ReadableNonInterleaved24BitRGBTrueColorImage
+
+			R1,R2,..,Rn, G1,G2,..,Gn, B1,B2,...,Bn
+
+	PhotometricInterpretation == HSV
+
+		minimum sample value is minimum value of vector
+
+		PlanarConfiguration == 0						--> ReadableInterleaved24BitHSVTrueColorImage
+
+			H1,S1,V1,H2,S2,V2....Hn,Sn,Vn
+
+		PlanarConfiguration == 1						--> ReadableNonInterleaved24BitHSVTrueColorImage
+
+			H1,H2,..,Hn, S1,S2,..,Sn, V1,V2,...,Vn
+
+SamplesPerPixel == 4
+
+	PhotometricInterpretation == ARGB
+
+		minimum sample RGB value displayed as minimum intensity color
+
+		alpha channel passed through palette color lookup tables, and
+		if the resulting pixel value > 0 replaces RGB pixel value
+
+		PlanarConfiguration == 0						--> ReadableInterleaved32BitARGBTrueColorImage
+
+			A1,R1,G1,B1,A2,R2,G2,B2,...,An,Rn,Gn,Bn
+
+		PlanarConfiguration == 1						--> ReadableNonInterleaved32BitARGBTrueColorImage
+
+			A1,A2,..,An, R1,R2,..,Rn, G1,G2,..,Gn, B1,B2,...,Bn
+
+	PhotometricInterpretation == CMYK
+
+		minimum sample value displayed as minimum intensity color
+
+		PlanarConfiguration == 0						--> ReadableInterleaved32BitCMYKTrueColorImage
+
+			C1,M1,Y1,K1,C2,M2,Y2,K2,...,Cn,Mn,Yn,Kn
+
+		PlanarConfiguration == 1						--> ReadableNonInterleaved32BitCMYKTrueColorImage
+
+			C1,C2,..,Cn, M1,M2,..,Mn, Y1,Y2,..,Yn, K1,K2,...,Kn
+
diff --git a/libsrc/include/dcdisp/lutclass.h b/libsrc/include/dcdisp/lutclass.h
new file mode 100644
index 0000000..8df140b
--- /dev/null
+++ b/libsrc/include/dcdisp/lutclass.h
@@ -0,0 +1,53 @@
+/* lutclass.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_lutclass__
+#define __Header_lutclass__
+
+class DicomLUT : public ErrorsInClass
+{
+protected:
+	Uint32 nentries;
+	Uint32 firstindexvalue;
+	Uint16 bitsallocated;
+	Uint16 *array;
+
+	bool fillArray(Attribute *data);
+public:
+	DicomLUT(Attribute *desc,Attribute*data);
+	virtual ~DicomLUT();
+
+	virtual Uint16 operator[](Uint32 index)
+		{
+			Assert(array);
+			Assert(index < nentries);
+//cerr << "DicomLUT::operator[]"
+//     << " index" << dec << index
+//     << " value" << hex << array[index]
+//     << dec << endl;
+			return array[index];
+		}
+
+	virtual Uint32 getLength(void)	{ return nentries; }
+};
+
+class NormalDicomLUT : public DicomLUT
+{
+public:
+	NormalDicomLUT(Attribute *desc,Attribute*data);
+	virtual ~NormalDicomLUT();
+};
+
+class LargeDicomLUT : public DicomLUT
+{
+public:
+	LargeDicomLUT(Attribute *desc,Attribute*data);
+	virtual ~LargeDicomLUT();
+};
+
+class SegmentedDicomLUT : public DicomLUT
+{
+public:
+	SegmentedDicomLUT(Attribute *desc,Attribute*data);
+	virtual ~SegmentedDicomLUT();
+};
+
+#endif /* __Header_lutclass__ */
diff --git a/libsrc/include/dcdisp/lutextr.h b/libsrc/include/dcdisp/lutextr.h
new file mode 100644
index 0000000..02ca1e1
--- /dev/null
+++ b/libsrc/include/dcdisp/lutextr.h
@@ -0,0 +1,10 @@
+/* lutextr.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_lutextr__
+#define __Header_lutextr__
+
+bool extractLookUpTables(TextOutputStream &log,AttributeList& list,
+	DicomLUT *&RedLUT,
+	DicomLUT *&GreenLUT,
+	DicomLUT *&BlueLUT);
+
+#endif /* __Header_lutextr__ */
diff --git a/libsrc/include/dcdisp/rdargb.h b/libsrc/include/dcdisp/rdargb.h
new file mode 100644
index 0000000..b5fa768
--- /dev/null
+++ b/libsrc/include/dcdisp/rdargb.h
@@ -0,0 +1,29 @@
+/* rdargb.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdargb__
+#define __Header_rdargb__
+
+class ReadableInterleaved32BitARGBImage :
+	public ReadableInterleaved32BitMultiplePlaneImage,
+	public UseableTrueColorImage,
+	public UseableIndexedColorImage
+{
+public:
+	ReadableInterleaved32BitARGBImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT);
+};
+
+class ReadableNonInterleaved32BitARGBImage :
+	public ReadableNonInterleaved32BitMultiplePlaneImage,
+	public UseableTrueColorImage,
+	public UseableIndexedColorImage
+{
+public:
+	ReadableNonInterleaved32BitARGBImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT);
+};
+
+#endif /* __Header_rdargb__ */
diff --git a/libsrc/include/dcdisp/rdcmyk.h b/libsrc/include/dcdisp/rdcmyk.h
new file mode 100644
index 0000000..c2a3bee
--- /dev/null
+++ b/libsrc/include/dcdisp/rdcmyk.h
@@ -0,0 +1,25 @@
+/* rdcmyk.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdcmyk__
+#define __Header_rdcmyk__
+
+class ReadableInterleaved32BitCMYKImage :
+	public ReadableInterleaved32BitMultiplePlaneImage,
+	public UseableTrueColorImage
+{
+public:
+	ReadableInterleaved32BitCMYKImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit);
+};
+
+class ReadableNonInterleaved32BitCMYKImage :
+	public ReadableNonInterleaved32BitMultiplePlaneImage,
+	public UseableTrueColorImage
+{
+public:
+	ReadableNonInterleaved32BitCMYKImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit);
+};
+
+#endif /* __Header_rdcmyk__ */
diff --git a/libsrc/include/dcdisp/rdgray.h b/libsrc/include/dcdisp/rdgray.h
new file mode 100644
index 0000000..2dd7cfd
--- /dev/null
+++ b/libsrc/include/dcdisp/rdgray.h
@@ -0,0 +1,77 @@
+/* rdgray.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdgray__
+#define __Header_rdgray__
+
+class ReadableWindowed8BitGrayImage :
+	public Readable8BitSinglePlaneImage,
+	public UseableWindowedGrayImage
+{
+protected:
+	char mapPixel(const Uint16 src)
+		{
+			return UseableWindowedGrayImage::operator[]((unsigned char)src);
+		}
+
+	const char *getPixelMap(Uint32 &mapsize) const
+		{
+			return UseableWindowedGrayImage::getPixelMap(mapsize);
+		}
+public:
+	ReadableWindowed8BitGrayImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		Uint16 vPixelRepresentation,bool invertedgrayscale);
+
+	virtual ~ReadableWindowed8BitGrayImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue);
+};
+
+class ReadableWindowed16BitGrayImage :
+	public Readable16BitSinglePlaneImage,
+	public UseableWindowedGrayImage
+{
+private:
+	bool usepadvalue;
+	Uint16 padvalue;
+protected:
+	char mapPixel(const Uint16 src)
+		{
+			return UseableWindowedGrayImage::operator[](src);
+		}
+
+	const char *getPixelMap(Uint32 &mapsize) const
+		{
+			return UseableWindowedGrayImage::getPixelMap(mapsize);
+		}
+public:
+	ReadableWindowed16BitGrayImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		Uint16 vPixelRepresentation,bool invertedgrayscale,
+		bool padvaluepresent,Uint16 vPixelPaddingValue);
+
+	virtual ~ReadableWindowed16BitGrayImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue);
+
+	bool hasWindowLevelWidth(void)	{ return true; }
+	bool setWindowLevelWidth(Uint16 level,Uint16 width);
+	bool getWindowLevelWidth(Uint16 &level,Uint16 &width);
+	bool needToResetColorCells(void);
+	bool needToResetIndexedPixels(void);
+
+	bool setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table);
+};
+
+#endif /* __Header_rdgray__ */
diff --git a/libsrc/include/dcdisp/rdhsv.h b/libsrc/include/dcdisp/rdhsv.h
new file mode 100644
index 0000000..1cae9a8
--- /dev/null
+++ b/libsrc/include/dcdisp/rdhsv.h
@@ -0,0 +1,25 @@
+/* rdhsv.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdhsv__
+#define __Header_rdhsv__
+
+class ReadableInterleaved24BitHSVImage :
+	public ReadableInterleaved24BitMultiplePlaneImage,
+	public UseableTrueColorImage
+{
+public:
+	ReadableInterleaved24BitHSVImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit);
+};
+
+class ReadableNonInterleaved24BitHSVImage :
+	public ReadableNonInterleaved24BitMultiplePlaneImage,
+	public UseableTrueColorImage
+{
+public:
+	ReadableNonInterleaved24BitHSVImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit);
+};
+
+#endif /* __Header_rdhsv__ */
diff --git a/libsrc/include/dcdisp/rdimage.h b/libsrc/include/dcdisp/rdimage.h
new file mode 100644
index 0000000..04157a6
--- /dev/null
+++ b/libsrc/include/dcdisp/rdimage.h
@@ -0,0 +1,216 @@
+/* rdimage.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdimage__
+#define __Header_rdimage__
+
+class ReadableImage
+{
+private:
+	SupplySource *supplysource;
+protected:
+	Uint16 columns;
+	Uint16 rows;
+	Uint16 frames;
+	Uint16 planes;
+	Uint16 bitsneeded;
+	Uint16 bitsallocated;
+	Uint16 bitsstored;
+	Uint16 highbit;
+	bool issigned;
+
+	class SourceBase<Uint16> *getSource(void);
+public:
+	ReadableImage(
+		SupplySource *s,Uint16 c,Uint16 r,Uint16 f,Uint16 p,
+		Uint16 bn,Uint16 ba,Uint16 bs,Uint16 hb,
+		bool issgn=false);
+
+	virtual ~ReadableImage();
+
+	virtual bool put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row);
+
+	virtual bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	virtual bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	virtual bool getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue);
+
+	virtual bool hasWindowLevelWidth(void)	{ return false; }
+	virtual bool setWindowLevelWidth(Uint16 level,Uint16 width);
+	virtual bool getWindowLevelWidth(Uint16 &level,Uint16 &width);
+	virtual bool needToResetColorCells(void);
+	virtual bool needToResetIndexedPixels(void);
+
+	virtual bool setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table);
+
+
+	bool getSigned(void)	{ return issigned; }
+	Uint16 getBits(void)	{ return bitsstored; }
+};
+
+class ReadableSinglePlaneImage :
+	public ReadableImage
+{
+private:
+	Uint16 *bufferforfulldepthimage;
+
+	virtual bool getBufferedFullDepthImage(void);
+protected:
+	virtual char mapPixel(const Uint16 src)
+		{ Assert(0); (void)src; return 0; }
+	virtual const char *getPixelMap(Uint32 &mapsize) const
+		{ Assert(0); mapsize=0; return 0; }
+public:
+	ReadableSinglePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsneeded,Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned=false);
+
+	virtual ~ReadableSinglePlaneImage();
+
+	virtual bool getImageStatistics(Uint16 framecount,
+		Uint16 &minval,Uint16 &maxval,
+		bool excludepadvalue,Uint16 padvalue);
+
+	virtual bool put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row);
+};
+
+class ReadableMultiplePlaneImage :
+	public ReadableImage
+{
+protected:
+	virtual char mapPixel(const Uint16 v1,const Uint16 v2,const Uint16 v3)
+		{ Assert(0); (void)v1; (void)v2; (void)v3; return 0; }
+public:
+	ReadableMultiplePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,Uint16 planes,
+		Uint16 bitsneeded,Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit);
+
+	virtual ~ReadableMultiplePlaneImage();
+};
+
+class Readable8BitSinglePlaneImage :
+	public ReadableSinglePlaneImage
+{
+public:
+	Readable8BitSinglePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned=false);
+
+	virtual ~Readable8BitSinglePlaneImage();
+
+	bool put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row);
+};
+
+class Readable16BitSinglePlaneImage :
+	public ReadableSinglePlaneImage
+{
+public:
+	Readable16BitSinglePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned=false);
+
+	virtual ~Readable16BitSinglePlaneImage();
+
+	bool put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row);
+};
+
+class Readable16BitMultiplePlaneImage :
+	public ReadableMultiplePlaneImage
+{
+public:
+	Readable16BitMultiplePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit);
+
+	virtual ~Readable16BitMultiplePlaneImage();
+};
+
+class ReadableInterleaved24BitMultiplePlaneImage :
+	public ReadableMultiplePlaneImage
+{
+public:
+	ReadableInterleaved24BitMultiplePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit);
+
+
+	virtual ~ReadableInterleaved24BitMultiplePlaneImage();
+
+	virtual bool put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row);
+};
+
+class ReadableNonInterleaved24BitMultiplePlaneImage :
+	public ReadableMultiplePlaneImage
+{
+public:
+	ReadableNonInterleaved24BitMultiplePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit);
+
+	virtual ~ReadableNonInterleaved24BitMultiplePlaneImage();
+
+	virtual bool put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row);
+};
+
+class ReadableInterleaved32BitMultiplePlaneImage :
+	public ReadableMultiplePlaneImage
+{
+public:
+	ReadableInterleaved32BitMultiplePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit);
+
+	virtual ~ReadableInterleaved32BitMultiplePlaneImage();
+};
+
+class ReadableNonInterleaved32BitMultiplePlaneImage :
+	public ReadableMultiplePlaneImage
+{
+public:
+	ReadableNonInterleaved32BitMultiplePlaneImage(
+		SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+		Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit);
+
+	virtual ~ReadableNonInterleaved32BitMultiplePlaneImage();
+};
+
+#endif /* __Header_rdimage__ */
diff --git a/libsrc/include/dcdisp/rdindex.h b/libsrc/include/dcdisp/rdindex.h
new file mode 100644
index 0000000..e4e7b8c
--- /dev/null
+++ b/libsrc/include/dcdisp/rdindex.h
@@ -0,0 +1,44 @@
+/* rdindex.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdindex__
+#define __Header_rdindex__
+
+class Readable8BitIndexedColorImage :
+	public Readable8BitSinglePlaneImage,
+	protected UseableIndexedColorImage
+{
+protected:
+	char mapPixel(const Uint16 src)
+		{
+			return UseableIndexedColorImage::operator[]((unsigned char)src);
+		}
+
+public:
+	Readable8BitIndexedColorImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT);
+
+	virtual ~Readable8BitIndexedColorImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue);
+};
+
+class Readable16BitIndexedColorImage :
+	public Readable16BitSinglePlaneImage,
+	public UseableIndexedColorImage
+{
+public:
+	Readable16BitIndexedColorImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+		DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT);
+
+	virtual ~Readable16BitIndexedColorImage();
+};
+
+#endif /* __Header_rdindex__ */
diff --git a/libsrc/include/dcdisp/rdrgb.h b/libsrc/include/dcdisp/rdrgb.h
new file mode 100644
index 0000000..ad7b4e6
--- /dev/null
+++ b/libsrc/include/dcdisp/rdrgb.h
@@ -0,0 +1,53 @@
+/* rdrgb.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_rdrgb__
+#define __Header_rdrgb__
+
+class ReadableInterleaved24BitRGBImage :
+	public ReadableInterleaved24BitMultiplePlaneImage,
+	public UseableTrueColorImage
+{
+protected:
+	char mapPixel(const Uint16 red,const Uint16 green,const Uint16 blue)
+		{
+			return UseableTrueColorImage::mapPixel(red,green,blue);
+		}
+public:
+	ReadableInterleaved24BitRGBImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit);
+
+	virtual ~ReadableInterleaved24BitRGBImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue);
+};
+
+class ReadableNonInterleaved24BitRGBImage :
+	public ReadableNonInterleaved24BitMultiplePlaneImage,
+	public UseableTrueColorImage
+{
+protected:
+	char mapPixel(const Uint16 red,const Uint16 green,const Uint16 blue)
+		{
+			return UseableTrueColorImage::mapPixel(red,green,blue);
+		}
+public:
+	ReadableNonInterleaved24BitRGBImage(
+		SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+		Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit);
+
+	virtual ~ReadableNonInterleaved24BitRGBImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue);
+};
+
+#endif /* __Header_rdrgb__ */
diff --git a/libsrc/include/dcdisp/usegray.h b/libsrc/include/dcdisp/usegray.h
new file mode 100644
index 0000000..638c12d
--- /dev/null
+++ b/libsrc/include/dcdisp/usegray.h
@@ -0,0 +1,57 @@
+/* usegray.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_usegray__
+#define __Header_usegray__
+
+class UseableWindowedGrayImage
+{
+private:
+	bool inverted;
+	bool needdefaultwindowsetting;
+	Uint16 mingray;
+	Uint16 maxgray;
+	Uint16 bottom;
+	Uint16 top;
+	Uint16 signxor;
+	char  *graytocell;
+	Uint32 ngrays;
+	char  *indextocell;
+	Uint32 ncells;
+
+	unsigned short *red;
+	unsigned short *green;
+	unsigned short *blue;
+public:
+	UseableWindowedGrayImage(
+		bool invertedgrayscale,Uint16 bits,bool issigned);
+	virtual ~UseableWindowedGrayImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&ared,
+		unsigned short *&agreen,
+		unsigned short *&ablue);
+
+	bool setSign(Uint16 bits,bool s);
+	bool setWindowRange(Uint16 b,Uint16 t);
+	bool setWindowLevelWidth(Uint16 level,Uint16 width);
+	bool getWindowLevelWidth(Uint16 &level,Uint16 &width);
+
+	bool setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table);
+
+	char operator[](Uint16 index)
+		{
+			Assert(index<ngrays);
+			Assert(graytocell);
+			return graytocell[index];
+		}
+
+	const char *getPixelMap(Uint32 &mapsize) const
+		{
+			Assert(graytocell);
+			mapsize=ncells;
+			return graytocell;
+		}
+};
+
+#endif /* __Header_usegray__ */
diff --git a/libsrc/include/dcdisp/useindex.h b/libsrc/include/dcdisp/useindex.h
new file mode 100644
index 0000000..954ea63
--- /dev/null
+++ b/libsrc/include/dcdisp/useindex.h
@@ -0,0 +1,38 @@
+/* useindex.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_useindex__
+#define __Header_useindex__
+
+class UseableIndexedColorImage
+{
+private:
+	UseablePalette *palette;
+	Uint16 *palettetocell;
+	Uint32 npalette;
+	Uint32 nused;
+
+	unsigned short *palettetoindex;
+	unsigned short *red;
+	unsigned short *green;
+	unsigned short *blue;
+public:
+	UseableIndexedColorImage(DicomLUT *RedLUT,
+			DicomLUT *GreenLUT,
+			DicomLUT *BlueLUT);
+	virtual ~UseableIndexedColorImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&ared,
+		unsigned short *&agreen,
+		unsigned short *&ablue);
+
+	Uint16 operator[](Uint16 index)
+		{
+			Assert(index<npalette);
+			Assert(palettetocell);
+			return palettetocell[index];
+		}
+};
+
+#endif /* __Header_useindex__ */
diff --git a/libsrc/include/dcdisp/usepal.h b/libsrc/include/dcdisp/usepal.h
new file mode 100644
index 0000000..728fae6
--- /dev/null
+++ b/libsrc/include/dcdisp/usepal.h
@@ -0,0 +1,37 @@
+/* usepal.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_usepal__
+#define __Header_usepal__
+
+class UseablePalette
+{
+protected:
+	DicomLUT *RedLUT;
+	DicomLUT *GreenLUT;
+	DicomLUT *BlueLUT;
+public:
+	UseablePalette(DicomLUT *r,DicomLUT *g,DicomLUT *b);
+	~UseablePalette();
+	Uint32 getLength(void);
+
+	bool get16BitColorIndex(
+			Uint16 index,
+			Uint16 &red,
+			Uint16 &green,
+			Uint16 &blue)
+		{
+//cerr << "UseablePalette::get16BitColorIndex index=" << index << endl;
+			if (index >= getLength()) return false;
+			red=(*RedLUT)[index];
+			green=(*GreenLUT)[index];
+			blue=(*BlueLUT)[index];
+//cerr << "UseablePalette::get16BitColorIndex"
+//     << " index=" << dec << index
+//     << " red=" << hex << red
+//     << " green=" << hex << green
+//     << " blue=" << hex << blue
+//     << dec << endl;
+			return true;
+		}
+};
+
+#endif /* __Header_usepal__ */
diff --git a/libsrc/include/dcdisp/usetrue.h b/libsrc/include/dcdisp/usetrue.h
new file mode 100644
index 0000000..ce53020
--- /dev/null
+++ b/libsrc/include/dcdisp/usetrue.h
@@ -0,0 +1,39 @@
+/* usetrue.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_usetrue__
+#define __Header_usetrue__
+
+class UseableTrueColorImage
+{
+private:
+	Uint16 nused;
+	unsigned char *rgbtocell;
+	unsigned short *red;
+	unsigned short *green;
+	unsigned short *blue;
+public:
+	UseableTrueColorImage(void);
+	virtual ~UseableTrueColorImage();
+
+	bool getColorCellsWanted(unsigned &nwanted,unsigned &nminimum);
+	bool setColorCellsAvailable(unsigned n,unsigned long *table);
+	bool getColorCellValues(unsigned n,
+		unsigned short *&ared,
+		unsigned short *&agreen,
+		unsigned short *&ablue);
+
+	char mapPixel(Uint16 r,Uint16 g,Uint16 b)
+		{
+			// should be 8 bit data in lower part of 16 bit words
+			Assert(r<256);
+			Assert(g<256);
+			Assert(b<256);
+			Assert(nused == 256);
+			Assert(rgbtocell);
+			// The +1 is to wrap around so 0=white and 1=black
+			// a la the default X convention
+			unsigned char index=(unsigned char)(((r)&0xe0)|((g>>3)&0x1c)|((b>>6)&0x03)+1);
+			return rgbtocell[index];
+		}
+};
+
+#endif /* __Header_usetrue__ */
diff --git a/libsrc/include/dconvert/Imakefile b/libsrc/include/dconvert/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/include/dconvert/dateconv.h b/libsrc/include/dconvert/dateconv.h
new file mode 100644
index 0000000..99174ad
--- /dev/null
+++ b/libsrc/include/dconvert/dateconv.h
@@ -0,0 +1,242 @@
+/* dateconv.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_dateconv__
+#define __Header_dateconv__
+
+//#include "generic/datetype.h"		// assume already included
+
+const unsigned long	SecondsPerDay       =60*60*24;
+const unsigned long	SecondsPerHour      =60*60;
+const unsigned long	SecondsPerMinute    =60;
+
+static bool
+isleap(short year)
+{
+	return year%400 == 0 || (year%4 == 0 && year%100 != 0);
+	//return year%4 == 0 && year%20 != 0;
+}
+
+static unsigned long
+SecondsPerYear(short year)
+{
+	return 60*60*24*(isleap(year) ? 366 : 365);
+}
+
+static unsigned SecondsPerMonthNormal [13] = {
+	0,
+	31*SecondsPerDay,
+	28*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay
+};
+
+static unsigned SecondsPerMonthLeap [13] = {
+	0,
+	31*SecondsPerDay,
+	29*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay,
+	30*SecondsPerDay,
+	31*SecondsPerDay
+};
+
+static unsigned long
+SecondsPerMonth(short year,short month)
+{
+	return isleap(year)
+		? SecondsPerMonthLeap[month]
+		: SecondsPerMonthNormal[month];
+}
+
+template <class T,int epochyear>
+class DateTimeEpoch_Base {
+	T binary;
+public:
+	DateTimeEpoch_Base(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	DateTimeEpoch_Base(unsigned long secs)
+		{
+			binary=secs;
+		}
+
+	DateTimeEpoch_Base<T,epochyear>& operator=(const DateTimeEpoch_Base<T,epochyear>& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator DateTime() const
+		{
+			// epoch is 00:00:00 1 Jan on epochyear
+
+			unsigned long SecondsSinceEpoch=binary;
+			unsigned long Seconds = SecondsSinceEpoch;
+			short Year 	= epochyear;
+			while (Seconds >= SecondsPerYear(Year)) {
+				Seconds-=SecondsPerYear(Year);
+				++Year;
+			}
+
+			short Month = 0;
+			while (Seconds >= SecondsPerMonth(Year,Month)) {
+				Seconds-=SecondsPerMonth(Year,Month);
+				++Month;
+			}
+
+			short Day=(short)(Seconds/SecondsPerDay);
+			Seconds-=Day*SecondsPerDay;
+			++Day;	// days are numbered from 1 not 0 !
+			short Hours=(short)(Seconds/SecondsPerHour);
+			Seconds-=Hours*SecondsPerHour;
+			short Minutes=(short)(Seconds/SecondsPerMinute);
+			Seconds-=Minutes*SecondsPerMinute;
+
+			return DateTime(Year,Month,Day,Hours,Minutes,(short)Seconds);
+		}
+};
+
+typedef DateTimeEpoch_Base<Uint32_L,1970> Unix_DateTime_L;
+typedef DateTimeEpoch_Base<Uint32_B,1970> Unix_DateTime_B;
+
+static unsigned long
+DaysPerYear(short year)
+{
+	return isleap(year) ? 366 : 365;
+}
+
+static unsigned DaysPerMonthNormal [13] = {
+	0,
+	31,
+	28,
+	31,
+	30,
+	31,
+	30,
+	31,
+	31,
+	30,
+	31,
+	30,
+	31
+};
+
+static unsigned DaysPerMonthLeap [13] = {
+	0,
+	31,
+	29,
+	31,
+	30,
+	31,
+	30,
+	31,
+	31,
+	30,
+	31,
+	30,
+	31
+};
+
+static unsigned long
+DaysPerMonth(short year,short month)
+{
+	return isleap(year)
+		? DaysPerMonthLeap[month]
+		: DaysPerMonthNormal[month];
+}
+
+template <class T,int epochyear>
+class DateEpoch_Base {
+	T binary;
+public:
+	DateEpoch_Base(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	DateEpoch_Base(unsigned long secs)
+		{
+			binary=secs;
+		}
+
+	DateEpoch_Base<T,epochyear>& operator=(const DateEpoch_Base<T,epochyear>& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator Date() const
+		{
+			// epoch is 0 Jan on epochyear
+
+			unsigned long Days=binary-1;
+			short Year 	= epochyear;
+			while (Days >= DaysPerYear(Year)) {
+				Days-=DaysPerYear(Year);
+				++Year;
+			}
+
+			short Month = 0;
+			while (Days >= DaysPerMonth(Year,Month)) {
+				Days-=DaysPerMonth(Year,Month);
+				++Month;
+			}
+
+			return Date(Year,Month,(short)Days);
+		}
+};
+
+typedef DateEpoch_Base<Uint32_B,1980> Pace_Date;
+
+template <class T>
+class Time_Milliseconds_Base {
+	T binary;
+public:
+	Time_Milliseconds_Base(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	Time_Milliseconds_Base(unsigned long ms)
+		{
+			binary=ms;
+		}
+
+	Time_Milliseconds_Base<T>& operator=(const Time_Milliseconds_Base<T>& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator Time() const
+		{
+			// epoch is 0 Jan on epochyear
+
+			unsigned long ticks=binary;
+			short Milliseconds=(short)(ticks%1000);
+			short Seconds=(short)((ticks/1000)%60);
+			short Minutes=(short)((ticks/(1000*60))%60);
+			short Hours  =(short)((ticks/(1000*60*60))%60);
+			return Time(Hours,Minutes,Seconds);
+		}
+};
+
+typedef Time_Milliseconds_Base<Uint32_B> Time_Milliseconds_B;
+typedef Time_Milliseconds_Base<Uint32_L> Time_Milliseconds_L;
+
+#endif /* __Header_dateconv__ */
diff --git a/libsrc/include/dconvert/plane.h b/libsrc/include/dconvert/plane.h
new file mode 100644
index 0000000..96b3aed
--- /dev/null
+++ b/libsrc/include/dconvert/plane.h
@@ -0,0 +1,282 @@
+/* plane.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_plane__
+#define __Header_plane__
+
+#include "planev.h"
+
+enum ImagePlaneHeadFeet { HeadFirst,FeetFirst };
+
+enum ImagePlanePosition { 
+	Supine,Prone,LeftLateralDecubitus,RightLateralDecubitus };
+
+enum ImagePlaneAxis { AnteriorPosterior,HeadFeet,LeftRight };
+
+enum ImagePlanePlane {  Axial,Sagittal,Coronal,
+			AxialLP, AxialRP,
+			SagittalPF,SagittalIP,
+			CoronalLI };
+
+class AbstractImagePlane {
+	Point3D center;
+	Point3D tlhc;
+	Vector3D rowvec;
+	Vector3D colvec;
+
+	friend class ImagePlane;	// uses the following methods ...
+
+	Point3D	_get_center	(void)			{ return center; }
+	void	_set_center	(Point3D p)		{ center=p; }
+	void	_rotate_center	(Rotation3D r)		{ center=center*r; }
+	void	_shift_center	(Vector3D shift)	{ center=center+shift; }
+
+	Point3D	_get_tlhc	(void)			{ return tlhc; }
+	void	_set_tlhc	(Point3D p)		{ tlhc=p; }
+	void	_rotate_tlhc	(Rotation3D r)		{ tlhc=tlhc*r; }
+	void	_shift_tlhc	(Vector3D shift)	{ tlhc=tlhc+shift; }
+
+	void	_scale_tlhc	(double factor)	
+		{
+			Point3D origin(0,0,0);
+			Vector3D v = (origin-tlhc)*factor;
+			tlhc=origin-v;
+		}
+
+	Vector3D	_get_rowvec	(void)		{ return rowvec; }
+	void		_set_rowvec	(Vector3D v)	{ rowvec=v; }
+	void		_rotate_rowvec	(Rotation3D r)	{ rowvec=rowvec*r; }
+
+	Vector3D	_get_colvec	(void)		{ return colvec; }
+	void		_set_colvec	(Vector3D v)	{ colvec=v; }
+	void		_rotate_colvec	(Rotation3D r)	{ colvec=colvec*r; }
+
+public:
+	AbstractImagePlane(void) {}
+	AbstractImagePlane(ImagePlanePlane plane,double hfov,double vfov);
+
+#ifdef DEBUGPLANE
+	void put(ostream &);
+#endif
+};
+
+
+class DerivedImagePlane
+{
+	Rotation3D	rotation;	// this to base
+	Rotation3D	unrotation;	// base to this
+
+	char *getOrientation(Vector3D vector);
+
+	// derived classes pass access to VirtualImagePlane's methods ...
+
+	virtual Point3D		_get_center	(void)			= 0;
+	virtual void		_set_center	(Point3D p)		= 0;
+	virtual void		_rotate_center	(Rotation3D r)		= 0;
+	virtual void		_shift_center	(Vector3D shift)	= 0;
+
+	virtual Point3D		_get_tlhc	(void)			= 0;
+	virtual void		_set_tlhc	(Point3D p)		= 0;
+	virtual void		_rotate_tlhc	(Rotation3D r)		= 0;
+	virtual void		_shift_tlhc	(Vector3D shift)	= 0;
+	virtual void		_scale_tlhc	(double factor)		= 0;
+
+	virtual Vector3D	_get_rowvec	(void)			= 0;
+	virtual void		_set_rowvec	(Vector3D v)		= 0;
+	virtual void		_rotate_rowvec	(Rotation3D r)		= 0;
+
+	virtual Vector3D	_get_colvec	(void)			= 0;
+	virtual void		_set_colvec	(Vector3D v)		= 0;
+	virtual void		_rotate_colvec	(Rotation3D r)		= 0;
+
+public:
+	DerivedImagePlane(ImagePlaneHeadFeet hfff,ImagePlanePosition posn);
+
+	char *getRowOrientation(void)
+		{
+			return getOrientation(getRowVector());
+		}
+	char *getColOrientation(void)
+		{
+			return getOrientation(getColVector());
+		}
+
+	Point3D  getTLHC(void)		{ return _get_tlhc()*rotation; }
+	Point3D  getCenter(void)	{ return _get_center()*rotation; }
+	Vector3D getRowVector(void)	{ return _get_rowvec()*rotation; }
+	Vector3D getColVector(void)	{ return _get_colvec()*rotation; }
+
+	void setCorners(Point3D tlhc,Vector3D row,Vector3D col);
+	void angle(ImagePlaneAxis axis,double angle);
+	void shift(Vector3D shift);
+	void scale(double factor);
+
+#ifdef DEBUGPLANE
+	void put(ostream &);
+#endif
+};
+
+class PatientPlane : public DerivedImagePlane
+{
+public:
+	PatientPlane(ImagePlaneHeadFeet hfff,ImagePlanePosition posn) :
+		DerivedImagePlane(hfff,posn)
+		{
+#ifdef DEBUGPLANE
+			cerr << "PatientPlane::PatientPlane(void)" << endl;
+#endif
+		}
+#ifdef DEBUGPLANE
+	void put(ostream &);
+#endif
+};
+
+class MachinePlane : public DerivedImagePlane
+{
+public:
+	MachinePlane(void) :
+		DerivedImagePlane(HeadFirst,Supine)
+		{
+#ifdef DEBUGPLANE
+			cerr << "MachinePlane::MachinePlane(void)" << endl;
+#endif
+		}
+#ifdef DEBUGPLANE
+	void put(ostream &);
+#endif
+};
+
+class ImagePlane :	public virtual AbstractImagePlane,
+			public PatientPlane,
+			public MachinePlane
+{
+	// instances of virtual methods of DerivedImagePlane
+	// allows DerivedImagePlane methods access to AbstractImagePlane
+
+	Point3D		_get_center	(void)
+			{
+				return AbstractImagePlane::_get_center();
+			}
+
+	void		_set_center	(Point3D p)
+			{
+				AbstractImagePlane::_set_center(p);
+			}
+
+	void		_rotate_center	(Rotation3D r)
+			{
+				AbstractImagePlane::_rotate_center(r);
+			}
+
+	void		_shift_center	(Vector3D shift)
+			{
+				AbstractImagePlane::_shift_center(shift);
+			}
+
+
+	Point3D		_get_tlhc	(void)
+			{
+				return AbstractImagePlane::_get_tlhc();
+			}
+
+	void		_set_tlhc	(Point3D p)
+			{
+				AbstractImagePlane::_set_tlhc(p);
+			}
+
+	void		_rotate_tlhc	(Rotation3D r)
+			{
+				AbstractImagePlane::_rotate_tlhc(r);
+			}
+
+	void		_shift_tlhc	(Vector3D shift)
+			{
+				AbstractImagePlane::_shift_tlhc(shift);
+			}
+
+	void		_scale_tlhc	(double factor)
+			{
+				AbstractImagePlane::_scale_tlhc(factor);
+			}
+
+
+
+	Vector3D	_get_rowvec	(void)
+			{
+				return AbstractImagePlane::_get_rowvec();
+			}
+
+	void		_set_rowvec	(Vector3D v)
+			{
+				AbstractImagePlane::_set_rowvec(v);
+			}
+
+	void		_rotate_rowvec	(Rotation3D r)
+			{
+				AbstractImagePlane::_rotate_rowvec(r);
+			}
+
+
+	Vector3D	_get_colvec	(void)
+			{
+				return AbstractImagePlane::_get_colvec();
+			}
+
+	void		_set_colvec	(Vector3D v)
+			{
+				AbstractImagePlane::_set_colvec(v);
+			}
+
+	void		_rotate_colvec	(Rotation3D r)
+			{
+				AbstractImagePlane::_rotate_colvec(r);
+			}
+public:
+	ImagePlane(
+		ImagePlanePlane		plane,
+		double fov,
+		ImagePlaneHeadFeet	hfff,
+		ImagePlanePosition	posn
+	) :
+		AbstractImagePlane(plane,fov,fov),
+		PatientPlane(hfff,posn),
+		MachinePlane()
+		{
+#ifdef DEBUGPLANE
+			cerr << "ImagePlane::ImagePlane(plane,fov,hfff,posn)" << endl;
+#endif
+		}
+
+	ImagePlane(
+		ImagePlanePlane		plane,
+		double hfov,
+		double vfov,
+		ImagePlaneHeadFeet	hfff,
+		ImagePlanePosition	posn
+	) :
+		AbstractImagePlane(plane,hfov,vfov),
+		PatientPlane(hfff,posn),
+		MachinePlane()
+		{
+#ifdef DEBUGPLANE
+			cerr << "ImagePlane::ImagePlane(plane,hfov,vfov,hfff,posn)" << endl;
+#endif
+		}
+
+	ImagePlane(
+		ImagePlaneHeadFeet	hfff,
+		ImagePlanePosition	posn
+	) :
+		AbstractImagePlane(),
+		PatientPlane(hfff,posn),
+		MachinePlane()
+		{
+#ifdef DEBUGPLANE
+			cerr << "ImagePlane::ImagePlane(hfff,posn)" << endl;
+#endif
+		}
+
+#ifdef DEBUGPLANE
+	void put(ostream &);
+#endif
+};
+
+#endif /* __Header_plane__ */
diff --git a/libsrc/include/dconvert/planea.h b/libsrc/include/dconvert/planea.h
new file mode 100644
index 0000000..124cf13
--- /dev/null
+++ b/libsrc/include/dconvert/planea.h
@@ -0,0 +1,18 @@
+/* planea.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_planea__
+#define __Header_planea__
+
+#include "plane.h"
+
+class ImagePlaneLister {
+ImagePlane *plane;
+public:
+	ImagePlaneLister(ImagePlane& p)
+		{
+			plane=&p;
+		}
+
+	void addPlaneToList(AttributeList& list);
+};
+
+#endif /* __Header_planea__ */
diff --git a/libsrc/include/dconvert/planev.h b/libsrc/include/dconvert/planev.h
new file mode 100644
index 0000000..b30d8cb
--- /dev/null
+++ b/libsrc/include/dconvert/planev.h
@@ -0,0 +1,291 @@
+/* planev.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+//#define DEBUGPLANE
+
+#ifndef __Header_planev__
+#define __Header_planev__
+
+#ifdef DEBUGPLANE
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+#endif
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define	cosd(theta)	cos((theta)/180*M_PI)
+#define	sind(theta)	sin((theta)/180*M_PI)
+
+enum Index3D { X=0,Y,Z };
+
+class Vector3DBase {
+protected:
+	double values[3];
+public:
+	Vector3DBase(void)
+		{
+			values[X]=0;
+			values[Y]=0;
+			values[Z]=0;
+		}
+
+	Vector3DBase(double x,double y,double z)
+		{
+			values[X]=x;
+			values[Y]=y;
+			values[Z]=z;
+		}
+
+	double& operator[](unsigned i)
+		{
+			return values[i];
+		}
+
+	Vector3DBase& operator=(int v)
+		{
+			int i;
+			for (i=0;i<3;++i) values[i]=v;
+			return *this;
+		}
+
+	double operator*(Vector3DBase v)
+		{
+			int i;
+			double product=0;
+			for (i=0;i<3;++i) product+=values[i]*v[i];
+			return product;
+		}
+
+	Vector3DBase operator/(double d)
+		{
+			Vector3DBase v(values[X]/d,values[Y]/d,values[Z]/d);
+			return v;
+		}
+
+	Vector3DBase operator-(void)
+		{
+			Vector3DBase v(-values[X],-values[Y],-values[Z]);
+			return v;
+		}
+
+	double magnitude()
+		{
+			return sqrt(
+				values[X]*values[X]+
+				values[Y]*values[Y]+
+				values[Z]*values[Z]
+			);
+		}
+
+	double getX(void)	{ return values[X]; }
+	double getY(void)	{ return values[Y]; }
+	double getZ(void)	{ return values[Z]; }
+
+#ifdef DEBUGPLANE
+	void put(ostream& ost)
+		{
+			ost << dec << setiosflags(ios::fixed)
+			    << setiosflags(ios::showpoint) << setprecision(2)
+			    << values[0] << ","
+			    << values[1] << ","
+			    << values[2] << endl;
+		}
+#endif
+};
+
+class Matrix3D {
+protected:
+	Vector3DBase values[3];
+public:
+	Matrix3D(void)
+		{
+		}
+
+	Matrix3D(double xx,double xy,double xz,
+		 double yx,double yy,double yz,
+		 double zx,double zy,double zz)
+		{
+			values[X][X]=xx;
+			values[X][Y]=xy;
+			values[X][Z]=xz;
+			values[Y][X]=yx;
+			values[Y][Y]=yy;
+			values[Y][Z]=yz;
+			values[Z][X]=zx;
+			values[Z][Y]=zy;
+			values[Z][Z]=zz;
+		}
+
+	Vector3DBase& operator[](unsigned i) { return values[i]; }
+
+	Matrix3D& operator=(int v)
+		{
+			int i;
+			for (i=0;i<3;++i) values[i]=0;
+			for (i=0;i<3;++i) values[i][i]=v;
+			return *this;
+		}
+
+	Vector3DBase operator*(Vector3DBase v)
+		{
+			int i;
+			Vector3DBase product;
+			for (i=0;i<3;++i) product[i]=values[i]*v;
+			return product;
+		}
+
+	Matrix3D operator*(Matrix3D m)
+		{
+			int i,j,k;
+			Matrix3D product;
+			for (i=0;i<3;++i)
+				for (j=0;j<3;++j) {
+					product[i][j]=0;
+					for (k=0;k<3;++k)
+						product[i][j]+=
+							(*this)[k][i]*m[j][k];
+				}
+			return product;
+		}
+
+	Matrix3D& operator*=(Matrix3D m)
+		{
+			Matrix3D work;
+			work=*this*m;
+			*this=work;
+			return *this;
+		}
+
+#ifdef DEBUGPLANE
+	void put(ostream& ost)
+		{
+			values[0].put(ost);
+			values[1].put(ost);
+			values[2].put(ost);
+			ost << endl;
+		}
+#endif
+};
+
+class Rotation3D : public Matrix3D {
+	void aboutX(double theta)
+		{
+			values[X][X]=1;
+			values[Y][Y]=cosd(theta);
+			values[Y][Z]=-sind(theta);
+			values[Z][Y]=sind(theta);
+			values[Z][Z]=cosd(theta);
+		}
+	void aboutY(double theta)
+		{
+			values[X][X]=cosd(theta);
+			values[X][Z]=sind(theta);
+			values[Y][Y]=1;
+			values[Z][X]=-sind(theta);
+			values[Z][Z]=cosd(theta);
+		}
+	void aboutZ(double theta)
+		{
+			values[X][X]=cosd(theta);
+			values[X][Y]=-sind(theta);
+			values[Y][X]=sind(theta);
+			values[Y][Y]=cosd(theta);
+			values[Z][Z]=1;
+		}
+public:
+	Rotation3D(void) : Matrix3D() { Matrix3D::operator=(1); }
+
+	Rotation3D(Matrix3D m) : Matrix3D(m) {}
+
+	Rotation3D(int plane,double theta)
+		{
+			Matrix3D::operator=(1);
+			if (plane == X) {
+				aboutX(theta);
+			}
+			else if (plane == Y) {
+				aboutY(theta);
+			}
+			else if (plane == Z) {
+				aboutZ(theta);
+			}
+			//cerr << "Rotation3D() plane=" << plane
+			//     << " theta=" << theta << "\n";
+			//put(cerr);
+		}
+};
+
+class Vector3D : public Vector3DBase {
+public:
+	Vector3D(void) : Vector3DBase() {}
+	Vector3D(double x,double y,double z) : Vector3DBase(x,y,z) {}
+	Vector3D(Vector3DBase v) : Vector3DBase(v) {}
+
+	Vector3D operator*(double d)
+		{
+			Vector3DBase v(values[X]*d,values[Y]*d,values[Z]*d);
+			return v;
+		}
+
+	Vector3D operator*(Rotation3D r)
+		{
+			//cerr << "Vector3D operator*(Rotation3D r)\n";
+			//put(cerr);
+			Vector3D p = r*(*this);
+			//p.put(cerr);
+			return p;
+		}
+
+	Vector3D& operator*=(Rotation3D r)
+		{
+			*this=r*(*this);
+			return *this;
+		}
+};
+
+class Point3D : public Vector3D {
+public:
+	Point3D(void) : Vector3D() {}
+	Point3D(double x,double y,double z) : Vector3D(x,y,z) {}
+	Point3D(Vector3D v) : Vector3D(v) {}
+
+	Vector3D operator-(Point3D p)
+		{
+			Vector3D v(
+				values[X]-p.getX(),
+				values[Y]-p.getY(),
+				values[Z]-p.getZ());
+			return v;
+		}
+
+	Point3D operator-(Vector3D v)
+		{
+			Point3D p(
+				values[X]-v.getX(),
+				values[Y]-v.getY(),
+				values[Z]-v.getZ());
+			return p;
+		}
+
+	Point3D operator+(Vector3D v)
+		{
+			Point3D p(
+				values[X]+v.getX(),
+				values[Y]+v.getY(),
+				values[Z]+v.getZ());
+			return p;
+		}
+};
+
+#endif /* __Header_planev__ */
diff --git a/libsrc/include/dconvert/ptyhdr.h b/libsrc/include/dconvert/ptyhdr.h
new file mode 100644
index 0000000..9d0bfcf
--- /dev/null
+++ b/libsrc/include/dconvert/ptyhdr.h
@@ -0,0 +1,35 @@
+/* ptyhdr.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ptyhdr__
+#define __Header_ptyhdr__
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "convtype.h"
+#include "fltype.h"
+#include "strtype.h"
+#include "datetype.h"
+#include "dateconv.h"
+
+static inline bool
+ReadProprietaryHeader(istream *istr,long offset,size_t length,char *buffer)
+{
+	istr->seekg(offset,ios::beg);
+	if (istr->fail()) {
+		return false;
+	}
+	else {
+		istr->read(buffer,length);
+		return istr->good() && istr->gcount() == length;
+	}
+}
+
+#endif /* __Header_ptyhdr__ */
diff --git a/libsrc/include/dctool/Imakefile b/libsrc/include/dctool/Imakefile
new file mode 100755
index 0000000..3f5ff98
--- /dev/null
+++ b/libsrc/include/dctool/Imakefile
@@ -0,0 +1,12 @@
+all::	depend
+
+ProjectToolLibraryHeaderTemplate(transynu,transyn,transyn,role=extern outname=transynu)
+ProjectToolLibraryHeaderTemplate(sopclu,sopcl,sopcl,role=extern outname=sopclu)
+ProjectToolLibraryHeaderTemplate(elmconst,elmdict,elmdict,role=constant outname=elmconst)
+
+ProjectToolLibraryHeaderTemplate(strvalc,strval,strval,role=declare outname=strvalc)
+ProjectToolLibraryHeaderTemplate(binvalc,binval,binval,role=declare outname=binvalc)
+ProjectToolLibraryHeaderTemplate(tagvalc,tagval,tagval,role=declare outname=tagvalc)
+ProjectToolLibraryHeaderTemplate(condnc,condn,condn,role=declare outname=condnc)
+ProjectToolLibraryHeaderTemplate(modulec,module,module,role=declare outname=modulec)
+ProjectToolLibraryHeaderTemplate(iodcompc,iodcomp,iodcomp,role=declare outname=iodcompc)
diff --git a/libsrc/include/dctool/attr.h b/libsrc/include/dctool/attr.h
new file mode 100644
index 0000000..920aff6
--- /dev/null
+++ b/libsrc/include/dctool/attr.h
@@ -0,0 +1,157 @@
+/* attr.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// public interface for Attribute class
+
+#ifndef __Header_attr__
+#define __Header_attr__
+
+#include "ie.h"
+#include "attrtag.h"
+#include "charset.h"
+#include "vr.h"
+
+class AttributeList;
+class OtherUnspecifiedLargeAttributeBase;
+class ElementDictionary;
+
+class Attribute {
+private:
+	Tag	tag;
+	Uint32	byteoffset;
+	bool used;
+	InformationEntity ie;
+protected:
+	TextOutputStream&	writeBase(
+		TextOutputStream& stream,
+		ElementDictionary *dict=0,
+		bool verbose=false,
+		bool showUsedAndIE=false);
+	BinaryOutputStream&	writeBase(BinaryOutputStream&);
+	DicomOutputStream&	writeBase(DicomOutputStream&);
+public:
+	Attribute(Tag t);
+	virtual ~Attribute();
+
+	void setTag(Tag t) { tag=t; }
+	
+	void	setByteOffset(Uint32 offset);
+	Uint32	getByteOffset(void) const;
+
+	void	setUsed(void)  { used=true; }
+	void	setUnused(void)  { used=false; }
+	bool	isUsed(void) const { return used; }
+	
+	void	setInformationEntity(InformationEntity i) { ie = i; }
+	InformationEntity	getInformationEntity() { return ie; }
+
+	virtual BinaryOutputStream& writeData(BinaryOutputStream& stream);
+	virtual TextOutputStream& writeData(TextOutputStream& stream);
+
+	virtual	TextOutputStream&	write(
+		TextOutputStream& stream,
+		ElementDictionary *dict=0,
+		bool verbose=false,
+		bool showUsedAndIE=false) = 0;
+	virtual	BinaryOutputStream&	write(BinaryOutputStream&) = 0;
+	virtual	DicomOutputStream&	write(DicomOutputStream& stream) = 0;
+
+	virtual BinaryInputStream&
+			read(BinaryInputStream& stream,Uint32 lengthinbytes) = 0;
+
+	virtual void setOutputEncoding(
+			TransferSyntax *transfersyntax,
+			unsigned short bytesinword,
+			unsigned short bitsallocated,
+			unsigned short bitsstored,
+			unsigned short highbit,
+			Uint32 length=0xffffffff);
+
+	virtual	bool validateVR(TextOutputStream& stream,
+			SpecificCharacterSetInfo *specificCharacterSetInfo = NULL,
+			ElementDictionary *dict=0) const
+		{ (void)stream; (void)dict; return true; }
+
+	bool validateRetired(TextOutputStream& stream,
+			ElementDictionary *dict=0) const;
+
+	virtual const char *	getVR(void) const = 0;
+	virtual Uint16		getVM(void) const = 0;
+	virtual Uint32		getVL(void) const = 0;
+		Tag		getTag(void) const	{ return tag; }
+	virtual Uint16		getValueSize(void) const = 0;
+		
+	virtual bool	isNumeric(void) const		{ return false; }
+	virtual bool	isNumericBinary(void) const	{ return false; }
+	virtual bool	isNumericString(void) const	{ return false; }
+	virtual bool	isString(void) const		{ return false; }
+	virtual bool	isTag(void) const		{ return false; }
+	virtual bool	isOtherData(void) const		{ return false; }
+	virtual bool	isOtherByteNonPixel(void) const	{ return false; }
+	virtual bool	isOtherWordNonPixel(void) const	{ return false; }
+	virtual bool	isUnknown(void) const		{ return false; }
+	virtual bool	isSequence(void) const		{ return false; }
+
+	virtual OtherUnspecifiedLargeAttributeBase *castToOtherData(void);
+
+	virtual bool	isEmpty(void) const			{ return getVM() == 0; }
+	virtual bool	isOne(void) const			{ return getVM() == 1; }
+	virtual bool	isMultiple(void) const			{ return getVM() > 1; }
+	virtual bool	isEmptyOrHasAnyEmptyValue(void) const	{ return getVL() == 0 || isEmpty(); }	// overriden in string attributes
+													// should be OK for SQ even if VL is 0xFFFFFFFF
+	virtual bool	isEmptyOrHasAllEmptyValues(void) const	{ return getVL() == 0 || isEmpty(); }	// overriden in string attributes
+													// should be OK for SQ even if VL is 0xFFFFFFFF
+		
+	virtual bool	getValue(unsigned,Uint16&) const;
+	virtual bool	getValue(unsigned,Uint32&) const;
+	virtual bool	getValue(unsigned,Int16&) const;
+	virtual bool	getValue(unsigned,Int32&) const;
+	virtual bool	getValue(unsigned,Float32&) const;
+	virtual bool	getValue(unsigned,Float64&) const;
+	virtual bool	getValue(unsigned,Tag&) const;
+	virtual bool	getValue(unsigned,char * &) const;
+	virtual bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	virtual bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const;
+
+	virtual void	setValue(unsigned,Uint16);
+	virtual void	setValue(unsigned,Uint32);
+	virtual void	setValue(unsigned,Int16);
+	virtual void	setValue(unsigned,Int32);
+	virtual void	setValue(unsigned,Float32);
+	virtual void	setValue(unsigned,Float64);
+	virtual void	setValue(unsigned,Tag);
+	virtual void	setValue(unsigned,const char *);
+	virtual void	setValue(const unsigned char *values,Uint32 length);
+	virtual void	setValue(const Uint16 *values,Uint32 lengthinwords);
+
+	virtual void	addValue(Uint16);
+	virtual void	addValue(Uint32);
+	virtual void	addValue(Int16)	;
+	virtual void	addValue(Int32)	;
+	virtual void	addValue(Float32);
+	virtual void	addValue(Float64);
+	virtual void	addValue(Tag);
+	virtual void	addValue(const char *);
+
+	virtual void	addValues(unsigned,Uint16 *);
+	virtual void	addValues(unsigned,Uint32 *);
+	virtual void	addValues(unsigned,Int16 *);
+	virtual void	addValues(unsigned,Int32 *);
+	virtual void	addValues(unsigned,Float32 *);
+	virtual void	addValues(unsigned,Float64 *);
+	virtual void	addValues(unsigned,Tag *);
+	virtual void	addValues(unsigned,const char **);
+	virtual void	addValues(const char *);
+
+	virtual int	getLists(AttributeList ***);
+
+	virtual bool	verifyDefinedTerms(char *(*method)(char *value),bool verbose,TextOutputStream& log,ElementDictionary *dict,int which=-1) const;
+	virtual bool	verifyEnumValues(char *(*method)(char *value),bool verbose,TextOutputStream& log,ElementDictionary *dict,int which=-1) const;
+	virtual bool	verifyEnumValues(char *(*method)(Uint16 value),bool verbose,TextOutputStream& log,ElementDictionary *dict,int which=-1) const;
+	virtual bool	verifyBitMap(char *(*method)(Uint16 value),bool verbose,TextOutputStream& log,ElementDictionary *dict,int which=-1) const;
+	virtual bool	verifyEnumValues(char *(*method)(Uint16 group,Uint16 value),bool verbose,TextOutputStream& log,ElementDictionary *dict,int which=-1) const;
+	virtual bool	verifyNotZero(bool verbose,TextOutputStream& log,ElementDictionary *dict,int which=-1,bool warningNotError=true) const;
+
+	virtual bool	verifyVR(const char *module,const char *element,TextOutputStream& log,ElementDictionary *dict) const;
+	virtual bool	verifyVM(const char *module,const char *element,TextOutputStream& log,ElementDictionary *dict,Uint16 multiplicityMin=0,Uint16 multiplicityMax=0,const char *source=NULL) const;
+};
+
+#endif // __Header_attr__
diff --git a/libsrc/include/dctool/attrlist.h b/libsrc/include/dctool/attrlist.h
new file mode 100644
index 0000000..742d5d8
--- /dev/null
+++ b/libsrc/include/dctool/attrlist.h
@@ -0,0 +1,54 @@
+/* attrlist.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrlist__
+#define __Header_attrlist__
+
+#include "elmdict.h"
+#include "charset.h"
+
+class Attribute;
+
+class AttributeListImpl;
+class AttributeListIteratorImpl;
+
+class AttributeList {
+	friend class AttributeListImpl;
+	friend class AttributeListIterator;
+private:
+	AttributeListImpl *	list;
+protected:
+	ElementDictionary *	dictionary;		// only ever set by inherited classes
+	class SpecificCharacterSetInfo *specificCharacterSetInfo;
+public:
+	AttributeList(void);
+	virtual ~AttributeList();
+
+	Attribute * operator[](Tag tag);
+	void	operator-=(Tag tag);
+	void	operator+=(Attribute *p);
+	void	operator-=(Attribute *p);
+	void	operator-=(AttributeList& deletelist);
+	void	operator+=(AttributeList& replacelist);
+
+	ElementDictionary *getDictionary(void)	     { return dictionary; } // Should all be const
+	
+	SpecificCharacterSetInfo *getSpecificCharacterSetInfo() { return specificCharacterSetInfo; }
+	void setSpecificCharacterSetInfo(SpecificCharacterSetInfo *info) { specificCharacterSetInfo = info; }
+};
+
+class AttributeListIterator {
+	AttributeListIteratorImpl *iterator;
+public:
+	AttributeListIterator(AttributeList& list);
+	virtual ~AttributeListIterator();
+
+	void first(void);
+	int ismore(void);
+	void next(void);
+	Attribute * value(void);
+	int operator!()			{ return ismore(); }
+	void operator++()		{ next(); }		// prefix  ++i
+	void operator++(int)		{ next(); }		// postfix i++
+	Attribute * operator()()	{ return value(); }
+};
+
+#endif /* __Header_attrlist__ */
diff --git a/libsrc/include/dctool/attrlsln.h b/libsrc/include/dctool/attrlsln.h
new file mode 100644
index 0000000..cec07c4
--- /dev/null
+++ b/libsrc/include/dctool/attrlsln.h
@@ -0,0 +1,26 @@
+/* attrlsln.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrlsln__
+#define __Header_attrlsln__
+
+#include "attr.h"
+#include "attrlist.h"
+#include "transyn.h"
+#include "elmdict.h"
+
+Uint32
+lengthOfFixedPartOfAttribute(
+	const TransferSyntax *ts,const Attribute *a);
+
+Uint32
+lengthOfFixedPartOfAttribute(
+	const TransferSyntax *metats,const TransferSyntax *datats,const Attribute *a);
+
+Uint32
+lengthOfEntireAttribute(const TransferSyntax *ts,const Attribute *a);
+
+
+Uint32
+lengthOfEntireAttribute(
+	const TransferSyntax *metats,const TransferSyntax *datats,const Attribute *a);
+
+#endif /* __Header_attrlsln__ */
diff --git a/libsrc/include/dctool/attrmxls.README b/libsrc/include/dctool/attrmxls.README
new file mode 100755
index 0000000..d6ffb3b
--- /dev/null
+++ b/libsrc/include/dctool/attrmxls.README
@@ -0,0 +1,39 @@
+These recursively descend into lists in sequence attributes:
+
+	bool doClean(void);
+	bool doRemovePrivate(void);
+	bool addDicom(void);
+	bool setOutputEncoding(TransferSyntax *);
+
+These don't:
+
+	bool doReplace(void);
+	bool doDelete(void);
+	bool addDisclaimer(void);
+	bool addMetaHeader(void);
+	bool addLengths(void);
+
+Note that this particularly applies to setOutputEncoding(). If
+PixelData elements are contained within a sequence, then the
+transfer syntax with which they are read must be compatible
+with the transfer sequence with which they are being written,
+unless setOutputEncoding(0 has been applied. The need to do
+this arose when examing Papyrus 3 files that contain embedded
+sequences of composite image objects.
+
+"Compatibility" is defined in the sense of VR and byte order
+macthing for unencapsulated transfer syntaxes as defined by
+the "==" operator for TransferSyntax in transyn.cc.
+
+Note though that in the case of Papyrus, no attempt is made to
+fix internal pointers such as ImagePointer and PixelOffset
+which will undoubtedly be incorrect after a copy operation.
+
+The intent is to provide enough support to be able to dump
+Papyrus files, and extract pixel data from within sequences,
+not to successfully copy or reconstruct them.
+
+While on the subject of Papyrus, they seem to have add a '0'
+not a NULL to the transfer syntax and use "1.2.840.10008.1.20"
+so added this to the transfer syntax template to keep the peace.
+
diff --git a/libsrc/include/dctool/attrmxls.h b/libsrc/include/dctool/attrmxls.h
new file mode 100644
index 0000000..63467ee
--- /dev/null
+++ b/libsrc/include/dctool/attrmxls.h
@@ -0,0 +1,145 @@
+/* attrmxls.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrmxls__
+#define __Header_attrmxls__
+
+#include "attr.h"
+#include "attrlist.h"
+#include "elmdict.h"
+
+#include "errclass.h"
+
+class SequenceAttribute;
+
+class ReadableAttributeList : public AttributeList, public ErrorsInClass {
+private:
+	DicomInputStream *	stream;
+	TextOutputStream *	log;
+	bool			verbose;
+	Uint32 			byteoffset;
+
+	TextOutputStream& 	writebase(const Tag tag,const char *vr,
+					Uint32 vl);
+	
+	const char *	getValueRepresentation(Tag tag,char *vre,bool& readAsImplicitRegardless);
+	Uint32			getValueLength(const char *vr,bool readAsImplicitRegardless);
+	void			skipEncapsulatedData(void);
+	SequenceAttribute *	readNewSequenceAttribute(Tag tag,Uint32 length,bool ignoreoutofordertags,bool useUSVRForLUTDataIfNotExplicit,bool undefinedLengthUNTreatedAsSequence,const char *sequenceOwner,bool fixBitsDuringRead);
+	bool			replaceWithPixelRepresentation(
+					const Tag &t,const char *name,
+					bool havepixrep,bool usesigned);
+protected:
+	bool			setValueRepresentation(void);
+public:
+	ReadableAttributeList(void);
+	virtual ~ReadableAttributeList();
+
+	bool read(DicomInputStream& stream,
+		ElementDictionary* dict,
+		TextOutputStream *log=0,
+		bool verbose=false,
+		Uint32 length=0xffffffff,
+		bool metaheadercheck=true,
+		bool uselengthtoend=false,
+		bool ignoreoutofordertags=false,
+		bool useUSVRForLUTDataIfNotExplicit=false,
+		bool forceImplicit=false,
+		bool useStopAtTag=false,
+		Tag stopAtTag=Tag(0,0),
+		bool nestedWithinSequence=false,
+		const char *sequenceOwner=NULL,
+		bool fixBitsDuringRead=true
+		);
+
+	Uint32		   getByteOffset(void) const { return byteoffset; }
+};
+
+class ManagedAttributeList : public ReadableAttributeList {
+public:
+	enum flag_types {
+		none = 0,
+		metaheader = 1,			// write metaheader (not just dataset)
+		addlengths = 2,
+		removeprivate = 4,
+		removeinstanceuid = 8,
+		adddicom = 16,
+		adddisclaimer = 32,
+		addlengthtoend = 64,
+		addtiff = 128,
+		dataset = 256,		// write dataset (not just metaheader)
+		disambiguateseriesbydescription = 512 };
+private:
+	friend class TextOutputStream& operator<<
+		(TextOutputStream& stream,ManagedAttributeList& list);
+	friend class DicomOutputStream& operator<<
+		(DicomOutputStream& stream,ManagedAttributeList& list);
+
+	flag_types flags;
+	const char *uidstamp;
+	const char *instanceCreationDate;
+	const char *instanceCreationTime;
+	const char *timezoneOffsetFromUTC;
+	DicomOutputStream *preparedstream;
+
+	bool removeLengths(void);
+	bool removeMetaHeader(bool leaveuid);
+	bool removeInstanceUID(void);
+	bool removePrivate(void);
+	bool addMetaHeader(TransferSyntax *datats,const char *stamp);
+	bool addDicom(bool disambiguateseriesbydescription);
+	bool addDisclaimer(void);
+	bool addLengths(
+		TransferSyntax *metats,TransferSyntax *datats,
+		bool allgroups,bool toend);
+	bool addTiffTrailer(DicomOutputStream& stream,bool metaflag);
+	bool setOutputEncoding(TransferSyntax *datats);
+public:
+	ManagedAttributeList(void);
+	virtual ~ManagedAttributeList();
+
+	void removeCommandGroup(void);
+
+	bool clean(flag_types fset=none,flag_types freset=none);
+
+	bool prepare(DicomOutputStream& stream,
+		flag_types fset=none,flag_types freset=none,
+		const char *stamp=0,
+		const char *creationDate=0,
+		const char *creationTime=0,
+		const char *tzOffset=0);
+
+	bool finalize(DicomOutputStream& stream);
+
+	bool read(DicomInputStream& stream,
+		TextOutputStream *log=0,
+		bool verbose=false,
+		Uint32 length=0xffffffff,
+		bool metaheadercheck=true,
+		bool uselengthtoend=false,
+		bool ignoreoutofordertags=false,
+		bool useUSVRForLUTDataIfNotExplicit=false,
+		bool useStopAtTag=false,
+		Tag stopAtTag=Tag(0,0),
+		bool fixBitsDuringRead=true);
+
+	DicomOutputStream& write(DicomOutputStream& stream);
+	TextOutputStream&  write(TextOutputStream& stream,bool verbose=false,bool showUsedAndIE=false);
+
+	bool validateVR(TextOutputStream &log);
+	bool validateRetired(TextOutputStream &log);
+	bool validateUsed(TextOutputStream &log);
+	bool validatePrivate(TextOutputStream &log);
+
+	flag_types set(flag_types f)	{ return flags=flag_types(flags|f); }
+	flag_types reset(flag_types f)	{ return flags=flag_types(flags&~f); }
+
+	void 		setUIDStamp(const char *s)	{ uidstamp=s; }
+	const char *	getUIDStamp(void) const		{ return uidstamp; }
+	
+	const char *getInstanceCreationDate(void)	{ return instanceCreationDate; }
+	const char *getInstanceCreationTime(void)	{ return instanceCreationTime; }
+	const char *getTimezoneOffsetFromUTC(void)	{ return timezoneOffsetFromUTC; }
+};
+
+#endif /* __Header_attrmxls__ */
+
+
diff --git a/libsrc/include/dctool/attrnew.h b/libsrc/include/dctool/attrnew.h
new file mode 100644
index 0000000..2528128
--- /dev/null
+++ b/libsrc/include/dctool/attrnew.h
@@ -0,0 +1,7 @@
+/* attrnew.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrnew__
+#define __Header_attrnew__
+
+Attribute *newAttribute(const char* vr,Tag tag);
+
+#endif /* __Header_attrnew__ */
diff --git a/libsrc/include/dctool/attrothr.h b/libsrc/include/dctool/attrothr.h
new file mode 100644
index 0000000..0f077d2
--- /dev/null
+++ b/libsrc/include/dctool/attrothr.h
@@ -0,0 +1,237 @@
+/* attrothr.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrothr__
+#define __Header_attrothr__
+
+#include "srcsink.h"
+
+/* ********************* Large Other Attributes ********************* */
+
+class OtherUnspecifiedLargeAttributeBase : public Attribute {
+protected:
+	class SourceBase<Uint16> *srcpixeldata;
+	class SourceBase<unsigned char> *srcrawdata;
+
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 frames;
+	Uint16 samplesperpixel;
+
+	Uint16 srcbitsallocated;
+	Uint16 srcbitsstored;
+	Uint16 srchighbit;
+
+	TransferSyntax *dsttransfersyntax;
+	Uint16 dstbytesinword;
+	Uint16 dstbitsallocated;
+	Uint16 dstbitsstored;
+	Uint16 dsthighbit;
+	Uint32	dstlength;
+	Endian dstendian;
+	
+	bool suppressScalingOnBitDepthConversion;
+
+	class PointFilter<Uint16,Uint16> *pixelDataPointTransformFilter;
+
+	void Proposal14EncodingRules(
+		Uint16 bitsallocated,
+		TransferSyntax *transfersyntax,
+		Uint16& bytesinword,
+		Endian& encodedendian,
+		Uint32& length,
+		Endian forceEndian);
+
+public:
+	OtherUnspecifiedLargeAttributeBase(Tag t,
+		Uint16 r,Uint16 c,Uint16 f,Uint16 sperp);
+
+	virtual ~OtherUnspecifiedLargeAttributeBase();
+
+	virtual BinaryOutputStream& writeData(BinaryOutputStream& stream);
+	virtual DicomOutputStream& writeData(DicomOutputStream& stream);
+	virtual TextOutputStream& writeData(TextOutputStream& stream)
+		{
+			return Attribute::writeData(stream);
+		}
+
+	virtual ostream& writeRaw(ostream& stream);
+	virtual ostream& writeRaw(ostream& stream,Uint32 byteOffset,Uint32 byteCount);
+
+	virtual TextOutputStream& write(TextOutputStream& stream,
+			ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+
+	virtual BinaryOutputStream& write(BinaryOutputStream& stream);
+
+	virtual DicomOutputStream& write(DicomOutputStream& stream);
+
+	virtual BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	void setOutputEncoding(
+			TransferSyntax *transfersyntax,
+			Uint16 bytesinword,
+			Uint16 bitsallocated,
+			Uint16 bitsstored,
+			Uint16 highbit,
+			Uint32 length=0xffffffff);
+
+	void setSuppressScalingOnBitDepthConversion(bool doNotConvert) { suppressScalingOnBitDepthConversion = doNotConvert; }
+
+	const char *	getVR() const
+		{
+			return dstbytesinword == 1
+				? "OB"
+				: (dstbytesinword == 2
+					? "OW"
+					: "OX");
+		}
+
+	Uint32		getVL(void) const	{ return dstlength; }
+	Uint16		getVM(void) const	{ return 1; }
+	Uint16	getValueSize(void) const	{ return 1; }	// should never be used, since is meaningless ... difference between srcbytesinword and dstbytesinword is handled elsewhere
+
+	bool	isOtherData(void) const	{ return true; }
+
+	OtherUnspecifiedLargeAttributeBase *castToOtherData(void)	{ return this; }
+
+	// these methods are not in base class ...
+
+	virtual class SourceBase<Uint16> *get16BitSource()	{ return srcpixeldata; }
+
+	virtual bool activateSource(void) = 0;
+
+	virtual bool activateSourceWithoutUnpacking(void) = 0;
+
+	void insertPixelPointTransform(class PointFilter<Uint16,Uint16> *f)
+		{
+			Assert(f);
+			pixelDataPointTransformFilter=f;
+		}
+		
+	Uint32 getDestinationBytesPerFrame(void);
+};
+
+class OtherUnspecifiedLargeAttribute : public OtherUnspecifiedLargeAttributeBase {
+public:
+	OtherUnspecifiedLargeAttribute(Tag t,
+			SourceBase<Uint16> *src,
+			Uint16 r,Uint16 c,Uint16 f,Uint16 sperp);
+
+	OtherUnspecifiedLargeAttribute(Tag t,
+			SourceBase<Uint16> *src,
+			Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+			TransferSyntax *transfersyntax,
+			Uint16 bytesinword,
+			Uint16 bitsallocated,
+			Uint16 bitsstored,
+			Uint16 highbit,
+			Uint32 length=0xffffffff);
+
+	virtual ~OtherUnspecifiedLargeAttribute();
+
+	bool activateSource(void);
+	
+	bool activateSourceWithoutUnpacking(void);
+};
+
+class OtherUnspecifiedLargeAttributeCopied
+	: public OtherUnspecifiedLargeAttributeBase {
+private:
+	DicomInputStream *srcstream;
+	OurStreamPos srcpos;
+
+	class Source<unsigned char> *srcinput;
+	class ConvertByteToUint16   *srcfrombyte;
+	class UnpackUint16          *srcfrompack;
+	class UnshiftUint16         *srcfromshift;
+
+	Uint16 srcbytesinword;
+	Uint32 srclength;
+	Endian srcendian;
+public:
+	OtherUnspecifiedLargeAttributeCopied(Tag t,
+		Uint16 r,Uint16 c,Uint16 f,Uint16 sperp);
+
+	OtherUnspecifiedLargeAttributeCopied(Tag t,
+			DicomInputStream &stream,OurStreamPos pos,
+			Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+			Uint16 bytesinword,
+			Uint16 bitsallocated,
+			Uint16 bitsstored,
+			Uint16 highbit,
+			Uint32 length=0xffffffff,
+			Endian forceEndian=NoEndian);
+
+	virtual ~OtherUnspecifiedLargeAttributeCopied();
+
+	bool activateSource(void);
+	
+	bool activateSourceWithoutUnpacking(void);
+};
+
+class OtherUnspecifiedLargeAttributeEncapsulated
+	: public OtherUnspecifiedLargeAttributeBase {
+private:
+	DicomInputStream *srcstream;
+	OurStreamPos srcpos;
+public:
+	OtherUnspecifiedLargeAttributeEncapsulated(Tag t,
+			DicomInputStream &stream,OurStreamPos pos,
+			Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+			Uint16 bitsallocated,
+			Uint16 bitsstored,
+			Uint16 highbit);
+
+	virtual ~OtherUnspecifiedLargeAttributeEncapsulated();
+
+	bool activateSource(void);
+	
+	bool activateSourceWithoutUnpacking(void);
+};
+
+class SupplySourceFromAttribute : public SupplySource {
+private:
+	OtherUnspecifiedLargeAttributeBase *otherdata;
+	bool withoutUnpacking;
+public:
+	SupplySourceFromAttribute(Attribute *a)
+		: SupplySource()
+		{
+			Assert(a);
+			Assert(a->isOtherData());
+			otherdata=a->castToOtherData();
+			Assert(otherdata);
+			withoutUnpacking=false;
+		}
+
+	SupplySourceFromAttribute(Attribute *a,bool w)
+		: SupplySource()
+		{
+			Assert(a);
+			Assert(a->isOtherData());
+			otherdata=a->castToOtherData();
+			Assert(otherdata);
+			withoutUnpacking=w;
+		}
+
+	virtual ~SupplySourceFromAttribute(void) {}
+
+	class SourceBase<Uint16> *getSource(void)
+		{
+			Assert(otherdata);
+			bool success=false;
+			if (withoutUnpacking) {
+				success = otherdata->activateSourceWithoutUnpacking();
+			}
+			else {
+				success = otherdata->activateSource();
+			}
+			if (!success) {
+				Assert(0);
+				return 0;
+			}
+			class SourceBase<Uint16> *source = otherdata->get16BitSource();
+			Assert(source);
+			return source;
+		}
+};
+
+#endif /* __Header_attrothr__ */
diff --git a/libsrc/include/dctool/attrseq.h b/libsrc/include/dctool/attrseq.h
new file mode 100644
index 0000000..9e9b84b
--- /dev/null
+++ b/libsrc/include/dctool/attrseq.h
@@ -0,0 +1,72 @@
+/* attrseq.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrseq__
+#define __Header_attrseq__
+
+#include "listfifo.h"
+
+// Note use of FifoList to preserve order of items in sequence
+
+/* ********************* Sequence Attribute ********************* */
+
+class SequenceAttribute : public Attribute {
+	FifoList<AttributeList *> listoflists;
+	Uint32 length;
+public:
+	SequenceAttribute(Tag t) : Attribute(t)
+		{
+			length=0xffffffff;	// unspecified until revised
+		}
+
+	virtual ~SequenceAttribute();
+
+	TextOutputStream& write(TextOutputStream& stream,
+			ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+
+	BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			Assert(0);
+			return stream;
+		}
+
+	DicomOutputStream& write(DicomOutputStream& stream);
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length)
+		{
+			// read is handled elsewhere ... see attrmxrd.h
+			Assert(0);
+			(void)length;
+			return stream;
+		}
+
+	const char *	getVR() const		{ return "SQ"; }
+	Uint16		getVM(void) const	{ return 1; }
+
+	Uint32		getVL(void) const	{ return length; }
+	
+	Uint16	getValueSize(void) const	{ return 1; }	// should never be used, since is meaningless
+
+	bool	isSequence(void) const		{ return true; }
+
+	bool	isEmpty(void) const		{ return /*getVM() == 0;*/ listoflists.isEmpty(); }
+	bool	isOne(void) const		{ return /*getVM() == 1;*/ listoflists.isOne(); }
+	bool	isMultiple(void) const		{ return /*getVM() > 1;*/  listoflists.isMultiple(); }
+	// isEmptyOrHasAnyEmptyValue() from attr.h should work fine
+	// isEmptyOrHasAllEmptyValues() from attr.h should work fine
+	
+	int	getLists(AttributeList ***);
+
+	// Methods unique to this class ...
+
+	void operator +=(AttributeList *item)
+		{
+			listoflists+=item;
+		}
+
+	Uint32 getNumberOfItems (void) const;
+
+	void reviseVL(void)	{}
+
+	bool verifyVM(const char *module,const char *element,TextOutputStream& log,ElementDictionary *dict,Uint16 multiplicityMin=0,Uint16 multiplicityMax=0,const char *source=NULL) const;
+};
+
+#endif /* __Header_attrseq__ */
diff --git a/libsrc/include/dctool/attrtag.h b/libsrc/include/dctool/attrtag.h
new file mode 100644
index 0000000..a8137ab
--- /dev/null
+++ b/libsrc/include/dctool/attrtag.h
@@ -0,0 +1,137 @@
+/* attrtag.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtag__
+#define __Header_attrtag__
+
+#include "basetype.h"
+#include "txstream.h"
+#include "dcstream.h"
+
+class ElementDictionary;
+
+class Tag {
+private:
+	Uint16 group;
+	Uint16 element;
+protected:
+public:
+	Tag(void)			{ group=0; element=0; }
+	Tag(Uint16 g,Uint16 e)		{ group=g; element=e; }
+
+	// allows initialization from 0 ...
+	Tag(Uint32 u)	{ group=(Uint16)(u>>16); element=(Uint16)(u&0xffff); }
+
+	Tag(const Tag& t)		{ group=t.group; element=t.element; }
+	void operator=(const Tag& t)	{ group=t.group; element=t.element; }
+
+	bool operator==(const Tag& t2) const
+		{ return group == t2.group && element == t2.element; }
+	bool operator<(const Tag& t2) const
+		{ return group < t2.group
+		      || (group == t2.group && element < t2.element); }
+	bool operator<=(const Tag& t2) const
+		{ return group < t2.group
+		      || (group == t2.group && element <= t2.element); }
+	bool operator>(const Tag& t2) const
+		{ return group > t2.group
+		      || (group == t2.group && element > t2.element); }
+	bool operator>=(const Tag& t2) const
+		{ return group > t2.group
+		      || (group == t2.group && element >= t2.element); }
+
+	operator const Uint32(void) const
+		{ return (Uint32)group<<16|element; }
+
+	Uint16	getElement(void) const	{ return element; }
+	Uint16	getGroup(void) const	{ return group; }
+
+	// Repeating groups and elements
+
+	Tag	getRepeatingBase(void) const;
+
+	// Private groups ... see PS3.5-1993-7.1
+
+	bool	isPrivateGroup(void) const			// for the purpose of parsing
+		{
+			return (group % 2) == 1
+		     	     //&& group > 0x0007
+		     	     && ((group&0xff00) != 0x7f00 || group>= 0x7fd1/*0x7fe0*/)
+					// Siemens uses odd groups for variable data in PS2 compression, so not private
+					// But Philips PMS uses 0x7fe1, which is private :(
+					// and Elscint uses 0x7fdf, which is private :(
+					// and GE uses 0x7fd1, which is private :(
+					// so assume that everything above 0x7fd1 is private ... this may fail
+					// if we encounter too large a number of variable data groups
+					// (and PS 3.2 6.0 specifically allows 0x7f00 thru 0x7fff8 :( )
+					// can't see a way around this without looking at other elements :(
+			     ;
+		}
+
+	bool	isValidPrivateGroup(void) const		// for the purpose of validation
+		{
+			return (group % 2) == 1 && group > 0x0007 && group != 0xffff;	// these groups are forbidden (and have been since 1993)
+		}
+
+	bool	isStandardGroup(void) const
+		{
+			return (group % 2) == 0;
+		}
+
+	bool	isPrivateOwner(void) const
+		{
+			//return element >= 0x0010 && element <= 0x00ff;		// what the standard says in PS 3.5 7.8.1
+			return element >= 0x0001 && element <= 0x00ff;			// Sectra in mammo images illegally uses 0x0001
+		}
+
+	bool	isPrivateTag(void) const
+		{
+			return element >= 0x1000
+			    /*&& element <= 0xffff*/;
+		}
+
+	bool	isRepeatingGroup(void) const
+		{
+			return (group >= 0x5000 
+			     && group <= 0x501e)
+			    || (group >= 0x6000 
+			     && group <= 0x601e);
+		}
+
+	bool	isMetaheaderGroup(void)	const
+		{
+			return group == 0x0002;
+		}
+
+	bool	isLengthElement(void)	const
+		{
+			return element == 0x0000;
+		}
+
+	bool	isLengthElementOrLengthToEnd(void)	const
+		{
+			return element == 0x0000
+			    || (group == 0x0008 && element == 0x0001);
+		}
+
+	bool	isPixelDataElement(void)	const
+		{
+			return (group == 0x7fe0 && element == 0x0010)
+			    || (group == 0x7fe1 && element > 0x00ff && (element&0x00ff) == 0x0010);
+				// includes the usual (0x7fe0,0x0010)
+				// includes private pixel data (0x7fe1,0x1010) (but not owner) as used by Philips PMS
+				// doesn't includes variable pixel data (0x7fxx,0x0010) ? if this is good
+		}
+
+	TextOutputStream&	write(TextOutputStream& stream,
+					ElementDictionary *dict=0) const;
+	BinaryOutputStream&	write(BinaryOutputStream& stream) const;
+	DicomOutputStream&	write(DicomOutputStream& stream) const;
+	BinaryInputStream&	read(BinaryInputStream& stream);
+	DicomInputStream&	read(DicomInputStream& stream);
+};
+
+#define TagFromName(name)	\
+		Tag(name##_GROUP,name##_ELEMENT)
+
+#endif /* __Header_attrtag__ */
+
+
diff --git a/libsrc/include/dctool/attrtypb.h b/libsrc/include/dctool/attrtypb.h
new file mode 100644
index 0000000..289b326
--- /dev/null
+++ b/libsrc/include/dctool/attrtypb.h
@@ -0,0 +1,17 @@
+/* attrtypb.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtypb__
+#define __Header_attrtypb__
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "attr.h"
+#include "listval.h"
+#include "attrtypt.h"
+#include "attrtyps.h"
+#include "attrtypn.h"
+#include "attrtypf.h"
+#include "attrtypo.h"
+#include "datetype.h"
+
+#endif /* __Header_attrtypb__ */
diff --git a/libsrc/include/dctool/attrtype.h b/libsrc/include/dctool/attrtype.h
new file mode 100644
index 0000000..6a8b53c
--- /dev/null
+++ b/libsrc/include/dctool/attrtype.h
@@ -0,0 +1,498 @@
+/* attrtype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtype__
+#define __Header_attrtype__
+
+#include "attrtypb.h"
+
+#ifndef LARGESTOTHERDATATOKEEPINMEMORY
+#define LARGESTOTHERDATATOKEEPINMEMORY 524288
+#endif
+
+/* ************************** Tag Attributes ************************* */
+
+class AttributeTagAttribute : public TagAttribute {
+public:
+	AttributeTagAttribute(Tag t) : TagAttribute(t) {}
+	AttributeTagAttribute(Tag t,Tag v)
+		: TagAttribute(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "AT"; }
+};
+
+/* ************************ String Attributes ************************ */
+
+class ApplicationEntityAttribute : public NonNumericStringAttribute {
+public:
+	ApplicationEntityAttribute(Tag t) : NonNumericStringAttribute(t) {}
+	ApplicationEntityAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+	const char *	getVR() const	{ return "AE"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class AgeStringAttribute : public NonNumericStringAttribute {
+public:
+	AgeStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+	AgeStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+
+	const char *	getVR() const	{ return "AS"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class CodeStringAttribute : public NonNumericStringAttribute {
+public:
+	CodeStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	CodeStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+	CodeStringAttribute(Tag t,const char *v1,const char *v2)
+		: NonNumericStringAttribute(t)
+		{
+			addValue(v1); addValue(v2);
+		}
+	CodeStringAttribute(Tag t,const char *v1,const char *v2,const char *v3)
+		: NonNumericStringAttribute(t)
+		{
+			addValue(v1); addValue(v2); addValue(v3);
+		}
+
+	const char *	getVR() const	{ return "CS"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class CodeStringFileComponentAttribute : public CodeStringFileComponentAttributeBase {
+public:
+	CodeStringFileComponentAttribute(Tag t) : CodeStringFileComponentAttributeBase(t) {}
+
+	CodeStringFileComponentAttribute(Tag t,const char *v)
+		: CodeStringFileComponentAttributeBase(t,v) {}
+
+	const char *	getVR() const	{ return "CS"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class DateStringAttribute : public NonNumericStringAttribute {
+public:
+	DateStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	DateStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+
+	DateStringAttribute(Tag t,Date const & date);
+
+	DateStringAttribute(Tag t,DateTime const & datetime);
+
+	const char *	getVR() const	{ return "DA"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class DateTimeStringAttribute : public NonNumericStringAttribute {
+public:
+	DateTimeStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	DateTimeStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+
+	DateTimeStringAttribute(Tag t,Date const & date,Time const & time);
+
+	const char *	getVR() const	{ return "DT"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class DecimalStringAttribute : public NumericStringAttribute {
+public:
+	DecimalStringAttribute(Tag t) : NumericStringAttribute(t) {}
+
+	DecimalStringAttribute(Tag t,const char *v)
+		: NumericStringAttribute(t,v)	{}
+	DecimalStringAttribute(Tag t,Uint16 v)
+		: NumericStringAttribute(t,v)	{}
+	DecimalStringAttribute(Tag t,Uint32 v)
+		: NumericStringAttribute(t,v)	{}
+	DecimalStringAttribute(Tag t,Int16 v)
+		: NumericStringAttribute(t,v)	{}
+	DecimalStringAttribute(Tag t,Int32 v)
+		: NumericStringAttribute(t,v)	{}
+	DecimalStringAttribute(Tag t,Float32 v)
+		: NumericStringAttribute(t,v)	{}
+	DecimalStringAttribute(Tag t,Float64 v)
+		: NumericStringAttribute(t,v)	{}
+
+	DecimalStringAttribute(Tag t,Float64 v1,Float64 v2)
+		: NumericStringAttribute(t)
+		{ addValue(v1); addValue(v2); }
+	DecimalStringAttribute(Tag t,Float64 v1,Float64 v2,Float64 v3)
+		: NumericStringAttribute(t)
+		{ addValue(v1); addValue(v2);  addValue(v3); }
+	DecimalStringAttribute(Tag t,
+			Float64 v1,Float64 v2,Float64 v3,
+			Float64 v4,Float64 v5,Float64 v6)
+		: NumericStringAttribute(t)
+		{
+			addValue(v1); addValue(v2);  addValue(v3);
+			addValue(v4); addValue(v5);  addValue(v6);
+		}
+
+	const char *	getVR() const	{ return "DS"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class IntegerStringAttribute : public NumericStringAttribute {
+public:
+	IntegerStringAttribute(Tag t) : NumericStringAttribute(t) {}
+
+	IntegerStringAttribute(Tag t,const char *v)
+		: NumericStringAttribute(t,v)	{}
+	IntegerStringAttribute(Tag t,Uint16 v)
+		: NumericStringAttribute(t,v)	{}
+	IntegerStringAttribute(Tag t,Uint32 v)
+		: NumericStringAttribute(t,v)	{}
+	IntegerStringAttribute(Tag t,Int16 v)
+		: NumericStringAttribute(t,v)	{}
+	IntegerStringAttribute(Tag t,Int32 v)
+		: NumericStringAttribute(t,v)	{}
+
+	const char *	getVR() const	{ return "IS"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class LongStringAttribute : public NonNumericStringAttribute {
+public:
+	LongStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	LongStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+	LongStringAttribute(Tag t,Uint16 v)
+		: NonNumericStringAttribute(t,v) {}
+	LongStringAttribute(Tag t,Uint32 v)
+		: NonNumericStringAttribute(t,v) {}
+	LongStringAttribute(Tag t,Int16 v)
+		: NonNumericStringAttribute(t,v) {}
+	LongStringAttribute(Tag t,Int32 v)
+		: NonNumericStringAttribute(t,v) {}
+	LongStringAttribute(Tag t,Float32 v)
+		: NonNumericStringAttribute(t,v) {}
+	LongStringAttribute(Tag t,Float64 v)
+		: NonNumericStringAttribute(t,v) {}
+
+	const char *	getVR() const	{ return "LO"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class LongTextAttribute : public LongTextAttributeBase {
+public:
+	LongTextAttribute(Tag t) : LongTextAttributeBase(t) {}
+	LongTextAttribute(Tag t,const char *v)
+		: LongTextAttributeBase(t,v) {}
+	const char *	getVR() const	{ return "LT"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class PersonNameAttribute : public NonNumericStringAttribute {
+public:
+	PersonNameAttribute(Tag t) : NonNumericStringAttribute(t) {}
+	PersonNameAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+	const char *	getVR() const	{ return "PN"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class ShortStringAttribute : public NonNumericStringAttribute {
+public:
+	ShortStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	ShortStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+	ShortStringAttribute(Tag t,Uint16 v)
+		: NonNumericStringAttribute(t,v) {}
+	ShortStringAttribute(Tag t,Uint32 v)
+		: NonNumericStringAttribute(t,v) {}
+	ShortStringAttribute(Tag t,Int16 v)
+		: NonNumericStringAttribute(t,v) {}
+	ShortStringAttribute(Tag t,Int32 v)
+		: NonNumericStringAttribute(t,v) {}
+	ShortStringAttribute(Tag t,Float32 v)
+		: NonNumericStringAttribute(t,v) {}
+	ShortStringAttribute(Tag t,Float64 v)
+		: NonNumericStringAttribute(t,v) {}
+
+	const char *	getVR() const	{ return "SH"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class ShortTextAttribute : public TextAttribute {
+public:
+	ShortTextAttribute(Tag t) : TextAttribute(t) {}
+	ShortTextAttribute(Tag t,const char *v)
+		: TextAttribute(t,v) {}
+	const char *	getVR() const	{ return "ST"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class TimeStringAttribute : public NonNumericStringAttribute {
+public:
+	TimeStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	TimeStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+
+	TimeStringAttribute(Tag t,Time const & time);
+
+	TimeStringAttribute(Tag t,DateTime const & datetime);
+
+	const char *	getVR() const	{ return "TM"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class UIStringAttribute : public NonNumericStringAttribute {
+public:
+	UIStringAttribute(Tag t) : NonNumericStringAttribute(t) {}
+	UIStringAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+
+	const char *	getVR() const	{ return "UI"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			writePaddedValues(stream,0);
+			return stream;
+		}
+
+	TextOutputStream& writeData(TextOutputStream& stream)
+		{
+			writePaddedValues(stream,0);
+			return stream;
+		}
+
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false)
+		{
+			writePadded(stream,0,dict,verbose);
+			return stream;
+		}
+
+	BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			writePadded(stream,0);
+			return stream;
+		}
+
+	DicomOutputStream& write(DicomOutputStream& stream)
+		{
+			writePadded(stream,0);
+			return stream;
+		}
+};
+
+class UnlimitedCharactersAttribute : public NonNumericStringAttribute {
+public:
+	UnlimitedCharactersAttribute(Tag t) : NonNumericStringAttribute(t) {}
+
+	UnlimitedCharactersAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t,v) {}
+	UnlimitedCharactersAttribute(Tag t,Uint16 v)
+		: NonNumericStringAttribute(t,v) {}
+	UnlimitedCharactersAttribute(Tag t,Uint32 v)
+		: NonNumericStringAttribute(t,v) {}
+	UnlimitedCharactersAttribute(Tag t,Int16 v)
+		: NonNumericStringAttribute(t,v) {}
+	UnlimitedCharactersAttribute(Tag t,Int32 v)
+		: NonNumericStringAttribute(t,v) {}
+	UnlimitedCharactersAttribute(Tag t,Float32 v)
+		: NonNumericStringAttribute(t,v) {}
+	UnlimitedCharactersAttribute(Tag t,Float64 v)
+		: NonNumericStringAttribute(t,v) {}
+
+	const char *	getVR() const	{ return "UC"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class UniversalResourceAttribute : public LongTextAttributeBase {
+public:
+	UniversalResourceAttribute(Tag t) : LongTextAttributeBase(t) {}
+	UniversalResourceAttribute(Tag t,const char *v)
+		: LongTextAttributeBase(t,v) {}
+	const char *	getVR() const	{ return "UR"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+class UnlimitedTextAttribute : public LongTextAttributeBase {
+public:
+	UnlimitedTextAttribute(Tag t) : LongTextAttributeBase(t) {}
+	UnlimitedTextAttribute(Tag t,const char *v)
+		: LongTextAttributeBase(t,v) {}
+	const char *	getVR() const	{ return "UT"; }
+	bool validateVR(TextOutputStream& stream,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const;
+};
+
+/* ********************* Numeric Binary Attributes ********************* */
+
+class UnsignedShortAttribute : public NumericBinaryAttribute<Uint16,2> {
+public:
+	UnsignedShortAttribute(Tag t) : NumericBinaryAttribute<Uint16,2>(t) {}
+	UnsignedShortAttribute(Tag t,Uint16 v)
+		: NumericBinaryAttribute<Uint16,2>(t)
+		{ addValue(v); }
+	UnsignedShortAttribute(Tag t,Uint16 v1,Uint16 v2,Uint16 v3)
+		: NumericBinaryAttribute<Uint16,2>(t)
+		{ addValue(v1); addValue(v2);  addValue(v3); }
+	const char *	getVR() const	{ return "US"; }
+	~UnsignedShortAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+class UnsignedLongAttribute : public NumericBinaryAttribute<Uint32,4> {
+public:
+	UnsignedLongAttribute(Tag t) : NumericBinaryAttribute<Uint32,4>(t) {}
+	UnsignedLongAttribute(Tag t,Uint32 v)
+		: NumericBinaryAttribute<Uint32,4>(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "UL"; }
+	~UnsignedLongAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+class SignedShortAttribute : public NumericBinaryAttribute<Int16,2> {
+public:
+	SignedShortAttribute(Tag t) : NumericBinaryAttribute<Int16,2>(t) {}
+	SignedShortAttribute(Tag t,Int16 v)
+		: NumericBinaryAttribute<Int16,2>(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "SS"; }
+	~SignedShortAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+class SignedLongAttribute : public NumericBinaryAttribute<Int32,4> {
+public:
+	SignedLongAttribute(Tag t) : NumericBinaryAttribute<Int32,4>(t) {}
+	SignedLongAttribute(Tag t,Int32 v)
+		: NumericBinaryAttribute<Int32,4>(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "SL"; }
+	~SignedLongAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+class UnspecifiedShortAttribute : public NumericBinaryAttribute<Uint16,2> {
+public:
+	UnspecifiedShortAttribute(Tag t)
+		: NumericBinaryAttribute<Uint16,2>(t) {}
+	UnspecifiedShortAttribute(Tag t,Uint16 v)
+		: NumericBinaryAttribute<Uint16,2>(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "XS"; }
+	~UnspecifiedShortAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+class UnspecifiedLongAttribute : public NumericBinaryAttribute<Uint32,4> {
+public:
+	UnspecifiedLongAttribute(Tag t)
+		: NumericBinaryAttribute<Uint32,4>(t) {}
+	UnspecifiedLongAttribute(Tag t,Uint32 v)
+		: NumericBinaryAttribute<Uint32,4>(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "XL"; }
+	~UnspecifiedLongAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+/* ********************* Floating Point Binary Attributes ********************* */
+
+class FloatSingleAttribute : public FloatBinaryAttribute<4> {
+public:
+	FloatSingleAttribute(Tag t)
+		: FloatBinaryAttribute<4>(t) {}
+	FloatSingleAttribute(Tag t,Float32 v)
+		: FloatBinaryAttribute<4>(t)
+		{ addValue(v); }
+	const char *	getVR() const	{ return "FL"; }
+	~FloatSingleAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+class FloatDoubleAttribute : public FloatBinaryAttribute<8> {
+public:
+	FloatDoubleAttribute(Tag t)
+		: FloatBinaryAttribute<8>(t) {}
+	FloatDoubleAttribute(Tag t,Float64 v)
+		: FloatBinaryAttribute<8>(t)
+		{ addValue(v); }
+	FloatDoubleAttribute(Tag t,Float64 v1,Float64 v2)
+		: FloatBinaryAttribute<8>(t)
+		{ addValue(v1); addValue(v2); }
+	FloatDoubleAttribute(Tag t,Float64 v1,Float64 v2,Float64 v3)
+		: FloatBinaryAttribute<8>(t)
+		{ addValue(v1); addValue(v2);  addValue(v3); }
+	FloatDoubleAttribute(Tag t,
+			Float64 v1,Float64 v2,Float64 v3,
+			Float64 v4,Float64 v5,Float64 v6)
+		: FloatBinaryAttribute<8>(t)
+		{
+			addValue(v1); addValue(v2);  addValue(v3);
+			addValue(v4); addValue(v5);  addValue(v6);
+		}
+	const char *	getVR() const	{ return "FD"; }
+	~FloatDoubleAttribute() {} // only because buggy g++ 2.7.0 freaks
+};
+
+/* ********************* Other Non-PixelData Attributes ********************* */
+
+class OtherByteSmallNonPixelAttribute : public OtherByteSmallNonPixelAttributeBase {
+public:
+	OtherByteSmallNonPixelAttribute(Tag t) : OtherByteSmallNonPixelAttributeBase(t) {}
+	virtual ~OtherByteSmallNonPixelAttribute() {}
+};
+
+class OtherWordSmallNonPixelAttribute : public OtherWordSmallNonPixelAttributeBase {
+public:
+	OtherWordSmallNonPixelAttribute(Tag t) : OtherWordSmallNonPixelAttributeBase(t) {}
+	virtual ~OtherWordSmallNonPixelAttribute() {}
+};
+
+class OtherByteLargeNonPixelAttribute : public OtherByteLargeNonPixelAttributeBase {
+public:
+	OtherByteLargeNonPixelAttribute(Tag t,BinaryInputStream &stream,OurStreamPos pos)
+		: OtherByteLargeNonPixelAttributeBase(t,stream,pos) {}
+	virtual ~OtherByteLargeNonPixelAttribute() {}
+};
+
+class OtherWordLargeNonPixelAttribute : public OtherWordLargeNonPixelAttributeBase {
+public:
+	OtherWordLargeNonPixelAttribute(Tag t,BinaryInputStream &stream,OurStreamPos pos)
+		: OtherWordLargeNonPixelAttributeBase(t,stream,pos) {}
+	virtual ~OtherWordLargeNonPixelAttribute() {}
+};
+
+class OtherLongLargeAttribute : public OtherLongLargeAttributeBase {
+public:
+	OtherLongLargeAttribute(Tag t,BinaryInputStream &stream,OurStreamPos pos)
+		: OtherLongLargeAttributeBase(t,stream,pos) {}
+	virtual ~OtherLongLargeAttribute() {}
+};
+
+class OtherFloatLargeAttribute : public OtherFloatLargeAttributeBase {
+public:
+	OtherFloatLargeAttribute(Tag t,BinaryInputStream &stream,OurStreamPos pos)
+		: OtherFloatLargeAttributeBase(t,stream,pos) {}
+	virtual ~OtherFloatLargeAttribute() {}
+};
+
+class OtherDoubleLargeAttribute : public OtherDoubleLargeAttributeBase {
+public:
+	OtherDoubleLargeAttribute(Tag t,BinaryInputStream &stream,OurStreamPos pos)
+		: OtherDoubleLargeAttributeBase(t,stream,pos) {}
+	virtual ~OtherDoubleLargeAttribute() {}
+};
+
+/* ********************* Unknown VR Attributes ********************* */
+
+class UnknownSmallAttribute : public UnknownSmallAttributeBase {
+public:
+	UnknownSmallAttribute(Tag t) : UnknownSmallAttributeBase(t) {}
+	virtual ~UnknownSmallAttribute() {}
+};
+
+class UnknownLargeAttribute : public UnknownLargeAttributeBase {
+public:
+	UnknownLargeAttribute(Tag t,BinaryInputStream &stream,OurStreamPos pos)
+		: UnknownLargeAttributeBase(t,stream,pos) {}
+	virtual ~UnknownLargeAttribute() {}
+};
+
+#endif /* __Header_attrtype__ */
diff --git a/libsrc/include/dctool/attrtypf.h b/libsrc/include/dctool/attrtypf.h
new file mode 100644
index 0000000..46b0f0f
--- /dev/null
+++ b/libsrc/include/dctool/attrtypf.h
@@ -0,0 +1,474 @@
+/* attrtypf.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtypf__
+#define __Header_attrtypf__
+
+// all the following is copied from dconvert/fltype.h
+
+#include <float.h>
+
+#ifdef POWINTEGEREXPONENTTYPE
+#define	powi(m,e)	pow(m,(POWINTEGEREXPONENTTYPE)(e))
+#else
+#define	powi(m,e)	pow(m,(long)(e))
+#endif
+
+#ifdef __SC__
+#define infinity()    HUGE_VAL
+#define quiet_nan(x)  0
+#endif /* __SC__ */
+
+#ifdef __MWERKS__
+#define infinity()    __inf()
+#define quiet_nan(x)  0
+#endif /* __MWERKS__ */
+
+#ifdef USEDUMBINFINITYANDNAN
+#if USEDUMBINFINITYANDNAN
+#define infinity()    FLT_MAX
+#define quiet_nan(x)  0
+#endif
+#endif
+
+/* ********************* Floating Point Binary Attributes ********************* */
+
+template<int Size>
+class FloatBinaryAttribute : public Attribute {
+private:
+	ValueList<unsigned char *> values;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream)
+		{
+			// Stored internally as big endian
+
+			ValueListIterator<unsigned char *> i(values);
+			while (!i) {
+				const unsigned char *p=i();
+				int direction;
+				if (stream.isBigEndian()) {
+					direction=1;
+				}
+				else if (stream.isLittleEndian()) {
+					p=p+Size-1;
+					direction=-1;
+				}
+				else {
+					Assert(0);
+				}
+				short j=0;
+				while (j < Size) {
+					stream.write8(*p);
+//cerr << "FloatBinaryAttribute:writeValues - writing " << dec << j << "th byte " << hex << unsigned(*p) << dec << endl;
+					p+=direction;
+					++j;
+				}
+				++i;
+			}
+			return stream;
+
+		}
+
+	unsigned char* newSize4Value(Float32 value) {
+		Uint32 sign=0;
+		Int32 exponent;
+		Uint32 mantissa;
+
+		if (value < 0) {
+			sign=0x80000000;
+			value=-value;
+		}
+
+		if (value == 0) {
+			exponent=0;
+			mantissa=0;
+		}
+		else {
+			exponent=(int)ourlog2(value);
+			if (value < 1) --exponent;
+			if (exponent <= -126) {
+				mantissa=(Uint32)((value/pow(2,-126))*(1<<23));
+				exponent=0;
+			}
+			else {
+				if (exponent > 127) exponent=127;
+				mantissa=(Uint32)(((value/pow(2,exponent))-1)*(1<<23));
+				exponent=((exponent+127)<<23)&0x7f800000;
+			}
+		}
+
+		Uint32 binary=sign+exponent+mantissa;
+
+		unsigned char *barray = new unsigned char[4];
+		barray[0]=(unsigned char)(binary>>24);
+		barray[1]=(unsigned char)(binary>>16);
+		barray[2]=(unsigned char)(binary>>8);
+		barray[3]=(unsigned char)(binary);
+
+		return barray;
+	}
+
+	unsigned char* newSize8Value(Float64 value) {
+//cerr << "FloatBinaryAttribute:newSize8Value: want " << dec << value << endl;
+                Uint32 sign=0;
+		Int32 exponent;
+		Uint32 mantissahigh;
+		Uint32 mantissalow;
+
+		if (value < 0) {
+			sign=0x80000000;
+			value=-value;
+		}
+
+		if (value == 0) {
+			exponent=0;
+			mantissahigh=0;
+			mantissalow=0;
+		}
+		else {
+			exponent=(int)ourlog2(value);
+			if (value < 1) --exponent;
+			if (exponent <= -1022) {
+                                double mantissavalue = value/pow(2,-1022);
+				mantissahigh=(Uint32)(mantissavalue*powi(2.0,20));
+                                mantissalow =(Uint32)(mantissavalue*powi(2.0,52));
+				exponent=0;
+			}
+			else {
+				if (exponent > 1023) exponent=1023;
+                                double mantissavalue = value/pow(2,exponent) - 1.0;
+				mantissahigh=(Uint32)(mantissavalue*powi(2.0,20));
+                                mantissalow =(Uint32)(mantissavalue*powi(2.0,52));
+				exponent=((exponent+1023)<<20)&0x7ff00000;
+			}
+		}
+
+//cerr << "FloatBinaryAttribute:newSize8Value: sign 0x" << hex << sign << dec << endl;
+//cerr << "FloatBinaryAttribute:newSize8Value: exponent 0x" << hex << exponent << dec << endl;
+//cerr << "FloatBinaryAttribute:newSize8Value: mantissahigh 0x" << hex << mantissahigh << dec << endl;
+//cerr << "FloatBinaryAttribute:newSize8Value: mantissalow 0x" << hex << mantissalow << dec << endl;
+
+		Uint32 binaryhigh=sign+exponent+mantissahigh;
+
+		unsigned char *barray = new unsigned char[8];
+		barray[0]=(unsigned char)(binaryhigh>>24);
+		barray[1]=(unsigned char)(binaryhigh>>16);
+		barray[2]=(unsigned char)(binaryhigh>>8);
+		barray[3]=(unsigned char)(binaryhigh);
+		barray[4]=(unsigned char)(mantissalow>>24);
+		barray[5]=(unsigned char)(mantissalow>>16);
+		barray[6]=(unsigned char)(mantissalow>>8);
+		barray[7]=(unsigned char)(mantissalow);
+		return barray;
+	}
+
+	// these two routines are derived from dconvert/fltype.h
+
+	bool	getSize4Value(unsigned index,Float32& vp) const {
+		Assert(Size == 4);
+		unsigned char *barray;
+		bool success=values.getValue(index,barray);
+		if (success) {
+			Uint32 binary = (((((barray[0]<<8)|barray[1])<<8)|barray[2])<<8)|barray[3];
+			double value;
+			Int16 sign	=(Int16)((binary&0x80000000)>>31);
+			Int16 exponent	=(Int16)((binary&0x7f800000)>>23);
+			Uint32 mantissa	= binary&0x007fffff;
+
+			if (exponent == 0) {
+				if (mantissa == 0)
+					value=0;
+				else {
+					value=((double)mantissa/
+						(1<<23))*powi(2.0,-126);
+					value = (sign == 0) ? value : -value;
+				}
+			}
+			else if (exponent == 255) {
+				if (mantissa)
+					value=quiet_nan(0);
+				else
+					value=infinity();
+			}
+			else {
+				value=(1.0+(double)mantissa/
+					(1<<23))*powi(2.0,exponent-127);
+				value = (sign == 0) ? value : -value;
+			}
+			vp=value;
+		}
+		else {
+			vp=0;
+		}
+		return success;
+	}
+
+	bool	getSize8Value(unsigned index,Float64& vp) const {
+		Assert(Size == 8);
+		unsigned char *barray;
+		bool success=values.getValue(index,barray);
+		if (success) {
+
+			Uint32 high = (((((barray[0]<<8)|barray[1])<<8)|barray[2])<<8)|barray[3];
+			Uint32 low  = (((((barray[4]<<8)|barray[5])<<8)|barray[6])<<8)|barray[7];
+			double value;
+			Int16 sign	=(Int16)((high&0x80000000)>>31);
+			Int16 exponent	=(Int16)((high&0x7ff00000)>>20);
+			Uint32 mantissahigh = high&0x000fffff;
+			Uint32 mantissalow  = low &0xffffffff;
+			double mantissavalue = (double)mantissahigh * powi(2.0,32)
+					     + (double)mantissalow;
+
+			if (exponent == 0) {
+				if (mantissahigh == 0 && mantissalow == 0)
+					value=0;
+				else {
+					value=(mantissavalue/powi(2.0,52))
+						*powi(2.0,-1022);
+					value = (sign == 0) ? value : -value;
+				}
+			}
+			else if (exponent == 255) {			// ? if this should be 1023
+				if (mantissahigh || mantissalow)
+					value=quiet_nan(0);
+				else
+					value=infinity();
+			}
+			else {
+				value=(1.0+mantissavalue/powi(2.0,52))
+					*powi(2.0,exponent-1023);
+				value = (sign == 0) ? value : -value;
+			}
+			vp=value;
+		}
+		else {
+			vp=0;
+		}
+		return success;
+	}
+
+
+public:
+	FloatBinaryAttribute(Tag t) : Attribute(t)
+		{
+			Assert(Size == 4 || Size == 8);
+		}
+
+	virtual ~FloatBinaryAttribute() {}
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return writeValues(stream);
+		}
+
+	TextOutputStream& writeData(TextOutputStream& stream)
+		{
+			int n = getVM();
+			int i;
+			for (i=0; i<n; ++i) {
+				if (i > 0) stream <<",";
+				Float64 value;
+				if (getValue(i,value)) {
+					stream << value;
+				}
+				else {
+					stream << "XXXX";
+				}
+			}
+			return stream;
+		}
+
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false)
+		{
+			Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+			stream << "{";
+			writeData(stream);
+			stream << "} ";
+			return stream;
+		}
+
+	BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	DicomOutputStream& write(DicomOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length)
+		{
+			Assert(length%Size == 0);
+
+			while (length && stream.good()) {
+				// Stored internally as big endian
+
+				unsigned char *p=new unsigned char[Size];
+				values.addValue(p);	// takes responsibility for dealloc
+							// note we are adding the value before filling it !
+//cerr << "FloatBinaryAttribute:read - allocated p= " << hex << (unsigned long)p << dec << endl;
+				int direction;
+				if (stream.isBigEndian()) {
+					direction=1;
+				}
+				else if (stream.isLittleEndian()) {
+					p=p+Size-1;
+					direction=-1;
+				}
+				else {
+					Assert(0);
+				}
+				short j=0;
+				while (j < Size) {
+					*p=stream.read8();
+//cerr << "FloatBinaryAttribute:read - using p= " << hex << (unsigned long)p << dec << endl;
+//cerr << "FloatBinaryAttribute:read - read " << dec << j << "th byte " << hex << unsigned(*p) << dec << endl;
+					p+=direction;
+					++j;
+				}
+				length-=Size;
+			}
+			return stream;
+		}
+
+	bool	isNumeric(void) const		{ return true; }
+
+	Uint16	getVM(void) const	{ return values.getVM(); }
+	Uint32	getVL(void) const	{ return Size*getVM(); }
+	Uint16	getValueSize(void) const	{ return Size; }
+
+	bool	getValue(unsigned index,Uint16& vp) const
+		{
+			Float64 value;
+			bool success=getValue(index,value);
+			if (success) vp=(Int32)value;
+			return success;
+		}
+
+	bool	getValue(unsigned index,Uint32& vp) const
+		{
+			Float64 value;
+			bool success=getValue(index,value);
+			if (success) vp=(Int32)value;
+			return success;
+		}
+
+	bool	getValue(unsigned index,Int16& vp) const
+		{
+			Float64 value;
+			bool success=getValue(index,value);
+			if (success) vp=(Int32)value;
+			return success;
+		}
+
+	bool	getValue(unsigned index,Int32& vp) const
+		{
+			Float64 value;
+			bool success=getValue(index,value);
+			if (success) vp=(Int32)value;
+			return success;
+		}
+
+	bool	getValue(unsigned index,Float32& vp) const
+		{
+			if (Size == 4) {
+				return getSize4Value(index,vp);
+			}
+			else {
+				Float64 value;
+				bool success=getSize8Value(index,value);
+				vp=(Float32)value;
+				return success;
+			}
+		}
+
+	bool	getValue(unsigned index,Float64& vp) const
+		{
+			if (Size == 8) {
+				return getSize8Value(index,vp);
+			}
+			else {
+				Float32 value;
+				bool success=getSize4Value(index,value);
+				vp=(Float64)value;
+				return success;
+			}
+		}
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+
+	void	addValue(Uint16 value)
+		{
+			values.addValue(Size == 4 ? newSize4Value((Float32)value) : newSize8Value((Float64)value));
+		}
+
+	void	addValue(Uint32 value)
+		{
+			values.addValue(Size == 4 ? newSize4Value((Float32)value) : newSize8Value((Float64)value));
+		}
+
+	void	addValue(Int16 value)
+		{
+			values.addValue(Size == 4 ? newSize4Value((Float32)value) : newSize8Value((Float64)value));
+		}
+
+	void	addValue(Int32 value)
+		{
+			values.addValue(Size == 4 ? newSize4Value((Float32)value) : newSize8Value((Float64)value));
+		}
+
+	void	addValue(Float32 value)
+		{
+			values.addValue(Size == 4 ? newSize4Value(value) : newSize8Value((Float64)value));
+		}
+
+	void	addValue(Float64 value)
+		{
+			values.addValue(Size == 4 ? newSize4Value((Float32)value) : newSize8Value(value));
+		}
+
+	void	addValue(Tag value)				{ Attribute::addValue(value); }
+	
+	void	addValue(const char *str)			{ addValue(atof(str)); }
+
+	void	addValues(unsigned number,Uint16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Uint32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float32 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float64 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Tag *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,const char **vptr)	{ Attribute::addValues(number,vptr); }
+
+	void	addValues(const char *vptr)
+		{
+			const char *p;
+			unsigned number;
+			for (number=1,p=vptr; *p; ++p)
+				if (*p == '\\') ++number;
+			Float64 *tptr = new double[number];
+			unsigned i;
+			for (i=0,p=vptr; i<number; ++i) {
+				tptr[i]=(Float64)atof(p);
+				if ((p=strchr(p,'\\')) != 0) ++p;
+			}
+			addValues(number,tptr);
+			if (tptr) delete[] tptr;
+		}
+};
+
+#endif /* __Header_attrtypf__ */
+
+
diff --git a/libsrc/include/dctool/attrtypn.h b/libsrc/include/dctool/attrtypn.h
new file mode 100644
index 0000000..2aac287
--- /dev/null
+++ b/libsrc/include/dctool/attrtypn.h
@@ -0,0 +1,294 @@
+/* attrtypn.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtypn__
+#define __Header_attrtypn__
+
+/* need these two for TagFromName() in isSufficientSpaceForOneMoreValue() */
+#include "attrtag.h"
+#include "elmconst.h"
+
+/* ********************* Numeric Binary Attributes ********************* */
+
+template<class T,int Size>
+class NumericBinaryAttribute : public Attribute {
+private:
+	ValueList<T> values;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream)
+		{
+			ValueListIterator<T> i(values);
+			if (Size == 1) while (!i) { stream.write8((unsigned char)i()); ++i; }
+			if (Size == 2) while (!i) { stream.write16((Uint16)i()); ++i; }
+			if (Size == 4) while (!i) { stream.write32((Uint32)i()); ++i; }
+			return stream;
+		}
+
+	bool isSufficientSpaceForOneMoreValue(void)
+		{
+			// logic here is that a short VL VR should never have a VL greater than can be sent in explicit VR (2^16-1 == 65535),
+			// with the except of RT DVH (DS) that sometimes must be sent as implicit VR (Mathews, Bosch 2006 Phys. Med. Biol. 51 L11 doi:10.1088/0031-9155/51/5/L01)
+			// also allow it in Histogram Data (encountered big one in Adani MG For Proc
+			return Size*(getVM()+1) < 65536 || getTag() == TagFromName(DVHData) || getTag() == TagFromName(HistogramData);
+		}
+public:
+	NumericBinaryAttribute(Tag t) : Attribute(t) {}
+	virtual ~NumericBinaryAttribute()	{}
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return writeValues(stream);
+		}
+
+	TextOutputStream& writeData(TextOutputStream& stream)
+		{
+			const int width=2+Size*2;
+			int count=0;
+			ValueListIterator<T> i(values);
+			while (!i) {
+				if (Size == 1) {
+					writeZeroPaddedHexNumber(stream,(unsigned short)i() & 0xff,2);
+				}	
+				else if (Size == 2) {
+					writeZeroPaddedHexNumber(stream,(unsigned short)i(),4);
+				}
+				else {
+					writeZeroPaddedHexNumber(stream,(unsigned long)i(),8);
+				}
+				++i;
+				++count;
+				if (!i) {
+					stream << ",";
+					if      (Size == 1 && count%16 == 0) { count=0; stream << "\n\t"; }
+					else if (Size == 2 && count%8 == 0)  { count=0; stream << "\n\t"; }
+					else if (             count%6 == 0)  { count=0; stream << "\n\t"; }
+				}
+			}
+			return stream;
+		}
+
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false)
+		{
+			Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+			stream << "[";
+			writeData(stream);
+			stream << "] ";
+			return stream;
+		}
+
+	BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	DicomOutputStream& write(DicomOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length)
+		{
+			// Allow short values ... some SPI values
+			// are supposed to be UL but are US in some files ...
+			// Assert(length%Size == 0);
+			unsigned size = (length < Size) ? (unsigned)length : Size;
+			Assert(size==0 || size==1 || size==2 || size==4);
+			while (length && stream.good()) {
+				if (size == 1) {
+					Uint16 i=stream.read8();
+					addValue(i);
+				}
+				else if (size == 2) {
+					Uint16 i=stream.read16();
+					addValue(i);
+				}
+				else if (size == 4) {
+					Uint32 i=stream.read32();
+					addValue(i);
+				}
+				length-=size;
+			}
+			return stream;
+		}
+
+	bool	isNumeric(void) const		{ return true; }
+	bool	isNumericBinary(void) const	{ return true; }
+
+	Uint16	getVM(void) const	{ return values.getVM(); }
+	Uint32	getVL(void) const	{ return Size*getVM(); }
+	Uint16	getValueSize(void) const	{ return Size; }
+
+	bool	getValue(unsigned index,Uint16& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) vp=(Uint16)value;
+			return success;
+		}
+	bool	getValue(unsigned index,Uint32& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) vp=(Uint32)value;
+			return success;
+		}
+	bool	getValue(unsigned index,Int16& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) vp=(Int16)value;
+			return success;
+		}
+	bool	getValue(unsigned index,Int32& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) vp=(Int32)value;
+			return success;
+		}
+	bool	getValue(unsigned index,Float32& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) vp=(Float32)value;
+			return success;
+		}
+	bool	getValue(unsigned index,Float64& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) vp=(Float64)value;
+			return success;
+		}
+	bool	getValue(unsigned index,Tag& vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) {
+				Uint32 v32=(Uint32)value;
+				Tag   t((Uint16)((value>>16)&0xffff),
+					(Uint16)(value&0xffff));
+				vp=t;
+			}
+			return success;
+		}
+	bool	getValue(unsigned index,char * & vp) const
+		{
+			T value;
+			bool success=values.getValue(index,value);
+			if (success) {
+				ostrstream ost;
+				ost << dec << value << ends;
+				vp=ost.str();	// copy - needs deletion !!!
+			}
+			return success;
+		}
+
+	void	setValue(unsigned index,Uint16 value)
+		{
+			values.setValue(index,(T)value);
+		}
+	void	setValue(unsigned index,Uint32 value)
+		{
+			values.setValue(index,(T)value);
+		}
+	void	setValue(unsigned index,Int16 value)
+		{
+			values.setValue(index,(T)value);
+		}
+	void	setValue(unsigned index,Int32 value)
+		{
+			values.setValue(index,(T)value);
+		}
+	void	setValue(unsigned index,Float32 value)
+		{
+			values.setValue(index,(T)value);
+		}
+	void	setValue(unsigned index,Float64 value)
+		{
+			values.setValue(index,(T)value);
+		}
+	void	setValue(unsigned index,Tag value)
+		{
+			Uint32 v32=((Uint32)value.getGroup()<<16)
+				   |(Uint32)value.getElement();
+			values.setValue(index,(T)v32);
+		}
+	void	setValue(unsigned index,const char *value)
+		{
+			values.setValue(index,(T)atol(value));
+		}
+
+	void	addValue(Uint16 value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)value);
+		}
+	void	addValue(Uint32 value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)value);
+		}
+	void	addValue(Int16 value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)value);
+		}
+	void	addValue(Int32 value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)value);
+		}
+	void	addValue(Float32 value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)value);
+		}
+	void	addValue(Float64 value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)value);
+		}
+	void	addValue(Tag value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			Uint32 v32=((Uint32)value.getGroup()<<16)
+				   |(Uint32)value.getElement();
+			values.addValue((T)v32);
+		}
+	void	addValue(const char *value)
+		{
+			Assert(isSufficientSpaceForOneMoreValue());
+			values.addValue((T)atol(value));
+		}
+
+
+	void	addValues(unsigned number,Uint16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Uint32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float32 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float64 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Tag *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,const char **vptr)	{ Attribute::addValues(number,vptr); }
+
+	void	addValues(const char *vptr)
+		{
+			const char *p;
+			unsigned number;
+			for (number=1,p=vptr; *p; ++p)
+				if (*p == '\\') ++number;
+			T *tptr = new T[number];
+			unsigned i;
+			for (i=0,p=vptr; i<number; ++i) {
+				tptr[i]=(T)atol(p);
+				if ((p=strchr(p,'\\')) != 0) ++p;
+			}
+			values.addValues(number,tptr);
+			if (tptr) delete[] tptr;
+		}
+};
+
+#endif /* __Header_attrtypn__ */
diff --git a/libsrc/include/dctool/attrtypo.h b/libsrc/include/dctool/attrtypo.h
new file mode 100644
index 0000000..dbb4fa7
--- /dev/null
+++ b/libsrc/include/dctool/attrtypo.h
@@ -0,0 +1,509 @@
+/* attrtypo.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtypo__
+#define __Header_attrtypo__
+
+/* ************************** Other Non-PixelData Attributes ************************* */
+
+class OtherNonPixelAttribute : public Attribute {
+protected:
+	Uint32 lengthinbytes; 
+	virtual BinaryOutputStream& writeValues(BinaryOutputStream& stream) = 0;
+public:
+	OtherNonPixelAttribute(Tag t);
+	virtual ~OtherNonPixelAttribute();
+
+	virtual BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return writeValues(stream);
+		}
+	virtual	TextOutputStream& writeData(TextOutputStream& stream) = 0;
+
+	virtual	TextOutputStream& write(
+		TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false) = 0;
+
+	BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	DicomOutputStream& write(DicomOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	Uint16	getVM(void) const	{ return 1; }
+	Uint32	getVL(void) const	{ return lengthinbytes; }
+};
+
+class OtherByteSmallNonPixelAttributeBase : public OtherNonPixelAttribute {
+private:
+	unsigned char *data;
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherByteSmallNonPixelAttributeBase(Tag t);
+	virtual ~OtherByteSmallNonPixelAttributeBase();
+
+	const char *	getVR() const	{ return "OB"; }
+	Uint16	getValueSize(void) const	{ return 1; }
+
+	bool	isOtherByteNonPixel(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+								{ return Attribute::getValue(rvalue,rlengthinwords); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length);
+	void	setValue(const Uint16 *values,Uint32 lengthinwords)
+								{ Attribute::setValue(values,lengthinwords); }
+};
+
+class OtherWordSmallNonPixelAttributeBase : public OtherNonPixelAttribute {
+private:
+	Uint16 *data;
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherWordSmallNonPixelAttributeBase(Tag t);
+	virtual ~OtherWordSmallNonPixelAttributeBase();
+
+	const char *	getVR() const	{ return "OW"; }
+	Uint16	getValueSize(void) const	{ return 2; }
+
+	bool	isOtherWordNonPixel(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const
+								{ return Attribute::getValue(rvalue,rlength); }
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const;
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length)
+								{ Attribute::setValue(values,length); }
+	void	setValue(const Uint16 *values,Uint32 lengthinwords);
+};
+
+class OtherByteLargeNonPixelAttributeBase : public OtherNonPixelAttribute {
+private:
+	BinaryInputStream *srcstream;
+	OurStreamPos srcpos;
+	OurStreamPos srclength;
+	bool hasSrclength;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherByteLargeNonPixelAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos);
+	OtherByteLargeNonPixelAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos,OurStreamPos length);
+	virtual ~OtherByteLargeNonPixelAttributeBase();
+
+	const char *	getVR() const	{ return "OB"; }
+	Uint16	getValueSize(void) const	{ return 1; }
+
+	bool	isOtherByteNonPixel(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+								{ return Attribute::getValue(rvalue,rlengthinwords); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length);
+	void	setValue(const Uint16 *values,Uint32 lengthinwords)
+								{ Attribute::setValue(values,lengthinwords); }
+};
+
+class OtherWordLargeNonPixelAttributeBase : public OtherNonPixelAttribute {
+private:
+	BinaryInputStream *srcstream;
+	OurStreamPos srcpos;
+	Endian srcendian;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherWordLargeNonPixelAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos);
+	virtual ~OtherWordLargeNonPixelAttributeBase();
+
+	const char *	getVR() const	{ return "OW"; }
+	Uint16	getValueSize(void) const	{ return 2; }
+
+	bool	isOtherWordNonPixel(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const
+								{ return Attribute::getValue(rvalue,rlength); }
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const;
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length)
+								{ Attribute::setValue(values,length); }
+	void	setValue(const Uint16 *values,Uint32 lengthinwords);
+};
+
+/* ********************* OL VR Attributes ********************* */
+
+class OtherLongLargeAttributeBase : public OtherNonPixelAttribute {
+private:
+	BinaryInputStream *srcstream;
+	OurStreamPos srcpos;
+	Endian srcendian;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherLongLargeAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos);
+	virtual ~OtherLongLargeAttributeBase();
+
+	const char *	getVR() const	{ return "OL"; }
+	Uint16	getValueSize(void) const	{ return 4; }
+
+	bool	isOtherLongNonPixel(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const
+								{ return Attribute::getValue(rvalue,rlength); }
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const;
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length)
+								{ Attribute::setValue(values,length); }
+	void	setValue(const Uint16 *values,Uint32 lengthinwords);
+};
+
+/* ********************* OF VR Attributes ********************* */
+
+class OtherFloatLargeAttributeBase : public OtherNonPixelAttribute {
+private:
+	BinaryInputStream *srcstream;
+	OurStreamPos srcpos;
+	Endian srcendian;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherFloatLargeAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos);
+	virtual ~OtherFloatLargeAttributeBase();
+
+	const char *	getVR() const	{ return "OF"; }
+	Uint16	getValueSize(void) const	{ return 4; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+								{ return Attribute::getValue(rvalue,rlengthinwords); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length);
+	void	setValue(const Uint16 *values,Uint32 lengthinwords)
+								{ Attribute::setValue(values,lengthinwords); }
+};
+
+
+/* ********************* OD VR Attributes ********************* */
+
+class OtherDoubleLargeAttributeBase : public OtherNonPixelAttribute {
+private:
+	BinaryInputStream *srcstream;
+	OurStreamPos srcpos;
+	Endian srcendian;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	OtherDoubleLargeAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos);
+	virtual ~OtherDoubleLargeAttributeBase();
+
+	const char *	getVR() const	{ return "OD"; }
+	Uint16	getValueSize(void) const	{ return 8; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+								{ return Attribute::getValue(rvalue,rlengthinwords); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length);
+	void	setValue(const Uint16 *values,Uint32 lengthinwords)
+								{ Attribute::setValue(values,lengthinwords); }
+};
+
+/* ********************* Unknown VR Attributes ********************* */
+
+class UnknownSmallAttributeBase : public OtherNonPixelAttribute {
+private:
+	unsigned char *data;
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	UnknownSmallAttributeBase(Tag t);
+	virtual ~UnknownSmallAttributeBase();
+
+	const char *	getVR() const	{ return "UN"; }
+	Uint16	getValueSize(void) const	{ return 1; }
+
+	bool	isUnknown(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+								{ return Attribute::getValue(rvalue,rlengthinwords); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length);
+	void	setValue(const Uint16 *values,Uint32 lengthinwords)
+								{ Attribute::setValue(values,lengthinwords); }
+
+	void	addValues(const char *);
+};
+
+class UnknownLargeAttributeBase : public OtherNonPixelAttribute {
+private:
+	BinaryInputStream *srcstream;
+	OurStreamPos srcpos;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	UnknownLargeAttributeBase(Tag t,BinaryInputStream &stream,OurStreamPos pos);
+	virtual ~UnknownLargeAttributeBase();
+
+	const char *	getVR() const	{ return "UN"; }
+	Uint16	getValueSize(void) const	{ return 1; }
+
+	bool	isUnknown(void) const	{ return true; }
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			return OtherNonPixelAttribute::writeData(stream);
+		}
+	TextOutputStream& writeData(TextOutputStream& stream);
+	TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false);
+	BinaryOutputStream& write(BinaryOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+	DicomOutputStream& write(DicomOutputStream& stream) { return OtherNonPixelAttribute::write(stream); }
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const		{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+	bool	getValue(const unsigned char * & rvalue,Uint32 &rlength) const;
+	bool	getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+								{ return Attribute::getValue(rvalue,rlengthinwords); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+	void	setValue(const unsigned char *values,Uint32 length);
+	void	setValue(const Uint16 *values,Uint32 lengthinwords)
+								{ Attribute::setValue(values,lengthinwords); }
+};
+
+#endif /* __Header_attrtypo__ */
diff --git a/libsrc/include/dctool/attrtyps.h b/libsrc/include/dctool/attrtyps.h
new file mode 100644
index 0000000..f9caec7
--- /dev/null
+++ b/libsrc/include/dctool/attrtyps.h
@@ -0,0 +1,293 @@
+/* attrtyps.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtyps__
+#define __Header_attrtyps__
+
+#include "strtype.h"
+
+/* ************************ String Attributes ************************ */
+
+class StringAttribute : public Attribute {
+private:
+	friend class TextAttribute;
+protected:
+	ValueList<char *> values;
+	bool trailingNullByte;
+	bool embeddedNullByte;
+	bool trailingSpace;
+		
+	TextOutputStream& writePaddedValues(TextOutputStream& stream,
+		char pad);
+
+	TextOutputStream& writePadded(TextOutputStream& stream,
+		char pad,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false)
+		{
+			Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+			stream << "<";
+			writePaddedValues(stream,pad);
+			stream << "> ";
+			return stream;
+		}
+
+	BinaryOutputStream& writePaddedValues(BinaryOutputStream& stream,
+		char pad);
+
+	BinaryOutputStream& writePadded(BinaryOutputStream& stream,char pad)
+		{
+			Attribute::writeBase(stream);
+			writePaddedValues(stream,pad);
+			return stream;
+		}
+
+	DicomOutputStream& writePadded(DicomOutputStream& stream,char pad)
+		{
+			Attribute::writeBase(stream);
+			writePaddedValues(stream,pad);
+			return stream;
+		}
+public:
+	StringAttribute(Tag t) : Attribute(t)
+		{
+			trailingNullByte=false;
+			embeddedNullByte=false;
+			trailingSpace=false;
+		}
+	
+	virtual ~StringAttribute()	{}
+
+	virtual BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			writePaddedValues(stream,' ');
+			return stream;
+		}
+
+	virtual TextOutputStream& writeData(TextOutputStream& stream)
+		{
+			writePaddedValues(stream,' ');
+			return stream;
+		}
+
+	virtual TextOutputStream& write(TextOutputStream& stream,ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false)
+		{
+			writePadded(stream,' ',dict,verbose,showUsedAndIE);
+			return stream;
+		}
+
+	virtual BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			writePadded(stream,' ');
+			return stream;
+		}
+
+	virtual DicomOutputStream& write(DicomOutputStream& stream)
+		{
+			writePadded(stream,' ');
+			return stream;
+		}
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	isString(void) const	{ return true; }
+
+	Uint16	getVM(void) const	{ return values.getVM(); }
+	Uint32	getVL(void) const;
+	Uint16	getValueSize(void) const	{ return 1; }
+
+	bool	isEmptyOrHasAnyEmptyValue(void) const;
+	bool	isEmptyOrHasAllEmptyValues(void) const;
+
+	// NB. seems silly to have to redefine those methods that
+	// just call the base class methods, but it seems that if
+	// ANY method distinguished only by its parameter types
+	// is redefined, they all have to be :(. This is enforced
+	// by SunPro C++ but not g++.
+
+	// Note also that the use of virtual is limited to those
+	// methods we know are going to be redefined in specific
+	// derived classes ... this is not intended to be a generic
+	// base class.
+
+	bool	getValue(unsigned index,Uint16& vp) const;
+	bool	getValue(unsigned index,Uint32& vp) const;
+	bool	getValue(unsigned index,Int16& vp) const;
+	bool	getValue(unsigned index,Int32& vp) const;
+	bool	getValue(unsigned index,Float32& vp) const;
+	bool	getValue(unsigned index,Float64& vp) const;
+	bool	getValue(unsigned index,Tag& vp) const			{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,char * & rvalue) const;
+
+	virtual void	setValue(unsigned index,Uint16 value);
+	virtual void	setValue(unsigned index,Uint32 value);
+	virtual void	setValue(unsigned index,Int16 value);
+	virtual void	setValue(unsigned index,Int32 value);
+	virtual void	setValue(unsigned index,Float32 value);
+	virtual void	setValue(unsigned index,Float64 value);
+	virtual void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,const char *str);
+
+	virtual void	addValue(Uint16 value);
+	virtual void	addValue(Uint32 value);
+	virtual void	addValue(Int16 value);
+	virtual void	addValue(Int32 value);
+	virtual void	addValue(Float32 value);
+	virtual void	addValue(Float64 value);
+	virtual void	addValue(Tag value)				{ Attribute::addValue(value); }
+	virtual void	addValue(const char *str);
+
+	virtual void	addValues(unsigned number,Uint16 *vptr)		{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,Uint32 *vptr)		{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,Int16 *vptr)		{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,Int32 *vptr)		{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,Float32 *vptr)	{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,Float64 *vptr)	{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,Tag *vptr)		{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(unsigned number,const char **vptr)	{ Attribute::addValues(number,vptr); }
+	virtual void	addValues(const char *vptr);
+};
+
+class NonNumericStringAttribute : public StringAttribute {
+public:
+	NonNumericStringAttribute(Tag t) : StringAttribute(t) {}
+	virtual ~NonNumericStringAttribute()	{}
+
+	NonNumericStringAttribute(Tag t,const char *v)
+		: StringAttribute(t)	{ addValue(v); }
+	NonNumericStringAttribute(Tag t,Uint16 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NonNumericStringAttribute(Tag t,Uint32 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NonNumericStringAttribute(Tag t,Int16 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NonNumericStringAttribute(Tag t,Int32 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NonNumericStringAttribute(Tag t,Float32 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NonNumericStringAttribute(Tag t,Float64 v)
+		: StringAttribute(t)	{ addValue(v); }
+};
+
+class NumericStringAttribute : public StringAttribute {
+public:
+	NumericStringAttribute(Tag t) : StringAttribute(t) {}
+	virtual ~NumericStringAttribute()	{}
+	NumericStringAttribute(Tag t,const char *v)
+		: StringAttribute(t)	{ addValue(v); }
+	NumericStringAttribute(Tag t,Uint16 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NumericStringAttribute(Tag t,Uint32 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NumericStringAttribute(Tag t,Int16 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NumericStringAttribute(Tag t,Int32 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NumericStringAttribute(Tag t,Float32 v)
+		: StringAttribute(t)	{ addValue(v); }
+	NumericStringAttribute(Tag t,Float64 v)
+		: StringAttribute(t)	{ addValue(v); }
+
+	bool	isNumeric(void) const		{ return 1; }
+	bool	isNumericString(void) const	{ return 1; }
+};
+
+class TextAttribute : public NonNumericStringAttribute {
+public:
+	TextAttribute(Tag t) : NonNumericStringAttribute(t) {}
+	TextAttribute(Tag t,const char *v)
+		: NonNumericStringAttribute(t)	{ addValue(v); }
+
+	virtual ~TextAttribute()	{}
+
+	virtual void	setValue(unsigned index,Uint16 value)		{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,Uint32 value)		{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,Int16 value)		{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,Int32 value)		{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,Float32 value)	 	{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,Float64 value)		{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,Tag value)		{ NonNumericStringAttribute::setValue(index,value); }
+	virtual void	setValue(unsigned index,const char *value);
+
+	virtual void	addValue(Uint16 value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(Uint32 value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(Int16 value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(Int32 value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(Float32 value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(Float64 value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(Tag value)				{ NonNumericStringAttribute::addValue(value); }
+	virtual void	addValue(const char *value);
+
+};
+
+class LongTextAttributeBase : public TextAttribute {
+public:
+	LongTextAttributeBase(Tag t) : TextAttribute(t) {}
+	LongTextAttributeBase(Tag t,const char *v)
+		: TextAttribute(t)	{ addValue(v); }
+
+	virtual ~LongTextAttributeBase()	{}
+
+	void	setValue(unsigned index,Uint16 value)		{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ TextAttribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *value);
+
+	void	addValue(Uint16 value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(Uint32 value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(Int16 value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(Int32 value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(Float32 value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(Float64 value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(Tag value)				{ NonNumericStringAttribute::addValue(value); }
+	void	addValue(const char *value);
+
+	void	addValues(unsigned number,Uint16 *vptr)		{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Uint32 *vptr)		{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int16 *vptr)		{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int32 *vptr)		{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float32 *vptr)	{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float64 *vptr)	{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Tag *vptr)		{ TextAttribute::addValues(number,vptr); }
+	void	addValues(unsigned number,const char **vptr)	{ TextAttribute::addValues(number,vptr); }
+	void	addValues(const char *vptr);
+};
+
+class CodeStringFileComponentAttributeBase : public NonNumericStringAttribute {
+public:
+	CodeStringFileComponentAttributeBase(Tag t) : NonNumericStringAttribute(t) {}
+	CodeStringFileComponentAttributeBase(Tag t,const char *v)
+		: NonNumericStringAttribute(t)	{ addValues(v); }
+
+	virtual ~CodeStringFileComponentAttributeBase()	{}
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,const char *value)	{ NonNumericStringAttribute::setValue(index,value); }
+
+	void	addValue(Uint16 value)				{ Attribute::addValue(value); }
+	void	addValue(Uint32 value)				{ Attribute::addValue(value); }
+	void	addValue(Int16 value)				{ Attribute::addValue(value); }
+	void	addValue(Int32 value)				{ Attribute::addValue(value); }
+	void	addValue(Float32 value)				{ Attribute::addValue(value); }
+	void	addValue(Float64 value)				{ Attribute::addValue(value); }
+	void	addValue(Tag value)				{ Attribute::addValue(value); }
+	void	addValue(const char *value)			{ NonNumericStringAttribute::addValue(value); }
+
+	void	addValues(unsigned number,Uint16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Uint32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float32 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float64 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Tag *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,const char **vptr)	{ NonNumericStringAttribute::addValues(number,vptr); }
+	void	addValues(const char *vptr);
+};
+
+#endif /* __Header_attrtyps__ */
diff --git a/libsrc/include/dctool/attrtypt.h b/libsrc/include/dctool/attrtypt.h
new file mode 100644
index 0000000..61fd23a
--- /dev/null
+++ b/libsrc/include/dctool/attrtypt.h
@@ -0,0 +1,94 @@
+/* attrtypt.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrtypt__
+#define __Header_attrtypt__
+
+/* ************************** Tag Attributes ************************* */
+
+class TagAttribute : public Attribute {
+private:
+	ValueList<Tag> values;
+
+	BinaryOutputStream& writeValues(BinaryOutputStream& stream);
+public:
+	TagAttribute(Tag t) : Attribute(t) {}
+	virtual ~TagAttribute()	{}
+
+	BinaryOutputStream& writeData(BinaryOutputStream& stream)
+		{
+			writeValues(stream);
+			return stream;
+		}
+
+	TextOutputStream& writeData(TextOutputStream& stream);
+
+	TextOutputStream& write(TextOutputStream& stream,
+		ElementDictionary *dict=0,bool verbose=false,bool showUsedAndIE=false)
+		{
+			Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+			stream << "{";
+			writeData(stream);
+			stream << "} ";
+			return stream;
+		}
+
+	BinaryOutputStream& write(BinaryOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	DicomOutputStream& write(DicomOutputStream& stream)
+		{
+			Attribute::writeBase(stream);
+			writeValues(stream);
+			return stream;
+		}
+
+	BinaryInputStream& read(BinaryInputStream& stream,Uint32 length);
+
+	bool	isTag(void) const	{ return true; }
+
+	Uint16	getVM(void) const	{ return values.getVM(); }
+	Uint32	getVL(void) const	{ return 4*getVM(); }
+	Uint16	getValueSize(void) const	{ return 4; }
+
+	bool	getValue(unsigned index,Uint16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Uint32& vp) const;
+	bool	getValue(unsigned index,Int16& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Int32& vp) const;
+	bool	getValue(unsigned index,Float32& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Float64& vp) const	{ return Attribute::getValue(index,vp); }
+	bool	getValue(unsigned index,Tag& vp) const;
+	bool	getValue(unsigned index,char * & rvalue) const	{ return Attribute::getValue(index,rvalue); }
+
+	void	setValue(unsigned index,Uint16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Uint32 value);
+	void	setValue(unsigned index,Int16 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Int32 value);
+	void	setValue(unsigned index,Float32 value)	 	{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Float64 value)		{ Attribute::setValue(index,value); }
+	void	setValue(unsigned index,Tag value);
+	void	setValue(unsigned index,const char *str)	{ Attribute::setValue(index,str); }
+
+	void	addValue(Uint16 value)				{ Attribute::addValue(value); }
+	void	addValue(Uint32 value);
+	void	addValue(Int16 value)				{ Attribute::addValue(value); }
+	void	addValue(Int32 value);
+	void	addValue(Float32 value)				{ Attribute::addValue(value); }
+	void	addValue(Float64 value)				{ Attribute::addValue(value); }
+	void	addValue(Tag value);
+	void	addValue(const char *str)			{ Attribute::addValue(str); }
+
+	void	addValues(unsigned number,Uint16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Uint32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int16 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Int32 *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float32 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Float64 *vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,Tag *vptr)		{ Attribute::addValues(number,vptr); }
+	void	addValues(unsigned number,const char **vptr)	{ Attribute::addValues(number,vptr); }
+	void	addValues(const char *vptr)			{ Attribute::addValues(vptr); }
+};
+
+#endif /* __Header_attrtypt__ */
diff --git a/libsrc/include/dctool/attrval.h b/libsrc/include/dctool/attrval.h
new file mode 100644
index 0000000..a2cb6ab
--- /dev/null
+++ b/libsrc/include/dctool/attrval.h
@@ -0,0 +1,77 @@
+/* attrval.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_attrval__
+#define __Header_attrval__
+
+#include "strtype.h"
+
+// Allows use of default type conversions to extract a single value
+// of the appropriate type, if present, else a default value
+// may be supplied (which will be 0 if absent), eg:
+//
+// AttributeList list;
+// Uint16 bitsStored=AttributeValue(list[TagFromName(BitsStored)],16);
+
+class AttributeValue {
+	Attribute 	*a;
+	unsigned long 	defaultinteger;
+	double 		defaultfloat;
+	const char 		*defaultstring;
+public:
+	AttributeValue(Attribute *attr,double def=0)
+		{
+			a=attr;
+			defaultinteger=(unsigned long)def;
+			defaultfloat=def;
+			defaultstring=0;
+		}
+
+	AttributeValue(Attribute *attr,const char *defstr)
+		{
+			a=attr;
+			defaultinteger=0;
+			defaultfloat=0;
+			defaultstring=defstr;
+		}
+
+	// If more than one value, only returns the first value
+
+	operator Uint16 () const
+		{
+			Uint16 value;
+			return (a && a->isNumeric() && a->getVM() >= 1 && a->getValue((Uint16)0,value))
+				? value : (Uint16)defaultinteger;
+		}
+	operator Uint32 () const
+		{
+			Uint32 value;
+			return (a && a->isNumeric() && a->getVM() >= 1 && a->getValue((Uint16)0,value))
+				? value : (Uint32)defaultinteger;
+		}
+	operator Int16 () const
+		{
+			Int16 value;
+			return (a && a->isNumeric() && a->getVM() >= 1 && a->getValue((Uint16)0,value))
+				? value : (Int16)defaultinteger;
+		}
+	operator Int32 () const
+		{
+			Int32 value;
+			return (a && a->isNumeric() && a->getVM() >= 1 && a->getValue((Uint16)0,value))
+				? value : (Int32)defaultinteger;
+		}
+	operator Float32 () const
+		{
+			Float32 value;
+			return (a && a->isNumeric() && a->getVM() >= 1 && a->getValue((Uint16)0,value))
+				? value : (Float32)defaultfloat;
+		}
+	operator char * () const
+		{
+			// NB. getValue() returns a copy, so don't need another StrDup(value)
+			char * value;
+			return (a && a->isString() && a->getVM() >= 1 && a->getValue((Uint16)0,value))
+				? value : StrDup(defaultstring);
+		}
+};
+
+#endif /* __Header_attrval__ */
diff --git a/libsrc/include/dctool/charset.h b/libsrc/include/dctool/charset.h
new file mode 100644
index 0000000..dffca7f
--- /dev/null
+++ b/libsrc/include/dctool/charset.h
@@ -0,0 +1,32 @@
+/* charset.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// public interface for SpecificCharacterSetInfo class
+
+#ifndef __Header_charset__
+#define __Header_charset__
+
+class Attribute;
+
+class SpecificCharacterSetInfo {
+private:
+	bool flag7BitSingleByte;
+	bool flag8BitSingleByte;
+	bool flagISO2022;
+	bool flagUTF8;
+public:
+	SpecificCharacterSetInfo(void);
+	SpecificCharacterSetInfo(int nCharSetValues,char**charSetValues);
+	SpecificCharacterSetInfo(Attribute *aSpecificCharacterSet);
+	~SpecificCharacterSetInfo();
+
+	void setSpecificCharacterSet();
+	void setSpecificCharacterSet(int nCharSetValues,char**charSetValues);
+
+	bool is7BitSingleByte() const { return flag7BitSingleByte; }
+	bool is8BitSingleByt() const { return flag8BitSingleByte; }
+	bool isISO2022() const { return flagISO2022; }
+	bool isUTF8() const { return flagUTF8; }
+	
+	bool isValidString(const char *s,int& badCharacterPosition) const;
+};
+
+#endif // __Header_charset__
diff --git a/libsrc/include/dctool/convtype.h b/libsrc/include/dctool/convtype.h
new file mode 100644
index 0000000..0e33086
--- /dev/null
+++ b/libsrc/include/dctool/convtype.h
@@ -0,0 +1,87 @@
+/* convtype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_convtype__
+#define __Header_convtype__
+
+//#include "dctool/basetype.h"		// should already be included
+//#include "dctool/endtype.h"		// should already be included
+
+// The following types may be assigned and manipulated, or used
+// in arrays or expressions, as if they were basic types.
+//
+// However they have EXACTLY the expected length and may be
+// mapped onto external types, without alignment restrictions
+// if used as components of structures.
+//
+// In particular sizeof(Uint16_L)==2, sizeof(Uint32_L)==4, etc.
+//
+// Note however that the assignment and increment operators
+// like += and ++, are not implemented.
+
+template <class T,int Hi,int Lo,int Signed>
+class Word_Base {
+private:
+	unsigned char bytes[((Hi>Lo)?Hi-Lo:Lo-Hi)+1];
+public:
+	Word_Base(void)
+		{
+			*this=0;
+		}
+
+	Word_Base(T word)
+		{
+			*this=word;
+		}
+
+	Word_Base<T,Hi,Lo,Signed>& operator=(T word)
+		{
+			unsigned index=Lo;
+			while (1) {
+				bytes[index]=(unsigned char)word;
+				word>>=8;
+				if (index == Hi) break;
+				index+=(Lo>Hi)?-1:1;
+			};
+			return *this;
+		}
+
+	Word_Base<T,Hi,Lo,Signed>& operator=(const Word_Base<T,Hi,Lo,Signed>& i)
+		{
+			// NB. be very careful about the size here !!!!
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator T() const
+		{
+			T word=0;
+			unsigned index=Hi;
+			// sign extend if necessary in case word is longer than expected
+			word=(Signed && (bytes[index]&0x80)) ? (T)ULONG_MAX : (T)0;
+			while (1) {
+				word<<=8;
+				word|=bytes[index];
+				if (index == Lo) break;
+				index+=(Hi>Lo)?-1:1;
+			};
+			return word;
+		}
+};
+
+// Note that the 8 bit types (which have no byte order) are
+// returned as longer types, in order to a) shut up the
+// shift >= 8 warnings (they should probably not use the
+// template) and b) to allow use in iostreams without being
+// written as chars, which gets annoying !
+
+typedef Word_Base<Uint16,0,0,0>  Uint8_8;
+typedef Word_Base<Uint16,1,0,0> Uint16_L;
+typedef Word_Base<Uint16,0,1,0> Uint16_B;
+typedef Word_Base<Uint32,3,0,0> Uint32_L;
+typedef Word_Base<Uint32,0,3,0> Uint32_B;
+typedef Word_Base<Int16,0,0,1>   Int8_8;
+typedef Word_Base<Int16,1,0,1>  Int16_L;
+typedef Word_Base<Int16,0,1,1>  Int16_B;
+typedef Word_Base<Int32,3,0,1>  Int32_L;
+typedef Word_Base<Int32,0,3,1>  Int32_B;
+
+#endif // __Header_convtype__
diff --git a/libsrc/include/dctool/dcopt.h b/libsrc/include/dctool/dcopt.h
new file mode 100644
index 0000000..dfac0a9
--- /dev/null
+++ b/libsrc/include/dctool/dcopt.h
@@ -0,0 +1,97 @@
+/* dcopt.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_dcopt__
+#define __Header_dcopt__
+
+#include "getoptns.h"
+#include "attrtag.h"
+
+class DicomInputOptions : public ErrorsInClass
+{
+public:
+	const char *	filename;
+	bool 		usemetaheader;
+	bool 		uselengthtoend;
+	bool		ignoreoutofordertags;
+	bool		useUSVRForLUTDataIfNotExplicit;
+	const char *	transfersyntaxuid;
+
+	DicomInputOptions(GetNamedOptions &options);
+	char *usage(void);
+	void done(void);
+};
+
+class DicomOutputOptions : public ErrorsInClass
+{
+public:
+	const char *	filename;
+	bool 		usemetaheader;
+	bool 		writedataset;
+	bool 		useimplicitmetaheader;
+	bool 		addlengths;
+	bool 		addlengthtoend;
+	bool 		removeprivate;
+	bool 		removeinstanceuid;
+	bool 		adddicom;
+	bool 		addtiff;
+	bool 		adddisclaimer;
+	bool		disambiguateseriesbydescription;
+	const char *	transfersyntaxuid;
+	const char *	stamp;
+	const char *	instancecreationdate;
+	const char *	instancecreationtime;
+	const char *	timezoneoffsetfromutc;
+	class AttributeList *replaceafterlist;
+	class AttributeList *replacebeforelist;
+	class AttributeList *deletelist;
+
+	DicomOutputOptions(GetNamedOptions &options);
+	~DicomOutputOptions();
+	char *usage(void);
+	void done(void);
+};
+
+class DicomInputOpenerFromOptions : public ErrorsInClass {
+	istream *str;
+	const char *filenameUsed;
+public:
+	DicomInputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename,istream &cstr);
+	DicomInputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename);
+
+	~DicomInputOpenerFromOptions();
+
+	operator istream *(void);
+	
+	const char *getFilename() {return filenameUsed;}
+};
+
+class DicomOutputOpenerFromOptions : public ErrorsInClass {
+	ostream *str;
+	const char *filenameUsed;
+public:
+	DicomOutputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename,ostream &cstr);
+
+	~DicomOutputOpenerFromOptions();
+
+	operator ostream *(void);
+	
+	const char *getFilename() {return filenameUsed;}
+};
+
+bool
+usualManagedAttributeListWrite(
+	class ManagedAttributeList& list,
+	class DicomOutputStream& dout,
+	class DicomOutputOptions& dicom_output_options,
+	class TextOutputStream& log,
+	bool verbose);
+
+bool
+getAttributeTagFromStringHexForm(
+	const char *arg,
+	Tag &tag);
+
+#endif /* __Header_dcopt__ */
+
diff --git a/libsrc/include/dctool/dcstream.h b/libsrc/include/dctool/dcstream.h
new file mode 100644
index 0000000..1fa6b0a
--- /dev/null
+++ b/libsrc/include/dctool/dcstream.h
@@ -0,0 +1,144 @@
+/* dcstream.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_dcstream__
+#define __Header_dcstream__
+
+#include "bnstream.h"
+#include "transyn.h"
+
+// See comments in bnstream.h about extractors and insertors
+
+class Tag;
+class Attribute;
+
+class DicomInputStream : public BinaryInputStream {
+private:
+	TransferSyntax *	TransferSyntaxToReadDataSet;
+	TransferSyntax *	TransferSyntaxToReadMetaHeader;
+	TransferSyntax *	TransferSyntaxInUse;
+
+	void initializeTransferSyntax(const char *uid,bool meta);
+public:
+	DicomInputStream(streambuf *buf,
+			  const char *uid=0,
+			  bool meta=true);
+	DicomInputStream(istream& istr,
+			  const char *uid=0,
+			  bool meta=true);
+
+	virtual ~DicomInputStream(void);
+
+	void setTransferSyntaxToReadDataSet(TransferSyntax *ts);
+	void guessTransferSyntaxToReadDataSet(bool& setswapped32big);
+	void readingDataSet(void);
+	void readingMetaHeader(void);
+
+	bool haveMetaHeader(void) const	{ return TransferSyntaxToReadMetaHeader != 0; }
+
+	TransferSyntax *getTransferSyntaxInUse(void)
+		{ return TransferSyntaxInUse; }
+
+	TransferSyntax *getTransferSyntaxToReadDataSet(void)
+		{ return TransferSyntaxToReadDataSet; }
+
+	TransferSyntax *getTransferSyntaxToReadMetaHeader(void)
+		{ return TransferSyntaxToReadMetaHeader; }
+
+	DicomInputStream& operator>>(Uint8& rhs)
+		{
+			((BinaryInputStream&)*this).operator>>(rhs);
+			return *this;
+		}
+	DicomInputStream& operator>>(Uint16& rhs)
+		{
+			((BinaryInputStream&)*this).operator>>(rhs);
+			return *this;
+		}
+	DicomInputStream& operator>>(Uint32& rhs)
+		{
+			((BinaryInputStream&)*this).operator>>(rhs);
+			return *this;
+		}
+
+	DicomInputStream& operator>>(Tag& rhs);		// in attrtag.cc
+};
+
+class DicomOutputStream : public BinaryOutputStream {
+private:
+	TransferSyntax *	TransferSyntaxToWriteDataSet;
+	TransferSyntax *	TransferSyntaxToWriteMetaHeader;
+	TransferSyntax *	TransferSyntaxInUse;
+	bool			preambledone;
+	bool			tiffinpreamble;
+	Uint32			offsetofIFD;
+
+	void initializeTransferSyntax(const char *uid,bool meta,
+		bool implicitmeta,bool addtiff);
+	void writeMetaHeaderPreamble(void);
+public:
+	DicomOutputStream(streambuf *buf,
+			  const char *uid=DefaultTransferSyntaxUID,
+			  bool meta=true,bool implicitmeta=false,
+			  bool addtiff=false);
+
+	DicomOutputStream(ostream& ostr,
+			  const char *uid=DefaultTransferSyntaxUID,
+			  bool meta=true,bool implicitmeta=false,
+			  bool addtiff=false);
+
+	virtual ~DicomOutputStream(void);
+
+	void writingDataSet(void);
+	void writingMetaHeader(void);
+
+	bool haveMetaHeader(void) const
+		{ return TransferSyntaxToWriteMetaHeader != 0; }
+
+	TransferSyntax *getTransferSyntaxInUse(void)
+		{ return TransferSyntaxInUse; }
+
+	TransferSyntax *getTransferSyntaxToWriteDataSet(void)
+		{ return TransferSyntaxToWriteDataSet; }
+
+	TransferSyntax *getTransferSyntaxToWriteMetaHeader(void)
+		{ return TransferSyntaxToWriteMetaHeader; }
+
+	void setIFDOffset(Uint32 o)
+		{
+			offsetofIFD=o;
+		}
+
+	DicomOutputStream& operator<<(Uint8 rhs)
+		{
+			((BinaryOutputStream&)*this).operator<<(rhs);
+			return *this;
+		}
+	DicomOutputStream& operator<<(Uint16 rhs)
+		{
+			((BinaryOutputStream&)*this).operator<<(rhs);
+			return *this;
+		}
+	DicomOutputStream& operator<<(Uint32 rhs)
+		{
+			((BinaryOutputStream&)*this).operator<<(rhs);
+			return *this;
+		}
+
+	DicomOutputStream& operator<<(const char *rhs)
+		{
+			((BinaryOutputStream&)*this).operator<<(rhs);
+			return *this;
+		}
+
+	DicomOutputStream& operator<<(char rhs)
+		{
+			((BinaryOutputStream&)*this).operator<<(rhs);
+			return *this;
+		}
+
+	DicomOutputStream& operator<<(Tag rhs);		// in attrtag.cc
+	DicomOutputStream& operator<<(Attribute& rhs);	// in attr.cc
+};
+
+#endif /* __Header_dcstream__ */
+
+
diff --git a/libsrc/include/dctool/dicomdir.h b/libsrc/include/dctool/dicomdir.h
new file mode 100644
index 0000000..72701d5
--- /dev/null
+++ b/libsrc/include/dctool/dicomdir.h
@@ -0,0 +1,10 @@
+/* dicomdir.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_dicomdir__
+#define __Header_dicomdir__
+
+bool parseDicomdir(ManagedAttributeList &list,
+	TextOutputStream &log,bool verbose,bool veryverbose,bool showrecordinfo,bool showabstract,bool showpaths,bool showdescription);
+
+#endif /* __Header_dicomdir__ */
+
+
diff --git a/libsrc/include/dctool/elmdict.h b/libsrc/include/dctool/elmdict.h
new file mode 100644
index 0000000..e8a69a5
--- /dev/null
+++ b/libsrc/include/dctool/elmdict.h
@@ -0,0 +1,31 @@
+/* elmdict.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_elmdict__
+#define __Header_elmdict__
+
+class PrivateOwners;
+class ElementDictionaryTableEntry;
+
+class ElementDictionary {
+	PrivateOwners *CurrentOwners;
+
+	const ElementDictionaryTableEntry *operator[] (Tag tag) const;
+	const ElementDictionaryTableEntry *operator[] (const char *keyword) const;
+public:
+	ElementDictionary(void);
+	~ElementDictionary();
+
+	const char *	getValueRepresentation(Tag t) const;
+	const Uint16	getValueMultiplicityMinimum(Tag t) const;
+	const Uint16	getValueMultiplicityMaximum(Tag t) const;
+	const char *	getDescription(Tag t) const;
+	const char *	getKeyword(Tag t) const;
+	bool		getTag(const char *keyword,Tag& tr) const;
+	bool		isRetired(Tag& t) const;
+	bool		isRenderAsString(Tag& t) const;
+
+	void			addOwner(Tag t,const char *owner);
+	bool			hasOwner(Tag& t) const;
+	const char *	getOwner(Tag& t) const;
+};
+
+#endif /* __Header_elmdict__ */
diff --git a/libsrc/include/dctool/fltype.h b/libsrc/include/dctool/fltype.h
new file mode 100644
index 0000000..0fe304f
--- /dev/null
+++ b/libsrc/include/dctool/fltype.h
@@ -0,0 +1,210 @@
+/* fltype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_fltype__
+#define __Header_fltype__
+
+#include <float.h>
+
+#ifdef POWINTEGEREXPONENTTYPE
+#define	powi(m,e)	pow(m,(POWINTEGEREXPONENTTYPE)(e))
+#else
+#define	powi(m,e)	pow(m,(long)(e))
+#endif
+
+#ifdef __SC__
+#define infinity()    HUGE_VAL
+#define quiet_nan(x)  0
+#endif /* __SC__ */
+
+#ifdef __MWERKS__
+#define infinity()    __inf()
+#define quiet_nan(x)  0
+#endif /* __MWERKS__ */
+
+#ifdef USEDUMBINFINITYANDNAN
+#if USEDUMBINFINITYANDNAN
+#define infinity()    FLT_MAX
+#define quiet_nan(x)  0
+#endif
+#endif
+
+template <class T>
+class IEEE_Float32_Base {
+private:
+	T binary;
+public:
+	IEEE_Float32_Base(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	IEEE_Float32_Base<T>& operator=(const IEEE_Float32_Base<T>& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator double() const
+		{
+			double value;
+			Int16 sign	=(Int16)((binary&0x80000000)>>31);
+			Int16 exponent	=(Int16)((binary&0x7f800000)>>23);
+			Uint32 mantissa	= binary&0x007fffff;
+
+			if (exponent == 0) {
+				if (mantissa == 0)
+					value=0;
+				else {
+					value=((double)mantissa/
+						(1<<23))*powi(2.0,-126);
+					value = (sign == 0) ? value : -value;
+				}
+			}
+			else if (exponent == 255) {
+				if (mantissa)
+					value=quiet_nan(0);
+				else
+					value=infinity();
+			}
+			else {
+				value=(1.0+(double)mantissa/
+					(1<<23))*powi(2.0,exponent-127);
+				value = (sign == 0) ? value : -value;
+			}
+			return value;
+		}
+};
+
+typedef IEEE_Float32_Base<Uint32_B> IEEE_Float32_B;
+typedef IEEE_Float32_Base<Uint32_L> IEEE_Float32_L;
+
+template <class T,int isbig>
+class IEEE_Float64_Base {
+private:
+	T binary1;
+	T binary2;
+public:
+	IEEE_Float64_Base(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	IEEE_Float64_Base<T,isbig>& operator=(const IEEE_Float64_Base<T,isbig>& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator double() const
+		{
+			double value;
+			Uint32 high = isbig ? binary1 : binary2;
+			Uint32 low  = isbig ? binary2 : binary1;
+
+			Int16 sign	=(Int16)((high&0x80000000)>>31);
+			Int16 exponent	=(Int16)((high&0x7ff00000)>>20);
+			Uint32 mantissahigh = high&0x000fffff;
+			Uint32 mantissalow  = low;
+			double mantissavalue = (double)mantissahigh * powi(2.0,32)
+					     + (double)mantissalow;
+
+			if (exponent == 0) {
+				if (mantissahigh == 0 && mantissalow == 0)
+					value=0;
+				else {
+					value=(mantissavalue/powi(2.0,52))
+						*powi(2.0,-1022);
+					value = (sign == 0) ? value : -value;
+				}
+			}
+			else if (exponent == 255) {
+				if (mantissahigh || mantissalow)
+					value=quiet_nan(0);
+				else
+					value=infinity();
+			}
+			else {
+				value=(1.0+mantissavalue/powi(2.0,52))
+					*powi(2.0,exponent-1023);
+				value = (sign == 0) ? value : -value;
+			}
+			return value;
+		}
+};
+
+typedef IEEE_Float64_Base<Uint32_B,1> IEEE_Float64_B;
+typedef IEEE_Float64_Base<Uint32_L,0> IEEE_Float64_L;
+
+class Vax_Float_F {
+private:
+	Uint32_L binary;
+public:
+	Vax_Float_F(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	Vax_Float_F& operator=(const Vax_Float_F& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator double() const
+		{
+			double value;
+			Uint32 mantissalow	= (binary&0xffff0000)>>16;
+			Int16  sign		= (Int16)((binary&0x00008000)>>15);
+			Int16  exponent		= (Int16)((binary&0x00007f80)>>7);
+			Uint32 mantissahigh	= binary&0x0000007f;
+			double mantissavalue    = (double)mantissahigh *
+				powi(2.0,16) + (double)mantissalow;
+			double mantissafraction = mantissavalue/powi(2.0,23);
+
+			if (exponent == 0 && mantissalow == 0 && mantissahigh == 0) {
+				value=0;
+			}
+			else {
+			// Always normalized ... the 1.0 is the "hidden" bit in VaxSpeak
+			// the exponent is excess 128, eg 10000010 is +2
+			// but refers to a binary point to the LEFT of the hidden bit
+			// hence the -129 rather than -128
+
+				value=(1.0+mantissafraction)
+					*powi(2.0,exponent-129);
+				value = (sign == 0) ? value : -value;
+			}
+			return value;
+		}
+};
+
+class DG_Float_F {
+private:
+	Uint32_B binary;
+public:
+	DG_Float_F(void)
+		{
+			memset((char *)this,0,sizeof *this);
+		}
+
+	DG_Float_F& operator=(const Vax_Float_F& i)
+		{
+			memcpy((char *)this,(const char *)&i,sizeof *this);
+			return *this;
+		}
+
+	operator double() const
+		{
+			double value;
+			
+			Uint32 mantissa	=         (binary&0x00ffffff);
+			Int16  exponent = (Int16)((binary&0x7f000000)>>24);
+			Int16  sign		= (Int16)((binary&0x80000000)>>31);
+
+			value = (double) mantissa / (1 << 24) * pow (16.0, (long)(exponent) - 64);
+			value = (sign == 0) ? value : -value;
+						
+			return value;
+		}
+};
+
+#endif /* __Header_fltype__ */
diff --git a/libsrc/include/dctool/ie.h b/libsrc/include/dctool/ie.h
new file mode 100644
index 0000000..be076de
--- /dev/null
+++ b/libsrc/include/dctool/ie.h
@@ -0,0 +1,40 @@
+/* ie.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ie__
+#define __Header_ie__
+
+enum InformationEntity {
+	UnknownIE,
+	DirectoryIE,
+	DocumentIE,
+	EncapsulatedDocumentIE,
+	EquipmentIE,
+	FileIE,
+	FrameOfReferenceIE,
+	HangingProtocolIE,
+	ImageIE,
+	MeasurementsIE,
+	MRSpectroscopyIE,
+	PatientIE,
+	PlanIE,
+	PresentationIE,
+	RawDataIE,
+	RealWorldValueMappingIE,
+	SeriesIE,
+	SpatialFiducialsIE,
+	SpatialRegistrationIE,
+	StructureSetIE,
+	StudyIE,
+	TreatmentRecordIE,
+	WaveformIE,
+	OverlayIE,
+	CurveIE,
+	ModalityLUTIE,
+	VOILUTIE,
+	ColorPaletteIE,
+	SurfaceIE
+};
+
+InformationEntity getInformationEntityFromDescription(const char *d);
+const char *describeInformationEntity(InformationEntity ie);
+
+#endif // __Header_ie__
diff --git a/libsrc/include/dctool/iodcomp.h b/libsrc/include/dctool/iodcomp.h
new file mode 100644
index 0000000..b11ea2e
--- /dev/null
+++ b/libsrc/include/dctool/iodcomp.h
@@ -0,0 +1,16 @@
+/* iodcomp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_iodcomp__
+#define __Header_iodcomp__
+
+class CompositeIOD {
+public:
+	virtual bool		retired(void) const = 0;
+	virtual const char *identify(void) const = 0;
+	virtual void        write(TextOutputStream& stream,AttributeList *list,ElementDictionary *dict) const = 0;
+	virtual bool        verify(AttributeList *list,bool verbose,TextOutputStream& log,ElementDictionary *dict) const = 0;
+};
+
+CompositeIOD *selectCompositeIOD(AttributeList *list,const char *profile);
+
+#endif /* __Header_iodcomp__ */
+
diff --git a/libsrc/include/dctool/listval.h b/libsrc/include/dctool/listval.h
new file mode 100644
index 0000000..8897ddf
--- /dev/null
+++ b/libsrc/include/dctool/listval.h
@@ -0,0 +1,130 @@
+/* listval.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_listval__
+#define __Header_listval__
+
+/* ************************* Value Lists ************************ */
+
+template<class T> class ValueList;
+template<class T> class ValueListIterator;
+
+template<class T>
+class ValueListEntry {
+private:
+	//friend class ValueList<T>;
+	//friend class ValueListIterator<T>;
+public:		// blech :(
+	T item;
+	ValueListEntry *next;
+};
+
+template<class T>
+class ValueList {
+private:
+	//friend class ValueListIterator<T>;
+	//ValueListEntry<T> *head;
+	
+	unsigned count;
+
+	ValueListEntry<T> *findLast(void)
+		{
+			ValueListEntry<T> *last=0;
+			ValueListEntry<T> *ptr=head;
+			while (ptr) {
+				last=ptr;
+				ptr=ptr->next;
+			}
+			return last;
+		}
+
+	ValueListEntry<T> *findEntry(unsigned index)
+		{
+			if (index >= count || !head) return 0;
+			ValueListEntry<T> *ptr=head;
+			unsigned i=0;
+			while (i++ < index) {
+				ptr=ptr->next;
+			}
+			return ptr;
+		}
+public:
+	ValueListEntry<T> *head;		// blech :(
+
+	ValueList(void)	{ head=0; count=0; }
+	virtual ~ValueList(void)
+		{
+			ValueListEntry<T> *ptr=head;
+			while (ptr) {
+				ValueListEntry<T> *next=ptr->next;
+				delete ptr;
+				ptr=next;
+			}
+		}
+
+	bool	getValue(unsigned index,T& value) const
+		{
+			if (index >= count || !head) return false;
+			const ValueListEntry<T> *ptr=head;
+			unsigned i=0;
+			while (i++ < index) {
+				ptr=ptr->next;
+			}
+			value=ptr->item;
+			return true;
+		}
+
+	void	setValue(unsigned index,T value)
+		{
+			T dummy = 0;
+			while (index >= count) addValue(dummy);
+			ValueListEntry<T> *ptr = findEntry(index);
+			if (ptr) ptr->item=value;
+			// else internal error :(
+		}
+
+	void	addValue(T value)
+		{
+			ValueListEntry<T> *ptr = 
+				new ValueListEntry<T>;
+			ptr->item=value;
+			ptr->next=0;
+			ValueListEntry<T> *last=findLast();
+			if (last) last->next=ptr;
+			else head=ptr;
+			++count;
+		}
+
+	void	addValues(unsigned number,T *vptr)
+		{
+			while (number--) addValue(*vptr++);
+		}
+
+	Uint16	getVM(void) const	{ return count; }
+};
+
+template<class T>
+class ValueListIterator {
+private:
+	ValueListEntry<T> *head;
+	ValueListEntry<T> *ptr;
+public:
+	ValueListIterator(void)
+				{ head=0; ptr=0;}
+
+	ValueListIterator(const ValueList<T>& list)
+				{ head=list.head; ptr=head; }
+
+	void set(ValueList<T>& list)
+				{ head=list.head; ptr=head; }
+	void first(void)	{ ptr=head; }
+	int ismore(void)	{ return ptr != 0; }
+	void next(void)		{ if (ptr) ptr=ptr->next; }
+	T value(void)	        { if (ptr) return ptr->item;
+				  else { T r = 0; return r; } }
+
+	int operator!()		{ return ismore(); }
+	void operator++()	{ next(); }		// prefix  ++i
+	void operator++(int)	{ next(); }		// postfix i++
+	T operator()()		{ return value(); }
+};
+
+#endif /* __Header_listval__ */
diff --git a/libsrc/include/dctool/misctype.h b/libsrc/include/dctool/misctype.h
new file mode 100644
index 0000000..ef08010
--- /dev/null
+++ b/libsrc/include/dctool/misctype.h
@@ -0,0 +1,10 @@
+/* misctype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_misctype__
+#define __Header_misctype__
+
+#include "basetype.h"
+#include "endtype.h"
+
+enum VRType { NoVR,ImplicitVR,ExplicitVR };
+
+#endif /* __Header_misctype__ */
diff --git a/libsrc/include/dctool/module.h b/libsrc/include/dctool/module.h
new file mode 100644
index 0000000..f07b858
--- /dev/null
+++ b/libsrc/include/dctool/module.h
@@ -0,0 +1,16 @@
+/* module.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_module__
+#define __Header_module__
+
+class Module {
+protected:
+	InformationEntity ie;
+public:
+	InformationEntity getInformationEntity() { return ie; }
+	virtual const char *identify(void) const = 0;
+	virtual void        write(TextOutputStream& stream,AttributeList *list,ElementDictionary *dict) const = 0 ;
+	virtual bool        verify(AttributeList *list,AttributeList *parentlist,AttributeList *rootlist,bool verbose,TextOutputStream& log,ElementDictionary *dict) const = 0;
+};
+
+#endif /* __Header_module__ */
+
diff --git a/libsrc/include/dctool/pixposn.h b/libsrc/include/dctool/pixposn.h
new file mode 100644
index 0000000..067cf96
--- /dev/null
+++ b/libsrc/include/dctool/pixposn.h
@@ -0,0 +1,36 @@
+/* pixposn.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_pixposn__
+#define __Header_pixposn__
+
+class PositionOfPixel {
+	TextOutputStream *logp;
+
+	bool havePixelSpacing;
+	Attribute *aPixelSpacing;
+	Float64 vPixelSpacingRow;
+	Float64 vPixelSpacingCol;
+
+	bool haveImagePositionPatient;
+	Attribute *aImagePositionPatient;
+	Float64 vImagePositionPatientX;
+	Float64 vImagePositionPatientY;
+	Float64 vImagePositionPatientZ;
+
+	bool haveImageOrientationPatient;
+	Float64 vImageOrientationPatientRowX;
+	Float64 vImageOrientationPatientRowY;
+	Float64 vImageOrientationPatientRowZ;
+	Float64 vImageOrientationPatientColX;
+	Float64 vImageOrientationPatientColY;
+	Float64 vImageOrientationPatientColZ;
+	Attribute *aImageOrientationPatient;
+
+public:
+	PositionOfPixel(AttributeList &list,TextOutputStream &log,
+		bool verbose=false);
+
+	bool good();
+	bool getPosition(Uint16 row,Uint16 col,Float64 &x,Float64 &y,Float64 &z);
+};
+
+#endif /* __Header_pixposn__ */
diff --git a/libsrc/include/dctool/sopcli.h b/libsrc/include/dctool/sopcli.h
new file mode 100644
index 0000000..201227a
--- /dev/null
+++ b/libsrc/include/dctool/sopcli.h
@@ -0,0 +1,7 @@
+/* sopcli.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_sopcli__
+#define __Header_sopcli__
+
+extern const char *getDirectoryRecordTypeFromUID(const char *uid);
+
+#endif /* __Header_sopcli__ */
diff --git a/libsrc/include/dctool/transyn.h b/libsrc/include/dctool/transyn.h
new file mode 100644
index 0000000..0249375
--- /dev/null
+++ b/libsrc/include/dctool/transyn.h
@@ -0,0 +1,45 @@
+/* transyn.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_transyn__
+#define __Header_transyn__
+
+#include "misctype.h"
+#include "transynu.h"
+
+class TransferSyntax {
+private:
+	const char *		UID;
+	const char *		Description;
+	Endian 			endian;
+	VRType 			VRtype;
+	bool 			encapsulated;
+	Endian 			pixelendian;
+public:	
+	TransferSyntax(const char *uid=DefaultTransferSyntaxUID);
+
+	TransferSyntax(VRType vr,Endian e,bool encap=false);
+
+	const char *	getUID(void) const		{ return UID; }
+	const char *	getDescription(void) const	{ return Description; }
+	Endian		getEndian(void) const		{ return endian; }
+	VRType		getVR(void) const		{ return VRtype; }
+	bool		getEncapsulated(void) const	{ return encapsulated; }
+	Endian		getPixelEndian(void) const	{ return pixelendian; }
+
+	bool	isLittleEndian(void) const	{ return endian == LittleEndian; }
+	bool	isBigEndian(void) const		{ return endian == BigEndian; }
+
+	bool	isPixelLittleEndian(void) const	{ return pixelendian == LittleEndian; }
+	bool	isPixelBigEndian(void) const	{ return pixelendian == BigEndian; }
+
+	bool	isImplicitVR(void) const	{ return VRtype == ImplicitVR; }
+	bool	isExplicitVR(void) const	{ return VRtype == ExplicitVR; }
+
+	bool	isEncapsulated(void) const	{ return encapsulated; }
+	bool	isNotEncapsulated(void) const	{ return !encapsulated; }
+
+	bool	isValid(void) const		{ return UID != 0; }
+
+	bool operator==(const TransferSyntax& t2) const;
+};
+
+#endif /* __Header_transyn__ */
diff --git a/libsrc/include/dctool/transynd.h b/libsrc/include/dctool/transynd.h
new file mode 100644
index 0000000..54bd50a
--- /dev/null
+++ b/libsrc/include/dctool/transynd.h
@@ -0,0 +1,105 @@
+/* transynd.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_transynd__
+#define __Header_transynd__
+
+void
+dumpTransferSyntaxUID(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	if (ts->getUID())
+		cerr << prefix << "UID\t\t"
+		     << ts->getUID() << endl;
+}
+
+void
+dumpTransferSyntaxDescription(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	if (ts->getDescription())
+		cerr << prefix << "Description\t\""
+		     << ts->getDescription() << "\"" << endl;
+}
+
+void
+dumpTransferSyntaxByteOrder(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	cerr << prefix << "ByteOrder\t";
+	switch (ts->getEndian()) {
+		case NoEndian:		cerr << "None"; break;
+		case LittleEndian:	cerr << "Little"; break;
+		case BigEndian:		cerr << "Big"; break;
+		case ByteEndian:	cerr << "Byte"; break;
+		default:		cerr << "**unrecognized**"; break;
+	}
+	cerr << endl;
+
+}
+
+void
+dumpTransferSyntaxPixelByteOrder(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	cerr << prefix << "PixelByteOrder\t";
+	switch (ts->getPixelEndian()) {
+		case NoEndian:		cerr << "None"; break;
+		case LittleEndian:	cerr << "Little"; break;
+		case BigEndian:		cerr << "Big"; break;
+		case ByteEndian:	cerr << "Byte"; break;
+		default:		cerr << "**unrecognized**"; break;
+	}
+	cerr << endl;
+
+}
+
+void
+dumpTransferSyntaxVR(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	cerr << prefix << "VR\t\t";
+	switch (ts->getVR()) {
+		case NoVR:		cerr << "None"; break;
+		case ImplicitVR:	cerr << "Implicit"; break;
+		case ExplicitVR:	cerr << "Explicit"; break;
+		default:		cerr << "**unrecognized**"; break;
+	}
+	cerr << endl;
+}
+
+void
+dumpTransferSyntaxEncapsulation(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	cerr << prefix << "Encapsulated\t"
+	     << (ts->isEncapsulated() ? "Yes" : "No")
+	     << endl;
+}
+
+
+void
+dumpTransferSyntax(TransferSyntax *ts,const char *prefix=0)
+{
+	Assert(ts);
+	if (!prefix) prefix="";
+
+	dumpTransferSyntaxUID(ts,prefix);
+	dumpTransferSyntaxDescription(ts,prefix);
+	dumpTransferSyntaxByteOrder(ts,prefix);
+	dumpTransferSyntaxVR(ts,prefix);
+	dumpTransferSyntaxEncapsulation(ts,prefix);
+
+}
+
+#endif /* __Header_transynd__ */
diff --git a/libsrc/include/dctool/uidgen.h b/libsrc/include/dctool/uidgen.h
new file mode 100644
index 0000000..1222524
--- /dev/null
+++ b/libsrc/include/dctool/uidgen.h
@@ -0,0 +1,272 @@
+/* uidgen.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_uidgen__
+#define __Header_uidgen__
+
+class GeneratedUID {
+	ostrstream ost;
+	char *string;
+	const char *stamp;
+protected:
+	void	setSOPInstance();
+	void	setStudyInstance();
+	void	setSeriesInstance();
+	void	setFrameOfReference();
+	void	setSynchronizationFrameOfReference();
+	void	setDirInstance();
+	void	setDimensionOrganization();
+	void	setConcatenation();
+	void	setIrradiationEvent();
+	void	setRawData();
+	void	setUnsigned(unsigned u);
+public:
+	GeneratedUID(void);
+	GeneratedUID(const char *s);
+	~GeneratedUID();
+	operator char *();
+};
+
+class GeneratedSOPInstanceUID : public GeneratedUID {
+public:
+	GeneratedSOPInstanceUID(void)
+		: GeneratedUID()
+		{
+			setSOPInstance();
+		}
+	GeneratedSOPInstanceUID(const char *s)
+		: GeneratedUID(s)
+		{
+			setSOPInstance();
+		}
+	GeneratedSOPInstanceUID
+			(unsigned study,unsigned series,unsigned instance,int inConcatenationNumber)
+		: GeneratedUID()
+		{
+			setSOPInstance();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(instance);
+			if (inConcatenationNumber != -1) setUnsigned(inConcatenationNumber);
+		}
+	GeneratedSOPInstanceUID
+			(const char *s,unsigned study,unsigned series,unsigned instance,int inConcatenationNumber)
+		: GeneratedUID(s)
+		{
+			setSOPInstance();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(instance);
+			if (inConcatenationNumber != -1) setUnsigned(inConcatenationNumber);
+		}
+};
+
+class GeneratedStudyInstanceUID : public GeneratedUID {
+public:
+	GeneratedStudyInstanceUID(unsigned study)
+		: GeneratedUID()
+		{
+			setStudyInstance();
+			setUnsigned(study);
+		}
+	GeneratedStudyInstanceUID(const char *s,unsigned study)
+		: GeneratedUID(s)
+		{
+			setStudyInstance();
+			setUnsigned(study);
+		}
+};
+
+class GeneratedSeriesInstanceUID : public GeneratedUID {
+public:
+	GeneratedSeriesInstanceUID(unsigned study,unsigned series)
+		: GeneratedUID()
+		{
+			setSeriesInstance();
+			setUnsigned(study);
+			setUnsigned(series);
+		}
+	GeneratedSeriesInstanceUID(const char *s,unsigned study,
+					unsigned series)
+		: GeneratedUID(s)
+		{
+			setSeriesInstance();
+			setUnsigned(study);
+			setUnsigned(series);
+		}
+};
+
+class GeneratedFrameOfReferenceUID : public GeneratedUID {
+public:
+	GeneratedFrameOfReferenceUID(void)
+		: GeneratedUID()
+		{
+			setFrameOfReference();
+		}
+	GeneratedFrameOfReferenceUID(const char *s)
+		: GeneratedUID(s)
+		{
+			setFrameOfReference();
+		}
+	GeneratedFrameOfReferenceUID(unsigned study)
+		: GeneratedUID()
+		{
+			setFrameOfReference();
+			setUnsigned(study);
+		}
+	GeneratedFrameOfReferenceUID(const char *s,unsigned study)
+		: GeneratedUID(s)
+		{
+			setFrameOfReference();
+			setUnsigned(study);
+		}
+	GeneratedFrameOfReferenceUID(unsigned study,unsigned series)
+		: GeneratedUID()
+		{
+			setFrameOfReference();
+			setUnsigned(study);
+			setUnsigned(series);
+		}
+	GeneratedFrameOfReferenceUID(const char *s,unsigned study,
+						unsigned series)
+		: GeneratedUID(s)
+		{
+			setFrameOfReference();
+			setUnsigned(study);
+			setUnsigned(series);
+		}
+};
+
+class GeneratedSynchronizationFrameOfReferenceUID : public GeneratedUID {
+public:
+	GeneratedSynchronizationFrameOfReferenceUID(void)
+		: GeneratedUID()
+		{
+			setSynchronizationFrameOfReference();
+		}
+	GeneratedSynchronizationFrameOfReferenceUID(const char *s)
+		: GeneratedUID(s)
+		{
+			setSynchronizationFrameOfReference();
+		}
+	GeneratedSynchronizationFrameOfReferenceUID(unsigned study)
+		: GeneratedUID()
+		{
+			setSynchronizationFrameOfReference();
+			setUnsigned(study);
+		}
+	GeneratedSynchronizationFrameOfReferenceUID(const char *s,unsigned study)
+		: GeneratedUID(s)
+		{
+			setSynchronizationFrameOfReference();
+			setUnsigned(study);
+		}
+	GeneratedSynchronizationFrameOfReferenceUID(unsigned study,unsigned series)
+		: GeneratedUID()
+		{
+			setSynchronizationFrameOfReference();
+			setUnsigned(study);
+			setUnsigned(series);
+		}
+	GeneratedSynchronizationFrameOfReferenceUID(const char *s,unsigned study,
+						unsigned series)
+		: GeneratedUID(s)
+		{
+			setSynchronizationFrameOfReference();
+			setUnsigned(study);
+			setUnsigned(series);
+		}
+};
+
+class GeneratedDirInstanceUID : public GeneratedUID {
+public:
+	GeneratedDirInstanceUID(void)
+		: GeneratedUID()
+		{
+			setDirInstance();
+		}
+	GeneratedDirInstanceUID(const char *s)
+		: GeneratedUID(s)
+		{
+			setDirInstance();
+		}
+};
+
+class GeneratedDimensionOrganizationUID : public GeneratedUID {
+public:
+	GeneratedDimensionOrganizationUID(unsigned study,unsigned series,int dimensionOrganization)
+		: GeneratedUID()
+		{
+			setDimensionOrganization();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(dimensionOrganization);
+		}
+	GeneratedDimensionOrganizationUID(const char *s,unsigned study,unsigned series,int dimensionOrganization)
+		: GeneratedUID(s)
+		{
+			setDimensionOrganization();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(dimensionOrganization);
+		}
+};
+
+class GeneratedConcatenationUID : public GeneratedUID {
+public:
+	GeneratedConcatenationUID(unsigned study,unsigned series,unsigned instance)
+		: GeneratedUID()
+		{
+			setConcatenation();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(instance);
+		}
+	GeneratedConcatenationUID(const char *s,unsigned study,unsigned series,unsigned instance)
+		: GeneratedUID(s)
+		{
+			setConcatenation();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(instance);
+		}
+};
+
+class GeneratedRawDataUID : public GeneratedUID {
+public:
+	GeneratedRawDataUID(unsigned study,unsigned acquisition)
+		: GeneratedUID()
+		{
+			setRawData();
+			setUnsigned(study);
+			setUnsigned(acquisition);
+		}
+	GeneratedRawDataUID(const char *s,unsigned study,unsigned acquisition)
+		: GeneratedUID(s)
+		{
+			setRawData();
+			setUnsigned(study);
+			setUnsigned(acquisition);
+		}
+};
+
+class GeneratedIrradiationEventUID : public GeneratedUID {
+public:
+	GeneratedIrradiationEventUID(unsigned study,unsigned series,unsigned instance)
+		: GeneratedUID()
+		{
+			setIrradiationEvent();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(instance);
+		}
+	GeneratedIrradiationEventUID(const char *s,unsigned study,unsigned series,unsigned instance)
+		: GeneratedUID(s)
+		{
+			setIrradiationEvent();
+			setUnsigned(study);
+			setUnsigned(series);
+			setUnsigned(instance);
+		}
+};
+
+#endif /* __Header_uidgen__ */
+
diff --git a/libsrc/include/dctool/vr.h b/libsrc/include/dctool/vr.h
new file mode 100644
index 0000000..a0e9ada
--- /dev/null
+++ b/libsrc/include/dctool/vr.h
@@ -0,0 +1,209 @@
+/* attr.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// utility methods for value representation
+
+#ifndef __Header_vr__
+#define __Header_vr__
+
+static bool isAgeStringVR(const char *vr) { return vr && vr[0]=='A' &&  vr[1]=='S'; }
+
+static bool isAttributeTagVR(const char *vr) { return vr && vr[0]=='A' &&  vr[1]=='T'; }
+
+static bool isDateStringVR(const char *vr) { return vr && vr[0]=='D' &&  vr[1]=='A'; }
+
+static bool isDateTimeStringVR(const char *vr) { return vr && vr[0]=='D' &&  vr[1]=='T'; }
+
+static bool isOtherUnspecifiedVR(const char *vr) { return vr && vr[0]=='O' && vr[1]=='X'; }
+
+static bool isOtherDoubleVR(const char *vr) { return vr && vr[0]=='O' && vr[1]=='D'; }
+
+static bool isOtherFloatVR(const char *vr) { return vr && vr[0]=='O' && vr[1]=='F'; }
+
+static bool isOtherLongVR(const char *vr) { return vr && vr[0]=='O' && vr[1]=='L'; }
+
+static bool isOtherByteVR(const char *vr) { return vr && vr[0]=='O' && vr[1]=='B'; }
+
+static bool isSequenceVR(const char *vr) { return vr && vr[0]=='S' &&  vr[1]=='Q'; }
+
+static bool isTimeStringVR(const char *vr) { return vr && vr[0]=='T' &&  vr[1]=='M'; }
+
+static bool isUIStringVR(const char *vr) { return vr && vr[0]=='U' &&  vr[1]=='I'; }
+
+static bool isUniversalResourceVR(const char *vr) { return vr && vr[0]=='U' &&  vr[1]=='R'; }
+
+static bool isUnknownVR(const char *vr) { return vr && vr[0]=='U' &&  vr[1]=='N'; }
+
+static bool isUnlimitedCharactersVR(const char *vr) { return vr && vr[0]=='U' &&  vr[1]=='C'; }
+
+static bool isUnlimitedTextVR(const char *vr) { return vr && vr[0]=='U' &&  vr[1]=='T'; }
+
+static bool isOtherByteOrWordOrUnspecifiedVR(const char *vr) { return vr && vr[0]=='O' && (vr[1]=='B' || vr[1]=='W' || vr[1]=='X'); }
+
+static bool isOtherByteOrLongOrWordOrFloatOrDoubleVR(const char *vr) { return vr && vr[0]=='O' && (vr[1]=='B' || vr[1]=='D' || vr[1]=='F' || vr[1]=='L' || vr[1]=='W' || vr[1]=='X'); }
+
+// use strncmp throughout, because might have passed fixed length array of 2 characters that is not null terminated ...
+
+static bool
+isLongValueLengthInExplicitValueRepresentation(const char *vr) {
+	// Check for known short form VRs, rather than known long form VRs, since all new VRs will be long form, in case we encounter unrecognized one
+	// but be sure and check that there really is a VR present
+	return  vr && vr[0] != 0 && vr[1] != 0 && (
+			strncmp(vr,"AE",2) != 0
+		 && strncmp(vr,"AS",2) != 0
+		 && strncmp(vr,"AT",2) != 0
+		 && strncmp(vr,"CS",2) != 0
+		 && strncmp(vr,"DA",2) != 0
+		 && strncmp(vr,"DS",2) != 0
+		 && strncmp(vr,"DT",2) != 0
+		 && strncmp(vr,"FD",2) != 0
+		 && strncmp(vr,"FL",2) != 0
+		 && strncmp(vr,"IS",2) != 0
+		 && strncmp(vr,"LO",2) != 0
+		 && strncmp(vr,"LT",2) != 0
+		 && strncmp(vr,"PN",2) != 0
+		 && strncmp(vr,"SH",2) != 0
+		 && strncmp(vr,"SL",2) != 0
+		 && strncmp(vr,"SS",2) != 0
+		 && strncmp(vr,"ST",2) != 0
+		 && strncmp(vr,"TM",2) != 0
+		 && strncmp(vr,"UI",2) != 0
+		 && strncmp(vr,"UL",2) != 0
+		 && strncmp(vr,"US",2) != 0
+		);
+}
+
+static bool
+isKnownExplicitValueRepresentation(const char *vr) {
+	return vr && (
+		   strncmp(vr,"AE",2) == 0
+		|| strncmp(vr,"AS",2) == 0
+		|| strncmp(vr,"AT",2) == 0
+		|| strncmp(vr,"CS",2) == 0
+		|| strncmp(vr,"DA",2) == 0
+		|| strncmp(vr,"DS",2) == 0
+		|| strncmp(vr,"DT",2) == 0
+		|| strncmp(vr,"FL",2) == 0
+		|| strncmp(vr,"FD",2) == 0
+		|| strncmp(vr,"IS",2) == 0
+		|| strncmp(vr,"LO",2) == 0
+		|| strncmp(vr,"LT",2) == 0
+		|| strncmp(vr,"OB",2) == 0
+		|| strncmp(vr,"OD",2) == 0
+		|| strncmp(vr,"OF",2) == 0
+		|| strncmp(vr,"OL",2) == 0
+		|| strncmp(vr,"OW",2) == 0
+		|| strncmp(vr,"PN",2) == 0
+		|| strncmp(vr,"SH",2) == 0
+		|| strncmp(vr,"SL",2) == 0
+		|| strncmp(vr,"SQ",2) == 0
+		|| strncmp(vr,"SS",2) == 0
+		|| strncmp(vr,"ST",2) == 0
+		|| strncmp(vr,"TM",2) == 0
+		|| strncmp(vr,"UI",2) == 0
+		|| strncmp(vr,"UL",2) == 0
+		|| strncmp(vr,"UN",2) == 0
+		|| strncmp(vr,"UR",2) == 0
+		|| strncmp(vr,"US",2) == 0
+		|| strncmp(vr,"UT",2) == 0
+		);
+}
+
+static bool
+isStringVR(const char *vr)
+{
+	return vr &&
+		(  strncmp(vr,"AE",2) == 0
+		|| strncmp(vr,"AS",2) == 0
+		|| strncmp(vr,"CS",2) == 0
+		|| strncmp(vr,"DA",2) == 0
+		|| strncmp(vr,"DT",2) == 0
+		|| strncmp(vr,"DS",2) == 0
+		|| strncmp(vr,"IS",2) == 0
+		|| strncmp(vr,"LO",2) == 0
+		|| strncmp(vr,"LT",2) == 0
+		|| strncmp(vr,"PN",2) == 0
+		|| strncmp(vr,"SH",2) == 0
+		|| strncmp(vr,"ST",2) == 0
+		|| strncmp(vr,"TM",2) == 0
+		|| strncmp(vr,"UC",2) == 0
+		|| strncmp(vr,"UI",2) == 0
+		|| strncmp(vr,"UR",2) == 0
+		|| strncmp(vr,"UT",2) == 0);
+}
+
+
+static bool
+isNonOtherNumericOrDateOrTimeOrUIStringVR(const char *vr)
+{
+	return vr &&
+		(  strncmp(vr,"DA",2) == 0
+		|| strncmp(vr,"DT",2) == 0
+		|| strncmp(vr,"DS",2) == 0
+		|| strncmp(vr,"IS",2) == 0
+		|| strncmp(vr,"TM",2) == 0
+		|| strncmp(vr,"UI",2) == 0);
+}
+
+static bool
+isNumericVR(const char *vr)
+{
+	return vr &&
+		(  strncmp(vr,"OB",2) == 0
+		|| strncmp(vr,"OL",2) == 0
+		|| strncmp(vr,"OW",2) == 0
+		|| strncmp(vr,"OX",2) == 0
+		|| strncmp(vr,"SL",2) == 0
+		|| strncmp(vr,"SS",2) == 0
+		|| strncmp(vr,"UL",2) == 0
+		|| strncmp(vr,"US",2) == 0
+		|| strncmp(vr,"XL",2) == 0
+		|| strncmp(vr,"XS",2) == 0);
+}
+
+static bool
+isFloatVR(const char *vr)
+{
+	return vr &&
+		(  strncmp(vr,"FL",2) == 0
+		|| strncmp(vr,"FD",2) == 0
+		|| strncmp(vr,"OD",2) == 0
+		|| strncmp(vr,"OF",2) == 0);
+}
+
+static size_t
+sizeofNumericVR(const char *vr)
+{
+	if (     strncmp(vr,"OB",2) == 0
+	      || strncmp(vr,"OX",2) == 0)
+		return 1;
+	else if (strncmp(vr,"OW",2) == 0
+	      || strncmp(vr,"US",2) == 0
+	      || strncmp(vr,"SS",2) == 0
+	      || strncmp(vr,"XS",2) == 0)
+		return 2;
+	else if (strncmp(vr,"OL",2) == 0
+	      || strncmp(vr,"SL",2) == 0
+	      || strncmp(vr,"UL",2) == 0
+	      || strncmp(vr,"XL",2) == 0)
+		return 4;
+	else {
+		Assert(0);
+	}
+	return 0;	// never gets here but prevents warning
+}
+
+static size_t
+sizeofFloatVR(const char *vr)
+{
+	if (     strncmp(vr,"FL",2) == 0
+	      || strncmp(vr,"OF",2) == 0)
+		return 4;
+	else if (strncmp(vr,"FD",2) == 0
+	      || strncmp(vr,"OD",2) == 0)
+		return 8;
+	else {
+		Assert(0);
+	}
+	return 0;	// never gets here but prevents warning
+}
+
+#endif // __Header_vr__
diff --git a/libsrc/include/dculsp/dculsp.h b/libsrc/include/dculsp/dculsp.h
new file mode 100644
index 0000000..735de95
--- /dev/null
+++ b/libsrc/include/dculsp/dculsp.h
@@ -0,0 +1,184 @@
+/* dculsp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+class PresentationAddress
+{
+public:
+
+	virtual bool isTCP(void)				{ return false; }
+	virtual class TcpPresentationAddress *castToTCP(void)	{ Assert(0); return 0; }
+};
+
+class TcpPresentationAddress : public PresentationAddress
+{
+public:
+
+	bool isTCP(void)				{ return true; }
+	class TcpPresentationAddress *castToTCP(void)	{return this; }
+};
+
+class UserInformationItem
+{
+};
+
+class PresentationContextDefinitionList
+{
+};
+
+class PresentationDataValueList
+{
+};
+
+class TransportLayerServiceRequestor
+{
+public:
+	TransportLayerServiceRequestor(void);
+	virtual ~TransportLayerServiceRequestor(void);
+
+	virtual void T_Connect_Request		(PresentationAddress& callingpresentationaddress,
+						 PresentationAddress& calledpresentationaddress) 	{ Assert(0); }
+
+	virtual void T_Connect_Confirm		(void) 							= 0;
+
+	virtual void T_Data_Request(PDU)	{ Assert(0); }
+	virtual void T_Data_Indication(PDU)	{ Assert(0); }
+};
+
+class TransportLayerServiceAcceptor
+{
+	TransportLayerServiceAcceptor(void);
+	virtual ~TransportLayerServiceAcceptor(void);
+
+	virtual void T_Connect_Indication	(PresentationAddress& callingpresentationaddress,
+				 		 PresentationAddress& calledpresentationaddress)	= 0;
+
+	virtual void T_Connect_Response		(void) 						 	{ Assert(0); }
+
+	virtual void T_Data_Request(PDU)	{ Assert(0); }
+	virtual void T_Data_Indication(PDU)	{ Assert(0); }
+};
+
+class TcpTransportLayerServiceRequestor : public virtual TransportLayerServiceRequestor
+{
+public:
+	TcpTransportLayerServiceRequestor(void);
+	virtual ~TcpTransportLayerServiceRequestor(void);
+
+	        void T_Connect_Request		(PresentationAddress& callingpresentationaddress,
+						 PresentationAddress& calledpresentationaddress);
+
+	virtual void T_Data_Request(PDU)	{ Assert(0); }
+	virtual void T_Data_Indication(PDU)	{ Assert(0); }
+};
+
+class TcpTransportLayerServiceAcceptor : public virtual TransportLayerServiceAcceptor
+{
+	TcpTransportLayerServiceAcceptor(void);
+	virtual ~TcpTransportLayerServiceAcceptor(void);
+
+	        void T_Connect_Response		(void);
+
+	virtual void T_Data_Request(PDU)	{ Assert(0); }
+	virtual void T_Data_Indication(PDU)	{ Assert(0); }
+};
+
+//
+//		       DICOM UL
+//		       Service
+//		       Provider
+//
+//	  request    |         |  indication
+//	-----------> | Message | ---------->
+//	             |         |
+//	<----------- | Message | <----------
+//	confirmation |         |  response
+//	            SAP       SAP
+//	
+//	 Requestor		  Acceptor
+
+// the pure virtual methods are callbacks to be supplied
+// by the using class derived from the base class
+
+
+class DICOMUpperLayerServiceRequestor : public virtual TransportLayerServiceRequestor {
+private:
+	int state;
+
+	const char *applicationcontextname;
+	const char *callingapplicationentitytitle;
+	const char *calledapplicationentitytitle;
+	UserInformationItem *userinformationitem;
+	PresentationAddress *callingpresentationaddress;
+	PresentationAddress *calledpresentationaddress;
+	PresentationContextDefinitionList *presentationcontextdefinitionlist;
+
+	       void T_Confirm	(void);
+public:
+	DICOMUpperLayerServiceRequestor(void);
+	virtual ~DICOMUpperLayerServiceRequestor();
+
+	        void A_Associate_Request	(const char *applicationcontextname,		// requestor to provider
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlist
+						);
+
+	virtual void A_Associate_Confirm	(const char *applicationcontextname,		// provider  to requestor
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 Uint16 result,
+						 Uint16 resultsource,
+						 Uint16 diagnostic,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlistresult
+						) = 0;
+
+	        void A_Release_Request		(Uint16 reason);				// requestor to provider
+
+	virtual void A_Release_Confirm	(Uint16 reason,Uint16 result) = 0;		// provider  to requestor
+
+	        void A_Abort_Request		(void);						// requestor to provider
+ 
+	virtual void A_P_Abort_Indication	(Uint16 reason) = 0;				// provider  to both
+
+	        void P_Data_Request		(PresentationDataValueList &data);		// requestor to provider
+ };
+
+class DICOMUpperLayerServiceAcceptor : public virtual TransportLayerServiceAcceptor {
+public:
+	DICOMUpperLayerServiceAcceptor(void);
+	virtual ~DICOMUpperLayerServiceAcceptor();
+
+	virtual void A_Associate_Indication	(const char *applicationcontextname,		// provider  to acceptor
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlist
+						) = 0;
+
+	        void A_Associate_Response	(const char *applicationcontextname,		// acceptor  to provider
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 Uint16 result,
+						 Uint16 diagnostic,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlistresult
+						);
+
+	virtual void A_Release_Indication	(Uint16 reason) = 0;				// provider  to acceptor 
+	        void A_Release_Response		(Uint16 reason,Uint16 result);			// acceptor  to provider
+
+	virtual void A_Abort_Indication		(Uint16 source) = 0;				// provider  to acceptor
+ 
+	virtual void A_P_Abort_Indication	(Uint16 reason) = 0;				// provider  to both
+
+	virtual void P_Data_Indication		(PresentationDataValueList &data) = 0;		// provider  to acceptor
+ };
+
diff --git a/libsrc/include/generic/Imakefile b/libsrc/include/generic/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/include/generic/basetype.h b/libsrc/include/generic/basetype.h
new file mode 100644
index 0000000..3fda40c
--- /dev/null
+++ b/libsrc/include/generic/basetype.h
@@ -0,0 +1,122 @@
+/* basetype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_basetype__
+#define __Header_basetype__
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <time.h>
+
+#ifdef __SC__
+#include <types.h>           // has an enum for false and true
+#define	NOBOOLEANTYPE
+#define NOINCLUDESUBDIRECTORIES
+#endif /* __SC__ */
+
+#ifdef __MWERKS__
+#define NOBOOLEANTYPE
+#define NOINCLUDESUBDIRECTORIES
+#define ANSILIBRARYPUBSEEK
+#endif /* __MWERKS__ */
+
+#ifdef __BORLANDC__
+#define	NOBOOLEANTYPE
+#define	NOBOOLEANVALUES
+#endif /* __BORLANDC__ */
+
+#ifdef NOBOOLEANTYPE
+typedef short int bool;
+#endif /* NOBOOLEANTYPE */
+
+#ifdef NOBOOLEANVALUES
+const bool false = 0;
+const bool true = 1;
+#endif /* NOBOOLEANVALUES */
+
+#if HASGETHOSTID == 0
+static inline long gethostid(void) { return 0; }
+#else
+#if HASGETHOSTIDPROTOTYPE == 0
+extern long gethostid(void);
+#endif /* HASGETHOSTIDPROTOTYPE */
+#endif /* HASGETHOSTID */
+
+#ifdef ANSILIBRARYPUBSEEK
+#ifndef PubSeekPos
+#define PubSeekPos	pubseekpos
+#endif
+#ifndef PubSeekOff
+#define PubSeekOff	pubseekoff
+#endif
+#else
+#ifndef PubSeekPos
+#define PubSeekPos	seekpos
+#endif
+#ifndef PubSeekOff
+#define PubSeekOff	seekoff
+#endif
+#endif /* ANSILIBRARYPUBSEEK */
+
+#ifndef PubSeekBad
+#define PubSeekBad	OurStreamPos(-1)
+#endif
+
+#if HASSTDNAMESPACEFORSTREAMPOS == 1
+#define OurStreamPos	std::streampos
+#define OurStreamOff	std::streamoff
+#define OurSeekDir	std::ios::seekdir
+#else
+#define OurStreamPos	streampos
+#define OurStreamOff	streamoff
+#define OurSeekDir	seek_dir
+#endif
+
+#include <assert.h>
+
+#define Assert(expr)	assert(expr)	// In case we get more creative later !
+
+// The following basic types for internal use, and
+// must be at least long enough to represent the
+// expected value range without loss of accuracy
+// but may be longer.
+
+// They should be distinct else stream insertors
+// will be ambiguous
+
+typedef unsigned char   Uint8;
+typedef unsigned short	Uint16;
+typedef unsigned long	Uint32;
+typedef unsigned long long Uint64;
+typedef signed char     Int8;
+typedef signed short	Int16;
+typedef signed long	Int32;
+typedef signed long long Int64;
+typedef float		Float32;
+typedef double		Float64;
+
+// These limits may not actually be true, but are desirable ...
+
+#define	Uint8_MAX	 0xFF
+#define	Uint16_MAX	 0xFFFF
+#define	Uint32_MAX	 0xFFFFFFFF
+#define	Int8_MIN	-0x80
+#define	Int8_MAX	 0x7F
+#define	Int16_MIN	-0x8000
+#define	Int16_MAX	 0x7FFF
+#define	Int32_MIN	-0x80000000
+#define	Int32_MAX	 0x7FFFFFFF
+
+#if defined(__GNUC__)  && __GNUC__ >= 3
+#include <backward/strstream>
+using std::istrstream;
+using std::ostrstream;
+#else
+#include <strstream.h>
+#endif
+
+#include <math.h>
+
+static inline double ourlog2(double x) { return log(x)/log(2); }
+
+#endif /* __Header_basetype__ */
diff --git a/libsrc/include/generic/bnchar.h b/libsrc/include/generic/bnchar.h
new file mode 100644
index 0000000..8447a68
--- /dev/null
+++ b/libsrc/include/generic/bnchar.h
@@ -0,0 +1,98 @@
+/* bnchar.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_bnchar__
+#define __Header_bnchar__
+
+#include "basetype.h"
+#include "endtype.h"
+
+static inline
+Uint16 extract16(const unsigned char *buffer,Endian endian)
+{
+	Assert(endian!=NoEndian);
+	Uint16 u;
+	if (endian == BigEndian) {
+		u =  (Uint16)buffer[0];
+		u <<= 8;
+		u |= (Uint16)buffer[1];
+	}
+	else {
+		u =  (Uint16)buffer[1];
+		u <<= 8;
+		u |= (Uint16)buffer[0];
+	}
+	return u;
+}
+
+static inline
+Uint32 extract32(const unsigned char *buffer,Endian endian)
+{
+	Assert(endian!=NoEndian);
+	Uint32 u;
+	if (endian == BigEndian) {
+		u =  (Uint32)buffer[0];
+		u <<= 8;
+		u |= (Uint32)buffer[1];
+		u <<= 8;
+		u |= (Uint32)buffer[2];
+		u <<= 8;
+		u |= (Uint32)buffer[3];
+	}
+	else {
+		u =  (Uint32)buffer[3];
+		u <<= 8;
+		u |= (Uint32)buffer[2];
+		u <<= 8;
+		u |= (Uint32)buffer[1];
+		u <<= 8;
+		u |= (Uint32)buffer[0];
+	}
+	return u;
+}
+
+static inline
+void insert16(Uint16 u,unsigned char *buffer,Endian endian)
+{
+	Assert(endian!=NoEndian);
+	if (endian == BigEndian) {
+		buffer[0]=(unsigned char)(u>>8);
+		buffer[1]=(unsigned char)u;
+	}
+	else {
+		buffer[1]=(unsigned char)(u>>8);
+		buffer[0]=(unsigned char)u;
+	}
+}
+
+static inline
+void insert32(Uint32 u,unsigned char *buffer,Endian endian)
+{
+	Assert(endian!=NoEndian);
+	if (endian == BigEndian) {
+		buffer[0]=(unsigned char)(u>>24);
+		buffer[1]=(unsigned char)(u>>16);
+		buffer[2]=(unsigned char)(u>>8);
+		buffer[3]=(unsigned char)u;
+	}
+	else {
+		buffer[3]=(unsigned char)(u>>24);
+		buffer[2]=(unsigned char)(u>>16);
+		buffer[1]=(unsigned char)(u>>8);
+		buffer[0]=(unsigned char)u;
+	}
+}
+
+static inline
+void insert16incr(Uint16 u,unsigned char *&buffer,Endian endian)
+{
+	insert16(u,buffer,endian);
+	buffer+=2;
+}
+
+static inline
+void insert32incr(Uint32 u,unsigned char *&buffer,Endian endian)
+{
+	insert32(u,buffer,endian);
+	buffer+=4;
+}
+
+#endif /* __Header_bnchar__ */
diff --git a/libsrc/include/generic/bnopt.h b/libsrc/include/generic/bnopt.h
new file mode 100644
index 0000000..cae8127
--- /dev/null
+++ b/libsrc/include/generic/bnopt.h
@@ -0,0 +1,68 @@
+/* bnopt.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_bnopt__
+#define __Header_bnopt__
+
+#include "getoptns.h"
+
+class BinaryInputOptions : public ErrorsInClass
+{
+public:
+	const char *	filename;
+
+	BinaryInputOptions(GetNamedOptions &options);
+	virtual char *usage(void);
+	virtual void done(void);
+};
+
+class BinaryInputOptionsWithByteOrder : public BinaryInputOptions
+{
+public:
+	Endian byteorder;
+
+	BinaryInputOptionsWithByteOrder(GetNamedOptions &options);
+	char *usage(void);
+};
+
+class BinaryOutputOptions : public ErrorsInClass
+{
+public:
+	const char *	filename;
+
+	BinaryOutputOptions(GetNamedOptions &options);
+	char *usage(void);
+	void done(void);
+};
+
+class BinaryOutputOptionsWithByteOrder : public BinaryOutputOptions
+{
+public:
+	Endian byteorder;
+
+	BinaryOutputOptionsWithByteOrder(GetNamedOptions &options);
+	char *usage(void);
+};
+
+class BinaryInputOpenerFromOptions : public ErrorsInClass {
+	istream *str;
+public:
+	BinaryInputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename,istream &cstr);
+
+	~BinaryInputOpenerFromOptions();
+
+	operator istream *(void);
+};
+
+class BinaryOutputOpenerFromOptions : public ErrorsInClass {
+	ostream *str;
+public:
+	BinaryOutputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename,ostream &cstr);
+
+	~BinaryOutputOpenerFromOptions();
+
+	operator ostream *(void);
+};
+
+#endif /* __Header_bnopt__ */
+
diff --git a/libsrc/include/generic/bnstream.h b/libsrc/include/generic/bnstream.h
new file mode 100644
index 0000000..d073772
--- /dev/null
+++ b/libsrc/include/generic/bnstream.h
@@ -0,0 +1,241 @@
+/* bnstream.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_bnstream__
+#define __Header_bnstream__
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+//#include <iomanip>
+#else
+#include <iostream.h>
+//#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "endtype.h"
+
+// Note that great care has to be taken adding insert and
+// extract operators as these classes (and any derived classes)
+// are themselves derived from iostream classes which DO NOT
+// define insert and extract methods as virtual, so method
+// calls from base objects will NOT call the derived objects
+// methods
+
+// Furthermore, as iostream classes declare the operators as
+// methods of the classes rather than global functions, then
+// they can not be overloaded with replacement global functions
+// or an ambiguity arises, hence the classes here MUST KNOW ABOUT
+// the objects that are inserted or extracted, hence the
+// need for forward declarations (blech :( ).
+
+// Finally, if such operators are declared here, then those of
+// the base class become invisible, hence useful guys like
+// operator<<(const char *) need to be passed on.
+
+class Tag;	// for operator<<() and operator>>()
+
+class BinaryInputStream : public istream {
+private:
+	Endian endian;
+	char buffer[4];
+	bool swapped32big;
+public:
+	BinaryInputStream(streambuf *buf,Endian e=NoEndian)
+		: istream(buf)
+		{ endian=e; swapped32big=false; }
+
+	BinaryInputStream(istream& istr,Endian e=NoEndian)
+		: istream(istr.rdbuf())
+		{ endian=e; swapped32big=false; }
+
+	virtual ~BinaryInputStream(void)	{}
+
+	bool 	isBigEndian(void)	{ return endian == BigEndian; }
+	bool 	isLittleEndian(void)	{ return endian == LittleEndian; }
+	bool	isSwapped32Big(void)	{ return swapped32big; }
+	Endian 	getEndian(void)				{ return endian; }
+	void 	setEndian(Endian e=LittleEndian)	{ endian=e; }
+	void	setSwapped32Big(void)			{ swapped32big=true; }
+
+	unsigned char read8(void)
+		{
+			Assert(endian!=NoEndian);
+			char u;
+			read(&u,1);
+			return (unsigned char)u;
+		}
+	Uint16 read16(void)
+		{
+			Assert(endian!=NoEndian);
+			Uint16 u;
+			read(buffer,2);
+			if (isBigEndian()) {
+				u =  (Uint16)((unsigned char *)buffer)[0];
+				u <<= 8;
+				u |= (Uint16)((unsigned char *)buffer)[1];
+			}
+			else {
+				u =  (Uint16)((unsigned char *)buffer)[1];
+				u <<= 8;
+				u |= (Uint16)((unsigned char *)buffer)[0];
+			}
+			return u;
+		}
+	Uint32 read32(void)
+		{
+			Assert(endian!=NoEndian);
+			Uint32 u;
+			read(buffer,4);
+			if (isBigEndian()) {
+				if (swapped32big) {
+					u =  (Uint32)((unsigned char *)buffer)[2];
+					u <<= 8;
+					u |= (Uint32)((unsigned char *)buffer)[3];
+					u <<= 8;
+					u |= (Uint32)((unsigned char *)buffer)[0];
+					u <<= 8;
+					u |= (Uint32)((unsigned char *)buffer)[1];
+				}
+				else {
+					u =  (Uint32)((unsigned char *)buffer)[0];
+					u <<= 8;
+					u |= (Uint32)((unsigned char *)buffer)[1];
+					u <<= 8;
+					u |= (Uint32)((unsigned char *)buffer)[2];
+					u <<= 8;
+					u |= (Uint32)((unsigned char *)buffer)[3];
+				}
+			}
+			else {
+				u =  (Uint32)((unsigned char *)buffer)[3];
+				u <<= 8;
+				u |= (Uint32)((unsigned char *)buffer)[2];
+				u <<= 8;
+				u |= (Uint32)((unsigned char *)buffer)[1];
+				u <<= 8;
+				u |= (Uint32)((unsigned char *)buffer)[0];
+			}
+			return u;
+		}
+
+	BinaryInputStream& operator>>(Uint8& rhs)
+		{
+			rhs=(Uint8)read8();
+			return *this;
+		}
+	BinaryInputStream& operator>>(Uint16& rhs)
+		{
+			rhs=read16();
+			return *this;
+		}
+	BinaryInputStream& operator>>(Uint32& rhs)
+		{
+			rhs=read32();
+			return *this;
+		}
+	BinaryInputStream& operator>>(Tag& rhs);	// in attrtag.cc
+
+//	istream& seekg(OurStreamPos p)
+//              {
+//			Assert(0);	// Too unportable to be used
+//			(void)p;
+//			return *this;
+//              }
+//	istream& seekg(OurStreamOff o,OurSeekDir d)
+//              {
+//			Assert(0);	// Too unportable to be used
+//			(void)o; (void)d;
+//			return *this;
+//              }
+};
+
+class BinaryOutputStream : public ostream {
+private:
+	Endian endian;
+	unsigned char buffer[4];
+public:
+	BinaryOutputStream(streambuf *buf,Endian e=NoEndian)
+		: ostream(buf)
+		{ endian=e; }
+
+	BinaryOutputStream(ostream &ostr,Endian e=NoEndian)
+		: ostream(ostr.rdbuf())
+		{ endian=e; }
+
+	virtual ~BinaryOutputStream(void)	{}
+
+	bool 	isBigEndian(void)	{ return endian == BigEndian; }
+	bool 	isLittleEndian(void)	{ return endian == LittleEndian; }
+	Endian 	getEndian(void)				{ return endian; }
+	void 	setEndian(Endian e=LittleEndian)	{ endian=e; }
+
+	void write8(unsigned char u)
+		{
+			Assert(endian!=NoEndian);
+			write((char *)&u,1);
+		}
+	void write16(Uint16 u)
+		{
+			Assert(endian!=NoEndian);
+			if (isBigEndian()) {
+				buffer[0]=(unsigned char)(u>>8);
+				buffer[1]=(unsigned char)u;
+			}
+			else {
+				buffer[1]=(unsigned char)(u>>8);
+				buffer[0]=(unsigned char)u;
+			}
+			write((char *)buffer,2);
+		}
+	void write32(Uint32 u)
+		{
+			Assert(endian!=NoEndian);
+			if (isBigEndian()) {
+				buffer[0]=(unsigned char)(u>>24);
+				buffer[1]=(unsigned char)(u>>16);
+				buffer[2]=(unsigned char)(u>>8);
+				buffer[3]=(unsigned char)u;
+			}
+			else {
+				buffer[3]=(unsigned char)(u>>24);
+				buffer[2]=(unsigned char)(u>>16);
+				buffer[1]=(unsigned char)(u>>8);
+				buffer[0]=(unsigned char)u;
+			}
+			write((char *)buffer,4);
+		}
+
+	BinaryOutputStream& operator<<(Uint8 rhs)
+		{
+			write8((unsigned char)rhs);
+			return *this;
+		}
+	BinaryOutputStream& operator<<(Uint16 rhs)
+		{
+			write16(rhs);
+			return *this;
+		}
+	BinaryOutputStream& operator<<(Uint32 rhs)
+		{
+			write32(rhs);
+			return *this;
+		}
+	BinaryOutputStream& operator<<(Tag rhs);	// in attrtag.cc
+
+	BinaryOutputStream& operator<<(const char *string)
+		{
+			((ostream &)*this) << string;
+			return *this;
+		}
+
+	BinaryOutputStream& operator<<(char c)
+		{
+			((ostream &)*this) << c;
+			return *this;
+		}
+};
+
+#endif /* __Header_bnstream__ */
diff --git a/libsrc/include/generic/buffer.h b/libsrc/include/generic/buffer.h
new file mode 100644
index 0000000..5e2af62
--- /dev/null
+++ b/libsrc/include/generic/buffer.h
@@ -0,0 +1,140 @@
+/* buffer.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_buffer__
+#define __Header_buffer__
+
+#ifndef DEFAULTMINIMUMBUFFERSIZE
+#define DEFAULTMINIMUMBUFFERSIZE 512
+#endif
+
+template<class T>
+class Buffer {
+protected:
+	T *head;
+	size_t size;
+	size_t count;
+	size_t minimum;
+public:
+	Buffer(void)
+		{
+			//cerr << "Buffer<T>::Buffer()\n" << flush;
+			head=0;
+			size=0;
+			count=0;
+			minimum=DEFAULTMINIMUMBUFFERSIZE;
+		}
+
+	Buffer(size_t m)
+		{
+			//cerr << "Buffer<T>::Buffer()\n" << flush;
+			head=0;
+			size=0;
+			count=0;
+			minimum=m;
+		}
+
+	virtual ~Buffer(void)
+		{
+			if (head) delete[] head;
+		}
+
+	void clear(void)
+		{
+			count=0;
+		}
+
+	void extend(size_t reqsize)
+		{
+			//cerr << "Buffer<T>::extend\n" << flush;
+			if (reqsize > size) {
+				size_t newsize=size;
+				while (newsize < reqsize) newsize+=minimum;
+				//cerr << "Buffer<T>::extend from "
+				//     << dec << size << " requested " << reqsize
+				//     << " actual " << newsize
+				//     << "\n" << flush;
+				T *oldhead=head;
+				head=new T[newsize];
+				size=newsize;
+				if (oldhead) {
+					if(count)
+						memcpy((char *)head,
+						       (char *)oldhead,
+						       count*sizeof(T));
+					delete[] oldhead;
+				}
+			}
+		}
+
+	void add(const T *values,size_t n)
+		{
+			//cerr << "Buffer<T>::add(T *values,size_t n)\n" << flush;
+			extend(count+n);
+			memcpy((char *)(head+count),(char*)values,n*sizeof(T));
+			count+=n;
+		}
+
+	void add(T value)
+		{
+			//cerr << "Buffer<T>::add(T value) = "
+			//     << dec << (unsigned long)value
+			//     << " 0x" << hex << (unsigned long)value
+			//     << "\n" << flush;
+			extend(count+1);
+			head[count++]=value;
+		}
+
+	void operator+=(T value)
+		{
+			//cerr << "Buffer<T>::operator+=\n" << flush;
+			add(value);
+		}
+
+	size_t getSize(void) const		{ return size; }
+	size_t getCount(void) const		{ return count; }
+	void   setCount(size_t n)		{ count=n; }
+	T * getValues(void)			{ return head; }
+
+	// NB. Allowing this internal access facilitates reading directly
+	// into buffers for example, without copying, eg.
+	//
+	//	istream istr;
+	//	buffer.clear(); buffer.extend(n);
+	//	istr.read(buffer.getValues(),n);
+	//	buffer.setCount(istr.gcount());
+};
+
+template<class T>
+class BufferIterator {
+protected:
+	Buffer<T> *buffer;
+	const T *ptr;
+	size_t count;
+public:
+	BufferIterator(Buffer<T>& b)
+		{
+			//cerr << "BufferIterator(Buffer<T>& b)\n" << flush;
+			buffer=&b;
+			first();
+		}
+
+	void first(void)
+		{
+			ptr=buffer->getValues();
+			count=0;
+		}
+
+	int ismore(void)	{ return count < buffer->getCount(); }
+
+	void next(void)		{ ++count; }
+
+	T value(void)	        { if (ptr) return ptr[count];
+				  else { T r = 0; return r; } }
+
+	int operator!()		{ return ismore(); }
+	void operator++()	{ next(); }		// prefix  ++i
+	void operator++(int)	{ next(); }		// postfix i++
+	T operator()()		{ return value(); }
+};
+
+#endif /* __Header_buffer__ */
+
diff --git a/libsrc/include/generic/datetype.h b/libsrc/include/generic/datetype.h
new file mode 100644
index 0000000..e39612e
--- /dev/null
+++ b/libsrc/include/generic/datetype.h
@@ -0,0 +1,112 @@
+/* datetype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_datetype__
+#define __Header_datetype__
+
+#ifndef DEFAULTGUESSEDDATEORDER
+#define DEFAULTGUESSEDDATEORDER DateOrderDayMiddleYearLast
+#endif
+
+enum DateOrder {
+	DateOrderMonthMiddleYearLast,
+	DateOrderDayMiddleYearLast,
+//	DateOrderDayMiddleYearFirst,
+	DateOrderMonthMiddleYearFirst
+};
+
+class Date {
+protected:
+	short dd;
+	short mm;
+	char *mmm;
+	short yyyy;
+	char tzo[6];
+	bool goodflag;
+
+	char *makeMMMFromMM(short m) const;
+	bool extractMMFromMMM(const char *&src,size_t &length,short &m) const;
+
+	bool getDatePossibilityFromString(
+		const char *&src,size_t &length,
+		short &value,int &value_ismmm) const;
+
+	bool getDatePossibilitiesFromString(
+		const char *src,size_t length,
+		short &v1,int &v1_ismmm,
+		short &v2,int &v2_ismmm,
+		short &v3,int &v3_ismmm) const;
+
+	bool validateDateValues(short d,short m,short &y);	// May update year
+	void assignIndex(int& assignto,int not1,int not2) const;
+	bool getDDMMYYFromString(const char *src,size_t length,DateOrder order);
+	void makeTimezoneOffset(long tm_gmtoff);
+public:
+	Date(short y,short m,short d);
+	Date(short y,const char *mmm,short d);
+	Date(const char *str,enum DateOrder order=DEFAULTGUESSEDDATEORDER);
+	Date(Date const & date);
+	Date(void);
+	Date& operator=(const Date & date);
+	~Date(void);
+
+	short getDD(void) const		{ return dd; }
+	short getMM(void) const		{ return mm; }
+	const char *getMMM(void) const	{ return mmm; }
+	short getYYYY(void) const	{ return yyyy; }
+	short getYY(void) const		{ return yyyy%100; }
+	const char *getTZOffset(void) const { return tzo; }
+	bool isgood() const		{ return goodflag; }
+
+	operator const Uint32(void) const
+		{
+		  return (Uint32)yyyy*10000u + mm*100u + dd;
+		}
+};
+
+class Time {
+protected:
+	short hour;
+	short min;
+	short sec;
+	short millisec;
+	bool goodflag;
+
+	bool validateTimeValues(short h,short m,short s,short ms) const;
+	bool getHHMMSSFromString(const char *src,size_t length);
+public:
+	Time(short h,short m,short s,short ms=0);
+	Time(const char *str);
+	Time(Time const & time);
+	Time(Uint32 totalms);
+	Time(void);
+
+	short getHour(void) const		{ return hour; }
+	short getMinute(void) const		{ return min; }
+	short getSecond(void) const		{ return sec; }
+	short getMilliSecond(void) const	{ return millisec; }
+	bool isgood() const			{ return goodflag; }
+
+	operator const Uint32(void) const
+		{
+		  return (Uint32)hour*3600000u + min*60000u + sec*1000u + millisec;
+		}
+};
+
+class DateTime : public Date, public Time {
+public:
+	DateTime(short year,short month,short day,short hour,short min,short sec)
+		: Date(year,month,day), Time(hour,min,sec) {}
+
+	DateTime(const char *d,const char *t,enum DateOrder order=DEFAULTGUESSEDDATEORDER)
+		: Date(d,order), Time(t) {}
+
+	DateTime(short year,const char *month,short day,short hour,short min,short sec)
+		: Date(year,month,day), Time(hour,min,sec) {}
+
+	DateTime(Date const & date,Time const & time)
+		: Date(date), Time(time) {}
+
+	bool isgood() const		{ return Date::isgood() && Time::isgood(); }
+
+};
+
+#endif /* __Header_datetype__ */
diff --git a/libsrc/include/generic/endtype.h b/libsrc/include/generic/endtype.h
new file mode 100644
index 0000000..818f3c0
--- /dev/null
+++ b/libsrc/include/generic/endtype.h
@@ -0,0 +1,44 @@
+/* endtype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_endtype__
+#define __Header_endtype__
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>	//for debugging only
+#else
+#include <iostream.h>	//for debugging only
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;	//for debugging only
+#endif
+
+typedef enum { NoEndian, LittleEndian, BigEndian, ByteEndian } Endian;
+
+class HostEndian {
+	Endian endian;
+public:
+	HostEndian(void)
+		{
+			Uint16 i=0;
+			*((char *)&i)=1;
+//cerr << "HostEndian::test value = 0x" << hex << i << dec << endl;
+//#define NOBUGINENDTYPE
+#ifdef NOBUGINENDTYPE
+			endian=(i==1) ? LittleEndian : BigEndian;
+#else
+			Uint16 j=i;	// assigning it works around some bug in gcc for Linux
+			if (j == 1)
+				endian=LittleEndian;
+			else
+				endian=BigEndian;
+#endif
+//cerr << "HostEndian::i == 1 = " << (i == 1 ? "Little" : "Big") << endl;
+//cerr << "HostEndian::endian = " << (endian == LittleEndian ? "Little" : "Big") << endl;
+		}
+
+	Endian getEndian(void) const	{ return endian; }
+	bool isLittleEndian(void) const	{ return endian == LittleEndian; }
+	bool isBigEndian(void) const	{ return endian == BigEndian; }
+};
+
+#endif /* __Header_endtype__ */
diff --git a/libsrc/include/generic/errclass.h b/libsrc/include/generic/errclass.h
new file mode 100644
index 0000000..5020c92
--- /dev/null
+++ b/libsrc/include/generic/errclass.h
@@ -0,0 +1,44 @@
+/* errclass.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_errclass__
+#define __Header_errclass__
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iomanip>
+#else
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+class ErrorsInClass {
+private:
+	char *			errorstring;
+protected:
+	bool 			good_flag;
+	ostrstream 		errorstream;
+public:
+	ErrorsInClass(void)
+		{
+			good_flag=true;
+			errorstring=0;
+			errorstream.setf(std::ios::showbase|std::ios::internal);
+		}
+
+	~ErrorsInClass()
+		{
+			if (errorstring) delete[] errorstring;
+		}
+
+	bool		good(void)	{ return good_flag; }
+
+	const char *	errors(void)
+		{
+			errorstream << ends;
+			errorstring=errorstream.str();
+			return errorstring ? errorstring : "";
+		}
+};
+
+#endif /* __Header_errclass__ */
diff --git a/libsrc/include/generic/getoptns.h b/libsrc/include/generic/getoptns.h
new file mode 100644
index 0000000..73e1317
--- /dev/null
+++ b/libsrc/include/generic/getoptns.h
@@ -0,0 +1,92 @@
+/* getoptns.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_getoptns__
+#define __Header_getoptns__
+
+#include "errclass.h"
+
+class GetNamedOptions : public ErrorsInClass {
+private:
+	const char *		command_string;
+	int			argc_start;
+	const char *const *	argv_start;
+	bool *			argv_used;
+	int 			argc_left;
+private:
+	bool	match(const char *arg,const char *index);
+
+	bool	extract(const char *index,const char * src,long &dst);
+	bool	extract(const char *index,const char * src,unsigned long &dst);
+	bool	extract(const char *index,const char * src,long long &dst);
+	bool	extract(const char *index,const char * src,int &dst);
+	bool	extract(const char *index,const char * src,unsigned int &dst);
+	bool	extract(const char *index,const char * src,float &dst);
+	bool	extract(const char *index,const char * src,double &dst);
+	bool	extract(const char *index,const char * src,const char * &dst);
+
+	bool 		get(const char *const *indexes,const char * &value,int& which);
+
+	int		findUnusedOption(void);
+	int		findUnusedOption(const char *index);
+	int		findUnusedOption(const char *const *indexes,int& which);
+	int		findUnusedValue(int n);
+	void		firstValue(void);
+	int		areMoreValues(void);
+	void		bumpValue(void);
+	const char *	value(int n);
+public:
+			GetNamedOptions(int argc,const char *const *argv);
+	virtual		 ~GetNamedOptions();
+
+	bool 		get(const char *index);
+	bool 		get(const char *const *indexes);
+	bool		operator[](const char *index);
+	bool		operator[](const char *const *indexes);
+
+	bool 		get(const char *index,int &value);
+	bool 		get(const char *index,unsigned int &value);
+	bool 		get(const char *index,unsigned long &value);
+	bool 		get(const char *index,long &value);
+	bool 		get(const char *index,long long &value);
+	bool 		get(const char *index,float &value);
+	bool 		get(const char *index,double &value);
+	bool 		get(const char *index,const char * &value);
+
+	int 		get(const char *index,unsigned int *ptr,int num);
+	int 		get(const char *index,int *ptr,int num);
+	int 		get(const char *index,unsigned long *ptr,int num);
+	int 		get(const char *index,long *ptr,int num);
+	int 		get(const char *index,long long *ptr,int num);
+	int 		get(const char *index,float *ptr,int num);
+	int 		get(const char *index,double *ptr,int num);
+	int 		get(const char *index,const char **ptr,int num);
+
+	bool 		get(const char *const *indexes,int &value);
+	bool 		get(const char *const *indexes,unsigned int &value);
+	bool 		get(const char *const *indexes,unsigned long &value);
+	bool 		get(const char *const *indexes,long &value);
+	bool 		get(const char *const *indexes,long long &value);
+	bool 		get(const char *const *indexes,float &value);
+	bool 		get(const char *const *indexes,double &value);
+	bool 		get(const char *const *indexes,const char * &value);
+
+	int 		get(const char *const *indexes,unsigned int *ptr,int num);
+	int 		get(const char *const *indexes,int *ptr,int num);
+	int 		get(const char *const *indexes,unsigned long *ptr,int num);
+	int 		get(const char *const *indexes,long *ptr,int num);
+	int 		get(const char *const *indexes,long long *ptr,int num);
+	int 		get(const char *const *indexes,float *ptr,int num);
+	int 		get(const char *const *indexes,double *ptr,int num);
+	int 		get(const char *const *indexes,const char **ptr,int num);
+
+	int 		operator!();
+	void 		operator++();		// prefix  ++i
+	void 		operator++(int);	// postfix i++
+	const char *	operator()();
+	const char *	operator[](int num);
+
+	const char *	command(void) const;
+
+	void		done(void);
+};
+
+#endif /* __Header_getoptns__ */
diff --git a/libsrc/include/generic/hash.h b/libsrc/include/generic/hash.h
new file mode 100644
index 0000000..7259aae
--- /dev/null
+++ b/libsrc/include/generic/hash.h
@@ -0,0 +1,104 @@
+/* hash.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_hash__
+#define __Header_hash__
+
+//#include "generic/basetype.h"
+//#include "generic/listsimp.h"
+#include "basetype.h"
+#include "listsimp.h"
+
+template <class E,class K,class L,class LI>
+class OpenHashTable {
+	L **table;
+	unsigned long size;
+
+	// This wierd return value stuff and splitting out
+	// the while from the constructor is to keep SunPro
+	// C++ happy :(
+
+	OpenHashTable& clear(void)
+		{
+			unsigned long s=size;
+			L **p=table;
+			while (s--) *p++=0;
+			return *this;
+		}
+public:
+	OpenHashTable(unsigned long s)
+		{
+			//typedef L *OpenHashTableEntry;
+			table=new L *[s];
+			size=s;
+			clear();
+		}
+
+	// need a destructor to free the table and ?? delete
+	// what is in it ?? :(
+
+	OpenHashTable&	operator+=(E entry)
+		{
+			unsigned long index=hash(key(entry),size);
+			L *list=table[index];
+			if (!list) {
+				list=new L;
+				table[index]=list;
+			}
+			*list+=entry;
+			return *this;
+		}
+
+	OpenHashTable&	operator-=(E entry)
+		{
+			unsigned long index=hash(key(entry),size);
+			L *list=table[index];
+			if (list) {
+				*list-=entry;
+			}
+			return *this;
+		}
+
+	E *		operator[](K k)
+		{
+			unsigned long index=hash(k,size);
+			L *list=table[index];
+			if (list) {
+				LI li(*list);
+				while (!li) {
+					E e=li();
+					if (key(e) == k) {
+						E *ep = new E;
+						*ep=e;
+						return ep;
+					}
+					++li;
+				}
+			}
+			return 0;
+		}
+
+	// virtual functions supplied by derived class ...
+
+	virtual	unsigned long	hash(const K &key,unsigned long size)	= 0;
+	virtual	K 		key (const E &entry)	= 0;
+
+};
+
+// ************** Useful classes for using OpenHashTable **************
+
+class HashKeyString {			// Use as class K
+	const char *string;
+public:
+	HashKeyString(void)		{ string=0; }
+	HashKeyString(const char *s)	{ string=s; }
+
+	const char *getString(void) const	{ return string; }
+
+	bool operator==(const HashKeyString& k) const
+		{
+			return string && k.getString()
+				   && strcmp(string,k.getString()) == 0;
+		}
+};
+
+#endif /* __Header_hash__ */
+
diff --git a/libsrc/include/generic/ioopt.h b/libsrc/include/generic/ioopt.h
new file mode 100644
index 0000000..9642ba4
--- /dev/null
+++ b/libsrc/include/generic/ioopt.h
@@ -0,0 +1,50 @@
+/* ioopt.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ioopt__
+#define __Header_ioopt__
+
+#include "getoptns.h"
+
+class InputOptions : public ErrorsInClass
+{
+public:
+	const char *	filename;
+
+	InputOptions(GetNamedOptions &options);
+	char *usage(void);
+	void done(void);
+};
+
+class OutputOptions : public ErrorsInClass
+{
+public:
+	const char *	filename;
+
+	OutputOptions(GetNamedOptions &options);
+	char *usage(void);
+	void done(void);
+};
+
+class InputOpenerFromOptions : public ErrorsInClass {
+	istream *str;
+public:
+	InputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename,istream &cstr,bool raw=true);
+
+	~InputOpenerFromOptions();
+
+	operator streambuf *(void);
+};
+
+class OutputOpenerFromOptions : public ErrorsInClass {
+	ostream *str;
+public:
+	OutputOpenerFromOptions(GetNamedOptions &options,
+		const char *filename,ostream &cstr,bool raw=true);
+
+	~OutputOpenerFromOptions();
+
+	operator streambuf *(void);
+};
+
+#endif /* __Header_ioopt__ */
+
diff --git a/libsrc/include/generic/listfifo.h b/libsrc/include/generic/listfifo.h
new file mode 100644
index 0000000..4297fde
--- /dev/null
+++ b/libsrc/include/generic/listfifo.h
@@ -0,0 +1,44 @@
+/* listfifo.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_listfifo__
+#define __Header_listfifo__
+
+#include "listsimp.h"
+
+// First thing entered remains at head of list
+
+template<class T>
+class FifoList : public SimpleList<T> {
+public:
+	FifoList(void) : SimpleList<T>()
+		{
+		}
+
+	void	operator+=(T value)
+		{
+			SimpleListEntry<T> *ptr = new SimpleListEntry<T>;
+			ptr->item=value;
+			// Insert into list at tail
+			SimpleListEntry<T> *test,*last;
+			test=SimpleList<T>::head;
+			last=0;
+			while (test) {
+				last=test;
+				test=test->next;
+			}
+			ptr->next=0;
+			if (last) last->next=ptr;
+			else SimpleList<T>::head=ptr;
+		}
+};
+
+template<class T>
+class FifoListIterator : public SimpleListIterator<T> {
+public:
+	FifoListIterator(FifoList<T>& list)
+		: SimpleListIterator<T> (list)
+		{
+		}
+};
+
+#endif /* __Header_listfifo__ */
+
diff --git a/libsrc/include/generic/listsimp.h b/libsrc/include/generic/listsimp.h
new file mode 100644
index 0000000..f1f82a8
--- /dev/null
+++ b/libsrc/include/generic/listsimp.h
@@ -0,0 +1,162 @@
+/* listsimp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_listsimp__
+#define __Header_listsimp__
+
+template<class T> class SimpleList;
+template<class T> class SimpleListIterator;
+
+template <class T>
+class SimpleListEntry {
+public:		// blech :(
+	T item;
+	SimpleListEntry* next;
+};
+
+template<class T>
+class SimpleList {
+protected:
+	//friend class SimpleListIterator<T>;
+	//SimpleListEntry<T> *head;
+public:
+	SimpleListEntry<T> *head;	// blech :(
+	
+	SimpleList(void)
+		{
+			//cerr << "SimpleList<T>::SimpleList()\n" << flush;
+			head=0;
+		}
+
+	virtual ~SimpleList(void)
+		{
+			SimpleListEntry<T> *ptr=head;
+			while (ptr) {
+				SimpleListEntry<T> *next=ptr->next;
+				delete ptr;
+				ptr=next;
+			}
+		}
+
+	void operator+=(T value)
+		{
+			//cerr << "SimpleList<T>::operator+=\n" << flush;
+			SimpleListEntry<T> *ptr = new SimpleListEntry<T>;
+			ptr->item=value;
+			// Insert at head of list
+			ptr->next=head;
+			head=ptr;
+		}
+
+	void operator-=(T value)
+		{
+			//cerr << "SimpleList<T>::operator-=() start\n"
+			//     << flush;
+			//cerr << "SimpleList<T>::operator-=() "
+			//     << "head=" << hex << (unsigned long)head
+			//     << "\n" << flush;
+			SimpleListEntry<T> *ptr = head;
+			SimpleListEntry<T> *last = 0;
+			while (ptr) {
+			//cerr << "SimpleList<T>::operator-=() looping\n"
+			//     << flush;
+			//cerr << "SimpleList<T>::operator-=() "
+			//     << "head=" << hex << (unsigned long)head
+			//     << "\n" << flush;
+			//cerr << "SimpleList<T>::operator-=() "
+			//     << "last=" << hex << (unsigned long)last
+			//     << "\n" << flush;
+			//cerr << "SimpleList<T>::operator-=() "
+			//     << "ptr=" << hex << (unsigned long)ptr
+			//     << "\n" << flush;
+			//cerr << "SimpleList<T>::operator-=() "
+			//     << "ptr->next=" << hex
+			//     << (unsigned long)ptr->next
+			//     << "\n" << flush;
+				if (ptr->item == value) {
+					if (last) last->next=ptr->next;
+					else head=ptr->next;
+					SimpleListEntry<T> *old = ptr;
+					ptr=ptr->next;
+					delete old;
+				}
+				else {
+					last=ptr;
+					ptr=ptr->next;
+				}
+			}
+			//cerr << "SimpleList<T>::operator-=() done\n" << flush;
+			//cerr << "SimpleList<T>::operator-=() "
+			//    << "head=" << hex << (unsigned long)head
+			//     << "\n" << flush;
+			//dump();
+		}
+
+	void	dump(void)
+		{
+			cerr << "SimpleList<T>::dump()\n" << flush;
+			cerr << "SimpleList<T>::dump() "
+			     << "head=" << hex << (unsigned long)(head)
+			     << "\n" << flush;
+			SimpleListEntry<T> *ptr=head;
+			while (ptr) {
+				cerr << "SimpleList<T>::dump() "
+				     << "ptr=" << hex << (unsigned long)(ptr)
+				     << "\n" << flush;
+				ptr=ptr->next;
+			}
+		}
+
+	bool	isEmpty(void) const		{ return head == NULL; }
+	bool	isOne(void) const		{ return head != NULL && head->next == NULL; }
+	bool	isMultiple(void) const		{ return head != NULL && head->next != NULL; }
+};
+
+template<class T>
+class SimpleListIterator {
+protected:
+	SimpleList<T>	   *list;
+	SimpleListEntry<T> *ptr;
+public:
+	SimpleListIterator(void)
+		{
+			//cerr << "SimpleListIterator(void)\n" << flush;
+			list=0; ptr=0;
+		}
+
+	SimpleListIterator(SimpleList<T>& l)
+		{
+			//cerr << "SimpleListIterator(list)\n" << flush;
+			list=&l; ptr=list->head;
+			//cerr << "SimpleListIterator(list) "
+			//     << "head=" << hex << (unsigned long)(list->head)
+			//     << "\n" << flush;
+			//cerr << "SimpleListIterator(list) "
+			//     << "ptr=" << hex << (unsigned long)ptr
+			//     << "\n" << flush;
+		}
+
+	void set(SimpleList<T>& l)
+		{
+			list=&l; ptr=list->head;
+		}
+
+	void first(void)	{ ptr=list->head; }
+	int ismore(void)
+		{
+			//cerr << "SimpleListIterator::ismore() "
+			//     << "ptr=" << hex << (unsigned long)ptr
+			//     << "\n" << flush;
+			return ptr != 0;
+		}
+	void next(void)		{ if (ptr) ptr=ptr->next; }
+	T value(void)	        { if (ptr) return ptr->item;
+				  else { T r = 0; return r; } }
+
+	int operator!()		{ return ismore(); }
+	void operator++()	{ next(); }		// prefix  ++i
+	void operator++(int)	{ next(); }		// postfix i++
+	T operator()()		{ return value(); }
+};
+
+#endif /* __Header_listsimp__ */
+
+
diff --git a/libsrc/include/generic/listsort.h b/libsrc/include/generic/listsort.h
new file mode 100644
index 0000000..b0e9e38
--- /dev/null
+++ b/libsrc/include/generic/listsort.h
@@ -0,0 +1,45 @@
+/* listsort.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_listsort__
+#define __Header_listsort__
+
+#include "listsimp.h"
+
+// type T must be cabable of ordering itself, specifically "<" must work
+
+template<class T>
+class SortedList : public SimpleList<T> {
+public:
+	SortedList(void) : SimpleList<T>()
+		{
+		}
+
+	void	operator+=(T value)
+		{
+			SimpleListEntry<T> *ptr = new SimpleListEntry<T>;
+			ptr->item=value;
+			// Insert into list in ascending order
+			SimpleListEntry<T> *test,*last;
+			test=SimpleList<T>::head;
+			last=0;
+			while (test && test->item < value) {
+				last=test;
+				test=test->next;
+			}
+			ptr->next=test;
+			if (last) last->next=ptr;
+			else SimpleList<T>::head=ptr;
+
+		}
+};
+
+template<class T>
+class SortedListIterator : public SimpleListIterator<T> {
+public:
+	SortedListIterator(SortedList<T>& list)
+		: SimpleListIterator<T> (list)
+		{
+		}
+};
+
+#endif /* __Header_listsort__ */
+
diff --git a/libsrc/include/generic/ntstream.h b/libsrc/include/generic/ntstream.h
new file mode 100644
index 0000000..ab9d07a
--- /dev/null
+++ b/libsrc/include/generic/ntstream.h
@@ -0,0 +1,75 @@
+/* ntstream.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_nstream__
+#define __Header_nstream__
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+class netbuf: public streambuf {
+protected:
+	int	mode;
+	int	open_flag;
+	int	socket;
+
+	virtual int	overflow(int=EOF);
+	virtual int	underflow(void);
+	virtual int	sync(void);
+	virtual int	xsputn(const char *p,int n);
+public:
+	netbuf();
+	virtual ~netbuf();
+
+	int	is_open(void)	{ return open_flag; }
+	netbuf*	open(const char *host,const char *service,const char *protocol,int md);
+	netbuf*	close(void);
+};
+
+class netstreambase : virtual public ios {
+private:
+	netbuf buf;
+public:
+	netstreambase();
+	netstreambase(const char *host,const char *service,const char *protocol,int mode);
+	virtual ~netstreambase();
+
+	void	open(const char *host,const char *service,const char *protocol,int mode);
+	void	close(void);
+	void	setbuf(char *p,int l);
+
+	netbuf*	rdbuf() { return &buf; }
+};
+
+class inetstream : public netstreambase, public istream {
+public:
+	inetstream();
+	inetstream(const char *host,const char *service,const char *protocol,int mode=ios::in);
+	virtual ~inetstream();
+
+	netbuf*	rdbuf() { return netstreambase::rdbuf(); }
+};
+
+class onetstream : public netstreambase, public ostream {
+public:
+	onetstream();
+	onetstream(const char *host,const char *service,const char *protocol,int mode=ios::out);
+	virtual ~onetstream();
+
+	netbuf*	rdbuf() { return netstreambase::rdbuf(); }
+};
+
+// There is no netstream class that does bidirectional i/o a la fstream
+// The en vogue way to do this is sharing the rdbuf() with another ostream
+// eg.
+//
+//	inetstream in("localhost","echo","tcp");
+//	ostream out(in.rdbuf());
+//	in.tie(&out);		// this is necessary if interactive
+
+#endif /* __Header_nstream__ */
diff --git a/libsrc/include/generic/platform.h b/libsrc/include/generic/platform.h
new file mode 100644
index 0000000..28c28db
--- /dev/null
+++ b/libsrc/include/generic/platform.h
@@ -0,0 +1,7 @@
+/* platform.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_platform__
+#define __Header_platform__
+
+extern const char* dicom3tools_platform_string;
+
+#endif /* __Header_platform__ */
diff --git a/libsrc/include/generic/strtype.h b/libsrc/include/generic/strtype.h
new file mode 100644
index 0000000..6cdc939
--- /dev/null
+++ b/libsrc/include/generic/strtype.h
@@ -0,0 +1,136 @@
+/* strtype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_strtype__
+#define __Header_strtype__
+
+//#include <string.h>	// always include basetype.h which includes this
+
+template <int Length>
+class String {
+	char string[Length];
+public:
+	String(void)
+		{
+		}
+	String(const char *s)
+		{
+			strncpy(string,s,Length);
+		}
+	operator const char *(void) const
+		{
+			// not delimited unless originally delimited
+			return string;
+		}
+	operator char *(void) const
+		{
+			// makes a delimited copy that caller must delete[]
+			char *s = new char[Length+1];
+			Assert(s);
+			strncpy(s,string,Length);
+			s[Length]=0;
+			return s;
+		}
+};
+
+// used as:
+//
+//	String<10> s;
+//
+//	ostr << String_Use(s);
+
+class String_Use {
+	char *string;
+public:
+	String_Use(char *s)
+		{
+			string=s;
+		}
+	~String_Use()
+		{
+			if (string) delete[] string;
+		}
+	operator const char *(void) const
+		{
+			return string;
+		}
+};
+
+class String_Cat_Use {
+	char *string;
+public:
+	String_Cat_Use(const char *s1,const char *s2)
+		{
+			size_t length=0;
+			if (s1) length+=strlen(s1);
+			if (s2) length+=strlen(s2);
+			string=new char[length+1];
+			string[0]=0;
+			if (s1) strcat(string,s1);
+			if (s2) strcat(string,s2);
+			string[length]=0;
+		}
+	~String_Cat_Use()
+		{
+			if (string) delete[] string;
+		}
+	operator const char *(void) const
+		{
+			return string;
+		}
+};
+
+static inline
+char *StrDup(const char *s)
+{
+	char *d;
+	if (s) {
+		d=new char[strlen(s)+1];
+		Assert(d);
+		strcpy(d,s);
+	}
+	else
+		d=0;
+	return d;
+}
+
+#ifdef CRAP
+class StringCopy {
+private:
+	char *string;
+public:
+	StringCopy(void)
+		{
+			string=0;
+		}
+	StringCopy(const char *from)
+		{
+			string=StrDup(from);
+		}
+	StringCopy(const StringCopy& from)
+		{
+			string=StrDup(from);
+		}
+
+	~StringCopy(void)
+		{
+			if (string) delete[] string;
+		}
+
+	StringCopy& operator=(const StringCopy& from)
+		{
+			string=StrDup(from.string);
+			return *this;
+		}
+
+	operator const char *() const
+		{
+			return string;
+		}
+
+	operator char *(void) const
+		{
+			return StrDup(string);
+		}
+};
+#endif
+
+#endif /* __Header_strtype__ */
diff --git a/libsrc/include/generic/txstream.h b/libsrc/include/generic/txstream.h
new file mode 100644
index 0000000..3768173
--- /dev/null
+++ b/libsrc/include/generic/txstream.h
@@ -0,0 +1,35 @@
+/* txstream.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_txstream__
+#define __Header_txstream__
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+class TextOutputStream : public ostream {
+public:
+	TextOutputStream(streambuf *buf) : ostream(buf)
+		{
+			setf(ios::showbase,ios::showbase);
+		}
+
+	TextOutputStream(ostream& ostr) : ostream(ostr.rdbuf())
+		{
+			setf(ios::showbase,ios::showbase);
+		}
+};
+
+ostream& writeZeroPaddedNumber(ostream& o,Uint32 value,ios::fmtflags basetouse,int size);
+ostream& writeZeroPaddedHexNumber(ostream& o,Uint32 value,int size);
+
+#endif /* __Header_txstream__ */
+
+
diff --git a/libsrc/include/generic/version.h b/libsrc/include/generic/version.h
new file mode 100644
index 0000000..336ac9b
--- /dev/null
+++ b/libsrc/include/generic/version.h
@@ -0,0 +1,7 @@
+/* version.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_version__
+#define __Header_version__
+
+extern const char* dicom3tools_version_string;
+
+#endif /* __Header_version__ */
diff --git a/libsrc/include/locale/Imakefile b/libsrc/include/locale/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/include/locale/mesgtext.h b/libsrc/include/locale/mesgtext.h
new file mode 100644
index 0000000..337045c
--- /dev/null
+++ b/libsrc/include/locale/mesgtext.h
@@ -0,0 +1,27 @@
+/* mesgtext.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_mesgtext__
+#define __Header_mesgtext__
+
+#include "strtype.h"
+
+class EMSGDC_Class {
+public:
+	char *		error(const char *index);
+	char *		warning(const char *index);
+	char *		abort(const char *index);
+	const char *	message(const char *index);
+};
+
+static EMSGDC_Class EMSGDC_Instance;
+
+#define EMsgDC(index)	String_Use(EMSGDC_Instance.error(#index))
+#define WMsgDC(index)	String_Use(EMSGDC_Instance.warning(#index))
+#define AMsgDC(index)	String_Use(EMSGDC_Instance.abort(#index))
+#define MMsgDC(index)	EMSGDC_Instance.message(#index)
+
+#define EMsgDCNull()	String_Use(EMSGDC_Instance.error("Null"))
+#define WMsgDCNull()	String_Use(EMSGDC_Instance.warning("Null"))
+#define AMsgDCNull()	String_Use(EMSGDC_Instance.abort("Null"))
+#define MMsgDCNull()	EMSGDC_Instance.message("Null")
+
+#endif /* __Header_mesgtext__ */
diff --git a/libsrc/include/ourdisp/Imakefile b/libsrc/include/ourdisp/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/include/ourdisp/ourdisp.h b/libsrc/include/ourdisp/ourdisp.h
new file mode 100644
index 0000000..f4cb173
--- /dev/null
+++ b/libsrc/include/ourdisp/ourdisp.h
@@ -0,0 +1,217 @@
+/* ourdisp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ourdisp__
+#define __Header_ourdisp__
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#if USEXMITSHMEXTENSION == 1
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+class OurDisplay : public ErrorsInClass {
+	friend class OurWindow;
+	friend class OurColorMap;
+
+	char *		name;
+	Display *	display;
+	int 		screen;
+	Window 		rootwindow;
+	Visual *	visual;
+	unsigned 	depth;
+	int 		bitmappad;
+
+	char * 		getName(void)		{ return name; }
+	Display *	getDisplay(void)	{ return display; }
+	int 		getScreen(void)		{ return screen; }
+	Window 		getRootwindow(void)	{ return rootwindow; }
+	Visual *	getVisual(void)		{ return visual; }
+	unsigned 	getDepth(void)		{ return depth; }
+	int 		getBitmapPad(void)	{ return bitmappad; }
+public:
+	OurDisplay(void);
+	~OurDisplay();
+
+	XEvent nextEvent(void);
+};
+
+class OurColorMap : public ErrorsInClass {
+	friend class OurWindow;
+
+	OurDisplay *	display;
+	Colormap 	colormap;
+
+	unsigned long *	cells;
+	unsigned length;
+
+	Colormap getColormap(void)	{ return colormap; }
+public:
+	OurColorMap(OurDisplay *d);
+	~OurColorMap(void);
+
+	bool setColorCellsWanted(unsigned nwanted,unsigned nminimum);
+	bool getColorCellsAvailable(unsigned &n,unsigned long *&table);
+	bool setColorCellValues(unsigned n,
+		unsigned short *red,
+		unsigned short *green,
+		unsigned short *blue);
+};
+
+class OurWindow : public ErrorsInClass {
+private:
+	friend class OurWindowImage;
+
+	OurDisplay *	ourdisplay;
+
+	Window 		window;
+	int 		x;
+	int 		y;
+	unsigned 	width;
+	unsigned	imageheight;
+	unsigned	totalheight;
+	unsigned	headerheight;
+	unsigned	footerheight;
+	unsigned 	border;
+
+	unsigned long	foreground;
+	unsigned long	background;
+
+	GC		reservedareagc;
+	XFontStruct *	reservedareafont;
+
+	Window 		getWindow(void)		{ return window; }
+	int 		getX(void)		{ return x; }
+	int 		getY(void)		{ return y; }
+	unsigned 	getImageStartX(void)	{ return 0; }
+	unsigned	getImageStartY(void)	{ return headerheight; }
+	unsigned 	getImageWidth(void)	{ return width; }
+	unsigned	getImageHeight(void)	{ return imageheight; }
+	unsigned	getReservedRowsTop(void)
+						{ return headerheight; }
+	unsigned	getReservedRowsBottom(void)
+						{ return footerheight; }
+	unsigned 	getBorder(void)		{ return border; }
+
+	unsigned long 	getForeground(void)	{ return foreground; }
+	unsigned long 	getBackground(void)	{ return background; }
+
+	char * 		getName(void)
+				{ return ourdisplay->getName(); }
+	Display *	getDisplay(void)
+				{ return ourdisplay->getDisplay(); }
+	int 		getScreen(void)
+				{ return ourdisplay->getScreen(); }
+	Window 		getRootwindow(void)
+				{ return ourdisplay->getRootwindow(); }
+	Visual *	getVisual(void)
+				{ return ourdisplay->getVisual(); }
+	unsigned 	getDepth(void)
+				{ return ourdisplay->getDepth(); }
+	int 		getBitmapPad(void)
+				{ return ourdisplay->getBitmapPad(); }
+
+	void writeTextSomewhere(int baseline,
+			const char *left,const char *center,const char *right);
+public:
+	OurWindow(OurDisplay *d,
+		unsigned w,unsigned h,
+		unsigned headerh=0,unsigned footerh=0);
+	~OurWindow(void);
+
+	void writeHeaderText(
+		const char *left,const char *center=0,const char *right=0);
+	void writeFooterText(
+		const char *left,const char *center=0,const char *right=0);
+	void clearHeader(void);
+	void clearFooter(void);
+
+	void reportPosition(
+			int x,int y,
+			unsigned short &row,unsigned short &col) const;
+
+	void useCursorLevelWidth(void);
+	void useCursorCrossHair(void);
+	void useCursorWatch(void);
+
+	void start(void);
+	void clear(void);
+	void alarm(void);
+	void setColormap(OurColorMap *colormap);
+
+	void redraw(void);
+};
+
+class OurWindowImage : public ErrorsInClass {
+	OurWindow *		window;
+	XImage *		ximage;
+	GC			imagegc;
+#if USEXMITSHMEXTENSION == 1
+	bool			shm_flag;
+	XShmSegmentInfo *	xshminfo;
+#endif
+public:
+	OurWindowImage(OurWindow *w);
+	~OurWindowImage();
+
+	void put(void);
+
+	char * get8BitDataAddress(void);
+	bool write8BitDataToStream(ostream &o);
+	bool write8BitDataToPGMStream(ostream &o);
+
+	void putPoint(unsigned x,unsigned y);
+
+	unsigned getHeight(void)	{ return window->getImageHeight(); }
+	unsigned getWidth(void)		{ return window->getImageWidth(); }
+	unsigned getDepth(void)		{ return window->getDepth(); }
+	unsigned getBytesPerRow(void)	{ return ximage->bytes_per_line; }
+};
+
+// NB. The OurWindowLevelWidthUpdator deals with an "internal" scale
+// of window level and width, ie. disregarding the intercept and slope
+// entirely and using the unsigned representation of what is in the
+// pixel data.
+
+// The one exception to this is displaying the values of the current
+// width and level in the rserved area, in which case the sign,
+// slop and intercept are used to translate into "real world" values 
+
+class OurWindowLevelWidthUpdator {
+private:
+	long maplevelmin;
+	long maplevelmax;
+	long mapwidthmin;
+	long mapwidthmax;
+	long maplevel;
+	long mapwidth;
+	long signxor;
+	long intercept;
+	long slopeby1024;
+	long lastx;
+	long lasty;
+	OurWindow *window;
+public:
+	OurWindowLevelWidthUpdator(OurWindow &w,Uint16 bits,bool issigned,
+		double rescaleintercept,double rescaleslope);
+	~OurWindowLevelWidthUpdator();
+
+	void set(Uint16 level,Uint16 width);
+	void get(Uint16 &level,Uint16 &width);
+
+	Uint16 getStoredLevelFromDisplayedLevel(long level);
+	Uint16 getStoredWidthFromDisplayedWidth(long width);
+	long getDisplayedLevelFromStoredLevel(long level);
+	long getDisplayedWidthFromStoredWidth(long width);
+
+	void put(void);
+	void press(long x,long y);
+	void release(long x,long y);
+	void move(long x,long y,long multiplier);
+	void update(long x,long y,long multiplier);
+};
+
+#endif /* __Header_ourdisp__ */
diff --git a/libsrc/include/pixeldat/Imakefile b/libsrc/include/pixeldat/Imakefile
new file mode 100755
index 0000000..96bd86b
--- /dev/null
+++ b/libsrc/include/pixeldat/Imakefile
@@ -0,0 +1,7 @@
+all::	depend
+
+depend::	smptetxt.h
+
+smptetxt.h:	makesmptetxt
+	./makesmptetxt smpte_string > smptetxt.h
+
diff --git a/libsrc/include/pixeldat/briggsrc.h b/libsrc/include/pixeldat/briggsrc.h
new file mode 100644
index 0000000..15a9904
--- /dev/null
+++ b/libsrc/include/pixeldat/briggsrc.h
@@ -0,0 +1,613 @@
+/* briggsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_BriggsSrc__
+#define __Header_BriggsSrc__
+
+#include "srcsink.h"
+
+// The following is the standard (unrotated) target).
+//
+// Checkerboard TLHC origin is defined relative to 0\0 origin
+//
+// Other targets are derived by rotating by 90,180,270 degrees
+// bearing in mind that the actual TLHC checker of each checkerboard
+// should be light (ie. because of even number of checkers B-80 and
+// B-90 need special attention)
+
+
+static const int bpt4_width  = 128;
+static const int bpt4_height = 256;
+static const int bpt4_checkerboards_per_target = 17;
+
+struct bpt4_parameter_entry {
+	unsigned short score;
+	unsigned short checkers_per_board;
+	unsigned short pixels_per_checker;
+	unsigned short tlhc_col;
+	unsigned short tlhc_row;
+} bpt4_parameter_table[bpt4_checkerboards_per_target] = {
+	90,	2,	1,	51,	188,
+	85,	3,	1,	38,	187,
+	80,	4,	1,	38,	200,
+	75,	5,	1,	52,	202,
+	70,	7,	1,	67,	200,
+	65,	11,	1,	63,	180,
+	60,	5,	2,	60,	160,
+	55,	7,	2,	36,	160,
+	50,	5,	3,	11,	160,
+	45,	5,	4,	8,	185,
+	40,	3,	7,	19,	215,
+	35,	3,	8,	50,	217,
+	30,	3,	10,	84,	209,
+	25,	3,	13,	84,	160,
+	20,	3,	16,	75,	102,
+	15,	3,	20,	4,	90,
+	10,	3,	25,	4,	4
+};
+
+static void
+generate_bpt4(Uint16 *matrix,unsigned width, unsigned height,
+			unsigned put_at_col,unsigned put_at_row,
+			unsigned short rotation,
+			Uint16 light_value,Uint16 dark_value,Uint16 surround_value)
+{
+	// Prepare coordinates of rotated target pattern from standard target ...
+
+	unsigned short target_width;
+	unsigned short target_height;
+	unsigned short target_tlhc_row[bpt4_checkerboards_per_target];
+	unsigned short target_tlhc_col[bpt4_checkerboards_per_target];
+
+	if (rotation == 0) {
+//cerr << "rotation = " << dec << rotation << endl;
+		target_width=bpt4_width;
+		target_height=bpt4_height;
+		unsigned short checkerboard;
+		for (checkerboard=0; checkerboard<bpt4_checkerboards_per_target; ++checkerboard) {
+//cerr << "checkerboard = " << dec << checkerboard << endl;
+			target_tlhc_row[checkerboard]=bpt4_parameter_table[checkerboard].tlhc_row;
+			target_tlhc_col[checkerboard]=bpt4_parameter_table[checkerboard].tlhc_col;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_row = " << dec << bpt4_parameter_table[checkerboard].tlhc_row << endl;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_col = " << dec << bpt4_parameter_table[checkerboard].tlhc_col << endl;
+//cerr << "\t target_tlhc_row[checkerboard] = " << dec << target_tlhc_row[checkerboard] << endl;
+//cerr << "\t target_tlhc_col[checkerboard] = " << dec << target_tlhc_col[checkerboard] << endl;
+			Assert(target_tlhc_row[checkerboard]<target_height);
+			Assert(target_tlhc_col[checkerboard]<target_width);
+		}
+	}
+	else if (rotation == 90) {
+//cerr << "rotation = " << dec << rotation << endl;
+		target_width=bpt4_height;	// swap height and width
+		target_height=bpt4_width;
+		unsigned short checkerboard;
+		for (checkerboard=0; checkerboard<bpt4_checkerboards_per_target; ++checkerboard) {
+//cerr << "checkerboard = " << dec << checkerboard << endl;
+			target_tlhc_col[checkerboard]=bpt4_height-bpt4_parameter_table[checkerboard].tlhc_row
+				-bpt4_parameter_table[checkerboard].pixels_per_checker*bpt4_parameter_table[checkerboard].checkers_per_board;
+			target_tlhc_row[checkerboard]=bpt4_parameter_table[checkerboard].tlhc_col;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_row = " << dec << bpt4_parameter_table[checkerboard].tlhc_row << endl;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_col = " << dec << bpt4_parameter_table[checkerboard].tlhc_col << endl;
+//cerr << "\t target_tlhc_row[checkerboard] = " << dec << target_tlhc_row[checkerboard] << endl;
+//cerr << "\t target_tlhc_col[checkerboard] = " << dec << target_tlhc_col[checkerboard] << endl;
+			Assert(target_tlhc_row[checkerboard]<target_height);
+			Assert(target_tlhc_col[checkerboard]<target_width);
+		}
+	}
+	else if (rotation == 180) {
+//cerr << "rotation = " << dec << rotation << endl;
+		target_width=bpt4_width;
+		target_height=bpt4_height;
+		unsigned short checkerboard;
+		for (checkerboard=0; checkerboard<bpt4_checkerboards_per_target; ++checkerboard) {
+//cerr << "checkerboard = " << dec << checkerboard << endl;
+			target_tlhc_row[checkerboard]=bpt4_height-bpt4_parameter_table[checkerboard].tlhc_row
+				-bpt4_parameter_table[checkerboard].pixels_per_checker*bpt4_parameter_table[checkerboard].checkers_per_board;
+			target_tlhc_col[checkerboard]=bpt4_width-bpt4_parameter_table[checkerboard].tlhc_col
+				-bpt4_parameter_table[checkerboard].pixels_per_checker*bpt4_parameter_table[checkerboard].checkers_per_board;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_row = " << dec << bpt4_parameter_table[checkerboard].tlhc_row << endl;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_col = " << dec << bpt4_parameter_table[checkerboard].tlhc_col << endl;
+//cerr << "\t target_tlhc_row[checkerboard] = " << dec << target_tlhc_row[checkerboard] << endl;
+//cerr << "\t target_tlhc_col[checkerboard] = " << dec << target_tlhc_col[checkerboard] << endl;
+			Assert(target_tlhc_row[checkerboard]<target_height);
+			Assert(target_tlhc_col[checkerboard]<target_width);
+		}
+	}
+	else if (rotation == 270) {
+//cerr << "rotation = " << dec << rotation << endl;
+		target_width=bpt4_height;	// swap height and width
+		target_height=bpt4_width;
+		unsigned short checkerboard;
+		for (checkerboard=0; checkerboard<bpt4_checkerboards_per_target; ++checkerboard) {
+//cerr << "checkerboard = " << dec << checkerboard << endl;
+			target_tlhc_col[checkerboard]=bpt4_parameter_table[checkerboard].tlhc_row;
+			target_tlhc_row[checkerboard]=bpt4_width-bpt4_parameter_table[checkerboard].tlhc_col
+				-bpt4_parameter_table[checkerboard].pixels_per_checker*bpt4_parameter_table[checkerboard].checkers_per_board;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_row = " << dec << bpt4_parameter_table[checkerboard].tlhc_row << endl;
+//cerr << "\t bpt4_parameter_table[checkerboard].tlhc_col = " << dec << bpt4_parameter_table[checkerboard].tlhc_col << endl;
+//cerr << "\t target_tlhc_row[checkerboard] = " << dec << target_tlhc_row[checkerboard] << endl;
+//cerr << "\t target_tlhc_col[checkerboard] = " << dec << target_tlhc_col[checkerboard] << endl;
+			Assert(target_tlhc_row[checkerboard]<target_height);
+			Assert(target_tlhc_col[checkerboard]<target_width);
+		}
+	}
+	else {
+		Assert(0);
+	}
+
+	// Verify space in pixel matrix and fill with surround value ...
+
+	Assert(matrix);
+	Assert(put_at_col+target_width <= width);
+	Assert(put_at_row+target_height <= height);
+
+//cerr << "filling surround" << endl;
+
+	unsigned row;
+	unsigned col;
+	for (row=put_at_row; row < put_at_row+target_height; ++row) {
+//cerr << "row=" << dec << row << endl;
+		 for (col=put_at_col; col < put_at_col+target_width; ++col) {
+			Assert(col<width);
+			Assert(row<height);
+			*(matrix+row*width+col)=surround_value;
+		}
+	}
+
+	// Generate the checkerboards that comprise the target
+	// by iterating through checkboard rows and columns,
+	// alternating light and dark, starting with light at TLHC ...
+
+	unsigned short checkerboard;
+	for (checkerboard=0; checkerboard<bpt4_checkerboards_per_target; ++checkerboard) {
+//cerr << "checkerboard = " << dec << checkerboard << endl;
+		unsigned ncheckers=bpt4_parameter_table[checkerboard].checkers_per_board;
+		unsigned start_row=put_at_row+target_tlhc_row[checkerboard];
+		unsigned start_col=put_at_col+target_tlhc_col[checkerboard];
+		unsigned checker_height=bpt4_parameter_table[checkerboard].pixels_per_checker;
+		unsigned checker_width =bpt4_parameter_table[checkerboard].pixels_per_checker;
+		bool first_checker_in_row_is_light=true;
+		unsigned row_checker_count;
+		for (row_checker_count=0; row_checker_count<ncheckers; ++row_checker_count) {
+			bool next_checker_in_row_is_light=first_checker_in_row_is_light;
+			unsigned col_checker_count;
+			for (col_checker_count=0; col_checker_count<ncheckers; ++col_checker_count) {
+				// make an entire checker ...
+//cerr << "\t row_checker_count = " << dec << row_checker_count << " col_checker_count = " << col_checker_count << endl;
+				Uint16 value = next_checker_in_row_is_light ? light_value : dark_value;
+				unsigned first_row=start_row+checker_height*row_checker_count;
+				unsigned last_row=start_row+checker_height*(row_checker_count+1)-1;
+				unsigned first_col=start_col+checker_width*col_checker_count;
+				unsigned last_col=start_col+checker_width*(col_checker_count+1)-1;
+				for (row=first_row; row <= last_row; ++row) {
+		 			for (col=first_col; col <= last_col; ++col) {
+//cerr << "\t\t row = " << dec << row << " col = " << col << endl;
+						Assert(col<width);
+						Assert(row<height);
+						*(matrix+row*width+col)=value;
+					}
+				}
+				next_checker_in_row_is_light=!next_checker_in_row_is_light;
+			}
+			first_checker_in_row_is_light=!first_checker_in_row_is_light;
+		}
+	
+	}
+}
+
+
+class Briggs_PixelDataSource : public SourceBase<Uint16> {
+protected:
+	Uint16 rows;
+	Uint16 columns;
+
+	bool signedpixrep;
+	bool inverted;
+
+	Int32  minval;
+	Int32  maxval;
+
+	Uint16 row;
+	Uint16 *buffer;
+	Uint16 *bufptr;
+
+public:
+	Briggs_PixelDataSource(Uint16 r,Uint16 c,bool pixrep,bool inv,Uint16 minv,Uint16 maxv,Uint16 contrast,Uint16 surround_percent,Uint16 background_percent)
+			: SourceBase<Uint16>()
+		{
+cerr << "Briggs_PixelDataSource: contrast = " << dec << contrast << endl;
+cerr << "Briggs_PixelDataSource: surround_percent = " << dec << surround_percent << endl;
+
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+cerr << "Briggs_PixelDataSource: rows=" << rows << endl;
+cerr << "Briggs_PixelDataSource: columns=" << columns << endl;
+
+			Assert(surround_percent<=100);
+			Assert(background_percent<=100);
+
+			signedpixrep=pixrep;
+			inverted=inv;
+
+			Uint32 range;
+			if (signedpixrep) {
+				Assert ((Int16)(maxv) > (Int16)(minv));
+				range=(Int16)(maxv)-(Int16)(minv);
+				minval=(Int16)minv;
+				maxval=(Int16)maxv;
+			}
+			else {
+				Assert (maxv > minv);
+				range=maxv-minv;
+				minval=(Uint32)minv;
+				maxval=(Uint32)maxv;
+			}
+
+			//minval=(Uint32)minv;
+			//maxval=(Uint32)maxv;
+			//Assert (maxv > minv);
+			//Uint32 range=maxv-minv;
+
+cerr << "Briggs_PixelDataSource: minval = " << dec << minval << endl;
+cerr << "Briggs_PixelDataSource: maxval = " << dec << maxval << endl;
+cerr << "Briggs_PixelDataSource: range = " << dec << range << endl;
+
+			Assert(contrast <= range);
+
+			// Allocate and buffer the entire array, not just one row ...
+
+			buffer=new Uint16[columns*rows];
+			Assert(buffer);
+			bufptr=buffer-columns;		// position BEFORE buffer, since 1st "read" increments it
+			row=0;
+
+
+			// Determine how many 256*256 paired targets will fit in
+			// available rows and columns ...
+
+			unsigned short pairsperrow = columns/256;
+			unsigned short pairspercolumn = rows/256;
+			unsigned short npairs = pairsperrow * pairspercolumn;
+
+			Assert(npairs);			// caller should have checked > 256*256
+
+cerr << "Briggs_PixelDataSource: pairsperrow=" << dec << pairsperrow << endl;
+cerr << "Briggs_PixelDataSource: pairspercolumn=" << dec << pairspercolumn << endl;
+cerr << "Briggs_PixelDataSource: npairs=" << npairs << dec << endl;
+
+			// Determine left over spacing ...
+
+			unsigned short col_offset=columns-pairsperrow*256;
+			unsigned short col_spacing=pairsperrow > 1 ? col_offset/(pairsperrow-1) : 0;
+			col_offset=(col_offset-col_spacing*(pairsperrow-1))/2;
+
+			unsigned short row_offset=rows-pairspercolumn*256;
+			unsigned short row_spacing=pairspercolumn > 1 ? row_offset/(pairspercolumn-1) : 0;
+			row_offset=(row_offset-row_spacing*(pairspercolumn-1))/2;
+
+cerr << "Briggs_PixelDataSource: col_offset=" << dec << col_offset << endl;
+cerr << "Briggs_PixelDataSource: col_spacing=" << dec << col_spacing << endl;
+cerr << "Briggs_PixelDataSource: row_offset=" << dec << row_offset << endl;
+cerr << "Briggs_PixelDataSource: row_spacing=" << dec << row_spacing << endl;
+
+			// Fill whole array with background value
+
+			Uint16 background_value = (Uint32)range*background_percent/100+minval;
+			if (inverted) {
+				background_value=range-(background_value-minval)+minval;
+			}
+
+			if (signedpixrep) {
+cerr << "Briggs_PixelDataSource: \t background_value = " << dec << (Int16)background_value << endl;
+				Assert((Int16)background_value >= minval);
+				Assert((Int16)background_value <= maxval);
+			}
+			else {
+cerr << "Briggs_PixelDataSource: \t background_value = " << dec << background_value << endl;
+				Assert(background_value >= minval);
+				Assert(background_value <= maxval);
+			}
+
+			{
+				Uint16 *ptr=buffer;
+				unsigned row;
+				for (row=0; row<rows;++row) {
+					unsigned col;
+					for (col=0; col<columns; ++col) {
+						*ptr++=background_value;
+					}
+				}
+			}
+
+			// Pairs are ordered by contrast between targets in the
+			// pair from 1 to npairs
+			//
+			// ie. P-1 has targets with ranks 1 and n
+			// and P-2 has targets with ranks 2 and n-1, etc.
+			//
+			// Goal is to spread pairs around so that average contrast
+			// between pairs is evenly distributed, ie. average along
+			// rows == average along columns == average along diagonals
+			//
+			// For a square matrix greater than 2*2, this is a "magic
+			// square" problem ... here we use the Siamese algorithm
+			// to find a magic square for squares of odd order ... for
+			// even order squares, a 2*2 square, or a rectangle it does
+			// close enough for the purpose ...
+
+			// Note also that for the 2*2 case , the Siamese algorithm will put
+			// P-3 top right and P-4 bottom left, swapped relative to Briggs'
+			// example, but this is OK, as Briggs points out.
+
+			unsigned short pair_table[npairs];
+			#define index_pair_table(pcol,prow)	(pair_table[(prow)*pairsperrow+(pcol)])
+
+			// Fill pair_table with zero to indicate unfilled ...
+
+			short prow;
+			short pcol;
+			for (prow=0; prow<pairspercolumn; prow++) {
+				for (pcol=0; pcol<pairsperrow; pcol++) {
+					index_pair_table(pcol,prow)=0;
+				}
+			}
+
+			// First pair goes in middle of top row (if odd number of pairsperrow)
+			// or left of middle (if even number of pairsperrow) ...
+
+			prow=0;
+			pcol=(pairsperrow+1)/2 - 1;	// 0->error,1->0,2->0,3->1,4->1,5->2, etc.
+			Assert(pcol != -1);
+
+			unsigned short whichpair=1;
+			while (1) {
+//cerr << "Briggs_PixelDataSource: Putting whichpair=" << whichpair << " at pcol=" << pcol << " prow=" << prow << endl;
+				index_pair_table(pcol,prow)=whichpair;
+
+				if (++whichpair > npairs) break;
+
+				// where to put next pair determined by Siamese algorithm
+				// "ordinary vector" (1,-1) with wraparound ...
+				short trycol = (pcol+1 >= pairsperrow) ? 0 : pcol+1;
+				short tryrow = (prow <= 0) ? pairspercolumn-1 : prow-1;
+//cerr << "Briggs_PixelDataSource: Trying trycol=" << trycol << " tryrow=" << tryrow << endl;
+				if (index_pair_table(trycol,tryrow)) {	// non-zero == filled
+//cerr << "Briggs_PixelDataSource: Filled" << endl;
+					// "break vector" (0,1) with wraparound ...
+					trycol = pcol;
+					tryrow = (prow+1 >= pairspercolumn) ? 0 : prow+1;
+//cerr << "Briggs_PixelDataSource: Trying trycol=" << trycol << " tryrow=" << tryrow << endl;
+					if (index_pair_table(trycol,tryrow)) {	// non-zero == filled
+//cerr << "Briggs_PixelDataSource: Filled" << endl;
+						// shit :(
+						//Assert(0);
+						break;
+					}
+				}
+				pcol=trycol;
+				prow=tryrow;
+			}
+
+			cerr << "Briggs_PixelDataSource: Pair table ..." << endl;
+			for (prow=0; prow<pairspercolumn; prow++) {
+				unsigned short rowtotal=0;
+				for (pcol=0; pcol<pairsperrow; pcol++) {
+					cerr << "\t" << index_pair_table(pcol,prow);
+					rowtotal+=index_pair_table(pcol,prow);
+				}
+				cerr << "\t| " << (float)rowtotal/pairsperrow << endl;
+			}
+			cerr << "\t";
+			for (pcol=0; pcol<pairsperrow; pcol++) {
+				cerr << "--------";
+			}
+			cerr << endl;
+			if (pairspercolumn == pairsperrow) {
+				unsigned short diagonaltotal=0;
+				unsigned short diagonalcount=0;
+				for (pcol=pairsperrow-1,prow=0; pcol>=0 && prow<pairspercolumn; pcol--, prow++) {
+					diagonaltotal+=index_pair_table(pcol,prow);
+					++diagonalcount;
+				}
+				cerr << (float)diagonaltotal/diagonalcount;
+			}
+			for (pcol=0; pcol<pairsperrow; pcol++) {
+				unsigned short coltotal=0;
+				for (prow=0; prow<pairspercolumn; prow++) {
+					coltotal+=index_pair_table(pcol,prow);
+				}
+				cerr << "\t" << (float)coltotal/pairspercolumn;
+			}
+			if (pairspercolumn == pairsperrow) {
+				unsigned short diagonaltotal=0;
+				unsigned short diagonalcount=0;
+				for (pcol=0,prow=0; pcol<pairsperrow && prow<pairspercolumn; pcol++, prow++) {
+					diagonaltotal+=index_pair_table(pcol,prow);
+					++diagonalcount;
+				}
+				cerr << "\t  " << (float)diagonaltotal/diagonalcount;
+			}
+			cerr << endl;
+
+			// Build target table by iterating through targets and indexing pair table ...
+			// - locations assigned by location in pair table
+			// - two ranks assigned by P-n and ntargets+1-n
+			// - alternating horizontal and vertical pairs
+
+			unsigned short ntargets=npairs*2;
+cerr << "Briggs_PixelDataSource: ntargets = " << dec << ntargets << endl;
+
+			// NB. this target table is NOT in Briggs target number (T-n) order ...
+
+			struct target_table_entry {
+				unsigned short rank;
+				unsigned short rotation;
+				unsigned short tlhc_col;
+				unsigned short tlhc_row;
+			} target_table[ntargets];
+
+			unsigned short target=0;
+			for (pcol=0; pcol<pairsperrow; pcol++) {
+				for (prow=0; prow<pairspercolumn; prow++) {
+					Assert(target<ntargets);
+
+					unsigned tlhc_pair_col=col_offset+pcol*(256+col_spacing);
+					unsigned tlhc_pair_row=row_offset+prow*(256+row_spacing);
+
+					// Horizontal or vertical orientation ?
+					// Also alternate hi/lo contrast rank order based on odd/even col
+					// (Briggs just says "balance" ranks ... this seems as good a way as any)
+
+					if (prow%2) {		// odd rows  (1,3,5 ...)
+						if (pcol%2) {	// odd cols  (1,3,5 ...)
+							// vertical ...
+							target_table[target].rotation=0;
+							target_table[target+1].rotation=180;
+							target_table[target].tlhc_col=tlhc_pair_col;
+							target_table[target].tlhc_row=tlhc_pair_row;
+							target_table[target+1].tlhc_col=tlhc_pair_col+128;
+							target_table[target+1].tlhc_row=tlhc_pair_row;
+							target_table[target].rank=index_pair_table(pcol,prow);
+							target_table[target+1].rank=ntargets+1-index_pair_table(pcol,prow);
+						}
+						else {		// even cols (0,2,4 ...)
+							// horizontal ...
+							target_table[target].rotation=270;
+							target_table[target+1].rotation=90;
+							target_table[target].tlhc_col=tlhc_pair_col;
+							target_table[target].tlhc_row=tlhc_pair_row;
+							target_table[target+1].tlhc_col=tlhc_pair_col;
+							target_table[target+1].tlhc_row=tlhc_pair_row+128;
+							target_table[target].rank=ntargets+1-index_pair_table(pcol,prow);
+							target_table[target+1].rank=index_pair_table(pcol,prow);
+						}
+					}
+					else {			// even rows (0,2,4 ...)
+						if (pcol%2) {	// odd cols  (1,3,5 ...)
+							// horizontal ...
+							target_table[target].rotation=270;
+							target_table[target+1].rotation=90;
+							target_table[target].tlhc_col=tlhc_pair_col;
+							target_table[target].tlhc_row=tlhc_pair_row;
+							target_table[target+1].tlhc_col=tlhc_pair_col;
+							target_table[target+1].tlhc_row=tlhc_pair_row+128;
+							target_table[target].rank=index_pair_table(pcol,prow);
+							target_table[target+1].rank=ntargets+1-index_pair_table(pcol,prow);
+						}
+						else {		// even cols (0,2,4 ...)
+							// vertical ...
+							target_table[target].rotation=0;
+							target_table[target+1].rotation=180;
+							target_table[target].tlhc_col=tlhc_pair_col;
+							target_table[target].tlhc_row=tlhc_pair_row;
+							target_table[target+1].tlhc_col=tlhc_pair_col+128;
+							target_table[target+1].tlhc_row=tlhc_pair_row;
+							target_table[target].rank=ntargets+1-index_pair_table(pcol,prow);
+							target_table[target+1].rank=index_pair_table(pcol,prow);
+						}
+					}
+
+					target+=2;
+				}
+			}
+									
+cerr << "Briggs_PixelDataSource: target table ..." << endl;
+			for (target=0; target < ntargets; ++target) {
+				cerr << "\trank=" << dec << target_table[target].rank
+				     << "\trotation=" << target_table[target].rotation
+				     << "\ttlhc_col=" << target_table[target].tlhc_col
+				     << "\ttlhc_row=" << target_table[target].tlhc_row
+				     << endl;
+			}
+
+
+			for (target=0; target < ntargets; ++target) {
+cerr << "Briggs_PixelDataSource: target = " << dec << (target+1) << endl;
+				unsigned short rank=target_table[target].rank;
+				Uint16 light_value= (rank-1)*(range-contrast)/(ntargets > 1 ? ntargets-1 : 1)+contrast+minval;
+				Uint16 dark_value = (rank-1)*(range-contrast)/(ntargets > 1 ? ntargets-1 : 1)+minval;	// ie. light_value-contrast
+
+				Uint16 average_command_level=(light_value+dark_value)/2;
+				Uint16 median_command_level=range/2+minval;
+				Uint16 surround_value;
+
+				if (signedpixrep) {
+					Int32 difference=(Int16)average_command_level-(Int16)median_command_level;
+//cerr << "Briggs_PixelDataSource: \t difference = " << dec << difference << endl;
+					surround_value=surround_percent*difference/100 + median_command_level;
+//cerr << "Briggs_PixelDataSource: \t average_command_level = " << dec << (Int16)average_command_level << endl;
+//cerr << "Briggs_PixelDataSource: \t median_command_level = " << dec << (Int16)median_command_level << endl;
+//cerr << "Briggs_PixelDataSource: \t surround_value = " << dec << (Int16)surround_value << endl;
+				}
+				else {
+					Int32 difference=average_command_level-median_command_level;
+//cerr << "Briggs_PixelDataSource: \t difference = " << dec << difference << endl;
+					surround_value=surround_percent*difference/100 + median_command_level;
+//cerr << "Briggs_PixelDataSource: \t average_command_level = " << dec << average_command_level << endl;
+//cerr << "Briggs_PixelDataSource: \t median_command_level = " << dec << median_command_level << endl;
+//cerr << "Briggs_PixelDataSource: \t surround_value = " << dec << surround_value << endl;
+				}
+
+				if (inverted) {
+					light_value=range-(light_value-minval)+minval;
+					dark_value=range-(dark_value-minval)+minval;
+					surround_value=range-(dark_value-minval)+minval;
+				}
+
+cerr << "Briggs_PixelDataSource: \t rank = " << dec << rank << endl;
+
+				if (signedpixrep) {
+cerr << "Briggs_PixelDataSource: \t light_value = " << dec << (Int16)light_value << endl;
+cerr << "Briggs_PixelDataSource: \t dark_value = " << dec << (Int16)dark_value << endl;
+cerr << "Briggs_PixelDataSource: \t surround_value = " << dec << (Int16)surround_value << endl;
+					Assert((Int16)light_value >= minval);
+					Assert((Int16)light_value <= maxval);
+					Assert((Int16)dark_value >= minval);
+					Assert((Int16)dark_value <= maxval);
+					Assert((Int16)surround_value >= minval);
+					Assert((Int16)surround_value <= maxval);
+				}
+				else {
+cerr << "Briggs_PixelDataSource: \t light_value = " << dec << light_value << endl;
+cerr << "Briggs_PixelDataSource: \t dark_value = " << dec << dark_value << endl;
+cerr << "Briggs_PixelDataSource: \t surround_value = " << dec << surround_value << endl;
+					Assert(light_value >= minval);
+					Assert(light_value <= maxval);
+					Assert(dark_value >= minval);
+					Assert(dark_value <= maxval);
+					Assert(surround_value >= minval);
+					Assert(surround_value <= maxval);
+				}
+
+				generate_bpt4(buffer,columns,rows,
+					target_table[target].tlhc_col,target_table[target].tlhc_row,target_table[target].rotation,
+					light_value,dark_value,surround_value);
+			}
+		}
+
+	~Briggs_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			bufptr+=columns;
+			++row;
+			return columns;
+		}
+
+	const Uint16 *getBuffer(void)
+		{
+			Assert (bufptr >= buffer);	// Just in case someone calls getBuffer() without read()
+			return bufptr;
+		}
+
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return row < rows; }
+};
+
+
+#endif // __Header_BriggsSrc__
diff --git a/libsrc/include/pixeldat/briggsrc.h.ptrrotate b/libsrc/include/pixeldat/briggsrc.h.ptrrotate
new file mode 100755
index 0000000..63f4a62
--- /dev/null
+++ b/libsrc/include/pixeldat/briggsrc.h.ptrrotate
@@ -0,0 +1,195 @@
+#ifndef __Header_BriggsSrc__
+#define __Header_BriggsSrc__
+
+#include "srcsink.h"
+
+// The following is the standard (unrotated) target).
+//
+// Checkerboard TLHC origin is defined relative to 0\0 origin
+//
+// Other targets are derived by rotating by 90,180,270 degrees
+// bearing in mind that the actual TLHC checker of each checkerboard
+// should be light (ie. because of even number of checkers B-80 and
+// B-90 need special attention)
+
+
+static const int bpt4_width  = 128;
+static const int bpt4_height = 256;
+static const int bpt4_checkerboards_per_target = 17;
+
+struct bpt4_parameter_entry {
+	unsigned short score;
+	unsigned short checkers_per_board;
+	unsigned short pixels_per_checker;
+	unsigned short tlhc_col;
+	unsigned short tlhc_row;
+} bpt4_parameter_table[bpt4_checkerboards_per_target] = {
+	90,	2,	1,	51,	188,
+	85,	3,	1,	38,	187,
+	80,	4,	1,	38,	200,
+	75,	5,	1,	52,	202,
+	70,	7,	1,	67,	200,
+	65,	11,	1,	63,	180,
+	60,	5,	2,	60,	160,
+	55,	7,	2,	36,	160,
+	50,	5,	3,	11,	160,
+	45,	5,	4,	8,	185,
+	40,	3,	7,	19,	215,
+	35,	3,	8,	50,	217,
+	30,	3,	10,	84,	209,
+	25,	3,	13,	84,	160,
+	20,	3,	16,	75,	102,
+	15,	3,	20,	4,	90,
+	10,	3,	25,	4,	4
+};
+
+static void
+generate_bpt4_0_degrees(Uint16 *matrix,unsigned width, unsigned height,
+			unsigned put_at_col,unsigned put_at_row,
+			Uint16 light_value,Uint16 dark_value,Uint16 surround_value)
+{
+	Assert(matrix);
+	Assert(put_at_col+bpt4_width <= width);
+	Assert(put_at_row+bpt4_height <= height);
+
+	unsigned row;
+	unsigned col;
+	for (row=put_at_row; row < put_at_row+bpt4_height; ++row) {
+		 for (col=put_at_col; col < put_at_col+bpt4_width; ++col) {
+			Assert(col<width);
+			Assert(row<height);
+			*(matrix+row*width+col)=surround_value;
+		}
+	}
+
+	unsigned checkerboard;
+	for (checkerboard=0; checkerboard<bpt4_checkerboards_per_target; ++checkerboard) {
+		unsigned ncheckers=bpt4_parameter_table[checkerboard].checkers_per_board;
+		unsigned start_row=put_at_row+bpt4_parameter_table[checkerboard].tlhc_row;
+		unsigned start_col=put_at_col+bpt4_parameter_table[checkerboard].tlhc_col;
+		unsigned checker_height=bpt4_parameter_table[checkerboard].pixels_per_checker;
+		unsigned checker_width =bpt4_parameter_table[checkerboard].pixels_per_checker;
+		bool first_checker_in_row_is_light=true;
+		unsigned row_checker_count;
+		for (row_checker_count=0; row_checker_count<ncheckers; ++row_checker_count) {
+			bool next_checker_in_row_is_light=first_checker_in_row_is_light;
+			unsigned col_checker_count;
+			for (col_checker_count=0; col_checker_count<ncheckers; ++col_checker_count) {
+				// make an entire checker ...
+				Uint16 value = next_checker_in_row_is_light ? light_value : dark_value;
+				unsigned first_row=start_row+checker_height*row_checker_count;
+				unsigned last_row=start_row+checker_height*(row_checker_count+1)-1;
+				unsigned first_col=start_col+checker_width*col_checker_count;
+				unsigned last_col=start_col+checker_width*(col_checker_count+1)-1;
+				for (row=first_row; row <= last_row; ++row) {
+		 			for (col=first_col; col <= last_col; ++col) {
+						Assert(col<width);
+						Assert(row<height);
+						*(matrix+row*width+col)=value;
+					}
+				}
+				next_checker_in_row_is_light=!next_checker_in_row_is_light;
+			}
+			first_checker_in_row_is_light=!first_checker_in_row_is_light;
+		}
+	
+	}
+}
+
+
+
+
+
+
+
+class Briggs_PixelDataSource : public SourceBase<Uint16> {
+protected:
+	Uint16 rows;
+	Uint16 columns;
+
+	Int32  minval;
+	Int32  maxval;
+
+	Uint16 row;
+	Uint16 *buffer;
+	Uint16 *bufptr;
+
+public:
+	Briggs_PixelDataSource(Uint16 r,Uint16 c,Uint16 minv,Uint16 maxv,Uint16 contrast,Uint16 surround_percent)
+			: SourceBase<Uint16>()
+		{
+cerr << "Briggs_PixelDataSource: contrast = " << dec << contrast << endl;
+cerr << "Briggs_PixelDataSource: surround_percent = " << dec << surround_percent << endl;
+
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+			Assert(surround_percent<=100);
+
+			minval=(Uint32)minv;
+			maxval=(Uint32)maxv;
+			Assert (maxv > minv);
+			Uint32 range=maxv-minv;
+
+cerr << "Briggs_PixelDataSource: minval = " << dec << minval << endl;
+cerr << "Briggs_PixelDataSource: maxval = " << dec << maxval << endl;
+cerr << "Briggs_PixelDataSource: range = " << dec << range << endl;
+
+			Assert(contrast <= range);
+
+			unsigned short rank=8;
+			unsigned short ntargets=8;
+			Uint16 light_value= (rank-1)*(range-contrast)/(ntargets > 1 ? ntargets-1 : 1)+contrast;
+			Uint16 dark_value = (rank-1)*(range-contrast)/(ntargets > 1 ? ntargets-1 : 1);	// ie. light_value-contrast
+			Uint16 background_value = ((surround_percent*(light_value+dark_value)+(100-surround_percent)*range)/2+50)/100;
+
+cerr << "Briggs_PixelDataSource: rank = " << dec << rank << endl;
+cerr << "Briggs_PixelDataSource: ntargets = " << dec << ntargets << endl;
+cerr << "Briggs_PixelDataSource: light_value = " << dec << light_value << endl;
+cerr << "Briggs_PixelDataSource: dark_value = " << dec << dark_value << endl;
+cerr << "Briggs_PixelDataSource: background_value = " << dec << background_value << endl;
+
+			Assert(light_value >= minval);
+			Assert(light_value <= maxval);
+			Assert(dark_value >= minval);
+			Assert(dark_value <= maxval);
+			Assert(background_value >= minval);
+			Assert(background_value <= maxval);
+
+			// Allocate and buffer the entire array, not just one row ...
+
+			row=0;
+			buffer=new Uint16[c*r];
+			Assert(buffer);
+			bufptr=buffer-columns;		// position BEFORE buffer, since 1st "read" increments it
+
+			generate_bpt4_0_degrees(buffer,columns,rows,0,0,light_value,dark_value,background_value);
+		}
+
+	~Briggs_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			bufptr+=columns;
+			++row;
+			return columns;
+		}
+
+	const Uint16 *getBuffer(void)
+		{
+			Assert (bufptr >= buffer);	// Just in case someone calls getBuffer() without read()
+			return bufptr;
+		}
+
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return row < rows; }
+};
+
+
+#endif // __Header_BriggsSrc__
diff --git a/libsrc/include/pixeldat/cnvbit.h b/libsrc/include/pixeldat/cnvbit.h
new file mode 100644
index 0000000..8d6f31f
--- /dev/null
+++ b/libsrc/include/pixeldat/cnvbit.h
@@ -0,0 +1,191 @@
+/* cnvbit.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ConvertBit__
+#define __Header_ConvertBit__
+
+// Create a class to change srcbitsstored length words (in low order bits)
+// into dstbitsstored length words (in low order bits)
+// (whose byte order is already that of the host)
+//
+// Note that only up to 16 bits are supported
+// Note that srcbitsstored may be > or = or < dstbitsstored
+
+// Supporting classes ....
+
+class ConvertBitUint16Base {
+protected:
+	SourceBase<Uint16> *source;
+public:
+	ConvertBitUint16Base(SourceBase<Uint16>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const Uint16 *getBuffer(void) 		= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class ConvertBitUint16Same : public ConvertBitUint16Base {
+	const Uint16 *buffer;
+	size_t length;
+public:
+	ConvertBitUint16Same(SourceBase<Uint16>& i,unsigned short,unsigned short)
+			: ConvertBitUint16Base(i)
+		{
+//cerr << "ConvertBitUint16Same::ConvertBitUint16Same" << endl;
+			buffer=0;
+			length=0;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				buffer=(const Uint16 *)source->getBuffer();
+				length=source->getBufferCount();
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class ConvertBitUint16Shrink : public ConvertBitUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+	Uint16 mask;
+	unsigned short rightshift;
+public:
+	ConvertBitUint16Shrink(SourceBase<Uint16>& i,unsigned short srcbitsstored,unsigned short dstbitsstored)
+			:ConvertBitUint16Base(i)
+		{
+//cerr << "ConvertBitUint16Shrink::ConvertBitUint16Shrink: from " << dec << srcbitsstored << " to " << dstbitsstored << endl;
+			buffer=0;
+			bufsize=0;
+			length=0;
+
+			Assert(srcbitsstored>dstbitsstored);
+			rightshift=srcbitsstored-dstbitsstored;
+			mask=(Uint16)(((Uint32)1<<dstbitsstored)-1);
+		}
+
+	~ConvertBitUint16Shrink()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				length=source->getBufferCount();
+
+				if (bufsize < length) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=length;
+					buffer=new Uint16[bufsize];
+				}
+
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				size_t n=length;
+				while (n--) *dst++=(*src++>>rightshift)&mask;
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class ConvertBitUint16Expand : public ConvertBitUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+	Uint16 mask;
+	unsigned short leftshift;
+public:
+	ConvertBitUint16Expand(SourceBase<Uint16>& i,unsigned short srcbitsstored,unsigned short dstbitsstored)
+			:ConvertBitUint16Base(i)
+		{
+//cerr << "ConvertBitUint16Expand::ConvertBitUint16Expand: from " << dec << srcbitsstored << " to " << dstbitsstored << endl;
+			buffer=0;
+			bufsize=0;
+			length=0;
+
+			Assert(dstbitsstored>srcbitsstored);
+			leftshift=dstbitsstored-srcbitsstored;
+			mask=(Uint16)(((Uint32)1<<dstbitsstored)-1);
+
+			// replicating to fill low order bits not implemented yet ... use zeroes
+		}
+
+	~ConvertBitUint16Expand()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				length=source->getBufferCount();
+
+				if (bufsize < length) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=length;
+					buffer=new Uint16[bufsize];
+				}
+
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				size_t n=length;
+				while (n--) *dst++=(*src++<<leftshift)&mask;
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+// These are the classes that are actually used as filters ...
+
+class ConvertBitUint16 : public FilterSourceToSinkBase<Uint16,Uint16> {
+	ConvertBitUint16Base *convertor;
+public:
+	ConvertBitUint16(SourceBase<Uint16>& i,
+			unsigned short srcbitsstored,unsigned short dstbitsstored)
+		: FilterSourceToSinkBase<Uint16,Uint16>(i)
+		{
+			Assert(srcbitsstored <= 16u);
+			Assert(dstbitsstored <= 16u);
+
+			if (srcbitsstored < dstbitsstored) {
+				convertor=new ConvertBitUint16Expand(i,srcbitsstored,dstbitsstored);
+			}
+			else if (srcbitsstored > dstbitsstored) {
+				convertor=new ConvertBitUint16Shrink(i,srcbitsstored,dstbitsstored);
+			}
+			else {
+				convertor=new ConvertBitUint16Same(i,srcbitsstored,dstbitsstored);
+			}
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const Uint16 *getBuffer(void) 		{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_ConvertBit__
diff --git a/libsrc/include/pixeldat/frombyte.h b/libsrc/include/pixeldat/frombyte.h
new file mode 100644
index 0000000..ec9da86
--- /dev/null
+++ b/libsrc/include/pixeldat/frombyte.h
@@ -0,0 +1,204 @@
+/* frombyte.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_FromByte__
+#define __Header_FromByte__
+
+// Create a class to convert words from a specified byte order
+// to the host native byte order, making the choice of whether
+// or not to swap the bytes as infrequently as possible, but
+// still automatically at run-time
+
+// NB. This implementation does not require that sizeof(Uint16) == 2
+// but is optimized for that case ...
+
+// Supporting classes ....
+
+class ConvertByteToUint16Base {
+protected:
+	SourceBase<unsigned char> *source;
+public:
+	ConvertByteToUint16Base(SourceBase<unsigned char>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const Uint16 *getBuffer(void) 		= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class ConvertUnswappedByteToUint16 : public ConvertByteToUint16Base {
+	const Uint16 *buffer;
+	size_t length;
+public:
+	ConvertUnswappedByteToUint16(SourceBase<unsigned char>& i)
+			: ConvertByteToUint16Base(i)
+		{
+			buffer=0;
+			length=0;
+		}
+
+	size_t read(void)
+		{
+//cerr << "ConvertUnswappedByteToUint16::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+//cerr << "ConvertUnswappedByteToUint16::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+//cerr << "ConvertUnswappedByteToUint16::read(void) " << n << " values\n" << flush;
+				buffer=(const Uint16 *)source->getBuffer();
+				length=n/2;
+			}
+			else length=0;
+//cerr << "ConvertUnswappedByteToUint16::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class ConvertSwappedByteToUint16 : public ConvertByteToUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+public:
+	ConvertSwappedByteToUint16(SourceBase<unsigned char>& i)
+			: ConvertByteToUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~ConvertSwappedByteToUint16()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+//cerr << "ConvertSwappedByteToUint16::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+//cerr << "ConvertSwappedByteToUint16::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+//cerr << "ConvertSwappedByteToUint16::read(void) " << n << " values\n" << flush;
+				Assert(n%2==0);
+				n=n/2;
+				if (bufsize < n+1) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=n+1;
+					buffer=new Uint16[bufsize];
+				}
+				length=n;
+				const unsigned char *src=source->getBuffer();
+				unsigned char *base=(unsigned char *)buffer;
+				memcpy(base+1,src,n*2);
+				while (n--) { *base=*(base+2); base+=2; }
+			}
+			else length=0;
+//cerr << "ConvertSwappedByteToUint16::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+template <class T>
+class ConvertEachByteToUint16 : public ConvertByteToUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+public:
+	ConvertEachByteToUint16(SourceBase<unsigned char>& i)
+			: ConvertByteToUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~ConvertEachByteToUint16()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+//cerr << "ConvertEachByteToUint16::read(void)\n" << flush;
+			Assert(source);
+//cerr << "ConvertEachByteToUint16::read(void) sizeof(T)" << sizeof(T) << "\n" << flush;
+			if (source->read()) {
+//cerr << "ConvertEachByteToUint16::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+				Assert(n%sizeof(T) == 0);
+				n=n/sizeof(T);
+//cerr << "ConvertEachByteToUint16::read(void) " << n << " values\n" << flush;
+				if (bufsize < n) {
+//cerr << "ConvertEachByteToUint16::read(void) reallocating buffer from " << bufsize << " to " << n << "\n" << flush;
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=n;
+					buffer=new Uint16[bufsize];
+				}
+				length=n;
+				const T *src=(const T *)source->getBuffer();
+				Uint16 *ptr = buffer;
+				while (n--) *ptr++=*src++;
+			}
+			else length=0;
+//cerr << "ConvertEachByteToUint16::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+// These are the classes that are actually used as filters ...
+
+class ConvertByteToUint16 : public FilterSourceToSinkBase<unsigned char,Uint16> {
+	ConvertByteToUint16Base *convertor;
+public:
+	ConvertByteToUint16(SourceBase<unsigned char>& i,Endian wanted)
+			: FilterSourceToSinkBase<unsigned char,Uint16>(i)
+		{
+			Assert(wanted != NoEndian);
+			if (wanted == ByteEndian)
+				convertor=new ConvertEachByteToUint16<unsigned char>(i);
+			else if (sizeof(Uint16) == 2) {
+//cerr << "ConvertEachByteToUint16::wanted = " << (wanted == LittleEndian ? "Little" : "Big") << endl;
+				HostEndian hostendian;
+				if (wanted == hostendian.getEndian()) {
+//cerr << "ConvertEachByteToUint16::unswapped" << endl;
+					convertor=new ConvertUnswappedByteToUint16(i);
+				}
+				else {
+//cerr << "ConvertEachByteToUint16::swapped" << endl;
+					convertor=new ConvertSwappedByteToUint16(i);
+				}
+			}
+			else {
+				if (wanted == BigEndian) {
+//cerr << "ConvertEachByteToUint16::manual big" << endl;
+					convertor=new ConvertEachByteToUint16<Uint16_B>(i);
+				}
+				else {
+//cerr << "ConvertEachByteToUint16::manual little" << endl;
+					convertor=new ConvertEachByteToUint16<Uint16_L>(i);
+				}
+			}
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const Uint16 *getBuffer(void) 		{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_FromByte__
diff --git a/libsrc/include/pixeldat/frompack.h b/libsrc/include/pixeldat/frompack.h
new file mode 100644
index 0000000..6b90415
--- /dev/null
+++ b/libsrc/include/pixeldat/frompack.h
@@ -0,0 +1,193 @@
+/* frompack.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_FromPack__
+#define __Header_FromPack__
+
+// Create a class to unpack bitsallocated length words from within
+// 16 bit words (whose byte order is already that of the host)
+
+// Supporting classes ....
+
+class UnpackUint16Base {
+protected:
+	SourceBase<Uint16> *source;
+public:
+	UnpackUint16Base(SourceBase<Uint16>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const Uint16 *getBuffer(void) 		= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class UnpackUint16From16 : public UnpackUint16Base {
+	const Uint16 *buffer;
+	size_t length;
+public:
+	UnpackUint16From16(SourceBase<Uint16>& i)
+			: UnpackUint16Base(i)
+		{
+			buffer=0;
+			length=0;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				buffer=(const Uint16 *)source->getBuffer();
+				length=source->getBufferCount();
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class UnpackUint16From12 : public UnpackUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+public:
+	UnpackUint16From12(SourceBase<Uint16>& i)
+			: UnpackUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~UnpackUint16From12()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "UnpackUint16From12::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "UnpackUint16From12::read(void) success\n" << flush;
+				unsigned long n=source->getBufferCount();
+				//cerr << "UnpackUint16From12::read(void) " << n << " source words\n" << flush;
+				Assert((n*4)%3==0);
+				n=(n*4)/3;
+				//cerr << "UnpackUint16From12::read(void) " << n << " dest words\n" << flush;
+				if (bufsize < n) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=(size_t)n;
+					buffer=new Uint16[bufsize];
+				}
+				length=(size_t)n;
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				while (n) {
+					*dst++= *(src  )        & 0x0fff;
+					*dst++=(*(src  ) >> 12) & 0x000f
+					      |(*(src+1) << 4 ) & 0x0ff0;
+					*dst++=(*(src+1) >> 8 ) & 0x00ff
+					      |(*(src+2) << 8 ) & 0x0f00;
+					*dst++=(*(src+2) >> 4 ) & 0x0fff;
+					src+=3;
+					n-=4;
+				}
+			}
+			else length=0;
+			//cerr << "UnpackUint16From12::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class UnpackUint16From8 : public UnpackUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+public:
+	UnpackUint16From8(SourceBase<Uint16>& i)
+			: UnpackUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~UnpackUint16From8()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "UnpackUint16From8::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "UnpackUint16From8::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+				//cerr << "UnpackUint16From8::read(void) " << n << " source words\n" << flush;
+				n=n*2;
+				//cerr << "UnpackUint16From8::read(void) " << n << " dest words\n" << flush;
+				if (bufsize < n) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=n;
+					buffer=new Uint16[bufsize];
+				}
+				length=n;
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				while (n) {
+					*dst++= *(src  )        & 0x00ff;
+					*dst++=(*(src  ) >> 8 ) & 0x00ff;
+					++src;
+					n-=2;
+				}
+			}
+			else length=0;
+			//cerr << "UnpackUint16From8::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+
+// These are the classes that are actually used as filters ...
+
+class UnpackUint16 : public FilterSourceToSinkBase<Uint16,Uint16> {
+	UnpackUint16Base *convertor;
+public:
+	UnpackUint16(SourceBase<Uint16>& i,
+			unsigned short bitsallocated)
+		: FilterSourceToSinkBase<Uint16,Uint16>(i)
+		{
+			Assert(bitsallocated <= 16);
+
+			if (bitsallocated == 16)
+				convertor=new UnpackUint16From16(i);
+			else if (bitsallocated == 12)
+				convertor=new UnpackUint16From12(i);
+			else if (bitsallocated == 8)
+				convertor=new UnpackUint16From8(i);
+			else
+				convertor=0;
+
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const Uint16 *getBuffer(void) 		{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_FromPack__
diff --git a/libsrc/include/pixeldat/fromshft.h b/libsrc/include/pixeldat/fromshft.h
new file mode 100644
index 0000000..704f667
--- /dev/null
+++ b/libsrc/include/pixeldat/fromshft.h
@@ -0,0 +1,104 @@
+/* fromshft.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_FromShift__
+#define __Header_FromShift__
+
+// Create a class to extract bitsstored length words starting at highbit
+// from within 16 bit words (whose byte order is already that of the host)
+
+// handles shifting so lsb is in bit 0
+// doesn't yet handle sign extension
+
+// Supporting classes ....
+
+class UnshiftUint16Base {
+protected:
+	SourceBase<Uint16> *source;
+public:
+	UnshiftUint16Base(SourceBase<Uint16>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const Uint16 *getBuffer(void) 		= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class UnshiftUint16General : public UnshiftUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+	Uint16 mask;
+	unsigned short rightshift;
+public:
+	UnshiftUint16General(SourceBase<Uint16>& i,unsigned short bitsstored,unsigned short highbit)
+			:UnshiftUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+
+			mask=(Uint16)(((Uint32)1<<bitsstored)-1);
+			rightshift=highbit+1-bitsstored;
+
+			// sign extension not implemented yet
+		}
+
+	~UnshiftUint16General()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				length=source->getBufferCount();
+
+				if (bufsize < length) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=length;
+					buffer=new Uint16[bufsize];
+				}
+
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				size_t n=length;
+				while (n--) *dst++=(*src++>>rightshift)&mask;
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+// These are the classes that are actually used as filters ...
+
+class UnshiftUint16 : public FilterSourceToSinkBase<Uint16,Uint16> {
+	UnshiftUint16Base *convertor;
+public:
+	UnshiftUint16(SourceBase<Uint16>& i,
+			unsigned short bitsallocated,unsigned short bitsstored,unsigned short highbit)
+		: FilterSourceToSinkBase<Uint16,Uint16>(i)
+		{
+			Assert(bitsallocated <= 16u);
+			Assert(bitsstored <= bitsallocated);
+			Assert(highbit <= bitsallocated-1u);
+
+			// no optimizations yet ...
+			convertor=new UnshiftUint16General(i,bitsstored,highbit);
+
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const Uint16 *getBuffer(void) 		{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_FromShift__
diff --git a/libsrc/include/pixeldat/makesmptetxt b/libsrc/include/pixeldat/makesmptetxt
new file mode 100755
index 0000000..6591140
--- /dev/null
+++ b/libsrc/include/pixeldat/makesmptetxt
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+TMPFILE="/tmp/$0.tmp.$$"
+
+if [ $# = 1 ]
+then
+	prefix="$1"
+else
+	echo "Usage: $0 prefix"
+	exit 1
+fi
+
+doonestring()	# Usage: doonestring prefix suffix string
+(
+	pbmtext "$3" | pnmcrop -quiet | pbmtoxbm | \
+		sed -e "s/noname/$1_$2/" \
+		    -e 's/^#define/static const unsigned short/' \
+		    -e 's/\([0-9]\)$/\1;/' \
+		    -e 's/_width /_width = /' \
+		    -e 's/_height /_height = /' \
+		    -e 's/static char/static const unsigned char/'
+	echo
+)
+
+doonestring "$prefix" "0percent"  "0%"
+doonestring "$prefix" "5percent"  "5%"
+doonestring "$prefix" "10percent" "10%"
+doonestring "$prefix" "20percent" "20%"
+doonestring "$prefix" "30percent" "30%"
+doonestring "$prefix" "40percent" "40%"
+doonestring "$prefix" "50percent" "50%"
+doonestring "$prefix" "60percent" "60%"
+doonestring "$prefix" "70percent" "70%"
+doonestring "$prefix" "80percent" "80%"
+doonestring "$prefix" "90percent" "90%"
+doonestring "$prefix" "95percent" "95%"
+doonestring "$prefix" "100percent" "100%"
+doonestring "$prefix" "smpte" "SMPTE TEST PATTERN"
+doonestring "$prefix" "revision" "Rev. 3/1/91 Copyright 1983"
diff --git a/libsrc/include/pixeldat/memsrc.h b/libsrc/include/pixeldat/memsrc.h
new file mode 100644
index 0000000..5cb7056
--- /dev/null
+++ b/libsrc/include/pixeldat/memsrc.h
@@ -0,0 +1,58 @@
+/* memsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_MemSrc__
+#define __Header_MemSrc__
+
+#include "srcsink.h"
+
+template<class T>
+class Memory_PixelDataSource : public SourceBase<T> {
+protected:
+	Uint16 rows;
+	Uint16 columns;
+
+	Uint16 row;
+	T *buffer;
+	T *bufptr;
+
+public:
+	Memory_PixelDataSource(Uint16 r,Uint16 c,T *srcbuffer)	// Takes ownership of srcbuffer memory
+			: SourceBase<T>()
+		{
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+			// Allocate and buffer the entire array, not just one row ...
+
+			buffer=srcbuffer;
+			Assert(buffer);
+			bufptr=buffer-columns;		// position BEFORE buffer, since 1st "read" increments it
+			row=0;
+		}
+
+	~Memory_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			bufptr+=columns;
+			++row;
+			return columns;
+		}
+
+	const T *getBuffer(void)
+		{
+			Assert (bufptr >= buffer);	// Just in case someone calls getBuffer() without read()
+			return bufptr;
+		}
+
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return row < rows; }
+};
+
+
+#endif // __Header_MemSrc__
diff --git a/libsrc/include/pixeldat/rawsrc.h b/libsrc/include/pixeldat/rawsrc.h
new file mode 100644
index 0000000..5c73f41
--- /dev/null
+++ b/libsrc/include/pixeldat/rawsrc.h
@@ -0,0 +1,156 @@
+/* rawsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_RawSrc__
+#define __Header_RawSrc__
+
+#include "srcsink.h"
+
+class Raw_PixelDataSourceBase : public SourceBase<Uint16> {
+protected:
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 frames;
+	Uint16 samples;
+
+	Uint32 totalrows;
+	Uint32 row;
+	Uint16 col;
+	Uint16 frame;
+	Uint16 *buffer;
+public:
+	Raw_PixelDataSourceBase(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			frames=f;
+			Assert(frames);
+			samples=s;
+			Assert(samples);
+
+			totalrows=((Uint32)rows)*frames;
+			row=0;
+			col=0;
+			frame=0;
+			buffer=new Uint16[c*s];
+			Assert(buffer);
+		}
+
+	virtual ~Raw_PixelDataSourceBase()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	virtual size_t read(void) = 0;
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+
+	size_t getBufferCount(void) const	{ return col*samples; }
+
+	int good(void) const	{ return istr && istr->good() && row < totalrows; }
+};
+
+class Raw_PixelDataSource_LittleEndian : public Raw_PixelDataSourceBase {
+public:
+	Raw_PixelDataSource_LittleEndian(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s)
+			: Raw_PixelDataSourceBase(i,off,r,c,f,s)
+		{}
+
+	size_t read(void)
+		{
+			if (row == 0 && frame == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= totalrows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				Uint16 sample=0;
+				while (sample < samples) {
+					unsigned char bytes[2];
+					istr->read((char *)bytes,2);
+					if (!istr->good()) return 0;
+					// Little endian ...
+					Uint16 pixel;
+					pixel=(bytes[1]<<8)|bytes[0];
+					*ptr++=pixel; ++sample;
+				}
+				++col;
+			}
+			return col*samples;
+		}
+};
+
+class Raw_PixelDataSource_BigEndian : public Raw_PixelDataSourceBase {
+public:
+	Raw_PixelDataSource_BigEndian(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s)
+			: Raw_PixelDataSourceBase(i,off,r,c,f,s)
+		{}
+
+	size_t read(void)
+		{
+			if (row == 0 && frame == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= totalrows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				Uint16 sample=0;
+				while (sample < samples) {
+					unsigned char bytes[2];
+					istr->read((char *)bytes,2);
+					if (!istr->good()) return 0;
+					// Big endian ...
+					Uint16 pixel;
+					pixel=(bytes[0]<<8)|bytes[1];
+					*ptr++=pixel; ++sample;
+				}
+				++col;
+			}
+			return col*samples;
+		}
+};
+
+class Raw_PixelDataSource_Byte : public Raw_PixelDataSourceBase {
+public:
+	Raw_PixelDataSource_Byte(istream& i,long off,Uint16 r,Uint16 c,
+		Uint16 f,Uint16 s)
+			: Raw_PixelDataSourceBase(i,off,r,c,f,s)
+		{}
+
+	size_t read(void)
+		{
+			if (row == 0 && frame == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= totalrows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				Uint16 sample=0;
+				while (sample < samples) {
+					unsigned char byte;
+					istr->read((char *)&byte,1);
+					if (!istr->good()) return 0;
+					*ptr++=Uint16(byte); ++sample;
+				}
+				++col;
+			}
+			return col*samples;
+		}
+};
+
+
+#endif // __Header_RawSrc__
diff --git a/libsrc/include/pixeldat/smptesrc.h b/libsrc/include/pixeldat/smptesrc.h
new file mode 100644
index 0000000..4cb2c9f
--- /dev/null
+++ b/libsrc/include/pixeldat/smptesrc.h
@@ -0,0 +1,843 @@
+/* smptesrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_SMPTESrc__
+#define __Header_SMPTESrc__
+
+#include "srcsink.h"
+#include "smptetxt.h"
+
+static const unsigned char SMPTE_Data_minval = 0;
+static const unsigned char SMPTE_Data_maxval = 100;
+
+class SMPTE_PixelDataSource : public SourceBase<Uint16> {
+protected:
+	Uint16 rows;
+	Uint16 columns;
+	bool signedpixrep;
+	bool inverted;
+	Int32  minval;
+	Uint32 src_range;
+	Uint32 dst_range;
+
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+
+	Uint16 background;
+	Uint16 linevalue;
+
+	Uint16 crosshatch_size;
+	Uint16 crosshatch_offset_row;
+	Uint16 crosshatch_offset_col;
+
+	Uint16 border_thickness;
+	Uint16 border_inset;
+
+	Uint16 left_edge;
+	Uint16 right_edge;
+	Uint16 top_edge;
+	Uint16 bottom_edge;
+
+	Uint16 percent100;
+	Uint16 percent95;
+	Uint16 percent90;
+	Uint16 percent80;
+	Uint16 percent70;
+	Uint16 percent60;
+	Uint16 percent50;
+	Uint16 percent40;
+	Uint16 percent30;
+	Uint16 percent20;
+	Uint16 percent10;
+	Uint16 percent5;
+	Uint16 percent0;
+
+	Uint16 highcontres_off;
+	Uint16 highcontres_on;
+
+	Uint16 contreslow_off;
+	Uint16 contreslow_on;
+	Uint16 contresmid_off;
+	Uint16 contresmid_on;
+	Uint16 contreshigh_off;
+	Uint16 contreshigh_on;
+
+	Uint16 resolution_block_size;
+
+	Uint16 center_pattern_right_edge;
+	Uint16 center_pattern_top_edge;
+
+	Uint16 squares_height;
+	Uint16 squares_width;
+
+	Uint16 squares_left_edge;
+	Uint16 squares_top_edge;
+
+	Uint16 strip_height;
+	Uint16 inset_height;
+
+	Uint16 strip_left_edge;
+	Uint16 strip_right_edge;
+	Uint16 top_strip_top_edge;
+	Uint16 bottom_strip_top_edge;
+
+	Uint16 inset_left_edge;
+	Uint16 inset_right_edge;
+	Uint16 top_inset_top_edge;
+	Uint16 bottom_inset_top_edge;
+
+	void write_left_justified_vertically_aligned_top_string(
+		const unsigned char *bitmap,Uint16 bitmap_cols,Uint16 bitmap_rows,
+		Uint16 left_col, Uint16 top_row,
+		Uint16 row,Uint16 col,Uint16 *ptr,
+		Uint16 on)
+		{
+			// In an XBM
+			// - the low bit is the first and the high bit the last
+			// - rows are padded to byte boundaries
+
+			if (col >= left_col && col < left_col+bitmap_cols && row >= top_row && row < top_row+bitmap_rows) {
+				Assert(row >= top_row);
+				Assert(col >= left_col);
+				unsigned short index = (row-top_row)*((bitmap_cols-1)/8+1)*8+(col-left_col);
+				//unsigned short byte_index = index/8;
+				//unsigned short bit_index = index%8;
+				//unsigned char bit = (bitmap[index/8] >> (index%8)) & 0x01;
+
+//cerr << "col=" << dec << col << " index=" << index << " byte_index=" << byte_index << " bit_index=" << bit_index << " bit=" << (unsigned)bit << endl;
+
+				if ((bitmap[index/8] >> (index%8)) & 0x01) *ptr=on;
+			}
+		}
+
+	void write_left_justified_vertically_aligned_center_string(
+		const unsigned char *bitmap,Uint16 bitmap_cols,Uint16 bitmap_rows,
+		Uint16 left_col, Uint16 vcenter,
+		Uint16 row,Uint16 col,Uint16 *ptr,
+		Uint16 on)
+		{
+			Assert(vcenter >= bitmap_rows/2);
+			unsigned short top_row=vcenter-bitmap_rows/2;
+
+			write_left_justified_vertically_aligned_top_string(bitmap,bitmap_cols,bitmap_rows,
+				left_col,top_row,
+				row,col,ptr,on);
+		}
+
+	void write_right_justified_vertically_aligned_center_string(
+		const unsigned char *bitmap,Uint16 bitmap_cols,Uint16 bitmap_rows,
+		Uint16 right_col, Uint16 vcenter,
+		Uint16 row,Uint16 col,Uint16 *ptr,
+		Uint16 on)
+		{
+			Assert(vcenter >= bitmap_rows/2);
+			unsigned short top_row=vcenter-bitmap_rows/2;
+			Assert(right_col >= bitmap_cols);
+			unsigned short left_col=right_col-bitmap_cols;
+
+			write_left_justified_vertically_aligned_top_string(bitmap,bitmap_cols,bitmap_rows,
+				left_col,top_row,
+				row,col,ptr,on);
+		}
+
+	void write_centered_vertically_aligned_center_string(
+		const unsigned char *bitmap,Uint16 bitmap_cols,Uint16 bitmap_rows,
+		Uint16 hcenter, Uint16 vcenter,
+		Uint16 row,Uint16 col,Uint16 *ptr,
+		Uint16 on)
+		{
+			Assert(vcenter >= bitmap_rows/2);
+			unsigned short top_row=vcenter-bitmap_rows/2;
+			Assert(hcenter >= bitmap_cols/2);
+			unsigned short left_col=hcenter-bitmap_cols/2;
+
+			write_left_justified_vertically_aligned_top_string(bitmap,bitmap_cols,bitmap_rows,
+				left_col,top_row,
+				row,col,ptr,on);
+		}
+
+	void write_centered_vertically_aligned_top_string(
+		const unsigned char *bitmap,Uint16 bitmap_cols,Uint16 bitmap_rows,
+		Uint16 hcenter, Uint16 top_row,
+		Uint16 row,Uint16 col,Uint16 *ptr,
+		Uint16 on)
+		{
+			Assert(hcenter >= bitmap_cols/2);
+			unsigned short left_col=hcenter-bitmap_cols/2;
+
+			write_left_justified_vertically_aligned_top_string(bitmap,bitmap_cols,bitmap_rows,
+				left_col,top_row,
+				row,col,ptr,on);
+		}
+
+	void write_centered_vertically_aligned_bottom_string(
+		const unsigned char *bitmap,Uint16 bitmap_cols,Uint16 bitmap_rows,
+		Uint16 hcenter, Uint16 bottom_row,
+		Uint16 row,Uint16 col,Uint16 *ptr,
+		Uint16 on)
+		{
+			Assert(bottom_row >= bitmap_rows);
+			unsigned short top_row=bottom_row-bitmap_rows;
+			Assert(hcenter >= bitmap_cols/2);
+			unsigned short left_col=hcenter-bitmap_cols/2;
+
+			write_left_justified_vertically_aligned_top_string(bitmap,bitmap_cols,bitmap_rows,
+				left_col,top_row,
+				row,col,ptr,on);
+		}
+
+public:
+	SMPTE_PixelDataSource(Uint16 r,Uint16 c,bool pixrep,bool inv,Uint16 minv,Uint16 maxv)
+			: SourceBase<Uint16>()
+		{
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+			signedpixrep=pixrep;
+			inverted=inv;
+
+			Assert (SMPTE_Data_maxval > SMPTE_Data_minval);
+			src_range=SMPTE_Data_maxval-SMPTE_Data_minval;
+
+			if (signedpixrep) {
+				Assert ((Int16)(maxv) > (Int16)(minv));
+				dst_range=(Int16)(maxv)-(Int16)(minv);
+				minval=(Int16)(minv);
+			}
+			else {
+				Assert (maxv > minv);
+				dst_range=maxv-minv;
+				minval=(Uint32)minv;
+			}
+
+//cerr << "minval     = 0x" << hex << minval       << " " << dec << minval     << " dec" << endl;
+//cerr << "dst_range  = 0x" << hex << dst_range    << " " << dec << dst_range  << " dec" << endl;
+
+			row=0;
+			col=0;
+			buffer=new Uint16[c];
+			Assert(buffer);
+
+			// 50% background
+			// 75% border around edges
+			// 75% cross-hatch pattern 2 pixels high and wide at 10% of height spacing
+			// Note that the cross-hatch extends outside the borders
+
+			background = (inverted ? 50l:50l)*dst_range/src_range+minval;
+			linevalue  = (inverted ? 25l:75l)*dst_range/src_range+minval;
+
+			crosshatch_size = rows / 10;		// Note: gives 51 not 50 for 512 cf. RP 133-1991
+			crosshatch_offset_row = (rows % crosshatch_size) / 2;		// Centers the cross hatch
+			crosshatch_offset_col = (columns % crosshatch_size) / 2;
+			if ((columns/crosshatch_size) % 2) crosshatch_offset_col+=crosshatch_size/2;
+
+//cerr << "crosshatch_size=" << dec << crosshatch_size << endl;
+//cerr << "crosshatch_offset_row=" << dec << crosshatch_offset_row << endl;
+//cerr << "crosshatch_offset_col=" << dec << crosshatch_offset_col << endl;
+
+			border_thickness = (rows < 400) ? 2 : (rows/200);	// 0.5% of height, not less than 2
+											// Note: gives 2 not 3 for 512 cf. RP 133-1991
+			border_inset     = (rows < 200) ? 2 : (rows/100);	// 1.0% of height, not less than 2
+
+//cerr << "border_thickness=" << dec << border_thickness << endl;
+//cerr << "border_inset=" << dec << border_inset << endl;
+
+			left_edge   = border_inset+border_thickness;		// first usable pixel
+			right_edge  = columns-border_inset-border_thickness-1;	// last  usable pixel
+			top_edge    = border_inset+border_thickness;		// first usable pixel
+			bottom_edge = rows-border_inset-border_thickness-1;	// last  usable pixel
+
+//cerr << "left_edge=" << dec << left_edge << endl;
+//cerr << "right_edge=" << dec << right_edge << endl;
+//cerr << "top_edge=" << dec << top_edge << endl;
+//cerr << "bottom_edge=" << dec << bottom_edge << endl;
+
+			// Precomputed pixel values ...
+
+			percent100=(inverted ?   0l:100l)*dst_range/src_range+minval;
+			percent95 =(inverted ?   5l: 95l)*dst_range/src_range+minval;
+			percent90 =(inverted ?  10l: 90l)*dst_range/src_range+minval;
+			percent80 =(inverted ?  20l: 80l)*dst_range/src_range+minval;
+			percent70 =(inverted ?  30l: 70l)*dst_range/src_range+minval;
+			percent60 =(inverted ?  40l: 60l)*dst_range/src_range+minval;
+			percent50 =(inverted ?  50l: 50l)*dst_range/src_range+minval;
+			percent40 =(inverted ?  60l: 40l)*dst_range/src_range+minval;
+			percent30 =(inverted ?  70l: 30l)*dst_range/src_range+minval;
+			percent20 =(inverted ?  80l: 20l)*dst_range/src_range+minval;
+			percent10 =(inverted ?  90l: 10l)*dst_range/src_range+minval;
+			percent5  =(inverted ?  95l:  5l)*dst_range/src_range+minval;
+			percent0  =(inverted ? 100l:  0l)*dst_range/src_range+minval;
+
+//cerr << "percent100 = 0x" << hex << percent100   << " " << dec << percent100 << " dec" << endl;
+//cerr << "percent95  = 0x" << hex << percent95    << " " << dec << percent95  << " dec" << endl;
+//cerr << "percent90  = 0x" << hex << percent90    << " " << dec << percent90  << " dec" << endl;
+//cerr << "percent80  = 0x" << hex << percent80    << " " << dec << percent80  << " dec" << endl;
+//cerr << "percent70  = 0x" << hex << percent70    << " " << dec << percent70  << " dec" << endl;
+//cerr << "percent60  = 0x" << hex << percent60    << " " << dec << percent60  << " dec" << endl;
+//cerr << "percent50  = 0x" << hex << percent50    << " " << dec << percent50  << " dec" << endl;
+//cerr << "percent40  = 0x" << hex << percent40    << " " << dec << percent40  << " dec" << endl;
+//cerr << "percent30  = 0x" << hex << percent30    << " " << dec << percent30  << " dec" << endl;
+//cerr << "percent20  = 0x" << hex << percent20    << " " << dec << percent20  << " dec" << endl;
+//cerr << "percent10  = 0x" << hex << percent10    << " " << dec << percent10  << " dec" << endl;
+//cerr << "percent5   = 0x" << hex << percent5     << " " << dec << percent5   << " dec" << endl;
+//cerr << "percent0   = 0x" << hex << percent0     << " " << dec << percent0   << " dec" << endl;
+
+			// High contrast resolution patterns
+
+			highcontres_off = percent0;
+			highcontres_on  = percent100;
+
+			// Low contrast resolution patterns
+
+			contreslow_off  = (inverted ? 50l:50l)*dst_range/src_range+minval;
+			contreslow_on   = (inverted ? 49l:51l)*dst_range/src_range+minval;
+			contresmid_off  = (inverted ? 52l:48l)*dst_range/src_range+minval;
+			contresmid_on   = (inverted ? 49l:51l)*dst_range/src_range+minval;
+			contreshigh_off = (inverted ? 52l:48l)*dst_range/src_range+minval;
+			contreshigh_on  = (inverted ? 47l:53l)*dst_range/src_range+minval;
+
+			resolution_block_size = rows * 25 / 400;	// 6.25% of height
+									// Note: gives 15 not 16 for 256 cf. RP 133-1991
+
+			center_pattern_right_edge = columns/2+resolution_block_size*2;
+			center_pattern_top_edge = crosshatch_size*5+crosshatch_offset_row - resolution_block_size*3/2;
+									// center between 4th and 6th horizontal cross-hatch
+
+			// Big grayscale squares and black/white strips are aligned with cross-hatch pattern
+
+			// cross-hatch interval is 10% of vertical height
+			// each square is 10%, 4 vertically (40% of vertical height) and 6 horizontally
+
+			Assert (columns > 6*crosshatch_size);	// can't do patterns if too tall and narrow
+			Assert (rows > 4*crosshatch_size);	// can't do patterns if too tall and narrow
+
+			squares_height=crosshatch_size;
+			squares_width =crosshatch_size;
+
+			squares_left_edge = ((columns-6*crosshatch_size)/2)/crosshatch_size*crosshatch_size+crosshatch_offset_col;
+			squares_top_edge  = ((rows-4*crosshatch_size)/2)/crosshatch_size*crosshatch_size+crosshatch_offset_row;
+
+			// each strip is 8%, centered in the 3rd and 8th horizontal cross-hatch areas
+			// and from the left of the 2nd to the right of the 2nd last vertical cross-hatch areas
+
+			strip_height=8*rows/100;
+			inset_height=strip_height/2;
+
+			Assert (crosshatch_size > strip_height);
+
+			strip_left_edge = crosshatch_size+crosshatch_offset_col;
+			strip_right_edge = columns-strip_left_edge+1;
+			top_strip_top_edge  = crosshatch_size*2+(crosshatch_size-strip_height)/2+crosshatch_offset_row+1;
+			bottom_strip_top_edge  = crosshatch_size*7+(crosshatch_size-strip_height)/2+crosshatch_offset_row+1;
+
+			Assert (strip_right_edge > strip_left_edge);
+
+			inset_left_edge = strip_left_edge + (strip_right_edge-strip_left_edge)/4;
+			inset_right_edge = strip_right_edge - (strip_right_edge-strip_left_edge)/4;
+			top_inset_top_edge  = top_strip_top_edge + strip_height/4;
+			bottom_inset_top_edge  = bottom_strip_top_edge + strip_height/4;
+
+
+		}
+
+	~SMPTE_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			col=0;
+			if (row >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+
+				// Do background, border and cross-hatch pattern
+
+				if (col >= border_inset && col < left_edge && row >= border_inset && row < rows-border_inset		// left border
+				 || col > right_edge && col < columns-border_inset && row >= border_inset && row < rows-border_inset	// right border
+				 || row >= border_inset && row < top_edge && col >= border_inset && col < columns-border_inset		// top border
+				 || row > bottom_edge && row < rows-border_inset && col >= border_inset && col < columns-border_inset	// bottom border
+				 || col%crosshatch_size == crosshatch_offset_col		// 1st pixel of vertical crosshatch
+				 || col%crosshatch_size == crosshatch_offset_col+1		// 2nd pixel of vertical crosshatch
+				 || row%crosshatch_size == crosshatch_offset_row		// 1st pixel of horizontal crosshatch
+				 || row%crosshatch_size == crosshatch_offset_row+1		// 2nd pixel of horizontal crosshatch
+				) {
+//cerr << "border at row=" << dec << row << " col=" << col << endl;
+					*ptr=linevalue;
+				}
+				else {
+					*ptr=background;
+				}
+
+				// Do long thin white or black strips ("windows" in RP 133-1991)
+
+				if (col >= strip_left_edge && col <= strip_right_edge) {
+					if (row >= top_strip_top_edge && row < top_strip_top_edge+strip_height) {
+						if (row >= top_inset_top_edge && row < top_inset_top_edge+inset_height
+				 		 && col >= inset_left_edge && col <= inset_right_edge) {
+							*ptr=percent0;
+						}
+						else {
+							*ptr=percent100;
+						}
+					}
+					else if (row >= bottom_strip_top_edge && row < bottom_strip_top_edge+strip_height) {
+						if (row >= bottom_inset_top_edge && row < bottom_inset_top_edge+inset_height
+				 		 && col >= inset_left_edge && col <= inset_right_edge) {
+							*ptr=percent100;
+						}
+						else {
+							*ptr=percent0;
+						}
+					}
+				}
+
+				// Do big grayscale squares aligned with cross-hatch pattern
+
+				// the choice of < or <= and > or >= and the occasional +1 are to cover 2 pixel wide cross-hatches
+
+				if (row >= squares_top_edge && row <= squares_top_edge+squares_height+1) {
+					if (col >= squares_left_edge && col <= squares_left_edge+squares_width+1) {
+						*ptr=percent30;
+					}
+					else if (col >= squares_left_edge+squares_width && col <= squares_left_edge+2*squares_width) {
+						*ptr=percent40;
+					}
+					else if (col >= squares_left_edge+2*squares_width && col <= squares_left_edge+4*squares_width) {
+						// two squares
+						*ptr=percent50;
+					}
+					else if (col >= squares_left_edge+4*squares_width && col <= squares_left_edge+5*squares_width) {
+						*ptr=percent60;
+					}
+					else if (col >= squares_left_edge+5*squares_width && col <= squares_left_edge+6*squares_width+1) {
+						*ptr=percent70;
+					}
+				}
+				else if (row > squares_top_edge+squares_height && row <= squares_top_edge+2*squares_height) {
+					if (col >= squares_left_edge && col <= squares_left_edge+squares_width+1) {
+						*ptr=percent20;
+					}
+					else if (col >= squares_left_edge+5*squares_width && col <= squares_left_edge+6*squares_width+1) {
+						*ptr=percent80;
+					}
+				}
+				else if (row > squares_top_edge+2*squares_height && row < squares_top_edge+3*squares_height) {
+					if (col >= squares_left_edge && col <= squares_left_edge+squares_width+1) {
+						*ptr=percent10;
+					}
+					else if (col >= squares_left_edge+5*squares_width && col <= squares_left_edge+6*squares_width+1) {
+						*ptr=percent90;
+					}
+				}
+				else if (row > squares_top_edge+3*squares_height-1 && row <= squares_top_edge+4*squares_height+1) {
+					if (col >= squares_left_edge && col <= squares_left_edge+squares_width) {
+						*ptr=percent0;
+					}
+					else if (col > squares_left_edge+squares_width && col <= squares_left_edge+2*squares_width) {
+						if (row > squares_top_edge+13*squares_height/4 && row <= squares_top_edge+15*squares_height/4
+						 && col > squares_left_edge+5*squares_width/4 && col <= squares_left_edge+7*squares_width/4) {
+							*ptr=percent5;
+						}
+						else {
+							*ptr=percent0;
+						}
+					}
+					else if (col > squares_left_edge+2*squares_width && col <= squares_left_edge+4*squares_width) {
+						*ptr=percent0;
+					}
+					else if (col > squares_left_edge+4*squares_width && col <= squares_left_edge+5*squares_width) {
+						if (row > squares_top_edge+13*squares_height/4 && row <= squares_top_edge+15*squares_height/4
+						 && col > squares_left_edge+17*squares_width/4 && col <= squares_left_edge+19*squares_width/4) {
+							*ptr=percent95;
+						}
+						else {
+							*ptr=percent100;
+						}
+					}
+					else if (col > squares_left_edge+5*squares_width && col <= squares_left_edge+6*squares_width+1) {
+						*ptr=percent100;
+					}
+				}
+
+
+				// Do high contrast resolution patterns in corners
+				// highest is 1 on 1 off
+				// middle  is 2 on 2 off
+				// lowest  is 3 on 3 off
+
+				
+				// horizontal high contrast resolution
+
+				if (col >= left_edge && col < left_edge+resolution_block_size
+				 || col > right_edge-resolution_block_size && col <= right_edge) {
+
+					// Top ...
+
+					if (row >= top_edge && row < top_edge+resolution_block_size) {
+						*ptr=(row-top_edge)%2 ? highcontres_on : highcontres_off;
+					}
+					if (row >= top_edge+resolution_block_size && row < top_edge+2*resolution_block_size) {
+						*ptr=((row-top_edge-resolution_block_size)%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row >= top_edge+2*resolution_block_size && row < top_edge+3*resolution_block_size) {
+						*ptr=((row-top_edge-2*resolution_block_size)%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+
+					// Bottom ...
+
+					if (row > bottom_edge-resolution_block_size && row <= bottom_edge) {
+						*ptr=(bottom_edge-row)%2 ? highcontres_on : highcontres_off;
+					}
+					if (row > bottom_edge-2*resolution_block_size && row <= bottom_edge-resolution_block_size) {
+						*ptr=((bottom_edge-resolution_block_size-row)%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row > bottom_edge-3*resolution_block_size && row <= bottom_edge-2*resolution_block_size) {
+						*ptr=((bottom_edge-2*resolution_block_size-row)%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+				}
+
+				// vertical high contrast resolution
+
+				// Left
+
+				if (col >= left_edge+resolution_block_size && col < left_edge+2*resolution_block_size) {
+
+					// Top ...
+
+					if (row >= top_edge && row < top_edge+resolution_block_size) {
+						*ptr=(col-left_edge-resolution_block_size)%2 ? highcontres_on : highcontres_off;
+					}
+					if (row >= top_edge+resolution_block_size && row < top_edge+2*resolution_block_size) {
+						*ptr=((col-left_edge-resolution_block_size)%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row >= top_edge+2*resolution_block_size && row < top_edge+3*resolution_block_size) {
+						*ptr=((col-left_edge-resolution_block_size)%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+
+					// Bottom ...
+
+					if (row > bottom_edge-resolution_block_size && row <= bottom_edge) {
+						*ptr=(col-left_edge-resolution_block_size)%2 ? highcontres_on : highcontres_off;
+					}
+					if (row > bottom_edge-2*resolution_block_size && row <= bottom_edge-resolution_block_size) {
+						*ptr=((col-left_edge-resolution_block_size)%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row > bottom_edge-3*resolution_block_size && row <= bottom_edge-2*resolution_block_size) {
+						*ptr=((col-left_edge-resolution_block_size)%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+				}
+
+				// Right
+
+				if (col > right_edge-2*resolution_block_size && col <= right_edge-resolution_block_size) {
+
+					// Top ...
+
+					if (row >= top_edge && row < top_edge+resolution_block_size) {
+						*ptr=(col-(right_edge-2*resolution_block_size))%2 ? highcontres_on : highcontres_off;
+					}
+					if (row >= top_edge+resolution_block_size && row < top_edge+2*resolution_block_size) {
+						*ptr=((col-(right_edge-2*resolution_block_size))%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row >= top_edge+2*resolution_block_size && row < top_edge+3*resolution_block_size) {
+						*ptr=((col-(right_edge-2*resolution_block_size))%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+
+					// Bottom ...
+
+					if (row > bottom_edge-resolution_block_size && row <= bottom_edge) {
+						*ptr=(col-(right_edge-2*resolution_block_size))%2 ? highcontres_on : highcontres_off;
+					}
+					if (row > bottom_edge-2*resolution_block_size && row <= bottom_edge-resolution_block_size) {
+						*ptr=((col-(right_edge-2*resolution_block_size))%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row > bottom_edge-3*resolution_block_size && row <= bottom_edge-2*resolution_block_size) {
+						*ptr=((col-(right_edge-2*resolution_block_size))%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+				}
+
+
+				// horizontal low contrast mid frequency resolution
+
+				if (col >= left_edge+2*resolution_block_size && col < left_edge+3*resolution_block_size
+				 || col > right_edge-3*resolution_block_size && col <= right_edge-2*resolution_block_size) {
+
+					// Top ...
+
+					if (row >= top_edge && row < top_edge+resolution_block_size) {
+						*ptr=((row-top_edge)%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row >= top_edge+resolution_block_size && row < top_edge+2*resolution_block_size) {
+						*ptr=((row-top_edge-resolution_block_size)%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row >= top_edge+2*resolution_block_size && row < top_edge+3*resolution_block_size) {
+						*ptr=((row-top_edge-2*resolution_block_size)%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+
+					// Bottom ...
+
+					if (row > bottom_edge-resolution_block_size && row <= bottom_edge) {
+						*ptr=((bottom_edge-row)%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row > bottom_edge-2*resolution_block_size && row <= bottom_edge-resolution_block_size) {
+						*ptr=((bottom_edge-resolution_block_size-row)%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row > bottom_edge-3*resolution_block_size && row <= bottom_edge-2*resolution_block_size) {
+						*ptr=((bottom_edge-2*resolution_block_size-row)%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+				}
+
+				// vertical low contrast mid frequency resolution
+
+				// Left
+
+				if (col >= left_edge+3*resolution_block_size && col < left_edge+4*resolution_block_size) {
+
+					// Top ...
+
+					if (row >= top_edge && row < top_edge+resolution_block_size) {
+						*ptr=((col-left_edge-3*resolution_block_size)%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row >= top_edge+resolution_block_size && row < top_edge+2*resolution_block_size) {
+						*ptr=((col-left_edge-3*resolution_block_size)%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row >= top_edge+2*resolution_block_size && row < top_edge+3*resolution_block_size) {
+						*ptr=((col-left_edge-3*resolution_block_size)%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+
+					// Bottom ...
+
+					if (row > bottom_edge-resolution_block_size && row <= bottom_edge) {
+						*ptr=((col-left_edge-3*resolution_block_size)%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row > bottom_edge-2*resolution_block_size && row <= bottom_edge-resolution_block_size) {
+						*ptr=((col-left_edge-3*resolution_block_size)%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row > bottom_edge-3*resolution_block_size && row <= bottom_edge-2*resolution_block_size) {
+						*ptr=((col-left_edge-3*resolution_block_size)%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+				}
+
+				// Right
+
+				if (col > right_edge-4*resolution_block_size && col <= right_edge-3*resolution_block_size) {
+
+					// Top ...
+
+					if (row >= top_edge && row < top_edge+resolution_block_size) {
+						*ptr=((col-(right_edge-4*resolution_block_size))%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row >= top_edge+resolution_block_size && row < top_edge+2*resolution_block_size) {
+						*ptr=((col-(right_edge-4*resolution_block_size))%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row >= top_edge+2*resolution_block_size && row < top_edge+3*resolution_block_size) {
+						*ptr=((col-(right_edge-4*resolution_block_size))%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+
+					// Bottom ...
+
+					if (row > bottom_edge-resolution_block_size && row <= bottom_edge) {
+						*ptr=((col-(right_edge-4*resolution_block_size))%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row > bottom_edge-2*resolution_block_size && row <= bottom_edge-resolution_block_size) {
+						*ptr=((col-(right_edge-4*resolution_block_size))%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row > bottom_edge-3*resolution_block_size && row <= bottom_edge-2*resolution_block_size) {
+						*ptr=((col-(right_edge-4*resolution_block_size))%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+				}
+
+				// Do center resolution pattern with same layout at top right hand corner ...
+
+				// horizontal high contrast resolution
+
+				if (col > center_pattern_right_edge-resolution_block_size && col <= center_pattern_right_edge) {
+
+					if (row >= center_pattern_top_edge && row < center_pattern_top_edge+resolution_block_size) {
+						*ptr=(row-center_pattern_top_edge)%2 ? highcontres_on : highcontres_off;
+					}
+					if (row >= center_pattern_top_edge+resolution_block_size && row < center_pattern_top_edge+2*resolution_block_size) {
+						*ptr=((row-center_pattern_top_edge-resolution_block_size)%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row >= center_pattern_top_edge+2*resolution_block_size && row < center_pattern_top_edge+3*resolution_block_size) {
+						*ptr=((row-center_pattern_top_edge-2*resolution_block_size)%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+				}
+
+				// vertical high contrast resolution
+
+				if (col > center_pattern_right_edge-2*resolution_block_size && col <= center_pattern_right_edge-resolution_block_size) {
+
+					if (row >= center_pattern_top_edge && row < center_pattern_top_edge+resolution_block_size) {
+						*ptr=(col-(center_pattern_right_edge-2*resolution_block_size))%2 ? highcontres_on : highcontres_off;
+					}
+					if (row >= center_pattern_top_edge+resolution_block_size && row < center_pattern_top_edge+2*resolution_block_size) {
+						*ptr=((col-(center_pattern_right_edge-2*resolution_block_size))%4 >= 2) ? highcontres_on : highcontres_off;
+					}
+					if (row >= center_pattern_top_edge+2*resolution_block_size && row < center_pattern_top_edge+3*resolution_block_size) {
+						*ptr=((col-(center_pattern_right_edge-2*resolution_block_size))%6 >= 3) ? highcontres_on : highcontres_off;
+					}
+				}
+
+				// horizontal low contrast mid frequency resolution
+
+				if (col > center_pattern_right_edge-3*resolution_block_size && col <= center_pattern_right_edge-2*resolution_block_size) {
+
+					if (row >= center_pattern_top_edge && row < center_pattern_top_edge+resolution_block_size) {
+						*ptr=((row-center_pattern_top_edge)%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row >= center_pattern_top_edge+resolution_block_size && row < center_pattern_top_edge+2*resolution_block_size) {
+						*ptr=((row-center_pattern_top_edge-resolution_block_size)%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row >= center_pattern_top_edge+2*resolution_block_size && row < center_pattern_top_edge+3*resolution_block_size) {
+						*ptr=((row-center_pattern_top_edge-2*resolution_block_size)%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+				}
+
+				// vertical low contrast mid frequency resolution
+
+				if (col > center_pattern_right_edge-4*resolution_block_size && col <= center_pattern_right_edge-3*resolution_block_size) {
+
+					// Top ...
+
+					if (row >= center_pattern_top_edge && row < center_pattern_top_edge+resolution_block_size) {
+						*ptr=((col-(center_pattern_right_edge-4*resolution_block_size))%4 >= 2) ? contreslow_on : contreslow_off;
+					}
+					if (row >= center_pattern_top_edge+resolution_block_size && row < center_pattern_top_edge+2*resolution_block_size) {
+						*ptr=((col-(center_pattern_right_edge-4*resolution_block_size))%4 >= 2) ? contresmid_on : contresmid_off;
+					}
+					if (row >= center_pattern_top_edge+2*resolution_block_size && row < center_pattern_top_edge+3*resolution_block_size) {
+						*ptr=((col-(center_pattern_right_edge-4*resolution_block_size))%4 >= 2) ? contreshigh_on : contreshigh_off;
+					}
+
+				}
+
+				// write text
+
+				write_left_justified_vertically_aligned_center_string(
+					smpte_string_70percent_bits,smpte_string_70percent_width,smpte_string_70percent_height,
+					squares_left_edge+6*squares_width+5,squares_top_edge+squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_left_justified_vertically_aligned_center_string(
+					smpte_string_80percent_bits,smpte_string_80percent_width,smpte_string_80percent_height,
+					squares_left_edge+6*squares_width+5,squares_top_edge+3*squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_left_justified_vertically_aligned_center_string(
+					smpte_string_90percent_bits,smpte_string_90percent_width,smpte_string_90percent_height,
+					squares_left_edge+6*squares_width+5,squares_top_edge+5*squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_left_justified_vertically_aligned_center_string(
+					smpte_string_100percent_bits,smpte_string_100percent_width,smpte_string_100percent_height,
+					squares_left_edge+6*squares_width+5,squares_top_edge+7*squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_right_justified_vertically_aligned_center_string(
+					smpte_string_30percent_bits,smpte_string_30percent_width,smpte_string_30percent_height,
+					squares_left_edge-5,squares_top_edge+squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_right_justified_vertically_aligned_center_string(
+					smpte_string_20percent_bits,smpte_string_20percent_width,smpte_string_20percent_height,
+					squares_left_edge-5,squares_top_edge+3*squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_right_justified_vertically_aligned_center_string(
+					smpte_string_10percent_bits,smpte_string_10percent_width,smpte_string_10percent_height,
+					squares_left_edge-5,squares_top_edge+5*squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_right_justified_vertically_aligned_center_string(
+					smpte_string_0percent_bits,smpte_string_0percent_width,smpte_string_0percent_height,
+					squares_left_edge-5,squares_top_edge+7*squares_height/2,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_top_string(
+					smpte_string_40percent_bits,smpte_string_40percent_width,smpte_string_40percent_height,
+					squares_left_edge+3*squares_width/2,squares_top_edge+5,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_top_string(
+					smpte_string_50percent_bits,smpte_string_50percent_width,smpte_string_50percent_height,
+					squares_left_edge+5*squares_width/2,squares_top_edge+5,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_top_string(
+					smpte_string_50percent_bits,smpte_string_50percent_width,smpte_string_50percent_height,
+					squares_left_edge+7*squares_width/2,squares_top_edge+5,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_top_string(
+					smpte_string_60percent_bits,smpte_string_60percent_width,smpte_string_60percent_height,
+					squares_left_edge+9*squares_width/2,squares_top_edge+5,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_center_string(
+					smpte_string_0percent_bits,smpte_string_0percent_width,smpte_string_0percent_height,
+					squares_left_edge+5*squares_width/2,squares_top_edge+7*squares_width/2-smpte_string_0percent_height,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_center_string(
+					smpte_string_95percent_bits,smpte_string_95percent_width,smpte_string_95percent_height,
+					squares_left_edge+7*squares_width/2,squares_top_edge+7*squares_width/2-smpte_string_95percent_height,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_center_string(
+					smpte_string_5percent_bits,smpte_string_5percent_width,smpte_string_5percent_height,
+					squares_left_edge+5*squares_width/2,squares_top_edge+7*squares_width/2+smpte_string_5percent_height,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_center_string(
+					smpte_string_100percent_bits,smpte_string_100percent_width,smpte_string_100percent_height,
+					squares_left_edge+7*squares_width/2,squares_top_edge+7*squares_width/2+smpte_string_100percent_height,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_bottom_string(
+					smpte_string_smpte_bits,smpte_string_smpte_width,smpte_string_smpte_height,
+					columns/2,bottom_edge-smpte_string_revision_height-4,
+					row,col,ptr,
+					percent100);
+
+				write_centered_vertically_aligned_bottom_string(
+					smpte_string_revision_bits,smpte_string_revision_width,smpte_string_revision_height,
+					columns/2,bottom_edge-2,
+					row,col,ptr,
+					percent100);
+
+				++ptr;
+				++col;
+			}
+			++row;
+			return columns;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return row < rows; }
+};
+
+
+#endif // __Header_SMPTESrc__
diff --git a/libsrc/include/pixeldat/smptetxt.h b/libsrc/include/pixeldat/smptetxt.h
new file mode 100644
index 0000000..60e5dee
--- /dev/null
+++ b/libsrc/include/pixeldat/smptetxt.h
@@ -0,0 +1,113 @@
+/* smptetxt.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+static const unsigned short smpte_string_0percent_width = 14;
+static const unsigned short smpte_string_0percent_height = 9;
+static const unsigned char smpte_string_0percent_bits[] = {
+ 0x8e,0x31,0x5b,0x1e,0x51,0x0a,0x91,0x05,0x11,0x02,0x11,0x1b,0x11,0x25,0x9b,
+ 0x24,0x8e,0x18};
+
+static const unsigned short smpte_string_5percent_width = 14;
+static const unsigned short smpte_string_5percent_height = 9;
+static const unsigned char smpte_string_5percent_bits[] = {
+ 0x9c,0x31,0x42,0x1e,0x42,0x0a,0x8e,0x05,0x18,0x02,0x10,0x1b,0x10,0x25,0x99,
+ 0x24,0x8e,0x18};
+
+static const unsigned short smpte_string_10percent_width = 20;
+static const unsigned short smpte_string_10percent_height = 9;
+static const unsigned char smpte_string_10percent_bits[] = {
+ 0x84,0x63,0x0c,0xc6,0x96,0x07,0x45,0x94,0x02,0x44,0x64,0x01,0x44,0x84,0x00,
+ 0x44,0xc4,0x06,0x44,0x44,0x09,0xc4,0x26,0x09,0x8e,0x23,0x06};
+
+static const unsigned short smpte_string_20percent_width = 20;
+static const unsigned short smpte_string_20percent_height = 9;
+static const unsigned char smpte_string_20percent_bits[] = {
+ 0x8e,0x63,0x0c,0xd1,0x96,0x07,0x50,0x94,0x02,0x50,0x64,0x01,0x48,0x84,0x00,
+ 0x44,0xc4,0x06,0x42,0x44,0x09,0xd1,0x26,0x09,0x9f,0x23,0x06};
+
+static const unsigned short smpte_string_30percent_width = 20;
+static const unsigned short smpte_string_30percent_height = 9;
+static const unsigned char smpte_string_30percent_bits[] = {
+ 0x8e,0x63,0x0c,0xd1,0x96,0x07,0x50,0x94,0x02,0x48,0x64,0x01,0x4e,0x84,0x00,
+ 0x50,0xc4,0x06,0x50,0x44,0x09,0xd1,0x26,0x09,0x8e,0x23,0x06};
+
+static const unsigned short smpte_string_40percent_width = 20;
+static const unsigned short smpte_string_40percent_height = 9;
+static const unsigned char smpte_string_40percent_bits[] = {
+ 0x88,0x63,0x0c,0xcc,0x96,0x07,0x4c,0x94,0x02,0x4a,0x64,0x01,0x4a,0x84,0x00,
+ 0x49,0xc4,0x06,0x5f,0x44,0x09,0xc8,0x26,0x09,0x88,0x23,0x06};
+
+static const unsigned short smpte_string_50percent_width = 20;
+static const unsigned short smpte_string_50percent_height = 9;
+static const unsigned char smpte_string_50percent_bits[] = {
+ 0x9c,0x63,0x0c,0xc2,0x96,0x07,0x42,0x94,0x02,0x4e,0x64,0x01,0x58,0x84,0x00,
+ 0x50,0xc4,0x06,0x50,0x44,0x09,0xd9,0x26,0x09,0x8e,0x23,0x06};
+
+static const unsigned short smpte_string_60percent_width = 20;
+static const unsigned short smpte_string_60percent_height = 9;
+static const unsigned char smpte_string_60percent_bits[] = {
+ 0x98,0x63,0x0c,0xc6,0x96,0x07,0x42,0x94,0x02,0x4f,0x64,0x01,0x59,0x84,0x00,
+ 0x51,0xc4,0x06,0x51,0x44,0x09,0xd3,0x26,0x09,0x8e,0x23,0x06};
+
+static const unsigned short smpte_string_70percent_width = 20;
+static const unsigned short smpte_string_70percent_height = 9;
+static const unsigned char smpte_string_70percent_bits[] = {
+ 0x9f,0x63,0x0c,0xd1,0x96,0x07,0x48,0x94,0x02,0x48,0x64,0x01,0x44,0x84,0x00,
+ 0x44,0xc4,0x06,0x42,0x44,0x09,0xc2,0x26,0x09,0x82,0x23,0x06};
+
+static const unsigned short smpte_string_80percent_width = 20;
+static const unsigned short smpte_string_80percent_height = 9;
+static const unsigned char smpte_string_80percent_bits[] = {
+ 0x8e,0x63,0x0c,0xd1,0x96,0x07,0x51,0x94,0x02,0x53,0x64,0x01,0x4e,0x84,0x00,
+ 0x59,0xc4,0x06,0x51,0x44,0x09,0xd1,0x26,0x09,0x8e,0x23,0x06};
+
+static const unsigned short smpte_string_90percent_width = 20;
+static const unsigned short smpte_string_90percent_height = 9;
+static const unsigned char smpte_string_90percent_bits[] = {
+ 0x8e,0x63,0x0c,0xd9,0x96,0x07,0x51,0x94,0x02,0x51,0x64,0x01,0x53,0x84,0x00,
+ 0x5e,0xc4,0x06,0x48,0x44,0x09,0xcc,0x26,0x09,0x83,0x23,0x06};
+
+static const unsigned short smpte_string_95percent_width = 20;
+static const unsigned short smpte_string_95percent_height = 9;
+static const unsigned char smpte_string_95percent_bits[] = {
+ 0x0e,0x67,0x0c,0x99,0x90,0x07,0x91,0x90,0x02,0x91,0x63,0x01,0x13,0x86,0x00,
+ 0x1e,0xc4,0x06,0x08,0x44,0x09,0x4c,0x26,0x09,0x83,0x23,0x06};
+
+static const unsigned short smpte_string_100percent_width = 26;
+static const unsigned short smpte_string_100percent_height = 9;
+static const unsigned char smpte_string_100percent_bits[] = {
+ 0x84,0xe3,0x18,0x03,0xc6,0xb6,0xe5,0x01,0x45,0x14,0xa5,0x00,0x44,0x14,0x59,
+ 0x00,0x44,0x14,0x21,0x00,0x44,0x14,0xb1,0x01,0x44,0x14,0x51,0x02,0xc4,0xb6,
+ 0x49,0x02,0x8e,0xe3,0x88,0x01};
+
+static const unsigned short smpte_string_smpte_width = 130;
+static const unsigned short smpte_string_smpte_height = 9;
+static const unsigned char smpte_string_smpte_bits[] = {
+ 0xae,0x01,0xff,0xfe,0x7f,0xf8,0xff,0xb9,0xfe,0xf8,0x41,0xf8,0xff,0xff,0x7e,
+ 0x86,0x03,0x31,0x83,0x89,0x93,0x42,0x48,0x0a,0xc5,0x92,0x10,0x43,0x48,0x26,
+ 0x85,0xc4,0x0c,0x01,0x21,0x83,0x09,0x11,0x02,0x40,0x08,0x84,0x10,0x10,0xa2,
+ 0x40,0x20,0x04,0x84,0x0c,0x01,0x06,0x45,0x89,0x11,0x22,0x40,0x88,0x18,0x10,
+ 0x10,0xa3,0x40,0x20,0x44,0xc4,0x14,0x01,0x1c,0x45,0xf9,0x10,0x3e,0x40,0xf8,
+ 0x70,0x10,0xf0,0x11,0x41,0x20,0x7c,0x7c,0x24,0x01,0x30,0x29,0x09,0x10,0x22,
+ 0x40,0x88,0xc0,0x10,0x10,0xf0,0x41,0x20,0x44,0x24,0x24,0x01,0x21,0x29,0x09,
+ 0x10,0x02,0x40,0x08,0x84,0x10,0x10,0x10,0x41,0x20,0x04,0x44,0x44,0x01,0x33,
+ 0x11,0x09,0x10,0x42,0x40,0x08,0xcd,0x10,0x10,0x08,0x42,0x20,0x84,0x84,0x84,
+ 0x01,0x9d,0x93,0x1f,0x38,0x7f,0xe0,0xfc,0x75,0x38,0x38,0x1c,0xe7,0x70,0xfe,
+ 0x8e,0x0f,0x01};
+
+static const unsigned short smpte_string_revision_width = 134;
+static const unsigned short smpte_string_revision_height = 12;
+static const unsigned char smpte_string_revision_bits[] = {
+ 0x3f,0x00,0x00,0x38,0x24,0xe8,0x10,0xe0,0x02,0x00,0x00,0x04,0x0c,0x00,0xc2,
+ 0x71,0x1c,0x62,0x00,0x00,0x44,0x34,0x98,0x19,0x30,0x03,0x00,0x00,0x00,0x08,
+ 0x00,0x23,0x8b,0x22,0x42,0x00,0x00,0x40,0x2c,0x18,0x15,0x10,0x02,0x00,0x00,
+ 0x00,0x08,0x82,0x22,0x8a,0x20,0x62,0xcc,0x0c,0x20,0x22,0x14,0x11,0x08,0x60,
+ 0x9e,0xb9,0xc7,0x3b,0x0f,0x22,0x9a,0x10,0x3e,0x92,0x04,0x38,0x22,0x34,0x11,
+ 0x08,0x90,0x24,0xc9,0x24,0x49,0x02,0x62,0x72,0x1c,0x12,0x9e,0x06,0x40,0x22,
+ 0xe4,0x11,0x08,0x90,0x24,0x4d,0x24,0x49,0x02,0xc2,0xcb,0x20,0x22,0x82,0x02,
+ 0x40,0x21,0x82,0x10,0x10,0x92,0x24,0x45,0xe4,0x48,0x02,0x02,0x89,0x20,0x42,
+ 0x26,0x03,0x44,0x21,0xc2,0x10,0x30,0x93,0x24,0x46,0x44,0x48,0x02,0x82,0x89,
+ 0x22,0xc7,0x1c,0x21,0x38,0x71,0x32,0x38,0xe0,0x61,0x1c,0xe2,0xce,0xdd,0x0c,
+ 0x67,0x70,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x20,
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
+ 0x01,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x8e,0x01,0xc0,0x01,0x00,0x00,0x00,0x00};
+
diff --git a/libsrc/include/pixeldat/srcsink.h b/libsrc/include/pixeldat/srcsink.h
new file mode 100644
index 0000000..789d3a1
--- /dev/null
+++ b/libsrc/include/pixeldat/srcsink.h
@@ -0,0 +1,418 @@
+/* srcsink.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_srcsink__
+#define __Header_srcsink__
+
+#include "buffer.h"
+
+#ifndef DEFAULTCHUNKSIZE
+#define DEFAULTCHUNKSIZE 16384
+#endif
+
+template<class T>
+class SourceBase {
+public:
+	SourceBase(void)	{}
+	virtual size_t read(void) = 0;
+	virtual const T *getBuffer(void) = 0;
+	virtual size_t getBufferCount(void) const = 0;
+	virtual int good(void) const = 0;
+	virtual ~SourceBase(void) {}
+};
+
+template<class T>
+class SourceBuffered : public SourceBase<T> {
+protected:
+	Buffer<T> buffer;
+public:
+	SourceBuffered(void) : SourceBase<T>()	{}
+
+	const T *getBuffer(void)			{ return buffer.getValues(); }
+	size_t getBufferCount(void) const		{ return buffer.getCount(); }
+
+	size_t readFromStream(istream &istr,size_t n)
+		{
+			//cerr << "SourceBuffered::read(istream &istr," << dec << n << ")\n" << flush;
+			buffer.clear(); buffer.extend(n);
+			istr.read((char *)buffer.getValues(),n*sizeof(T));
+			size_t count=istr.gcount()/sizeof(T);
+			//if (n > count) {
+				//cerr << "SourceBuffered::read(istream &istr,size_t n) read " << dec << count << " but expected " << n << endl;
+			//}
+			buffer.setCount(count);
+			//cerr << "SourceBuffered::read(istream &istr,size_t n) read " << dec << count << endl;
+			return count;
+		}
+};
+
+
+template<class T>
+class Source : public SourceBuffered<T> {
+	istream *istr;
+	size_t chunkSize;
+	unsigned long bytesLeft;
+	int bad;
+public:
+	Source(istream& i,size_t chunksize=DEFAULTCHUNKSIZE,unsigned long byteswanted=ULONG_MAX)
+			: SourceBuffered<T>()
+		{
+			istr=&i;
+			chunkSize=chunksize;
+			bytesLeft=byteswanted;
+			bad=0;
+		}
+
+	size_t read(void)
+		{
+//cerr << "Source::read(void) bytesLeft=" << dec << bytesLeft << endl;
+			size_t n;
+			if (good() && bytesLeft > 0) {
+				size_t readsize = (size_t)(chunkSize > bytesLeft ? bytesLeft : chunkSize);
+//cerr << "Source::read(void) readsize=" << dec << readsize << endl;
+				n=SourceBuffered<T>::readFromStream(*istr,readsize);
+//cerr << "Source::read(void) n=" << dec << n << endl;
+				bytesLeft-=n;
+				if (n != readsize) bad=1;
+			}
+			else {
+				// Trying to read past previous failure or finish
+				bad=1;
+			}
+			return good() ? n : 0;
+		}
+
+	int good(void) const
+		{
+			Assert(istr);
+//cerr << "Source::good() istr->good()=" << (istr->good() ? "T":"F") << endl;
+//cerr << "Source::good() bad=" << bad << endl;
+			return istr->good() && !bad;
+		}
+};
+
+template<class T>
+class Sink {
+	ostream *ostr;
+	SourceBase<T> *source;
+public:
+	Sink(ostream& o,SourceBase<T>& i)
+		{
+			ostr=&o;
+			source=&i;
+		}
+
+	void write(unsigned long nwords=ULONG_MAX)
+		{
+			//cerr << "Sink::write nwords=" << nwords << endl;
+			Assert(source);
+			Assert(ostr);
+			while (nwords && source->good() && good()) {
+				//cerr << "Sink::operator<< in loop nwords=" << nwords << "\n" << flush;
+				size_t n=source->read();
+				//cerr << "Sink::operator<< read " << n << "\n" << flush;
+				if (!n) break; // premature end unless nwords=0xffffffff
+				if (n>nwords) n=(size_t)nwords;
+				if (n) ostr->write((const char *)(source->getBuffer()),n*sizeof(T));
+				nwords-=n;
+				if (nwords == 1 && sizeof(T) == 1 && !source->good()) {		// need to do this now, because will not loop again because source will not be good
+					// handle special case of single byte input rows*cols is odd, which is legitimate (e.g., pnmtodc), and single byte padding is needed ... (000136),(000185)
+					//cerr << "Sink::write padding odd rows*cols to even byte\n" << flush;
+					const char pad = 0x00;
+					ostr->write(&pad,1);
+				}
+				//cerr << "Sink::operator<< loop end\n" << flush;
+			}
+			//cerr << "Sink::write return\n" << flush;
+		}
+
+	void write(unsigned long nskip,unsigned long nwords)
+		{
+			//cerr << "Sink::write nskip=" << nskip << endl;
+			//cerr << "Sink::write nwords=" << nwords << endl;
+			unsigned long ntotal = (nwords == ULONG_MAX) ? ULONG_MAX : nskip+nwords;
+				//cerr << "Sink::operator<< loop end\n" << flush;
+			Assert(source);
+			Assert(ostr);
+			while (ntotal && source->good() && good()) {
+				//cerr << "Sink::operator<< in loop ntotal=" << ntotal << "\n" << flush;
+				//cerr << "Sink::operator<< in loop nskip=" << nskip << "\n" << flush;
+				size_t n=source->read();
+				//cerr << "Sink::operator<< read " << n << "\n" << flush;
+				if (!n) break;	// premature end unless nwords=0xffffffff
+				if (n>ntotal) n=(size_t)ntotal;
+				size_t offset=0;
+				if (nskip >= n) {
+					//cerr << "Sink::operator<< skipping " << n << "\n" << flush;
+					nskip-=n;
+					ntotal-=n;
+					continue;
+				}
+				//cerr << "Sink::operator<< writing " << (n-nskip) << " after skipping " << nskip << "\n" << flush;
+				if (n) ostr->write((const char *)(source->getBuffer()+nskip),(n-nskip)*sizeof(T));
+				ntotal-=n;
+				nskip=0;
+				if (ntotal == 1 && sizeof(T) == 1 && !source->good()) {		// need to do this now, because will not loop again because source will not be good
+					// handle special case of single byte input rows*cols is odd, which is legitimate (e.g., pnmtodc), and single byte padding is needed ... (000136),(000185)
+					//cerr << "Sink::write padding odd rows*cols to even byte\n" << flush;
+					const char pad = 0x00;
+					ostr->write(&pad,1);
+				}
+				//cerr << "Sink::operator<< loop end\n" << flush;
+			}
+			//cerr << "Sink::write return\n" << flush;
+		}
+
+	int good(void) const	{ Assert(ostr); return ostr->good(); }
+};
+
+template<class Tin>
+class SourceToSink {
+protected:
+	SourceBase<Tin> *source;
+public:
+	SourceToSink(SourceBase<Tin>& i)
+		{
+			source=&i;
+		}
+};
+
+// These classes are the basis for filters ...
+
+template<class Tin,class Tout>
+class FilterSourceToSinkBase : public SourceToSink<Tin>, public SourceBase<Tout> {
+public:
+	FilterSourceToSinkBase(SourceBase<Tin>& i): SourceToSink<Tin>(i), SourceBase<Tout>() {}
+};
+
+template<class Tin,class Tout>
+class FilterSourceToSinkBufferedBase : public SourceToSink<Tin>, public SourceBuffered<Tout> {
+public:
+	FilterSourceToSinkBufferedBase(SourceBase<Tin>& i): SourceToSink<Tin>(i), SourceBuffered<Tout>() {}
+};
+
+// These two are provided as examples of how to write filters ...
+
+template<class T>
+class CopySourceToSink : public FilterSourceToSinkBase<T,T> {
+	const T *buffer;
+	size_t length;
+public:
+	CopySourceToSink(SourceBase<T>& i)
+			: FilterSourceToSinkBase<T,T>(i)
+		{}
+
+	size_t read(void)
+		{
+			Assert(SourceToSink<T>::source);
+			if (SourceToSink<T>::source->read()) {
+				size_t n=SourceToSink<T>::source->getBufferCount();
+				buffer=(const T *)SourceToSink<T>::source->getBuffer();
+				length=n;
+			}
+			else length=0;
+			return length;
+		}
+
+	int good(void) const	{ return SourceToSink<T>::source && SourceToSink<T>::source->good(); }
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+template<class T>
+class DuplicateSourceToSink : public FilterSourceToSinkBufferedBase<T,T> {
+public:
+	DuplicateSourceToSink(SourceBase<T>& i)
+			: FilterSourceToSinkBufferedBase<T,T>(i)
+		{}
+
+	size_t read(void)
+		{
+			//cerr << "DuplicateSourceToSink::read(void)\n" << flush;
+			FilterSourceToSinkBufferedBase<T,T>::buffer.clear();
+			if (FilterSourceToSinkBufferedBase<T,T>::source && FilterSourceToSinkBufferedBase<T,T>::source->read()) {
+				//cerr << "DuplicateSourceToSink::read(void) success\n" << flush;
+				size_t n=FilterSourceToSinkBufferedBase<T,T>::source->getBufferCount();
+				//cerr << "DuplicateSourceToSink::read(void) " << n << " values\n" << flush;
+				const T *inptr=FilterSourceToSinkBufferedBase<T,T>::source->getBuffer();
+				FilterSourceToSinkBufferedBase<T,T>::buffer.add(inptr,n);
+			}
+			//cerr << "DuplicateSourceToSink::read(void) return " << getBufferCount() << " values\n" << flush;
+			return FilterSourceToSinkBufferedBase<T,T>::getBufferCount();
+		}
+
+	int good(void) const	{ return FilterSourceToSinkBufferedBase<T,T>::source && FilterSourceToSinkBufferedBase<T,T>::source->good(); }
+};
+
+template<class Tin,class Tout>
+class ConvertSourceToSink : public FilterSourceToSinkBufferedBase<Tin,Tout> {
+public:
+	ConvertSourceToSink(SourceBase<Tin>& i)
+			: FilterSourceToSinkBufferedBase<Tin,Tout>(i)
+		{}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertSourceToSink::read(void)\n" << flush;
+			FilterSourceToSinkBufferedBase<Tin,Tout>::buffer.clear();
+			if (FilterSourceToSinkBufferedBase<Tin,Tout>::source && FilterSourceToSinkBufferedBase<Tin,Tout>::source->read()) {
+				//cerr << "ConvertSourceToSink::read(void) success\n" << flush;
+				size_t n=FilterSourceToSinkBufferedBase<Tin,Tout>::source->getBufferCount();
+				//cerr << "ConvertSourceToSink::read(void) " << n << " values\n" << flush;
+				const Tin *inptr=FilterSourceToSinkBufferedBase<Tin,Tout>::source->getBuffer();
+
+				while (n--) FilterSourceToSinkBufferedBase<Tin,Tout>::buffer.add((Tout)(*inptr++));
+			}
+			//cerr << "ConvertSourceToSink::read(void) return " << getBufferCount() << " values\n" << flush;
+			return FilterSourceToSinkBufferedBase<Tin,Tout>::getBufferCount();
+		}
+
+	int good(void) const	{ return FilterSourceToSinkBufferedBase<Tin,Tout>::source && FilterSourceToSinkBufferedBase<Tin,Tout>::source->good(); }
+};
+
+template<class Tin,class Tout,int swapSpan>
+class ConvertSourceToSinkSwapping : public FilterSourceToSinkBufferedBase<Tin,Tout> {
+public:
+	ConvertSourceToSinkSwapping(SourceBase<Tin>& i)
+			: FilterSourceToSinkBufferedBase<Tin,Tout>(i)
+		{}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertSourceToSink::read(void)\n" << flush;
+			FilterSourceToSinkBufferedBase<Tin,Tout>::buffer.clear();
+			if (FilterSourceToSinkBufferedBase<Tin,Tout>::source && FilterSourceToSinkBufferedBase<Tin,Tout>::source->read()) {
+				//cerr << "ConvertSourceToSink::read(void) success\n" << flush;
+				size_t n=FilterSourceToSinkBufferedBase<Tin,Tout>::source->getBufferCount();
+				//cerr << "ConvertSourceToSink::read(void) " << n << " values\n" << flush;
+				const Tin *inptr=FilterSourceToSinkBufferedBase<Tin,Tout>::source->getBuffer();
+				Assert(n%swapSpan == 0);
+				//while (n--) buffer.add((Tout)(*inptr++));
+				while (n > 0) {
+					int j;
+					for (j=swapSpan; j > 0; --j) {
+						FilterSourceToSinkBufferedBase<Tin,Tout>::buffer.add((Tout)(*(inptr+j-1)));
+					}
+					inptr+=swapSpan;
+					n-=swapSpan;
+				}
+			}
+			//cerr << "ConvertSourceToSink::read(void) return " << getBufferCount() << " values\n" << flush;
+			return FilterSourceToSinkBufferedBase<Tin,Tout>::getBufferCount();
+		}
+
+	int good(void) const	{ return FilterSourceToSinkBufferedBase<Tin,Tout>::source && FilterSourceToSinkBufferedBase<Tin,Tout>::source->good(); }
+};
+
+template<class Tin,class Tout>
+class PointFilter {
+public:
+	PointFilter() {}
+	virtual Tout filter(Tin) = 0;
+	virtual Tout filter(Tin,size_t offset) = 0;
+	virtual bool isOffsetIndependent() = 0;
+};
+
+template<class Tin,class Tout>
+class PointFilterIndependentOfOffset : public PointFilter<Tin,Tout>  {
+public:
+	PointFilterIndependentOfOffset() {}
+	virtual Tout filter(Tin) = 0;
+	Tout filter(Tin,size_t offset) { Assert(0); }
+	bool isOffsetIndependent() { return true; }
+};
+
+template<class Tin,class Tout>
+class PointFilterDependentOnOffset : public PointFilter<Tin,Tout> {
+public:
+	PointFilterDependentOnOffset() {}
+	Tout filter(Tin) { Assert(0); }
+	virtual Tout filter(Tin,size_t offset) = 0;
+	bool isOffsetIndependent() { return false; }
+};
+
+
+template<class Tin,class Tout>
+class ConvertSourceToSinkWithFilter : public FilterSourceToSinkBufferedBase<Tin,Tout> {
+public:
+	ConvertSourceToSinkWithFilter(SourceBase<Tin>& i)
+			: FilterSourceToSinkBufferedBase<Tin,Tout>(i)
+		{
+		}
+	
+	virtual size_t read(void) = 0;
+
+	int good(void) const	{ return FilterSourceToSinkBufferedBase<Tin,Tout>::source && FilterSourceToSinkBufferedBase<Tin,Tout>::source->good(); }
+};
+
+template<class Tin,class Tout>
+class ConvertSourceToSinkWithFilterIndependentOfOffset : public ConvertSourceToSinkWithFilter<Tin,Tout> {
+private:
+	PointFilterIndependentOfOffset<Tin,Tout> *filter;
+public:
+	ConvertSourceToSinkWithFilterIndependentOfOffset(SourceBase<Tin>& i,PointFilterIndependentOfOffset<Tin,Tout> *f)
+			: ConvertSourceToSinkWithFilter<Tin,Tout>(i)
+		{
+			Assert(f);
+			filter=f;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertSourceToSinkWithFilter::read(void)\n" << flush;
+			ConvertSourceToSinkWithFilter<Tin,Tout>::buffer.clear();
+			if (ConvertSourceToSinkWithFilter<Tin,Tout>::source && ConvertSourceToSinkWithFilter<Tin,Tout>::source->read()) {
+				//cerr << "ConvertSourceToSinkWithFilter::read(void) success\n" << flush;
+				size_t n=ConvertSourceToSinkWithFilter<Tin,Tout>::source->getBufferCount();
+				//cerr << "ConvertSourceToSinkWithFilter::read(void) " << n << " values\n" << flush;
+				const Tin *inptr=ConvertSourceToSinkWithFilter<Tin,Tout>::source->getBuffer();
+
+				while (n--) ConvertSourceToSinkWithFilter<Tin,Tout>::buffer.add(filter->filter((Tout)(*inptr++)));
+			}
+			//cerr << "ConvertSourceToSinkWithFilter::read(void) return " << getBufferCount() << " values\n" << flush;
+			return ConvertSourceToSinkWithFilter<Tin,Tout>::getBufferCount();
+		}
+
+	int good(void) const	{ return ConvertSourceToSinkWithFilter<Tin,Tout>::source && ConvertSourceToSinkWithFilter<Tin,Tout>::source->good(); }
+};
+
+
+template<class Tin,class Tout>
+class ConvertSourceToSinkWithFilterDependentOnOffset : public ConvertSourceToSinkWithFilter<Tin,Tout> {
+private:
+	PointFilterDependentOnOffset<Tin,Tout> *filter;
+	size_t offset;
+public:
+	ConvertSourceToSinkWithFilterDependentOnOffset(SourceBase<Tin>& i,PointFilterDependentOnOffset<Tin,Tout> *f)
+			: ConvertSourceToSinkWithFilter<Tin,Tout>(i)
+		{
+			Assert(f);
+			filter=f;
+			offset=0;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertSourceToSinkWithFilter::read(void)\n" << flush;
+			ConvertSourceToSinkWithFilter<Tin,Tout>::buffer.clear();
+			if (ConvertSourceToSinkWithFilter<Tin,Tout>::source && ConvertSourceToSinkWithFilter<Tin,Tout>::source->read()) {
+				//cerr << "ConvertSourceToSinkWithFilter::read(void) success\n" << flush;
+				size_t n=ConvertSourceToSinkWithFilter<Tin,Tout>::source->getBufferCount();
+				//cerr << "ConvertSourceToSinkWithFilter::read(void) " << n << " values\n" << flush;
+				const Tin *inptr=ConvertSourceToSinkWithFilter<Tin,Tout>::source->getBuffer();
+
+				while (n--) ConvertSourceToSinkWithFilter<Tin,Tout>::buffer.add(filter->filter((Tout)(*inptr++),offset++));
+			}
+			//cerr << "ConvertSourceToSinkWithFilter::read(void) return " << getBufferCount() << " values\n" << flush;
+			return ConvertSourceToSinkWithFilter<Tin,Tout>::getBufferCount();
+		}
+
+	int good(void) const	{ return ConvertSourceToSinkWithFilter<Tin,Tout>::source && ConvertSourceToSinkWithFilter<Tin,Tout>::source->good(); }
+};
+
+class SupplySource {
+public:
+	SupplySource(void) {}
+	virtual ~SupplySource(void) {}
+	virtual class SourceBase<Uint16> *getSource(void) = 0;
+};
+
+#endif /* __Header_srcsink__ */
diff --git a/libsrc/include/pixeldat/tobyte.h b/libsrc/include/pixeldat/tobyte.h
new file mode 100644
index 0000000..1be5d47
--- /dev/null
+++ b/libsrc/include/pixeldat/tobyte.h
@@ -0,0 +1,194 @@
+/* tobyte.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ToByte__
+#define __Header_ToByte__
+
+// Create a class to insert words from the host native byte order
+// to a specified byte order, making the choice of whether
+// or not to swap the bytes as infrequently as possible, but
+// still automatically at run-time
+
+// NB. This implementation does not require that sizeof(Uint16) == 2
+// but is optimized for that case ...
+
+// Supporting classes ....
+
+class ConvertUint16ToByteBase {
+protected:
+	SourceBase<Uint16> *source;
+public:
+	ConvertUint16ToByteBase(SourceBase<Uint16>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const unsigned char *getBuffer(void) 	= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class ConvertUnswappedUint16ToByte : public ConvertUint16ToByteBase {
+	const unsigned char *buffer;
+	size_t length;
+public:
+	ConvertUnswappedUint16ToByte(SourceBase<Uint16>& i)
+			: ConvertUint16ToByteBase(i)
+		{
+			buffer=0;
+			length=0;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertUnswappedUint16ToByte::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "ConvertUnswappedUint16ToByte::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+				//cerr << "ConvertUnswappedUint16ToByte::read(void) " << n << " values\n" << flush;
+				buffer=(const unsigned char *)source->getBuffer();
+				length=n*2;
+			}
+			else length=0;
+			//cerr << "ConvertUnswappedUint16ToByte::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const unsigned char *getBuffer(void)	{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class ConvertSwappedUint16ToByte : public ConvertUint16ToByteBase {
+	Uint16 *buffer;
+	size_t bufsize;		// In Uint16 words
+	size_t length;		// In bytes
+public:
+	ConvertSwappedUint16ToByte(SourceBase<Uint16>& i)
+			: ConvertUint16ToByteBase(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~ConvertSwappedUint16ToByte()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertSwappedUint16ToByte::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "ConvertSwappedUint16ToByte::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+				//cerr << "ConvertSwappedUint16ToByte::read(void) " << n << " values\n" << flush;
+				if (bufsize < n+1) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=n+1;
+					buffer=new Uint16[bufsize];
+				}
+				length=n*2;
+				const unsigned char *src=(const unsigned char *)source->getBuffer();
+				unsigned char *base=(unsigned char *)buffer;
+				memcpy(base+1,src,n*2);
+				while (n--) { *base=*(base+2); base+=2; }
+			}
+			else length=0;
+			//cerr << "ConvertSwappedUint16ToByte::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const unsigned char *getBuffer(void)	{ return (unsigned char *)buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+template <class T>
+class ConvertEachUint16ToByte : public ConvertUint16ToByteBase {
+	T *buffer;
+	size_t bufsize;		// In T words
+	size_t length;		// In bytes
+public:
+	ConvertEachUint16ToByte(SourceBase<Uint16>& i)
+			: ConvertUint16ToByteBase(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~ConvertEachUint16ToByte()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "ConvertEachUint16ToByte::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "ConvertEachUint16ToByte::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+				//cerr << "ConvertEachUint16ToByte::read(void) " << n << " values\n" << flush;
+				if (bufsize < n) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=n;
+					buffer=new T[bufsize];
+				}
+				length=n*sizeof(T);
+				const Uint16 *src=source->getBuffer();
+				T *ptr = buffer;
+				while (n--) *ptr++=*src++;
+			}
+			else length=0;
+			//cerr << "ConvertEachUint16ToByte::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const unsigned char *getBuffer(void)	{ return (unsigned char *)buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+// These are the classes that are actually used as filters ...
+
+class ConvertUint16ToByte : public FilterSourceToSinkBase<Uint16,unsigned char> {
+	ConvertUint16ToByteBase *convertor;
+public:
+	ConvertUint16ToByte(SourceBase<Uint16>& i,Endian wanted)
+			: FilterSourceToSinkBase<Uint16,unsigned char>(i)
+		{
+			Assert(wanted != NoEndian);
+			if (wanted == ByteEndian)
+				convertor=new ConvertEachUint16ToByte<unsigned char>(i);
+			else if (sizeof(Uint16) == 2) {
+				HostEndian hostendian;
+				if (wanted == hostendian.getEndian()) {
+//cerr << "ConvertUint16ToByte::unswapped" << endl;
+					convertor=new ConvertUnswappedUint16ToByte(i);
+				}
+				else {
+					convertor=new ConvertSwappedUint16ToByte(i);
+				}
+			}
+			else {
+				if (wanted == BigEndian) {
+					convertor=new ConvertEachUint16ToByte<Uint16_B>(i);
+				}
+				else {
+					convertor=new ConvertEachUint16ToByte<Uint16_L>(i);
+				}
+			}
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const unsigned char *getBuffer(void) 	{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_ToByte__
diff --git a/libsrc/include/pixeldat/topack.h b/libsrc/include/pixeldat/topack.h
new file mode 100644
index 0000000..b662959
--- /dev/null
+++ b/libsrc/include/pixeldat/topack.h
@@ -0,0 +1,194 @@
+/* topack.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ToPack__
+#define __Header_ToPack__
+
+// Create a class to pack bitsallocated length words into
+// 16 bit words (whose byte order is still that of the host)
+
+// Supporting classes ....
+
+class PackUint16Base {
+protected:
+	SourceBase<Uint16> *source;
+public:
+	PackUint16Base(SourceBase<Uint16>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const Uint16 *getBuffer(void) 		= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class PackUint16To16 : public PackUint16Base {
+	const Uint16 *buffer;
+	size_t length;
+public:
+	PackUint16To16(SourceBase<Uint16>& i)
+			: PackUint16Base(i)
+		{
+			buffer=0;
+			length=0;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				buffer=(const Uint16 *)source->getBuffer();
+				length=source->getBufferCount();
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class PackUint16To12 : public PackUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+public:
+	PackUint16To12(SourceBase<Uint16>& i)
+			: PackUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~PackUint16To12()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "PackUint16To12::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "PackUint16To12::read(void) success\n" << flush;
+				unsigned long n=source->getBufferCount();
+				//cerr << "PackUint16To12::read(void) " << n << " source words\n" << flush;
+				Assert((n*3)%4==0);
+				n=(n*3)/4;
+				//cerr << "PackUint16To12::read(void) " << n << " dest words\n" << flush;
+				if (bufsize < n) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=(size_t)n;
+					buffer=new Uint16[bufsize];
+				}
+				length=(size_t)n;
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				while (n) {
+					*dst++= *(src  )        & 0x0fff
+					      |(*(src+1) << 12) & 0xf000;
+					*dst++=(*(src+1) >> 4 ) & 0x00ff
+					      |(*(src+2) << 8 ) & 0xff00;
+					*dst++=(*(src+2) >> 8 ) & 0x000f
+					      |(*(src+3) << 4 ) & 0xfff0;
+					src+=4;
+					n-=3;
+				}
+			}
+			else length=0;
+			//cerr << "PackUint16To12::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+class PackUint16To8 : public PackUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+public:
+	PackUint16To8(SourceBase<Uint16>& i)
+			: PackUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+		}
+
+	~PackUint16To8()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			//cerr << "PackUint16To8::read(void)\n" << flush;
+			Assert(source);
+			if (source->read()) {
+				//cerr << "PackUint16To8::read(void) success\n" << flush;
+				size_t n=source->getBufferCount();
+				//cerr << "PackUint16To8::read(void) " << n << " source words\n" << flush;
+				Assert(n%2==0);
+				n=n/2;
+				//cerr << "PackUint16To8::read(void) " << n << " dest words\n" << flush;
+				if (bufsize < n) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=n;
+					buffer=new Uint16[bufsize];
+				}
+				length=n;
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				while (n) {
+					*dst++= *(src  )        & 0x00ff
+					      |(*(src+1) << 8 ) & 0xff00;
+					src+=2;
+					--n;
+				}
+			}
+			else length=0;
+			//cerr << "PackUint16To8::read(void) return " << length << " values\n" << flush;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+
+// These are the classes that are actually used as filters ...
+
+class PackUint16 : public FilterSourceToSinkBase<Uint16,Uint16> {
+	PackUint16Base *convertor;
+public:
+	PackUint16(SourceBase<Uint16>& i,
+			unsigned short bitsallocated)
+		: FilterSourceToSinkBase<Uint16,Uint16>(i)
+		{
+			Assert(bitsallocated <= 16);
+
+			if (bitsallocated == 16)
+				convertor=new PackUint16To16(i);
+			else if (bitsallocated == 12)
+				convertor=new PackUint16To12(i);
+			else if (bitsallocated == 8)
+				convertor=new PackUint16To8(i);
+			else
+				convertor=0;
+
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const Uint16 *getBuffer(void) 		{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_ToPack__
diff --git a/libsrc/include/pixeldat/toshft.h b/libsrc/include/pixeldat/toshft.h
new file mode 100644
index 0000000..47beac3
--- /dev/null
+++ b/libsrc/include/pixeldat/toshft.h
@@ -0,0 +1,104 @@
+/* toshft.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ToShift__
+#define __Header_ToShift__
+
+// Create a class to insert bitsstored length words starting at highbit
+// into 16 bit words (whose byte order is already that of the host)
+
+// handles shifting so lsb is in bit 0
+// doesn't yet handle sign extension
+
+// Supporting classes ....
+
+class ShiftUint16Base {
+protected:
+	SourceBase<Uint16> *source;
+public:
+	ShiftUint16Base(SourceBase<Uint16>& i)
+		{
+			source=&i;
+		}
+	virtual size_t read(void)			= 0;
+	virtual const Uint16 *getBuffer(void) 		= 0; 
+	virtual size_t getBufferCount(void) const	= 0;
+	virtual int good(void) const	{ return source && source->good(); }
+};
+
+class ShiftUint16General : public ShiftUint16Base {
+	Uint16 *buffer;
+	size_t bufsize;
+	size_t length;
+	Uint16 mask;
+	unsigned short leftshift;
+public:
+	ShiftUint16General(SourceBase<Uint16>& i,unsigned short bitsstored,unsigned short highbit)
+			:ShiftUint16Base(i)
+		{
+			buffer=0;
+			bufsize=0;
+			length=0;
+
+			leftshift=highbit+1-bitsstored;
+			mask=(Uint16)(((Uint32)1<<bitsstored)-1)<<leftshift;
+
+			// sign extension not implemented yet
+		}
+
+	~ShiftUint16General()
+		{
+			Assert((!bufsize && !buffer) || (bufsize && buffer));
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			Assert(source);
+			if (source->read()) {
+				length=source->getBufferCount();
+
+				if (bufsize < length) {
+					Assert((!bufsize && !buffer) || (bufsize && buffer));
+					if (buffer) delete[] buffer;
+					bufsize=length;
+					buffer=new Uint16[bufsize];
+				}
+
+				const Uint16 *src=source->getBuffer();
+				Uint16 *dst=buffer;
+				size_t n=length;
+				while (n--) *dst++=(*src++<<leftshift)&mask;
+			}
+			else length=0;
+			return length;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return length; }
+};
+
+// These are the classes that are actually used as filters ...
+
+class ShiftUint16 : public FilterSourceToSinkBase<Uint16,Uint16> {
+	ShiftUint16Base *convertor;
+public:
+	ShiftUint16(SourceBase<Uint16>& i,
+			unsigned short bitsallocated,unsigned short bitsstored,unsigned short highbit)
+		: FilterSourceToSinkBase<Uint16,Uint16>(i)
+		{
+			Assert(bitsallocated <= 16u);
+			Assert(bitsstored <= bitsallocated);
+			Assert(highbit <= bitsallocated-1u);
+
+			// no optimizations yet ...
+			convertor=new ShiftUint16General(i,bitsstored,highbit);
+
+			Assert(convertor);
+		}
+
+	size_t read(void)			{ return convertor->read(); }
+	const Uint16 *getBuffer(void) 		{ return convertor->getBuffer(); } 
+	size_t getBufferCount(void) const	{ return convertor->getBufferCount(); }
+	int good(void) const			{ return convertor->good(); }
+};
+
+#endif // __Header_ToShift__
diff --git a/libsrc/include/pixeldat/unencap.h b/libsrc/include/pixeldat/unencap.h
new file mode 100644
index 0000000..46f5a1a
--- /dev/null
+++ b/libsrc/include/pixeldat/unencap.h
@@ -0,0 +1,170 @@
+/* unencap.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_UnEncap__
+#define __Header_UnEncap__
+
+class UnencapsulatePixelData : public SourceBase<unsigned char> {
+private:
+	istream *istr;
+	Uint32 lefttoreadthisfragment;
+	int fragmentnumber;
+	bool finished;
+	bool bad;
+
+	unsigned char *buffer;
+	size_t maxlength;
+	size_t length;
+
+	unsigned char b[4];
+
+	Uint16 read16(void)
+		{
+			Uint16 u;
+			istr->read((char *)b,2);
+			u =  (Uint16)b[1];
+			u <<= 8;
+			u |= (Uint16)b[0];
+			return u;
+		}
+
+	Uint32 read32(void)
+		{
+			Uint32 u;
+			istr->read((char *)b,4);
+			u =  (Uint32)b[3];
+			u <<= 8;
+			u |= (Uint32)b[2];
+			u <<= 8;
+			u |= (Uint32)b[1];
+			u <<= 8;
+			u |= (Uint32)b[0];
+			return u;
+		}
+
+public:
+	UnencapsulatePixelData(istream& i)
+		{
+			istr=&i;
+			fragmentnumber=-1;	// the first is the offset table
+			lefttoreadthisfragment=0;
+			finished=false;
+			bad=!istr->good();
+			buffer=new unsigned char[DEFAULTCHUNKSIZE];
+			Assert(buffer);
+			maxlength=DEFAULTCHUNKSIZE;
+			length=0;
+		}
+
+	size_t read(void)
+		{
+			// We do this the hardwired way - for encapsulated data:
+			// - non-pixel data is always LE, including fragment delimiters and lengths
+			// - 1st item is offset table, may have zero VL
+			// - other items are fragments
+			// - finally sequence delimitation tag (with zero VL)
+			// - each delimiter is 2 byte group,2 byte element, 4 byte VL, little endian
+			// - Item tag      is (0xfffe,0xe000) (GE mistake is 0xfeff,0x00e0 or 0xe000,0xfffe)
+			// - Seq delimiter is (0xfffe,0xe0dd) (GE mistake is 0xfeff,0xdde0 or 0xe0dd,0xfffe)
+			// - when GE mistake is present, fragment 32 bit VL is also swapped
+
+			length=0;
+
+			while (!lefttoreadthisfragment && !finished && !bad) {
+//cerr << "UnencapsulatePixelData::read starting fragment" << endl;
+				Uint16 group=read16();
+				if (!istr) { bad=true; break; }
+				Uint16 element=read16();
+				if (!istr) { bad=true; break; }
+				Uint32 vl=read32();
+				if (!istr) { bad=true; break; }
+//cerr << "UnencapsulatePixelData::read fragment group=0x" << hex << group << " element=0x" << element << " length=0x" << vl << " (" << dec << vl << " dec)" << endl;
+				if (group == 0xfffe || group == 0xfeff || group == 0xe000 || group == 0xe0dd) {
+					if (group != 0xfffe) {
+//cerr << "UnencapsulatePixelData::unexpected group (? bad byte order)=" << hex << group << dec << endl;
+					}
+					if (element == 0xe0dd || element == 0xdde0 || group == 0xe0dd) {	// Sequence Delimiter Tag
+//cerr << "UnencapsulatePixelData::read Sequence Delimiter Tag" << endl;
+						if (element != 0xe0dd) {
+//cerr << "UnencapsulatePixelData::unexpected element (? bad byte order)=0x" << hex << element << dec << endl;
+						}
+						//Assert(vl == 0);	// just ignore it ... some Opal images have bad value here
+						finished=true;
+					}
+					else /* if (element == 0xe000) */ {	// Item Tag
+cerr << "UnencapsulatePixelData::read Item Tag length=0x" << hex << vl << " (" << dec << vl << " dec)" << endl;
+						bool vlbyteorderwrong=false;
+						if (element != 0xe000) {
+//cerr << "UnencapsulatePixelData::unexpected element (? bad byte order)=0x" << hex << element << dec << endl;
+							vlbyteorderwrong=true;
+						}
+						if (++fragmentnumber > 0) {
+							Assert(vl);	// Zero length fragments thought not to be legal
+							if (vlbyteorderwrong) {
+								lefttoreadthisfragment=
+									 (((Uint32)vl&0xff000000)>>24)
+									+(((Uint32)vl&0x00ff0000)>>8)
+									+(((Uint32)vl&0x0000ff00)<<8)
+									+(((Uint32)vl&0x000000ff)<<24);
+//cerr << "UnencapsulatePixelData::assuming VL also had bad byte order, using 0x" << hex << lefttoreadthisfragment << dec << endl;
+							}
+							else {
+								lefttoreadthisfragment=vl;
+							}
+//cerr << "UnencapsulatePixelData::read next fragment with lefttoreadthisfragment=" << dec << lefttoreadthisfragment << endl;
+						}
+						else {
+							// skip the offset table
+//cerr << "UnencapsulatePixelData::read skip the offset table" << endl;
+							Assert(vl%4 == 0);
+							unsigned i=0;
+							while (vl) {
+								Uint32 offset=read32();
+								if (!istr) { bad=true; break; }
+//cerr << "UnencapsulatePixelData::read [" << i << "] offset " << offset << endl;
+								vl-=4;
+								++i;
+							}
+							//if (istr->rdbuf()->PubSeekOff(vl,ios::cur) == PubSeekBad || istr->fail())
+							//	bad=true;
+						}
+					}
+#ifdef CRAP
+					else {
+						// bad tag element in encapsulated data 
+//cerr << "UnencapsulatePixelData::read bad tag element in encapsulated data" << endl;
+						bad=true;
+					}
+#endif
+				}
+				else {
+					// bad tag group in encapsulated data
+//cerr << "UnencapsulatePixelData::read bad tag group in encapsulated data" << endl;
+					bad=true;
+				}
+			}
+
+			if (lefttoreadthisfragment && !bad) {
+//cerr << "UnencapsulatePixelData::read reading with lefttoreadthisfragment=" << dec << lefttoreadthisfragment << endl;
+				length=unsigned(lefttoreadthisfragment > maxlength ? maxlength : lefttoreadthisfragment);
+				if (istr->read((char *)buffer,length)) {
+					length=istr->gcount();
+//cerr << "UnencapsulatePixelData::read read length=" << dec << length << endl;
+				}
+				else {
+					bad=true;
+					length=0;
+//cerr << "UnencapsulatePixelData::read bad read" << endl;
+				}
+				lefttoreadthisfragment-=length;
+			}
+
+//cerr << "UnencapsulatePixelData::read returning length=" << dec << length << endl;
+			return length;
+		}
+
+	const unsigned char *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const		{ return length; }
+
+	int good(void) const				{ return !bad; }
+};
+
+#endif /* __Header_UnEncap__ */
diff --git a/libsrc/lib/Imakefile b/libsrc/lib/Imakefile
new file mode 100755
index 0000000..873192c
--- /dev/null
+++ b/libsrc/lib/Imakefile
@@ -0,0 +1,9 @@
+clean::
+	-$(RM) lib*
+
+InstallLibrary($(PROJECTDCDISPLIBNAME),$(INSTALLLIBDIR))
+InstallLibrary($(PROJECTDCONVERTLIBNAME),$(INSTALLLIBDIR))
+InstallLibrary($(PROJECTDCTOOLLIBNAME),$(INSTALLLIBDIR))
+InstallLibrary($(PROJECTGENERICLIBNAME),$(INSTALLLIBDIR))
+InstallLibrary($(PROJECTLOCALELIBNAME),$(INSTALLLIBDIR))
+InstallLibrary($(PROJECTOURDISPLIBNAME),$(INSTALLLIBDIR))
diff --git a/libsrc/src/Imakefile b/libsrc/src/Imakefile
new file mode 100755
index 0000000..ce7b8e8
--- /dev/null
+++ b/libsrc/src/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = dcdisp dctool generic locale ourdisp dconvert
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/libsrc/src/dcdisp/Imakefile b/libsrc/src/dcdisp/Imakefile
new file mode 100755
index 0000000..7c8be86
--- /dev/null
+++ b/libsrc/src/dcdisp/Imakefile
@@ -0,0 +1,17 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCDISPEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = lutclass.cc lutextr.cc \
+		 rdargb.cc rdcmyk.cc rdgray.cc rdhsv.cc \
+		 rdimage.cc rdindex.cc rdrgb.cc \
+		 usegray.cc useindex.cc usepal.cc usetrue.cc
+
+OBJS =           lutclass.o  lutextr.o  \
+		 rdargb.o  rdcmyk.o  rdgray.o  rdhsv.o  \
+		 rdimage.o  rdindex.o  rdrgb.o  \
+		 usegray.o  useindex.o  usepal.o  usetrue.o 
+
+LibraryTarget($(PROJECTLIBDIR)/lib$(PROJECTDCDISPLIBNAME).a,$(OBJS))
+
+DependCCTarget()
diff --git a/libsrc/src/dcdisp/lutclass.cc b/libsrc/src/dcdisp/lutclass.cc
new file mode 100644
index 0000000..4bee9ba
--- /dev/null
+++ b/libsrc/src/dcdisp/lutclass.cc
@@ -0,0 +1,155 @@
+static const char *CopyrightIdentifier(void) { return "@(#)lutclass.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "errclass.h"
+#include "lutclass.h"
+#include "mesgtext.h"
+
+bool
+DicomLUT::fillArray(Attribute *data)
+{
+	// current definitions in the standard make these LUTs OW all the time
+	if (data->isOtherWordNonPixel()) {
+		// retrieve entire OW array at once and copy into our array
+		const Uint16 *values;
+		Uint32 lengthinwords;
+		if (!data->getValue(values,lengthinwords) || !values) {
+			errorstream << EMsgDC(LUTDataBad)
+				    << " - VR=\"" << data->getVR() << "\""
+				    << " VM=" << data->getVM()
+				    << " VL=" << data->getVL()
+				    << endl;
+			good_flag=false;
+			return false;
+		}
+		if (lengthinwords != nentries-firstindexvalue) {
+			errorstream << EMsgDC(LUTDataWrongLength)
+				    << " - length in words=" << lengthinwords
+				    << " but n entries wanted=" << nentries
+				    << " and first index value=" << firstindexvalue
+				    << endl;
+			good_flag=false;
+			return false;
+		}
+		Uint32 i,j;
+		for (i=firstindexvalue,j=0; i<nentries; ++i) {
+			array[i]=values[j];
+			if (i >= firstindexvalue) ++j;
+		}
+
+		return true;
+	}
+	
+	// leave old one-value-at-a-time US approach in case old explicit VR data encountered ...
+	
+	if (!data->isNumeric()) {
+		errorstream << EMsgDC(LUTDataNotNumeric)
+			    << " - \"" << data->getVR() << "\"" << endl;
+		good_flag=false;
+		return false;
+	}
+	if (data->getVM() != nentries) {
+		errorstream << EMsgDC(LUTDataWrongLength)
+			    << " - VR=\"" << data->getVR() << "\""
+			    << " VM=" << data->getVM()
+			    << " VL=" << data->getVL()
+			    << " needed=" << nentries
+			    << endl;
+		good_flag=false;
+		return false;
+	}
+
+	Uint32 i,j;
+	for (i=firstindexvalue,j=0; i<nentries; ++i) {
+		Uint16 lutvalue;
+		if (!data->getValue(Uint16(j),lutvalue)) {
+			errorstream << EMsgDC(LUTDataBad)
+				    << " - VR=\"" << data->getVR() << "\""
+				    << " VM=" << data->getVM()
+				    << " VL=" << data->getVL()
+				    << endl;
+			good_flag=false;
+			return false;
+		}
+		array[i]=lutvalue;
+		if (i >= firstindexvalue) ++j;
+	}
+		
+	return true;
+}
+
+DicomLUT::DicomLUT(Attribute *desc,Attribute*data)
+		{
+			Assert(desc);
+			Assert(data);
+
+			array=0;
+			nentries=0;
+			firstindexvalue=0;
+			bitsallocated=0;
+
+			if (!desc->isNumeric()) {
+				errorstream << EMsgDC(LUTDescriptorNotNumeric)
+					    << " - \"" << desc->getVR() << "\"" << endl;
+				good_flag=false;
+				return;
+			}
+			if (desc->getVM() >= 3 && desc->getVM() <= 4) {
+				if (!desc->getValue(Uint16(0),nentries)
+				 || !desc->getValue(1,firstindexvalue)
+				 || !desc->getValue(2,bitsallocated)) {
+					errorstream << EMsgDC(LUTDescriptorBad)
+						    << " - \"" << desc->getVR() << "\"" << endl;
+					good_flag=false;
+					return;
+				}
+				if (nentries == 0) nentries=0x10000;	// as per Supplement 5 US
+
+				if (nentries) {
+					array=new Uint16[nentries];
+					Assert(array);
+					if (!fillArray(data)) return;
+				}
+			}
+			else {
+				errorstream << EMsgDC(LUTDescriptorWrongVM)
+					    << " - " << desc->getVM() << endl;
+				good_flag=false;
+				return;
+			}
+
+			if (desc->getVM() == 4) {
+				// who knows what this was for ?
+			}
+//cerr << "DicomLUT::DicomLUT - dumping ..." << endl;
+//{
+//Uint32 i;
+//i=0;
+//while (i < nentries) { cerr << "[" << dec << i << "]=" << hex << array[i] << dec << endl; ++i; }
+//}
+		}
+
+DicomLUT::~DicomLUT()
+{
+	if (array) delete[] array;
+}
+
+NormalDicomLUT::NormalDicomLUT(Attribute *desc,Attribute*data)
+	: DicomLUT(desc,data)
+{}
+
+NormalDicomLUT::~NormalDicomLUT()
+{}
+
+LargeDicomLUT::LargeDicomLUT(Attribute *desc,Attribute*data)
+	: DicomLUT(desc,data)
+{}
+
+LargeDicomLUT::~LargeDicomLUT()
+{}
+
+SegmentedDicomLUT::SegmentedDicomLUT(Attribute *desc,Attribute*data)
+	: DicomLUT(desc,data)
+{ Assert(0); }
+
+SegmentedDicomLUT::~SegmentedDicomLUT()
+{}
diff --git a/libsrc/src/dcdisp/lutextr.cc b/libsrc/src/dcdisp/lutextr.cc
new file mode 100644
index 0000000..250754f
--- /dev/null
+++ b/libsrc/src/dcdisp/lutextr.cc
@@ -0,0 +1,75 @@
+static const char *CopyrightIdentifier(void) { return "@(#)lutextr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "errclass.h"
+#include "lutclass.h"
+#include "lutextr.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+
+#define GENERATEEXTRACTNEWLOOKUPTABLE(color,desctype,datatype,luttype) \
+	a##color##LUTData=list[TagFromName(datatype##color##PaletteColorLookupTableData)]; \
+	if (a##color##LUTData) { \
+		if (color##LUT) { \
+			log << EMsgDC(LUTDataMultiplyDefined) \
+			    << " - \"" << #datatype << #color << "PaletteColorLookupTableData\"" \
+			    << endl; \
+			return false; \
+		} \
+		else { \
+			a##color##LUTDescriptor=list[TagFromName(desctype##color##PaletteColorLookupTableDescriptor)]; \
+			if (a##color##LUTData) \
+				color##LUT=new luttype##DicomLUT(a##color##LUTDescriptor,a##color##LUTData); \
+			else { \
+				log << EMsgDC(LUTDataWithoutDescriptor) \
+				    << " - \"" << #datatype << #color << "PaletteColorLookupTableData\"" \
+				    << " needs \"" << #desctype << #color << "PaletteColorLookupTableDescriptor\"" \
+				    << endl; \
+				return false; \
+			} \
+		} \
+	}
+
+bool
+extractLookUpTables(TextOutputStream &log,AttributeList& list,
+	DicomLUT *&RedLUT,
+	DicomLUT *&GreenLUT,
+	DicomLUT *&BlueLUT)
+{
+//cerr << "extractLookUpTables: start" << endl;
+	Attribute *aRedLUTDescriptor = 0;
+	Attribute *aGreenLUTDescriptor = 0;
+	Attribute *aBlueLUTDescriptor = 0;
+	Attribute *aRedLUTData = 0;
+	Attribute *aGreenLUTData = 0;
+	Attribute *aBlueLUTData = 0;
+
+	RedLUT = 0;
+	GreenLUT = 0;
+	BlueLUT = 0;
+
+	GENERATEEXTRACTNEWLOOKUPTABLE(Red,,,Normal);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Red,Large,Large,Large);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Red,,Segmented,Segmented);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Green,,,Normal);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Green,Large,Large,Large);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Green,,Segmented,Segmented);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Blue,,,Normal);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Blue,Large,Large,Large);
+	GENERATEEXTRACTNEWLOOKUPTABLE(Blue,,Segmented,Segmented);
+
+	if (!RedLUT || !GreenLUT || !BlueLUT) {
+		log << EMsgDC(MissingLUTs) << endl;
+		return false;
+	}
+	if (!RedLUT->good() || !GreenLUT->good() || !BlueLUT->good()) {
+		log << RedLUT->errors();
+		log << GreenLUT->errors();
+		log << BlueLUT->errors();
+		return false;
+	}
+
+//cerr << "extractLookUpTables: success" << endl;
+	return true;
+}
+
diff --git a/libsrc/src/dcdisp/rdargb.cc b/libsrc/src/dcdisp/rdargb.cc
new file mode 100644
index 0000000..fbfc47a
--- /dev/null
+++ b/libsrc/src/dcdisp/rdargb.cc
@@ -0,0 +1,42 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdargb.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attr.h"
+#include "srcsink.h"
+#include "errclass.h"
+#include "lutclass.h"
+#include "usepal.h"
+#include "useindex.h"
+#include "usetrue.h"
+#include "rdimage.h"
+#include "rdargb.h"
+
+ReadableInterleaved32BitARGBImage::ReadableInterleaved32BitARGBImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT)
+		: ReadableInterleaved32BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage(),
+		  UseableIndexedColorImage(RedLUT,GreenLUT,BlueLUT)
+{}
+
+ReadableNonInterleaved32BitARGBImage::ReadableNonInterleaved32BitARGBImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT)
+		: ReadableNonInterleaved32BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage(),
+		  UseableIndexedColorImage(RedLUT,GreenLUT,BlueLUT)
+{}
diff --git a/libsrc/src/dcdisp/rdcmyk.cc b/libsrc/src/dcdisp/rdcmyk.cc
new file mode 100644
index 0000000..4cb760e
--- /dev/null
+++ b/libsrc/src/dcdisp/rdcmyk.cc
@@ -0,0 +1,34 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdcmyk.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "usetrue.h"
+#include "rdimage.h"
+#include "rdcmyk.h"
+
+ReadableInterleaved32BitCMYKImage::ReadableInterleaved32BitCMYKImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: ReadableInterleaved32BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage()
+{}
+
+ReadableNonInterleaved32BitCMYKImage::ReadableNonInterleaved32BitCMYKImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: ReadableNonInterleaved32BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage()
+{}
diff --git a/libsrc/src/dcdisp/rdgray.cc b/libsrc/src/dcdisp/rdgray.cc
new file mode 100644
index 0000000..46a7163
--- /dev/null
+++ b/libsrc/src/dcdisp/rdgray.cc
@@ -0,0 +1,131 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdgray.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "usegray.h"
+#include "rdimage.h"
+#include "rdgray.h"
+
+ReadableWindowed8BitGrayImage::ReadableWindowed8BitGrayImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	Uint16 vPixelRepresentation,bool invertedgrayscale)
+		: Readable8BitSinglePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,vPixelRepresentation),
+		  UseableWindowedGrayImage(
+			invertedgrayscale,vBitsStored,vPixelRepresentation)
+{}
+
+ReadableWindowed8BitGrayImage::~ReadableWindowed8BitGrayImage()
+{
+}
+
+bool
+ReadableWindowed8BitGrayImage::getColorCellsWanted(
+	unsigned &nwanted,unsigned &nminimum)
+{
+	return UseableWindowedGrayImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+ReadableWindowed8BitGrayImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	return UseableWindowedGrayImage::setColorCellsAvailable(n,table);
+}
+
+bool
+ReadableWindowed8BitGrayImage::getColorCellValues(unsigned n,
+	unsigned short *&red,
+	unsigned short *&green,
+	unsigned short *&blue)
+{
+	return UseableWindowedGrayImage::getColorCellValues(n,red,green,blue);
+}
+
+ReadableWindowed16BitGrayImage::ReadableWindowed16BitGrayImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	Uint16 vPixelRepresentation,bool invertedgrayscale,
+	bool padvaluepresent,Uint16 vPixelPaddingValue)
+		: Readable16BitSinglePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,vPixelRepresentation),
+		  UseableWindowedGrayImage(
+			invertedgrayscale,vBitsStored,vPixelRepresentation)
+{
+	usepadvalue=padvaluepresent;
+	padvalue=vPixelPaddingValue;
+}
+
+ReadableWindowed16BitGrayImage::~ReadableWindowed16BitGrayImage()
+{
+}
+
+bool
+ReadableWindowed16BitGrayImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	return UseableWindowedGrayImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+ReadableWindowed16BitGrayImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	Uint16 minval;
+	Uint16 maxval;
+	return UseableWindowedGrayImage::setColorCellsAvailable(n,table)
+	    && getImageStatistics(1,minval,maxval,usepadvalue,padvalue)	// just one frame
+	    && UseableWindowedGrayImage::setSign(getBits(),getSigned())	// may be changed by stats
+	    && UseableWindowedGrayImage::setWindowRange(minval,maxval);
+}
+
+bool
+ReadableWindowed16BitGrayImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	return UseableWindowedGrayImage::getColorCellValues(n,red,green,blue);
+}
+
+bool
+ReadableWindowed16BitGrayImage::setWindowLevelWidth(Uint16 level,Uint16 width)
+{
+	return UseableWindowedGrayImage::setWindowLevelWidth(level,width);
+}
+
+bool
+ReadableWindowed16BitGrayImage::getWindowLevelWidth(Uint16 &level,Uint16 &width)
+{
+	return UseableWindowedGrayImage::getWindowLevelWidth(level,width);
+}
+
+bool
+ReadableWindowed16BitGrayImage::needToResetColorCells(void)
+{
+	return false;
+}
+
+bool
+ReadableWindowed16BitGrayImage::needToResetIndexedPixels(void)
+{
+	return false;
+}
+
+bool
+ReadableWindowed16BitGrayImage::setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table)
+{
+	return UseableWindowedGrayImage::setVOILUT(first,number,depth,table);
+}
diff --git a/libsrc/src/dcdisp/rdgray.cc.postsignextend b/libsrc/src/dcdisp/rdgray.cc.postsignextend
new file mode 100755
index 0000000..c033479
--- /dev/null
+++ b/libsrc/src/dcdisp/rdgray.cc.postsignextend
@@ -0,0 +1,118 @@
+#include <iostream.h>
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "usegray.h"
+#include "rdimage.h"
+#include "rdgray.h"
+
+ReadableWindowed8BitGrayImage::ReadableWindowed8BitGrayImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	Uint16 vPixelRepresentation,bool invertedgrayscale)
+		: Readable8BitSinglePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,vPixelRepresentation),
+		  UseableWindowedGrayImage(
+			invertedgrayscale,vBitsAllocated,vPixelRepresentation)
+{}
+
+ReadableWindowed8BitGrayImage::~ReadableWindowed8BitGrayImage()
+{
+}
+
+bool
+ReadableWindowed8BitGrayImage::getColorCellsWanted(
+	unsigned &nwanted,unsigned &nminimum)
+{
+	return UseableWindowedGrayImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+ReadableWindowed8BitGrayImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	return UseableWindowedGrayImage::setColorCellsAvailable(n,table);
+}
+
+bool
+ReadableWindowed8BitGrayImage::getColorCellValues(unsigned n,
+	unsigned short *&red,
+	unsigned short *&green,
+	unsigned short *&blue)
+{
+	return UseableWindowedGrayImage::getColorCellValues(n,red,green,blue);
+}
+
+ReadableWindowed16BitGrayImage::ReadableWindowed16BitGrayImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	Uint16 vPixelRepresentation,bool invertedgrayscale)
+		: Readable16BitSinglePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit,vPixelRepresentation),
+		  UseableWindowedGrayImage(
+			invertedgrayscale,vBitsAllocated,vPixelRepresentation)
+{}
+
+ReadableWindowed16BitGrayImage::~ReadableWindowed16BitGrayImage()
+{
+}
+
+bool
+ReadableWindowed16BitGrayImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	return UseableWindowedGrayImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+ReadableWindowed16BitGrayImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	Uint16 minval;
+	Uint16 maxval;
+	return UseableWindowedGrayImage::setColorCellsAvailable(n,table)
+	    && getImageStatistics(1,minval,maxval)			// just one frame
+	    && UseableWindowedGrayImage::setSign(getBits(),getSigned())	// may be changed by stats
+	    && UseableWindowedGrayImage::setWindowRange(minval,maxval);
+}
+
+bool
+ReadableWindowed16BitGrayImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	return UseableWindowedGrayImage::getColorCellValues(n,red,green,blue);
+}
+
+bool
+ReadableWindowed16BitGrayImage::setWindowLevelWidth(Uint16 level,Uint16 width)
+{
+	return UseableWindowedGrayImage::setWindowLevelWidth(level,width);
+}
+
+bool
+ReadableWindowed16BitGrayImage::getWindowLevelWidth(Uint16 &level,Uint16 &width)
+{
+	return UseableWindowedGrayImage::getWindowLevelWidth(level,width);
+}
+
+bool
+ReadableWindowed16BitGrayImage::needToResetColorCells(void)
+{
+	return false;
+}
+
+bool
+ReadableWindowed16BitGrayImage::needToResetIndexedPixels(void)
+{
+	return false;
+}
+
+bool
+ReadableWindowed16BitGrayImage::setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table)
+{
+	return UseableWindowedGrayImage::setVOILUT(first,number,depth,table);
+}
diff --git a/libsrc/src/dcdisp/rdhsv.cc b/libsrc/src/dcdisp/rdhsv.cc
new file mode 100644
index 0000000..c4233fd
--- /dev/null
+++ b/libsrc/src/dcdisp/rdhsv.cc
@@ -0,0 +1,35 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdhsv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "usetrue.h"
+#include "rdimage.h"
+#include "rdhsv.h"
+
+ReadableInterleaved24BitHSVImage::ReadableInterleaved24BitHSVImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: ReadableInterleaved24BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage()
+{}
+
+ReadableNonInterleaved24BitHSVImage::ReadableNonInterleaved24BitHSVImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: ReadableNonInterleaved24BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage()
+{}
+
diff --git a/libsrc/src/dcdisp/rdimage.cc b/libsrc/src/dcdisp/rdimage.cc
new file mode 100644
index 0000000..6ec3d08
--- /dev/null
+++ b/libsrc/src/dcdisp/rdimage.cc
@@ -0,0 +1,709 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdimage.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "rdimage.h"
+#include "mesgtext.h"
+
+class SourceBase<Uint16> *
+ReadableImage::getSource(void)
+{
+	Assert(supplysource);
+	return supplysource->getSource();
+}
+
+ReadableImage::ReadableImage(
+	SupplySource *s,Uint16 c,Uint16 r,Uint16 f,Uint16 p,
+	Uint16 bn,Uint16 ba,Uint16 bs,Uint16 hb,bool issgn)
+{
+	supplysource=s;
+	columns=c;
+	rows=r;
+	frames=f;
+	planes=p;
+	bitsneeded=bn;
+	bitsallocated=ba;
+	bitsstored=bs;
+	highbit=hb;
+	issigned=issgn;
+	Assert(supplysource);
+	Assert(columns);
+	Assert(rows);
+	Assert(frames);
+	Assert(planes);
+	Assert(bitsneeded);
+	Assert(bitsallocated);
+	Assert(bitsstored);
+	//Assert(highbit);	// could legitimately be zero for single bit image
+}
+
+ReadableImage::~ReadableImage()
+{}
+
+bool
+ReadableImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	Assert(0);
+	(void)dest;
+	(void)bytes_per_row;
+	(void)tlhc_col;
+	(void)tlhc_row;
+	(void)brhc_col;
+	(void)brhc_row;
+	return false;
+}
+
+bool
+ReadableImage::getColorCellsWanted(unsigned &nwanted,unsigned &nminimum)
+{
+	Assert(0);
+	(void)nwanted;
+	(void)nminimum;
+	return false;
+}
+
+bool
+ReadableImage::setColorCellsAvailable(unsigned n,unsigned long *table)
+{
+	Assert(0);
+	(void)n;
+	(void)table;
+	return false;
+}
+
+bool
+ReadableImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	Assert(0);
+	(void)n;
+	(void)red;
+	(void)green;
+	(void)blue;
+	return false;
+}
+
+bool
+ReadableImage::setWindowLevelWidth(Uint16 level,Uint16 width)
+{
+	Assert(0);
+	(void)width;
+	(void)level;
+	return false;
+}
+
+bool
+ReadableImage::setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table)
+{
+	Assert(0);
+	(void)first;
+	(void)number;
+	(void)depth;
+	(void)table;
+	return false;
+}
+
+bool
+ReadableImage::getWindowLevelWidth(Uint16 &level,Uint16 &width)
+{
+	Assert(0);
+	width=0;
+	level=0;
+	return false;
+}
+
+bool
+ReadableImage::needToResetColorCells(void)
+{
+	Assert(0);
+	return false;
+}
+
+bool
+ReadableImage::needToResetIndexedPixels(void)
+{
+	Assert(0);
+	return false;
+}
+
+ReadableSinglePlaneImage::ReadableSinglePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsneeded,Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned)
+		: ReadableImage(
+			s,columns,rows,frames,1,
+			bitsneeded,bitsallocated,bitsstored,highbit,
+			issigned)
+{
+	bufferforfulldepthimage=0;
+}
+
+ReadableSinglePlaneImage::~ReadableSinglePlaneImage()
+{
+	if (bufferforfulldepthimage) delete[] bufferforfulldepthimage;
+}
+
+bool
+ReadableSinglePlaneImage::getBufferedFullDepthImage(void)
+{
+	if (!bufferforfulldepthimage) {
+		Assert(rows);
+		Assert(columns);
+		Assert(planes==1);
+		Assert(frames);
+
+		class SourceBase<Uint16> *source = getSource();
+		if (!source) return false;
+
+		Assert(!bufferforfulldepthimage);
+		bufferforfulldepthimage=new Uint16[columns*rows*frames];
+		Assert(bufferforfulldepthimage);
+		Uint16 *ptr=bufferforfulldepthimage;
+#ifdef REALLYSLOW
+		unsigned row=0;
+		unsigned column=0;
+		while (row < rows*frames && source->read()) {
+			size_t n=source->getBufferCount();
+			Assert(n);
+			const Uint16 *buffer=source->getBuffer();
+			Assert(buffer);
+			while (n-- && row < rows*frames) {
+				*ptr++=*buffer++;
+				if (++column >= columns) {
+					column=0;
+					++row;
+				}
+			}
+		}
+		//Assert(column == 0 && row == rows*frames);
+#else
+		size_t n;
+		const Uint16 *buffer;
+		while (source->read()) {
+			n=source->getBufferCount();
+			//Assert(n);
+			buffer=source->getBuffer();
+			//Assert(buffer);
+			while (n--) {
+				*ptr++=*buffer++;
+			}
+		}
+#endif
+	}
+	//return row >= rows*frames;	// read enough
+	return true;	// ignore premature eof
+}
+
+bool
+ReadableSinglePlaneImage::getImageStatistics(Uint16 framecount,
+		Uint16 &minval,Uint16 &maxval,
+		bool excludepadvalue,Uint16 padvalue)
+{
+	if (!bufferforfulldepthimage) getBufferedFullDepthImage();
+	Uint16 *ptr=bufferforfulldepthimage;
+
+	Int16  signedminval=Int16_MAX;
+	Int16  signedmaxval=Int16_MIN;
+	Uint16 unsignedminval=Uint16_MAX;
+	Uint16 unsignedmaxval=0;
+
+//cerr << "ReadableSinglePlaneImage::getImageStatistics start min=" << hex << minval << " max=" << hex << maxval << dec << endl;
+
+	unsigned row=0;
+	unsigned column=0;
+	while (row < rows*framecount) {
+		Uint16 value=*ptr++;
+		if (!excludepadvalue || value != padvalue) {
+			if (Int16(value) < signedminval) signedminval=value;
+			if (Int16(value) > signedmaxval) signedmaxval=value;
+			if (value < unsignedminval) unsignedminval=value;
+			if (value > unsignedmaxval) unsignedmaxval=value;
+		}
+		if (++column >= columns) {
+			column=0;
+			++row;
+		}
+	}
+	//Assert(column == 0 && row == rows*framecount);
+
+//cerr << "ReadableSinglePlaneImage::getImageStatistics signedminval=" << hex << Uint16(signedminval) << endl;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics signedmaxval=" << hex << Uint16(signedmaxval) << dec << endl;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics unsignedminval=" << hex << unsignedminval << endl;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics unsignedmaxval=" << hex << unsignedmaxval << dec << endl;
+
+	Uint16 signedrange=Uint16(signedmaxval-signedminval);
+	Uint16 unsignedrange=unsignedmaxval-unsignedminval;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics signedrange=" << hex << signedrange << dec << endl;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics unsignedrange=" << hex << unsignedrange << endl;
+#ifdef FIXSIGNIFGUESSDIFFERENT
+	if (signedrange < unsignedrange) {
+		if (!issigned) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Signed)
+			     << endl;
+			issigned=true;
+		}
+		minval=Uint16(signedminval);
+		maxval=Uint16(signedmaxval);
+	}
+	else if (signedrange > unsignedrange) {
+		if (issigned) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Unsigned)
+			     << endl;
+			issigned=false;
+		}
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+	else {
+		issigned=false;
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+#else /* FIXSIGNIFGUESSDIFFERENT */
+	if (issigned) {
+		if (signedrange > unsignedrange) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Unsigned)
+			     << endl;
+			issigned=true;
+		}
+		minval=Uint16(signedminval);
+		maxval=Uint16(signedmaxval);
+	}
+	else {
+		if (signedrange < unsignedrange) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Signed)
+			     << endl;
+			issigned=false;
+		}
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+#endif /* FIXSIGNIFGUESSDIFFERENT */
+
+//cerr << "ReadableSinglePlaneImage::getImageStatistics minval before xoring=" << hex << minval << endl;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics maxval before xoring=" << hex << maxval << dec << endl;
+
+	// xor with high bit into unsigned space used to represent pixels ...
+
+	if (issigned) minval=minval^(1<<(bitsstored-1));
+	if (issigned) maxval=maxval^(1<<(bitsstored-1));
+
+//cerr << "ReadableSinglePlaneImage::getImageStatistics minval=" << hex << minval << endl;
+//cerr << "ReadableSinglePlaneImage::getImageStatistics maxval=" << hex << maxval << dec << endl;
+
+//cerr << "ReadableSinglePlaneImage::getImageStatistics done min=" << hex << minval << " max=" << hex << maxval << dec << endl;
+
+	//return row >= rows*framecount;	// read enough
+	return true;	// ignore premature eof
+}
+
+bool
+ReadableSinglePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	if (!bufferforfulldepthimage) getBufferedFullDepthImage();
+	Uint16 *ptr=bufferforfulldepthimage;
+
+	if (tlhc_row+rows > brhc_row+1
+	 || tlhc_col+columns  > brhc_col+1) {
+		return false;
+	}
+	unsigned row=0;
+	unsigned column=0;
+	char *p = dest
+		+ tlhc_row*bytes_per_row
+		+ tlhc_col;
+
+#ifndef REALLYSLOW
+		Uint32 pixelMapLength=0;
+//cerr << "ReadableSinglePlaneImage::put8BitIndexedPixels: about to getPixelMap()" << endl;
+		const char *pixelMap=getPixelMap(pixelMapLength);	// this will fail on palette color images :(
+		Assert(pixelMap && pixelMapLength);
+#endif
+
+#ifdef REALLYSLOW
+	while (row < rows*frames) {
+		*p=mapPixel(*ptr);
+		p++;
+		ptr++;
+		if (++column >= columns) {
+			column=0;
+			++row;
+			p = dest
+			  + (tlhc_row+row)*bytes_per_row
+			  + tlhc_col;
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+	return row >= rows*frames;	// read enough
+#else
+#ifdef PRETTYSLOW
+	while (row < rows*frames) {
+		//Assert(*ptr < pixelMapLength);
+		*p++=pixelMap[*ptr++];
+		if (++column >= columns) {
+			column=0;
+			++row;
+			p = dest
+			  + (tlhc_row+row)*bytes_per_row
+			  + tlhc_col;
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+	return row >= rows*frames;	// read enough
+#else
+	char *plast=p+rows*frames*bytes_per_row;
+	int add_at_row_end=bytes_per_row-columns;
+	if (add_at_row_end) {
+		while (p < plast) {
+			char *p_row_end=p+columns;
+			while (p < p_row_end) {
+				*p++=pixelMap[*ptr++];
+			}
+			p+=add_at_row_end;
+		}
+	}
+	else {
+//cerr << "ReadableSinglePlaneImage::put8BitIndexedPixels: optimizing for no row end padding" << endl;
+		if (columns%8 == 0) {
+//cerr << "ReadableSinglePlaneImage::put8BitIndexedPixels: optimizing for mod 8" << endl;
+			while (p < plast) {
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+			}
+		}
+		else {
+			while (p < plast) *p++=pixelMap[*ptr++];
+		}
+	}
+	return true;
+#endif
+#endif
+}
+
+ReadableMultiplePlaneImage::ReadableMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,Uint16 planes,
+	Uint16 bitsneeded,Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableImage(
+			s,columns,rows,frames,planes,
+			bitsneeded,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableMultiplePlaneImage::~ReadableMultiplePlaneImage()
+{}
+
+Readable8BitSinglePlaneImage::Readable8BitSinglePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned)
+		: ReadableSinglePlaneImage(
+			s,columns,rows,frames,
+			8,bitsallocated,bitsstored,highbit,
+			issigned)
+{}
+
+Readable8BitSinglePlaneImage::~Readable8BitSinglePlaneImage()
+{}
+
+bool
+Readable8BitSinglePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+//cerr << "Readable8BitSinglePlaneImage::put8BitIndexedPixels" << endl;
+	Assert(bitsneeded==8);
+	Assert(bitsallocated==8);
+	Assert(bitsstored==8);
+	Assert(highbit==7);
+	return ReadableSinglePlaneImage::put8BitIndexedPixels(dest,
+		bytes_per_row,tlhc_col,tlhc_row,brhc_col,brhc_row);
+}
+
+Readable16BitSinglePlaneImage::Readable16BitSinglePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned)
+		: ReadableSinglePlaneImage(
+			s,columns,rows,frames,
+			16,bitsallocated,bitsstored,highbit,
+			issigned)
+{}
+
+Readable16BitSinglePlaneImage::~Readable16BitSinglePlaneImage()
+{}
+
+bool Readable16BitSinglePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+//cerr << "Readable16BitSinglePlaneImage::put8BitIndexedPixels" << endl;
+	Assert(bitsneeded<=16);
+	Assert(bitsallocated<=16);
+	Assert(bitsstored<=16);
+	Assert(highbit<=15);
+	return ReadableSinglePlaneImage::put8BitIndexedPixels(dest,
+		bytes_per_row,tlhc_col,tlhc_row,brhc_col,brhc_row);
+}
+
+Readable16BitMultiplePlaneImage::Readable16BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,3,
+			5,bitsallocated,bitsstored,highbit)
+{}
+
+Readable16BitMultiplePlaneImage::~Readable16BitMultiplePlaneImage()
+{}
+
+ReadableInterleaved24BitMultiplePlaneImage::ReadableInterleaved24BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,3,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableInterleaved24BitMultiplePlaneImage::~ReadableInterleaved24BitMultiplePlaneImage()
+{}
+
+bool
+ReadableInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	Assert(rows);
+	Assert(columns);
+	Assert(planes==3);
+
+//cerr << "ReadableInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(): bytes_per_row=" << bytes_per_row << endl;
+
+	class SourceBase<Uint16> *source = getSource();
+	if (!source) return false;
+
+	if (tlhc_row+rows > brhc_row+1
+	 || tlhc_col+columns  > brhc_col+1) {
+		return false;
+	}
+	unsigned row=0;
+	unsigned column=0;
+	char *p = dest
+		+ tlhc_row*bytes_per_row
+		+ tlhc_col;
+	while (row < rows*frames && source->read()) {
+		size_t n=source->getBufferCount();
+		Assert(n);
+		Assert(n%3 == 0);
+		const Uint16 *buffer=source->getBuffer();
+		Assert(buffer);
+		while (n >= 3 && row < rows*frames) {
+			n-=3;
+			*p=mapPixel(*buffer,*(buffer+1),*(buffer+2));
+//if (row%50 == 0) {
+//cerr << "[" << dec << column << "," << dec << row
+//     << "] = " << hex << *buffer
+//     << ", " << hex << *(buffer+1)
+//     << ", " << hex << *(buffer+2)
+//     << " -> " << dec << Uint16(*(unsigned char *)p)
+//     << dec << endl;
+//}
+
+//if (column == 0 || column == columns-1) {
+//	cerr << "[" << row << "," << column << "]: r=" << *buffer << " g=" << *(buffer+1) << " b= " << *(buffer+2) << endl;
+//}
+			p++;
+			buffer+=3;
+			if (++column >= columns) {
+				column=0;
+				++row;
+				char *p = dest
+					+ (tlhc_row+row)*bytes_per_row
+					+ tlhc_col;
+//cerr << "ReadableInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(): Start new row=" << row << " with p=" << (unsigned long)p << " and " << n << " left in buffer" << endl;
+			}
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+	return row >= rows*frames;	// read enough
+}
+
+ReadableNonInterleaved24BitMultiplePlaneImage::ReadableNonInterleaved24BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,3,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableNonInterleaved24BitMultiplePlaneImage::~ReadableNonInterleaved24BitMultiplePlaneImage()
+{}
+
+bool
+ReadableNonInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	Assert(rows);
+	Assert(columns);
+	Assert(planes==3);
+
+	class SourceBase<Uint16> *source = getSource();
+	if (!source) return false;
+
+	// be wary here about using unsigned char to truncate Uint16
+	// from buffer - inadvertent sign extension will confuse
+	// mapPixel()
+
+	int pixelsinframe=rows*columns;
+
+	unsigned char *redplane  =new unsigned char[pixelsinframe];
+	Assert(redplane);
+	unsigned char *greenplane=new  unsigned char[pixelsinframe];
+	Assert(greenplane);
+	unsigned char *blueplane =new  unsigned char[pixelsinframe];
+	Assert(blueplane);
+
+	unsigned char *planes[3];
+	planes[0]=redplane;
+	planes[1]=greenplane;
+	planes[2]=blueplane;
+
+	if (tlhc_row+rows > brhc_row+1
+	 || tlhc_col+columns  > brhc_col+1) {
+		return false;
+	}
+
+	unsigned row=0;
+	unsigned column=0;
+	unsigned frame=0;
+	unsigned plane=0;
+
+	size_t n=0;
+	const Uint16 *buffer=0;
+	while (frame < frames) {
+		if (n <= 0) {
+			if (source->read()) {
+				n=source->getBufferCount();
+				Assert(n);
+				buffer=source->getBuffer();
+				Assert(buffer);
+			}
+			else
+				break;
+		}
+
+		*(planes[plane]++)=*buffer++;
+		--n;
+
+		if (++column >= columns) {
+			column=0;
+			if (++row >= rows) {
+				row=0;
+				if (++plane >= 3) {
+					plane=0;
+
+					unsigned char *rp=planes[0]=redplane;
+					unsigned char *gp=planes[1]=greenplane;
+					unsigned char *bp=planes[2]=blueplane;
+
+					unsigned r=0;
+					while (r < rows) {
+						char *p = dest
+							+ (tlhc_row+r+frame*rows)*bytes_per_row
+							+ tlhc_col;
+						unsigned c=0;
+						while (c++ < columns) {
+							*p++=mapPixel(*rp++,*gp++,*bp++);
+						}
+						++r;
+					}
+
+					++frame;
+				}
+			}
+		}
+	}
+
+	if (redplane)   delete[] redplane;
+	if (greenplane) delete[] greenplane;
+	if (blueplane)  delete[] blueplane;
+
+	return frame >= frames;	// read enough
+}
+
+ReadableInterleaved32BitMultiplePlaneImage::ReadableInterleaved32BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,4,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableInterleaved32BitMultiplePlaneImage::~ReadableInterleaved32BitMultiplePlaneImage()
+{}
+
+ReadableNonInterleaved32BitMultiplePlaneImage::ReadableNonInterleaved32BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,4,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableNonInterleaved32BitMultiplePlaneImage::~ReadableNonInterleaved32BitMultiplePlaneImage()
+{}
+
diff --git a/libsrc/src/dcdisp/rdimage.cc.postsignextend b/libsrc/src/dcdisp/rdimage.cc.postsignextend
new file mode 100755
index 0000000..d7e9cf8
--- /dev/null
+++ b/libsrc/src/dcdisp/rdimage.cc.postsignextend
@@ -0,0 +1,715 @@
+#include <iostream.h>
+#include <iomanip.h>
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "rdimage.h"
+#include "mesgtext.h"
+
+class SourceBase<Uint16> *
+ReadableImage::getSource(void)
+{
+	Assert(supplysource);
+	return supplysource->getSource();
+}
+
+ReadableImage::ReadableImage(
+	SupplySource *s,Uint16 c,Uint16 r,Uint16 f,Uint16 p,
+	Uint16 bn,Uint16 ba,Uint16 bs,Uint16 hb,bool issgn)
+{
+	supplysource=s;
+	columns=c;
+	rows=r;
+	frames=f;
+	planes=p;
+	bitsneeded=bn;
+	bitsallocated=ba;
+	bitsstored=bs;
+	highbit=hb;
+	issigned=issgn;
+	Assert(supplysource);
+	Assert(columns);
+	Assert(rows);
+	Assert(frames);
+	Assert(planes);
+	Assert(bitsneeded);
+	Assert(bitsallocated);
+	Assert(bitsstored);
+	Assert(highbit);
+}
+
+ReadableImage::~ReadableImage()
+{}
+
+bool
+ReadableImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	Assert(0);
+	(void)dest;
+	(void)bytes_per_row;
+	(void)tlhc_col;
+	(void)tlhc_row;
+	(void)brhc_col;
+	(void)brhc_row;
+	return false;
+}
+
+bool
+ReadableImage::getColorCellsWanted(unsigned &nwanted,unsigned &nminimum)
+{
+	Assert(0);
+	(void)nwanted;
+	(void)nminimum;
+	return false;
+}
+
+bool
+ReadableImage::setColorCellsAvailable(unsigned n,unsigned long *table)
+{
+	Assert(0);
+	(void)n;
+	(void)table;
+	return false;
+}
+
+bool
+ReadableImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	Assert(0);
+	(void)n;
+	(void)red;
+	(void)green;
+	(void)blue;
+	return false;
+}
+
+bool
+ReadableImage::setWindowLevelWidth(Uint16 level,Uint16 width)
+{
+	Assert(0);
+	(void)width;
+	(void)level;
+	return false;
+}
+
+bool
+ReadableImage::setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table)
+{
+	Assert(0);
+	(void)first;
+	(void)number;
+	(void)depth;
+	(void)table;
+	return false;
+}
+
+bool
+ReadableImage::getWindowLevelWidth(Uint16 &level,Uint16 &width)
+{
+	Assert(0);
+	width=0;
+	level=0;
+	return false;
+}
+
+bool
+ReadableImage::needToResetColorCells(void)
+{
+	Assert(0);
+	return false;
+}
+
+bool
+ReadableImage::needToResetIndexedPixels(void)
+{
+	Assert(0);
+	return false;
+}
+
+ReadableSinglePlaneImage::ReadableSinglePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsneeded,Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned)
+		: ReadableImage(
+			s,columns,rows,frames,1,
+			bitsneeded,bitsallocated,bitsstored,highbit,
+			issigned)
+{
+	bufferforfulldepthimage=0;
+}
+
+ReadableSinglePlaneImage::~ReadableSinglePlaneImage()
+{
+	if (bufferforfulldepthimage) delete[] bufferforfulldepthimage;
+}
+
+bool
+ReadableSinglePlaneImage::getBufferedFullDepthImage(void)
+{
+	if (!bufferforfulldepthimage) {
+		Assert(rows);
+		Assert(columns);
+		Assert(planes==1);
+		Assert(frames);
+
+		class SourceBase<Uint16> *source = getSource();
+		if (!source) return false;
+
+		Assert(!bufferforfulldepthimage);
+		bufferforfulldepthimage=new Uint16[columns*rows*frames];
+		Assert(bufferforfulldepthimage);
+		Uint16 *ptr=bufferforfulldepthimage;
+#ifdef REALLYSLOW
+		unsigned row=0;
+		unsigned column=0;
+		while (row < rows*frames && source->read()) {
+			size_t n=source->getBufferCount();
+			Assert(n);
+			const Uint16 *buffer=source->getBuffer();
+			Assert(buffer);
+			while (n-- && row < rows*frames) {
+				*ptr++=*buffer++;
+				if (++column >= columns) {
+					column=0;
+					++row;
+				}
+			}
+		}
+		//Assert(column == 0 && row == rows*frames);
+#else
+		size_t n;
+		const Uint16 *buffer;
+		while (source->read()) {
+			n=source->getBufferCount();
+			//Assert(n);
+			buffer=source->getBuffer();
+			//Assert(buffer);
+			while (n--) {
+				*ptr++=*buffer++;
+			}
+		}
+#endif
+	}
+	//return row >= rows*frames;	// read enough
+	return true;	// ignore premature eof
+}
+
+static inline Int16
+sign_extend(Uint16 value,Uint16 bitsstored)
+{
+//cerr << "sign_extend: value was=0x" << hex << value << dec << endl;
+//cerr << "sign_extend: bitsstored=" << dec << bitsstored << endl;
+
+	Uint16 signbit_mask = 1<<(bitsstored-1);
+	Assert(sizeof(Uint16)*8 >= bitsstored);
+	Uint16 highbit_mask = ~(Uint16_MAX >> (sizeof(Uint16)*8-bitsstored));
+
+//cerr << "sign_extend: signbit_mask=0x" << hex << signbit_mask << " highbit_mask=0x" << hex << highbit_mask << dec << endl;
+
+	value = (value & signbit_mask) ? (value | highbit_mask) : (value & ~highbit_mask);
+
+//cerr << "sign_extend: value now=0x" << hex << value << " Int16 is=0x" << hex << Int16(value) << dec << endl;
+
+	return Int16(value);
+}
+
+bool
+ReadableSinglePlaneImage::getImageStatistics(Uint16 framecount,
+		Uint16 &minval,Uint16 &maxval)
+{
+	if (!bufferforfulldepthimage) getBufferedFullDepthImage();
+	Uint16 *ptr=bufferforfulldepthimage;
+
+	Int16  signedminval=Int16_MAX;
+	Int16  signedmaxval=Int16_MIN;
+	Uint16 unsignedminval=Uint16_MAX;
+	Uint16 unsignedmaxval=0;
+
+cerr << "ReadableSinglePlaneImage::getImageStatistics start min=" << hex << minval << " max=" << hex << maxval << dec << endl;
+
+	unsigned row=0;
+	unsigned column=0;
+	while (row < rows*framecount) {
+		Uint16 value=*ptr++;
+		Int16 svalue=sign_extend(value,bitsstored);
+		if (svalue < signedminval) signedminval=svalue;
+		if (svalue > signedmaxval) signedmaxval=svalue;
+		if (value < unsignedminval) unsignedminval=value;
+		if (value > unsignedmaxval) unsignedmaxval=value;
+		if (++column >= columns) {
+			column=0;
+			++row;
+		}
+	}
+	//Assert(column == 0 && row == rows*framecount);
+
+cerr << "ReadableSinglePlaneImage::getImageStatistics signedminval=" << hex << Uint16(signedminval) << endl;
+cerr << "ReadableSinglePlaneImage::getImageStatistics signedmaxval=" << hex << Uint16(signedmaxval) << dec << endl;
+cerr << "ReadableSinglePlaneImage::getImageStatistics unsignedminval=" << hex << unsignedminval << endl;
+cerr << "ReadableSinglePlaneImage::getImageStatistics unsignedmaxval=" << hex << unsignedmaxval << dec << endl;
+
+	Uint16 signedrange=Uint16(signedmaxval-signedminval);
+	Uint16 unsignedrange=unsignedmaxval-unsignedminval;
+cerr << "ReadableSinglePlaneImage::getImageStatistics signedrange=" << hex << signedrange << dec << endl;
+cerr << "ReadableSinglePlaneImage::getImageStatistics unsignedrange=" << hex << unsignedrange << endl;
+#ifdef FIXSIGNIFGUESSDIFFERENT
+	if (signedrange < unsignedrange) {
+		if (!issigned) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Signed)
+			     << endl;
+			issigned=true;
+		}
+		minval=Uint16(signedminval);
+		maxval=Uint16(signedmaxval);
+	}
+	else if (signedrange > unsignedrange) {
+		if (issigned) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Unsigned)
+			     << endl;
+			issigned=false;
+		}
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+	else {
+		issigned=false;
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+#else /* FIXSIGNIFGUESSDIFFERENT */
+	if (issigned) {
+		if (signedrange > unsignedrange) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Unsigned)
+			     << endl;
+			issigned=true;
+		}
+		minval=Uint16(signedminval);
+		maxval=Uint16(signedmaxval);
+	}
+	else {
+		if (signedrange < unsignedrange) {
+			// This message should be propagated properly ... :(
+			cerr << WMsgDC(PixelRepresentationIncorrect)
+			     << " - " << MMsgDC(ShouldBe) << " " << MMsgDC(Signed)
+			     << endl;
+			issigned=false;
+		}
+		minval=unsignedminval;
+		maxval=unsignedmaxval;
+	}
+#endif /* FIXSIGNIFGUESSDIFFERENT */
+
+cerr << "ReadableSinglePlaneImage::getImageStatistics minval before xoring=" << hex << minval << endl;
+cerr << "ReadableSinglePlaneImage::getImageStatistics maxval before xoring=" << hex << maxval << dec << endl;
+
+	// xor with high bit into unsigned space used to represent pixels ...
+
+	if (issigned) minval=minval^(1<<(sizeof(Uint16)*8-1));	// was bitstored-1 before sign extension feature added
+	if (issigned) maxval=maxval^(1<<(sizeof(Uint16)*8-1));
+
+cerr << "ReadableSinglePlaneImage::getImageStatistics minval=" << hex << minval << endl;
+cerr << "ReadableSinglePlaneImage::getImageStatistics maxval=" << hex << maxval << dec << endl;
+
+cerr << "ReadableSinglePlaneImage::getImageStatistics done min=" << hex << minval << " max=" << hex << maxval << dec << endl;
+
+	//return row >= rows*framecount;	// read enough
+	return true;	// ignore premature eof
+}
+
+bool
+ReadableSinglePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	if (!bufferforfulldepthimage) getBufferedFullDepthImage();
+	Uint16 *ptr=bufferforfulldepthimage;
+
+	if (tlhc_row+rows > brhc_row+1
+	 || tlhc_col+columns  > brhc_col+1) {
+		return false;
+	}
+	unsigned row=0;
+	unsigned column=0;
+	char *p = dest
+		+ tlhc_row*bytes_per_row
+		+ tlhc_col;
+
+#ifndef REALLYSLOW
+		Uint32 pixelMapLength=0;
+		const char *pixelMap=getPixelMap(pixelMapLength);
+		Assert(pixelMap && pixelMapLength);
+#endif
+
+#ifdef REALLYSLOW
+	while (row < rows*frames) {
+		*p=mapPixel(*ptr);
+		p++;
+		ptr++;
+		if (++column >= columns) {
+			column=0;
+			++row;
+			p = dest
+			  + (tlhc_row+row)*bytes_per_row
+			  + tlhc_col;
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+	return row >= rows*frames;	// read enough
+#else
+#ifdef PRETTYSLOW
+	while (row < rows*frames) {
+		//Assert(*ptr < pixelMapLength);
+		*p++=pixelMap[*ptr++];
+		if (++column >= columns) {
+			column=0;
+			++row;
+			p = dest
+			  + (tlhc_row+row)*bytes_per_row
+			  + tlhc_col;
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+	return row >= rows*frames;	// read enough
+#else
+	char *plast=p+rows*frames*bytes_per_row;
+	int add_at_row_end=bytes_per_row-columns;
+	if (add_at_row_end) {
+		while (p < plast) {
+			char *p_row_end=p+columns;
+			while (p < p_row_end) {
+				*p++=pixelMap[*ptr++];
+			}
+			p+=add_at_row_end;
+		}
+	}
+	else {
+cerr << "ReadableSinglePlaneImage::put8BitIndexedPixels: optimizing for no row end padding" << endl;
+		if (columns%8 == 0) {
+cerr << "ReadableSinglePlaneImage::put8BitIndexedPixels: optimizing for mod 8" << endl;
+			while (p < plast) {
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+				*p++=pixelMap[*ptr++];
+			}
+		}
+		else {
+			while (p < plast) *p++=pixelMap[*ptr++];
+		}
+	}
+	return true;
+#endif
+#endif
+}
+
+ReadableMultiplePlaneImage::ReadableMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,Uint16 planes,
+	Uint16 bitsneeded,Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableImage(
+			s,columns,rows,frames,planes,
+			bitsneeded,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableMultiplePlaneImage::~ReadableMultiplePlaneImage()
+{}
+
+Readable8BitSinglePlaneImage::Readable8BitSinglePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned)
+		: ReadableSinglePlaneImage(
+			s,columns,rows,frames,
+			8,bitsallocated,bitsstored,highbit,
+			issigned)
+{}
+
+Readable8BitSinglePlaneImage::~Readable8BitSinglePlaneImage()
+{}
+
+bool
+Readable8BitSinglePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+//cerr << "Readable8BitSinglePlaneImage::put8BitIndexedPixels" << endl;
+	Assert(bitsneeded==8);
+	Assert(bitsallocated==8);
+	Assert(bitsstored==8);
+	Assert(highbit==7);
+	return ReadableSinglePlaneImage::put8BitIndexedPixels(dest,
+		bytes_per_row,tlhc_col,tlhc_row,brhc_col,brhc_row);
+}
+
+Readable16BitSinglePlaneImage::Readable16BitSinglePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit,
+		bool issigned)
+		: ReadableSinglePlaneImage(
+			s,columns,rows,frames,
+			16,bitsallocated,bitsstored,highbit,
+			issigned)
+{}
+
+Readable16BitSinglePlaneImage::~Readable16BitSinglePlaneImage()
+{}
+
+bool Readable16BitSinglePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+//cerr << "Readable16BitSinglePlaneImage::put8BitIndexedPixels" << endl;
+	Assert(bitsneeded<=16);
+	Assert(bitsallocated<=16);
+	Assert(bitsstored<=16);
+	Assert(highbit<=15);
+	return ReadableSinglePlaneImage::put8BitIndexedPixels(dest,
+		bytes_per_row,tlhc_col,tlhc_row,brhc_col,brhc_row);
+}
+
+Readable16BitMultiplePlaneImage::Readable16BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,3,
+			5,bitsallocated,bitsstored,highbit)
+{}
+
+Readable16BitMultiplePlaneImage::~Readable16BitMultiplePlaneImage()
+{}
+
+ReadableInterleaved24BitMultiplePlaneImage::ReadableInterleaved24BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,3,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableInterleaved24BitMultiplePlaneImage::~ReadableInterleaved24BitMultiplePlaneImage()
+{}
+
+bool
+ReadableInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	Assert(rows);
+	Assert(columns);
+	Assert(planes==3);
+
+//cerr << "ReadableInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(): bytes_per_row=" << bytes_per_row << endl;
+
+	class SourceBase<Uint16> *source = getSource();
+	if (!source) return false;
+
+	if (tlhc_row+rows > brhc_row+1
+	 || tlhc_col+columns  > brhc_col+1) {
+		return false;
+	}
+	unsigned row=0;
+	unsigned column=0;
+	char *p = dest
+		+ tlhc_row*bytes_per_row
+		+ tlhc_col;
+	while (row < rows*frames && source->read()) {
+		size_t n=source->getBufferCount();
+		Assert(n);
+		Assert(n%3 == 0);
+		const Uint16 *buffer=source->getBuffer();
+		Assert(buffer);
+		while (n >= 3 && row < rows*frames) {
+			n-=3;
+			*p=mapPixel(*buffer,*(buffer+1),*(buffer+2));
+//if (row%50 == 0) {
+//cerr << "[" << dec << column << "," << dec << row
+//     << "] = " << hex << *buffer
+//     << ", " << hex << *(buffer+1)
+//     << ", " << hex << *(buffer+2)
+//     << " -> " << dec << Uint16(*(unsigned char *)p)
+//     << dec << endl;
+//}
+
+//if (column == 0 || column == columns-1) {
+//	cerr << "[" << row << "," << column << "]: r=" << *buffer << " g=" << *(buffer+1) << " b= " << *(buffer+2) << endl;
+//}
+			p++;
+			buffer+=3;
+			if (++column >= columns) {
+				column=0;
+				++row;
+				char *p = dest
+					+ (tlhc_row+row)*bytes_per_row
+					+ tlhc_col;
+//cerr << "ReadableInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(): Start new row=" << row << " with p=" << (unsigned long)p << " and " << n << " left in buffer" << endl;
+			}
+		}
+	}
+	//Assert(column == 0 && row == rows*frames);
+	return row >= rows*frames;	// read enough
+}
+
+ReadableNonInterleaved24BitMultiplePlaneImage::ReadableNonInterleaved24BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,3,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableNonInterleaved24BitMultiplePlaneImage::~ReadableNonInterleaved24BitMultiplePlaneImage()
+{}
+
+bool
+ReadableNonInterleaved24BitMultiplePlaneImage::put8BitIndexedPixels(
+			char *dest,
+			unsigned long bytes_per_row,
+			unsigned long tlhc_col,
+			unsigned long tlhc_row,
+			unsigned long brhc_col,
+			unsigned long brhc_row)
+{
+	Assert(rows);
+	Assert(columns);
+	Assert(planes==3);
+
+	class SourceBase<Uint16> *source = getSource();
+	if (!source) return false;
+
+	// be wary here about using unsigned char to truncate Uint16
+	// from buffer - inadvertent sign extension will confuse
+	// mapPixel()
+
+	int pixelsinframe=rows*columns;
+
+	unsigned char *redplane  =new unsigned char[pixelsinframe];
+	Assert(redplane);
+	unsigned char *greenplane=new  unsigned char[pixelsinframe];
+	Assert(greenplane);
+	unsigned char *blueplane =new  unsigned char[pixelsinframe];
+	Assert(blueplane);
+
+	unsigned char *planes[3];
+	planes[0]=redplane;
+	planes[1]=greenplane;
+	planes[2]=blueplane;
+
+	if (tlhc_row+rows > brhc_row+1
+	 || tlhc_col+columns  > brhc_col+1) {
+		return false;
+	}
+
+	unsigned row=0;
+	unsigned column=0;
+	unsigned frame=0;
+	unsigned plane=0;
+
+	size_t n=0;
+	const Uint16 *buffer=0;
+	while (frame < frames) {
+		if (n <= 0) {
+			if (source->read()) {
+				n=source->getBufferCount();
+				Assert(n);
+				buffer=source->getBuffer();
+				Assert(buffer);
+			}
+			else
+				break;
+		}
+
+		*(planes[plane]++)=*buffer++;
+		--n;
+
+		if (++column >= columns) {
+			column=0;
+			if (++row >= rows) {
+				row=0;
+				if (++plane >= 3) {
+					plane=0;
+
+					unsigned char *rp=planes[0]=redplane;
+					unsigned char *gp=planes[1]=greenplane;
+					unsigned char *bp=planes[2]=blueplane;
+
+					unsigned r=0;
+					while (r < rows) {
+						char *p = dest
+							+ (tlhc_row+r+frame*rows)*bytes_per_row
+							+ tlhc_col;
+						unsigned c=0;
+						while (c++ < columns) {
+							*p++=mapPixel(*rp++,*gp++,*bp++);
+						}
+						++r;
+					}
+
+					++frame;
+				}
+			}
+		}
+	}
+
+	if (redplane)   delete[] redplane;
+	if (greenplane) delete[] greenplane;
+	if (blueplane)  delete[] blueplane;
+
+	return frame >= frames;	// read enough
+}
+
+ReadableInterleaved32BitMultiplePlaneImage::ReadableInterleaved32BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,4,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableInterleaved32BitMultiplePlaneImage::~ReadableInterleaved32BitMultiplePlaneImage()
+{}
+
+ReadableNonInterleaved32BitMultiplePlaneImage::ReadableNonInterleaved32BitMultiplePlaneImage(
+	SupplySource *s,Uint16 columns,Uint16 rows,Uint16 frames,
+	Uint16 bitsallocated,Uint16 bitsstored,Uint16 highbit)
+		: ReadableMultiplePlaneImage(
+			s,columns,rows,frames,4,
+			8,bitsallocated,bitsstored,highbit)
+{}
+
+ReadableNonInterleaved32BitMultiplePlaneImage::~ReadableNonInterleaved32BitMultiplePlaneImage()
+{}
+
diff --git a/libsrc/src/dcdisp/rdindex.cc b/libsrc/src/dcdisp/rdindex.cc
new file mode 100644
index 0000000..e585ada
--- /dev/null
+++ b/libsrc/src/dcdisp/rdindex.cc
@@ -0,0 +1,68 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdindex.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attr.h"
+#include "srcsink.h"
+#include "errclass.h"
+#include "lutclass.h"
+#include "usepal.h"
+#include "useindex.h"
+#include "rdimage.h"
+#include "rdindex.h"
+
+Readable8BitIndexedColorImage::Readable8BitIndexedColorImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT)
+		: Readable8BitSinglePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableIndexedColorImage(RedLUT,GreenLUT,BlueLUT)
+{}
+
+Readable8BitIndexedColorImage::~Readable8BitIndexedColorImage()
+{}
+
+bool
+Readable8BitIndexedColorImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	return UseableIndexedColorImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+Readable8BitIndexedColorImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	return UseableIndexedColorImage::setColorCellsAvailable(n,table);
+}
+
+bool
+Readable8BitIndexedColorImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	return UseableIndexedColorImage::getColorCellValues(n,red,green,blue);
+}
+
+Readable16BitIndexedColorImage::Readable16BitIndexedColorImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit,
+	DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT) 
+		: Readable16BitSinglePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableIndexedColorImage(RedLUT,GreenLUT,BlueLUT)
+{}
+
+Readable16BitIndexedColorImage::~Readable16BitIndexedColorImage()
+{}
diff --git a/libsrc/src/dcdisp/rdrgb.cc b/libsrc/src/dcdisp/rdrgb.cc
new file mode 100644
index 0000000..ff442ad
--- /dev/null
+++ b/libsrc/src/dcdisp/rdrgb.cc
@@ -0,0 +1,87 @@
+static const char *CopyrightIdentifier(void) { return "@(#)rdrgb.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "srcsink.h"
+#include "usetrue.h"
+#include "rdimage.h"
+#include "rdrgb.h"
+
+ReadableInterleaved24BitRGBImage::ReadableInterleaved24BitRGBImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: ReadableInterleaved24BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage()
+{}
+
+ReadableInterleaved24BitRGBImage::~ReadableInterleaved24BitRGBImage()
+{}
+
+bool
+ReadableInterleaved24BitRGBImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	return UseableTrueColorImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+ReadableInterleaved24BitRGBImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	return UseableTrueColorImage::setColorCellsAvailable(n,table);
+}
+
+bool
+ReadableInterleaved24BitRGBImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	return UseableTrueColorImage::getColorCellValues(n,red,green,blue);
+}
+
+ReadableNonInterleaved24BitRGBImage::ReadableNonInterleaved24BitRGBImage(
+	SupplySource *s,Uint16 vColumns,Uint16 vRows,Uint16 vNumberOfFrames,
+	Uint16 vBitsAllocated,Uint16 vBitsStored,Uint16 vHighBit)
+		: ReadableNonInterleaved24BitMultiplePlaneImage(
+			s,vColumns,vRows,vNumberOfFrames,
+			vBitsAllocated,vBitsStored,vHighBit),
+		  UseableTrueColorImage()
+{}
+
+ReadableNonInterleaved24BitRGBImage::~ReadableNonInterleaved24BitRGBImage()
+{}
+
+bool
+ReadableNonInterleaved24BitRGBImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	return UseableTrueColorImage::getColorCellsWanted(nwanted,nminimum);
+}
+
+bool
+ReadableNonInterleaved24BitRGBImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+	return UseableTrueColorImage::setColorCellsAvailable(n,table);
+}
+
+bool
+ReadableNonInterleaved24BitRGBImage::getColorCellValues(unsigned n,
+		unsigned short *&red,
+		unsigned short *&green,
+		unsigned short *&blue)
+{
+	return UseableTrueColorImage::getColorCellValues(n,red,green,blue);
+}
+
diff --git a/libsrc/src/dcdisp/usegray.cc b/libsrc/src/dcdisp/usegray.cc
new file mode 100644
index 0000000..62eb86c
--- /dev/null
+++ b/libsrc/src/dcdisp/usegray.cc
@@ -0,0 +1,340 @@
+static const char *CopyrightIdentifier(void) { return "@(#)usegray.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>	// only for debugging
+#include <iomanip>	// only for debugging
+#else
+#include <iostream.h>	// only for debugging
+#include <iomanip.h>	// only for debugging
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;	// only for debugging
+#endif
+
+#include "basetype.h"
+#include "usegray.h"
+
+UseableWindowedGrayImage::UseableWindowedGrayImage(
+	bool invertedgrayscale,Uint16 bits,bool issigned)
+{
+	Assert(bits);
+	inverted=invertedgrayscale;
+	mingray=0;
+	Uint32 mx=(Uint32(1)<<bits)-1;
+	Assert(mx <= Uint16_MAX);
+	maxgray=Uint16(mx);
+	Assert(maxgray >= mingray);
+	ngrays=maxgray-mingray+1;
+
+	(void)setSign(bits,issigned);
+
+//cerr << "UseableWindowedGrayImage::UseableWindowedGrayImage" << "\n"
+//     << "\t invertedgrayscale=" << dec << invertedgrayscale << "\n"
+//     << "\t bits=" << dec << bits << "\n"
+//     << "\t issigned=" << dec << issigned << "\n"
+//     << "\t mingray=" << dec << mingray << "\n"
+//     << "\t mx=" << dec << mx << "\n"
+//     << "\t maxgray=" << dec << maxgray << "\n"
+//     << "\t ngrays=" << dec << ngrays << "\n"
+//     << "\t signxor(hex)=" << hex << signxor << dec << "\n"
+//     << endl;
+
+	graytocell=new char[ngrays];
+	Assert(graytocell);
+	ncells=0;
+	indextocell=0;
+	red=0;
+	green=0;
+	blue=0;
+	needdefaultwindowsetting=true;
+}
+
+UseableWindowedGrayImage::~UseableWindowedGrayImage()
+{
+	if (graytocell) delete[] graytocell;
+	if (indextocell) delete[] indextocell;
+	if (red) delete[] red;
+	if (green) delete[] green;
+	if (blue) delete[] blue;
+}
+
+	// gray is the real gray value in the image pixel data
+	// index is the gray value windowed to a range 0..ncells
+	// cell is the actual number of the cell used in the display array
+
+	// strategy is ...
+	//	allocate lut of gray to cell
+	//	request <= 244 cells
+	//	load those cells with a linear gray scale
+	//	fill graytocell lut with cell numbers
+	//	operator[] returns cell number given gray value
+
+	// indextocell is kept around in case windowing is changed and
+	// need to recalculate graytocell
+
+bool
+UseableWindowedGrayImage::setSign(Uint16 bits,bool issigned)
+{
+	signxor=issigned
+		? 1<<(bits-1)
+		: 0;
+
+	return true;
+}
+
+bool UseableWindowedGrayImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	nwanted=256;
+	nminimum=8;
+//cerr << "UseableWindowedGrayImage::getColorCellsWanted nwanted=" << dec << nwanted << endl;
+//cerr << "UseableWindowedGrayImage::getColorCellsWanted nminimum=" << dec << nminimum << endl;
+	return true;
+}
+
+bool
+UseableWindowedGrayImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+//cerr << "UseableWindowedGrayImage::setColorCellsAvailable n=" << dec << n << endl;
+	Assert(n);
+	ncells=n;
+	indextocell=new char[ncells];
+	Assert(indextocell);
+
+	unsigned i;
+	for (i=0; i<ncells; ++i) {
+		Assert(i<n);
+		Assert(table[i] < 256);
+		indextocell[i]=(char)table[i];
+	}
+	return true;
+}
+
+bool
+UseableWindowedGrayImage::getColorCellValues(unsigned n,
+		unsigned short *&ared,
+		unsigned short *&agreen,
+		unsigned short *&ablue)
+{
+//cerr << "UseableWindowedGrayImage::getColorCellValues n=" << dec << n << endl;
+	Assert(n==ncells);
+	ared=red=new unsigned short [ncells];
+	Assert(red);
+	agreen=green=new unsigned short [ncells];
+	Assert(green);
+	ablue=blue=new unsigned short [ncells];
+	Assert(blue);
+
+	unsigned i;
+	for (i=0; i<ncells; ++i) {
+		unsigned short k =(unsigned short)(Uint32(0xffff)*i/(ncells-1));
+//cerr << "i=" << dec << i
+//     << " k=" << hex << k
+//     << dec << endl;
+		red[i]=k;
+		green[i]=k;
+		blue[i]=k;
+	}
+	return needdefaultwindowsetting
+		? setWindowRange(mingray,maxgray) : true;
+}
+
+bool
+UseableWindowedGrayImage::setWindowRange(Uint16 b,Uint16 t)
+{
+	bottom=b;
+	top=t;
+
+//cerr << "UseableWindowedGrayImage::setWindowRange"
+//     << " bottom=" << dec << bottom
+//     << " top=" << dec << top
+//     << endl;
+
+	Assert(bottom<=top);
+	Assert(bottom>=mingray);
+	Assert(top<=maxgray);
+	Assert(indextocell);
+	Assert(graytocell);
+
+	needdefaultwindowsetting=false;
+
+	unsigned long i;
+	for (i=0; i<bottom; ++i) {
+		graytocell[(inverted ? (ngrays-i-1) : i)^signxor]=indextocell[0];
+	}
+	for (i=bottom; i<=top; ++i) {
+		long index=((i-bottom)*ncells)/(top-bottom+1);
+//cerr << "UseableWindowedGrayImage::setWindowRange"
+//     << " mapping gray=" << dec << i
+//     << " to index=" << dec << index
+//     << endl;
+		Assert(index>=0);
+		Assert(index<ncells);
+		graytocell[(inverted ? (ngrays-i-1) : i)^signxor]=indextocell[index];
+	}
+	for (i=top+1; i<ngrays; ++i) {
+		graytocell[(inverted ? (ngrays-i-1) : i)^signxor]=indextocell[ncells-1];
+	}
+	return true;
+}
+
+bool
+UseableWindowedGrayImage::setWindowLevelWidth(Uint16 level,Uint16 width)
+{
+//cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+//     << " level=" << dec << level
+//     << " width=" << dec << width
+//     << endl;
+	long lbottom=(long)level-width/2;
+//cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+//     << " lbottom=" << dec << lbottom
+//     << endl;
+	if (lbottom < mingray) lbottom=mingray;
+	if (lbottom > maxgray) lbottom=maxgray;	 // just in case
+//cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+//     << " lbottom clamped to=" << dec << lbottom
+//     << endl;
+	long ltop=(long)level+width/2;
+//cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+//     << " ltop=" << dec << ltop
+//     << endl;
+	if (ltop > maxgray) ltop=maxgray;
+	if (ltop < mingray) ltop=mingray;	// just in case
+//cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+//     << " ltop clamped to=" << dec << ltop
+//     << endl;
+	Assert(lbottom<=Uint16_MAX);
+	Assert(ltop<=Uint16_MAX);
+	return setWindowRange(Uint16(lbottom),Uint16(ltop));
+}
+
+bool
+UseableWindowedGrayImage::getWindowLevelWidth(Uint16 &level,Uint16 &width)
+{
+	long llevel=(top+bottom)/2;
+	long lwidth=top-bottom;
+	Assert(llevel<=Uint16_MAX);
+	Assert(lwidth<=Uint16_MAX);
+	level=Uint16(llevel);
+	width=Uint16(lwidth);
+	return true;
+}
+
+
+bool
+UseableWindowedGrayImage::setVOILUT(Uint16 first,Uint16 number,Uint16 depth,const Uint16 *table)
+{
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " first=" << dec << first
+//     << " number=" << dec << number
+//     << " depth=" << dec << depth
+//     << endl;
+
+	bottom=first;
+	Assert(number >= 1);
+	top=first+(number-1);
+
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " bottom=" << dec << bottom
+//     << " top=" << dec << top
+//     << endl;
+
+	if (bottom < mingray) bottom=mingray;
+	if (top > maxgray) top=maxgray;
+
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " clamped bottom=" << dec << bottom
+//     << " clamped top=" << dec << top
+//     << endl;
+
+	Assert(bottom<=top);
+	Assert(bottom>=mingray);
+	Assert(top<=maxgray);
+	Assert(indextocell);
+	Assert(graytocell);
+
+	// theoretically, LUT output range should be related to
+	// the depth (in the third LUT descriptor), however it is
+	// often sent as much less ... hence the check for the
+	// actual range here ...
+#ifdef USELUTDEPTHFORRANGE
+	unsigned long lutoutputrange=1lu<<depth;
+	Uint16 lutmin=0;
+#else
+	Uint16 lutmin=Uint16((1lu<<depth)-1);
+	Uint16 lutmax=0;
+
+	{
+		int i;
+		for (i=0; i<number; ++i) {
+			if (table[i] < lutmin) lutmin=table[i];
+			if (table[i] > lutmax) lutmax=table[i];
+		}
+	}
+	unsigned long lutoutputrange=lutmax-lutmin+1;
+
+cerr << "UseableWindowedGrayImage::setVOILUT"
+     << " lutmax=" << dec << lutmax
+     << endl;
+#endif
+
+cerr << "UseableWindowedGrayImage::setVOILUT"
+     << " lutoutputrange=" << dec << lutoutputrange
+     << " lutmin=" << dec << lutmin
+     << endl;
+
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " ncells=" << dec << ncells
+//     << endl;
+
+	unsigned long i;
+
+	unsigned long bottomindex=((table[0]-lutmin)*ncells)/lutoutputrange;
+	Assert(bottomindex>=0);
+	Assert(bottomindex<ncells);
+	char bottomcell=indextocell[inverted ? (ncells-bottomindex-1) : bottomindex];
+	for (i=0; i<=bottom; ++i) {
+		graytocell[i^signxor]=bottomcell;
+	}
+
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " bottomindex=" << dec << bottomindex
+//     << " bottomcell=" << dec << (unsigned)bottomcell
+//     << endl;
+
+	for (i=bottom+1; i<top; ++i) {
+		unsigned long lutoutput=table[i-bottom];
+		unsigned long index=((lutoutput-lutmin)*ncells)/lutoutputrange;
+		Assert(index>=0);
+		Assert(index<ncells);
+		graytocell[i^signxor]=indextocell[inverted ? (ncells-index-1) : index];
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " i=" << dec << i
+//     << " i^signxor=" << dec << (i^signxor)
+//     << " lutoutput=" << dec << lutoutput
+//     << " index=" << dec << index
+//     << " inverted ? (ncells-index-1) : index=" << dec << (inverted ? (ncells-index-1) : index)
+//     << " cell=" << dec << (unsigned)(unsigned char)indextocell[inverted ? (ncells-index-1) : index]
+//     << endl;
+
+	}
+
+	unsigned long topindex=((table[number-1]-lutmin)*ncells)/lutoutputrange;
+	Assert(topindex>=0);
+	Assert(topindex<ncells);
+	char topcell=indextocell[inverted ? (ncells-topindex-1) : topindex];
+	for (i=top; i<ngrays; ++i) {
+		graytocell[i^signxor]=indextocell[topcell];
+	}
+
+//cerr << "UseableWindowedGrayImage::setVOILUT"
+//     << " topindex=" << dec << topindex
+//     << " topcell=" << dec << (unsigned)topcell
+//     << endl;
+
+	needdefaultwindowsetting=false;
+
+	return true;
+}
+
diff --git a/libsrc/src/dcdisp/usegray.cc.signedwork b/libsrc/src/dcdisp/usegray.cc.signedwork
new file mode 100755
index 0000000..15e3ac0
--- /dev/null
+++ b/libsrc/src/dcdisp/usegray.cc.signedwork
@@ -0,0 +1,216 @@
+#include <iostream.h>	// only for debugging
+#include <iomanip.h>	// only for debugging
+
+#include "basetype.h"
+#include "usegray.h"
+
+UseableWindowedGrayImage::UseableWindowedGrayImage(
+	bool invertedgrayscale,Uint16 bits,bool issigned)
+{
+	Assert(bits);
+	inverted=invertedgrayscale;
+	mingray=0;
+	Uint32 mx=(Uint32(1)<<bits)-1;
+	Assert(mx <= Uint16_MAX);
+	maxgray=Uint16(mx);
+	Assert(maxgray >= mingray);
+	ngrays=maxgray-mingray+1;
+
+	(void)setSign(bits,issigned);
+
+cerr << "UseableWindowedGrayImage::UseableWindowedGrayImage" << "\n"
+     << "\t invertedgrayscale=" << dec << invertedgrayscale << "\n"
+     << "\t bits=" << dec << bits << "\n"
+     << "\t issigned=" << dec << issigned << "\n"
+     << "\t mingray=" << dec << mingray << "\n"
+     << "\t mx=" << dec << mx << "\n"
+     << "\t maxgray=" << dec << maxgray << "\n"
+     << "\t ngrays=" << dec << ngrays << "\n"
+     << "\t signxor(hex)=" << hex << signxor << dec << "\n"
+     << endl;
+
+	graytocell=new Uint16[ngrays];
+	Assert(graytocell);
+	ncells=0;
+	indextocell=0;
+	red=0;
+	green=0;
+	blue=0;
+	needdefaultwindowsetting=true;
+}
+
+UseableWindowedGrayImage::~UseableWindowedGrayImage()
+{
+	if (graytocell) delete[] graytocell;
+	if (indextocell) delete[] indextocell;
+	if (red) delete[] red;
+	if (green) delete[] green;
+	if (blue) delete[] blue;
+}
+
+	// gray is the real gray value in the image pixel data
+	// index is the gray value windowed to a range 0..ncells
+	// cell is the actual number of the cell used in the display array
+
+	// strategy is ...
+	//	allocate lut of gray to cell
+	//	request <= 244 cells
+	//	load those cells with a linear gray scale
+	//	fill graytocell lut with cell numbers
+	//	operator[] returns cell number given gray value
+
+	// indextocell is kept around in case windowing is changed and
+	// need to recalculate graytocell
+
+bool
+UseableWindowedGrayImage::setSign(Uint16 bits,bool issigned)
+{
+	signxor=issigned
+		? 1<<(bits-1)
+		: 0;
+
+	return true;
+}
+
+bool UseableWindowedGrayImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	nwanted=256;
+	nminimum=8;
+//cerr << "UseableWindowedGrayImage::getColorCellsWanted nwanted=" << dec << nwanted << endl;
+//cerr << "UseableWindowedGrayImage::getColorCellsWanted nminimum=" << dec << nminimum << endl;
+	return true;
+}
+
+bool
+UseableWindowedGrayImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+//cerr << "UseableWindowedGrayImage::setColorCellsAvailable n=" << dec << n << endl;
+	Assert(n);
+	ncells=n;
+	indextocell=new Uint16[ncells];
+	Assert(indextocell);
+
+	unsigned i;
+	for (i=0; i<ncells; ++i) {
+		Assert(i<n);
+		Assert(indextocell[i] <= Uint16_MAX);
+//cerr << "UseableWindowedGrayImage::setColorCellsAvailable indextocell[i]=(Uint16)table[i]="
+//     << dec << (Uint16)table[i] << endl;
+		indextocell[i]=(Uint16)table[i];
+	}
+	return true;
+}
+
+bool
+UseableWindowedGrayImage::getColorCellValues(unsigned n,
+		unsigned short *&ared,
+		unsigned short *&agreen,
+		unsigned short *&ablue)
+{
+//cerr << "UseableWindowedGrayImage::getColorCellValues n=" << dec << n << endl;
+	Assert(n==ncells);
+	ared=red=new unsigned short [ncells];
+	Assert(red);
+	agreen=green=new unsigned short [ncells];
+	Assert(green);
+	ablue=blue=new unsigned short [ncells];
+	Assert(blue);
+
+	unsigned i;
+	for (i=0; i<ncells; ++i) {
+		unsigned short k =(unsigned short)(Uint32(0xffff)*i/(ncells-1));
+//cerr << "i=" << dec << i
+//     << " k=" << hex << k
+//     << dec << endl;
+		red[i]=k;
+		green[i]=k;
+		blue[i]=k;
+	}
+	return needdefaultwindowsetting
+		? setWindowRange(mingray,maxgray) : true;
+}
+
+bool
+UseableWindowedGrayImage::setWindowRange(Uint16 b,Uint16 t)
+{
+	bottom=b;
+	top=t;
+
+cerr << "UseableWindowedGrayImage::setWindowRange"
+     << " bottom=" << dec << bottom
+     << " top=" << dec << top
+     << endl;
+
+	Assert(bottom<=top);
+	Assert(bottom>=mingray);
+	Assert(top<=maxgray);
+	Assert(indextocell);
+	Assert(graytocell);
+
+	needdefaultwindowsetting=false;
+
+	unsigned long i;
+	for (i=0; i<bottom; ++i) {
+		graytocell[(inverted ? (ngrays-i-1) : i)^signxor]=indextocell[0];
+	}
+	for (i=bottom; i<=top; ++i) {
+		long index=((i-bottom)*ncells)/(top-bottom+1);
+cerr << "UseableWindowedGrayImage::setWindowRange"
+     << " mapping gray=" << dec << i
+     << " to index=" << dec << index
+     << endl;
+		Assert(index>=0);
+		Assert(index<ncells);
+		graytocell[(inverted ? (ngrays-i-1) : i)^signxor]=indextocell[index];
+	}
+	for (i=top+1; i<ngrays; ++i) {
+		graytocell[(inverted ? (ngrays-i-1) : i)^signxor]=indextocell[ncells-1];
+	}
+	return true;
+}
+
+bool
+UseableWindowedGrayImage::setWindowLevelWidth(Uint16 level,Uint16 width)
+{
+cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+     << " level=" << dec << level
+     << " width=" << dec << width
+     << endl;
+	long lbottom=(long)level-width/2;
+cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+     << " lbottom=" << dec << lbottom
+     << endl;
+	if (lbottom < mingray) lbottom=mingray;
+	if (lbottom > maxgray) lbottom=maxgray;	 // just in case
+cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+     << " lbottom clamped to=" << dec << lbottom
+     << endl;
+	long ltop=(long)level+width/2;
+cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+     << " ltop=" << dec << ltop
+     << endl;
+	if (ltop > maxgray) ltop=maxgray;
+	if (ltop < mingray) ltop=mingray;	// just in case
+cerr << "UseableWindowedGrayImage::setImageLevelWidth"
+     << " ltop clamped to=" << dec << ltop
+     << endl;
+	Assert(lbottom<=Uint16_MAX);
+	Assert(ltop<=Uint16_MAX);
+	return setWindowRange(Uint16(lbottom),Uint16(ltop));
+}
+
+bool
+UseableWindowedGrayImage::getWindowLevelWidth(Uint16 &level,Uint16 &width)
+{
+	long llevel=(top+bottom)/2;
+	long lwidth=top-bottom;
+	Assert(llevel<=Uint16_MAX);
+	Assert(lwidth<=Uint16_MAX);
+	level=Uint16(llevel);
+	width=Uint16(lwidth);
+	return true;
+}
+
+
diff --git a/libsrc/src/dcdisp/useindex.cc b/libsrc/src/dcdisp/useindex.cc
new file mode 100644
index 0000000..f021a86
--- /dev/null
+++ b/libsrc/src/dcdisp/useindex.cc
@@ -0,0 +1,143 @@
+static const char *CopyrightIdentifier(void) { return "@(#)useindex.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "errclass.h"
+#include "lutclass.h"
+#include "usepal.h"
+#include "useindex.h"
+
+UseableIndexedColorImage::UseableIndexedColorImage(
+		DicomLUT *RedLUT,DicomLUT *GreenLUT,DicomLUT *BlueLUT)
+{
+	palette=new UseablePalette(RedLUT,GreenLUT,BlueLUT);
+	Assert(palette);
+	palettetocell=0;
+	npalette=0;
+	palettetoindex=0;
+	nused=0;
+	red=0;
+	green=0;
+	blue=0;
+}
+
+UseableIndexedColorImage::~UseableIndexedColorImage()
+{
+	if (palette) delete palette;
+	if (palettetocell) delete[] palettetocell;
+	if (palettetoindex) delete[] palettetoindex;
+	if (red) delete[] red;
+	if (green) delete[] green;
+	if (blue) delete[] blue;
+}
+
+bool
+UseableIndexedColorImage::getColorCellsWanted(unsigned &nwanted,
+		unsigned &nminimum)
+{
+	Assert(palette);
+	Uint32 nstart=palette->getLength();
+//cerr << "UseableIndexedColorImage::getColorCellsWanted nstart=" << dec << nstart << endl;
+	palettetoindex=new unsigned short [nstart];
+	Assert(palettetoindex);
+	red=new unsigned short [nstart];
+	Assert(red);
+	green=new unsigned short [nstart];
+	Assert(green);
+	blue=new unsigned short [nstart];
+	Assert(blue);
+
+	// Only want cells for unique values in palette ...
+
+	Uint32 i;
+	for (i=0; i<nstart; ++i) {
+		Assert(i<=Uint16_MAX);
+		Uint16 r;
+		Uint16 g;
+		Uint16 b;
+		if (palette->get16BitColorIndex(Uint16(i),r,g,b)) {
+//cerr << "UseableIndexedColorImage::getColorCellsWanted testing color"
+//     << " i=" << dec << i
+//     << " r=" << hex << r
+//     << " g=" << hex << g
+//     << " b=" << hex << b
+//     << dec << endl;
+			Uint32 j=0;
+			while (1) {
+				Assert(j<=Uint16_MAX);
+				if (j == nused) {
+					red[j]=r;
+					green[j]=g;
+					blue[j]=b;
+					palettetoindex[i]=Uint16(j);
+//cerr << "UseableIndexedColorImage::getColorCellsWanted new"
+//     << " i=" << dec << i
+//     << " j=" << dec << j
+//     << endl;
+					++nused;
+					break;
+				}
+				Assert(j<nused);
+				if (red[j] == r && green[j] == g && blue[j] == b) {
+					palettetoindex[i]=Uint16(j);
+//cerr << "UseableIndexedColorImage::getColorCellsWanted existing"
+//     << " i=" << dec << i
+//     << " j=" << dec << j
+//     << endl;
+					break;
+				}
+				++j;
+			}
+		}
+		else
+			Assert(0);
+	}
+
+//cerr << "UseableIndexedColorImage::getColorCellsWanted nused=" << dec << nused << endl;
+	Assert(nused <= UINT_MAX);
+	nwanted=nminimum=unsigned(nused);
+	return true;
+}
+
+bool
+UseableIndexedColorImage::setColorCellsAvailable(unsigned n,
+		unsigned long *table)
+{
+//cerr << "UseableIndexedColorImage::setColorCellsAvailable n=" << dec << n << endl;
+	// not having enough color cells is not supported yet :(
+
+	Assert(n >= nused);
+
+	npalette=palette->getLength();
+	palettetocell=new Uint16[npalette];
+	Assert(palettetocell);
+
+	unsigned i;
+	for (i=0; i<npalette; ++i) {
+		Uint16 index=palettetoindex[i];
+//cerr << "UseableIndexedColorImage::setColorCellsAvailable"
+//     << " i=" << dec << i
+//     << " index=" << dec << index
+//     << " table[index]=" << dec << table[index]
+//     << endl;
+		Assert(table[index] <= Uint16_MAX);
+		palettetocell[i]=(Uint16)table[index];
+	}
+	return true;
+}
+
+bool
+UseableIndexedColorImage::getColorCellValues(unsigned n,
+	unsigned short *&ared,
+	unsigned short *&agreen,
+	unsigned short *&ablue)
+{
+//cerr << "UseableIndexedColorImage::getColorCellValues n=" << dec << n << endl;
+	Assert(n <= nused);
+	Assert(red);
+	ared=red;
+	Assert(green);
+	agreen=green;
+	Assert(blue);
+	ablue=blue;
+
+	return true;
+}
diff --git a/libsrc/src/dcdisp/usepal.cc b/libsrc/src/dcdisp/usepal.cc
new file mode 100644
index 0000000..14d05cb
--- /dev/null
+++ b/libsrc/src/dcdisp/usepal.cc
@@ -0,0 +1,34 @@
+static const char *CopyrightIdentifier(void) { return "@(#)usepal.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "errclass.h"
+#include "lutclass.h"
+#include "usepal.h"
+
+UseablePalette::UseablePalette(DicomLUT *r,DicomLUT *g,DicomLUT *b)
+{
+//cerr << "UseablePalette::UseablePalette(r,g,b) this=" << this << endl;
+	RedLUT=r;
+	GreenLUT=g;
+	BlueLUT=b;
+	Assert(RedLUT);
+	Assert(GreenLUT);
+	Assert(BlueLUT);
+}
+
+UseablePalette::~UseablePalette()
+{
+	if (RedLUT) delete RedLUT;
+	if (GreenLUT) delete GreenLUT;
+	if (BlueLUT) delete BlueLUT;
+}
+
+Uint32
+UseablePalette::getLength(void)
+{
+//cerr << "UseablePalette::getLength" << endl;
+	Assert(RedLUT->getLength() == GreenLUT->getLength()
+	    && RedLUT->getLength() == BlueLUT->getLength());
+//cerr << "UseablePalette::getLength returns=" << RedLUT->getLength() << endl;
+	return RedLUT->getLength();
+}
+
diff --git a/libsrc/src/dcdisp/usetrue.cc b/libsrc/src/dcdisp/usetrue.cc
new file mode 100644
index 0000000..d968d11
--- /dev/null
+++ b/libsrc/src/dcdisp/usetrue.cc
@@ -0,0 +1,100 @@
+static const char *CopyrightIdentifier(void) { return "@(#)usetrue.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "usetrue.h"
+
+UseableTrueColorImage::UseableTrueColorImage(void)
+{
+	nused=0;
+	rgbtocell=0;
+	red=0;
+	green=0;
+	blue=0;
+}
+
+UseableTrueColorImage::~UseableTrueColorImage()
+{
+	if (rgbtocell) delete[] rgbtocell;
+	if (red) delete[] red;
+	if (green) delete[] green;
+	if (blue) delete[] blue;
+}
+
+bool
+UseableTrueColorImage::getColorCellsWanted(unsigned &nwanted,unsigned &nminimum)
+{
+	// 332 palette is 256 long
+
+	nused=nwanted=nminimum=256;
+	return true;
+}
+
+bool
+UseableTrueColorImage::setColorCellsAvailable(unsigned n,unsigned long *table)
+{
+	// not having enough color cells is not supported yet :(
+
+	Assert(n >= nused);
+
+	rgbtocell=new unsigned char[nused];
+	Assert(rgbtocell);
+
+	unsigned i;
+	for (i=0; i<n; ++i) {
+		rgbtocell[i]=(unsigned char)table[i];
+	}
+	return true;
+}
+
+bool
+UseableTrueColorImage::getColorCellValues(unsigned n,unsigned short *&ared,unsigned short *&agreen,unsigned short *&ablue)
+{
+	Assert(n == 256);
+	Assert(nused == 256);
+	ared=red=new unsigned short [nused];
+	Assert(red);
+	agreen=green=new unsigned short [nused];
+	Assert(green);
+	ablue=blue=new unsigned short [nused];
+	Assert(blue);
+
+	// dirty trick here ...because a 3/3/2 palette needs to be
+	// 256 long (which means we have to tolerate flashing)
+	// the problem of where black and white are arises. Now the
+	// X convention is colorcell 0 is white and 1 is black which
+	// seems ass backwards until you consider the possibility of
+	// wrapping a linear palette around by 1 ... almost as fast
+	// to index, and black and white are always accessible ...
+	
+	unsigned short rval;
+	unsigned short gval;
+	unsigned short bval;
+	unsigned short *rptr=red+1;	// offset by 1 so 1=black
+	unsigned short *gptr=green+1;
+	unsigned short *bptr=blue+1;
+	unsigned short rcount;
+	unsigned short gcount;
+	unsigned short bcount;
+	for (rcount=0,rval=0; rcount<8; ++rcount,rval+=0x2492) {
+		for (gcount=0,gval=0; gcount<8; ++gcount,gval+=0x2492) {
+			for (bcount=0,bval=0; bcount<4; ++bcount,bval+=0x5555) {
+//cerr << "UseableTrueColorImage::getColorCellValues"
+//     << " rval=" << hex << rval
+//     << " gval=" << hex << gval
+//     << " bval=" << hex << bval
+//     << dec << endl;
+				if (rptr-red == 255) {
+					// wrap around last entry so 0=white
+					*red=rval;
+					*green=gval;
+					*blue=bval;
+				}
+				else {
+					*rptr++=rval;
+					*gptr++=gval;
+					*bptr++=bval;
+				}
+			}
+		}
+	}
+	return true;
+}
diff --git a/libsrc/src/dconvert/Imakefile b/libsrc/src/dconvert/Imakefile
new file mode 100755
index 0000000..1260029
--- /dev/null
+++ b/libsrc/src/dconvert/Imakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = support pace xxxx imtn gen gaw shim somp himr pq signa ge9800
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/libsrc/src/dconvert/gaw/Imakefile b/libsrc/src/dconvert/gaw/Imakefile
new file mode 100755
index 0000000..01f4fe5
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/Imakefile
@@ -0,0 +1,31 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = gawdc.cc gawconv.cc gawmpln.cc \
+		 gawmmsc.cc gawmdt.cc \
+		 gawdmp.cc gawdmpf.cc \
+		 gawhdrc.cc gaw.cc
+
+OBJS = 		 gawdc.o  gawconv.o  gawmpln.o  \
+		 gawmmsc.o  gawmdt.o  \
+		 gawdmp.o  gawdmpf.o  \
+		 gawhdrc.o  gaw.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdgaw.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(gaw,dconvert)
+ProjectInstallOnMakeUpdatedLibraryHeader(gawinfo,dconvert)
+
+ProjectConvertTemplate(gawhdrp.h,gaw,convert,prefix=GAW_ role=headerpart offsetwarning=off)
+ProjectConvertTemplate(gawhdrw.h,gaw,convert,prefix=GAW_ role=wholeheader headerclassparameters=",GAW_FileStructureInformation &fileinfo")
+ProjectConvertTemplate(gawhdrc.h,gaw,convert,prefix=GAW_ role=constructheader headerclassparameters=",GAW_FileStructureInformation &fileinfo")
+ProjectConvertTemplate(gawconv.h,gaw,convert,prefix=GAW_ role=dicom)
+ProjectConvertTemplate(gawdmpf.h,gaw,convert,prefix=GAW_ role=dump)
+
+gawdmpf.o: gawdmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) gawdmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/gaw/README b/libsrc/src/dconvert/gaw/README
new file mode 100755
index 0000000..2471054
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"gaw.h"
+		class GAW_Conversion {
+			GAW_Conversion(istream &i,ostream &e);
+			virtual ~GAW_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"gaw.cc"
+
+		GAW_Conversion::GAW_Conversion(istream &i,ostream &e);
+		GAW_Conversion::~GAW_Conversion();
+
+	"gawcl.h"
+
+		class GAW_Header_BothClass  : public GAW_HeaderClass
+		{
+		public:
+			GAW_Header_BothClass(istream *ist) : GAW_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"gawconv.cc"
+
+		#include "gawconv.h"
+
+	"gawdc.c"
+
+		bool GAW_Conversion::convertHeader(AttributeList *list);
+		bool GAW_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool GAW_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"gawdc.h"
+
+	"gawdmp.cc"
+
+		bool GAW_Conversion::dump(ostream &o);
+
+	"gawdmp.h"
+
+	"gawhdrc.cc"
+
+		#include "gawhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"gaw.tpl"
+
+		The template "describing" the format for header gaweration
+
+	"gawmdt.cc"
+
+		void GAW_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"gawmmsc.cc"
+
+		void GAW_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"gawmpln.cc"
+
+		void GAW_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"gawptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"gawsrc.h"
+
+		class GAW_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			GAW_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~GAW_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically gawerated from gaw.tpl:
+
+	"gawhdrp.h"
+
+		gawerated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class GAW_HeaderClass_HDR1 {
+		public:
+			GAW_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"gawhdrw.h"
+
+		gawerated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class GAW_HeaderClass
+		{
+		public:
+			GAW_HeaderClass(istream *ist);
+
+			GAW_HeaderClass_HDR1 *GAW_HeaderInstance_HDR1;
+			GAW_HeaderClass_HDR2 *GAW_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"gawhdrc.h"
+
+		gawerated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		GAW_HeaderClass::GAW_HeaderClass(istream *ist);
+
+	"gawconv.h"
+
+		gawerated with role=dicom
+
+		contains the code to gawerate DICOM attributes
+
+		void GAW_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"gawdmpf.h"
+		gawerated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void GAW_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "gawhdrm.h".
+
+	if you have special purpose code, then "gawhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "gawhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/gaw/gaw.cc b/libsrc/src/dconvert/gaw/gaw.cc
new file mode 100644
index 0000000..a6ed139
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gaw.cc
@@ -0,0 +1,55 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gaw.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "gaw.h"
+#include "gawcl.h"
+#include "srcsink.h"
+#include "gawsrc.h"
+
+void
+GAW_Conversion::init(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	gawhdr=0;
+	pixeldatasrc=0;
+}
+
+GAW_Conversion::GAW_Conversion(istream &i,ostream &e)
+{
+	init(i,e);
+	// use GAW_FileStructureInformation as constructed already
+}
+
+GAW_Conversion::GAW_Conversion(istream &i,ostream &e,
+		bool explicitoff,
+		bool lengthpresent,
+		Uint32 fileptr,
+		Uint32 suiteptr,
+		Uint32 examptr,
+		Uint32 seriesptr,
+		Uint32 imageptr)
+{
+	init(i,e);
+	fileinfo=GAW_FileStructureInformation(
+		explicitoff,	// explicit
+		lengthpresent,	// length field
+		fileptr,	// file header
+		suiteptr,	// suite header
+		examptr,	// exam header
+		seriesptr,	// series header
+		imageptr);	// image header
+}
+
+GAW_Conversion::~GAW_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (gawhdr) delete gawhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/gaw/gaw.h b/libsrc/src/dconvert/gaw/gaw.h
new file mode 100644
index 0000000..b1f4efe
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gaw.h
@@ -0,0 +1,61 @@
+/* gaw.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_gaw__
+#define __Header_gaw__
+
+#include "gawinfo.h"
+
+// NB. a GAW_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~GAW_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class GAW_Header_BothClass;
+class GAW_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class GAW_Conversion {
+	GAW_Header_BothClass *gawhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	GAW_PixelDataSource *pixeldatasrc;
+
+	GAW_FileStructureInformation fileinfo;
+
+	void init(istream &i,ostream &e);
+public:
+	GAW_Conversion(istream &i,ostream &e);
+
+	GAW_Conversion(istream &i,ostream &e,
+		bool explicitoff,
+		bool lengthpresent,
+		Uint32 fileptr,
+		Uint32 suiteptr,
+		Uint32 examptr,
+		Uint32 seriesptr,
+		Uint32 imageptr);
+
+	virtual ~GAW_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0)
+		{
+			(void)out; (void)imagenumber;
+			return true;
+		}
+
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_gaw__ */
+
diff --git a/libsrc/src/dconvert/gaw/gaw.tpl b/libsrc/src/dconvert/gaw/gaw.tpl
new file mode 100755
index 0000000..e2241f3
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gaw.tpl
@@ -0,0 +1,634 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="FILEHDR"	offset="0"	intype="Int32_B"	inlength="1"	name="IH_img_magic"		dicomtype="?"	dicomtag="?"		#  magic number
+block="FILEHDR"	offset="4"	intype="Int32_B"	inlength="1"	keyword="IH_img_hdr_length"	dicomtype="?"	dicomtag="?"		#  a byte displacement to the <pixel data area>
+block="FILEHDR"	offset="8"	intype="Int32_B"	inlength="1"	keyword="IH_img_width"		dicomtype="?"	dicomtag="?"		#  width (pixels) of image
+block="FILEHDR"	offset="12"	intype="Int32_B"	inlength="1"	keyword="IH_img_height"		dicomtype="?"	dicomtag="?"		#  height (pixels) of image
+block="FILEHDR"	offset="16"	intype="Int32_B"	inlength="1"	keyword="IH_img_depth"		dicomtype="?"	dicomtag="?"		#  depth (1, 8, 16, or 24 bits) of
+block="FILEHDR"	offset="20"	intype="Int32_B"	inlength="1"	keyword="IH_img_compress"	dicomtype="?"	dicomtag="?"		#  type of compression; see IC_* below
+block="FILEHDR"	offset="24"	intype="Int32_B"	inlength="1"	name="IH_img_dwindow"		dicomtype="DS"	dicomtag="WindowWidth"	#  default window setting
+block="FILEHDR"	offset="28"	intype="Int32_B"	inlength="1"	name="IH_img_dlevel"		dicomtype="DS"	dicomtag="WindowCenter"	#  default level setting
+block="FILEHDR"	offset="32"	intype="Int32_B"	inlength="1"	name="IH_img_bgshade"		dicomtype="?"	dicomtag="?"		#  background shade to use for non-image
+block="FILEHDR"	offset="36"	intype="Int32_B"	inlength="1"	name="IH_img_ovrflow"		dicomtype="?"	dicomtag="?"		#  overflow value
+block="FILEHDR"	offset="40"	intype="Int32_B"	inlength="1"	name="IH_img_undflow"		dicomtype="?"	dicomtag="?"		#  underflow value
+block="FILEHDR"	offset="44"	intype="Int32_B"	inlength="1"	name="IH_img_top_offset"	dicomtype="?"	dicomtag="?"		#  number of blank lines at image top
+block="FILEHDR"	offset="48"	intype="Int32_B"	inlength="1"	name="IH_img_bot_offset"	dicomtype="?"	dicomtag="?"		#  number of blank lines at image bottom
+block="FILEHDR"	offset="52"	intype="Int16_B"	inlength="1"	name="IH_img_version"		dicomtype="LO"	dicomtag="SoftwareVersions"	#  version of the header structure
+block="FILEHDR"	offset="54"	intype="Uint16_B"	inlength="1"	name="IH_img_checksum"		dicomtype="?"	dicomtag="?"		#  16 bit end_around_carry sum of pixels
+block="FILEHDR"	offset="56"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_id"		dicomtype="?"	dicomtag="?"		#  a byte disp to unique image identifier
+block="FILEHDR"	offset="60"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_id"		dicomtype="?"	dicomtag="?"		#  byte length of unique image identifier
+block="FILEHDR"	offset="64"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_unpack"	dicomtype="?"	dicomtag="?"		#  a byte disp to <unpack control>
+block="FILEHDR"	offset="68"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_unpack"	dicomtype="?"	dicomtag="?"		#  byte length of <unpack control>
+block="FILEHDR"	offset="72"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_compress"	dicomtype="?"	dicomtag="?"		#  a byte disp to <compression control>
+block="FILEHDR"	offset="76"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_compress"	dicomtype="?"	dicomtag="?"		#  byte length of <compression control>
+block="FILEHDR"	offset="80"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_histo"	dicomtype="?"	dicomtag="?"		#  a byte disp to <histogram control>
+block="FILEHDR"	offset="84"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_histo"	dicomtype="?"	dicomtag="?"		#  byte length of <histogram control>
+block="FILEHDR"	offset="88"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_text"		dicomtype="?"	dicomtag="?"		#  a byte disp to <text plane data>
+block="FILEHDR"	offset="92"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_text"		dicomtype="?"	dicomtag="?"		#  byte length of <text plane data>
+block="FILEHDR"	offset="96"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_graphics"	dicomtype="?"	dicomtag="?"		#  a byte disp to <graphics plane data>
+block="FILEHDR"	offset="100"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_graphics"	dicomtype="?"	dicomtag="?"		#  byte length of <graphics plane data>
+block="FILEHDR"	offset="104"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_dbHdr"	dicomtype="?"	dicomtag="?"		#  a byte disp to <data base header data>
+block="FILEHDR"	offset="108"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_dbHdr"	dicomtype="?"	dicomtag="?"		#  byte length of <data base header data>
+block="FILEHDR"	offset="112"	intype="Int32_B"	inlength="1"	keyword="IH_img_levelOffset"	dicomtype="DS"	dicomtag="RescaleIntercept"		#  value to add to stored Pixel Data values
+block="FILEHDR"	offset="116"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_user"		dicomtype="?"	dicomtag="?"		#  byte displacement to user defined data
+block="FILEHDR"	offset="120"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_user"		dicomtype="?"	dicomtag="?"		#  byte length of user defined data
+block="FILEHDR"	offset="124"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_suite"	dicomtype="?"	dicomtag="?"		#  byte displacement to <suite> header data
+block="FILEHDR"	offset="128"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_suite"	dicomtype="?"	dicomtag="?"		#  byte length of <suite> header data
+block="FILEHDR"	offset="132"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_exam"		dicomtype="?"	dicomtag="?"		#  byte displacement to <exam> header data
+block="FILEHDR"	offset="136"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_exam"		dicomtype="?"	dicomtag="?"		#  byte length of <exam> header data
+block="FILEHDR"	offset="140"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_series"	dicomtype="?"	dicomtag="?"		#  byte displacement to <series> header data
+block="FILEHDR"	offset="144"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_series"	dicomtype="?"	dicomtag="?"		#  byte length of <series> header data
+block="FILEHDR"	offset="148"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_image"	dicomtype="?"	dicomtag="?"		#  byte displacement to <image> header data
+block="FILEHDR"	offset="152"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_image"	dicomtype="?"	dicomtag="?"		#  byte length of <image> header data
+block="UIDHDR" condition="hasuid"	offset="0"	intype="Int32_B"	inlength="1"	name="ID_id_version"		dicomtype="?"	dicomtag="?"		#  version of the uid area
+block="UIDHDR" condition="hasuid"	offset="4"	intype="String"		inlength="80"	name="ID_id_text"		dicomtype="?"	dicomtag="?"		#  unique text area or orphan description
+block="HISTOHDR" condition="hashisto"	offset="0"	intype="Int32_B"	inlength="1"	name="HS_hs_version"		dicomtype="?"	dicomtag="?"		#  version of the histogram structure
+block="HISTOHDR"	condition="hashisto"	offset="4"	intype="IEEE_Float32_B"	inlength="1"	name="HS_hs_sd"			dicomtype="?"	dicomtag="?"		#  standard deviation of pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="8"	intype="Int16_B"	inlength="1"	name="HS_hs_mean"		dicomtype="?"	dicomtag="?"		#  rounded mean pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="10"	intype="Int16_B"	inlength="1"	name="HS_hs_min"		dicomtype="XS"	dicomtag="SmallestImagePixelValue"	#  minimum pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="12"	intype="Int16_B"	inlength="1"	name="HS_hs_max"		dicomtype="XS"	dicomtag="LargestImagePixelValue"	#  maximum pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="14"	intype="Int16_B"	inlength="1"	name="HS_hs_first"		dicomtype="?"	dicomtag="?"		#  first histogram entry used for <hs_sd>
+block="HISTOHDR"	condition="hashisto"	offset="16"	intype="Int16_B"	inlength="1"	name="HS_hs_region"		dicomtype="?"	dicomtag="?"		#  region entries used for <hs_sd>
+block="HISTOHDR"	condition="hashisto"	offset="18"	intype="Int16_B"	inlength="1"	name="HS_hs_length"		dicomtype="?"	dicomtag="?"		#  number of bins in the histogram area
+block="SUITEHDR"	offset="0"	intype="String"	inlength="4"	name="SU_su_id"		dicomtype="?"	dicomtag="?"		#  Suite ID
+block="SUITEHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="SU_su_uniq"		dicomtype="?"	dicomtag="?"	#  Make Unique Flag
+block="SUITEHDR"	offset="6"	intype="String"	inlength="1"	name="SU_su_diskid"		dicomtype="?"	dicomtag="?"	#  Disk ID
+block="SUITEHDR"	offset="7"	intype="String"	inlength="13"	name="SU_prodid"		dicomtype="LO"	dicomtag="ManufacturerModelName"	#  Product ID
+block="SUITEHDR"	offset="20"	intype="String"	inlength="2"	name="SU_su_verscre"		dicomtype="?"	dicomtag="?"	#  Original Version of Record
+block="SUITEHDR"	offset="22"	intype="String"	inlength="2"	name="SU_su_verscur"		dicomtype="?"	dicomtag="?"	#  Current Version of Record
+block="SUITEHDR"	offset="24"	intype="Uint32_B"	inlength="1"	name="SU_su_checksum"		dicomtype="?"	dicomtag="?"	#  Suite Record Checksum
+block="SUITEHDR"	offset="28"	intype="String"	inlength="85"	name="SU_su_padding"		dicomtype="?"	dicomtag="?"	#  Spare Space
+block="EXAMHDR"	offset="0"	intype="String"	inlength="4"	name="EX_ex_suid"		dicomtype="SH"	dicomtag="StationName"	#  Suite ID for this Exam
+block="EXAMHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="EX_ex_uniq"		dicomtype="?"	dicomtag="?"		#  Make-Unique Flag
+block="EXAMHDR"	offset="6"	intype="String"	inlength="1"	name="EX_ex_diskid"		dicomtype="?"	dicomtag="?"		#  Disk ID for this Exam
+block="EXAMHDR"	offset="8"	intype="Uint16_B"	inlength="1"	keyword="EX_ex_no"		dicomtype="SH"	dicomtag="StudyID"	#  Exam Number
+block="EXAMHDR"	offset="10"	intype="String"	inlength="33"	name="EX_hospname"		dicomtype="LO"	dicomtag="InstitutionName"	#  Hospital Name
+block="EXAMHDR"	offset="44"	intype="Int16_B"	inlength="1"	name="EX_detect"		dicomtype="?"	dicomtag="?"	enum="1=Xenon,2=Hilight"	#  Detector Type
+block="EXAMHDR"	offset="48"	intype="Int32_B"	inlength="1"	name="EX_numcells"		dicomtype="?"	dicomtag="?"		#  Number of cells in det
+block="EXAMHDR"	offset="52"	intype="IEEE_Float32_B"	inlength="1"	name="EX_zerocell"		dicomtype="?"	dicomtag="?"		#  Cell number at theta
+block="EXAMHDR"	offset="56"	intype="IEEE_Float32_B"	inlength="1"	name="EX_cellspace"		dicomtype="?"	dicomtag="?"		#  Cell spacing
+block="EXAMHDR"	offset="60"	intype="IEEE_Float32_B"	inlength="1"	keyword="EX_srctodet"		dicomtype="?"	dicomtag="?"		#  Distance from source to detector
+block="EXAMHDR"	offset="64"	intype="IEEE_Float32_B"	inlength="1"	keyword="EX_srctoiso"		dicomtype="?"	dicomtag="?"		#  Distance from source to iso
+block="EXAMHDR"	offset="68"	intype="Int16_B"	inlength="1"	name="EX_tubetyp"		dicomtype="?"	dicomtag="?"	enum="0=MX100_TUBE,1=MX125_TUBE,2=TT9800:9800_TUBE,3=TT9100:9100_TUBE,4=HPRI_TUBE,5=HPRII_TUBE,6=ADV650_TUBE,7=ADV681_TUBE,8=ST2000CT_6_TUBE,9=ST2000CT_10_TUBE,12=MX_135CT_TUBE,13=MX_165CT_TUBE,14=MX_165CT_I_TUBE"	#  Tube type
+block="EXAMHDR"	offset="70"	intype="Int16_B"	inlength="1"	name="EX_dastyp"		dicomtype="?"	dicomtag="?"	enum="1=CDAS,2=EDAS"	#  DAS type
+block="EXAMHDR"	offset="72"	intype="Int16_B"	inlength="1"	name="EX_num_dcnk"		dicomtype="?"	dicomtag="?"		#  Number of Decon Kernals
+block="EXAMHDR"	offset="74"	intype="Int16_B"	inlength="1"	name="EX_dcn_len"		dicomtype="?"	dicomtag="?"		#  Number of elements in a Decon Kernal
+block="EXAMHDR"	offset="76"	intype="Int16_B"	inlength="1"	name="EX_dcn_density"	dicomtype="?"	dicomtag="?"			#  Decon Kernal density
+block="EXAMHDR"	offset="78"	intype="Int16_B"	inlength="1"	name="EX_dcn_stepsize"	dicomtype="?"	dicomtag="?"			#  Decon Kernal stepsize
+block="EXAMHDR"	offset="80"	intype="Int16_B"	inlength="1"	name="EX_dcn_shiftcnt"	dicomtype="?"	dicomtag="?"			#  Decon Kernal Shift Count
+block="EXAMHDR"	offset="84"	intype="Int32_B"	inlength="1"	keyword="EX_magstrength"	dicomtype="?"	dicomtag="?"		#  Magnet strength (in gauss)
+block="EXAMHDR"	offset="88"	intype="String"	inlength="13"	name="EX_patid"		dicomtype="LO"	dicomtag="PatientID"		#  Patient ID for this Exam
+block="EXAMHDR"	offset="101"	intype="String"	inlength="25"	name="EX_patname"	dicomtype="PN"	dicomtag="PatientName"		#  Patient Name
+block="EXAMHDR"	offset="126"	intype="Int16_B"	inlength="1"	keyword="EX_patage"	dicomtype="?"	dicomtag="?"			#  Patient Age (years, months or days)
+block="EXAMHDR"	offset="128"	intype="Int16_B"	inlength="1"	keyword="EX_patian"	dicomtype="?"	dicomtag="?"	enum="0=Years:Y,1=Months:M,2=Days:D,3=Weeks:W"	#  Patient Age Notation
+block="EXAMHDR"	offset="130"	intype="Int16_B"	inlength="1"	keyword="EX_patsex"	dicomtype="?"	dicomtag="?"	enum="1=Male:M,2=Female:F"	#  Patient Sex
+block="EXAMHDR"	offset="132"	intype="Int32_B"	inlength="1"	keyword="EX_patweight"	dicomtype="?"	dicomtag="?"			#  Patient Weight ? grams
+block="EXAMHDR"	offset="136"	intype="Int16_B"	inlength="1"	name="EX_trauma"	dicomtype="?"	dicomtag="?"	enum="0=Trauma Flag Off,1=Trauma Flag On"	#  Trauma Flag
+block="EXAMHDR"	offset="138"	intype="String"	inlength="61"	name="EX_hist"		dicomtype="LT"	dicomtag="AdditionalPatientHistory"	#  Patient History
+block="EXAMHDR"	offset="199"	intype="String"	inlength="13"	name="EX_reqnum"	dicomtype="?"	dicomtag="?"			#  Requisition Number
+block="EXAMHDR"	offset="212"	intype="Unix_DateTime_B"	inlength="1"	keyword="EX_ex_datetime"	dicomtype="?"	dicomtag="?"			#  Exam date/time stamp
+block="EXAMHDR"	offset="216"	intype="String"	inlength="33"	name="EX_refphy"	dicomtype="PN"	dicomtag="ReferringPhysicianName"	#  Referring Physician
+block="EXAMHDR"	offset="249"	intype="String"	inlength="33"	name="EX_diagrad"	dicomtype="PN"	dicomtag="PerformingPhysicianName"	#  Diagnostician/Radiologist
+block="EXAMHDR"	offset="282"	intype="String"	inlength="4"	name="EX_op"			dicomtype="PN"	dicomtag="OperatorsName"	#  Operator
+block="EXAMHDR"	offset="286"	intype="String"	inlength="23"	name="EX_ex_desc"		dicomtype="LO"	dicomtag="StudyDescription"	#  Exam Description
+block="EXAMHDR"	offset="309"	intype="String"	inlength="3"	keyword="EX_ex_typ"		dicomtype="CS"	dicomtag="Modality"		#  Exam Type ('CT' or 'MR')
+block="EXAMHDR"	offset="312"	intype="Int16_B"	inlength="1"	name="EX_ex_format"		dicomtype="?"	dicomtag="?"	enum="0=Foreign,1=Genesis Image,2=Technicare HPS1440,3=Technicare Delta Scan 2010,4=Technicare Delta Scan 2020,5=Technicare Delta Scan 2060,6=Signa,7=CT9800,8=CT9800 Q,9=CT9800 QHL,10=EMI_9800,11=CT_8800_9800,12=CT9600,13=Jupiter,14=Zeus:CT HiSpeed Advantage,15=CT HiSpeed Advantage VX,16=Resona,17=Vectra,18=MR Max,19=CT Max,20=CT Pace,21=CT Sytec 2000,22=CT Sytec 3000,23=CT Sytec 40 [...]
+block="EXAMHDR"	offset="320"	intype="IEEE_Float64_B"	inlength="1"	name="EX_firstaxtime"	dicomtype="?"	dicomtag="?"		#  Start time(secs) of first axial in exam
+block="EXAMHDR"	offset="328"	intype="String"	inlength="9"	name="EX_ex_sysid"		dicomtype="?"	dicomtag="?"		#  Creator Suite and Host
+block="EXAMHDR"	offset="340"	intype="Unix_DateTime_B"	inlength="1"	keyword="EX_ex_lastmod"		dicomtype="?"	dicomtag="?"		#  Date/Time of Last Change
+block="EXAMHDR"	offset="344"	intype="Int16_B"	inlength="1"	name="EX_protocolflag"	dicomtype="?"	dicomtag="?"		#  Non-Zero indicates Protocol Exam
+block="EXAMHDR"	offset="346"	intype="String"	inlength="13"	name="EX_ex_alloc_key"	dicomtype="?"	dicomtag="?"		#  Process that allocated this record
+block="EXAMHDR"	offset="360"	intype="Int32_B"	inlength="1"	name="EX_ex_delta_cnt"	dicomtype="?"	dicomtag="?"		#  Indicates number of updates to header
+block="EXAMHDR"	offset="364"	intype="String"	inlength="2"	name="EX_ex_verscre"		dicomtype="?"	dicomtag="?"		#  Genesis Version - Created
+block="EXAMHDR"	offset="366"	intype="String"	inlength="2"	name="EX_ex_verscur"		dicomtype="?"	dicomtag="?"		#  Genesis Version - Now
+block="EXAMHDR"	offset="368"	intype="Uint32_B"	inlength="1"	name="EX_ex_checksum"	dicomtype="?"	dicomtag="?"		#  Exam Record Checksum
+block="EXAMHDR"	offset="372"	intype="Int32_B"	inlength="1"	name="EX_ex_complete"	dicomtype="?"	dicomtag="?"		#  Exam Complete Flag
+block="EXAMHDR"	offset="376"	intype="Int32_B"	inlength="1"	name="EX_ex_seriesct"	dicomtype="?"	dicomtag="?"		#  Last Series Number Used
+block="EXAMHDR"	offset="380"	intype="Int32_B"	inlength="1"	name="EX_ex_numarch"	dicomtype="?"	dicomtag="?"		#  Number of Series Archived
+block="EXAMHDR"	offset="384"	intype="Int32_B"	inlength="1"	name="EX_ex_numseries"	dicomtype="?"	dicomtag="?"		#  Number of Series Existing
+block="EXAMHDR"	offset="388"	intype="Uint32_B"	inlength="1"	name="EX_ex_series_l"	dicomtype="?"	dicomtag="?"		#  Series Keys for this exam - length
+block="EXAMHDR"	offset="392"	intype="Uint32_B"	inlength="1"	name="EX_ex_series_d"	dicomtype="?"	dicomtag="?"		#  Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="396"	intype="Int32_B"	inlength="1"	name="EX_ex_numunser"	dicomtype="?"	dicomtag="?"		#  Number of Unstored Series
+block="EXAMHDR"	offset="400"	intype="Uint32_B"	inlength="1"	name="EX_ex_unseries_l"	dicomtype="?"	dicomtag="?"		#  Unstored Series Keys for this exam - length
+block="EXAMHDR"	offset="404"	intype="Uint32_B"	inlength="1"	name="EX_ex_unseries_d"	dicomtype="?"	dicomtag="?"		#  Unstored Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="408"	intype="Int32_B"	inlength="1"	name="EX_ex_toarchcnt"	dicomtype="?"	dicomtag="?"		#  Number of Unarchived Series
+block="EXAMHDR"	offset="412"	intype="Uint32_B"	inlength="1"	name="EX_ex_toarchive_l"	dicomtype="?"	dicomtag="?"	#  Unarchived Series Keys for this exam - length
+block="EXAMHDR"	offset="416"	intype="Uint32_B"	inlength="1"	name="EX_ex_toarchive_d"	dicomtype="?"	dicomtag="?"	#  Unarchived Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="420"	intype="Int32_B"	inlength="1"	name="EX_ex_prospcnt"	dicomtype="?"	dicomtag="?"		#  Number of Prospective/Scout Series
+block="EXAMHDR"	offset="424"	intype="Uint32_B"	inlength="1"	name="EX_ex_prosp_l"	dicomtype="?"	dicomtag="?"		#  Prospective Series Keys for this exam - length
+block="EXAMHDR"	offset="428"	intype="Uint32_B"	inlength="1"	name="EX_ex_prosp_d"	dicomtype="?"	dicomtag="?"		#  Prospective Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="432"	intype="Int32_B"	inlength="1"	name="EX_ex_modelnum"	dicomtype="?"	dicomtag="?"		#  Last Model Number used
+block="EXAMHDR"	offset="436"	intype="Int32_B"	inlength="1"	name="EX_ex_modelcnt"	dicomtype="?"	dicomtag="?"		#  Number of ThreeD Models
+block="EXAMHDR"	offset="440"	intype="Uint32_B"	inlength="1"	name="EX_ex_models_l"	dicomtype="?"	dicomtag="?"		#  3D Model Keys for this exam - length
+block="EXAMHDR"	offset="444"	intype="Uint32_B"	inlength="1"	name="EX_ex_models_d"	dicomtype="?"	dicomtag="?"		#  3D Model Keys for this exam - data ptr
+block="EXAMHDR"	offset="448"	intype="Int16_B"	inlength="1"	name="EX_ex_stat"		dicomtype="?"	dicomtag="?"	enum="0=In Patient:IN,1=Out Patient:OUT,2=Emergency:EM,3=Referral:REF"	#  Patient Status
+block="EXAMHDR"	offset="450"	intype="String"	inlength="16"	name="EX_uniq_sys_id"	dicomtype="?"	dicomtag="?"		#  Unique System ID
+block="EXAMHDR"	offset="466"	intype="String"	inlength="16"	name="EX_service_id"		dicomtype="?"	dicomtag="?"		#  Unique Service ID
+block="EXAMHDR"	offset="482"	intype="String"	inlength="4"	name="EX_mobile_loc"		dicomtype="?"	dicomtag="?"		#  Mobile Location Number
+block="EXAMHDR"	offset="486"	intype="String"	inlength="32"	name="EX_study_uid"		dicomtype="?"	dicomtag="?"		#  Study Entity Unique ID
+block="EXAMHDR"	offset="518"	intype="String"	inlength="518"	name="EX_ex_padding"		dicomtype="?"	dicomtag="?"		#  Spare Space
+block="SERIESHDR"	offset="0"	intype="String"	inlength="4"	name="SE_se_suid"	dicomtype="?"	dicomtag="?"		#  Suite ID for this Series
+block="SERIESHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="SE_se_uniq"	dicomtype="?"	dicomtag="?"		#  The Make-Unique Flag
+block="SERIESHDR"	offset="6"	intype="String"	inlength="1"	name="SE_se_diskid"	dicomtype="?"	dicomtag="?"		#  Disk ID for this Series
+block="SERIESHDR"	offset="8"	intype="Uint16_B"	inlength="1"	name="SE_se_exno"	dicomtype="?"	dicomtag="?"		#  Exam Number
+block="SERIESHDR"	offset="10"	intype="Int16_B"	inlength="1"	keyword="SE_se_no"	dicomtype="IS"	dicomtag="SeriesNumber"	#  Series Number
+block="SERIESHDR"	offset="12"	intype="Unix_DateTime_B"	inlength="1"	keyword="SE_se_datetime"	dicomtype="?"	dicomtag="?"	#  Allocation Series Date/Time stamp
+block="SERIESHDR"	offset="16"	intype="Unix_DateTime_B"	inlength="1"	keyword="SE_se_actual_dt"	dicomtype="?"	dicomtag="?"	#  Actual Series Date/Time stamp
+block="SERIESHDR"	offset="20"	intype="String"	inlength="30"	name="SE_se_desc"	dicomtype="LO"	dicomtag="SeriesDescription"	#  Series Description
+block="SERIESHDR"	offset="50"	intype="String"	inlength="9"	name="SE_pr_sysid"	dicomtype="?"	dicomtag="?"		#  Primary Receiver Suite and Host
+block="SERIESHDR"	offset="59"	intype="String"	inlength="9"	name="SE_pansysid"	dicomtype="?"	dicomtag="?"		#  Archiver Suite and Host
+block="SERIESHDR"	offset="68"	intype="Int16_B"	inlength="1"	keyword="SE_se_typ"	dicomtype="?"	dicomtag="?"	enum="1=prospective:PROSP,2=Retrospective:RETRO,3=Scout Series:SCOUT,4=Reformatted:REFMT,5=Screensave:SSAVE,6=Xenon:XENON,7=Service:SERV,9=Projected:PJN"	#  Series Type
+block="SERIESHDR"	offset="70"	intype="Int16_B"	inlength="1"	name="SE_se_source"	dicomtype="?"	dicomtag="?"		#  Series from which prescribed
+block="SERIESHDR"	offset="72"	intype="Int16_B"	inlength="1"	name="SE_se_plane"	dicomtype="?"	dicomtag="?"		#  Most-like Plane (for L/S)
+block="SERIESHDR"	offset="74"	intype="Int16_B"	inlength="1"	name="SE_scan_type"	dicomtype="?"	dicomtag="?"	enum="1=Scout:SCT,2=Axial:AX,3=Screensave:SS"	#  Scout or Axial (for CT)
+block="SERIESHDR"	offset="76"	intype="Int32_B"	inlength="1"	keyword="SE_position"	dicomtype="?"	dicomtag="?"	bitmap="0:none,Supine;1:none,Prone;2:none,Decubitus Left;3:none,Decubitus Right"	#  Patient Position
+block="SERIESHDR"	offset="80"	intype="Int32_B"	inlength="1"	keyword="SE_entry"	dicomtype="?"	dicomtag="?"	enum="1=Head First,2=Feet First"	#  Patient Entry
+block="SERIESHDR"	offset="84"	intype="String"	inlength="3"	name="SE_anref"	dicomtype="LO"	dicomtag="PositionReferenceIndicator"		#  Anatomical reference
+block="SERIESHDR"	offset="88"	intype="IEEE_Float32_B"	inlength="1"	name="SE_lmhor"	dicomtype="?"	dicomtag="?"		#  Horizontal Landmark
+block="SERIESHDR"	offset="92"	intype="String"	inlength="25"	name="SE_prtcl"	dicomtype="LO"	dicomtag="ProtocolName"	#  Scan Protocol Name
+block="SERIESHDR"	offset="118"	intype="Int16_B"	inlength="1"	name="SE_se_contrast"	dicomtype="?"	dicomtag="?"	#  Non-zero if > 0 image used contrast(L/S)
+block="SERIESHDR"	offset="120"	intype="String"	inlength="1"	name="SE_start_ras"	dicomtype="?"	dicomtag="?"		#  RAS letter for first scan location (L/S)
+block="SERIESHDR"	offset="124"	intype="IEEE_Float32_B"	inlength="1"	name="SE_start_loc"	dicomtype="?"	dicomtag="?"		#  First scan location (L/S)
+block="SERIESHDR"	offset="128"	intype="String"	inlength="1"	name="SE_end_ras"	dicomtype="?"	dicomtag="?"		#  RAS letter for last scan location (L/S)
+block="SERIESHDR"	offset="132"	intype="IEEE_Float32_B"	inlength="1"	name="SE_end_loc"	dicomtype="?"	dicomtag="?"		#  Last scan location (L/S)
+block="SERIESHDR"	offset="136"	intype="Int16_B"	inlength="1"	name="SE_se_pseq"	dicomtype="?"	dicomtag="?"		#  Last Pulse Sequence Used (L/S)
+block="SERIESHDR"	offset="138"	intype="Int16_B"	inlength="1"	name="SE_se_sortorder"	dicomtype="?"	dicomtag="?"	#  Image Sort Order (L/S)
+block="SERIESHDR"	offset="140"	intype="Int32_B"	inlength="1"	name="SE_se_lndmrkcnt"	dicomtype="?"	dicomtag="?"	#  Landmark Counter
+block="SERIESHDR"	offset="144"	intype="Int16_B"	inlength="1"	name="SE_se_nacq"	dicomtype="IS"	dicomtag="ImagesInAcquisition"	#  Number of Acquisitions
+block="SERIESHDR"	offset="146"	intype="Int16_B"	inlength="1"	name="SE_xbasest"		dicomtype="?"	dicomtag="?"	#  Starting number for baselines
+block="SERIESHDR"	offset="148"	intype="Int16_B"	inlength="1"	name="SE_xbaseend"		dicomtype="?"	dicomtag="?"	#  Ending number for baselines
+block="SERIESHDR"	offset="150"	intype="Int16_B"	inlength="1"	name="SE_xenhst"		dicomtype="?"	dicomtag="?"	#  Starting number for enhanced scans
+block="SERIESHDR"	offset="152"	intype="Int16_B"	inlength="1"	name="SE_xenhend"		dicomtype="?"	dicomtag="?"	#  Ending number for enhanced scans
+block="SERIESHDR"	offset="156"	intype="Unix_DateTime_B"	inlength="1"	keyword="SE_se_lastmod"		dicomtype="?"	dicomtag="?"	#  Date/Time of Last Change
+block="SERIESHDR"	offset="160"	intype="String"	inlength="13"	name="SE_se_alloc_key"	dicomtype="?"	dicomtag="?"	#  Process that allocated this record
+block="SERIESHDR"	offset="176"	intype="Int32_B"	inlength="1"	name="SE_se_delta_cnt"	dicomtype="?"	dicomtag="?"	#  Indicates number of updates to header
+block="SERIESHDR"	offset="180"	intype="String"	inlength="2"	name="SE_se_verscre"		dicomtype="?"	dicomtag="?"	#  Genesis Version - Created
+block="SERIESHDR"	offset="182"	intype="String"	inlength="2"	name="SE_se_verscur"		dicomtype="?"	dicomtag="?"	#  Genesis Version - Now
+block="SERIESHDR"	offset="184"	intype="IEEE_Float32_B"	inlength="1"	name="SE_se_pds_a"		dicomtype="?"	dicomtag="?"	#  PixelData size - as stored
+block="SERIESHDR"	offset="188"	intype="IEEE_Float32_B"	inlength="1"	name="SE_se_pds_c"		dicomtype="?"	dicomtag="?"	#  PixelData size - Compressed
+block="SERIESHDR"	offset="192"	intype="IEEE_Float32_B"	inlength="1"	name="SE_se_pds_u"		dicomtype="?"	dicomtag="?"	#  PixelData size - UnCompressed
+block="SERIESHDR"	offset="196"	intype="Uint32_B"	inlength="1"	name="SE_se_checksum"		dicomtype="?"	dicomtag="?"	#  Series Record checksum
+block="SERIESHDR"	offset="200"	intype="Int32_B"	inlength="1"	name="SE_se_complete"		dicomtype="?"	dicomtag="?"	#  Series Complete Flag
+block="SERIESHDR"	offset="204"	intype="Int32_B"	inlength="1"	name="SE_se_numarch"		dicomtype="?"	dicomtag="?"	#  Number of Images Archived
+block="SERIESHDR"	offset="208"	intype="Int32_B"	inlength="1"	name="SE_se_imagect"		dicomtype="?"	dicomtag="?"	#  Last Image Number Used
+block="SERIESHDR"	offset="212"	intype="Int32_B"	inlength="1"	name="SE_se_numimages"		dicomtype="?"	dicomtag="?"	#  Number of Images Existing
+block="SERIESHDR"	offset="216"	intype="Uint32_B"	inlength="1"	name="SE_se_images_l"		dicomtype="?"	dicomtag="?"	#  Image Keys for this Series - length
+block="SERIESHDR"	offset="220"	intype="Uint32_B"	inlength="1"	name="SE_se_images_d"		dicomtype="?"	dicomtag="?"	#  Image Keys for this Series - data ptr
+block="SERIESHDR"	offset="224"	intype="Int32_B"	inlength="1"	name="SE_se_numunimg"		dicomtype="?"	dicomtag="?"	#  Number of Unstored Images
+block="SERIESHDR"	offset="228"	intype="Uint32_B"	inlength="1"	name="SE_se_unimages_l"		dicomtype="?"	dicomtag="?"	#  Unstored Image Keys for this Series - length
+block="SERIESHDR"	offset="232"	intype="Uint32_B"	inlength="1"	name="SE_se_unimages_d"		dicomtype="?"	dicomtag="?"	#  Unstored Image Keys for this Series - data ptr
+block="SERIESHDR"	offset="236"	intype="Int32_B"	inlength="1"	name="SE_se_toarchcnt"		dicomtype="?"	dicomtag="?"	#  Number of Unarchived Images
+block="SERIESHDR"	offset="240"	intype="Uint32_B"	inlength="1"	name="SE_se_toarchive_l"	dicomtype="?"	dicomtag="?"	#  Unarchived Image Keys for this Series - length
+block="SERIESHDR"	offset="244"	intype="Uint32_B"	inlength="1"	name="SE_se_toarchive_d"	dicomtype="?"	dicomtag="?"	#  Unarchived Image Keys for this Series - data ptr
+block="SERIESHDR"	offset="248"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo1_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 1 Alpha Value
+block="SERIESHDR"	offset="252"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo1_beta"		dicomtype="?"	dicomtag="?"	#  Echo 1 Beta Value
+block="SERIESHDR"	offset="256"	intype="Uint16_B"	inlength="1"	name="SE_echo1_window"	dicomtype="?"	dicomtag="?"	#  Echo 1 Window Value
+block="SERIESHDR"	offset="258"	intype="Int16_B"	inlength="1"	name="SE_echo1_level"	dicomtype="?"	dicomtag="?"	#  Echo 1 Level Value
+block="SERIESHDR"	offset="260"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo2_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 2 Alpha Value
+block="SERIESHDR"	offset="264"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo2_beta"		dicomtype="?"	dicomtag="?"	#  Echo 2 Beta Value
+block="SERIESHDR"	offset="268"	intype="Uint16_B"	inlength="1"	name="SE_echo2_window"	dicomtype="?"	dicomtag="?"	#  Echo 2 Window Value
+block="SERIESHDR"	offset="270"	intype="Int16_B"	inlength="1"	name="SE_echo2_level"	dicomtype="?"	dicomtag="?"	#  Echo 2 Level Value
+block="SERIESHDR"	offset="272"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo3_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 3 Alpha Value
+block="SERIESHDR"	offset="276"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo3_beta"		dicomtype="?"	dicomtag="?"	#  Echo 3 Beta Value
+block="SERIESHDR"	offset="280"	intype="Uint16_B"	inlength="1"	name="SE_echo3_window"	dicomtype="?"	dicomtag="?"	#  Echo 3 Window Value
+block="SERIESHDR"	offset="282"	intype="Int16_B"	inlength="1"	name="SE_echo3_level"	dicomtype="?"	dicomtag="?"	#  Echo 3 Level Value
+block="SERIESHDR"	offset="284"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo4_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 4 Alpha Value
+block="SERIESHDR"	offset="288"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo4_beta"		dicomtype="?"	dicomtag="?"	#  Echo 4 Beta Value
+block="SERIESHDR"	offset="292"	intype="Uint16_B"	inlength="1"	name="SE_echo4_window"	dicomtype="?"	dicomtag="?"	#  Echo 4 Window Value
+block="SERIESHDR"	offset="294"	intype="Int16_B"	inlength="1"	name="SE_echo4_level"	dicomtype="?"	dicomtag="?"	#  Echo 4 Level Value
+block="SERIESHDR"	offset="296"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo5_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 5 Alpha Value
+block="SERIESHDR"	offset="300"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo5_beta"		dicomtype="?"	dicomtag="?"	#  Echo 5 Beta Value
+block="SERIESHDR"	offset="304"	intype="Uint16_B"	inlength="1"	name="SE_echo5_window"	dicomtype="?"	dicomtag="?"	#  Echo 5 Window Value
+block="SERIESHDR"	offset="306"	intype="Int16_B"	inlength="1"	name="SE_echo5_level"	dicomtype="?"	dicomtag="?"	#  Echo 5 Level Value
+block="SERIESHDR"	offset="308"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo6_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 6 Alpha Value
+block="SERIESHDR"	offset="312"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo6_beta"		dicomtype="?"	dicomtag="?"	#  Echo 6 Beta Value
+block="SERIESHDR"	offset="316"	intype="Uint16_B"	inlength="1"	name="SE_echo6_window"	dicomtype="?"	dicomtag="?"	#  Echo 6 Window Value
+block="SERIESHDR"	offset="318"	intype="Int16_B"	inlength="1"	name="SE_echo6_level"	dicomtype="?"	dicomtag="?"	#  Echo 6 Level Value
+block="SERIESHDR"	offset="320"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo7_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 7 Alpha Value
+block="SERIESHDR"	offset="324"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo7_beta"		dicomtype="?"	dicomtag="?"	#  Echo 7 Beta Value
+block="SERIESHDR"	offset="328"	intype="Uint16_B"	inlength="1"	name="SE_echo7_window"	dicomtype="?"	dicomtag="?"	#  Echo 7 Window Value
+block="SERIESHDR"	offset="330"	intype="Int16_B"	inlength="1"	name="SE_echo7_level"	dicomtype="?"	dicomtag="?"	#  Echo 7 Level Value
+block="SERIESHDR"	offset="332"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo8_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 8 Alpha Value
+block="SERIESHDR"	offset="336"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo8_beta"		dicomtype="?"	dicomtag="?"	#  Echo 8 Beta Value
+block="SERIESHDR"	offset="340"	intype="Uint16_B"	inlength="1"	name="SE_echo8_window"	dicomtype="?"	dicomtag="?"	#  Echo 8 Window Value
+block="SERIESHDR"	offset="342"	intype="Int16_B"	inlength="1"	name="SE_echo8_level"	dicomtype="?"	dicomtag="?"	#  Echo 8 Level Value
+block="SERIESHDR"	offset="344"	intype="String"	inlength="32"	name="SE_series_uid"		dicomtype="?"	dicomtag="?"	#  Series Entity Unique ID
+block="SERIESHDR"	offset="376"	intype="String"	inlength="32"	name="SE_landmark_uid"	dicomtype="?"	dicomtag="?"	#  Landmark Unique ID
+block="SERIESHDR"	offset="408"	intype="String"	inlength="32"	name="SE_equipmnt_uid"	dicomtype="?"	dicomtag="?"	#  Equipment Unique ID
+block="SERIESHDR"	offset="440"	intype="String"	inlength="588"	name="SE_se_padding"		dicomtype="?"	dicomtag="?"	#  Spare Space
+block="CTHDR"  condition="isct"	offset="0"	intype="String"	inlength="4"	name="CT_im_suid"		dicomtype="?"	dicomtag="?"		#  Suite id for this image
+block="CTHDR"  condition="isct"	offset="4"	intype="Int16_B"	inlength="1"	name="CT_im_uniq"		dicomtype="?"	dicomtag="?"		#  The Make-Unique Flag
+block="CTHDR"  condition="isct"	offset="6"	intype="String"	inlength="1"	name="CT_im_diskid"		dicomtype="?"	dicomtag="?"		#  Disk ID for this Image
+block="CTHDR"  condition="isct"	offset="8"	intype="Uint16_B"	inlength="1"	name="CT_im_exno"		dicomtype="?"	dicomtag="?"		#  Exam number for this image
+block="CTHDR"  condition="isct"	offset="10"	intype="Int16_B"	inlength="1"	name="CT_im_seno"		dicomtype="?"	dicomtag="?"		#  Series Number for this image
+block="CTHDR"  condition="isct"	offset="12"	intype="Int16_B"	inlength="1"	keyword="CT_im_no"		dicomtype="IS"	dicomtag="InstanceNumber"	#  Image Number
+block="CTHDR"  condition="isct"	offset="16"	intype="Unix_DateTime_B"	inlength="1"	keyword="CT_im_datetime"	dicomtype="?"	dicomtag="?"		#  Allocation Image date/time stamp
+block="CTHDR"  condition="isct"	offset="20"	intype="Unix_DateTime_B"	inlength="1"	keyword="CT_im_actual_dt"	dicomtype="?"	dicomtag="?"		#  Actual Image date/time stamp
+block="CTHDR"  condition="isct"	offset="24"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sctime"		dicomtype="?"	dicomtag="?"		#  Duration of scan (secs)
+block="CTHDR"  condition="isct"	offset="28"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slthick"		dicomtype="DS"	dicomtag="SliceThickness"	#  Slice Thickness (mm)
+block="CTHDR"  condition="isct"	offset="32"	intype="Int16_B"	inlength="1"	keyword="CT_imatrix_X"		dicomtype="?"	dicomtag="?"		#  Image matrix size - X
+block="CTHDR"  condition="isct"	offset="34"	intype="Int16_B"	inlength="1"	keyword="CT_imatrix_Y"		dicomtype="?"	dicomtag="?"		#  Image matrix size - Y
+block="CTHDR"  condition="isct"	offset="36"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dfov"		dicomtype="?"	dicomtag="?"		#  Display field of view - X (mm)
+block="CTHDR"  condition="isct"	offset="40"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dfov_rect"		dicomtype="?"	dicomtag="?"		#  Display field of view - Y (if different)
+block="CTHDR"  condition="isct"	offset="44"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dim_X"		dicomtype="?"	dicomtag="?"		#  Image dimension - X
+block="CTHDR"  condition="isct"	offset="48"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dim_Y"		dicomtype="?"	dicomtag="?"		#  Image dimension - Y
+block="CTHDR"  condition="isct"	offset="52"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_pixsize_X"		dicomtype="?"	dicomtag="?"	#  Image pixel size - X
+block="CTHDR"  condition="isct"	offset="56"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_pixsize_Y"		dicomtype="?"	dicomtag="?"	#  Image pixel size - Y
+block="CTHDR"  condition="isct"	offset="60"	intype="String"	inlength="14"	name="CT_pdid"		dicomtype="?"	dicomtag="?"		#  Pixel Data ID
+block="CTHDR"  condition="isct"	offset="74"	intype="String"	inlength="17"	name="CT_contrastIV"		dicomtype="?"	dicomtag="?"		#  IV Contrast Agent
+block="CTHDR"  condition="isct"	offset="91"	intype="String"	inlength="17"	name="CT_contrastOral"	dicomtype="?"	dicomtag="?"		#  Oral Contrast Agent
+block="CTHDR"  condition="isct"	offset="108"	intype="Int16_B"	inlength="1"	name="CT_contmode"		dicomtype="?"	dicomtag="?"	bitmap="0:none,oral;1:none,intravenous"	#  Image Contrast Mode
+block="CTHDR"  condition="isct"	offset="110"	intype="Int16_B"	inlength="1"	name="CT_serrx"		dicomtype="?"	dicomtag="?"		#  Series from which prescribed
+block="CTHDR"  condition="isct"	offset="112"	intype="Int16_B"	inlength="1"	name="CT_imgrx"		dicomtype="?"	dicomtag="?"		#  Image from which prescribed
+block="CTHDR"  condition="isct"	offset="114"	intype="Int16_B"	inlength="1"	name="CT_screenformat"	dicomtype="?"	dicomtag="?"		#  Screen Format(8/16 bit)
+block="CTHDR"  condition="isct"	offset="116"	intype="Int16_B"	inlength="1"	name="CT_plane"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Scout Plane(SCT);1:none,Axial Plane(Ax);2:none,Sagittal Plane(Sag);3:none,Coronal Plane(Cor);4:none,Oblique Plane(O);5:none,ParAxial Plane(PAX);6:none,Reformatted Plane(RFMT);7:none,Projected Plane(PJN);8:none,Mixed Plane(MIXED)"	#  Plane Type
+block="CTHDR"  condition="isct"	offset="120"	intype="IEEE_Float32_B"	inlength="1"	name="CT_scanspacing"	dicomtype="DS"	dicomtag="SpacingBetweenSlices"	#  Spacing between scans (mm?)
+block="CTHDR"  condition="isct"	offset="124"	intype="Int16_B"	inlength="1"	name="CT_im_compress"	dicomtype="?"	dicomtag="?"		#  Image compression type for allocation
+block="CTHDR"  condition="isct"	offset="126"	intype="Int16_B"	inlength="1"	name="CT_im_scouttype"	dicomtype="?"	dicomtag="?"		#  Scout Type (AP or lateral)
+block="CTHDR"  condition="isct"	offset="128"	intype="String"	inlength="1"	name="CT_loc_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter of image location
+block="CTHDR"  condition="isct"	offset="132"	intype="IEEE_Float32_B"	inlength="1"	name="CT_loc"		dicomtype="DS"	dicomtag="SliceLocation"	#  Image location
+block="CTHDR"  condition="isct"	offset="136"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_ctr_R"		dicomtype="?"	dicomtag="?"		#  Center R coord of plane image
+block="CTHDR"  condition="isct"	offset="140"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_ctr_A"		dicomtype="?"	dicomtag="?"		#  Center A coord of plane image
+block="CTHDR"  condition="isct"	offset="144"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_ctr_S"		dicomtype="?"	dicomtag="?"		#  Center S coord of plane image
+block="CTHDR"  condition="isct"	offset="148"	intype="IEEE_Float32_B"	inlength="1"	name="CT_norm_R"		dicomtype="?"	dicomtag="?"		#  Normal R coord
+block="CTHDR"  condition="isct"	offset="152"	intype="IEEE_Float32_B"	inlength="1"	name="CT_norm_A"		dicomtype="?"	dicomtag="?"		#  Normal A coord
+block="CTHDR"  condition="isct"	offset="156"	intype="IEEE_Float32_B"	inlength="1"	name="CT_norm_S"		dicomtype="?"	dicomtag="?"		#  Normal S coord
+block="CTHDR"  condition="isct"	offset="160"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_tlhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Left Hand
+block="CTHDR"  condition="isct"	offset="164"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_tlhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Left Hand
+block="CTHDR"  condition="isct"	offset="168"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_tlhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Left Hand
+block="CTHDR"  condition="isct"	offset="172"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_trhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Right Hand
+block="CTHDR"  condition="isct"	offset="176"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_trhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Right Hand
+block="CTHDR"  condition="isct"	offset="180"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_trhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Right Hand
+block="CTHDR"  condition="isct"	offset="184"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_brhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Bottom Right Hand
+block="CTHDR"  condition="isct"	offset="188"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_brhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Bottom Right Hand
+block="CTHDR"  condition="isct"	offset="192"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_brhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Bottom Right Hand
+block="CTHDR"  condition="isct"	offset="196"	intype="String"	inlength="4"	name="CT_forimgrev"		dicomtype="?"	dicomtag="?"		#  Foreign Image Revision
+block="CTHDR"  condition="isct"	offset="200"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sctstr"		dicomtype="?"	dicomtag="?"		#  Table Start Location
+block="CTHDR"  condition="isct"	offset="204"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sctend"		dicomtype="?"	dicomtag="?"		#  Table End Location
+block="CTHDR"  condition="isct"	offset="208"	intype="IEEE_Float32_B"	inlength="1"	name="CT_tblspd"		dicomtype="?"	dicomtag="?"		#  Table Speed (mm/sec)
+block="CTHDR"  condition="isct"	offset="212"	intype="IEEE_Float32_B"	inlength="1"	name="CT_tblht"		dicomtype="DS"	dicomtag="TableHeight"	#  Table Height
+block="CTHDR"  condition="isct"	offset="216"	intype="IEEE_Float32_B"	inlength="1"	name="CT_midstime"		dicomtype="?"	dicomtag="?"		#  Mid Scan Time
+block="CTHDR"  condition="isct"	offset="220"	intype="Int16_B"	inlength="1"	name="CT_midsflag"		dicomtype="?"	dicomtag="?"		#  does midstime apply
+block="CTHDR"  condition="isct"	offset="224"	intype="Int32_B"	inlength="1"	name="CT_kvolt"			dicomtype="DS"	dicomtag="KVP"		#  KVolt generator setting
+block="CTHDR"  condition="isct"	offset="228"	intype="Int32_B"	inlength="1"	keyword="CT_mamp"		dicomtype="IS"	dicomtag="XRayTubeCurrent"	#  MAmp generator setting
+block="CTHDR"  condition="isct"	offset="232"	intype="IEEE_Float32_B"	inlength="1"	name="CT_gantilt"		dicomtype="DS"	dicomtag="GantryDetectorTilt"	#  Gantry Tilt (degrees)
+block="CTHDR"  condition="isct"	offset="236"	intype="Int32_B"	inlength="1"	name="CT_azimuth"		dicomtype="?"	dicomtag="?"		#  Degrees of Azimuth
+block="CTHDR"  condition="isct"	offset="240"	intype="IEEE_Float32_B"	inlength="1"	name="CT_ganvel"		dicomtype="?"	dicomtag="?"		#  Gantry Velocity
+block="CTHDR"  condition="isct"	offset="244"	intype="Int32_B"	inlength="1"	name="CT_ganfilt"		dicomtype="?"	dicomtag="?"		#  Gantry Filter Position
+block="CTHDR"  condition="isct"	offset="248"	intype="IEEE_Float32_B"	inlength="1"	name="CT_trigon"		dicomtype="?"	dicomtag="?"		#  Trigger on Position
+block="CTHDR"  condition="isct"	offset="252"	intype="IEEE_Float32_B"	inlength="1"	name="CT_degrot"		dicomtype="?"	dicomtag="?"		#  Degrees of rotation
+block="CTHDR"  condition="isct"	offset="256"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xrayon"		dicomtype="?"	dicomtag="?"		#  X-Ray On Position
+block="CTHDR"  condition="isct"	offset="260"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xrayoff"		dicomtype="?"	dicomtag="?"		#  X-Ray Off Position
+block="CTHDR"  condition="isct"	offset="264"	intype="Int32_B"	inlength="1"	name="CT_numtrig"		dicomtype="?"	dicomtag="?"		#  Number of Triggers
+block="CTHDR"  condition="isct"	offset="268"	intype="Int16_B"	inlength="1"	name="CT_inviews"		dicomtype="?"	dicomtag="?"		#  Total input views
+block="CTHDR"  condition="isct"	offset="272"	intype="IEEE_Float32_B"	inlength="1"	name="CT_view1ang"		dicomtype="?"	dicomtag="?"		#  Angle of first view
+block="CTHDR"  condition="isct"	offset="276"	intype="IEEE_Float32_B"	inlength="1"	name="CT_trigfreq"		dicomtype="?"	dicomtag="?"		#  Trigger frequency
+block="CTHDR"  condition="isct"	offset="280"	intype="Int32_B"	inlength="1"	name="CT_trigsrc"		dicomtype="?"	dicomtag="?"	enum="1=internal,2=external"	#  DAS trigger source
+block="CTHDR"  condition="isct"	offset="284"	intype="Int32_B"	inlength="1"	name="CT_fpagain"		dicomtype="?"	dicomtag="?"	bitmap="0:none,auto;1:none,X1;3:none,X8;6:none,X64"	#  DAS fpa gain
+block="CTHDR"  condition="isct"	offset="288"	intype="Int32_B"	inlength="1"	name="CT_scanopmode"		dicomtype="?"	dicomtag="?"	bitmap="0:none,???;1:none,???;2:none,???;3:none,scout mode;4:none,axial Xron mode;5:none,axial Xroff mode;6:none,static Xron mode;7:none,static Xroff mode;8:none,tube heat mode;9:none,DAS mode;10:none,tube cal mode;11:none,biopsy mode;12:none,cine mode;13:none,helical mode;14:none,rotgencal mode"	#  Scan Type
+block="CTHDR"  condition="isct"	offset="292"	intype="Int32_B"	inlength="1"	name="CT_outsrc"		dicomtype="?"	dicomtag="?"	enum="1=AID,2=XM"	#  DAS output source
+block="CTHDR"  condition="isct"	offset="296"	intype="Int32_B"	inlength="1"	name="CT_adin"		dicomtype="?"	dicomtag="?"	enum="1=DAS Filter Card,2=Aux"	#  DAS ad input
+block="CTHDR"  condition="isct"	offset="300"	intype="Int32_B"	inlength="1"	name="CT_calmode"		dicomtype="?"	dicomtag="?"	enum="1=DC DAS Cal,2=AC DAS Cal,3=No DAS Cal"	#  DAS cal mode
+block="CTHDR"  condition="isct"	offset="304"	intype="Int32_B"	inlength="1"	name="CT_calfreq"		dicomtype="?"	dicomtag="?"	enum="0=?,1=?"	#  DAS cal frequency
+block="CTHDR"  condition="isct"	offset="308"	intype="Int32_B"	inlength="1"	name="CT_regxm"		dicomtype="?"	dicomtag="?"	enum="1=hold,2=shift"	#  DAS reg xm
+block="CTHDR"  condition="isct"	offset="312"	intype="Int32_B"	inlength="1"	name="CT_autozero"		dicomtype="?"	dicomtag="?"		#  DAS auto zero
+block="CTHDR"  condition="isct"	offset="316"	intype="Int16_B"	inlength="1"	name="CT_sfovtyp"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Ped Head;1:none,Adult Head;2:none,Small;3:none,Medium;4:none,Large;5:none,No Sfovtype"	#  Axial Type
+block="CTHDR"  condition="isct"	offset="318"	intype="Int16_B"	inlength="1"	name="CT_phantsize"		dicomtype="?"	dicomtag="?"	enum="1=No Psize,2=Small Psize,3=Medium Psize,4=Large Psize"	#  Calibration phantom size
+block="CTHDR"  condition="isct"	offset="320"	intype="Int16_B"	inlength="1"	name="CT_phanttyp"		dicomtype="?"	dicomtag="?"	enum="1=None,2=Air,3=Water,4=Poly"	#  Calibration phantom type
+block="CTHDR"  condition="isct"	offset="322"	intype="Int16_B"	inlength="1"	keyword="CT_filttyp"		dicomtype="?"	dicomtag="?"	enum="1=Air Filter,2=Body Filter,3=Bowtie Flat Filter:Adult Head,4=Flat Filter,5=High Filter:Adult Head/HF"	#  Calibration filter type
+block="CTHDR"  condition="isct"	offset="324"	intype="Int16_B"	inlength="1"	keyword="CT_reconalg"		dicomtype="?"	dicomtag="?"	bitmap="0:none,smooth(SMTH);1:none,soft(SOFT);2:none,standard(STND);3:none,detail(DETL);4:none,bone(BONE);5:none,edge(EDGE);6:none,sharp(SHRP);7:none,experimental 2(EXP2)"	#  Recon Algorithm
+block="CTHDR"  condition="isct"	offset="326"	intype="Int16_B"	inlength="1"	keyword="CT_perisflag"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:/P"	#  Peristaltic flag
+block="CTHDR"  condition="isct"	offset="328"	intype="Int16_B"	inlength="1"	keyword="CT_iboneflag"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:/I"	#  IterBone flag
+block="CTHDR"  condition="isct"	offset="330"	intype="Int16_B"	inlength="1"	name="CT_statflag"		dicomtype="?"	dicomtag="?"		#  Stat Recon flag
+block="CTHDR"  condition="isct"	offset="332"	intype="Int16_B"	inlength="1"	name="CT_computetyp"		dicomtype="?"	dicomtag="?"	enum="1=axial,2=calcheck,3=scout,4=ppscan,5=viewsvschannels"	#  Compute Type
+block="CTHDR"  condition="isct"	offset="334"	intype="Int16_B"	inlength="1"	name="CT_segnum"		dicomtype="?"	dicomtag="?"		#  Segment Number
+block="CTHDR"  condition="isct"	offset="336"	intype="Int16_B"	inlength="1"	name="CT_segstotal"		dicomtype="?"	dicomtag="?"		#  Total Number of Segments Requested
+block="CTHDR"  condition="isct"	offset="340"	intype="IEEE_Float32_B"	inlength="1"	name="CT_isd"		dicomtype="?"	dicomtag="?"		#  Inter scan delay (secs)
+block="CTHDR"  condition="isct"	offset="344"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_sfovmm"		dicomtype="DS"	dicomtag="DataCollectionDiameter"		#  Scan field of view (mm)
+block="CTHDR"  condition="isct"	offset="348"	intype="Int16_B"	inlength="1"	name="CT_scannum"		dicomtype="IS"	dicomtag="AcquisitionNumber"		#  Scan Number
+block="CTHDR"  condition="isct"	offset="350"	intype="Int16_B"	inlength="1"	name="CT_viewstrtchan"	dicomtype="?"	dicomtag="?"		#  Starting Channel of View
+block="CTHDR"  condition="isct"	offset="352"	intype="Int16_B"	inlength="1"	name="CT_viewcompfctr"	dicomtype="?"	dicomtag="?"		#  View Compression Factor
+block="CTHDR"  condition="isct"	offset="354"	intype="Int16_B"	inlength="1"	name="CT_outviews"		dicomtype="?"	dicomtag="?"		#  Total Output Views
+block="CTHDR"  condition="isct"	offset="356"	intype="Int16_B"	inlength="1"	name="CT_overranges"		dicomtype="?"	dicomtag="?"		#  Number of Overranges
+block="CTHDR"  condition="isct"	offset="358"	intype="Int16_B"	inlength="1"	name="CT_totrefchan"		dicomtype="?"	dicomtag="?"		#  Total Number of Ref Channels
+block="CTHDR"  condition="isct"	offset="360"	intype="Int32_B"	inlength="1"	name="CT_scdatasize"		dicomtype="?"	dicomtag="?"		#  data size for scan data
+block="CTHDR"  condition="isct"	offset="364"	intype="Int16_B"	inlength="1"	name="CT_refchan1"		dicomtype="?"	dicomtag="?"		#  z or q channel
+block="CTHDR"  condition="isct"	offset="366"	intype="Int16_B"	inlength="1"	name="CT_refchan2"		dicomtype="?"	dicomtag="?"		#  Reference channel 1
+block="CTHDR"  condition="isct"	offset="368"	intype="Int16_B"	inlength="1"	name="CT_refchan3"		dicomtype="?"	dicomtag="?"		#  Reference channel 2
+block="CTHDR"  condition="isct"	offset="370"	intype="Int16_B"	inlength="1"	name="CT_refchan4"		dicomtype="?"	dicomtag="?"		#  Reference channel 3
+block="CTHDR"  condition="isct"	offset="372"	intype="Int16_B"	inlength="1"	name="CT_refchan5"		dicomtype="?"	dicomtag="?"		#  Reference channel 4
+block="CTHDR"  condition="isct"	offset="374"	intype="Int16_B"	inlength="1"	name="CT_refchan6"		dicomtype="?"	dicomtag="?"		#  Reference channel 5
+block="CTHDR"  condition="isct"	offset="376"	intype="Int16_B"	inlength="1"	name="CT_postproc"		dicomtype="?"	dicomtag="?"		#  Recon post processing flag
+block="CTHDR"  condition="isct"	offset="380"	intype="Int32_B"	inlength="1"	name="CT_xmpat"		dicomtype="?"	dicomtag="?"		#  DAS xm pattern
+block="CTHDR"  condition="isct"	offset="384"	intype="Int16_B"	inlength="1"	name="CT_rottyp"		dicomtype="?"	dicomtag="?"	bitmap="0:none,half scan(rotating);1:none,normal scan(rotating);2:none,over scan(rotating);3:none,stationary(stationary)"	#  Prescribed rotation type
+block="CTHDR"  condition="isct"	offset="386"	intype="Int16_B"	inlength="1"	name="CT_rawdataflag"	dicomtype="?"	dicomtag="?"		#  Save Raw Data Flag
+block="CTHDR"  condition="isct"	offset="388"	intype="IEEE_Float32_B"	inlength="1"	name="CT_ct_scalefact"	dicomtype="?"	dicomtag="?"		#  IBH Image scale factors
+block="CTHDR"  condition="isct"	offset="392"	intype="Int16_B"	inlength="1"	name="CT_ct_water_num"	dicomtype="?"	dicomtag="?"		#  CT Water Number
+block="CTHDR"  condition="isct"	offset="394"	intype="Int16_B"	inlength="1"	name="CT_ct_bone_num"	dicomtype="?"	dicomtag="?"		#  CT Bone Number
+block="CTHDR"  condition="isct"	offset="396"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bbh_coef1"		dicomtype="?"	dicomtag="?"		#  BBH coefficient 1
+block="CTHDR"  condition="isct"	offset="400"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bbh_coef2"		dicomtype="?"	dicomtag="?"		#  BBH coefficient 2
+block="CTHDR"  condition="isct"	offset="404"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bbh_coef3"		dicomtype="?"	dicomtag="?"		#  BBH coefficient 3
+block="CTHDR"  condition="isct"	offset="408"	intype="Int16_B"	inlength="1"	name="CT_bbh_numblend"	dicomtype="?"	dicomtag="?"		#  Num of BBH channels to blend
+block="CTHDR"  condition="isct"	offset="412"	intype="Int32_B"	inlength="1"	name="CT_firstchan"		dicomtype="?"	dicomtag="?"		#  Starting channel
+block="CTHDR"  condition="isct"	offset="416"	intype="Int32_B"	inlength="1"	name="CT_numchan"		dicomtype="?"	dicomtag="?"		#  Number of channels (1..512)
+block="CTHDR"  condition="isct"	offset="420"	intype="Int32_B"	inlength="1"	name="CT_chaninc"		dicomtype="?"	dicomtag="?"		#  Increment between channels
+block="CTHDR"  condition="isct"	offset="424"	intype="Int32_B"	inlength="1"	name="CT_firstview"		dicomtype="?"	dicomtag="?"		#  Starting view
+block="CTHDR"  condition="isct"	offset="428"	intype="Int32_B"	inlength="1"	name="CT_numview"		dicomtype="?"	dicomtag="?"		#  Number of views
+block="CTHDR"  condition="isct"	offset="432"	intype="Int32_B"	inlength="1"	name="CT_viewinc"		dicomtype="?"	dicomtag="?"		#  Increment between views
+block="CTHDR"  condition="isct"	offset="436"	intype="Int32_B"	inlength="1"	name="CT_windowrange"	dicomtype="?"	dicomtag="?"		#  Window Range (0..4095)
+block="CTHDR"  condition="isct"	offset="440"	intype="IEEE_Float32_B"	inlength="1"	name="CT_scalemin"		dicomtype="?"	dicomtag="?"		#  Scaling value of the image data
+block="CTHDR"  condition="isct"	offset="444"	intype="IEEE_Float32_B"	inlength="1"	name="CT_scalemax"		dicomtype="?"	dicomtag="?"		#  Scaling value of the image data
+block="CTHDR"  condition="isct"	offset="448"	intype="Int32_B"	inlength="1"	name="CT_datamod"		dicomtype="?"	dicomtag="?"	enum="1=Raw,2=Offset Corrected,3=Normalized"	#  Amount of processing that will be
+block="CTHDR"  condition="isct"	offset="452"	intype="String"	inlength="13"	name="CT_qcalfile"		dicomtype="?"	dicomtag="?"		#  Source of the qcal vectors
+block="CTHDR"  condition="isct"	offset="465"	intype="String"	inlength="13"	name="CT_calmodfile"		dicomtype="?"	dicomtag="?"		#  Source of the cal vectors
+block="CTHDR"  condition="isct"	offset="478"	intype="Int16_B"	inlength="1"	name="CT_wordsperview"	dicomtype="?"	dicomtag="?"		#  Number of words per view
+block="CTHDR"  condition="isct"	offset="480"	intype="String"	inlength="1"	name="CT_rl_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for side of image
+block="CTHDR"  condition="isct"	offset="481"	intype="String"	inlength="1"	name="CT_ap_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for anterior/posterior
+block="CTHDR"  condition="isct"	offset="482"	intype="String"	inlength="1"	name="CT_sctstr_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for scout start loc
+block="CTHDR"  condition="isct"	offset="483"	intype="String"	inlength="1"	name="CT_sctend_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for scout end loc
+block="CTHDR"  condition="isct"	offset="484"	intype="String"	inlength="3"	name="CT_sct_anref"		dicomtype="?"	dicomtag="?"		#  Anatomical reference for scout
+block="CTHDR"  condition="isct"	offset="488"	intype="Int16_B"	inlength="1"	name="CT_pps_scalwin"	dicomtype="?"	dicomtag="?"		#  PpScan window range for output Scaling
+block="CTHDR"  condition="isct"	offset="490"	intype="Int16_B"	inlength="1"	name="CT_pps_qcalflag"	dicomtype="?"	dicomtag="?"		#  PpScan Qcal modification flag
+block="CTHDR"  condition="isct"	offset="492"	intype="Int16_B"	inlength="1"	name="CT_pps_pcalflag"	dicomtype="?"	dicomtag="?"		#  PpScan Pcal modification flag
+block="CTHDR"  condition="isct"	offset="494"	intype="Int16_B"	inlength="1"	name="CT_pps_thetafix"	dicomtype="?"	dicomtag="?"		#  PpScan Theta Fix (Angle Correction)
+block="CTHDR"  condition="isct"	offset="496"	intype="Int16_B"	inlength="1"	name="CT_pps_bhflag"		dicomtype="?"	dicomtag="?"		#  PpScan Beam Hardening Flag
+block="CTHDR"  condition="isct"	offset="498"	intype="Int16_B"	inlength="1"	name="CT_spot_size"		dicomtype="?"	dicomtag="?"	enum="1=small,2=large"	#  tube focal spot size
+block="CTHDR"  condition="isct"	offset="500"	intype="Int16_B"	inlength="1"	name="CT_spot_pos"		dicomtype="?"	dicomtag="?"	enum="1=left,2=center,3=right"	#  tube focal spot position
+block="CTHDR"  condition="isct"	offset="502"	intype="Int16_B"	inlength="1"	name="CT_recondataset"	dicomtype="?"	dicomtag="?"	bitmap="0:none,half scan views;1:none,normal scan views;2:none,over scan views;3:none,variable views"	#  Dependent on number of views processed
+block="CTHDR"  condition="isct"	offset="504"	intype="Int16_B"	inlength="1"	name="CT_ndetcellsfov"	dicomtype="?"	dicomtag="?"		#  Field of view in detector cells
+block="CTHDR"  condition="isct"	offset="512"	intype="IEEE_Float64_B"	inlength="1"	name="CT_strtscantime"	dicomtype="?"	dicomtag="?"		#  Start time(secs) of this scan
+block="CTHDR"  condition="isct"	offset="520"	intype="Int16_B"	inlength="1"	keyword="CT_gandir"		dicomtype="?"	dicomtag="?"	enum="1=Clockwise:CW,2=CounterClockwise:CCW"	#  Gantry Rotation Direction
+block="CTHDR"  condition="isct"	offset="522"	intype="Int16_B"	inlength="1"	name="CT_rotorspeed"		dicomtype="?"	dicomtag="?"	enum="1=off,2=low,3=medium,4=high"	#  Tube Rotor Speed
+block="CTHDR"  condition="isct"	offset="524"	intype="Int16_B"	inlength="1"	name="CT_trigmode"		dicomtype="?"	dicomtag="?"	enum="1=Normal Trigger:XTTX,2=XRayoff Trigger:TT,3=TXXT,4=XXTT"	#  TGGC Trigger Mode
+block="CTHDR"  condition="isct"	offset="528"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sitilt"		dicomtype="?"	dicomtag="?"		#  Rx'd gantry tilt - not annotated
+block="CTHDR"  condition="isct"	offset="532"	intype="IEEE_Float32_B"	inlength="1"	name="CT_targcen_R"		dicomtype="?"	dicomtag="?"		#  R/L coordinate for target recon center
+block="CTHDR"  condition="isct"	offset="536"	intype="IEEE_Float32_B"	inlength="1"	name="CT_targcen_A"		dicomtype="?"	dicomtag="?"		#  A/P coordinate for target recon center
+block="CTHDR"  condition="isct"	offset="540"	intype="Int16_B"	inlength="1"	name="CT_backprojflag"	dicomtype="?"	dicomtag="?"		#  Value of Back Projection button
+block="CTHDR"  condition="isct"	offset="542"	intype="Int16_B"	inlength="1"	name="CT_fatqestflag"	dicomtype="?"	dicomtag="?"		#  Set if fatq estimates were used
+block="CTHDR"  condition="isct"	offset="544"	intype="IEEE_Float32_B"	inlength="1"	name="CT_zavg"		dicomtype="?"	dicomtag="?"		#  Z chan avg over views
+block="CTHDR"  condition="isct"	offset="548"	intype="IEEE_Float32_B"	inlength="1"	name="CT_leftrefavg"		dicomtype="?"	dicomtag="?"		#  avg of left ref chans over
+block="CTHDR"  condition="isct"	offset="552"	intype="IEEE_Float32_B"	inlength="1"	name="CT_leftrefmax"		dicomtype="?"	dicomtag="?"		#  max left chan value over views
+block="CTHDR"  condition="isct"	offset="556"	intype="IEEE_Float32_B"	inlength="1"	name="CT_rightrefavg"	dicomtype="?"	dicomtag="?"		#  avg of right ref chans over
+block="CTHDR"  condition="isct"	offset="560"	intype="IEEE_Float32_B"	inlength="1"	name="CT_rightrefmax"	dicomtype="?"	dicomtag="?"		#  max right chan value over views
+block="CTHDR"  condition="isct"	offset="564"	intype="String"	inlength="13"	name="CT_im_alloc_key"	dicomtype="?"	dicomtag="?"		#  process that last allocated this record
+block="CTHDR"  condition="isct"	offset="580"	intype="Unix_DateTime_B"	inlength="1"	keyword="CT_im_lastmod"		dicomtype="?"	dicomtag="?"		#  Date/Time of Last Change
+block="CTHDR"  condition="isct"	offset="584"	intype="String"	inlength="2"	name="CT_im_verscre"		dicomtype="?"	dicomtag="?"		#  Genesis version - Created
+block="CTHDR"  condition="isct"	offset="586"	intype="String"	inlength="2"	name="CT_im_verscur"		dicomtype="?"	dicomtag="?"		#  Genesis version - Now
+block="CTHDR"  condition="isct"	offset="588"	intype="Int32_B"	inlength="1"	name="CT_im_pds_a"		dicomtype="?"	dicomtag="?"		#  PixelData size - as stored
+block="CTHDR"  condition="isct"	offset="592"	intype="Int32_B"	inlength="1"	name="CT_im_pds_c"		dicomtype="?"	dicomtag="?"		#  PixelData size - Compressed
+block="CTHDR"  condition="isct"	offset="596"	intype="Int32_B"	inlength="1"	name="CT_im_pds_u"		dicomtype="?"	dicomtag="?"		#  PixelData size - UnCompressed
+block="CTHDR"  condition="isct"	offset="600"	intype="Uint32_B"	inlength="1"	name="CT_im_checksum"	dicomtype="?"	dicomtag="?"		#  AcqRecon record checksum
+block="CTHDR"  condition="isct"	offset="604"	intype="Int32_B"	inlength="1"	name="CT_im_archived"	dicomtype="?"	dicomtag="?"		#  Image Archive Flag
+block="CTHDR"  condition="isct"	offset="608"	intype="Int32_B"	inlength="1"	name="CT_im_complete"	dicomtype="?"	dicomtag="?"		#  Image Complete Flag
+block="CTHDR"  condition="isct"	offset="612"	intype="Int16_B"	inlength="1"	name="CT_biop_pos"		dicomtype="?"	dicomtag="?"	bitmap="0:none,superior;1:none,centered;2:none,inferior"	#  Biopsy Position
+block="CTHDR"  condition="isct"	offset="616"	intype="IEEE_Float32_B"	inlength="1"	name="CT_biop_tloc"		dicomtype="?"	dicomtag="?"		#  Biopsy T Location
+block="CTHDR"  condition="isct"	offset="620"	intype="IEEE_Float32_B"	inlength="1"	name="CT_biop_refloc"	dicomtype="?"	dicomtag="?"		#  Biopsy Ref Location
+block="CTHDR"  condition="isct"	offset="624"	intype="Int16_B"	inlength="1"	name="CT_ref_chan"		dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	#  Reference Channel Used
+block="CTHDR"  condition="isct"	offset="628"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bp_coef"		dicomtype="?"	dicomtag="?"		#  Back Projector Coefficient
+block="CTHDR"  condition="isct"	offset="632"	intype="Int16_B"	inlength="1"	name="CT_psc"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#  Primary Speed Correction Used
+block="CTHDR"  condition="isct"	offset="634"	intype="Int16_B"	inlength="1"	name="CT_overrng_corr"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#  Overrange Correction Used
+block="CTHDR"  condition="isct"	offset="636"	intype="IEEE_Float32_B"	inlength="1"	name="CT_dyn_z_alpha"	dicomtype="?"	dicomtag="?"		#  Dynamic Z Alpha Value
+block="CTHDR"  condition="isct"	offset="640"	intype="String"	inlength="1"	name="CT_ref_img"		dicomtype="?"	dicomtag="?"		#  Reference Image Field
+block="CTHDR"  condition="isct"	offset="641"	intype="String"	inlength="1"	name="CT_sum_img"		dicomtype="?"	dicomtag="?"		#  Summary Image Field
+block="CTHDR"  condition="isct"	offset="642"	intype="Uint16_B"	inlength="1"	name="CT_img_window"		dicomtype="?"	dicomtag="?"		#  Window Value
+block="CTHDR"  condition="isct"	offset="644"	intype="Int16_B"	inlength="1"	name="CT_img_level"		dicomtype="?"	dicomtag="?"		#  Level Value
+block="CTHDR"  condition="isct"	offset="648"	intype="Int32_B"	inlength="1"	name="CT_slop_int_1"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 1
+block="CTHDR"  condition="isct"	offset="652"	intype="Int32_B"	inlength="1"	name="CT_slop_int_2"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 2
+block="CTHDR"  condition="isct"	offset="656"	intype="Int32_B"	inlength="1"	name="CT_slop_int_3"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 3
+block="CTHDR"  condition="isct"	offset="660"	intype="Int32_B"	inlength="1"	name="CT_slop_int_4"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 4
+block="CTHDR"  condition="isct"	offset="664"	intype="Int32_B"	inlength="1"	name="CT_slop_int_5"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 5
+block="CTHDR"  condition="isct"	offset="668"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_1"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 1
+block="CTHDR"  condition="isct"	offset="672"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_2"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 2
+block="CTHDR"  condition="isct"	offset="676"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_3"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 3
+block="CTHDR"  condition="isct"	offset="680"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_4"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 4
+block="CTHDR"  condition="isct"	offset="684"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_5"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 5
+block="CTHDR"  condition="isct"	offset="688"	intype="String"	inlength="16"	name="CT_slop_str_1"		dicomtype="?"	dicomtag="?"		#  String Slop Field 1
+block="CTHDR"  condition="isct"	offset="704"	intype="String"	inlength="16"	name="CT_slop_str_2"		dicomtype="?"	dicomtag="?"		#  String Slop Field 2
+block="CTHDR"  condition="isct"	offset="720"	intype="IEEE_Float32_B"	inlength="1"	name="CT_deltastart"		dicomtype="?"	dicomtag="?"		#  Delta Start Time
+block="CTHDR"  condition="isct"	offset="724"	intype="Int32_B"	inlength="1"	name="CT_maxOverrange"	dicomtype="?"	dicomtag="?"		#  Max Overranges In A View
+block="CTHDR"  condition="isct"	offset="728"	intype="IEEE_Float32_B"	inlength="1"	name="CT_avgOverrange"	dicomtype="?"	dicomtag="?"		#  Avg Overranges All Views
+block="CTHDR"  condition="isct"	offset="732"	intype="Int16_B"	inlength="1"	name="CT_afterglow"		dicomtype="?"	dicomtag="?"	bitmap="0:PSC term off,PSC term on;1:Second term off,Second term on;2:Third term off,Third term on;3:Fourth term off,Fourth term on"	#  Corrected Afterglow Terms
+block="CTHDR"  condition="isct"	offset="734"	intype="Uint16_B"	inlength="1"	name="CT_z_blocked"		dicomtype="?"	dicomtag="?"		#  No Views z Channel Blocked
+block="CTHDR"  condition="isct"	offset="736"	intype="Uint16_B"	inlength="1"	name="CT_ref1_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref1 Channel Blocked
+block="CTHDR"  condition="isct"	offset="738"	intype="Uint16_B"	inlength="1"	name="CT_ref2_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref2 Channel Blocked
+block="CTHDR"  condition="isct"	offset="740"	intype="Uint16_B"	inlength="1"	name="CT_ref3_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref3 Channel Blocked
+block="CTHDR"  condition="isct"	offset="742"	intype="Uint16_B"	inlength="1"	name="CT_ref4_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref4 Channel Blocked
+block="CTHDR"  condition="isct"	offset="744"	intype="Uint16_B"	inlength="1"	name="CT_ref5_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref5 Channel Blocked
+block="CTHDR"  condition="isct"	offset="746"	intype="Int16_B"	inlength="1"	name="CT_integrity"		dicomtype="?"	dicomtag="?"	enum="0=GE Image,1=Imported Image"	#  GE Image Integrity
+block="CTHDR"  condition="isct"	offset="748"	intype="String"	inlength="8"	name="CT_pitchRatio"		dicomtype="?"	dicomtag="?"		#  Scan Pitch Ratio
+block="CTHDR"  condition="isct"	offset="756"	intype="String"	inlength="32"	name="CT_image_uid"		dicomtype="?"	dicomtag="?"		#  Image Unique ID
+block="CTHDR"  condition="isct"	offset="788"	intype="String"	inlength="32"	name="CT_sop_uid"		dicomtype="?"	dicomtag="?"		#  Service Obj Class Unique ID
+block="CTHDR"  condition="isct"	offset="820"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xraydelay"		dicomtype="?"	dicomtag="?"		#  Start Scan To XRay On Delay
+block="CTHDR"  condition="isct"	offset="824"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xrayduration"	dicomtype="?"	dicomtag="?"		#  Duration Of XRay On
+block="CTHDR"  condition="isct"	offset="828"	intype="String"	inlength="223"	name="CT_ct_padding"		dicomtype="?"	dicomtag="?"		#  Spare Space
+block="MRHDR"  condition="ismr"	offset="0"	intype="String"	inlength="4"	name="MR_im_suid"		dicomtype="?"	dicomtag="?"		#  Suite id for this image
+block="MRHDR"  condition="ismr"	offset="4"	intype="Int16_B"	inlength="1"	name="MR_im_uniq"		dicomtype="?"	dicomtag="?"		#  The Make-Unique Flag
+block="MRHDR"  condition="ismr"	offset="6"	intype="String"	inlength="1"	name="MR_im_diskid"		dicomtype="?"	dicomtag="?"		#  Disk ID for this Image
+block="MRHDR"  condition="ismr"	offset="8"	intype="Uint16_B"	inlength="1"	name="MR_im_exno"		dicomtype="?"	dicomtag="?"		#  Exam number for this image
+block="MRHDR"  condition="ismr"	offset="10"	intype="Int16_B"	inlength="1"	name="MR_im_seno"		dicomtype="?"	dicomtag="?"		#  Series Number for this image
+block="MRHDR"  condition="ismr"	offset="12"	intype="Int16_B"	inlength="1"	keyword="MR_im_no"		dicomtype="IS"	dicomtag="InstanceNumber"	#  Image Number
+block="MRHDR"  condition="ismr"	offset="16"	intype="Unix_DateTime_B"	inlength="1"	keyword="MR_im_datetime"	dicomtype="?"	dicomtag="?"		#  Allocation Image date/time stamp
+block="MRHDR"  condition="ismr"	offset="20"	intype="Unix_DateTime_B"	inlength="1"	keyword="MR_im_actual_dt"	dicomtype="?"	dicomtag="?"		#  Actual Image date/time stamp
+block="MRHDR"  condition="ismr"	offset="24"	intype="IEEE_Float32_B"	inlength="1"	name="MR_sctime"		dicomtype="?"	dicomtag="?"		#  Duration of scan (secs)
+block="MRHDR"  condition="ismr"	offset="28"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slthick"		dicomtype="DS"	dicomtag="SliceThickness"	#  Slice Thickness (mm)
+block="MRHDR"  condition="ismr"	offset="32"	intype="Int16_B"	inlength="1"	keyword="MR_imatrix_X"		dicomtype="?"	dicomtag="?"		#  Image matrix size - X
+block="MRHDR"  condition="ismr"	offset="34"	intype="Int16_B"	inlength="1"	keyword="MR_imatrix_Y"		dicomtype="?"	dicomtag="?"		#  Image matrix size - Y
+block="MRHDR"  condition="ismr"	offset="36"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dfov"		dicomtype="?"	dicomtag="?"		#  Display field of view - X (mm)
+block="MRHDR"  condition="ismr"	offset="40"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dfov_rect"		dicomtype="?"	dicomtag="?"		#  Display field of view - Y (if different)
+block="MRHDR"  condition="ismr"	offset="44"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dim_X"		dicomtype="?"	dicomtag="?"		#  Image dimension - X
+block="MRHDR"  condition="ismr"	offset="48"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dim_Y"		dicomtype="?"	dicomtag="?"		#  Image dimension - Y
+block="MRHDR"  condition="ismr"	offset="52"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_pixsize_X"		dicomtype="?"	dicomtag="?"	#  Image pixel size - X
+block="MRHDR"  condition="ismr"	offset="56"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_pixsize_Y"		dicomtype="?"	dicomtag="?"	#  Image pixel size - Y
+block="MRHDR"  condition="ismr"	offset="60"	intype="String"	inlength="14"	name="MR_pdid"		dicomtype="?"	dicomtag="?"		#  Pixel Data ID
+block="MRHDR"  condition="ismr"	offset="74"	intype="String"	inlength="17"	name="MR_contrastIV"		dicomtype="?"	dicomtag="?"		#  IV Contrast Agent
+block="MRHDR"  condition="ismr"	offset="91"	intype="String"	inlength="17"	name="MR_contrastOral"	dicomtype="?"	dicomtag="?"		#  Oral Contrast Agent
+block="MRHDR"  condition="ismr"	offset="108"	intype="Int16_B"	inlength="1"	name="MR_contmode"		dicomtype="?"	dicomtag="?"	bitmap="0:none,oral;1:none,intravenous"	#  Image Contrast Mode
+block="MRHDR"  condition="ismr"	offset="110"	intype="Int16_B"	inlength="1"	name="MR_serrx"		dicomtype="?"	dicomtag="?"		#  Series from which prescribed
+block="MRHDR"  condition="ismr"	offset="112"	intype="Int16_B"	inlength="1"	name="MR_imgrx"		dicomtype="?"	dicomtag="?"		#  Image from which prescribed
+block="MRHDR"  condition="ismr"	offset="114"	intype="Int16_B"	inlength="1"	name="MR_screenformat"	dicomtype="?"	dicomtag="?"		#  Screen Format(8/16 bit)
+block="MRHDR"  condition="ismr"	offset="116"	intype="Int16_B"	inlength="1"	name="MR_plane"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Scout Plane(SCT);1:none,Axial Plane(Ax);2:none,Sagittal Plane(Sag);3:none,Coronal Plane(Cor);4:none,Oblique Plane(O);5:none,ParAxial Plane(PAX);6:none,Reformatted Plane(RFMT);7:none,Projected Plane(PJN);8:none,Mixed Plane(MIXED)"	#  Plane Type
+block="MRHDR"  condition="ismr"	offset="120"	intype="IEEE_Float32_B"	inlength="1"	name="MR_scanspacing"	dicomtype="DS"	dicomtag="SpacingBetweenSlices"	#  Spacing between scans (mm?)
+block="MRHDR"  condition="ismr"	offset="124"	intype="Int16_B"	inlength="1"	name="MR_im_compress"	dicomtype="?"	dicomtag="?"		#  Image compression type for allocation
+block="MRHDR"  condition="ismr"	offset="126"	intype="Int16_B"	inlength="1"	name="MR_im_scouttype"	dicomtype="?"	dicomtag="?"		#  Scout Type (AP or lateral)
+block="MRHDR"  condition="ismr"	offset="128"	intype="String"	inlength="1"	name="MR_loc_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter of image location
+block="MRHDR"  condition="ismr"	offset="132"	intype="IEEE_Float32_B"	inlength="1"	name="MR_loc"		dicomtype="DS"	dicomtag="SliceLocation"	#  Image location
+block="MRHDR"  condition="ismr"	offset="136"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_ctr_R"		dicomtype="?"	dicomtag="?"		#  Center R coord of plane image
+block="MRHDR"  condition="ismr"	offset="140"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_ctr_A"		dicomtype="?"	dicomtag="?"		#  Center A coord of plane image
+block="MRHDR"  condition="ismr"	offset="144"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_ctr_S"		dicomtype="?"	dicomtag="?"		#  Center S coord of plane image
+block="MRHDR"  condition="ismr"	offset="148"	intype="IEEE_Float32_B"	inlength="1"	name="MR_norm_R"		dicomtype="?"	dicomtag="?"		#  Normal R coord
+block="MRHDR"  condition="ismr"	offset="152"	intype="IEEE_Float32_B"	inlength="1"	name="MR_norm_A"		dicomtype="?"	dicomtag="?"		#  Normal A coord
+block="MRHDR"  condition="ismr"	offset="156"	intype="IEEE_Float32_B"	inlength="1"	name="MR_norm_S"		dicomtype="?"	dicomtag="?"		#  Normal S coord
+block="MRHDR"  condition="ismr"	offset="160"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_tlhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Left Hand Corner
+block="MRHDR"  condition="ismr"	offset="164"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_tlhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Left Hand Corner
+block="MRHDR"  condition="ismr"	offset="168"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_tlhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Left Hand Corner
+block="MRHDR"  condition="ismr"	offset="172"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_trhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="176"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_trhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="180"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_trhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="184"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_brhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Bottom Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="188"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_brhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Bottom Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="192"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_brhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Bottom Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="196"	intype="String"	inlength="4"	name="MR_forimgrev"		dicomtype="?"	dicomtag="?"		#  Foreign Image Revision
+block="MRHDR"  condition="ismr"	offset="200"	intype="Int32_B"	inlength="1"	keyword="MR_tr"			dicomtype="?"	dicomtag="?"		#  Pulse repetition time(usec)
+block="MRHDR"  condition="ismr"	offset="204"	intype="Int32_B"	inlength="1"	keyword="MR_ti"			dicomtype="?"	dicomtag="?"		#  Pulse inversion time(usec)
+block="MRHDR"  condition="ismr"	offset="208"	intype="Int32_B"	inlength="1"	keyword="MR_te"			dicomtype="?"	dicomtag="?"		#  Pulse echo time(usec)
+block="MRHDR"  condition="ismr"	offset="212"	intype="Int32_B"	inlength="1"	name="MR_te2"			dicomtype="?"	dicomtag="?"		#  Second echo echo (usec)
+block="MRHDR"  condition="ismr"	offset="216"	intype="Int16_B"	inlength="1"	name="MR_numecho"		dicomtype="?"	dicomtag="?"	#  Number of echoes
+block="MRHDR"  condition="ismr"	offset="218"	intype="Int16_B"	inlength="1"	name="MR_echonum"		dicomtype="IS"	dicomtag="EchoNumbers"	#  Echo Number
+block="MRHDR"  condition="ismr"	offset="220"	intype="IEEE_Float32_B"	inlength="1"	name="MR_tbldlta"		dicomtype="?"	dicomtag="?"		#  Table Delta
+block="MRHDR"  condition="ismr"	offset="224"	intype="IEEE_Float32_B"	inlength="1"	name="MR_nex"		dicomtype="DS"	dicomtag="NumberOfAverages"	#  Number of Excitations
+block="MRHDR"  condition="ismr"	offset="228"	intype="Int16_B"	inlength="1"	name="MR_contig"		dicomtype="?"	dicomtag="?"	enum="0=No:/I,1=Yes:/C"	#  Continuous Slices Flag
+block="MRHDR"  condition="ismr"	offset="230"	intype="Int16_B"	inlength="1"	name="MR_hrtrate"		dicomtype="IS"	dicomtag="HeartRate"	#  Cardiac Heart Rate (bpm)
+block="MRHDR"  condition="ismr"	offset="232"	intype="Int32_B"	inlength="1"	name="MR_tdel"		dicomtype="?"	dicomtag="?"		#  Delay time after trigger (msec)
+block="MRHDR"  condition="ismr"	offset="236"	intype="IEEE_Float32_B"	inlength="1"	name="MR_saravg"		dicomtype="DS"	dicomtag="SAR"		#  Average SAR
+block="MRHDR"  condition="ismr"	offset="240"	intype="IEEE_Float32_B"	inlength="1"	name="MR_sarpeak"		dicomtype="?"	dicomtag="?"		#  Peak SAR
+block="MRHDR"  condition="ismr"	offset="244"	intype="Int16_B"	inlength="1"	name="MR_monsar"		dicomtype="?"	dicomtag="?"		#  Monitor SAR flag
+block="MRHDR"  condition="ismr"	offset="246"	intype="Int16_B"	inlength="1"	name="MR_trgwindow"		dicomtype="IS"	dicomtag="TriggerWindow"	#  Trigger window (% of R-R interval)
+block="MRHDR"  condition="ismr"	offset="248"	intype="IEEE_Float32_B"	inlength="1"	name="MR_reptime"		dicomtype="?"	dicomtag="?"		#  Cardiac repetition time
+block="MRHDR"  condition="ismr"	offset="252"	intype="Int16_B"	inlength="1"	name="MR_imgpcyc"		dicomtype="IS"	dicomtag="CardiacNumberOfImages"	#  Images per cardiac cycle
+block="MRHDR"  condition="ismr"	offset="254"	intype="Int16_B"	inlength="1"	name="MR_xmtgain"		dicomtype="?"	dicomtag="?"		#  Actual Transmit Gain (.1 db)
+block="MRHDR"  condition="ismr"	offset="256"	intype="Int16_B"	inlength="1"	name="MR_rcvgain1"		dicomtype="?"	dicomtag="?"		#  Actual Receive Gain Analog (.1 db)
+block="MRHDR"  condition="ismr"	offset="258"	intype="Int16_B"	inlength="1"	name="MR_rcvgain2"		dicomtype="?"	dicomtag="?"		#  Actual Receive Gain Digital (.1 db)
+block="MRHDR"  condition="ismr"	offset="260"	intype="Int16_B"	inlength="1"	name="MR_mr_flip"		dicomtype="DS"	dicomtag="FlipAngle"	#  Flip Angle for GRASS scans (deg.)
+block="MRHDR"  condition="ismr"	offset="264"	intype="Int32_B"	inlength="1"	name="MR_mindat"		dicomtype="?"	dicomtag="?"		#  Minimum Delay after Trigger (uSec)
+block="MRHDR"  condition="ismr"	offset="268"	intype="Int16_B"	inlength="1"	name="MR_cphase"		dicomtype="?"	dicomtag="?"		#  Total Cardiac Phase prescribed
+block="MRHDR"  condition="ismr"	offset="270"	intype="Int16_B"	inlength="1"	keyword="MR_swappf"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:SPF"	#  Swap Phase/Frequency Axis
+block="MRHDR"  condition="ismr"	offset="272"	intype="Int16_B"	inlength="1"	name="MR_pauseint"		dicomtype="?"	dicomtag="?"		#  Pause Interval (slices)
+block="MRHDR"  condition="ismr"	offset="276"	intype="IEEE_Float32_B"	inlength="1"	name="MR_pausetime"		dicomtype="?"	dicomtag="?"		#  Pause Time
+block="MRHDR"  condition="ismr"	offset="280"	intype="Int32_B"	inlength="1"	name="MR_obplane"		dicomtype="?"	dicomtag="?"		#  Oblique Plane
+block="MRHDR"  condition="ismr"	offset="284"	intype="Int32_B"	inlength="1"	name="MR_slocfov"		dicomtype="?"	dicomtag="?"		#  Slice Offsets on Freq axis
+block="MRHDR"  condition="ismr"	offset="288"	intype="Int32_B"	inlength="1"	keyword="MR_xmtfreq"		dicomtype="?"	dicomtag="?"		#  Center Frequency (0.1 Hz)
+block="MRHDR"  condition="ismr"	offset="292"	intype="Int32_B"	inlength="1"	name="MR_autoxmtfreq"	dicomtype="?"	dicomtag="?"		#  Auto Center Frequency (0.1 Hz)
+block="MRHDR"  condition="ismr"	offset="296"	intype="Int16_B"	inlength="1"	name="MR_autoxmtgain"	dicomtype="?"	dicomtag="?"		#  Auto Transmit Gain (0.1 dB)
+block="MRHDR"  condition="ismr"	offset="298"	intype="Int16_B"	inlength="1"	name="MR_prescan_r1"		dicomtype="?"	dicomtag="?"		#  PreScan R1 - Analog
+block="MRHDR"  condition="ismr"	offset="300"	intype="Int16_B"	inlength="1"	name="MR_prescan_r2"		dicomtype="?"	dicomtag="?"		#  PreScan R2 - Digital
+block="MRHDR"  condition="ismr"	offset="304"	intype="Int32_B"	inlength="1"	name="MR_user_bitmap"	dicomtype="?"	dicomtag="?"		#  Bitmap defining user CVs
+block="MRHDR"  condition="ismr"	offset="308"	intype="Int16_B"	inlength="1"	name="MR_cenfreq"		dicomtype="?"	dicomtag="?"		#  Center Frequency Method
+block="MRHDR"  condition="ismr"	offset="310"	intype="Int16_B"	inlength="1"	keyword="MR_imode"		dicomtype="?"	dicomtag="?"	enum="1=Two D:2D,2=Three D Volume:3D,3=Three D Fourier:none,4=Cine:Cine,5=Angiography:ANGIO,6=Spectroscopy:SPECT,7=Flouroscopy:FLOURO,8=Research Mode:RM"	#  Imaging Mode
+block="MRHDR"  condition="ismr"	offset="312"	intype="Int32_B"	inlength="1"	keyword="MR_iopt"		dicomtype="?"	dicomtag="?"	bitmap="0:none,EG;1:none,RESP;2:none,RC;3:none,FC;4:none,CL;5:none,ST;6:none,PG;7:none,NP;8:none,NF;9:none,RT;10:none,VB;11:none,ED;12:none,PM;13:none,SQ;14:none,CS;15:none,MP;16:none,SQPIX"	#  Imaging Options
+block="MRHDR"  condition="ismr"	offset="316"	intype="Int16_B"	inlength="1"	keyword="MR_pseq"		dicomtype="?"	dicomtag="?"	enum="0=SE,1=IR,2=RM:RM,3=RMGE:none,4=GRE:GR,5=MPGR,6=MPIRS:IR/s,7=MPIRI:IR,8=VOGRE:3D/GR,9=CINEGRE:Cine/GRE,10=SPGR,11=SSFP,12=TF:TOF,13=PC,14=CINSPGR:Cine/SPGR,15=TOFGR:TOG/GR,16=TOFSPGR:TOF/SPGR,17=PCGR:PC/GR,18=PCSPGR:PC/SPGR,19=FSE,20=FGR,21=FMPGR,22=FSPGR,23=FMPSPGR,24=SPECT,25=PSEQ_MIXED:MIXED,26=FMPIR,27=SPECSTEAM,28=SPECPRESS"	#  Pulse Sequence
+block="MRHDR"  condition="ismr"	offset="318"	intype="Int16_B"	inlength="1"	name="MR_pseqmode"		dicomtype="?"	dicomtag="?"	enum="1=Product,2=Research Mode,3=Research Mode GE"	#  Pulse Sequence Mode
+block="MRHDR"  condition="ismr"	offset="320"	intype="String"	inlength="33"	name="MR_psdname"		dicomtype="SH"	dicomtag="SequenceName"		#  Pulse Sequence Name
+block="MRHDR"  condition="ismr"	offset="356"	intype="Unix_DateTime_B"	inlength="1"	name="MR_psd_datetime"		dicomtype="?"	dicomtag="?"		#  PSD Creation Date and Time
+block="MRHDR"  condition="ismr"	offset="360"	intype="String"	inlength="13"	name="MR_psd_iname"		dicomtype="?"	dicomtag="?"		#  PSD name from inside PSD
+block="MRHDR"  condition="ismr"	offset="374"	intype="Int16_B"	inlength="1"	name="MR_ctyp"			dicomtype="?"	dicomtag="?"	enum="1=head,2=body,3=surface"	#  Coil Type
+block="MRHDR"  condition="ismr"	offset="376"	intype="String"	inlength="17"	name="MR_cname"			dicomtype="SH"	dicomtag="ReceiveCoilName"	#  Coil Name
+block="MRHDR"  condition="ismr"	offset="394"	intype="Int16_B"	inlength="1"	name="MR_surfctyp"		dicomtype="?"	dicomtag="?"		#  Surface Coil Type
+block="MRHDR"  condition="ismr"	offset="396"	intype="Int16_B"	inlength="1"	name="MR_surfcext"		dicomtype="?"	dicomtag="?"		#  Extremity Coil Flag
+block="MRHDR"  condition="ismr"	offset="400"	intype="Int32_B"	inlength="1"	name="MR_rawrunnum"		dicomtype="IS"	dicomtag="AcquisitionNumber"		#  RawData Run Number
+block="MRHDR"  condition="ismr"	offset="404"	intype="Uint32_B"	inlength="1"	name="MR_cal_fldstr"		dicomtype="?"	dicomtag="?"		#  Calibrated Field Strength (x10 uGauss)
+block="MRHDR"  condition="ismr"	offset="408"	intype="Int16_B"	inlength="1"	keyword="MR_supp_tech"		dicomtype="?"	dicomtag="?"	enum="0=none,1=fat:F,2=water:W"	#  SAT fat/water/none
+block="MRHDR"  condition="ismr"	offset="412"	intype="IEEE_Float32_B"	inlength="1"	name="MR_vbw"			dicomtype="?"	dicomtag="?"		#  Variable Bandwidth (Hz)
+block="MRHDR"  condition="ismr"	offset="416"	intype="Int16_B"	inlength="1"	name="MR_slquant"		dicomtype="?"	dicomtag="?"		#  Number of slices in this scan group
+block="MRHDR"  condition="ismr"	offset="418"	intype="Int16_B"	inlength="1"	name="MR_gpre"			dicomtype="?"	dicomtag="?"	enum="0=No GRX,1=GRX 1 localizer,2=GRX 2 localizers"	#  Graphically prescribed
+block="MRHDR"  condition="ismr"	offset="420"	intype="Int32_B"	inlength="1"	name="MR_intr_del"		dicomtype="?"	dicomtag="?"		#  Interimage/interloc delay (uSec)
+block="MRHDR"  condition="ismr"	offset="424"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user0"		dicomtype="?"	dicomtag="?"		#  User Variable 0
+block="MRHDR"  condition="ismr"	offset="428"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user1"		dicomtype="?"	dicomtag="?"		#  User Variable 1
+block="MRHDR"  condition="ismr"	offset="432"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user2"		dicomtype="?"	dicomtag="?"		#  User Variable 2
+block="MRHDR"  condition="ismr"	offset="436"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user3"		dicomtype="?"	dicomtag="?"		#  User Variable 3
+block="MRHDR"  condition="ismr"	offset="440"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user4"		dicomtype="?"	dicomtag="?"		#  User Variable 4
+block="MRHDR"  condition="ismr"	offset="444"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user5"		dicomtype="?"	dicomtag="?"		#  User Variable 5
+block="MRHDR"  condition="ismr"	offset="448"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user6"		dicomtype="?"	dicomtag="?"		#  User Variable 6
+block="MRHDR"  condition="ismr"	offset="452"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user7"		dicomtype="?"	dicomtag="?"		#  User Variable 7
+block="MRHDR"  condition="ismr"	offset="456"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user8"		dicomtype="?"	dicomtag="?"		#  User Variable 8
+block="MRHDR"  condition="ismr"	offset="460"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user9"		dicomtype="?"	dicomtag="?"		#  User Variable 9
+block="MRHDR"  condition="ismr"	offset="464"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user10"		dicomtype="?"	dicomtag="?"		#  User Variable 10
+block="MRHDR"  condition="ismr"	offset="468"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user11"		dicomtype="?"	dicomtag="?"		#  User Variable 11
+block="MRHDR"  condition="ismr"	offset="472"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user12"		dicomtype="?"	dicomtag="?"		#  User Variable 12
+block="MRHDR"  condition="ismr"	offset="476"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user13"		dicomtype="?"	dicomtag="?"		#  User Variable 13
+block="MRHDR"  condition="ismr"	offset="480"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user14"		dicomtype="?"	dicomtag="?"		#  User Variable 14
+block="MRHDR"  condition="ismr"	offset="484"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user15"		dicomtype="?"	dicomtag="?"		#  User Variable 15
+block="MRHDR"  condition="ismr"	offset="488"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user16"		dicomtype="?"	dicomtag="?"		#  User Variable 16
+block="MRHDR"  condition="ismr"	offset="492"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user17"		dicomtype="?"	dicomtag="?"		#  User Variable 17
+block="MRHDR"  condition="ismr"	offset="496"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user18"		dicomtype="?"	dicomtag="?"		#  User Variable 18
+block="MRHDR"  condition="ismr"	offset="500"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user19"		dicomtype="?"	dicomtag="?"		#  User Variable 19
+block="MRHDR"  condition="ismr"	offset="504"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user20"		dicomtype="?"	dicomtag="?"		#  User Variable 20
+block="MRHDR"  condition="ismr"	offset="508"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user21"		dicomtype="?"	dicomtag="?"		#  User Variable 21
+block="MRHDR"  condition="ismr"	offset="512"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user22"		dicomtype="?"	dicomtag="?"		#  User Variable 22
+block="MRHDR"  condition="ismr"	offset="516"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user23"		dicomtype="?"	dicomtag="?"		#  Projection Angle
+block="MRHDR"  condition="ismr"	offset="520"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user24"		dicomtype="?"	dicomtag="?"		#  Concat Sat Type Flag
+block="MRHDR"  condition="ismr"	offset="524"	intype="String"	inlength="13"	name="MR_im_alloc_key"	dicomtype="?"	dicomtag="?"			#  Process that allocated this record
+block="MRHDR"  condition="ismr"	offset="540"	intype="Unix_DateTime_B"	inlength="1"	keyword="MR_im_lastmod"		dicomtype="?"	dicomtag="?"		#  Date/Time of Last Change
+block="MRHDR"  condition="ismr"	offset="544"	intype="String"	inlength="2"	name="MR_im_verscre"		dicomtype="?"	dicomtag="?"		#  Genesis version - Created
+block="MRHDR"  condition="ismr"	offset="546"	intype="String"	inlength="2"	name="MR_im_verscur"		dicomtype="?"	dicomtag="?"		#  Genesis version - Now
+block="MRHDR"  condition="ismr"	offset="548"	intype="Int32_B"	inlength="1"	name="MR_im_pds_a"		dicomtype="?"	dicomtag="?"		#  PixelData size - as stored
+block="MRHDR"  condition="ismr"	offset="552"	intype="Int32_B"	inlength="1"	name="MR_im_pds_c"		dicomtype="?"	dicomtag="?"		#  PixelData size -Compressed
+block="MRHDR"  condition="ismr"	offset="556"	intype="Int32_B"	inlength="1"	name="MR_im_pds_u"		dicomtype="?"	dicomtag="?"		#  PixelData size -UnCompressed
+block="MRHDR"  condition="ismr"	offset="560"	intype="Uint32_B"	inlength="1"	name="MR_im_checksum"		dicomtype="?"	dicomtag="?"		#  AcqRecon record checksum
+block="MRHDR"  condition="ismr"	offset="564"	intype="Int32_B"	inlength="1"	name="MR_im_archived"		dicomtype="?"	dicomtag="?"		#  Image Archive Flag
+block="MRHDR"  condition="ismr"	offset="568"	intype="Int32_B"	inlength="1"	name="MR_im_complete"		dicomtype="?"	dicomtag="?"		#  Image Complete Flag
+block="MRHDR"  condition="ismr"	offset="572"	intype="Int16_B"	inlength="1"	keyword="MR_satbits"		dicomtype="?"	dicomtag="?"	bitmap="0:none,superior(S);1:none,inferior(I);2:none,right(R);3:none,left(R);4:none,anterior(A);5:none,posterior(P);6:none,superior(s);7:none,inferior(i);8:none,right(r);9:none,left(l);10:none,anterior(a);11:none,posterior(p)"	#  Bitmap of SAT selections
+block="MRHDR"  condition="ismr"	offset="574"	intype="Int16_B"	inlength="1"	keyword="MR_scic"		dicomtype="?"	dicomtag="?"	enum="0=Off,1=On:IIC"	#  Surface Coil Intensity Correction Flag
+block="MRHDR"  condition="ismr"	offset="576"	intype="Int16_B"	inlength="1"	name="MR_satxloc1"		dicomtype="?"	dicomtag="?"		#  R-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="578"	intype="Int16_B"	inlength="1"	name="MR_satxloc2"		dicomtype="?"	dicomtag="?"		#  L-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="580"	intype="Int16_B"	inlength="1"	name="MR_satyloc1"		dicomtype="?"	dicomtag="?"		#  A-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="582"	intype="Int16_B"	inlength="1"	name="MR_satyloc2"		dicomtype="?"	dicomtag="?"		#  P-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="584"	intype="Int16_B"	inlength="1"	name="MR_satzloc1"		dicomtype="?"	dicomtag="?"		#  S-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="586"	intype="Int16_B"	inlength="1"	name="MR_satzloc2"		dicomtype="?"	dicomtag="?"		#  I-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="588"	intype="Int16_B"	inlength="1"	name="MR_satxthick"		dicomtype="?"	dicomtag="?"		#  Thickness of X-axis SAT pulse
+block="MRHDR"  condition="ismr"	offset="590"	intype="Int16_B"	inlength="1"	name="MR_satythick"		dicomtype="?"	dicomtag="?"		#  Thickness of Y-axis SAT pulse
+block="MRHDR"  condition="ismr"	offset="592"	intype="Int16_B"	inlength="1"	name="MR_satzthick"		dicomtype="?"	dicomtag="?"		#  Thickness of Z-axis SAT pulse
+block="MRHDR"  condition="ismr"	offset="594"	intype="Int16_B"	inlength="1"	keyword="MR_flax"		dicomtype="?"	dicomtag="?"	bitmap="0:none,S/I;1:none,A/P;2:none,R/L;3:none,SLC"	#  Phase contrast flow axis
+block="MRHDR"  condition="ismr"	offset="596"	intype="Int16_B"	inlength="1"	name="MR_venc"		dicomtype="?"	dicomtag="?"		#  Phase contrast velocity encoding
+block="MRHDR"  condition="ismr"	offset="598"	intype="Int16_B"	inlength="1"	name="MR_thk_disclmr"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#  Slice Thickness Disclaimer
+block="MRHDR"  condition="ismr"	offset="600"	intype="Int16_B"	inlength="1"	name="MR_ps_flag"		dicomtype="?"	dicomtag="?"	bitmap="0:none,AF(a);1:none,AS(A);2:none,M(M)"	#  Auto/Manual Prescan flag
+block="MRHDR"  condition="ismr"	offset="602"	intype="Int16_B"	inlength="1"	name="MR_ps_status"		dicomtype="?"	dicomtag="?"	bitmap="0:none,CF;1:none,TA;2:none,R1;3:none,R2"	#  Bitmap of changed values
+block="MRHDR"  condition="ismr"	offset="604"	intype="Int16_B"	inlength="1"	keyword="MR_image_type"		dicomtype="?"	dicomtag="?"	enum="0=Magnitude,1=Phase:PHASE,2=Real:REAL,3=Imaginary:IMAGINARY,4=Spectroscopy:SPECTRO"	#  Magnitude, Phase, Imaginary,Real,Spectroscopy
+block="MRHDR"  condition="ismr"	offset="606"	intype="Int16_B"	inlength="1"	keyword="MR_vas_collapse"	dicomtype="?"	dicomtag="?"	enum="0=Off,1=:COL,2=:MAG,3=:R/L,4=:A/P,5=:S/I,6=:PJN,7=:ALL"	#  Collapse Image
+block="MRHDR"  condition="ismr"	offset="608"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user23n"		dicomtype="?"	dicomtag="?"		#  User Variable 23
+block="MRHDR"  condition="ismr"	offset="612"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user24n"		dicomtype="?"	dicomtag="?"		#  User Variable 24
+block="MRHDR"  condition="ismr"	offset="616"	intype="Int16_B"	inlength="1"	keyword="MR_proj_alg"	dicomtype="?"	dicomtag="?"	enum="0=None,1=Prototype,2=Minimum Pixel:Min,3=Maximum Pixel:Max"	#  Projection Algorithm
+block="MRHDR"  condition="ismr"	offset="618"	intype="String"	inlength="13"	name="MR_proj_name"		dicomtype="?"	dicomtag="?"		#  Projection Algorithm Name
+block="MRHDR"  condition="ismr"	offset="632"	intype="IEEE_Float32_B"	inlength="1"	name="MR_x_axis_rot"		dicomtype="?"	dicomtag="?"		#  X Axis Rotation
+block="MRHDR"  condition="ismr"	offset="636"	intype="IEEE_Float32_B"	inlength="1"	name="MR_y_axis_rot"		dicomtype="?"	dicomtag="?"		#  Y Axis Rotation
+block="MRHDR"  condition="ismr"	offset="640"	intype="IEEE_Float32_B"	inlength="1"	name="MR_z_axis_rot"		dicomtype="?"	dicomtag="?"		#  Z Axis Rotation
+block="MRHDR"  condition="ismr"	offset="644"	intype="Int32_B"	inlength="1"	name="MR_thresh_min1"	dicomtype="?"	dicomtag="?"		#  Lower Range of Pixels 1
+block="MRHDR"  condition="ismr"	offset="648"	intype="Int32_B"	inlength="1"	name="MR_thresh_max1"	dicomtype="?"	dicomtag="?"		#  Upper Range of Pixels 1
+block="MRHDR"  condition="ismr"	offset="652"	intype="Int32_B"	inlength="1"	name="MR_thresh_min2"	dicomtype="?"	dicomtag="?"		#  Lower Range of Pixels 2
+block="MRHDR"  condition="ismr"	offset="656"	intype="Int32_B"	inlength="1"	name="MR_thresh_max2"	dicomtype="?"	dicomtag="?"		#  Upper Range of Pixels 2
+block="MRHDR"  condition="ismr"	offset="660"	intype="Int16_B"	inlength="1"	keyword="MR_echo_trn_len"	dicomtype="?"	dicomtag="?"		#  Echo Train Length for Fast Spin Echo
+block="MRHDR"  condition="ismr"	offset="662"	intype="Int16_B"	inlength="1"	keyword="MR_frac_echo"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Fractional(Fr);1:none,Effective(Ef)"	#  Effective TE Flag
+block="MRHDR"  condition="ismr"	offset="664"	intype="Int16_B"	inlength="1"	keyword="MR_prep_pulse"		dicomtype="?"	dicomtag="?"	enum="0=None,1=Inversion Recovery:IR,2=Driven Equilibrium:DE"	#  Preparatory Pulse Option
+block="MRHDR"  condition="ismr"	offset="666"	intype="Int16_B"	inlength="1"	name="MR_cphasenum"		dicomtype="?"	dicomtag="?"		#  Cardiac Phase Number
+block="MRHDR"  condition="ismr"	offset="668"	intype="Int16_B"	inlength="1"	keyword="MR_var_echo"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:/V"	#  Variable Echo Flag
+block="MRHDR"  condition="ismr"	offset="670"	intype="String"	inlength="1"	name="MR_ref_img"		dicomtype="?"	dicomtag="?"		#  Reference Image Field
+block="MRHDR"  condition="ismr"	offset="671"	intype="String"	inlength="1"	name="MR_sum_img"		dicomtype="?"	dicomtag="?"		#  Summary Image Field
+block="MRHDR"  condition="ismr"	offset="672"	intype="Uint16_B"	inlength="1"	name="MR_img_window"		dicomtype="?"	dicomtag="?"		#  Window Value
+block="MRHDR"  condition="ismr"	offset="674"	intype="Int16_B"	inlength="1"	name="MR_img_level"		dicomtype="?"	dicomtag="?"		#  Level Value
+block="MRHDR"  condition="ismr"	offset="676"	intype="Int32_B"	inlength="1"	name="MR_slop_int_1"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 1
+block="MRHDR"  condition="ismr"	offset="680"	intype="Int32_B"	inlength="1"	name="MR_slop_int_2"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 2
+block="MRHDR"  condition="ismr"	offset="684"	intype="Int32_B"	inlength="1"	name="MR_slop_int_3"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 3
+block="MRHDR"  condition="ismr"	offset="688"	intype="Int32_B"	inlength="1"	name="MR_slop_int_4"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 4
+block="MRHDR"  condition="ismr"	offset="692"	intype="Int32_B"	inlength="1"	name="MR_slop_int_5"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 5
+block="MRHDR"  condition="ismr"	offset="696"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_1"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 1
+block="MRHDR"  condition="ismr"	offset="700"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_2"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 2
+block="MRHDR"  condition="ismr"	offset="704"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_3"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 3
+block="MRHDR"  condition="ismr"	offset="708"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_4"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 4
+block="MRHDR"  condition="ismr"	offset="712"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_5"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 5
+block="MRHDR"  condition="ismr"	offset="716"	intype="String"		inlength="16"	name="MR_slop_str_1"		dicomtype="?"	dicomtag="?"		#  String Slop Field 1
+block="MRHDR"  condition="ismr"	offset="732"	intype="String"		inlength="16"	name="MR_slop_str_2"		dicomtype="?"	dicomtag="?"		#  String Slop Field 2
+block="MRHDR"  condition="ismr"	offset="748"	intype="Int16_B"	inlength="1"	name="MR_scanactno"		dicomtype="?"	dicomtag="?"		#  Scan Acquisition Number
+block="MRHDR"  condition="ismr"	offset="750"	intype="Int16_B"	inlength="1"	name="MR_vasflags"		dicomtype="?"	dicomtag="?"	bitmap="0:none,NOFLAGS;1:none,MAGWEIGHT;2:none,CD RECON;3:none,PD RECON;4:none,PHASECOR OFF"	#  Magnitude Weighting Flag
+block="MRHDR"  condition="ismr"	offset="752"	intype="IEEE_Float32_B"	inlength="1"	name="MR_vencscale"		dicomtype="?"	dicomtag="?"		#  Scale Weighted Venc
+block="MRHDR"  condition="ismr"	offset="756"	intype="Int16_B"	inlength="1"	name="MR_integrity"		dicomtype="?"	dicomtag="?"	enum="0=GE Image,1=Imported Image"	#  GE Image Integrity
+block="MRHDR"  condition="ismr"	offset="760"	intype="Int32_B"	inlength="1"	name="MR_fphase"		dicomtype="?"	dicomtag="?"		#  Number Of Phases
+block="MRHDR"  condition="ismr"	offset="764"	intype="Int16_B"	inlength="1"	name="MR_freq_dir"		dicomtype="?"	dicomtag="?"	enum="0=Unknown,1=Row,2=Col"	#  Frequency Direction
+block="MRHDR"  condition="ismr"	offset="766"	intype="Int16_B"	inlength="1"	name="MR_vas_mode"		dicomtype="?"	dicomtag="?"	num="0=None,1=TOF,2=PC"	#  Vascular Mode
+block="MRHDR"  condition="ismr"	offset="768"	intype="String"		inlength="32"	name="MR_image_uid"		dicomtype="?"	dicomtag="?"		#  Image Unique ID
+block="MRHDR"  condition="ismr"	offset="800"	intype="String"		inlength="32"	name="MR_sop_uid"		dicomtype="?"	dicomtag="?"		#  Service Obj Class Unique ID
+block="MRHDR"  condition="ismr"	offset="832"	intype="String"		inlength="212"	name="MR_mr_padding"		dicomtype="?"	dicomtag="?"		#  Spare Space
+
+constant="16" 							dicomtype="US"	dicomtag="BitsAllocated"		#
+constant="1" 							dicomtype="US"	dicomtag="PixelRepresentation"		# Signed
+constant="1" 							dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 						dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="1" 							dicomtype="DS"	dicomtag="RescaleSlope"			# 
+constant="US" 				condition="ismr"	dicomtype="LO"	dicomtag="RescaleType"			# 
+constant="HU" 				condition="isct"	dicomtype="LO"	dicomtag="RescaleType"			# 
+constant="0" 							dicomtype="XS"	dicomtag="PixelPaddingValue"		# 
+constant=""							dicomtype="SH"	dicomtag="AccessionNumber"		# 
+constant=""							dicomtype="DA"	dicomtag="PatientBirthDate"		# 
+constant="GE Medical Systems"					dicomtype="LO"	dicomtag="Manufacturer"			# 
+constant="1.2.840.10008.5.1.4.1.1.4"	condition="ismr"	dicomtype="UI"	dicomtag="SOPClassUID"			# 
+constant="1.2.840.10008.5.1.4.1.1.2"	condition="isct"	dicomtype="UI"	dicomtag="SOPClassUID"			# 
+
diff --git a/libsrc/src/dconvert/gaw/gawcl.h b/libsrc/src/dconvert/gaw/gawcl.h
new file mode 100644
index 0000000..b5033dd
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawcl.h
@@ -0,0 +1,31 @@
+/* gawcl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "gawinfo.h"
+#include "gawhdrp.h"
+#include "gawhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class GAW_Header_BothClass : public GAW_HeaderClass
+{
+	GAW_FileStructureInformation fileinfo;
+public:
+	GAW_Header_BothClass(istream *ist,GAW_FileStructureInformation &info)
+		: GAW_HeaderClass(ist,info)
+		{
+			fileinfo=info;
+		}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/gaw/gawconv.cc b/libsrc/src/dconvert/gaw/gawconv.cc
new file mode 100644
index 0000000..bd08678
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "gawdc.h"
+#include "gawptrs.h"
+#include "gawconv.h"
diff --git a/libsrc/src/dconvert/gaw/gawdc.cc b/libsrc/src/dconvert/gaw/gawdc.cc
new file mode 100644
index 0000000..afbae9c
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawdc.cc
@@ -0,0 +1,96 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawdc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gawdc.h"
+#include "gaw.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "gawsrc.h"
+
+bool
+GAW_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!gawhdr) gawhdr=new GAW_Header_BothClass(in,fileinfo);
+	Assert(gawhdr);
+
+	gawhdr->ToDicom_Template(list);
+	gawhdr->ToDicom_ManualMisc(list);
+	gawhdr->ToDicom_ManualPlane(list);
+	gawhdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in gaw.h about the importance of the scope
+// of a GAW_Conversion object and AttributeList object
+
+bool
+GAW_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!gawhdr) gawhdr=new GAW_Header_BothClass(in,fileinfo);
+	Assert(gawhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	// Manually expand the offsets
+
+	pixeldatasrc=new GAW_PixelDataSource(
+		*in,
+		GAW_Offset_FILEHDR_ptr+gawhdr->GAW_HeaderInstance_FILEHDR->IH_img_hdr_length
+			 + (fileinfo.pixelDataLengthFieldPresent ? 4 : 0),
+		GAW_Offset_FILEHDR_ptr+gawhdr->GAW_HeaderInstance_FILEHDR->IH_img_p_unpack,
+		gawhdr->GAW_HeaderInstance_FILEHDR->IH_img_l_unpack,
+		gawhdr->GAW_HeaderInstance_FILEHDR->IH_img_compress,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+GAW_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/gaw/gawdc.h b/libsrc/src/dconvert/gaw/gawdc.h
new file mode 100644
index 0000000..b77ff7c
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawdc.h
@@ -0,0 +1,7 @@
+/* gawdc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "gawcl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "gawptrs.h"
diff --git a/libsrc/src/dconvert/gaw/gawdmp.cc b/libsrc/src/dconvert/gaw/gawdmp.cc
new file mode 100644
index 0000000..905d62e
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawdmp.cc
@@ -0,0 +1,23 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gawdmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "gaw.h"
+
+bool
+GAW_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!gawhdr) gawhdr=new GAW_Header_BothClass(in,fileinfo);
+	Assert(gawhdr);
+
+	TextOutputStream out(o);
+
+	gawhdr->DumpCommon(&out);
+
+	return true;
+}
+
+
diff --git a/libsrc/src/dconvert/gaw/gawdmp.h b/libsrc/src/dconvert/gaw/gawdmp.h
new file mode 100644
index 0000000..df9f0b2
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawdmp.h
@@ -0,0 +1,4 @@
+/* gawdmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "gawcl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/gaw/gawdmpf.cc b/libsrc/src/dconvert/gaw/gawdmpf.cc
new file mode 100644
index 0000000..f31bac4
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawdmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawdmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gawdmp.h"
+#include "gawptrs.h"
+#include "gawdmpf.h"
diff --git a/libsrc/src/dconvert/gaw/gawhdrc.cc b/libsrc/src/dconvert/gaw/gawhdrc.cc
new file mode 100644
index 0000000..e4ecaed
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawhdrc.cc
@@ -0,0 +1,8 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "gawinfo.h"
+#include "gawptrs.h"
+#include "gawhdrp.h"
+#include "gawhdrw.h"
+#include "gawhdrc.h"
+
diff --git a/libsrc/src/dconvert/gaw/gawinfo.h b/libsrc/src/dconvert/gaw/gawinfo.h
new file mode 100644
index 0000000..f9869c1
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawinfo.h
@@ -0,0 +1,45 @@
+/* gawinfo.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_gawinfo__
+#define __Header_gawinfo__
+
+class GAW_FileStructureInformation  {
+public:
+	bool useExplicitOffsets;
+	bool pixelDataLengthFieldPresent;
+	Uint32 explicitFileHdrPtr;
+	Uint32 explicitSuiteHdrPtr;
+	Uint32 explicitExamHdrPtr;
+	Uint32 explicitSeriesHdrPtr;
+	Uint32 explicitImageHdrPtr;
+
+	GAW_FileStructureInformation(void)
+		{
+			useExplicitOffsets=false;
+			pixelDataLengthFieldPresent=false;
+			explicitFileHdrPtr=0;
+			explicitSuiteHdrPtr=0;
+			explicitExamHdrPtr=0;
+			explicitSeriesHdrPtr=0;
+			explicitImageHdrPtr=0;
+		}
+
+	GAW_FileStructureInformation(
+			bool explicitoff,
+			bool lengthpresent,
+			Uint32 fileptr,
+			Uint32 suiteptr,
+			Uint32 examptr,
+			Uint32 seriesptr,
+			Uint32 imageptr)
+		{
+			useExplicitOffsets=explicitoff;
+			pixelDataLengthFieldPresent=lengthpresent;
+			explicitFileHdrPtr=fileptr;
+			explicitSuiteHdrPtr=suiteptr;
+			explicitExamHdrPtr=examptr;
+			explicitSeriesHdrPtr=seriesptr;
+			explicitImageHdrPtr=imageptr;
+		}
+};
+
+#endif // __Header_gawinfo__
diff --git a/libsrc/src/dconvert/gaw/gawmdt.cc b/libsrc/src/dconvert/gaw/gawmdt.cc
new file mode 100644
index 0000000..a6f9b0a
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawmdt.cc
@@ -0,0 +1,112 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gawdc.h"
+#include "elmconst.h"
+
+void 
+GAW_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// ? should use EX_ex_lastmod ?
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),
+		Date(DateTime(GAW_HeaderInstance_EXAMHDR->EX_ex_datetime)));
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),
+		Time(DateTime(GAW_HeaderInstance_EXAMHDR->EX_ex_datetime)));
+
+	// ? should use SE_se_actual_dt ? SE_se_lastmod ?
+
+	// SeriesDate
+
+	(*list)+=new DateStringAttribute(TagFromName(SeriesDate),
+		Date(DateTime(GAW_HeaderInstance_SERIESHDR->SE_se_datetime)));
+
+	// SeriesTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(SeriesTime),
+		Time(DateTime(GAW_HeaderInstance_SERIESHDR->SE_se_datetime)));
+
+	// ? should use im_datetime ? im_lastmod ? im_actual_dt ?
+
+	// ContentDate (formerly Image)
+
+	if (GAW_isct)
+		(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+			Date(DateTime(GAW_HeaderInstance_CTHDR->CT_im_lastmod)));
+	else if (GAW_ismr)
+		(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+			Date(DateTime(GAW_HeaderInstance_MRHDR->MR_im_lastmod)));
+
+	// ContentTime (formerly Image)
+
+	if (GAW_isct)
+		(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+			Time(DateTime(GAW_HeaderInstance_CTHDR->CT_im_lastmod)));
+	else if (GAW_ismr)
+		(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+			Time(DateTime(GAW_HeaderInstance_MRHDR->MR_im_lastmod)));
+
+	// AcquisitionDate
+
+	if (GAW_isct)
+		(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),
+			Date(DateTime(GAW_HeaderInstance_CTHDR->CT_im_datetime)));
+	else if (GAW_ismr)
+		(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),
+			Date(DateTime(GAW_HeaderInstance_MRHDR->MR_im_datetime)));
+
+	// AcquisitionTime
+
+	if (GAW_isct)
+		(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),
+			Time(DateTime(GAW_HeaderInstance_CTHDR->CT_im_datetime)));
+	else if (GAW_ismr)
+		(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),
+			Time(DateTime(GAW_HeaderInstance_MRHDR->MR_im_datetime)));
+
+	{
+		// PatientSex
+
+		const char *str;
+		switch (GAW_HeaderInstance_EXAMHDR->EX_patsex) {
+			case 1:		str="M"; break;
+			case 2:		str="F"; break;
+			default:	str="";  break;
+		}
+
+		(*list)+=new CodeStringAttribute(TagFromName(PatientSex),str);
+	}
+
+	{
+		// PatientAge
+
+		ostrstream ost;
+		ost << setfill('0') << setw(3) << dec
+		    << GAW_HeaderInstance_EXAMHDR->EX_patage;
+		switch (GAW_HeaderInstance_EXAMHDR->EX_patian) {
+			case 0:	ost << "Y"; break;
+			case 1:	ost << "M"; break;
+			case 2:	ost << "D"; break;
+			case 3:	ost << "W"; break;
+		}
+		ost << ends;
+		char *agestr=ost.str();
+		if (agestr) {
+			if (strlen(agestr))
+				(*list)+=new AgeStringAttribute(
+					TagFromName(PatientAge),agestr);
+			delete[] agestr;
+		}
+	}
+
+	// PatientWeight
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PatientWeight),
+		Uint32(GAW_HeaderInstance_EXAMHDR->EX_patweight)/1000.0);
+}
+
diff --git a/libsrc/src/dconvert/gaw/gawmmsc.cc b/libsrc/src/dconvert/gaw/gawmmsc.cc
new file mode 100644
index 0000000..202a122
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawmmsc.cc
@@ -0,0 +1,632 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gawdc.h"
+#include "elmconst.h"
+
+void 
+GAW_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	{
+		//    Rows = IH_img_height ? IH_img_height : CT_ or MR_imatrix_Y
+		// Columns = IH_img_width  ? IH_img_width  : CT_ or MR_imatrix_X
+
+//		Uint16    rows = GAW_HeaderInstance_FILEHDR->IH_img_height
+//			? (Uint16)GAW_HeaderInstance_FILEHDR->IH_img_height
+//			: (GAW_ismr
+
+		Uint16 rows = (GAW_ismr
+				? GAW_HeaderInstance_MRHDR->MR_imatrix_Y
+				: GAW_HeaderInstance_CTHDR->CT_imatrix_Y);
+
+//		Uint16 columns = GAW_HeaderInstance_FILEHDR->IH_img_width  
+//			? (Uint16)GAW_HeaderInstance_FILEHDR->IH_img_width  
+//			: (GAW_ismr
+
+		Uint16 columns = (GAW_ismr
+				? GAW_HeaderInstance_MRHDR->MR_imatrix_X
+				: GAW_HeaderInstance_CTHDR->CT_imatrix_X);
+
+		(*list)+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+		(*list)+=new UnsignedShortAttribute(TagFromName(Columns),columns);
+	}
+
+	{
+		// BitsStored = depth
+		// HighBit = depth - 1
+
+		Uint16 depth;
+#ifdef GENESISUSEDEPTHVALUE
+		if (GAW_hashisto && Uint16(GAW_HeaderInstance_HISTOHDR->HS_hs_max) < 4096u)
+			depth=12;
+		else if (GAW_HeaderInstance_FILEHDR->IH_img_depth)
+			depth=GAW_HeaderInstance_FILEHDR->IH_img_depth;
+		else
+#endif
+			depth=16;
+
+		(*list)+=new UnsignedShortAttribute(TagFromName(BitsStored),depth);
+		(*list)+=new UnsignedShortAttribute(TagFromName(HighBit),depth-1);
+	}
+
+	// ContrastBolus Module
+
+	{
+		bool oral=false;
+		const char *oralagent=0;
+		bool iv=false;
+		const char *ivagent=0;
+
+		if (GAW_ismr) {
+			if (GAW_HeaderInstance_MRHDR->MR_contmode & 0x1)
+				oral=true;
+			if (GAW_HeaderInstance_MRHDR->MR_contmode & 0x2)
+				iv=true;
+			oralagent=GAW_HeaderInstance_MRHDR->MR_contrastOral;
+			ivagent=GAW_HeaderInstance_MRHDR->MR_contrastIV;
+		}
+		if (GAW_isct) {
+			if (GAW_HeaderInstance_CTHDR->CT_contmode & 0x1)
+				oral=true;
+			if (GAW_HeaderInstance_CTHDR->CT_contmode & 0x2)
+				iv=true;
+			oralagent=GAW_HeaderInstance_CTHDR->CT_contrastOral;
+			ivagent=GAW_HeaderInstance_CTHDR->CT_contrastIV;
+		}
+
+		// NB. VM of ContrastBolusAgent, etc. is 1 :(
+
+		ostrstream oContrastBolusAgent;
+		ostrstream oContrastBolusRoute;
+
+		if (oral) {
+			oContrastBolusAgent <<
+			    (strlen(oralagent) ? oralagent : "ORAL AGENT UNKNOWN");
+			oContrastBolusRoute << "ORAL";
+		}
+		if (oral && iv) {
+			oContrastBolusAgent << " AND ";
+			oContrastBolusRoute << " AND ";
+		}
+		if (iv) {
+			oContrastBolusAgent <<
+			    (strlen(ivagent) ? ivagent : "IV AGENT UNKNOWN");
+			oContrastBolusRoute << "IV";
+		}
+		oContrastBolusAgent << ends;
+		oContrastBolusRoute << ends;
+		char *ContrastBolusAgent=oContrastBolusAgent.str();
+		char *sContrastBolusRoute=oContrastBolusRoute.str();
+
+		if (ContrastBolusAgent) {
+			if (strlen(ContrastBolusAgent)) {
+				(*list)+=new
+					LongStringAttribute(
+						TagFromName(ContrastBolusAgent),
+						ContrastBolusAgent);
+			}
+			delete[] ContrastBolusAgent;
+		}
+
+		if (sContrastBolusRoute) {
+			if (strlen(sContrastBolusRoute)) {
+				(*list)+=new
+					LongStringAttribute(
+						TagFromName(ContrastBolusRoute),
+						sContrastBolusRoute);
+			}
+			delete[] sContrastBolusRoute;
+		}
+	}
+
+	{
+		// ImageType
+
+		const char *value1,*value2,*value3;
+
+		switch (GAW_HeaderInstance_SERIESHDR->SE_se_typ) {
+			case 1:		// Prospective
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					if (GAW_isct) value3="AXIAL";
+					if (GAW_ismr) value3="OTHER";
+					break;
+			case 2:		// Retrospective
+					value1="ORIGINAL";
+					value2="SECONDARY";
+					if (GAW_isct) value3="AXIAL";
+					if (GAW_ismr) value3="OTHER";
+					break;
+			case 3:		// Scout
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="LOCALIZER";	// CT IOD
+					break;
+			case 4:		// Reformatted
+			case 5:		// Screensave
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="OTHER";		// MR IOD
+					break;
+			case 6:		// Xenon
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="AXIAL";		// CT IOD
+			case 7:		// Service
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="OTHER";		// MR IOD
+					break;
+			case 9:		// Projected
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="PROJECTION IMAGE"; // MR IOD
+					break;
+			default:
+					value1="UNKNOWN";
+					value2="UNKNOWN";
+					value3="UNKNOWN";
+					break;
+		}
+
+		(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+				value1,value2,value3);
+	}
+
+	if (GAW_isct) {
+		// ConvolutionKernel
+
+		const char *str;
+
+		// supposed to be a bitmap - we will assume enum :(
+
+		switch (GAW_HeaderInstance_CTHDR->CT_reconalg) {
+			case 1:		str="SMOOTH";
+					break;
+			case 2:		str="SOFT";
+					break;
+			case 4:		str="STANDARD";
+					break;
+			case 8:		str="DETAIL";
+					break;
+			case 16:	str="BONE";
+					break;
+			case 32:	str="EDGE";
+					break;
+			case 64:	str="SHARP";
+					break;
+			case 128:	str="EXP2";
+					break;
+			default:	str="UNKNOWN";
+					break;
+		}
+
+		// could also utilize CT_perisflag & CT_iboneflag ??
+
+		(*list)+=new ShortStringAttribute(TagFromName(ConvolutionKernel),str);
+
+		// FilterType
+
+		switch (GAW_HeaderInstance_CTHDR->CT_filttyp) {
+			case 1:		str="AIR"; break;
+			case 2:		str="BODY"; break;
+			case 3:		str="BOWTIE:ADLT HEAD"; break;
+			case 4:		str="FLAT"; break;
+			case 5:		str="HI:ADULT HEAD/HF"; break;
+			default:	str="UNKNOWN"; break;
+		}
+		(*list)+=new ShortStringAttribute(TagFromName(FilterType),str);
+
+		// RotationDirection
+
+		switch (GAW_HeaderInstance_CTHDR->CT_gandir) {
+			case 1:		str="CW"; break;
+			case 2:		str="CC"; break;
+			default:	str="UNKNOWN"; break;
+		}
+		(*list)+=new
+			ShortStringAttribute(TagFromName(RotationDirection),
+				str);
+
+		// ExposureTime
+		// Exposure
+
+		(*list)+=new
+			IntegerStringAttribute(TagFromName(ExposureTime),
+				Uint32(GAW_HeaderInstance_CTHDR->CT_sctime*1000.0));
+		(*list)+=new
+			IntegerStringAttribute(TagFromName(Exposure),
+				Uint32(GAW_HeaderInstance_CTHDR->CT_sctime
+					*GAW_HeaderInstance_CTHDR->CT_mamp));
+
+		// DistanceSourceToDetector
+		// DistanceSourceToPatient
+
+		// (these are here rather than in template to avoid inclusion in MR)
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(DistanceSourceToDetector),
+				GAW_HeaderInstance_EXAMHDR->EX_srctodet);
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(DistanceSourceToPatient),
+				GAW_HeaderInstance_EXAMHDR->EX_srctoiso);
+	}
+
+	if (GAW_ismr) {
+		// MagneticFieldStrength - Tesla
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(MagneticFieldStrength),
+				Uint32(GAW_HeaderInstance_EXAMHDR->EX_magstrength)/10000.0);
+
+		// ImagingFrequency MHz (Genesis is in .1 Hz)
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(ImagingFrequency),
+				Uint32(GAW_HeaderInstance_MRHDR->MR_xmtfreq)/10000000.0);
+
+		// RepetitionTime
+		// EchoTime
+		// InversionTime
+
+		Uint32 tr_us=GAW_HeaderInstance_MRHDR->MR_tr;
+		if (tr_us) (*list)+=new
+			DecimalStringAttribute(TagFromName(RepetitionTime),
+				tr_us/1000.0);
+
+
+		Uint32 te_us=GAW_HeaderInstance_MRHDR->MR_te;
+		if (te_us) (*list)+=new
+			DecimalStringAttribute(TagFromName(EchoTime),
+				te_us/1000.0);
+
+
+		Uint32 ti_us=GAW_HeaderInstance_MRHDR->MR_ti;
+		if (ti_us) (*list)+=new
+			DecimalStringAttribute(TagFromName(InversionTime),
+				ti_us/1000.0);
+
+		double sctime_fd=GAW_HeaderInstance_MRHDR->MR_sctime;
+		if (sctime_fd) (*list)+=new
+			FloatDoubleAttribute(TagFromName(AcquisitionDuration),
+				sctime_fd/1000000.0);
+
+		// EchoTrainLength
+
+		unsigned etl=GAW_HeaderInstance_MRHDR->MR_echo_trn_len;
+		unsigned numecho=GAW_HeaderInstance_MRHDR->MR_numecho;
+		unsigned useetl = etl ? etl : numecho;
+
+		if (useetl) (*list)+=new
+			IntegerStringAttribute(TagFromName(EchoTrainLength),
+				Uint32(useetl));
+	}
+
+	if (GAW_ismr) {
+		// ScanningSequence
+		// SequenceVariant
+		// ScanOptions
+
+		CodeStringAttribute *ScanningSequence =
+			new CodeStringAttribute(TagFromName(ScanningSequence));
+
+		CodeStringAttribute *SequenceVariant =
+			new CodeStringAttribute(TagFromName(SequenceVariant));
+
+		CodeStringAttribute *ScanOptions =
+			new CodeStringAttribute(TagFromName(ScanOptions));
+
+		switch (GAW_HeaderInstance_MRHDR->MR_pseq) {
+			case 0:			// SE
+					ScanningSequence->addValue("SE");
+					break;
+			case 1:			// IR
+					ScanningSequence->addValue("IR");
+					break;
+			case 2:			// RM:RM
+					ScanningSequence->addValue("RM");
+					break;
+			case 3:			// RMGE:none
+					ScanningSequence->addValue("RM");
+					break;
+			case 4:			// GRE:GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 5:			// MPGR
+					ScanningSequence->addValue("GR");
+					break;
+			case 6:			// MPIRS:IR/s
+					ScanningSequence->addValue("IR");
+					break;
+			case 7:			// MPIRI:IR
+					ScanningSequence->addValue("IR");
+					break;
+			case 8:			// VOGRE:3D/GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 9:			// CINEGRE:Cine/GRE
+					ScanningSequence->addValue("GR");
+					break;
+			case 10:		// SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 11:		// SSFP
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("TRSS");
+					break;
+			case 12:		// TF:TOF
+					ScanningSequence->addValue("GR");
+					break;
+			case 13:		// PC
+					ScanningSequence->addValue("GR");
+					break;
+			case 14:		// CINSPGR:Cine/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 15:		// TOFGR:TOG/GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 16:		// TOFSPGR:TOF/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 17:		// PCGR:PC/GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 18:		// PCSPGR:PC/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 19:		// FSE
+					ScanningSequence->addValue("SE");
+					SequenceVariant->addValue("SK");
+					break;
+			case 20:		// FGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 21:		// FMPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 22:		// FSPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					SequenceVariant->addValue("SK");
+					break;
+			case 23:		// FMPSPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					SequenceVariant->addValue("SK");
+					break;
+			case 24:		// SPECT
+					break;
+			case 25:		// PSEQ_MIXED:MIXED
+					break;
+			default:	break;
+		}
+
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<0)) {	// EG - ECG Gated
+			ScanOptions->addValue("CG");
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<1)) {	// RESP - Resp Gated
+			ScanOptions->addValue("RG");
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<2)) {	// RC - Resp Compensated
+			ScanOptions->addValue("PER");
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<3)) {	// FC - Flow Compensated
+			ScanOptions->addValue("FC");
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<4)) {	// CL
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<5)		// ST - Sat parameters
+		 || GAW_HeaderInstance_MRHDR->MR_satbits) {		// if any sat bits set
+			ScanOptions->addValue("SP");			// spatial presaturation
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<6)) {	// PG - Periph Gated
+			ScanOptions->addValue("PPG");
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<7)) {	// NP - No Phase Wrap
+			SequenceVariant->addValue("OSP");
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<8)) {	// NF - ?
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<9)) {	// RT - Rect FOV
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<10)) {	// VB - Var Bandwidth
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<11)) {	// ED - Ext Dynamic Rng
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<12)) {	// PM - POMP
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<13)) {	// SQ - ?
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<14)) {	// CS - Contig Slice
+		}
+		if (GAW_HeaderInstance_MRHDR->MR_iopt & (1<<15)) {	// MP - Multiplanar
+		}
+
+		switch (GAW_HeaderInstance_MRHDR->MR_supp_tech) {
+			case 1:
+				ScanOptions->addValue("FS");		// fat saturation
+				break;
+			case 2:
+				ScanOptions->addValue("WS");		// water saturation
+				break;					// not DICOM def term
+			default:
+				break;
+		}
+
+		if (GAW_HeaderInstance_MRHDR->MR_scic) {
+			ScanOptions->addValue("IIC");			// intensity correction
+		}							// not DICOM def term
+
+		if (GAW_HeaderInstance_MRHDR->MR_frac_echo & 1<<0) {
+			ScanOptions->addValue("PFF");			// partial fourier freq
+		}
+
+		switch (GAW_HeaderInstance_MRHDR->MR_prep_pulse) {
+			case 1:						// Inversion Recovery:IR
+			case 2:						// Driven Equilibrium:DE
+				SequenceVariant->addValue("MP");	// mag prepared
+				break;
+			default:
+				break;
+		}
+
+		if (!SequenceVariant->getVM())
+			SequenceVariant->addValue("NONE");
+
+		(*list)+=ScanningSequence;
+		(*list)+=SequenceVariant;
+		(*list)+=ScanOptions;
+	}
+
+	if (GAW_ismr) {
+		// MRAcquisitionType
+
+		const char *str;
+		switch(GAW_HeaderInstance_MRHDR->MR_imode) {
+			case 1:			// Two D:2D
+				str="2D";
+				break;
+			case 2:			// Three D Volume:3D
+			case 3:			// Three D Fourier:
+				str="3D";
+				break;
+			case 4:			// Cine:Cine
+			case 5:			// Angiography:ANGIO
+			case 6:			// Spectroscopy:SPECT
+			case 7:			// Flouroscopy:FLOURO
+			case 8:			// Research Mode:RM
+			default:
+				str="UNKNOWN";
+				break;
+		}
+		(*list)+=new CodeStringAttribute(TagFromName(MRAcquisitionType),str);
+	}
+
+	if (GAW_ismr) {
+		// InPlanePhaseEncodingDirection
+
+		const char *str;
+
+		//if (GAW_HeaderInstance_MRHDR->MR_swappf)	// Swap Phase/Frequency:SPF
+		//	str="COL";
+		//else
+		//	str="ROW";
+		//(*list)+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),str);
+
+		if (GAW_HeaderInstance_MRHDR->MR_freq_dir == 1)
+			str="COL";
+		else if (GAW_HeaderInstance_MRHDR->MR_freq_dir == 2
+		      || GAW_HeaderInstance_MRHDR->MR_freq_dir == 0)	// assume "unknown" is row
+			str="ROW";
+		else
+			str=0;
+
+		if (str)
+			(*list)+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),str);
+	}
+
+	if (GAW_ismr) {
+		// Acquisition Matrix
+
+		Uint16 freq_rows=0;
+		Uint16 freq_cols=0;
+		Uint16 phase_rows=0;
+		Uint16 phase_cols=0;
+
+		if (GAW_HeaderInstance_MRHDR->MR_freq_dir == 1) {
+			freq_rows=GAW_HeaderInstance_MRHDR->MR_dim_X;
+			phase_cols=GAW_HeaderInstance_MRHDR->MR_dim_Y;
+		}
+		else if (GAW_HeaderInstance_MRHDR->MR_freq_dir == 2
+		      || GAW_HeaderInstance_MRHDR->MR_freq_dir == 0) {	// assume "unknown" is row
+			freq_cols=GAW_HeaderInstance_MRHDR->MR_dim_X;
+			phase_rows=GAW_HeaderInstance_MRHDR->MR_dim_Y;
+		}
+
+		if (freq_rows || freq_cols || phase_rows || phase_cols) {
+			Attribute *a=new UnsignedShortAttribute(TagFromName(AcquisitionMatrix));
+			Assert(a);
+			a->addValue(freq_rows);
+			a->addValue(freq_cols);
+			a->addValue(phase_rows);
+			a->addValue(phase_cols);
+			(*list)+=a;
+		}
+	}
+
+	if (GAW_ismr) {
+		// Number Of Phase Encoding Steps
+
+		(*list)+=new IntegerStringAttribute(TagFromName(NumberOfPhaseEncodingSteps),(Uint32)GAW_HeaderInstance_MRHDR->MR_dim_Y);
+	}
+	
+	if (GAW_ismr) {
+		// MRAcquisitionPhaseEncodingStepsOutOfPlane (from new multiframe MR object)
+
+		if (GAW_HeaderInstance_MRHDR->MR_imode == 2		// 3D mode
+		 && GAW_HeaderInstance_MRHDR->MR_slquant > 0) {		// Number of slices in this scan group
+			(*list)+=new UnsignedShortAttribute(TagFromName(MRAcquisitionPhaseEncodingStepsOutOfPlane),(Uint16)GAW_HeaderInstance_MRHDR->MR_slquant);
+		}
+	}
+	
+	if (GAW_ismr) {
+		// AngioFlag
+
+		bool angio;
+		switch (GAW_HeaderInstance_MRHDR->MR_pseq) {
+			case 12:		// TF:TOF
+			case 13:		// PC
+			case 15:		// TOFGR:TOG/GR
+			case 16:		// TOFSPGR:TOF/SPGR
+			case 17:		// PCGR:PC/GR
+			case 18:		// PCSPGR:PC/SPGR
+				angio=true;
+				break;
+			default:
+				angio=false;
+				break;
+		}
+
+		bool projected;
+		switch (GAW_HeaderInstance_MRHDR->MR_proj_alg) {
+			case 0:			// none
+				projected=false;
+				break;
+			case 1:			// Prototype
+			case 2:			// Minimum Pixel:Min
+			case 3:			// Maximum Pixel:Max
+			default:
+				projected=true;
+				break;
+		}
+
+		// if any bits set ...
+
+		bool collapsed = GAW_HeaderInstance_MRHDR->MR_vas_collapse;
+
+		if (angio) {
+			const char *str;
+			if (!collapsed && !projected)
+				str="Y";
+			else
+				str="N";
+			(*list)+=new CodeStringAttribute(TagFromName(AngioFlag),str);
+		}
+		// else leave it out
+	}
+
+	if (GAW_ismr && GAW_HeaderInstance_MRHDR->MR_vbw != 0) {
+		// PixelBandwidth
+
+		(*list)+=new DecimalStringAttribute(TagFromName(PixelBandwidth),(Float32)GAW_HeaderInstance_MRHDR->MR_vbw*2*1000);
+	}
+	
+}
+
diff --git a/libsrc/src/dconvert/gaw/gawmpln.cc b/libsrc/src/dconvert/gaw/gawmpln.cc
new file mode 100644
index 0000000..51e5941
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawmpln.cc
@@ -0,0 +1,191 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gawmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gawdc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+GAW_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlaneHeadFeet headfeet;
+
+	switch (GAW_HeaderInstance_SERIESHDR->SE_entry) {
+		case 1:
+				hfff="HF";
+				headfeet=HeadFirst;
+				break;
+		case 2:
+				hfff="FF";
+				headfeet=FeetFirst;
+				break;
+		default:	hfff="UNKNOWN";		// :(
+				headfeet=HeadFirst;
+				break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (GAW_HeaderInstance_SERIESHDR->SE_position) {
+		case 1:
+				ap="S";
+				position=Supine;
+				break;
+		case 2:
+				ap="P";
+				position=Prone;
+				break;
+		case 4:
+				ap="DL";
+				position=LeftLateralDecubitus;
+				break;
+		case 8:
+				ap="DR";
+				position=RightLateralDecubitus;
+				break;
+		default:	ap="UNKNOWN";		// :(
+				position=Supine;
+				break;
+	}
+
+	ImagePlane imageplane(headfeet,position);
+
+	// get common definitions for CT or MR
+
+	double tlhc_R;
+	double tlhc_A;
+	double tlhc_S;
+	double trhc_R;
+	double trhc_A;
+	double trhc_S;
+	double brhc_R;
+	double brhc_A;
+	double brhc_S;
+	if (GAW_isct) {
+		tlhc_R=GAW_HeaderInstance_CTHDR->CT_tlhc_R;
+		tlhc_A=GAW_HeaderInstance_CTHDR->CT_tlhc_A;
+		tlhc_S=GAW_HeaderInstance_CTHDR->CT_tlhc_S;
+		trhc_R=GAW_HeaderInstance_CTHDR->CT_trhc_R;
+		trhc_A=GAW_HeaderInstance_CTHDR->CT_trhc_A;
+		trhc_S=GAW_HeaderInstance_CTHDR->CT_trhc_S;
+		brhc_R=GAW_HeaderInstance_CTHDR->CT_brhc_R;
+		brhc_A=GAW_HeaderInstance_CTHDR->CT_brhc_A;
+		brhc_S=GAW_HeaderInstance_CTHDR->CT_brhc_S;
+	}
+	if (GAW_ismr) {
+		tlhc_R=GAW_HeaderInstance_MRHDR->MR_tlhc_R;
+		tlhc_A=GAW_HeaderInstance_MRHDR->MR_tlhc_A;
+		tlhc_S=GAW_HeaderInstance_MRHDR->MR_tlhc_S;
+		trhc_R=GAW_HeaderInstance_MRHDR->MR_trhc_R;
+		trhc_A=GAW_HeaderInstance_MRHDR->MR_trhc_A;
+		trhc_S=GAW_HeaderInstance_MRHDR->MR_trhc_S;
+		brhc_R=GAW_HeaderInstance_MRHDR->MR_brhc_R;
+		brhc_A=GAW_HeaderInstance_MRHDR->MR_brhc_A;
+		brhc_S=GAW_HeaderInstance_MRHDR->MR_brhc_S;
+	}
+
+	// DICOM plane definitions are:
+	// - Left Pos Superior +ve
+
+	// The Genesis co-ordinates are:
+	// - Right Ant Superior +ve
+	// - Corners offset by center co-ordinates
+	// - already account for offset from isocenter/reference
+
+	// (NB. no effort is made to fix the sign of SliceLocation)
+
+	// Change sign of AP and LR from Genesis to DICOM...
+
+	Point3D TLHC(-tlhc_R,-tlhc_A, tlhc_S);
+	Point3D TRHC(-trhc_R,-trhc_A, trhc_S);
+	Point3D BRHC(-brhc_R,-brhc_A, brhc_S);
+
+	imageplane.PatientPlane::setCorners(TLHC,
+					    TRHC-TLHC,	// Row Vector
+					    BRHC-TRHC);	// Col Vector
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+
+
+	// PixelSpacing
+	// ReconstructionDiameter
+
+	double 	dfov       = 0;
+	double 	dfov_rect  = 0;
+	double 	pixsize_X  = 0;
+	double 	pixsize_Y  = 0;
+	if (GAW_isct) {
+		dfov     =GAW_HeaderInstance_CTHDR->CT_dfov;
+		dfov_rect=GAW_HeaderInstance_CTHDR->CT_dfov_rect;
+		pixsize_X=GAW_HeaderInstance_CTHDR->CT_pixsize_X;
+		pixsize_Y=GAW_HeaderInstance_CTHDR->CT_pixsize_Y;
+	}
+	if (GAW_ismr) {
+		dfov     =GAW_HeaderInstance_MRHDR->MR_dfov;
+		dfov_rect=GAW_HeaderInstance_MRHDR->MR_dfov_rect;
+		pixsize_X=GAW_HeaderInstance_MRHDR->MR_pixsize_X;
+		pixsize_Y=GAW_HeaderInstance_MRHDR->MR_pixsize_Y;
+	}
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+					pixsize_X,pixsize_Y);
+
+	// which Gawesis tags to use for ReconstructionDiameter ?
+
+	// sample gawesis mr sagittal:
+
+	// Image matrix size - X  <256>
+	// Image matrix size - Y  <256>
+	// Display field of view - X (mm) (MR_dfov)       <240.000000>
+	// Display field of view - Y (if different) (MR_dfov_rect)        <240.000000>
+	// Image dimension - X    <256.000000>
+	// Image dimension - Y    <192.000000>
+	// Image pixel size - X   <0.937500>
+	// Image pixel size - Y   <0.937500>
+
+	// sample gawesis ct scout:
+
+	// Image matrix size - X  <512>
+	// Image matrix size - Y  <197>
+	// Display field of view - X (mm) (CT_dfov)       <496.375183>
+	// Display field of view - Y (if different) (CT_dfov_rect)        <199.890442>
+	// Image dimension - X    <496.375183>
+	// Image dimension - Y    <199.890442>
+	// Image pixel size - X   <0.969483>
+	// Image pixel size - Y   <1.014672>
+	// Scan field of view (mm)        <496.369995>
+
+	// it seems that imatrix_X*pixsize_X=dfov
+	// and           imatrix_Y*pixsize_Y=dfov_rect
+	//
+	// furthermore this matches the image co-ordinate values
+	//
+	// so use average or max of dfov and dfov_rect
+	//
+	// what then are dim_X and dim_Y ? (they are acquisition matrix)
+
+	// NB. the DataCollectionDiameter is done for CT in the
+	// template using CT_sfovmm
+
+	// NB. this highlights the fact that DICOM is wrong to
+	// use just a simple diameter and not a multivalued
+	// dimension ... therefore to be useful one has to use
+	// the pixel spacing times matrix size to be safe !
+
+	// should this be average or max  ... use max ?
+
+	(*list)+=new
+		DecimalStringAttribute(TagFromName(ReconstructionDiameter),
+			(dfov > dfov_rect) ? dfov : dfov_rect);
+}
+
diff --git a/libsrc/src/dconvert/gaw/gawptrs.h b/libsrc/src/dconvert/gaw/gawptrs.h
new file mode 100644
index 0000000..e39e28b
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawptrs.h
@@ -0,0 +1,47 @@
+/* gawptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	GAW_Offset_FILEHDR_ptr		(fileinfo.explicitFileHdrPtr)
+
+#define	GAW_Offset_UIDHDR_ptr		(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_id)
+#define	GAW_Offset_UNPACKHDR_ptr	(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_unpack)
+#define	GAW_Offset_COMPRESSHDR_ptr	(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_compress)
+#define	GAW_Offset_HISTOHDR_ptr		(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_histo)
+#define	GAW_Offset_TEXTHDR_ptr		(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_text)
+#define	GAW_Offset_GRAPHICSHDR_ptr	(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_graphics)
+#define	GAW_Offset_DBHDR_ptr		(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_dbHdr)
+#define	GAW_Offset_USERHDR_ptr		(fileinfo.explicitFileHdrPtr+GAW_HeaderInstance_FILEHDR->IH_img_p_user)
+
+#define	GAW_Offset_SUITEHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitSuiteHdrPtr  : Uint32(GAW_HeaderInstance_FILEHDR->IH_img_p_suite))
+#define	GAW_Offset_EXAMHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitExamHdrPtr   : Uint32(GAW_HeaderInstance_FILEHDR->IH_img_p_exam))
+#define	GAW_Offset_SERIESHDR_ptr	(fileinfo.useExplicitOffsets ? fileinfo.explicitSeriesHdrPtr : Uint32(GAW_HeaderInstance_FILEHDR->IH_img_p_series))
+
+#define	GAW_Offset_UIDHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_id
+#define	GAW_Offset_UNPACKHDR_lng	GAW_HeaderInstance_FILEHDR->IH_img_l_unpack
+#define	GAW_Offset_COMPRESSHDR_lng	GAW_HeaderInstance_FILEHDR->IH_img_l_compress
+#define	GAW_Offset_HISTOHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_histo
+#define	GAW_Offset_TEXTHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_text
+#define	GAW_Offset_GRAPHICSHDR_lng	GAW_HeaderInstance_FILEHDR->IH_img_l_graphics
+#define	GAW_Offset_DBHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_dbHdr
+#define	GAW_Offset_USERHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_user
+
+//#define	GAW_Offset_SUITEHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_suite
+//#define	GAW_Offset_EXAMHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_exam
+//#define	GAW_Offset_SERIESHDR_lng	GAW_HeaderInstance_FILEHDR->IH_img_l_series
+
+#define GAW_hasuid			(GAW_Offset_UIDHDR_lng      != 0)
+#define GAW_hasunpack			(GAW_Offset_UNPACKHDR_lng   != 0)
+#define GAW_hascompress			(GAW_Offset_COMPRESSHDR_lng != 0)
+#define GAW_hashisto			(GAW_Offset_HISTOHDR_lng    != 0)
+#define GAW_hastext			(GAW_Offset_TEXTHDR_lng     != 0)
+#define GAW_hasgraphics			(GAW_Offset_GRAPHICSHDR_lng != 0)
+#define GAW_hasuser			(GAW_Offset_USERHDR_lng     != 0)
+
+#define	GAW_Offset_MRHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitImageHdrPtr : Uint32(GAW_HeaderInstance_FILEHDR->IH_img_p_image))
+#define	GAW_Offset_CTHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitImageHdrPtr : Uint32(GAW_HeaderInstance_FILEHDR->IH_img_p_image))
+
+//#define	GAW_Offset_MRHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_image
+//#define	GAW_Offset_CTHDR_lng		GAW_HeaderInstance_FILEHDR->IH_img_l_image
+
+#define GAW_isct			(strcmp(GAW_HeaderInstance_EXAMHDR->EX_ex_typ,"CT") == 0)
+#define GAW_ismr			(strcmp(GAW_HeaderInstance_EXAMHDR->EX_ex_typ,"MR") == 0)
+
+#define	GAW_Offset_PixelData_ptr	GAW_HeaderInstance_FILEHDR->IH_img_hdr_length + (fileinfo.pixelDataLengthFieldPresent ? 4 : 0)
diff --git a/libsrc/src/dconvert/gaw/gawsrc.h b/libsrc/src/dconvert/gaw/gawsrc.h
new file mode 100644
index 0000000..e8097cf
--- /dev/null
+++ b/libsrc/src/dconvert/gaw/gawsrc.h
@@ -0,0 +1,171 @@
+/* gawsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_gawsrc__
+#define __Header_gawsrc__
+
+class GAW_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long pixeloffset;
+	long mapoffset;
+	long maplength;
+	long offset;
+	Uint16 compress;
+	Uint16 rows;
+	Uint16 columns;
+
+	Int16 last_pixel;
+	Uint16 currentrow;
+	Uint16 *linebuffer;
+
+	Uint16	*map_left;
+	Uint16	*map_wide;
+
+	unsigned char ubuffer[2];
+
+	Uint16 readUint16(void)
+		{
+			Uint16 u;
+			istr->read((char *)ubuffer,2);
+			// Gawesis is a sun3 which is a Big Endian machine
+			u =  (Uint16)ubuffer[0];
+			u <<= 8;
+			u |= (Uint16)ubuffer[1];
+			return u;
+	}
+
+	bool readMap(void)
+		{
+			Assert(maplength);
+			Assert(maplength == 4*rows);
+
+			istr->seekg(mapoffset,ios::beg);
+			if (!(istr && istr->good())) return false;
+
+			map_left=new Uint16[rows];
+			map_wide=new Uint16[rows];
+			if (!map_left || !map_wide) return false;
+			unsigned i;
+			for (i=0; i<rows; ++i) {
+				map_left[i]=readUint16();
+				map_wide[i]=readUint16();
+			}
+			return istr && istr->good();
+		}
+public:
+	GAW_PixelDataSource(istream& i,long pixoff,long mapoff,long maplng,Uint16 cflag,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			pixeloffset=pixoff;
+			mapoffset=mapoff;
+			maplength=maplng;
+			compress=cflag;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+			currentrow=0;		// used as index into map
+			last_pixel=0;		// used for DPCM decoding
+
+			linebuffer=new Uint16[columns];
+			Assert(linebuffer);
+
+			map_left=0;
+			map_wide=0;
+		}
+
+	~GAW_PixelDataSource()
+		{
+			if (linebuffer) delete[] linebuffer;
+			if (map_left) delete[] map_left;
+			if (map_wide) delete[] map_wide;
+		}
+
+	size_t read(void)
+		{
+			if (currentrow == 0) {
+				Assert(istr);
+				if (compress == 2 || compress == 4) { // packed or compacked
+					readMap();
+				}
+				istr->seekg(pixeloffset,ios::beg);
+			}
+
+			if (!good() || currentrow >= rows) return 0;
+
+			Uint16 *ptr=linebuffer;
+			unsigned start;
+			unsigned end;
+			unsigned j;
+
+			if (compress == 2 || compress == 4) { // packed or compacked
+				start=map_left[currentrow];
+				end=start+map_wide[currentrow];
+			}
+			else {
+				start=0;
+				end=columns;
+			}
+
+			Assert(start <= columns);
+			Assert(end <= columns);
+
+			// Pad the first "empty" part of the line ...
+			for (j=0; j<start; j++)*ptr++=0;
+
+			// Copy the middle of the line
+
+			if (compress == 3 || compress == 4) { // compressed or compacked
+				while (start<end) {
+					unsigned char byte;
+					istr->read((char *)&byte,1);
+					if (!istr) break;
+					if (byte & 0x80) {
+						unsigned char byte2;
+						istr->read((char *)&byte2,1);
+						if (!istr) break;
+						if (byte & 0x40) {	// next word
+							istr->read((char *)&byte,1);
+							if (!istr) break;
+							last_pixel=
+							    (((Uint16)byte2<<8)+byte);
+						}
+						else {			// 14 bit delta
+							if (byte & 0x20) byte|=0xe0;
+							else byte&=0x1f;
+							last_pixel+=
+							    (((Int16)byte<<8)+byte2);
+						}
+					}
+					else {				// 7 bit delta
+						if (byte & 0x40) byte|=0xc0;
+						last_pixel+=(signed char)byte;
+					}
+					*ptr++=(Uint16)last_pixel;
+					++start;
+				}
+			}
+			else {
+				while (start<end) {
+					Uint16 u=readUint16();
+					if (!istr) break;
+					*ptr++=u;
+					++start;
+				}
+			}
+
+			// Pad the last "empty" part of the line ...
+			for (j=end; j<columns; j++) *ptr++=0;
+
+			++currentrow;
+
+			return (istr && istr->good()) ? columns : 0;
+		}
+
+	const Uint16 *getBuffer(void)		{ return linebuffer; }
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return istr && istr->good() && currentrow < rows; }
+};
+
+#endif // __Header_gawsrc__
diff --git a/libsrc/src/dconvert/ge9800/Imakefile b/libsrc/src/dconvert/ge9800/Imakefile
new file mode 100644
index 0000000..064c79f
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = ge9800dc.cc ge9800conv.cc ge9800mpln.cc \
+		 ge9800mmsc.cc ge9800mdt.cc \
+		 ge9800dmp.cc ge9800dmpf.cc \
+		 ge9800hdrc.cc ge9800.cc
+
+OBJS =   ge9800dc.o  ge9800conv.o  ge9800mpln.o  \
+		 ge9800mmsc.o  ge9800mdt.o  \
+		 ge9800dmp.o  ge9800dmpf.o  \
+		 ge9800hdrc.o  ge9800.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdge9800.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(ge9800,dconvert)
+
+ProjectConvertTemplate(ge9800hdrp.h,ge9800,convert,prefix=GE9800_ role=headerpart)
+ProjectConvertTemplate(ge9800hdrw.h,ge9800,convert,prefix=GE9800_ role=wholeheader)
+ProjectConvertTemplate(ge9800hdrc.h,ge9800,convert,prefix=GE9800_ role=constructheader)
+ProjectConvertTemplate(ge9800conv.h,ge9800,convert,prefix=GE9800_ role=dicom)
+ProjectConvertTemplate(ge9800dmpf.h,ge9800,convert,prefix=GE9800_ role=dump)
+
+ge9800dmpf.o: ge9800dmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) ge9800dmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/ge9800/README b/libsrc/src/dconvert/ge9800/README
new file mode 100755
index 0000000..80fad0d
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"xxxx.h"
+		class XXXX_Conversion {
+			XXXX_Conversion(istream &i,ostream &e);
+			virtual ~XXXX_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"xxxx.cc"
+
+		XXXX_Conversion::XXXX_Conversion(istream &i,ostream &e);
+		XXXX_Conversion::~XXXX_Conversion();
+
+	"xxxxcl.h"
+
+		class XXXX_Header_BothClass  : public XXXX_HeaderClass
+		{
+		public:
+			XXXX_Header_BothClass(istream *ist) : XXXX_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"xxxxconv.cc"
+
+		#include "xxxxconv.h"
+
+	"xxxxdc.c"
+
+		bool XXXX_Conversion::convertHeader(AttributeList *list);
+		bool XXXX_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool XXXX_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"xxxxdc.h"
+
+	"xxxxdmp.cc"
+
+		bool XXXX_Conversion::dump(ostream &o);
+
+	"xxxxdmp.h"
+
+	"xxxxhdrc.cc"
+
+		#include "xxxxhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"xxxx.tpl"
+
+		The template "describing" the format for header generation
+
+	"xxxxmdt.cc"
+
+		void XXXX_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"xxxxmmsc.cc"
+
+		void XXXX_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"xxxxmpln.cc"
+
+		void XXXX_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"xxxxptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"xxxxsrc.h"
+
+		class XXXX_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			XXXX_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~XXXX_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from xxxx.tpl:
+
+	"xxxxhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class XXXX_HeaderClass_HDR1 {
+		public:
+			XXXX_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"xxxxhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class XXXX_HeaderClass
+		{
+		public:
+			XXXX_HeaderClass(istream *ist);
+
+			XXXX_HeaderClass_HDR1 *XXXX_HeaderInstance_HDR1;
+			XXXX_HeaderClass_HDR2 *XXXX_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"xxxxhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		XXXX_HeaderClass::XXXX_HeaderClass(istream *ist);
+
+	"xxxxconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void XXXX_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"xxxxdmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void XXXX_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "xxxxhdrm.h".
+
+	if you have special purpose code, then "xxxxhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "xxxxhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/ge9800/doubleoffset.awk b/libsrc/src/dconvert/ge9800/doubleoffset.awk
new file mode 100644
index 0000000..1b0380f
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/doubleoffset.awk
@@ -0,0 +1,20 @@
+#  doubleoffset.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# Usage:	mv ge9800.tpl ge9800.tpl.bak; awk -F\t -f doubleoffset.awk <ge9800.tpl.bak >ge9800.tpl; rm ge9800.tpl.bak
+
+	{
+		if (match($0,"offset=") > 0) {
+			#print $2
+			if (match($2,"[0-9]+") > 0) {
+				offsetvalue = substr($2,RSTART,RLENGTH);
+				#print $2 " = " offsetvalue;
+				newoffsetvalue = offsetvalue * 2;
+				replaceoffsetstring = "offset=\"" newoffsetvalue "\"";
+				#print $2 " = " offsetvalue " ; " replaceoffsetstring;
+				sub($2,replaceoffsetstring,$0);
+				print $0;
+			}
+		}
+		else {
+			print $0
+		}
+	}
diff --git a/libsrc/src/dconvert/ge9800/ge9800.cc b/libsrc/src/dconvert/ge9800/ge9800.cc
new file mode 100644
index 0000000..06b0783
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "ge9800.h"
+#include "ge9800cl.h"
+#include "srcsink.h"
+#include "ge9800src.h"
+
+GE9800_Conversion::GE9800_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	ge9800hdr=0;
+	pixeldatasrc=0;
+}
+
+GE9800_Conversion::~GE9800_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (ge9800hdr) delete ge9800hdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800.h b/libsrc/src/dconvert/ge9800/ge9800.h
new file mode 100644
index 0000000..0f8d155
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800.h
@@ -0,0 +1,41 @@
+/* ge9800.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ge9800__
+#define __Header_ge9800__
+
+// NB. a GE9800_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~GE9800_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class GE9800_Header_BothClass;
+class GE9800_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class GE9800_Conversion {
+	GE9800_Header_BothClass *ge9800hdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	GE9800_PixelDataSource *pixeldatasrc;
+public:
+	GE9800_Conversion(istream &i,ostream &e);
+
+	virtual ~GE9800_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0);
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_ge9800__ */
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800.tpl b/libsrc/src/dconvert/ge9800/ge9800.tpl
new file mode 100644
index 0000000..0cde07d
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800.tpl
@@ -0,0 +1,356 @@
+# Offsets are in 8 bit bytes from 0
+# Lengths are in intype words
+
+# Global Header
+
+block="GLOBALHDR"	offset="0"	intype="String"	inlength="6"	name="?"	dicomtype="?"	dicomtag="?"				# Data base membership ID (ASCII '9800') 
+block="GLOBALHDR"	offset="6"	intype="String"	inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# Revision Level 
+block="GLOBALHDR"	offset="8"	intype="String"	inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# Format code 
+block="GLOBALHDR"	offset="10"	intype="String"	inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# User Revision code
+block="GLOBALHDR"	offset="12"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Month of Creation 
+block="GLOBALHDR"	offset="14"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Day of Creation 
+block="GLOBALHDR"	offset="16"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Year of Creation 
+block="GLOBALHDR"	offset="18"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Hour of Creation 
+block="GLOBALHDR"	offset="20"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Minute of Creation 
+block="GLOBALHDR"	offset="22"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Second of Creation 
+block="GLOBALHDR"	offset="24"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Originating Station ID 
+
+block="GLOBALHDR"	offset="32"	intype="String"	inlength="14"	name="?"	dicomtype="?"	dicomtag="?"				# External File Name 
+
+block="GLOBALHDR"	offset="64"	intype="String"	inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# Image Block 0 revision code 
+
+block="GLOBALHDR"	offset="66"	intype="Int16_B"	inlength="1"	name="GLOBALHDRPTR"		dicomtype="?"	dicomtag="?"		# Word ptr to global header
+block="GLOBALHDR"	offset="68"	intype="Int16_B"	inlength="1"	keyword="EXAMHDRPTR"		dicomtype="?"	dicomtag="?"		# Word ptr to exam header
+block="GLOBALHDR"	offset="70"	intype="Int16_B"	inlength="1"	keyword="IMAGE1HDRPTR"		dicomtype="?"	dicomtag="?"		# Word ptr to image header 1
+block="GLOBALHDR"	offset="72"	intype="Int16_B"	inlength="1"	keyword="IMAGE2HDRPTR"		dicomtype="?"	dicomtag="?"		# Word ptr to image header 2
+block="GLOBALHDR"	offset="74"	intype="Int16_B"	inlength="1"	keyword="IMAGEMAPPTR"		dicomtype="?"	dicomtag="?"		# Word ptr to image map
+block="GLOBALHDR"	offset="76"	intype="Int16_B"	inlength="1"	keyword="IMAGEDATAPTR"		dicomtype="?"	dicomtag="?"		# Word ptr to image data
+
+block="GLOBALHDR"	offset="78"	intype="Int16_B"	inlength="1"	name="GLOBALHDRLNG"		dicomtype="?"	dicomtag="?"		# Blocks in global header
+block="GLOBALHDR"	offset="80"	intype="Int16_B"	inlength="1"	name="EXAMHDRLNG"		dicomtype="?"	dicomtag="?"		# Blocks in exam header
+block="GLOBALHDR"	offset="82"	intype="Int16_B"	inlength="1"	name="IMAGE1HDRLNG"		dicomtype="?"	dicomtag="?"		# Blocks in image header 1
+block="GLOBALHDR"	offset="84"	intype="Int16_B"	inlength="1"	name="IMAGE2HDRLNG"		dicomtype="?"	dicomtag="?"		# Blocks in image header 2
+block="GLOBALHDR"	offset="86"	intype="Int16_B"	inlength="1"	name="IMAGEMAPLNG"		dicomtype="?"	dicomtag="?"		# Blocks in image map
+block="GLOBALHDR"	offset="88"	intype="Int16_B"	inlength="1"	name="IMAGEDATALNG"		dicomtype="?"	dicomtag="?"		# Blocks in image data
+
+block="GLOBALHDR"	offset="90"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# max # of images in file 
+block="GLOBALHDR"	offset="92"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 3*16 bits for images 
+block="GLOBALHDR"	offset="94"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recon done flags 
+block="GLOBALHDR"	offset="100"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Image write locked flags 
+block="GLOBALHDR"	offset="106"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Archive required flags 
+block="GLOBALHDR"	offset="112"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Archive done flags 
+block="GLOBALHDR"	offset="118"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Image removed flags 
+block="GLOBALHDR"	offset="124"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# block ptrs to image hdrs 
+block="GLOBALHDR"	offset="192"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# should be constant = 1 
+block="GLOBALHDR"	offset="194"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# should be constant = 512
+
+# Exam Header
+
+block="EXAMHDR"	offset="0"	intype="String"	inlength="2"	name="?"	dicomtype="LO"	dicomtag="SoftwareVersions"		# Revision Code 
+block="EXAMHDR"	offset="2"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# CT System number 
+block="EXAMHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="SH"	dicomtag="StationName"			# CT Station ID 
+block="EXAMHDR"	offset="6"	intype="Int16_B"	inlength="1"	keyword="StudyNumber"	dicomtype="SH"	dicomtag="StudyID"		# Exam Number (integer) 
+block="EXAMHDR"	offset="8"	intype="String"	inlength="14"	name="?"	dicomtype="?"	dicomtag="?"				# Exam Number (ascii) 
+block="EXAMHDR"	offset="22"	intype="String"	inlength="12"	name="?"	dicomtype="LO"	dicomtag="PatientID"			# Patient ID 
+block="EXAMHDR"	offset="34"	intype="String"	inlength="30"	name="?"	dicomtype="PN"	dicomtag="PatientName"			# Patient Name 
+block="EXAMHDR"	offset="64"	intype="String"	inlength="30"	name="?"	dicomtype="PN"	dicomtag="ReferringPhysicianName"	# Referring Physician 
+block="EXAMHDR"	offset="94"	intype="String"	inlength="24"	name="?"	dicomtype="LO"	dicomtag="InstitutionName"		# Hospital Name 
+block="EXAMHDR"	offset="118"	intype="String"	inlength="30"	name="?"	dicomtype="PN"	dicomtag="PerformingPhysicianName"	# Diagnostician 
+block="EXAMHDR"	offset="148"	intype="String"	inlength="4"	name="?"	dicomtype="PN"	dicomtag="OperatorsName"			# Operator Initials 
+block="EXAMHDR"	offset="152"	intype="String"	inlength="80"	name="?"	dicomtype="LO"	dicomtag="StudyDescription"		# Exam Description 
+
+# Exam Details
+
+block="EXAMHDR"	offset="232"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of scout scans 
+block="EXAMHDR"	offset="234"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of axial scans 
+block="EXAMHDR"	offset="236"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of standard axial scans 
+block="EXAMHDR"	offset="238"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of dynamic scans done 
+block="EXAMHDR"	offset="240"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of standard target axials 
+block="EXAMHDR"	offset="242"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # dynamic target axials 
+block="EXAMHDR"	offset="244"	intype="Int16_B"	inlength="1"	name="EXAMSTARTDATEMM"	dicomtype="?"	dicomtag="?"			# Exam start Date (M/D/Y) 
+block="EXAMHDR"	offset="246"	intype="Int16_B"	inlength="1"	name="EXAMSTARTDATEDD"	dicomtype="?"	dicomtag="?"			#  
+block="EXAMHDR"	offset="248"	intype="Int16_B"	inlength="1"	name="EXAMSTARTDATEYY"	dicomtype="?"	dicomtag="?"			#  
+block="EXAMHDR"	offset="250"	intype="Int16_B"	inlength="1"	name="EXAMSTARTTIMEHH"	dicomtype="?"	dicomtag="?"			# Exam start Time (H/M/S) 
+block="EXAMHDR"	offset="252"	intype="Int16_B"	inlength="1"	name="EXAMSTARTTIMEMM"	dicomtype="?"	dicomtag="?"			#  
+block="EXAMHDR"	offset="254"	intype="Int16_B"	inlength="1"	name="EXAMSTARTTIMESS"	dicomtype="?"	dicomtag="?"			# 
+block="EXAMHDR"	offset="256"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"			# Exam end Date (M/D/Y) 
+block="EXAMHDR"	offset="258"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"			#  
+block="EXAMHDR"	offset="260"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"			#  
+block="EXAMHDR"	offset="262"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"			# Exam end Time (H/M/S) 
+block="EXAMHDR"	offset="264"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"			#  
+block="EXAMHDR"	offset="266"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"			# 
+block="EXAMHDR"	offset="268"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Scan Revision Type 
+block="EXAMHDR"	offset="270"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Trauma Flag (0=n,1=y) 
+
+# Hardware
+
+block="EXAMHDR"	offset="272"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# CT Detector Type 
+block="EXAMHDR"	offset="274"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of Detectors 
+block="EXAMHDR"	offset="276"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Detector # at theta=0 
+block="EXAMHDR"	offset="280"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Detector spacing in mm (fp) 
+block="EXAMHDR"	offset="284"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="DistanceSourceToDetector"	# Source to detector mm (fp) 
+block="EXAMHDR"	offset="288"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="DistanceSourceToPatient"	# Source to center mm (fp) 
+block="EXAMHDR"	offset="292"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Tube type 
+block="EXAMHDR"	offset="294"	intype="String"	inlength="4"	name="?"	dicomtype="?"	dicomtag="?"				# DAS type 
+block="EXAMHDR"	offset="298"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Das read direction 
+block="EXAMHDR"	offset="300"	intype="String"	inlength="4"	name="?"	dicomtype="?"	dicomtag="?"				# Table firmware revision 
+block="EXAMHDR"	offset="304"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Drive count 
+block="EXAMHDR"	offset="306"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Axial trigger rate 
+block="EXAMHDR"	offset="308"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Scout trigger rate 
+block="EXAMHDR"	offset="310"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Disk Drive Type 
+
+# Header Control Values
+
+block="EXAMHDR"	offset="312"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Calcheck file ? 
+block="EXAMHDR"	offset="314"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Header info ok? 
+block="EXAMHDR"	offset="316"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# All prospective recons done? 
+block="EXAMHDR"	offset="318"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Prospect. & scouts archived? 
+block="EXAMHDR"	offset="320"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Images archived? 
+block="EXAMHDR"	offset="322"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Header modified? 
+block="EXAMHDR"	offset="324"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Validation tape number 
+block="EXAMHDR"	offset="326"	intype="String"		inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# Engineering release number 
+block="EXAMHDR"	offset="328"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# temp (was checksum ?)
+block="EXAMHDR"	offset="330"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 9800 Family ID 
+block="EXAMHDR"	offset="332"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon PRS number 
+block="EXAMHDR"	offset="334"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon 1st baseline 
+block="EXAMHDR"	offset="336"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon last baseline 
+block="EXAMHDR"	offset="338"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon 1st enhanced 
+block="EXAMHDR"	offset="340"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon last enhanced 
+block="EXAMHDR"	offset="342"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Checksum 
+
+# Image Header #1
+
+block="IMAGE1HDR"	offset="0"	intype="String"		inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# Revision code 
+block="IMAGE1HDR"	offset="2"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Station ID 
+block="IMAGE1HDR"	offset="4"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Exam Number 
+block="IMAGE1HDR"	offset="6"	intype="String"		inlength="14"	name="?"	dicomtype="?"	dicomtag="?"				# Exam Number (ascii) 
+block="IMAGE1HDR"	offset="20"	intype="Int16_B"	inlength="1"	keyword="?"	dicomtype="?"	dicomtag="?"		# Position (study) number 
+block="IMAGE1HDR"	offset="22"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Intermediate support pos 
+block="IMAGE1HDR"	offset="24"	intype="Int16_B"	inlength="1"	keyword="GroupType"	dicomtype="?"	dicomtag="?"				# Group (2=scout,3=std,4=dyn,5=arr) 
+block="IMAGE1HDR"	offset="26"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="SeriesNumber"				# Group Number 
+block="IMAGE1HDR"	offset="28"	intype="String"		inlength="30"	name="?"	dicomtype="LO"	dicomtag="SeriesDescription"				# Group Description 
+block="IMAGE1HDR"	offset="92"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="AcquisitionNumber"		# Scan Number 
+block="IMAGE1HDR"	offset="94"	intype="Int16_B"	inlength="1"	keyword="ImageNumber"	dicomtype="IS"	dicomtag="InstanceNumber"		# Image Number 
+block="IMAGE1HDR"	offset="96"	intype="Int16_B"	inlength="1"	name="PatientType"	dicomtype="?"	dicomtag="?"			# Patient Type (2=sm,3=me,4=la) 
+block="IMAGE1HDR"	offset="98"	intype="Int16_B"	inlength="1"	keyword="PatientOrientation"	dicomtype="?"	dicomtag="?"		# Patient Orientation (1=Head first,2=Feet first) 
+block="IMAGE1HDR"	offset="100"	intype="Int16_B"	inlength="1"	keyword="APPatientOrientation"	dicomtype="?"	dicomtag="?"		# AP Orientation (1=prone,2=supine,3=left lateral decubitus,4=right lateral decubitus) 
+block="IMAGE1HDR"	offset="102"	intype="String"		inlength="6"	keyword="PositionReference"	dicomtype="LO"	dicomtag="PositionReferenceIndicator"		# Position Reference 
+block="IMAGE1HDR"	offset="108"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Contrast Flag (0=n,1=y) 
+block="IMAGE1HDR"	offset="110"	intype="String"		inlength="64"	name="?"	dicomtype="LO"	dicomtag="ContrastBolusAgent"		# Contrast Description 
+block="IMAGE1HDR"	offset="174"	intype="Int16_B"	inlength="1"	keyword="BowtieFilter"	dicomtype="?"	dicomtag="?"			# Bowtie Filter (1=body,2=head,3=a) 
+block="IMAGE1HDR"	offset="176"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="SliceThickness"		# Aperture (1.5,3,5,10) (fp) 
+block="IMAGE1HDR"	offset="180"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="KVP"				# Generator KVP (80,120,140) 
+block="IMAGE1HDR"	offset="182"	intype="Int16_B"	inlength="1"	keyword="TubeCurrent"	dicomtype="IS"	dicomtag="XRayTubeCurrent"	# Tube current (10-360) 
+block="IMAGE1HDR"	offset="184"	intype="DG_Float_F"	inlength="1"	keyword="GantryAngle"	dicomtype="DS"	dicomtag="GantryDetectorTilt"			# Gantry Angle 
+block="IMAGE1HDR"	offset="188"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="TableHeight"			# Table Height (mm) (fp) 
+block="IMAGE1HDR"	offset="192"	intype="DG_Float_F"	inlength="1"	keyword="SlicePosition"	dicomtype="DS"	dicomtag="SliceLocation"	# Axial Table Location (fp) 
+block="IMAGE1HDR"	offset="196"	intype="DG_Float_F"	inlength="1"	keyword="ScanTime"	dicomtype="?"	dicomtag="?"			# Scan time (1.4-9.4) (fp) 
+block="IMAGE1HDR"	offset="200"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Cal phantom size (1=sm,2=md,3=la) 
+block="IMAGE1HDR"	offset="202"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Cal type (1=air,2=water,3=poly) 
+block="IMAGE1HDR"	offset="204"	intype="Int16_B"	inlength="1"	name="STARTOFSCANDATEMM"	dicomtype="?"	dicomtag="?"			# Start of Scan (M/D/Y) 
+block="IMAGE1HDR"	offset="206"	intype="Int16_B"	inlength="1"	name="STARTOFSCANDATEDD"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="208"	intype="Int16_B"	inlength="1"	name="STARTOFSCANDATEYY"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="210"	intype="Int16_B"	inlength="1"	name="STARTOFSCANTIMEHH"	dicomtype="?"	dicomtag="?"			# Start of Scan (H:M:S) 
+block="IMAGE1HDR"	offset="212"	intype="Int16_B"	inlength="1"	name="STARTOFSCANTIMEMM"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="214"	intype="Int16_B"	inlength="1"	name="STARTOFSCANTIMESS"	dicomtype="?"	dicomtag="?"			# 
+block="IMAGE1HDR"	offset="216"	intype="Int16_B"	inlength="1"	name="ENDOFSCANTIMEHH"	dicomtype="?"	dicomtag="?"				# End of Scan (H:M:S)
+block="IMAGE1HDR"	offset="218"	intype="Int16_B"	inlength="1"	name="ENDOFSCANTIMEMM"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="220"	intype="Int16_B"	inlength="1"	name="ENDOFSCANTIMESS"	dicomtype="?"	dicomtag="?"			# 
+block="IMAGE1HDR"	offset="222"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of overranged views 
+block="IMAGE1HDR"	offset="224"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # overranges 
+
+# Axial Scans
+
+block="IMAGE1HDR"	offset="226"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Angle of 1st view 
+block="IMAGE1HDR"	offset="228"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Scout Scan # use to prescribe 
+block="IMAGE1HDR"	offset="230"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Axial type (1=std,2=half,3=over) 
+block="IMAGE1HDR"	offset="232"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Calcheck image number 
+block="IMAGE1HDR"	offset="234"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Prep Delay in sec (fp) 
+block="IMAGE1HDR"	offset="238"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Mid-scan time in sec (fp) 
+block="IMAGE1HDR"	offset="242"	intype="Int16_B"	inlength="1"	keyword="RotationDirection"	dicomtype="?"	dicomtag="?"		# Gantry rotation dir (1=cw,2=ccw) 
+block="IMAGE1HDR"	offset="244"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# image type (0=no,1=seg,2=tar) 
+block="IMAGE1HDR"	offset="246"	intype="Int16_B"	inlength="1"	keyword="ImageSize"	dicomtype="?"	dicomtag="?"			# image size (256/320/512) 
+
+# Scout Scans
+
+block="IMAGE1HDR"	offset="248"	intype="DG_Float_F"	inlength="1"	name="?"			dicomtype="?"	dicomtag="?"		# table speed (37.5,75. mm/sec) (fp) 
+block="IMAGE1HDR"	offset="252"	intype="Int16_B"	inlength="1"	keyword="TubeAzimuth"		dicomtype="?"	dicomtag="?"		# x-ray azimuth angle 0-360) 
+block="IMAGE1HDR"	offset="254"	intype="DG_Float_F"	inlength="1"	keyword="ScoutEndLocation"	dicomtype="?"	dicomtag="?"		# scout end loc (mm) (fp) 
+block="IMAGE1HDR"	offset="258"	intype="DG_Float_F"	inlength="1"	name="ViewSpacing"		dicomtype="?"	dicomtag="?"		# view spacing (mm) (fp) 
+
+# Data Structure Information
+
+block="IMAGE1HDR"	offset="262"	intype="Int16_B"	inlength="1"	keyword="DetectorsPerView"	dicomtype="?"	dicomtag="?"		# # data detectors (wds)/view 
+block="IMAGE1HDR"	offset="264"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 1st detector # of a view 
+block="IMAGE1HDR"	offset="266"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# padding/view (to block align) 
+block="IMAGE1HDR"	offset="268"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# view compression factor 
+block="IMAGE1HDR"	offset="270"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# total input views/scan 
+block="IMAGE1HDR"	offset="272"	intype="Int16_B"	inlength="1"	keyword="ViewsPerScan"		dicomtype="?"	dicomtag="?"		# views/scan (compressed) 
+
+# Raw Data Structure
+
+block="IMAGE1HDR"	offset="274"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# views/frame 
+block="IMAGE1HDR"	offset="276"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# views/superframe 
+block="IMAGE1HDR"	offset="278"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# frame size in words 
+block="IMAGE1HDR"	offset="280"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# blocks per frame 
+block="IMAGE1HDR"	offset="282"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# ref channel rbn pointer 
+block="IMAGE1HDR"	offset="284"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# drive # of ref channel frame 
+
+# Recon Image Creation
+
+block="IMAGE1HDR"	offset="286"	intype="DG_Float_F"	inlength="1"	keyword="XDiameter"	dicomtype="?"	dicomtag="?"			# X diam of recon (height) mm (fp) 
+block="IMAGE1HDR"	offset="290"	intype="DG_Float_F"	inlength="1"	keyword="YDiameter"	dicomtype="?"	dicomtag="?"			# Y diam of recon (length) mm (fp) 
+block="IMAGE1HDR"	offset="294"	intype="DG_Float_F"	inlength="1"	name="Pixel256"	dicomtype="?"	dicomtag="?"			# Std pixel size for image size = 256 
+block="IMAGE1HDR"	offset="298"	intype="DG_Float_F"	inlength="1"	name="Pixel320"	dicomtype="?"	dicomtag="?"			# Std pixel size for image size = 320 
+block="IMAGE1HDR"	offset="302"	intype="DG_Float_F"	inlength="1"	name="Pixel512"	dicomtype="?"	dicomtag="?"			# Std pixel size for image size = 512 
+
+# Miscellaneous
+
+block="IMAGE1HDR"	offset="306"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Floppy pixel numbers 
+
+# Display Defaults
+
+block="IMAGE1HDR"	offset="308"	intype="DG_Float_F"	inlength="1"	keyword="MagFactor"	dicomtype="?"	dicomtag="?"				# magnification factor (fp) 
+block="IMAGE1HDR"	offset="312"	intype="DG_Float_F"	inlength="1"	keyword="XCenter"	dicomtype="?"	dicomtag="?"				# image display x center (fp) 
+block="IMAGE1HDR"	offset="316"	intype="DG_Float_F"	inlength="1"	keyword="YCenter"	dicomtype="?"	dicomtag="?"				# image display y center (fp) 
+block="IMAGE1HDR"	offset="320"	intype="Int16_B"	inlength="1"	keyword="WindowSetting"	dicomtype="?"	dicomtag="?"			# window (-1=default) 
+block="IMAGE1HDR"	offset="322"	intype="Int16_B"	inlength="1"	keyword="LevelSetting"	dicomtype="?"	dicomtag="?"			# level (0=default) 
+block="IMAGE1HDR"	offset="324"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Gamma table (-1=default) 
+block="IMAGE1HDR"	offset="326"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Hdr modified flag 
+block="IMAGE1HDR"	offset="328"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# checksum 
+block="IMAGE1HDR"	offset="330"	intype="Int16_B"	inlength="1"	name="RECONDATEMM"	dicomtype="?"	dicomtag="?"			# Recon date (M/D/Y) 
+block="IMAGE1HDR"	offset="332"	intype="Int16_B"	inlength="1"	name="RECONDATEDD"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="334"	intype="Int16_B"	inlength="1"	name="RECONDATEYY"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="336"	intype="Int16_B"	inlength="1"	name="RECONTIMEHH"	dicomtype="?"	dicomtag="?"			# Recon time (H:M:S) 
+block="IMAGE1HDR"	offset="338"	intype="Int16_B"	inlength="1"	name="RECONTIMEMM"	dicomtype="?"	dicomtag="?"			#  
+block="IMAGE1HDR"	offset="340"	intype="Int16_B"	inlength="1"	name="RECONTIMESS"	dicomtype="?"	dicomtag="?"			# 
+block="IMAGE1HDR"	offset="342"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recon station ID 
+block="IMAGE1HDR"	offset="344"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recon unique number 
+block="IMAGE1HDR"	offset="346"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# blocks in image (incl headers) 
+block="IMAGE1HDR"	offset="348"	intype="Int16_B"	inlength="1"	keyword="UseImageMap"		dicomtype="?"	dicomtag="?"		# use image map (1=y,2=n (rect) 
+block="IMAGE1HDR"	offset="350"	intype="String"	inlength="80"	name="?"	dicomtype="?"	dicomtag="?"				# line of free text 
+block="IMAGE1HDR"	offset="430"	intype="DG_Float_F"	inlength="1"	keyword="ReconPixelSize"	dicomtype="?"	dicomtag="?"		# actual image pixel size (mm,fp) (scout), standard pixel size/target factor (recon) 
+block="IMAGE1HDR"	offset="434"	intype="Int16_B"	inlength="1"	keyword="FileType"	dicomtype="?"	dicomtag="?"			# file type (1=prospective,2=scout,3=retrospective,4=segmented,5=screensave,6=plot) 
+block="IMAGE1HDR"	offset="436"	intype="Int16_B"	inlength="1"	keyword="DataRange"	dicomtype="?"	dicomtag="?"			# Data range (# bits) 
+
+# Recon information
+
+block="IMAGE1HDR"	offset="438"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0=std, >0 = segment # 
+block="IMAGE1HDR"	offset="440"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# back proj. window (0-2) 
+block="IMAGE1HDR"	offset="442"	intype="Int16_B"	inlength="1"	keyword="PreprocessReconType"	dicomtype="?"	dicomtag="?"		# preprocess target recon type 0=undefined,1=bone,2=soft tissue,3=quick soft tissue 
+block="IMAGE1HDR"	offset="444"	intype="DG_Float_F"	inlength="1"	keyword="ReconXDiameter"	dicomtype="?"	dicomtag="?"		# actual x_diam recon (hgt) mm-fp 
+block="IMAGE1HDR"	offset="448"	intype="DG_Float_F"	inlength="1"	keyword="ReconYDiameter"	dicomtype="?"	dicomtag="?"		# actual y_diam recon (len) mm-fp 
+block="IMAGE1HDR"	offset="452"	intype="DG_Float_F"	inlength="1"	keyword="ReconXCenter"	dicomtype="?"	dicomtag="?"			# x_center of target recon mm-fp 
+block="IMAGE1HDR"	offset="456"	intype="DG_Float_F"	inlength="1"	keyword="ReconYCenter"	dicomtype="?"	dicomtag="?"			# y-center of target recon mm-fp 
+block="IMAGE1HDR"	offset="460"	intype="DG_Float_F"	inlength="1"	keyword="ReconMagFactor"	dicomtype="?"	dicomtag="?"		# target mag factor 
+
+# Pre-Pre-Processing
+
+block="IMAGE1HDR"	offset="464"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0 = norm, 1 = halfview 
+block="IMAGE1HDR"	offset="466"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# sagittal format? (0=n,1=y) 
+block="IMAGE1HDR"	offset="468"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# disk image compressed? 
+block="IMAGE1HDR"	offset="470"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# scout image orient (0=ap,1=lat) 
+block="IMAGE1HDR"	offset="472"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# archive done flag 
+block="IMAGE1HDR"	offset="474"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# image use cnt 
+block="IMAGE1HDR"	offset="476"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# image removed flag 
+
+block="IMAGE1HDR"	offset="478"	intype="String"	inlength="2"	name="?"	dicomtype="?"	dicomtag="?"				# image hdr revision code 
+block="IMAGE1HDR"	offset="480"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# image map type (0=large) 
+block="IMAGE1HDR"	offset="482"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# image origin (1=98,2=88,3=emi) 
+block="IMAGE1HDR"	offset="484"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# image file source format 
+block="IMAGE1HDR"	offset="486"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# flow image flag (0=not) 
+
+# Image Header #2
+
+block="IMAGE2HDR"	offset="0"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# requesting station id 
+block="IMAGE2HDR"	offset="2"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# ap1 type 
+block="IMAGE2HDR"	offset="4"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # creation failures 
+block="IMAGE2HDR"	offset="6"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# recon-construction id 
+block="IMAGE2HDR"	offset="8"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # ap's in system 
+block="IMAGE2HDR"	offset="10"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# ap2 type 
+block="IMAGE2HDR"	offset="12"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# birp type 
+block="IMAGE2HDR"	offset="14"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # reference channels/view 
+block="IMAGE2HDR"	offset="16"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# birp recon symmetry mode 
+block="IMAGE2HDR"	offset="18"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # of imhproc != 0 
+block="IMAGE2HDR"	offset="20"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0=norm, 1=gated 
+block="IMAGE2HDR"	offset="22"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0=normal,1=rubout,2=son of rubout
+block="IMAGE2HDR"	offset="24"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0=normal,1=oversize,2=fatman,3=both 
+block="IMAGE2HDR"	offset="26"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0=norm,1=iterative 
+block="IMAGE2HDR"	offset="28"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# fft size (0=nominal) 
+block="IMAGE2HDR"	offset="30"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# source image type for targ 
+block="IMAGE2HDR"	offset="32"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# source image number for targ 
+block="IMAGE2HDR"	offset="34"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# first view number 
+block="IMAGE2HDR"	offset="36"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 1=std,2=halfscan,3=overscan 
+block="IMAGE2HDR"	offset="38"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 0=std,1=half-detector 
+block="IMAGE2HDR"	offset="40"	intype="String"	inlength="20"	name="?"	dicomtype="?"	dicomtag="?"				# filename for rubout information
+block="IMAGE2HDR"	offset="60"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # views in filter region 
+block="IMAGE2HDR"	offset="62"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # detectors in filter region 
+block="IMAGE2HDR"	offset="64"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# filter center wght 
+block="IMAGE2HDR"	offset="68"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# filter subtraction wght 
+block="IMAGE2HDR"	offset="72"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# min of cal and windowed data 
+block="IMAGE2HDR"	offset="76"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# max of cal and windowed data 
+block="IMAGE2HDR"	offset="80"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# avg of cal and windowed data 
+block="IMAGE2HDR"	offset="84"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# filter function 
+block="IMAGE2HDR"	offset="86"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Head Scan (0=n,1=y) 
+block="IMAGE2HDR"	offset="88"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Tech factor (0=n,1=y) 
+block="IMAGE2HDR"	offset="90"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 SMoothing (0=n,1=y) 
+block="IMAGE2HDR"	offset="92"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Top view # 
+block="IMAGE2HDR"	offset="94"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Data Flag (0=rev,1=norm,2=BH, 
+block="IMAGE2HDR"	offset="96"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Dtyp (0=10,1=11,2=11x,3=12) 
+block="IMAGE2HDR"	offset="98"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 old contrast flag 
+block="IMAGE2HDR"	offset="100"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 0=60Hz, 1 = 50Hz 
+block="IMAGE2HDR"	offset="102"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 file complete (0=y) 
+block="IMAGE2HDR"	offset="104"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Bit flags for recond slices 
+block="IMAGE2HDR"	offset="112"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 'SS' flag for rev >=EA 
+block="IMAGE2HDR"	offset="114"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Display rev (0=old,1=new) 
+block="IMAGE2HDR"	offset="116"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 used by EMI files 
+block="IMAGE2HDR"	offset="118"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Pulse Width Code 
+block="IMAGE2HDR"	offset="120"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Screen save mode 
+block="IMAGE2HDR"	offset="122"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 EMI system code 
+block="IMAGE2HDR"	offset="124"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 EMI system code 
+block="IMAGE2HDR"	offset="126"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 link to raw data run # 
+block="IMAGE2HDR"	offset="128"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 3 X-ray counts 
+block="IMAGE2HDR"	offset="130"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 link to orig run # 
+block="IMAGE2HDR"	offset="132"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 oversize recon flag 
+block="IMAGE2HDR"	offset="134"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Scout DAS speed 
+block="IMAGE2HDR"	offset="136"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Scout C2 table bias 
+block="IMAGE2HDR"	offset="138"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Scout table elevation 
+block="IMAGE2HDR"	offset="140"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Scout Pulse Width cnt 
+block="IMAGE2HDR"	offset="142"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Scout Interp Compr. 
+block="IMAGE2HDR"	offset="146"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# 8800 Scout Pulse Code Freq 
+block="IMAGE2HDR"	offset="148"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# # recon checkpoints 
+block="IMAGE2HDR"	offset="150"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Percent Xenon used 
+block="IMAGE2HDR"	offset="152"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Arterial enhancement val 
+block="IMAGE2HDR"	offset="156"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Arterial Rate  constant 
+block="IMAGE2HDR"	offset="160"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon Start time (H:M:S) H
+block="IMAGE2HDR"	offset="162"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon Start time (H:M:S) M
+block="IMAGE2HDR"	offset="164"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Xenon Start time (H:M:S) S
+block="IMAGE2HDR"	offset="166"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Hematocrit value 
+block="IMAGE2HDR"	offset="168"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PCO2 values 1,2,3 1
+block="IMAGE2HDR"	offset="170"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PCO2 values 1,2,3 2
+block="IMAGE2HDR"	offset="172"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PCO2 values 1,2,3 3
+block="IMAGE2HDR"	offset="174"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Filter used in flow 
+block="IMAGE2HDR"	offset="176"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Mask used in flow 
+block="IMAGE2HDR"	offset="178"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Baseline scans 1,2 1
+block="IMAGE2HDR"	offset="180"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Baseline scans 1,2 2
+block="IMAGE2HDR"	offset="182"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# enhancement scans 1-6 1
+block="IMAGE2HDR"	offset="184"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# enhancement scans 1-6 2
+block="IMAGE2HDR"	offset="186"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# enhancement scans 1-6 3
+block="IMAGE2HDR"	offset="188"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# enhancement scans 1-6 4
+block="IMAGE2HDR"	offset="190"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# enhancement scans 1-6 5
+block="IMAGE2HDR"	offset="192"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# enhancement scans 1-6 6
+
+constant="16"									dicomtype="US"	dicomtag="BitsAllocated"				#
+constant="0"									dicomtype="US"	dicomtag="PixelRepresentation"			# Unsigned
+constant="1"									dicomtype="US"	dicomtag="SamplesPerPixel"				# 
+constant="MONOCHROME2"							dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="-1024"								dicomtype="DS"	dicomtag="RescaleIntercept"				# 
+constant="1"									dicomtype="DS"	dicomtag="RescaleSlope"					# 
+constant="HU"									dicomtype="LO"	dicomtag="RescaleType"					# 
+constant=""										dicomtype="SH"	dicomtag="AccessionNumber"				# 
+constant=""										dicomtype="DA"	dicomtag="PatientBirthDate"				# 
+constant=""										dicomtype="CS"	dicomtag="PatientSex"					# 
+constant="GE Medical Systems"					dicomtype="LO"	dicomtag="Manufacturer"					# 
+constant="1.2.840.10008.5.1.4.1.1.2"			dicomtype="UI"	dicomtag="SOPClassUID"					# 
+constant="CT"									dicomtype="CS"	dicomtag="Modality"						# 
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800cl.h b/libsrc/src/dconvert/ge9800/ge9800cl.h
new file mode 100644
index 0000000..9ceae02
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800cl.h
@@ -0,0 +1,25 @@
+/* ge9800cl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "ge9800hdrp.h"
+#include "ge9800hdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class GE9800_Header_BothClass : public GE9800_HeaderClass
+{
+public:
+	GE9800_Header_BothClass(istream *ist) : GE9800_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800conv.cc b/libsrc/src/dconvert/ge9800/ge9800conv.cc
new file mode 100644
index 0000000..5b4dd02
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800conv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800conv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "ge9800dc.h"
+#include "ge9800ptrs.h"
+#include "ge9800conv.h"
diff --git a/libsrc/src/dconvert/ge9800/ge9800dc.cc b/libsrc/src/dconvert/ge9800/ge9800dc.cc
new file mode 100644
index 0000000..6b93518
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800dc.cc
@@ -0,0 +1,92 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800dc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ge9800dc.h"
+#include "ge9800.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "ge9800src.h"
+
+bool
+GE9800_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!ge9800hdr) ge9800hdr=new GE9800_Header_BothClass(in);
+	Assert(ge9800hdr);
+
+	ge9800hdr->ToDicom_Template(list);
+	ge9800hdr->ToDicom_ManualMisc(list);
+	ge9800hdr->ToDicom_ManualPlane(list);
+	ge9800hdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in ge9800.h about the importance of the scope
+// of a GE9800_Conversion object and AttributeList object
+
+bool
+GE9800_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!ge9800hdr) ge9800hdr=new GE9800_Header_BothClass(in);
+	Assert(ge9800hdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	pixeldatasrc=new GE9800_PixelDataSource(
+		*in,
+		GE9800_UsePixelDataMap,
+		GE9800_Offset_PixelDataMap_ptr,
+		GE9800_Offset_PixelData_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+GE9800_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800dc.h b/libsrc/src/dconvert/ge9800/ge9800dc.h
new file mode 100644
index 0000000..28b39d9
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800dc.h
@@ -0,0 +1,7 @@
+/* ge9800dc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ge9800cl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "ge9800ptrs.h"
diff --git a/libsrc/src/dconvert/ge9800/ge9800dmp.cc b/libsrc/src/dconvert/ge9800/ge9800dmp.cc
new file mode 100644
index 0000000..be29f14
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800dmp.cc
@@ -0,0 +1,37 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800dmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ge9800dmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "ge9800.h"
+
+bool
+GE9800_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!ge9800hdr) ge9800hdr=new GE9800_Header_BothClass(in);
+	Assert(ge9800hdr);
+
+	TextOutputStream out(o);
+
+	ge9800hdr->DumpCommon(&out);
+
+	return true;
+}
+
+
+bool
+GE9800_Conversion::dumpSelectedImage(ostream &o,unsigned imagenumber)
+{
+	Assert(in);
+	if (!ge9800hdr) ge9800hdr=new GE9800_Header_BothClass(in);
+	Assert(ge9800hdr);
+
+	TextOutputStream out(o);
+
+	ge9800hdr->DumpSelectedImage(&out,imagenumber);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800dmp.h b/libsrc/src/dconvert/ge9800/ge9800dmp.h
new file mode 100644
index 0000000..eddb665
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800dmp.h
@@ -0,0 +1,4 @@
+/* ge9800dmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ge9800cl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/ge9800/ge9800dmpf.cc b/libsrc/src/dconvert/ge9800/ge9800dmpf.cc
new file mode 100644
index 0000000..bc1e316
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800dmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800dmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ge9800dmp.h"
+#include "ge9800ptrs.h"
+#include "ge9800dmpf.h"
diff --git a/libsrc/src/dconvert/ge9800/ge9800hdrc.cc b/libsrc/src/dconvert/ge9800/ge9800hdrc.cc
new file mode 100644
index 0000000..354084f
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800hdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800hdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "ge9800ptrs.h"
+#include "ge9800hdrp.h"
+#include "ge9800hdrw.h"
+#include "ge9800hdrc.h"
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800mdt.cc b/libsrc/src/dconvert/ge9800/ge9800mdt.cc
new file mode 100644
index 0000000..303ed58
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800mdt.cc
@@ -0,0 +1,64 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800mdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ge9800dc.h"
+#include "elmconst.h"
+
+void 
+GE9800_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),
+		Date(
+			GE9800_HeaderInstance_EXAMHDR->EXAMSTARTDATEYY,
+			GE9800_HeaderInstance_EXAMHDR->EXAMSTARTDATEMM,
+			GE9800_HeaderInstance_EXAMHDR->EXAMSTARTDATEDD
+		));
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),
+		Time(
+			GE9800_HeaderInstance_EXAMHDR->EXAMSTARTTIMEHH,
+			GE9800_HeaderInstance_EXAMHDR->EXAMSTARTTIMEMM,
+			GE9800_HeaderInstance_EXAMHDR->EXAMSTARTTIMESS
+		));
+
+	// ContentDate (formerly Image)
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+		Date(
+			GE9800_HeaderInstance_IMAGE1HDR->RECONDATEYY,
+			GE9800_HeaderInstance_IMAGE1HDR->RECONDATEMM,
+			GE9800_HeaderInstance_IMAGE1HDR->RECONDATEDD
+		));
+
+	// ContentTime (formerly Image)
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+		Time(
+			GE9800_HeaderInstance_IMAGE1HDR->RECONTIMEHH,
+			GE9800_HeaderInstance_IMAGE1HDR->RECONTIMEMM,
+			GE9800_HeaderInstance_IMAGE1HDR->RECONTIMESS
+		));
+
+	// AcquisitionDate
+
+	(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),
+		Date(
+			GE9800_HeaderInstance_IMAGE1HDR->STARTOFSCANDATEYY,
+			GE9800_HeaderInstance_IMAGE1HDR->STARTOFSCANDATEMM,
+			GE9800_HeaderInstance_IMAGE1HDR->STARTOFSCANDATEDD
+		));
+
+	// AcquisitionTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),
+		Time(
+			GE9800_HeaderInstance_IMAGE1HDR->STARTOFSCANTIMEHH,
+			GE9800_HeaderInstance_IMAGE1HDR->STARTOFSCANTIMEMM,
+			GE9800_HeaderInstance_IMAGE1HDR->STARTOFSCANTIMESS
+		));
+}
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800mmsc.cc b/libsrc/src/dconvert/ge9800/ge9800mmsc.cc
new file mode 100644
index 0000000..15dae13
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800mmsc.cc
@@ -0,0 +1,174 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800mmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ge9800dc.h"
+#include "elmconst.h"
+
+void 
+GE9800_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	
+	{
+		// BitsStored
+		// HighBit
+
+		Int16 bitsstored = GE9800_HeaderInstance_IMAGE1HDR->DataRange;
+		
+		if (bitsstored <= 0) {	// seen as -1 for YL files
+			bitsstored = 12;
+		}
+
+		(*list)+=new UnsignedShortAttribute(TagFromName(BitsStored),bitsstored);
+		(*list)+=new UnsignedShortAttribute(TagFromName(HighBit),bitsstored-1);
+	}
+	{
+		// Rows
+
+		Uint16 rows =
+			(GE9800_HeaderInstance_IMAGE1HDR->FileType == 2)	// Scout
+			? GE9800_HeaderInstance_IMAGE1HDR->ViewsPerScan
+			: GE9800_HeaderInstance_IMAGE1HDR->ImageSize;
+		
+		(*list)+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+	}
+	{
+		// Columns
+
+		Uint16 columns =
+			(GE9800_HeaderInstance_IMAGE1HDR->FileType == 2)	// Scout
+			? GE9800_HeaderInstance_IMAGE1HDR->DetectorsPerView
+			: GE9800_HeaderInstance_IMAGE1HDR->ImageSize;
+
+		(*list)+=new UnsignedShortAttribute(TagFromName(Columns),columns);
+	}
+	{
+		// WindowCenter
+		// WindowWidth
+
+		Int16 center = GE9800_HeaderInstance_IMAGE1HDR->LevelSetting;
+		Int16 width = GE9800_HeaderInstance_IMAGE1HDR->WindowSetting;
+		
+		if (width > 0) {
+			(*list)+=new DecimalStringAttribute(TagFromName(WindowCenter),center);
+			(*list)+=new DecimalStringAttribute(TagFromName(WindowWidth),width);
+		}
+	}
+
+	{
+		// ImageType
+
+		char *value1,*value2,*value3;
+
+		switch (GE9800_HeaderInstance_IMAGE1HDR->FileType) {
+			case 1:		// Prospective
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="AXIAL";
+					break;
+			case 2:		// Scout
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="LOCALIZER";
+					break;
+			case 3:		// Retrospective
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="AXIAL";
+					break;
+			case 4:		// Segmented
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="AXIAL";
+					break;
+			case 5:		// Screensave
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="AXIAL";
+					break;
+			case 6:		// Plot
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="OTHER";
+					break;
+			default:
+					value1="";
+					value2="";
+					value3="";
+					break;
+		}
+
+		(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+			value1,value2,value3);
+	}
+	
+	{
+		// ConvolutionKernel
+
+		char *str;
+
+		switch (GE9800_HeaderInstance_IMAGE1HDR->PreprocessReconType) {
+			case 0:		str="UNDEFINED";
+					break;
+			case 1:		str="BONE";
+					break;
+			case 2:		str="SOFTTISSUE";
+					break;
+			case 3:		str="QUICKSOFTTISSUE";
+					break;
+			default:	str="";
+					break;
+		}
+
+		(*list)+=new ShortStringAttribute(TagFromName(ConvolutionKernel),str);
+	}
+
+	{
+		// FilterType
+
+		char *str;
+		switch (GE9800_HeaderInstance_IMAGE1HDR->BowtieFilter) {
+			case 1:		str="BODY"; break;
+			case 2:		str="HEAD"; break;
+			case 3:		str="A"; break;
+			default:	str=""; break;
+		}
+		(*list)+=new ShortStringAttribute(TagFromName(FilterType),str);
+	}
+	{
+		// RotationDirection
+
+		char *str;
+		switch (GE9800_HeaderInstance_IMAGE1HDR->RotationDirection) {
+			case 1:		str="CW"; break;
+			case 2:		str="CC"; break;
+			default:	str=""; break;
+		}
+		(*list)+=new CodeStringAttribute(TagFromName(RotationDirection),str);
+	}
+	{
+		// ExposureTime
+
+		Uint16 exposuretime = (Uint16)(GE9800_HeaderInstance_IMAGE1HDR->ScanTime * 1000.0);
+		(*list)+=new IntegerStringAttribute(TagFromName(ExposureTime),exposuretime);
+	}
+
+	{
+		// BodyPartExamined
+		
+		// guess from filter ...
+
+		char *str;
+		switch (GE9800_HeaderInstance_IMAGE1HDR->BowtieFilter) {
+			case 1:		str="WHOLEBODY"; break;
+			case 2:		str="HEAD"; break;
+			default:	str=NULL; break;
+		}
+		if (str) {
+			(*list)+=new CodeStringAttribute(TagFromName(BodyPartExamined),str);
+		}
+		else {
+			(*list)+=new CodeStringAttribute(TagFromName(Laterality));		// laterality is Type 2 if can't tell if unpaired body part
+		}
+	}
+	
+}
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800mpln.cc b/libsrc/src/dconvert/ge9800/ge9800mpln.cc
new file mode 100644
index 0000000..4f5b2d5
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800mpln.cc
@@ -0,0 +1,240 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ge9800mpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ge9800dc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+GE9800_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	// GE 9800 plane definitions are unknown:
+	// ? units of X,Y center
+	// ? direction of table position
+	// assume Left Ant Superior +ve (for no really good reason)
+
+	// DICOM plane definitions are:
+	// - Left Pos Superior +ve
+
+	// Determine the plane of the image ...
+	// There is really no valid way to do this for other
+	// than Prospective & Scout views, so presume axial
+
+	ImagePlanePlane plane;
+
+	// Determine the "machine" plane of the image ...
+
+		switch (GE9800_HeaderInstance_IMAGE1HDR->FileType) {
+			case 1:	// Prospective
+					plane=Axial;
+					break;
+
+			case 2:	// Scout - use tube azimuth later
+					// 0 degrees is AP Scout
+					plane=Coronal;
+		// this is theoretically ok, but 9800 seems to rotate
+		// the lateral scout to F/P rather than A/F :(
+		// need to do some tests to see in which cases this happens
+					break;
+
+			case 3:		// Retrospective
+			case 4:		// Segmented
+			case 5:		// Screensave
+			case 6:		// Plot
+			default:	// :(
+					plane=Axial;
+					break;
+		}
+
+	ImagePlaneHeadFeet orientation;
+
+		switch (GE9800_HeaderInstance_IMAGE1HDR->PatientOrientation) {
+			case 1:
+					hfff="HF";
+					orientation=HeadFirst;
+					break;
+			case 2:
+					hfff="FF";
+					orientation=FeetFirst;
+					break;
+			default:	hfff="";		// :(
+					orientation=HeadFirst;
+					break;
+		}
+
+	ImagePlanePosition position;
+
+		switch (GE9800_HeaderInstance_IMAGE1HDR->APPatientOrientation) {
+			case 1:
+					ap="P";
+					position=Prone;
+					break;
+			case 2:
+					ap="S";
+					position=Supine;
+					break;
+			case 3:
+					ap="DL";
+					position=LeftLateralDecubitus;
+					break;
+			case 4:
+					ap="DR";
+					position=RightLateralDecubitus;
+					break;
+			default:	ap="";			// :(
+					position=Supine;
+					break;
+		}
+
+		double xscanfov;
+		double yscanfov;
+
+		if (GE9800_HeaderInstance_IMAGE1HDR->FileType == 2) {	// Scout
+			// Could use CT98_ViewsPerScan.toUS() * pixsize ...
+
+			yscanfov = GE9800_HeaderInstance_IMAGE1HDR->ScoutEndLocation - GE9800_HeaderInstance_IMAGE1HDR->SlicePosition;
+			if (yscanfov < 0) yscanfov=-yscanfov;
+
+			// Could use CT98_ReconPixelSize for pixsize ...
+			// Could use CT98_ViewSpacing    for pixsize ...
+			// but calculating it is more accurate
+
+			double pixsize = yscanfov / GE9800_HeaderInstance_IMAGE1HDR->ViewsPerScan;
+
+			xscanfov = GE9800_HeaderInstance_IMAGE1HDR->DetectorsPerView * pixsize;
+		}
+		else {
+			// These may actually different, but the image
+			// is always square, so select the maximum,
+			// otherwise the mag/recon scaling will fail
+
+			xscanfov = GE9800_HeaderInstance_IMAGE1HDR->XDiameter;
+			yscanfov = GE9800_HeaderInstance_IMAGE1HDR->YDiameter;
+			if (xscanfov > yscanfov) yscanfov=xscanfov;
+			if (yscanfov > xscanfov) xscanfov=yscanfov;
+		}
+
+		double scanfov = (xscanfov > yscanfov) ? xscanfov : yscanfov;
+
+		double xreconfov;
+		double yreconfov;
+
+		if (GE9800_HeaderInstance_IMAGE1HDR->FileType == 2) {	// Scout
+			xreconfov = xscanfov;
+			yreconfov = xscanfov;
+		}
+		else {
+			xreconfov = GE9800_HeaderInstance_IMAGE1HDR->ReconXDiameter;
+			yreconfov = GE9800_HeaderInstance_IMAGE1HDR->ReconYDiameter;
+		}
+
+		double reconfov = (xreconfov > yreconfov)
+				 ? xreconfov : yreconfov;
+
+	// Make a model of the image plane ...
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlanet" << endl;
+
+	ImagePlane imageplane(plane,xscanfov,yscanfov,orientation,position);
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlane done" << endl;
+//imageplane.put(cerr);
+
+		// If scout, rotate into the correct plane ...
+
+		// Rotation is CCW around Z
+		// eg. Right Lateral is +90 degrees		... note sure this is correct ... have seen examples of the opposite ... need to check more samples :(
+
+		if (GE9800_HeaderInstance_IMAGE1HDR->FileType == 2) {	// Scout 
+			imageplane.MachinePlane::angle(
+				HeadFeet,-(double)GE9800_HeaderInstance_IMAGE1HDR->TubeAzimuth);	// Note sign change ... not entirely sure this is correct ... need to check more samples :(
+		}
+
+		// While we are in the "display" or "gantry plane ...
+		// (before angulation) 
+
+		// Apply any transformations specified in the
+		// display/gantry plane, such as magnification and
+		// reconstruction target offsets ...
+
+		// Assume that offsets are machine rather than body relative
+
+		// Could use reconfov/scanfov ... same effect ...
+
+		double reconfac	= GE9800_HeaderInstance_IMAGE1HDR->ReconMagFactor;
+		double reconch	= GE9800_HeaderInstance_IMAGE1HDR->ReconXCenter;
+		double reconcv	= GE9800_HeaderInstance_IMAGE1HDR->ReconYCenter;
+
+		if (reconfac > .00001) {	// ie. not zero
+			imageplane.MachinePlane::scale(1.0/reconfac);
+
+			imageplane.MachinePlane::shift(
+				Vector3D(reconch,-reconcv,0));
+		}
+
+		double magfac	= GE9800_HeaderInstance_IMAGE1HDR->MagFactor;
+		double magch	= GE9800_HeaderInstance_IMAGE1HDR->XCenter;
+		double magcv	= GE9800_HeaderInstance_IMAGE1HDR->YCenter;
+
+		if (magfac > .00001) {	// ie. not zero
+			imageplane.MachinePlane::scale(1.0/magfac);
+
+			imageplane.MachinePlane::shift(
+				Vector3D(magch,-magcv,0));
+		}
+
+		// CT9800 -ve is top towards table
+		// Z is +ve into gantry, but X is +ve left, so leave sign alone
+
+		double gantrydetectortilt=GE9800_HeaderInstance_IMAGE1HDR->GantryAngle;
+
+		imageplane.MachinePlane::angle(LeftRight,gantrydetectortilt);
+
+		// Account for physical offsets after angulation ...
+		// CT9800 SlicePosition is positive into gantry
+
+		// For scouts SlicePosition is start position not center
+
+		{
+			double zoffset;
+
+			if (GE9800_HeaderInstance_IMAGE1HDR->FileType == 2) {	// Scout
+				zoffset=((double)(GE9800_HeaderInstance_IMAGE1HDR->ScoutEndLocation)
+				        +GE9800_HeaderInstance_IMAGE1HDR->SlicePosition)/2;
+			}
+			else {
+				zoffset=GE9800_HeaderInstance_IMAGE1HDR->SlicePosition;
+			}
+			imageplane.MachinePlane::shift(Vector3D(0,0,zoffset));
+		}
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+//cerr << "ToDicom_ManualPlane::addPlaneToList:" << endl;
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+//cerr << "ToDicom_ManualPlane::addPlaneToList done:" << endl;
+
+	// PixelSpacing
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		GE9800_HeaderInstance_IMAGE1HDR->ReconPixelSize,
+		GE9800_HeaderInstance_IMAGE1HDR->ReconPixelSize);
+
+	// ReconstructionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),reconfov);
+
+	// DataCollectionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(DataCollectionDiameter),scanfov);
+		
+}
+
diff --git a/libsrc/src/dconvert/ge9800/ge9800ptrs.h b/libsrc/src/dconvert/ge9800/ge9800ptrs.h
new file mode 100644
index 0000000..77fa872
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800ptrs.h
@@ -0,0 +1,16 @@
+/* ge9800ptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// Offsets are in bytes from 0
+// Offsets extracted from header are in 2 byte words - blocks are 512 bytes long
+
+#define	GE9800_Offset_GLOBALHDR_ptr	0
+
+// these are not qualified by "ge9800hdr->", since they are used within methods of that instance's class (GE9800_Conversion) ...
+#define	GE9800_Offset_EXAMHDR_ptr	(GE9800_HeaderInstance_GLOBALHDR->EXAMHDRPTR		? (GE9800_HeaderInstance_GLOBALHDR->EXAMHDRPTR   - 1u)*2 : 512)
+#define	GE9800_Offset_IMAGE1HDR_ptr	(GE9800_HeaderInstance_GLOBALHDR->IMAGE1HDRPTR	? (GE9800_HeaderInstance_GLOBALHDR->IMAGE1HDRPTR - 1u)*2 : 1024)
+#define	GE9800_Offset_IMAGE2HDR_ptr	(GE9800_HeaderInstance_GLOBALHDR->IMAGE2HDRPTR	? (GE9800_HeaderInstance_GLOBALHDR->IMAGE2HDRPTR - 1u)*2 : 1536)
+
+// these are  qualified by "ge9800hdr->", since they are used outside methods of that instance's class (GE9800_Conversion) ...
+#define GE9800_Offset_PixelDataMap_ptr	(ge9800hdr->GE9800_HeaderInstance_GLOBALHDR->IMAGEMAPPTR   ? (ge9800hdr->GE9800_HeaderInstance_GLOBALHDR->IMAGEMAPPTR  - 1u)*2  : (ge9800hdr->GE9800_HeaderInstance_IMAGE1HDR->GroupType == 5 ?  9 : 4)*512 )
+#define GE9800_Offset_PixelData_ptr		(ge9800hdr->GE9800_HeaderInstance_GLOBALHDR->IMAGEDATAPTR  ? (ge9800hdr->GE9800_HeaderInstance_GLOBALHDR->IMAGEDATAPTR - 1u)*2  : (ge9800hdr->GE9800_HeaderInstance_IMAGE1HDR->GroupType == 5 ? 11 : 6)*512 )
+
+#define	GE9800_UsePixelDataMap		(ge9800hdr->GE9800_HeaderInstance_IMAGE1HDR->UseImageMap == 1 ? true : false)			// 1=y,2=n
diff --git a/libsrc/src/dconvert/ge9800/ge9800src.h b/libsrc/src/dconvert/ge9800/ge9800src.h
new file mode 100644
index 0000000..5e86a3d
--- /dev/null
+++ b/libsrc/src/dconvert/ge9800/ge9800src.h
@@ -0,0 +1,121 @@
+/* ge9800src.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ge9800src__
+#define __Header_ge9800src__
+
+class GE9800_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *map;
+	Uint16 *buffer;
+	Int16 last_pixel;
+public:
+	GE9800_PixelDataSource(istream& i,bool usemap,long mapoff,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+			last_pixel=0;
+			if (usemap) {
+				map = new Uint16[rows];
+				Assert(map);
+				Assert(istr);
+				istr->seekg(mapoff,ios::beg);
+				unsigned i;
+				for (i=0; i<rows; ++i) {
+					unsigned char bytes[2];
+					istr->read((char *)bytes,2);
+					Assert(istr->good());
+					// Big endian ...
+					map[i]=(bytes[0]<<8)|bytes[1];
+				}
+			}
+			else {
+				map = NULL;
+			}
+		}
+
+	~GE9800_PixelDataSource()
+		{
+			if (map) delete[] map;
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			
+			unsigned 	start;
+			unsigned 	end;
+			if (map) {
+				unsigned line = map[row];
+				start = columns/2-line;
+				end	= start+line*2;
+			}
+			else {
+				start = 0;
+				end	= columns;
+			}
+
+			if (!istr->good() || row++ >= rows) return 0;
+
+			Uint16 *ptr=buffer;
+
+			// Pad the first "empty" part of the line ...
+			for (col=0; col<start; col++) *ptr++=0;
+			
+			Assert(col == start);
+			
+			while (col < end) {
+				unsigned char byte;
+				istr->read((char *)&byte,1);
+				if (!istr->good()) return 0;
+				if (byte & 0x80) {
+					signed char delta;
+					if (byte & 0x40) {
+						delta=byte;
+					}
+					else {
+						delta=byte & 0x3f;
+					}
+					last_pixel+=delta;
+				}
+				else {
+					last_pixel=byte << 8;
+					istr->read((char *)&byte,1);
+					if (!istr->good()) return 0;
+					last_pixel+=byte;
+				}
+				*ptr++=(Uint16)last_pixel & 0x0fff;
+				++col;
+			}
+			
+			Assert(col == end);
+			
+			// Pad the last "empty" part of the line ...
+			for (col=end; col<columns; col++) *ptr++=0;
+			
+			return columns;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_ge9800src__
diff --git a/libsrc/src/dconvert/gen/Imakefile b/libsrc/src/dconvert/gen/Imakefile
new file mode 100755
index 0000000..1767c14
--- /dev/null
+++ b/libsrc/src/dconvert/gen/Imakefile
@@ -0,0 +1,31 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = gendc.cc genconv.cc genmpln.cc \
+		 genmmsc.cc genmdt.cc \
+		 gendmp.cc gendmpf.cc \
+		 genhdrc.cc gen.cc
+
+OBJS = 		 gendc.o  genconv.o  genmpln.o  \
+		 genmmsc.o  genmdt.o  \
+		 gendmp.o  gendmpf.o  \
+		 genhdrc.o  gen.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdgen.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(gen,dconvert)
+ProjectInstallOnMakeUpdatedLibraryHeader(geninfo,dconvert)
+
+ProjectConvertTemplate(genhdrp.h,gen,convert,prefix=GEN_ role=headerpart offsetwarning=off)
+ProjectConvertTemplate(genhdrw.h,gen,convert,prefix=GEN_ role=wholeheader headerclassparameters=",GEN_FileStructureInformation &fileinfo")
+ProjectConvertTemplate(genhdrc.h,gen,convert,prefix=GEN_ role=constructheader headerclassparameters=",GEN_FileStructureInformation &fileinfo")
+ProjectConvertTemplate(genconv.h,gen,convert,prefix=GEN_ role=dicom)
+ProjectConvertTemplate(gendmpf.h,gen,convert,prefix=GEN_ role=dump)
+
+gendmpf.o: gendmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) gendmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/gen/Imakefile.tmpl b/libsrc/src/dconvert/gen/Imakefile.tmpl
new file mode 100755
index 0000000..1767c14
--- /dev/null
+++ b/libsrc/src/dconvert/gen/Imakefile.tmpl
@@ -0,0 +1,31 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = gendc.cc genconv.cc genmpln.cc \
+		 genmmsc.cc genmdt.cc \
+		 gendmp.cc gendmpf.cc \
+		 genhdrc.cc gen.cc
+
+OBJS = 		 gendc.o  genconv.o  genmpln.o  \
+		 genmmsc.o  genmdt.o  \
+		 gendmp.o  gendmpf.o  \
+		 genhdrc.o  gen.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdgen.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(gen,dconvert)
+ProjectInstallOnMakeUpdatedLibraryHeader(geninfo,dconvert)
+
+ProjectConvertTemplate(genhdrp.h,gen,convert,prefix=GEN_ role=headerpart offsetwarning=off)
+ProjectConvertTemplate(genhdrw.h,gen,convert,prefix=GEN_ role=wholeheader headerclassparameters=",GEN_FileStructureInformation &fileinfo")
+ProjectConvertTemplate(genhdrc.h,gen,convert,prefix=GEN_ role=constructheader headerclassparameters=",GEN_FileStructureInformation &fileinfo")
+ProjectConvertTemplate(genconv.h,gen,convert,prefix=GEN_ role=dicom)
+ProjectConvertTemplate(gendmpf.h,gen,convert,prefix=GEN_ role=dump)
+
+gendmpf.o: gendmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) gendmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/gen/README b/libsrc/src/dconvert/gen/README
new file mode 100755
index 0000000..97c5db9
--- /dev/null
+++ b/libsrc/src/dconvert/gen/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"gen.h"
+		class GEN_Conversion {
+			GEN_Conversion(istream &i,ostream &e);
+			virtual ~GEN_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"gen.cc"
+
+		GEN_Conversion::GEN_Conversion(istream &i,ostream &e);
+		GEN_Conversion::~GEN_Conversion();
+
+	"gencl.h"
+
+		class GEN_Header_BothClass  : public GEN_HeaderClass
+		{
+		public:
+			GEN_Header_BothClass(istream *ist) : GEN_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"genconv.cc"
+
+		#include "genconv.h"
+
+	"gendc.c"
+
+		bool GEN_Conversion::convertHeader(AttributeList *list);
+		bool GEN_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool GEN_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"gendc.h"
+
+	"gendmp.cc"
+
+		bool GEN_Conversion::dump(ostream &o);
+
+	"gendmp.h"
+
+	"genhdrc.cc"
+
+		#include "genhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"gen.tpl"
+
+		The template "describing" the format for header generation
+
+	"genmdt.cc"
+
+		void GEN_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"genmmsc.cc"
+
+		void GEN_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"genmpln.cc"
+
+		void GEN_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"genptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"gensrc.h"
+
+		class GEN_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			GEN_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~GEN_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from gen.tpl:
+
+	"genhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class GEN_HeaderClass_HDR1 {
+		public:
+			GEN_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"genhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class GEN_HeaderClass
+		{
+		public:
+			GEN_HeaderClass(istream *ist);
+
+			GEN_HeaderClass_HDR1 *GEN_HeaderInstance_HDR1;
+			GEN_HeaderClass_HDR2 *GEN_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"genhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		GEN_HeaderClass::GEN_HeaderClass(istream *ist);
+
+	"genconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void GEN_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"gendmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void GEN_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "genhdrm.h".
+
+	if you have special purpose code, then "genhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "genhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/gen/gen.cc b/libsrc/src/dconvert/gen/gen.cc
new file mode 100644
index 0000000..81e2497
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gen.cc
@@ -0,0 +1,55 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gen.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "gen.h"
+#include "gencl.h"
+#include "srcsink.h"
+#include "gensrc.h"
+
+void
+GEN_Conversion::init(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	genhdr=0;
+	pixeldatasrc=0;
+}
+
+GEN_Conversion::GEN_Conversion(istream &i,ostream &e)
+{
+	init(i,e);
+	// use GEN_FileStructureInformation as constructed already
+}
+
+GEN_Conversion::GEN_Conversion(istream &i,ostream &e,
+		bool explicitoff,
+		bool lengthpresent,
+		Uint32 fileptr,
+		Uint32 suiteptr,
+		Uint32 examptr,
+		Uint32 seriesptr,
+		Uint32 imageptr)
+{
+	init(i,e);
+	fileinfo=GEN_FileStructureInformation(
+		explicitoff,	// explicit
+		lengthpresent,	// length field
+		fileptr,	// file header
+		suiteptr,	// suite header
+		examptr,	// exam header
+		seriesptr,	// series header
+		imageptr);	// image header
+}
+
+GEN_Conversion::~GEN_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (genhdr) delete genhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/gen/gen.h b/libsrc/src/dconvert/gen/gen.h
new file mode 100644
index 0000000..5ed5d16
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gen.h
@@ -0,0 +1,61 @@
+/* gen.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_gen__
+#define __Header_gen__
+
+#include "geninfo.h"
+
+// NB. a GEN_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~GEN_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class GEN_Header_BothClass;
+class GEN_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class GEN_Conversion {
+	GEN_Header_BothClass *genhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	GEN_PixelDataSource *pixeldatasrc;
+
+	GEN_FileStructureInformation fileinfo;
+
+	void init(istream &i,ostream &e);
+public:
+	GEN_Conversion(istream &i,ostream &e);
+
+	GEN_Conversion(istream &i,ostream &e,
+		bool explicitoff,
+		bool lengthpresent,
+		Uint32 fileptr,
+		Uint32 suiteptr,
+		Uint32 examptr,
+		Uint32 seriesptr,
+		Uint32 imageptr);
+
+	virtual ~GEN_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0)
+		{
+			(void)out; (void)imagenumber;
+			return true;
+		}
+
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_gen__ */
+
diff --git a/libsrc/src/dconvert/gen/gen.tpl b/libsrc/src/dconvert/gen/gen.tpl
new file mode 100755
index 0000000..ac5e101
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gen.tpl
@@ -0,0 +1,634 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="FILEHDR"	offset="0"	intype="Int32_B"	inlength="1"	name="IH_img_magic"		dicomtype="?"	dicomtag="?"		#  magic number
+block="FILEHDR"	offset="4"	intype="Int32_B"	inlength="1"	keyword="IH_img_hdr_length"	dicomtype="?"	dicomtag="?"		#  a byte displacement to the <pixel data area>
+block="FILEHDR"	offset="8"	intype="Int32_B"	inlength="1"	keyword="IH_img_width"		dicomtype="?"	dicomtag="?"		#  width (pixels) of image
+block="FILEHDR"	offset="12"	intype="Int32_B"	inlength="1"	keyword="IH_img_height"		dicomtype="?"	dicomtag="?"		#  height (pixels) of image
+block="FILEHDR"	offset="16"	intype="Int32_B"	inlength="1"	keyword="IH_img_depth"		dicomtype="?"	dicomtag="?"		#  depth (1, 8, 16, or 24 bits) of
+block="FILEHDR"	offset="20"	intype="Int32_B"	inlength="1"	keyword="IH_img_compress"	dicomtype="?"	dicomtag="?"		#  type of compression; see IC_* below
+block="FILEHDR"	offset="24"	intype="Int32_B"	inlength="1"	name="IH_img_dwindow"		dicomtype="DS"	dicomtag="WindowWidth"	#  default window setting
+block="FILEHDR"	offset="28"	intype="Int32_B"	inlength="1"	name="IH_img_dlevel"		dicomtype="DS"	dicomtag="WindowCenter"	#  default level setting
+block="FILEHDR"	offset="32"	intype="Int32_B"	inlength="1"	name="IH_img_bgshade"		dicomtype="?"	dicomtag="?"		#  background shade to use for non-image
+block="FILEHDR"	offset="36"	intype="Int32_B"	inlength="1"	name="IH_img_ovrflow"		dicomtype="?"	dicomtag="?"		#  overflow value
+block="FILEHDR"	offset="40"	intype="Int32_B"	inlength="1"	name="IH_img_undflow"		dicomtype="?"	dicomtag="?"		#  underflow value
+block="FILEHDR"	offset="44"	intype="Int32_B"	inlength="1"	name="IH_img_top_offset"	dicomtype="?"	dicomtag="?"		#  number of blank lines at image top
+block="FILEHDR"	offset="48"	intype="Int32_B"	inlength="1"	name="IH_img_bot_offset"	dicomtype="?"	dicomtag="?"		#  number of blank lines at image bottom
+block="FILEHDR"	offset="52"	intype="Int16_B"	inlength="1"	name="IH_img_version"		dicomtype="LO"	dicomtag="SoftwareVersions"	#  version of the header structure
+block="FILEHDR"	offset="54"	intype="Uint16_B"	inlength="1"	name="IH_img_checksum"		dicomtype="?"	dicomtag="?"		#  16 bit end_around_carry sum of pixels
+block="FILEHDR"	offset="56"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_id"		dicomtype="?"	dicomtag="?"		#  a byte disp to unique image identifier
+block="FILEHDR"	offset="60"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_id"		dicomtype="?"	dicomtag="?"		#  byte length of unique image identifier
+block="FILEHDR"	offset="64"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_unpack"	dicomtype="?"	dicomtag="?"		#  a byte disp to <unpack control>
+block="FILEHDR"	offset="68"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_unpack"	dicomtype="?"	dicomtag="?"		#  byte length of <unpack control>
+block="FILEHDR"	offset="72"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_compress"	dicomtype="?"	dicomtag="?"		#  a byte disp to <compression control>
+block="FILEHDR"	offset="76"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_compress"	dicomtype="?"	dicomtag="?"		#  byte length of <compression control>
+block="FILEHDR"	offset="80"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_histo"	dicomtype="?"	dicomtag="?"		#  a byte disp to <histogram control>
+block="FILEHDR"	offset="84"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_histo"	dicomtype="?"	dicomtag="?"		#  byte length of <histogram control>
+block="FILEHDR"	offset="88"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_text"		dicomtype="?"	dicomtag="?"		#  a byte disp to <text plane data>
+block="FILEHDR"	offset="92"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_text"		dicomtype="?"	dicomtag="?"		#  byte length of <text plane data>
+block="FILEHDR"	offset="96"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_graphics"	dicomtype="?"	dicomtag="?"		#  a byte disp to <graphics plane data>
+block="FILEHDR"	offset="100"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_graphics"	dicomtype="?"	dicomtag="?"		#  byte length of <graphics plane data>
+block="FILEHDR"	offset="104"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_dbHdr"	dicomtype="?"	dicomtag="?"		#  a byte disp to <data base header data>
+block="FILEHDR"	offset="108"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_dbHdr"	dicomtype="?"	dicomtag="?"		#  byte length of <data base header data>
+block="FILEHDR"	offset="112"	intype="Int32_B"	inlength="1"	keyword="IH_img_levelOffset"	dicomtype="DS"	dicomtag="RescaleIntercept"		#  value to add to stored Pixel Data values
+block="FILEHDR"	offset="116"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_user"		dicomtype="?"	dicomtag="?"		#  byte displacement to user defined data
+block="FILEHDR"	offset="120"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_user"		dicomtype="?"	dicomtag="?"		#  byte length of user defined data
+block="FILEHDR"	offset="124"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_suite"	dicomtype="?"	dicomtag="?"		#  byte displacement to <suite> header data
+block="FILEHDR"	offset="128"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_suite"	dicomtype="?"	dicomtag="?"		#  byte length of <suite> header data
+block="FILEHDR"	offset="132"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_exam"		dicomtype="?"	dicomtag="?"		#  byte displacement to <exam> header data
+block="FILEHDR"	offset="136"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_exam"		dicomtype="?"	dicomtag="?"		#  byte length of <exam> header data
+block="FILEHDR"	offset="140"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_series"	dicomtype="?"	dicomtag="?"		#  byte displacement to <series> header data
+block="FILEHDR"	offset="144"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_series"	dicomtype="?"	dicomtag="?"		#  byte length of <series> header data
+block="FILEHDR"	offset="148"	intype="Int32_B"	inlength="1"	keyword="IH_img_p_image"	dicomtype="?"	dicomtag="?"		#  byte displacement to <image> header data
+block="FILEHDR"	offset="152"	intype="Int32_B"	inlength="1"	keyword="IH_img_l_image"	dicomtype="?"	dicomtag="?"		#  byte length of <image> header data
+block="UIDHDR" condition="hasuid"	offset="0"	intype="Int32_B"	inlength="1"	name="ID_id_version"		dicomtype="?"	dicomtag="?"		#  version of the uid area
+block="UIDHDR" condition="hasuid"	offset="4"	intype="String"		inlength="80"	name="ID_id_text"		dicomtype="?"	dicomtag="?"		#  unique text area or orphan description
+block="HISTOHDR" condition="hashisto"	offset="0"	intype="Int32_B"	inlength="1"	name="HS_hs_version"		dicomtype="?"	dicomtag="?"		#  version of the histogram structure
+block="HISTOHDR"	condition="hashisto"	offset="4"	intype="IEEE_Float32_B"	inlength="1"	name="HS_hs_sd"			dicomtype="?"	dicomtag="?"		#  standard deviation of pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="8"	intype="Int16_B"	inlength="1"	name="HS_hs_mean"		dicomtype="?"	dicomtag="?"		#  rounded mean pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="10"	intype="Int16_B"	inlength="1"	name="HS_hs_min"		dicomtype="XS"	dicomtag="SmallestImagePixelValue"	#  minimum pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="12"	intype="Int16_B"	inlength="1"	name="HS_hs_max"		dicomtype="XS"	dicomtag="LargestImagePixelValue"	#  maximum pixel data value
+block="HISTOHDR"	condition="hashisto"	offset="14"	intype="Int16_B"	inlength="1"	name="HS_hs_first"		dicomtype="?"	dicomtag="?"		#  first histogram entry used for <hs_sd>
+block="HISTOHDR"	condition="hashisto"	offset="16"	intype="Int16_B"	inlength="1"	name="HS_hs_region"		dicomtype="?"	dicomtag="?"		#  region entries used for <hs_sd>
+block="HISTOHDR"	condition="hashisto"	offset="18"	intype="Int16_B"	inlength="1"	name="HS_hs_length"		dicomtype="?"	dicomtag="?"		#  number of bins in the histogram area
+block="SUITEHDR"	offset="0"	intype="String"	inlength="4"	name="SU_su_id"		dicomtype="?"	dicomtag="?"		#  Suite ID
+block="SUITEHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="SU_su_uniq"		dicomtype="?"	dicomtag="?"	#  Make Unique Flag
+block="SUITEHDR"	offset="6"	intype="String"	inlength="1"	name="SU_su_diskid"		dicomtype="?"	dicomtag="?"	#  Disk ID
+block="SUITEHDR"	offset="7"	intype="String"	inlength="13"	name="SU_prodid"		dicomtype="LO"	dicomtag="ManufacturerModelName"	#  Product ID
+block="SUITEHDR"	offset="20"	intype="String"	inlength="2"	name="SU_su_verscre"		dicomtype="?"	dicomtag="?"	#  Original Version of Record
+block="SUITEHDR"	offset="22"	intype="String"	inlength="2"	name="SU_su_verscur"		dicomtype="?"	dicomtag="?"	#  Current Version of Record
+block="SUITEHDR"	offset="24"	intype="Uint32_B"	inlength="1"	name="SU_su_checksum"		dicomtype="?"	dicomtag="?"	#  Suite Record Checksum
+block="SUITEHDR"	offset="28"	intype="String"	inlength="85"	name="SU_su_padding"		dicomtype="?"	dicomtag="?"	#  Spare Space
+block="EXAMHDR"	offset="0"	intype="String"	inlength="4"	name="EX_ex_suid"		dicomtype="SH"	dicomtag="StationName"	#  Suite ID for this Exam
+block="EXAMHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="EX_ex_uniq"		dicomtype="?"	dicomtag="?"		#  Make-Unique Flag
+block="EXAMHDR"	offset="6"	intype="String"	inlength="1"	name="EX_ex_diskid"		dicomtype="?"	dicomtag="?"		#  Disk ID for this Exam
+block="EXAMHDR"	offset="8"	intype="Uint16_B"	inlength="1"	keyword="EX_ex_no"		dicomtype="SH"	dicomtag="StudyID"	#  Exam Number
+block="EXAMHDR"	offset="10"	intype="String"	inlength="33"	name="EX_hospname"		dicomtype="LO"	dicomtag="InstitutionName"	#  Hospital Name
+block="EXAMHDR"	offset="44"	intype="Int16_B"	inlength="1"	name="EX_detect"		dicomtype="?"	dicomtag="?"	enum="1=Xenon,2=Hilight"	#  Detector Type
+block="EXAMHDR"	offset="46"	intype="Int32_B"	inlength="1"	name="EX_numcells"		dicomtype="?"	dicomtag="?"		#  Number of cells in det
+block="EXAMHDR"	offset="50"	intype="IEEE_Float32_B"	inlength="1"	name="EX_zerocell"		dicomtype="?"	dicomtag="?"		#  Cell number at theta
+block="EXAMHDR"	offset="54"	intype="IEEE_Float32_B"	inlength="1"	name="EX_cellspace"		dicomtype="?"	dicomtag="?"		#  Cell spacing
+block="EXAMHDR"	offset="58"	intype="IEEE_Float32_B"	inlength="1"	keyword="EX_srctodet"		dicomtype="?"	dicomtag="?"		#  Distance from source to detector
+block="EXAMHDR"	offset="62"	intype="IEEE_Float32_B"	inlength="1"	keyword="EX_srctoiso"		dicomtype="?"	dicomtag="?"		#  Distance from source to iso
+block="EXAMHDR"	offset="66"	intype="Int16_B"	inlength="1"	name="EX_tubetyp"		dicomtype="?"	dicomtag="?"	enum="0=MX100_TUBE,1=MX125_TUBE,2=TT9800:9800_TUBE,3=TT9100:9100_TUBE,4=HPRI_TUBE,5=HPRII_TUBE,6=ADV650_TUBE,7=ADV681_TUBE,8=ST2000CT_6_TUBE,9=ST2000CT_10_TUBE,12=MX_135CT_TUBE,13=MX_165CT_TUBE,14=MX_165CT_I_TUBE"	#  Tube type
+block="EXAMHDR"	offset="68"	intype="Int16_B"	inlength="1"	name="EX_dastyp"		dicomtype="?"	dicomtag="?"	enum="1=CDAS,2=EDAS"	#  DAS type
+block="EXAMHDR"	offset="70"	intype="Int16_B"	inlength="1"	name="EX_num_dcnk"		dicomtype="?"	dicomtag="?"		#  Number of Decon Kernals
+block="EXAMHDR"	offset="72"	intype="Int16_B"	inlength="1"	name="EX_dcn_len"		dicomtype="?"	dicomtag="?"		#  Number of elements in a Decon Kernal
+block="EXAMHDR"	offset="74"	intype="Int16_B"	inlength="1"	name="EX_dcn_density"	dicomtype="?"	dicomtag="?"			#  Decon Kernal density
+block="EXAMHDR"	offset="76"	intype="Int16_B"	inlength="1"	name="EX_dcn_stepsize"	dicomtype="?"	dicomtag="?"			#  Decon Kernal stepsize
+block="EXAMHDR"	offset="78"	intype="Int16_B"	inlength="1"	name="EX_dcn_shiftcnt"	dicomtype="?"	dicomtag="?"			#  Decon Kernal Shift Count
+block="EXAMHDR"	offset="80"	intype="Int32_B"	inlength="1"	keyword="EX_magstrength"	dicomtype="?"	dicomtag="?"		#  Magnet strength (in gauss)
+block="EXAMHDR"	offset="84"	intype="String"	inlength="13"	name="EX_patid"		dicomtype="LO"	dicomtag="PatientID"		#  Patient ID for this Exam
+block="EXAMHDR"	offset="97"	intype="String"	inlength="25"	name="EX_patname"	dicomtype="PN"	dicomtag="PatientName"		#  Patient Name
+block="EXAMHDR"	offset="122"	intype="Int16_B"	inlength="1"	keyword="EX_patage"	dicomtype="?"	dicomtag="?"			#  Patient Age (years, months or days)
+block="EXAMHDR"	offset="124"	intype="Int16_B"	inlength="1"	keyword="EX_patian"	dicomtype="?"	dicomtag="?"	enum="0=Years:Y,1=Months:M,2=Days:D,3=Weeks:W"	#  Patient Age Notation
+block="EXAMHDR"	offset="126"	intype="Int16_B"	inlength="1"	keyword="EX_patsex"	dicomtype="?"	dicomtag="?"	enum="1=Male:M,2=Female:F"	#  Patient Sex
+block="EXAMHDR"	offset="128"	intype="Int32_B"	inlength="1"	keyword="EX_patweight"	dicomtype="?"	dicomtag="?"			#  Patient Weight ? grams
+block="EXAMHDR"	offset="132"	intype="Int16_B"	inlength="1"	name="EX_trauma"	dicomtype="?"	dicomtag="?"	enum="0=Trauma Flag Off,1=Trauma Flag On"	#  Trauma Flag
+block="EXAMHDR"	offset="134"	intype="String"	inlength="61"	name="EX_hist"		dicomtype="LT"	dicomtag="AdditionalPatientHistory"	#  Patient History
+block="EXAMHDR"	offset="195"	intype="String"	inlength="13"	name="EX_reqnum"	dicomtype="?"	dicomtag="?"			#  Requisition Number
+block="EXAMHDR"	offset="208"	intype="Unix_DateTime_B"	inlength="1"	keyword="EX_ex_datetime"	dicomtype="?"	dicomtag="?"			#  Exam date/time stamp
+block="EXAMHDR"	offset="212"	intype="String"	inlength="33"	name="EX_refphy"	dicomtype="PN"	dicomtag="ReferringPhysicianName"	#  Referring Physician
+block="EXAMHDR"	offset="245"	intype="String"	inlength="33"	name="EX_diagrad"	dicomtype="PN"	dicomtag="PerformingPhysicianName"	#  Diagnostician/Radiologist
+block="EXAMHDR"	offset="278"	intype="String"	inlength="4"	name="EX_op"			dicomtype="PN"	dicomtag="OperatorsName"	#  Operator
+block="EXAMHDR"	offset="282"	intype="String"	inlength="23"	name="EX_ex_desc"		dicomtype="LO"	dicomtag="StudyDescription"	#  Exam Description
+block="EXAMHDR"	offset="305"	intype="String"	inlength="3"	keyword="EX_ex_typ"		dicomtype="CS"	dicomtag="Modality"		#  Exam Type ('CT' or 'MR')
+block="EXAMHDR"	offset="308"	intype="Int16_B"	inlength="1"	name="EX_ex_format"		dicomtype="?"	dicomtag="?"	enum="0=Foreign,1=Genesis Image,2=Technicare HPS1440,3=Technicare Delta Scan 2010,4=Technicare Delta Scan 2020,5=Technicare Delta Scan 2060,6=Signa,7=CT9800,8=CT9800 Q,9=CT9800 QHL,10=EMI_9800,11=CT_8800_9800,12=CT9600,13=Jupiter,14=Zeus:CT HiSpeed Advantage,15=CT HiSpeed Advantage VX,16=Resona,17=Vectra,18=MR Max,19=CT Max,20=CT Pace,21=CT Sytec 2000,22=CT Sytec 3000,23=CT Sytec 40 [...]
+block="EXAMHDR"	offset="310"	intype="IEEE_Float64_B"	inlength="1"	name="EX_firstaxtime"	dicomtype="?"	dicomtag="?"		#  Start time(secs) of first axial in exam
+block="EXAMHDR"	offset="318"	intype="String"	inlength="9"	name="EX_ex_sysid"		dicomtype="?"	dicomtag="?"		#  Creator Suite and Host
+block="EXAMHDR"	offset="328"	intype="Unix_DateTime_B"	inlength="1"	keyword="EX_ex_lastmod"		dicomtype="?"	dicomtag="?"		#  Date/Time of Last Change
+block="EXAMHDR"	offset="332"	intype="Int16_B"	inlength="1"	name="EX_protocolflag"	dicomtype="?"	dicomtag="?"		#  Non-Zero indicates Protocol Exam
+block="EXAMHDR"	offset="334"	intype="String"	inlength="13"	name="EX_ex_alloc_key"	dicomtype="?"	dicomtag="?"		#  Process that allocated this record
+block="EXAMHDR"	offset="348"	intype="Int32_B"	inlength="1"	name="EX_ex_delta_cnt"	dicomtype="?"	dicomtag="?"		#  Indicates number of updates to header
+block="EXAMHDR"	offset="352"	intype="String"	inlength="2"	name="EX_ex_verscre"		dicomtype="?"	dicomtag="?"		#  Genesis Version - Created
+block="EXAMHDR"	offset="354"	intype="String"	inlength="2"	name="EX_ex_verscur"		dicomtype="?"	dicomtag="?"		#  Genesis Version - Now
+block="EXAMHDR"	offset="356"	intype="Uint32_B"	inlength="1"	name="EX_ex_checksum"	dicomtype="?"	dicomtag="?"		#  Exam Record Checksum
+block="EXAMHDR"	offset="360"	intype="Int32_B"	inlength="1"	name="EX_ex_complete"	dicomtype="?"	dicomtag="?"		#  Exam Complete Flag
+block="EXAMHDR"	offset="364"	intype="Int32_B"	inlength="1"	name="EX_ex_seriesct"	dicomtype="?"	dicomtag="?"		#  Last Series Number Used
+block="EXAMHDR"	offset="368"	intype="Int32_B"	inlength="1"	name="EX_ex_numarch"	dicomtype="?"	dicomtag="?"		#  Number of Series Archived
+block="EXAMHDR"	offset="372"	intype="Int32_B"	inlength="1"	name="EX_ex_numseries"	dicomtype="?"	dicomtag="?"		#  Number of Series Existing
+block="EXAMHDR"	offset="376"	intype="Uint32_B"	inlength="1"	name="EX_ex_series_l"	dicomtype="?"	dicomtag="?"		#  Series Keys for this exam - length
+block="EXAMHDR"	offset="380"	intype="Uint32_B"	inlength="1"	name="EX_ex_series_d"	dicomtype="?"	dicomtag="?"		#  Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="384"	intype="Int32_B"	inlength="1"	name="EX_ex_numunser"	dicomtype="?"	dicomtag="?"		#  Number of Unstored Series
+block="EXAMHDR"	offset="388"	intype="Uint32_B"	inlength="1"	name="EX_ex_unseries_l"	dicomtype="?"	dicomtag="?"		#  Unstored Series Keys for this exam - length
+block="EXAMHDR"	offset="392"	intype="Uint32_B"	inlength="1"	name="EX_ex_unseries_d"	dicomtype="?"	dicomtag="?"		#  Unstored Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="396"	intype="Int32_B"	inlength="1"	name="EX_ex_toarchcnt"	dicomtype="?"	dicomtag="?"		#  Number of Unarchived Series
+block="EXAMHDR"	offset="400"	intype="Uint32_B"	inlength="1"	name="EX_ex_toarchive_l"	dicomtype="?"	dicomtag="?"	#  Unarchived Series Keys for this exam - length
+block="EXAMHDR"	offset="404"	intype="Uint32_B"	inlength="1"	name="EX_ex_toarchive_d"	dicomtype="?"	dicomtag="?"	#  Unarchived Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="408"	intype="Int32_B"	inlength="1"	name="EX_ex_prospcnt"	dicomtype="?"	dicomtag="?"		#  Number of Prospective/Scout Series
+block="EXAMHDR"	offset="412"	intype="Uint32_B"	inlength="1"	name="EX_ex_prosp_l"	dicomtype="?"	dicomtag="?"		#  Prospective Series Keys for this exam - length
+block="EXAMHDR"	offset="416"	intype="Uint32_B"	inlength="1"	name="EX_ex_prosp_d"	dicomtype="?"	dicomtag="?"		#  Prospective Series Keys for this exam - data ptr
+block="EXAMHDR"	offset="420"	intype="Int32_B"	inlength="1"	name="EX_ex_modelnum"	dicomtype="?"	dicomtag="?"		#  Last Model Number used
+block="EXAMHDR"	offset="424"	intype="Int32_B"	inlength="1"	name="EX_ex_modelcnt"	dicomtype="?"	dicomtag="?"		#  Number of ThreeD Models
+block="EXAMHDR"	offset="428"	intype="Uint32_B"	inlength="1"	name="EX_ex_models_l"	dicomtype="?"	dicomtag="?"		#  3D Model Keys for this exam - length
+block="EXAMHDR"	offset="432"	intype="Uint32_B"	inlength="1"	name="EX_ex_models_d"	dicomtype="?"	dicomtag="?"		#  3D Model Keys for this exam - data ptr
+block="EXAMHDR"	offset="436"	intype="Int16_B"	inlength="1"	name="EX_ex_stat"		dicomtype="?"	dicomtag="?"	enum="0=In Patient:IN,1=Out Patient:OUT,2=Emergency:EM,3=Referral:REF"	#  Patient Status
+block="EXAMHDR"	offset="438"	intype="String"	inlength="16"	name="EX_uniq_sys_id"	dicomtype="?"	dicomtag="?"		#  Unique System ID
+block="EXAMHDR"	offset="454"	intype="String"	inlength="16"	name="EX_service_id"		dicomtype="?"	dicomtag="?"		#  Unique Service ID
+block="EXAMHDR"	offset="470"	intype="String"	inlength="4"	name="EX_mobile_loc"		dicomtype="?"	dicomtag="?"		#  Mobile Location Number
+block="EXAMHDR"	offset="474"	intype="String"	inlength="32"	name="EX_study_uid"		dicomtype="?"	dicomtag="?"		#  Study Entity Unique ID
+block="EXAMHDR"	offset="506"	intype="String"	inlength="518"	name="EX_ex_padding"		dicomtype="?"	dicomtag="?"		#  Spare Space
+block="SERIESHDR"	offset="0"	intype="String"	inlength="4"	name="SE_se_suid"	dicomtype="?"	dicomtag="?"		#  Suite ID for this Series
+block="SERIESHDR"	offset="4"	intype="Int16_B"	inlength="1"	name="SE_se_uniq"	dicomtype="?"	dicomtag="?"		#  The Make-Unique Flag
+block="SERIESHDR"	offset="6"	intype="String"	inlength="1"	name="SE_se_diskid"	dicomtype="?"	dicomtag="?"		#  Disk ID for this Series
+block="SERIESHDR"	offset="8"	intype="Uint16_B"	inlength="1"	name="SE_se_exno"	dicomtype="?"	dicomtag="?"		#  Exam Number
+block="SERIESHDR"	offset="10"	intype="Int16_B"	inlength="1"	keyword="SE_se_no"	dicomtype="IS"	dicomtag="SeriesNumber"	#  Series Number
+block="SERIESHDR"	offset="12"	intype="Unix_DateTime_B"	inlength="1"	keyword="SE_se_datetime"	dicomtype="?"	dicomtag="?"	#  Allocation Series Date/Time stamp
+block="SERIESHDR"	offset="16"	intype="Unix_DateTime_B"	inlength="1"	keyword="SE_se_actual_dt"	dicomtype="?"	dicomtag="?"	#  Actual Series Date/Time stamp
+block="SERIESHDR"	offset="20"	intype="String"	inlength="30"	name="SE_se_desc"	dicomtype="LO"	dicomtag="SeriesDescription"	#  Series Description
+block="SERIESHDR"	offset="50"	intype="String"	inlength="9"	name="SE_pr_sysid"	dicomtype="?"	dicomtag="?"		#  Primary Receiver Suite and Host
+block="SERIESHDR"	offset="59"	intype="String"	inlength="9"	name="SE_pansysid"	dicomtype="?"	dicomtag="?"		#  Archiver Suite and Host
+block="SERIESHDR"	offset="68"	intype="Int16_B"	inlength="1"	keyword="SE_se_typ"	dicomtype="?"	dicomtag="?"	enum="1=prospective:PROSP,2=Retrospective:RETRO,3=Scout Series:SCOUT,4=Reformatted:REFMT,5=Screensave:SSAVE,6=Xenon:XENON,7=Service:SERV,9=Projected:PJN"	#  Series Type
+block="SERIESHDR"	offset="70"	intype="Int16_B"	inlength="1"	name="SE_se_source"	dicomtype="?"	dicomtag="?"		#  Series from which prescribed
+block="SERIESHDR"	offset="72"	intype="Int16_B"	inlength="1"	name="SE_se_plane"	dicomtype="?"	dicomtag="?"		#  Most-like Plane (for L/S)
+block="SERIESHDR"	offset="74"	intype="Int16_B"	inlength="1"	name="SE_scan_type"	dicomtype="?"	dicomtag="?"	enum="1=Scout:SCT,2=Axial:AX,3=Screensave:SS"	#  Scout or Axial (for CT)
+block="SERIESHDR"	offset="76"	intype="Int32_B"	inlength="1"	keyword="SE_position"	dicomtype="?"	dicomtag="?"	bitmap="0:none,Supine;1:none,Prone;2:none,Decubitus Left;3:none,Decubitus Right"	#  Patient Position
+block="SERIESHDR"	offset="80"	intype="Int32_B"	inlength="1"	keyword="SE_entry"	dicomtype="?"	dicomtag="?"	enum="1=Head First,2=Feet First"	#  Patient Entry
+block="SERIESHDR"	offset="84"	intype="String"	inlength="3"	name="SE_anref"	dicomtype="LO"	dicomtag="PositionReferenceIndicator"		#  Anatomical reference
+block="SERIESHDR"	offset="88"	intype="IEEE_Float32_B"	inlength="1"	name="SE_lmhor"	dicomtype="?"	dicomtag="?"		#  Horizontal Landmark
+block="SERIESHDR"	offset="92"	intype="String"	inlength="25"	name="SE_prtcl"	dicomtype="LO"	dicomtag="ProtocolName"	#  Scan Protocol Name
+block="SERIESHDR"	offset="118"	intype="Int16_B"	inlength="1"	name="SE_se_contrast"	dicomtype="?"	dicomtag="?"	#  Non-zero if > 0 image used contrast(L/S)
+block="SERIESHDR"	offset="120"	intype="String"	inlength="1"	name="SE_start_ras"	dicomtype="?"	dicomtag="?"		#  RAS letter for first scan location (L/S)
+block="SERIESHDR"	offset="122"	intype="IEEE_Float32_B"	inlength="1"	name="SE_start_loc"	dicomtype="?"	dicomtag="?"		#  First scan location (L/S)
+block="SERIESHDR"	offset="126"	intype="String"	inlength="1"	name="SE_end_ras"	dicomtype="?"	dicomtag="?"		#  RAS letter for last scan location (L/S)
+block="SERIESHDR"	offset="128"	intype="IEEE_Float32_B"	inlength="1"	name="SE_end_loc"	dicomtype="?"	dicomtag="?"		#  Last scan location (L/S)
+block="SERIESHDR"	offset="132"	intype="Int16_B"	inlength="1"	name="SE_se_pseq"	dicomtype="?"	dicomtag="?"		#  Last Pulse Sequence Used (L/S)
+block="SERIESHDR"	offset="134"	intype="Int16_B"	inlength="1"	name="SE_se_sortorder"	dicomtype="?"	dicomtag="?"	#  Image Sort Order (L/S)
+block="SERIESHDR"	offset="136"	intype="Int32_B"	inlength="1"	name="SE_se_lndmrkcnt"	dicomtype="?"	dicomtag="?"	#  Landmark Counter
+block="SERIESHDR"	offset="140"	intype="Int16_B"	inlength="1"	name="SE_se_nacq"	dicomtype="IS"	dicomtag="ImagesInAcquisition"	#  Number of Acquisitions
+block="SERIESHDR"	offset="142"	intype="Int16_B"	inlength="1"	name="SE_xbasest"		dicomtype="?"	dicomtag="?"	#  Starting number for baselines
+block="SERIESHDR"	offset="144"	intype="Int16_B"	inlength="1"	name="SE_xbaseend"		dicomtype="?"	dicomtag="?"	#  Ending number for baselines
+block="SERIESHDR"	offset="146"	intype="Int16_B"	inlength="1"	name="SE_xenhst"		dicomtype="?"	dicomtag="?"	#  Starting number for enhanced scans
+block="SERIESHDR"	offset="148"	intype="Int16_B"	inlength="1"	name="SE_xenhend"		dicomtype="?"	dicomtag="?"	#  Ending number for enhanced scans
+block="SERIESHDR"	offset="150"	intype="Unix_DateTime_B"	inlength="1"	keyword="SE_se_lastmod"		dicomtype="?"	dicomtag="?"	#  Date/Time of Last Change
+block="SERIESHDR"	offset="154"	intype="String"	inlength="13"	name="SE_se_alloc_key"	dicomtype="?"	dicomtag="?"	#  Process that allocated this record
+block="SERIESHDR"	offset="168"	intype="Int32_B"	inlength="1"	name="SE_se_delta_cnt"	dicomtype="?"	dicomtag="?"	#  Indicates number of updates to header
+block="SERIESHDR"	offset="172"	intype="String"	inlength="2"	name="SE_se_verscre"		dicomtype="?"	dicomtag="?"	#  Genesis Version - Created
+block="SERIESHDR"	offset="174"	intype="String"	inlength="2"	name="SE_se_verscur"		dicomtype="?"	dicomtag="?"	#  Genesis Version - Now
+block="SERIESHDR"	offset="176"	intype="IEEE_Float32_B"	inlength="1"	name="SE_se_pds_a"		dicomtype="?"	dicomtag="?"	#  PixelData size - as stored
+block="SERIESHDR"	offset="180"	intype="IEEE_Float32_B"	inlength="1"	name="SE_se_pds_c"		dicomtype="?"	dicomtag="?"	#  PixelData size - Compressed
+block="SERIESHDR"	offset="184"	intype="IEEE_Float32_B"	inlength="1"	name="SE_se_pds_u"		dicomtype="?"	dicomtag="?"	#  PixelData size - UnCompressed
+block="SERIESHDR"	offset="188"	intype="Uint32_B"	inlength="1"	name="SE_se_checksum"		dicomtype="?"	dicomtag="?"	#  Series Record checksum
+block="SERIESHDR"	offset="192"	intype="Int32_B"	inlength="1"	name="SE_se_complete"		dicomtype="?"	dicomtag="?"	#  Series Complete Flag
+block="SERIESHDR"	offset="196"	intype="Int32_B"	inlength="1"	name="SE_se_numarch"		dicomtype="?"	dicomtag="?"	#  Number of Images Archived
+block="SERIESHDR"	offset="200"	intype="Int32_B"	inlength="1"	name="SE_se_imagect"		dicomtype="?"	dicomtag="?"	#  Last Image Number Used
+block="SERIESHDR"	offset="204"	intype="Int32_B"	inlength="1"	name="SE_se_numimages"		dicomtype="?"	dicomtag="?"	#  Number of Images Existing
+block="SERIESHDR"	offset="208"	intype="Uint32_B"	inlength="1"	name="SE_se_images_l"		dicomtype="?"	dicomtag="?"	#  Image Keys for this Series - length
+block="SERIESHDR"	offset="212"	intype="Uint32_B"	inlength="1"	name="SE_se_images_d"		dicomtype="?"	dicomtag="?"	#  Image Keys for this Series - data ptr
+block="SERIESHDR"	offset="216"	intype="Int32_B"	inlength="1"	name="SE_se_numunimg"		dicomtype="?"	dicomtag="?"	#  Number of Unstored Images
+block="SERIESHDR"	offset="220"	intype="Uint32_B"	inlength="1"	name="SE_se_unimages_l"		dicomtype="?"	dicomtag="?"	#  Unstored Image Keys for this Series - length
+block="SERIESHDR"	offset="224"	intype="Uint32_B"	inlength="1"	name="SE_se_unimages_d"		dicomtype="?"	dicomtag="?"	#  Unstored Image Keys for this Series - data ptr
+block="SERIESHDR"	offset="228"	intype="Int32_B"	inlength="1"	name="SE_se_toarchcnt"		dicomtype="?"	dicomtag="?"	#  Number of Unarchived Images
+block="SERIESHDR"	offset="232"	intype="Uint32_B"	inlength="1"	name="SE_se_toarchive_l"	dicomtype="?"	dicomtag="?"	#  Unarchived Image Keys for this Series - length
+block="SERIESHDR"	offset="236"	intype="Uint32_B"	inlength="1"	name="SE_se_toarchive_d"	dicomtype="?"	dicomtag="?"	#  Unarchived Image Keys for this Series - data ptr
+block="SERIESHDR"	offset="240"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo1_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 1 Alpha Value
+block="SERIESHDR"	offset="244"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo1_beta"		dicomtype="?"	dicomtag="?"	#  Echo 1 Beta Value
+block="SERIESHDR"	offset="248"	intype="Uint16_B"	inlength="1"	name="SE_echo1_window"	dicomtype="?"	dicomtag="?"	#  Echo 1 Window Value
+block="SERIESHDR"	offset="250"	intype="Int16_B"	inlength="1"	name="SE_echo1_level"	dicomtype="?"	dicomtag="?"	#  Echo 1 Level Value
+block="SERIESHDR"	offset="252"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo2_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 2 Alpha Value
+block="SERIESHDR"	offset="256"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo2_beta"		dicomtype="?"	dicomtag="?"	#  Echo 2 Beta Value
+block="SERIESHDR"	offset="260"	intype="Uint16_B"	inlength="1"	name="SE_echo2_window"	dicomtype="?"	dicomtag="?"	#  Echo 2 Window Value
+block="SERIESHDR"	offset="262"	intype="Int16_B"	inlength="1"	name="SE_echo2_level"	dicomtype="?"	dicomtag="?"	#  Echo 2 Level Value
+block="SERIESHDR"	offset="264"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo3_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 3 Alpha Value
+block="SERIESHDR"	offset="268"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo3_beta"		dicomtype="?"	dicomtag="?"	#  Echo 3 Beta Value
+block="SERIESHDR"	offset="272"	intype="Uint16_B"	inlength="1"	name="SE_echo3_window"	dicomtype="?"	dicomtag="?"	#  Echo 3 Window Value
+block="SERIESHDR"	offset="274"	intype="Int16_B"	inlength="1"	name="SE_echo3_level"	dicomtype="?"	dicomtag="?"	#  Echo 3 Level Value
+block="SERIESHDR"	offset="276"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo4_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 4 Alpha Value
+block="SERIESHDR"	offset="280"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo4_beta"		dicomtype="?"	dicomtag="?"	#  Echo 4 Beta Value
+block="SERIESHDR"	offset="284"	intype="Uint16_B"	inlength="1"	name="SE_echo4_window"	dicomtype="?"	dicomtag="?"	#  Echo 4 Window Value
+block="SERIESHDR"	offset="286"	intype="Int16_B"	inlength="1"	name="SE_echo4_level"	dicomtype="?"	dicomtag="?"	#  Echo 4 Level Value
+block="SERIESHDR"	offset="288"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo5_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 5 Alpha Value
+block="SERIESHDR"	offset="292"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo5_beta"		dicomtype="?"	dicomtag="?"	#  Echo 5 Beta Value
+block="SERIESHDR"	offset="296"	intype="Uint16_B"	inlength="1"	name="SE_echo5_window"	dicomtype="?"	dicomtag="?"	#  Echo 5 Window Value
+block="SERIESHDR"	offset="298"	intype="Int16_B"	inlength="1"	name="SE_echo5_level"	dicomtype="?"	dicomtag="?"	#  Echo 5 Level Value
+block="SERIESHDR"	offset="300"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo6_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 6 Alpha Value
+block="SERIESHDR"	offset="304"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo6_beta"		dicomtype="?"	dicomtag="?"	#  Echo 6 Beta Value
+block="SERIESHDR"	offset="308"	intype="Uint16_B"	inlength="1"	name="SE_echo6_window"	dicomtype="?"	dicomtag="?"	#  Echo 6 Window Value
+block="SERIESHDR"	offset="310"	intype="Int16_B"	inlength="1"	name="SE_echo6_level"	dicomtype="?"	dicomtag="?"	#  Echo 6 Level Value
+block="SERIESHDR"	offset="312"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo7_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 7 Alpha Value
+block="SERIESHDR"	offset="316"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo7_beta"		dicomtype="?"	dicomtag="?"	#  Echo 7 Beta Value
+block="SERIESHDR"	offset="320"	intype="Uint16_B"	inlength="1"	name="SE_echo7_window"	dicomtype="?"	dicomtag="?"	#  Echo 7 Window Value
+block="SERIESHDR"	offset="322"	intype="Int16_B"	inlength="1"	name="SE_echo7_level"	dicomtype="?"	dicomtag="?"	#  Echo 7 Level Value
+block="SERIESHDR"	offset="324"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo8_alpha"	dicomtype="?"	dicomtag="?"	#  Echo 8 Alpha Value
+block="SERIESHDR"	offset="328"	intype="IEEE_Float32_B"	inlength="1"	name="SE_echo8_beta"		dicomtype="?"	dicomtag="?"	#  Echo 8 Beta Value
+block="SERIESHDR"	offset="332"	intype="Uint16_B"	inlength="1"	name="SE_echo8_window"	dicomtype="?"	dicomtag="?"	#  Echo 8 Window Value
+block="SERIESHDR"	offset="334"	intype="Int16_B"	inlength="1"	name="SE_echo8_level"	dicomtype="?"	dicomtag="?"	#  Echo 8 Level Value
+block="SERIESHDR"	offset="336"	intype="String"	inlength="32"	name="SE_series_uid"		dicomtype="?"	dicomtag="?"	#  Series Entity Unique ID
+block="SERIESHDR"	offset="368"	intype="String"	inlength="32"	name="SE_landmark_uid"	dicomtype="?"	dicomtag="?"	#  Landmark Unique ID
+block="SERIESHDR"	offset="400"	intype="String"	inlength="32"	name="SE_equipmnt_uid"	dicomtype="?"	dicomtag="?"	#  Equipment Unique ID
+block="SERIESHDR"	offset="432"	intype="String"	inlength="588"	name="SE_se_padding"		dicomtype="?"	dicomtag="?"	#  Spare Space
+block="CTHDR"  condition="isct"	offset="0"	intype="String"	inlength="4"	name="CT_im_suid"		dicomtype="?"	dicomtag="?"		#  Suite id for this image
+block="CTHDR"  condition="isct"	offset="4"	intype="Int16_B"	inlength="1"	name="CT_im_uniq"		dicomtype="?"	dicomtag="?"		#  The Make-Unique Flag
+block="CTHDR"  condition="isct"	offset="6"	intype="String"	inlength="1"	name="CT_im_diskid"		dicomtype="?"	dicomtag="?"		#  Disk ID for this Image
+block="CTHDR"  condition="isct"	offset="8"	intype="Uint16_B"	inlength="1"	name="CT_im_exno"		dicomtype="?"	dicomtag="?"		#  Exam number for this image
+block="CTHDR"  condition="isct"	offset="10"	intype="Int16_B"	inlength="1"	name="CT_im_seno"		dicomtype="?"	dicomtag="?"		#  Series Number for this image
+block="CTHDR"  condition="isct"	offset="12"	intype="Int16_B"	inlength="1"	keyword="CT_im_no"		dicomtype="IS"	dicomtag="InstanceNumber"	#  Image Number
+block="CTHDR"  condition="isct"	offset="14"	intype="Unix_DateTime_B"	inlength="1"	keyword="CT_im_datetime"	dicomtype="?"	dicomtag="?"		#  Allocation Image date/time stamp
+block="CTHDR"  condition="isct"	offset="18"	intype="Unix_DateTime_B"	inlength="1"	keyword="CT_im_actual_dt"	dicomtype="?"	dicomtag="?"		#  Actual Image date/time stamp
+block="CTHDR"  condition="isct"	offset="22"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_sctime"		dicomtype="?"	dicomtag="?"		#  Duration of scan (secs)
+block="CTHDR"  condition="isct"	offset="26"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slthick"		dicomtype="DS"	dicomtag="SliceThickness"	#  Slice Thickness (mm)
+block="CTHDR"  condition="isct"	offset="30"	intype="Int16_B"	inlength="1"	keyword="CT_imatrix_X"		dicomtype="?"	dicomtag="?"		#  Image matrix size - X
+block="CTHDR"  condition="isct"	offset="32"	intype="Int16_B"	inlength="1"	keyword="CT_imatrix_Y"		dicomtype="?"	dicomtag="?"		#  Image matrix size - Y
+block="CTHDR"  condition="isct"	offset="34"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dfov"		dicomtype="?"	dicomtag="?"		#  Display field of view - X (mm)
+block="CTHDR"  condition="isct"	offset="38"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dfov_rect"		dicomtype="?"	dicomtag="?"		#  Display field of view - Y (if different)
+block="CTHDR"  condition="isct"	offset="42"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dim_X"		dicomtype="?"	dicomtag="?"		#  Image dimension - X
+block="CTHDR"  condition="isct"	offset="46"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_dim_Y"		dicomtype="?"	dicomtag="?"		#  Image dimension - Y
+block="CTHDR"  condition="isct"	offset="50"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_pixsize_X"		dicomtype="?"	dicomtag="?"	#  Image pixel size - X
+block="CTHDR"  condition="isct"	offset="54"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_pixsize_Y"		dicomtype="?"	dicomtag="?"	#  Image pixel size - Y
+block="CTHDR"  condition="isct"	offset="58"	intype="String"	inlength="14"	name="CT_pdid"		dicomtype="?"	dicomtag="?"		#  Pixel Data ID
+block="CTHDR"  condition="isct"	offset="72"	intype="String"	inlength="17"	name="CT_contrastIV"		dicomtype="?"	dicomtag="?"		#  IV Contrast Agent
+block="CTHDR"  condition="isct"	offset="89"	intype="String"	inlength="17"	name="CT_contrastOral"	dicomtype="?"	dicomtag="?"		#  Oral Contrast Agent
+block="CTHDR"  condition="isct"	offset="106"	intype="Int16_B"	inlength="1"	name="CT_contmode"		dicomtype="?"	dicomtag="?"	bitmap="0:none,oral;1:none,intravenous"	#  Image Contrast Mode
+block="CTHDR"  condition="isct"	offset="108"	intype="Int16_B"	inlength="1"	name="CT_serrx"		dicomtype="?"	dicomtag="?"		#  Series from which prescribed
+block="CTHDR"  condition="isct"	offset="110"	intype="Int16_B"	inlength="1"	name="CT_imgrx"		dicomtype="?"	dicomtag="?"		#  Image from which prescribed
+block="CTHDR"  condition="isct"	offset="112"	intype="Int16_B"	inlength="1"	name="CT_screenformat"	dicomtype="?"	dicomtag="?"		#  Screen Format(8/16 bit)
+block="CTHDR"  condition="isct"	offset="114"	intype="Int16_B"	inlength="1"	name="CT_plane"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Scout Plane(SCT);1:none,Axial Plane(Ax);2:none,Sagittal Plane(Sag);3:none,Coronal Plane(Cor);4:none,Oblique Plane(O);5:none,ParAxial Plane(PAX);6:none,Reformatted Plane(RFMT);7:none,Projected Plane(PJN);8:none,Mixed Plane(MIXED)"	#  Plane Type
+block="CTHDR"  condition="isct"	offset="116"	intype="IEEE_Float32_B"	inlength="1"	name="CT_scanspacing"	dicomtype="DS"	dicomtag="SpacingBetweenSlices"	#  Spacing between scans (mm?)
+block="CTHDR"  condition="isct"	offset="120"	intype="Int16_B"	inlength="1"	name="CT_im_compress"	dicomtype="?"	dicomtag="?"		#  Image compression type for allocation
+block="CTHDR"  condition="isct"	offset="122"	intype="Int16_B"	inlength="1"	name="CT_im_scouttype"	dicomtype="?"	dicomtag="?"	enum="1=Scout Vertical,2=Scout Horizontal"	#  Scout Type (AP or lateral)
+block="CTHDR"  condition="isct"	offset="124"	intype="String"	inlength="1"	name="CT_loc_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter of image location
+block="CTHDR"  condition="isct"	offset="126"	intype="IEEE_Float32_B"	inlength="1"	name="CT_loc"		dicomtype="DS"	dicomtag="SliceLocation"	#  Image location
+block="CTHDR"  condition="isct"	offset="130"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_ctr_R"		dicomtype="?"	dicomtag="?"		#  Center R coord of plane image
+block="CTHDR"  condition="isct"	offset="134"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_ctr_A"		dicomtype="?"	dicomtag="?"		#  Center A coord of plane image
+block="CTHDR"  condition="isct"	offset="138"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_ctr_S"		dicomtype="?"	dicomtag="?"		#  Center S coord of plane image
+block="CTHDR"  condition="isct"	offset="142"	intype="IEEE_Float32_B"	inlength="1"	name="CT_norm_R"		dicomtype="?"	dicomtag="?"		#  Normal R coord
+block="CTHDR"  condition="isct"	offset="146"	intype="IEEE_Float32_B"	inlength="1"	name="CT_norm_A"		dicomtype="?"	dicomtag="?"		#  Normal A coord
+block="CTHDR"  condition="isct"	offset="150"	intype="IEEE_Float32_B"	inlength="1"	name="CT_norm_S"		dicomtype="?"	dicomtag="?"		#  Normal S coord
+block="CTHDR"  condition="isct"	offset="154"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_tlhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Left Hand
+block="CTHDR"  condition="isct"	offset="158"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_tlhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Left Hand
+block="CTHDR"  condition="isct"	offset="162"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_tlhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Left Hand
+block="CTHDR"  condition="isct"	offset="166"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_trhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Right Hand
+block="CTHDR"  condition="isct"	offset="170"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_trhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Right Hand
+block="CTHDR"  condition="isct"	offset="174"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_trhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Right Hand
+block="CTHDR"  condition="isct"	offset="178"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_brhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Bottom Right Hand
+block="CTHDR"  condition="isct"	offset="182"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_brhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Bottom Right Hand
+block="CTHDR"  condition="isct"	offset="186"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_brhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Bottom Right Hand
+block="CTHDR"  condition="isct"	offset="190"	intype="String"	inlength="4"	name="CT_forimgrev"		dicomtype="?"	dicomtag="?"		#  Foreign Image Revision
+block="CTHDR"  condition="isct"	offset="194"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sctstr"		dicomtype="?"	dicomtag="?"		#  Table Start Location
+block="CTHDR"  condition="isct"	offset="198"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sctend"		dicomtype="?"	dicomtag="?"		#  Table End Location
+block="CTHDR"  condition="isct"	offset="202"	intype="IEEE_Float32_B"	inlength="1"	name="CT_tblspd"		dicomtype="?"	dicomtag="?"		#  Table Speed (mm/sec)
+block="CTHDR"  condition="isct"	offset="206"	intype="IEEE_Float32_B"	inlength="1"	name="CT_tblht"		dicomtype="DS"	dicomtag="TableHeight"	#  Table Height
+block="CTHDR"  condition="isct"	offset="210"	intype="IEEE_Float32_B"	inlength="1"	name="CT_midstime"		dicomtype="?"	dicomtag="?"		#  Mid Scan Time
+block="CTHDR"  condition="isct"	offset="214"	intype="Int16_B"	inlength="1"	name="CT_midsflag"		dicomtype="?"	dicomtag="?"		#  does midstime apply
+block="CTHDR"  condition="isct"	offset="216"	intype="Int32_B"	inlength="1"	name="CT_kvolt"			dicomtype="DS"	dicomtag="KVP"		#  KVolt generator setting
+block="CTHDR"  condition="isct"	offset="220"	intype="Int32_B"	inlength="1"	keyword="CT_mamp"		dicomtype="IS"	dicomtag="XRayTubeCurrent"	#  MAmp generator setting
+block="CTHDR"  condition="isct"	offset="224"	intype="IEEE_Float32_B"	inlength="1"	name="CT_gantilt"		dicomtype="DS"	dicomtag="GantryDetectorTilt"	#  Gantry Tilt (degrees)
+block="CTHDR"  condition="isct"	offset="228"	intype="Int32_B"	inlength="1"	name="CT_azimuth"		dicomtype="?"	dicomtag="?"		#  Degrees of Azimuth
+block="CTHDR"  condition="isct"	offset="232"	intype="IEEE_Float32_B"	inlength="1"	name="CT_ganvel"		dicomtype="?"	dicomtag="?"		#  Gantry Velocity
+block="CTHDR"  condition="isct"	offset="236"	intype="Int32_B"	inlength="1"	name="CT_ganfilt"		dicomtype="?"	dicomtag="?"		#  Gantry Filter Position
+block="CTHDR"  condition="isct"	offset="240"	intype="IEEE_Float32_B"	inlength="1"	name="CT_trigon"		dicomtype="?"	dicomtag="?"		#  Trigger on Position
+block="CTHDR"  condition="isct"	offset="244"	intype="IEEE_Float32_B"	inlength="1"	name="CT_degrot"		dicomtype="?"	dicomtag="?"		#  Degrees of rotation
+block="CTHDR"  condition="isct"	offset="248"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xrayon"		dicomtype="?"	dicomtag="?"		#  X-Ray On Position
+block="CTHDR"  condition="isct"	offset="252"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xrayoff"		dicomtype="?"	dicomtag="?"		#  X-Ray Off Position
+block="CTHDR"  condition="isct"	offset="256"	intype="Int32_B"	inlength="1"	name="CT_numtrig"		dicomtype="?"	dicomtag="?"		#  Number of Triggers
+block="CTHDR"  condition="isct"	offset="260"	intype="Int16_B"	inlength="1"	name="CT_inviews"		dicomtype="?"	dicomtag="?"		#  Total input views
+block="CTHDR"  condition="isct"	offset="262"	intype="IEEE_Float32_B"	inlength="1"	name="CT_view1ang"		dicomtype="?"	dicomtag="?"		#  Angle of first view
+block="CTHDR"  condition="isct"	offset="266"	intype="IEEE_Float32_B"	inlength="1"	name="CT_trigfreq"		dicomtype="?"	dicomtag="?"		#  Trigger frequency
+block="CTHDR"  condition="isct"	offset="270"	intype="Int32_B"	inlength="1"	name="CT_trigsrc"		dicomtype="?"	dicomtag="?"	enum="1=internal,2=external"	#  DAS trigger source
+block="CTHDR"  condition="isct"	offset="274"	intype="Int32_B"	inlength="1"	name="CT_fpagain"		dicomtype="?"	dicomtag="?"	bitmap="0:none,auto;1:none,X1;3:none,X8;6:none,X64"	#  DAS fpa gain
+block="CTHDR"  condition="isct"	offset="278"	intype="Int32_B"	inlength="1"	name="CT_scanopmode"		dicomtype="?"	dicomtag="?"	bitmap="0:none,???;1:none,???;2:none,???;3:none,scout mode;4:none,axial Xron mode;5:none,axial Xroff mode;6:none,static Xron mode;7:none,static Xroff mode;8:none,tube heat mode;9:none,DAS mode;10:none,tube cal mode;11:none,biopsy mode;12:none,cine mode;13:none,helical mode;14:none,rotgencal mode"	#  Scan Type
+block="CTHDR"  condition="isct"	offset="282"	intype="Int32_B"	inlength="1"	name="CT_outsrc"		dicomtype="?"	dicomtag="?"	enum="1=AID,2=XM"	#  DAS output source
+block="CTHDR"  condition="isct"	offset="286"	intype="Int32_B"	inlength="1"	name="CT_adin"		dicomtype="?"	dicomtag="?"	enum="1=DAS Filter Card,2=Aux"	#  DAS ad input
+block="CTHDR"  condition="isct"	offset="290"	intype="Int32_B"	inlength="1"	name="CT_calmode"		dicomtype="?"	dicomtag="?"	enum="1=DC DAS Cal,2=AC DAS Cal,3=No DAS Cal"	#  DAS cal mode
+block="CTHDR"  condition="isct"	offset="294"	intype="Int32_B"	inlength="1"	name="CT_calfreq"		dicomtype="?"	dicomtag="?"	enum="0=?,1=?"	#  DAS cal frequency
+block="CTHDR"  condition="isct"	offset="298"	intype="Int32_B"	inlength="1"	name="CT_regxm"		dicomtype="?"	dicomtag="?"	enum="1=hold,2=shift"	#  DAS reg xm
+block="CTHDR"  condition="isct"	offset="302"	intype="Int32_B"	inlength="1"	name="CT_autozero"		dicomtype="?"	dicomtag="?"		#  DAS auto zero
+block="CTHDR"  condition="isct"	offset="306"	intype="Int16_B"	inlength="1"	name="CT_sfovtyp"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Ped Head;1:none,Adult Head;2:none,Small;3:none,Medium;4:none,Large;5:none,No Sfovtype"	#  Axial Type
+block="CTHDR"  condition="isct"	offset="308"	intype="Int16_B"	inlength="1"	name="CT_phantsize"		dicomtype="?"	dicomtag="?"	enum="1=No Psize,2=Small Psize,3=Medium Psize,4=Large Psize"	#  Calibration phantom size
+block="CTHDR"  condition="isct"	offset="310"	intype="Int16_B"	inlength="1"	name="CT_phanttyp"		dicomtype="?"	dicomtag="?"	enum="1=None,2=Air,3=Water,4=Poly"	#  Calibration phantom type
+block="CTHDR"  condition="isct"	offset="312"	intype="Int16_B"	inlength="1"	keyword="CT_filttyp"		dicomtype="?"	dicomtag="?"	enum="1=Air Filter,2=Body Filter,3=Bowtie Flat Filter:Adult Head,4=Flat Filter,5=High Filter:Adult Head/HF"	#  Calibration filter type
+block="CTHDR"  condition="isct"	offset="314"	intype="Int16_B"	inlength="1"	keyword="CT_reconalg"		dicomtype="?"	dicomtag="?"	bitmap="0:none,smooth(SMTH);1:none,soft(SOFT);2:none,standard(STND);3:none,detail(DETL);4:none,bone(BONE);5:none,edge(EDGE);6:none,sharp(SHRP);7:none,experimental 2(EXP2)"	#  Recon Algorithm
+block="CTHDR"  condition="isct"	offset="316"	intype="Int16_B"	inlength="1"	keyword="CT_perisflag"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:/P"	#  Peristaltic flag
+block="CTHDR"  condition="isct"	offset="318"	intype="Int16_B"	inlength="1"	keyword="CT_iboneflag"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:/I"	#  IterBone flag
+block="CTHDR"  condition="isct"	offset="320"	intype="Int16_B"	inlength="1"	name="CT_statflag"		dicomtype="?"	dicomtag="?"		#  Stat Recon flag
+block="CTHDR"  condition="isct"	offset="322"	intype="Int16_B"	inlength="1"	name="CT_computetyp"		dicomtype="?"	dicomtag="?"	enum="1=axial,2=calcheck,3=scout,4=ppscan,5=viewsvschannels"	#  Compute Type
+block="CTHDR"  condition="isct"	offset="324"	intype="Int16_B"	inlength="1"	name="CT_segnum"		dicomtype="?"	dicomtag="?"		#  Segment Number
+block="CTHDR"  condition="isct"	offset="326"	intype="Int16_B"	inlength="1"	name="CT_segstotal"		dicomtype="?"	dicomtag="?"		#  Total Number of Segments Requested
+block="CTHDR"  condition="isct"	offset="328"	intype="IEEE_Float32_B"	inlength="1"	name="CT_isd"		dicomtype="?"	dicomtag="?"		#  Inter scan delay (secs)
+block="CTHDR"  condition="isct"	offset="332"	intype="IEEE_Float32_B"	inlength="1"	keyword="CT_sfovmm"		dicomtype="DS"	dicomtag="DataCollectionDiameter"		#  Scan field of view (mm)
+block="CTHDR"  condition="isct"	offset="336"	intype="Int16_B"	inlength="1"	name="CT_scannum"		dicomtype="IS"	dicomtag="AcquisitionNumber"		#  Scan Number
+block="CTHDR"  condition="isct"	offset="338"	intype="Int16_B"	inlength="1"	name="CT_viewstrtchan"	dicomtype="?"	dicomtag="?"		#  Starting Channel of View
+block="CTHDR"  condition="isct"	offset="340"	intype="Int16_B"	inlength="1"	name="CT_viewcompfctr"	dicomtype="?"	dicomtag="?"		#  View Compression Factor
+block="CTHDR"  condition="isct"	offset="342"	intype="Int16_B"	inlength="1"	name="CT_outviews"		dicomtype="?"	dicomtag="?"		#  Total Output Views
+block="CTHDR"  condition="isct"	offset="344"	intype="Int16_B"	inlength="1"	name="CT_overranges"		dicomtype="?"	dicomtag="?"		#  Number of Overranges
+block="CTHDR"  condition="isct"	offset="346"	intype="Int16_B"	inlength="1"	name="CT_totrefchan"		dicomtype="?"	dicomtag="?"		#  Total Number of Ref Channels
+block="CTHDR"  condition="isct"	offset="348"	intype="Int32_B"	inlength="1"	name="CT_scdatasize"		dicomtype="?"	dicomtag="?"		#  data size for scan data
+block="CTHDR"  condition="isct"	offset="352"	intype="Int16_B"	inlength="1"	name="CT_refchan1"		dicomtype="?"	dicomtag="?"		#  z or q channel
+block="CTHDR"  condition="isct"	offset="354"	intype="Int16_B"	inlength="1"	name="CT_refchan2"		dicomtype="?"	dicomtag="?"		#  Reference channel 1
+block="CTHDR"  condition="isct"	offset="356"	intype="Int16_B"	inlength="1"	name="CT_refchan3"		dicomtype="?"	dicomtag="?"		#  Reference channel 2
+block="CTHDR"  condition="isct"	offset="358"	intype="Int16_B"	inlength="1"	name="CT_refchan4"		dicomtype="?"	dicomtag="?"		#  Reference channel 3
+block="CTHDR"  condition="isct"	offset="360"	intype="Int16_B"	inlength="1"	name="CT_refchan5"		dicomtype="?"	dicomtag="?"		#  Reference channel 4
+block="CTHDR"  condition="isct"	offset="362"	intype="Int16_B"	inlength="1"	name="CT_refchan6"		dicomtype="?"	dicomtag="?"		#  Reference channel 5
+block="CTHDR"  condition="isct"	offset="364"	intype="Int16_B"	inlength="1"	name="CT_postproc"		dicomtype="?"	dicomtag="?"		#  Recon post processing flag
+block="CTHDR"  condition="isct"	offset="366"	intype="Int32_B"	inlength="1"	name="CT_xmpat"		dicomtype="?"	dicomtag="?"		#  DAS xm pattern
+block="CTHDR"  condition="isct"	offset="370"	intype="Int16_B"	inlength="1"	name="CT_rottyp"		dicomtype="?"	dicomtag="?"	bitmap="0:none,half scan(rotating);1:none,normal scan(rotating);2:none,over scan(rotating);3:none,stationary(stationary)"	#  Prescribed rotation type
+block="CTHDR"  condition="isct"	offset="372"	intype="Int16_B"	inlength="1"	name="CT_rawdataflag"	dicomtype="?"	dicomtag="?"		#  Save Raw Data Flag
+block="CTHDR"  condition="isct"	offset="374"	intype="IEEE_Float32_B"	inlength="1"	name="CT_ct_scalefact"	dicomtype="?"	dicomtag="?"		#  IBH Image scale factors
+block="CTHDR"  condition="isct"	offset="378"	intype="Int16_B"	inlength="1"	name="CT_ct_water_num"	dicomtype="?"	dicomtag="?"		#  CT Water Number
+block="CTHDR"  condition="isct"	offset="380"	intype="Int16_B"	inlength="1"	name="CT_ct_bone_num"	dicomtype="?"	dicomtag="?"		#  CT Bone Number
+block="CTHDR"  condition="isct"	offset="382"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bbh_coef1"		dicomtype="?"	dicomtag="?"		#  BBH coefficient 1
+block="CTHDR"  condition="isct"	offset="386"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bbh_coef2"		dicomtype="?"	dicomtag="?"		#  BBH coefficient 2
+block="CTHDR"  condition="isct"	offset="390"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bbh_coef3"		dicomtype="?"	dicomtag="?"		#  BBH coefficient 3
+block="CTHDR"  condition="isct"	offset="394"	intype="Int16_B"	inlength="1"	name="CT_bbh_numblend"	dicomtype="?"	dicomtag="?"		#  Num of BBH channels to blend
+block="CTHDR"  condition="isct"	offset="396"	intype="Int32_B"	inlength="1"	name="CT_firstchan"		dicomtype="?"	dicomtag="?"		#  Starting channel
+block="CTHDR"  condition="isct"	offset="400"	intype="Int32_B"	inlength="1"	name="CT_numchan"		dicomtype="?"	dicomtag="?"		#  Number of channels (1..512)
+block="CTHDR"  condition="isct"	offset="404"	intype="Int32_B"	inlength="1"	name="CT_chaninc"		dicomtype="?"	dicomtag="?"		#  Increment between channels
+block="CTHDR"  condition="isct"	offset="408"	intype="Int32_B"	inlength="1"	name="CT_firstview"		dicomtype="?"	dicomtag="?"		#  Starting view
+block="CTHDR"  condition="isct"	offset="412"	intype="Int32_B"	inlength="1"	name="CT_numview"		dicomtype="?"	dicomtag="?"		#  Number of views
+block="CTHDR"  condition="isct"	offset="416"	intype="Int32_B"	inlength="1"	name="CT_viewinc"		dicomtype="?"	dicomtag="?"		#  Increment between views
+block="CTHDR"  condition="isct"	offset="420"	intype="Int32_B"	inlength="1"	name="CT_windowrange"	dicomtype="?"	dicomtag="?"		#  Window Range (0..4095)
+block="CTHDR"  condition="isct"	offset="424"	intype="IEEE_Float32_B"	inlength="1"	name="CT_scalemin"		dicomtype="?"	dicomtag="?"		#  Scaling value of the image data
+block="CTHDR"  condition="isct"	offset="428"	intype="IEEE_Float32_B"	inlength="1"	name="CT_scalemax"		dicomtype="?"	dicomtag="?"		#  Scaling value of the image data
+block="CTHDR"  condition="isct"	offset="432"	intype="Int32_B"	inlength="1"	name="CT_datamod"		dicomtype="?"	dicomtag="?"	enum="1=Raw,2=Offset Corrected,3=Normalized"	#  Amount of processing that will be
+block="CTHDR"  condition="isct"	offset="436"	intype="String"	inlength="13"	name="CT_qcalfile"		dicomtype="?"	dicomtag="?"		#  Source of the qcal vectors
+block="CTHDR"  condition="isct"	offset="449"	intype="String"	inlength="13"	name="CT_calmodfile"		dicomtype="?"	dicomtag="?"		#  Source of the cal vectors
+block="CTHDR"  condition="isct"	offset="462"	intype="Int16_B"	inlength="1"	name="CT_wordsperview"	dicomtype="?"	dicomtag="?"		#  Number of words per view
+block="CTHDR"  condition="isct"	offset="464"	intype="String"	inlength="1"	name="CT_rl_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for side of image
+block="CTHDR"  condition="isct"	offset="465"	intype="String"	inlength="1"	name="CT_ap_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for anterior/posterior
+block="CTHDR"  condition="isct"	offset="466"	intype="String"	inlength="1"	name="CT_sctstr_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for scout start loc
+block="CTHDR"  condition="isct"	offset="467"	intype="String"	inlength="1"	name="CT_sctend_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter for scout end loc
+block="CTHDR"  condition="isct"	offset="468"	intype="String"	inlength="3"	name="CT_sct_anref"		dicomtype="?"	dicomtag="?"		#  Anatomical reference for scout
+block="CTHDR"  condition="isct"	offset="472"	intype="Int16_B"	inlength="1"	name="CT_pps_scalwin"	dicomtype="?"	dicomtag="?"		#  PpScan window range for output Scaling
+block="CTHDR"  condition="isct"	offset="474"	intype="Int16_B"	inlength="1"	name="CT_pps_qcalflag"	dicomtype="?"	dicomtag="?"		#  PpScan Qcal modification flag
+block="CTHDR"  condition="isct"	offset="476"	intype="Int16_B"	inlength="1"	name="CT_pps_pcalflag"	dicomtype="?"	dicomtag="?"		#  PpScan Pcal modification flag
+block="CTHDR"  condition="isct"	offset="478"	intype="Int16_B"	inlength="1"	name="CT_pps_thetafix"	dicomtype="?"	dicomtag="?"		#  PpScan Theta Fix (Angle Correction)
+block="CTHDR"  condition="isct"	offset="480"	intype="Int16_B"	inlength="1"	name="CT_pps_bhflag"		dicomtype="?"	dicomtag="?"		#  PpScan Beam Hardening Flag
+block="CTHDR"  condition="isct"	offset="482"	intype="Int16_B"	inlength="1"	name="CT_spot_size"		dicomtype="?"	dicomtag="?"	enum="1=small,2=large"	#  tube focal spot size
+block="CTHDR"  condition="isct"	offset="484"	intype="Int16_B"	inlength="1"	name="CT_spot_pos"		dicomtype="?"	dicomtag="?"	enum="1=left,2=center,3=right"	#  tube focal spot position
+block="CTHDR"  condition="isct"	offset="486"	intype="Int16_B"	inlength="1"	name="CT_recondataset"	dicomtype="?"	dicomtag="?"	bitmap="0:none,half scan views;1:none,normal scan views;2:none,over scan views;3:none,variable views"	#  Dependent on number of views processed
+block="CTHDR"  condition="isct"	offset="488"	intype="Int16_B"	inlength="1"	name="CT_ndetcellsfov"	dicomtype="?"	dicomtag="?"		#  Field of view in detector cells
+block="CTHDR"  condition="isct"	offset="490"	intype="IEEE_Float64_B"	inlength="1"	name="CT_strtscantime"	dicomtype="?"	dicomtag="?"		#  Start time(secs) of this scan
+block="CTHDR"  condition="isct"	offset="498"	intype="Int16_B"	inlength="1"	keyword="CT_gandir"		dicomtype="?"	dicomtag="?"	enum="1=Clockwise:CW,2=CounterClockwise:CCW"	#  Gantry Rotation Direction
+block="CTHDR"  condition="isct"	offset="500"	intype="Int16_B"	inlength="1"	name="CT_rotorspeed"		dicomtype="?"	dicomtag="?"	enum="1=off,2=low,3=medium,4=high"	#  Tube Rotor Speed
+block="CTHDR"  condition="isct"	offset="502"	intype="Int16_B"	inlength="1"	name="CT_trigmode"		dicomtype="?"	dicomtag="?"	enum="1=Normal Trigger:XTTX,2=XRayoff Trigger:TT,3=TXXT,4=XXTT"	#  TGGC Trigger Mode
+block="CTHDR"  condition="isct"	offset="504"	intype="IEEE_Float32_B"	inlength="1"	name="CT_sitilt"		dicomtype="?"	dicomtag="?"		#  Rx'd gantry tilt - not annotated
+block="CTHDR"  condition="isct"	offset="508"	intype="IEEE_Float32_B"	inlength="1"	name="CT_targcen_R"		dicomtype="?"	dicomtag="?"		#  R/L coordinate for target recon center
+block="CTHDR"  condition="isct"	offset="512"	intype="IEEE_Float32_B"	inlength="1"	name="CT_targcen_A"		dicomtype="?"	dicomtag="?"		#  A/P coordinate for target recon center
+block="CTHDR"  condition="isct"	offset="516"	intype="Int16_B"	inlength="1"	name="CT_backprojflag"	dicomtype="?"	dicomtag="?"		#  Value of Back Projection button
+block="CTHDR"  condition="isct"	offset="518"	intype="Int16_B"	inlength="1"	name="CT_fatqestflag"	dicomtype="?"	dicomtag="?"		#  Set if fatq estimates were used
+block="CTHDR"  condition="isct"	offset="520"	intype="IEEE_Float32_B"	inlength="1"	name="CT_zavg"		dicomtype="?"	dicomtag="?"		#  Z chan avg over views
+block="CTHDR"  condition="isct"	offset="524"	intype="IEEE_Float32_B"	inlength="1"	name="CT_leftrefavg"		dicomtype="?"	dicomtag="?"		#  avg of left ref chans over
+block="CTHDR"  condition="isct"	offset="528"	intype="IEEE_Float32_B"	inlength="1"	name="CT_leftrefmax"		dicomtype="?"	dicomtag="?"		#  max left chan value over views
+block="CTHDR"  condition="isct"	offset="532"	intype="IEEE_Float32_B"	inlength="1"	name="CT_rightrefavg"	dicomtype="?"	dicomtag="?"		#  avg of right ref chans over
+block="CTHDR"  condition="isct"	offset="536"	intype="IEEE_Float32_B"	inlength="1"	name="CT_rightrefmax"	dicomtype="?"	dicomtag="?"		#  max right chan value over views
+block="CTHDR"  condition="isct"	offset="540"	intype="String"	inlength="13"	name="CT_im_alloc_key"	dicomtype="?"	dicomtag="?"		#  process that last allocated this record
+block="CTHDR"  condition="isct"	offset="554"	intype="Unix_DateTime_B"	inlength="1"	keyword="CT_im_lastmod"		dicomtype="?"	dicomtag="?"		#  Date/Time of Last Change
+block="CTHDR"  condition="isct"	offset="558"	intype="String"	inlength="2"	name="CT_im_verscre"		dicomtype="?"	dicomtag="?"		#  Genesis version - Created
+block="CTHDR"  condition="isct"	offset="560"	intype="String"	inlength="2"	name="CT_im_verscur"		dicomtype="?"	dicomtag="?"		#  Genesis version - Now
+block="CTHDR"  condition="isct"	offset="562"	intype="Int32_B"	inlength="1"	name="CT_im_pds_a"		dicomtype="?"	dicomtag="?"		#  PixelData size - as stored
+block="CTHDR"  condition="isct"	offset="566"	intype="Int32_B"	inlength="1"	name="CT_im_pds_c"		dicomtype="?"	dicomtag="?"		#  PixelData size - Compressed
+block="CTHDR"  condition="isct"	offset="570"	intype="Int32_B"	inlength="1"	name="CT_im_pds_u"		dicomtype="?"	dicomtag="?"		#  PixelData size - UnCompressed
+block="CTHDR"  condition="isct"	offset="574"	intype="Uint32_B"	inlength="1"	name="CT_im_checksum"	dicomtype="?"	dicomtag="?"		#  AcqRecon record checksum
+block="CTHDR"  condition="isct"	offset="578"	intype="Int32_B"	inlength="1"	name="CT_im_archived"	dicomtype="?"	dicomtag="?"		#  Image Archive Flag
+block="CTHDR"  condition="isct"	offset="582"	intype="Int32_B"	inlength="1"	name="CT_im_complete"	dicomtype="?"	dicomtag="?"		#  Image Complete Flag
+block="CTHDR"  condition="isct"	offset="586"	intype="Int16_B"	inlength="1"	name="CT_biop_pos"		dicomtype="?"	dicomtag="?"	bitmap="0:none,superior;1:none,centered;2:none,inferior"	#  Biopsy Position
+block="CTHDR"  condition="isct"	offset="588"	intype="IEEE_Float32_B"	inlength="1"	name="CT_biop_tloc"		dicomtype="?"	dicomtag="?"		#  Biopsy T Location
+block="CTHDR"  condition="isct"	offset="592"	intype="IEEE_Float32_B"	inlength="1"	name="CT_biop_refloc"	dicomtype="?"	dicomtag="?"		#  Biopsy Ref Location
+block="CTHDR"  condition="isct"	offset="596"	intype="Int16_B"	inlength="1"	name="CT_ref_chan"		dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	#  Reference Channel Used
+block="CTHDR"  condition="isct"	offset="598"	intype="IEEE_Float32_B"	inlength="1"	name="CT_bp_coef"		dicomtype="?"	dicomtag="?"		#  Back Projector Coefficient
+block="CTHDR"  condition="isct"	offset="602"	intype="Int16_B"	inlength="1"	name="CT_psc"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#  Primary Speed Correction Used
+block="CTHDR"  condition="isct"	offset="604"	intype="Int16_B"	inlength="1"	name="CT_overrng_corr"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#  Overrange Correction Used
+block="CTHDR"  condition="isct"	offset="606"	intype="IEEE_Float32_B"	inlength="1"	name="CT_dyn_z_alpha"	dicomtype="?"	dicomtag="?"		#  Dynamic Z Alpha Value
+block="CTHDR"  condition="isct"	offset="610"	intype="String"	inlength="1"	name="CT_ref_img"		dicomtype="?"	dicomtag="?"		#  Reference Image Field
+block="CTHDR"  condition="isct"	offset="611"	intype="String"	inlength="1"	name="CT_sum_img"		dicomtype="?"	dicomtag="?"		#  Summary Image Field
+block="CTHDR"  condition="isct"	offset="612"	intype="Uint16_B"	inlength="1"	name="CT_img_window"		dicomtype="?"	dicomtag="?"		#  Window Value
+block="CTHDR"  condition="isct"	offset="614"	intype="Int16_B"	inlength="1"	name="CT_img_level"		dicomtype="?"	dicomtag="?"		#  Level Value
+block="CTHDR"  condition="isct"	offset="616"	intype="Int32_B"	inlength="1"	name="CT_slop_int_1"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 1
+block="CTHDR"  condition="isct"	offset="620"	intype="Int32_B"	inlength="1"	name="CT_slop_int_2"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 2
+block="CTHDR"  condition="isct"	offset="624"	intype="Int32_B"	inlength="1"	name="CT_slop_int_3"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 3
+block="CTHDR"  condition="isct"	offset="628"	intype="Int32_B"	inlength="1"	name="CT_slop_int_4"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 4
+block="CTHDR"  condition="isct"	offset="632"	intype="Int32_B"	inlength="1"	name="CT_slop_int_5"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 5
+block="CTHDR"  condition="isct"	offset="636"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_1"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 1
+block="CTHDR"  condition="isct"	offset="640"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_2"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 2
+block="CTHDR"  condition="isct"	offset="644"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_3"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 3
+block="CTHDR"  condition="isct"	offset="648"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_4"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 4
+block="CTHDR"  condition="isct"	offset="652"	intype="IEEE_Float32_B"	inlength="1"	name="CT_slop_float_5"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 5
+block="CTHDR"  condition="isct"	offset="656"	intype="String"	inlength="16"	name="CT_slop_str_1"		dicomtype="?"	dicomtag="?"		#  String Slop Field 1
+block="CTHDR"  condition="isct"	offset="672"	intype="String"	inlength="16"	name="CT_slop_str_2"		dicomtype="?"	dicomtag="?"		#  String Slop Field 2
+block="CTHDR"  condition="isct"	offset="688"	intype="IEEE_Float32_B"	inlength="1"	name="CT_deltastart"		dicomtype="?"	dicomtag="?"		#  Delta Start Time
+block="CTHDR"  condition="isct"	offset="692"	intype="Int32_B"	inlength="1"	name="CT_maxOverrange"	dicomtype="?"	dicomtag="?"		#  Max Overranges In A View
+block="CTHDR"  condition="isct"	offset="696"	intype="IEEE_Float32_B"	inlength="1"	name="CT_avgOverrange"	dicomtype="?"	dicomtag="?"		#  Avg Overranges All Views
+block="CTHDR"  condition="isct"	offset="700"	intype="Int16_B"	inlength="1"	name="CT_afterglow"		dicomtype="?"	dicomtag="?"	bitmap="0:PSC term off,PSC term on;1:Second term off,Second term on;2:Third term off,Third term on;3:Fourth term off,Fourth term on"	#  Corrected Afterglow Terms
+block="CTHDR"  condition="isct"	offset="702"	intype="Uint16_B"	inlength="1"	name="CT_z_blocked"		dicomtype="?"	dicomtag="?"		#  No Views z Channel Blocked
+block="CTHDR"  condition="isct"	offset="704"	intype="Uint16_B"	inlength="1"	name="CT_ref1_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref1 Channel Blocked
+block="CTHDR"  condition="isct"	offset="706"	intype="Uint16_B"	inlength="1"	name="CT_ref2_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref2 Channel Blocked
+block="CTHDR"  condition="isct"	offset="708"	intype="Uint16_B"	inlength="1"	name="CT_ref3_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref3 Channel Blocked
+block="CTHDR"  condition="isct"	offset="710"	intype="Uint16_B"	inlength="1"	name="CT_ref4_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref4 Channel Blocked
+block="CTHDR"  condition="isct"	offset="712"	intype="Uint16_B"	inlength="1"	name="CT_ref5_blocked"	dicomtype="?"	dicomtag="?"		#  No Views Ref5 Channel Blocked
+block="CTHDR"  condition="isct"	offset="714"	intype="Int16_B"	inlength="1"	name="CT_integrity"		dicomtype="?"	dicomtag="?"	enum="0=GE Image,1=Imported Image"	#  GE Image Integrity
+block="CTHDR"  condition="isct"	offset="716"	intype="String"	inlength="8"	name="CT_pitchRatio"		dicomtype="?"	dicomtag="?"		#  Scan Pitch Ratio
+block="CTHDR"  condition="isct"	offset="724"	intype="String"	inlength="32"	name="CT_image_uid"		dicomtype="?"	dicomtag="?"		#  Image Unique ID
+block="CTHDR"  condition="isct"	offset="756"	intype="String"	inlength="32"	name="CT_sop_uid"		dicomtype="?"	dicomtag="?"		#  Service Obj Class Unique ID
+block="CTHDR"  condition="isct"	offset="788"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xraydelay"		dicomtype="?"	dicomtag="?"		#  Start Scan To XRay On Delay
+block="CTHDR"  condition="isct"	offset="792"	intype="IEEE_Float32_B"	inlength="1"	name="CT_xrayduration"	dicomtype="?"	dicomtag="?"		#  Duration Of XRay On
+block="CTHDR"  condition="isct"	offset="796"	intype="String"	inlength="223"	name="CT_ct_padding"		dicomtype="?"	dicomtag="?"		#  Spare Space
+block="MRHDR"  condition="ismr"	offset="0"	intype="String"	inlength="4"	name="MR_im_suid"		dicomtype="?"	dicomtag="?"		#  Suite id for this image
+block="MRHDR"  condition="ismr"	offset="4"	intype="Int16_B"	inlength="1"	name="MR_im_uniq"		dicomtype="?"	dicomtag="?"		#  The Make-Unique Flag
+block="MRHDR"  condition="ismr"	offset="6"	intype="String"	inlength="1"	name="MR_im_diskid"		dicomtype="?"	dicomtag="?"		#  Disk ID for this Image
+block="MRHDR"  condition="ismr"	offset="8"	intype="Uint16_B"	inlength="1"	name="MR_im_exno"		dicomtype="?"	dicomtag="?"		#  Exam number for this image
+block="MRHDR"  condition="ismr"	offset="10"	intype="Int16_B"	inlength="1"	name="MR_im_seno"		dicomtype="?"	dicomtag="?"		#  Series Number for this image
+block="MRHDR"  condition="ismr"	offset="12"	intype="Int16_B"	inlength="1"	keyword="MR_im_no"		dicomtype="IS"	dicomtag="InstanceNumber"	#  Image Number
+block="MRHDR"  condition="ismr"	offset="14"	intype="Unix_DateTime_B"	inlength="1"	keyword="MR_im_datetime"	dicomtype="?"	dicomtag="?"		#  Allocation Image date/time stamp
+block="MRHDR"  condition="ismr"	offset="18"	intype="Unix_DateTime_B"	inlength="1"	keyword="MR_im_actual_dt"	dicomtype="?"	dicomtag="?"		#  Actual Image date/time stamp
+block="MRHDR"  condition="ismr"	offset="22"	intype="IEEE_Float32_B"	inlength="1"	name="MR_sctime"		dicomtype="?"	dicomtag="?"		#  Duration of scan (secs)
+block="MRHDR"  condition="ismr"	offset="26"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slthick"		dicomtype="DS"	dicomtag="SliceThickness"	#  Slice Thickness (mm)
+block="MRHDR"  condition="ismr"	offset="30"	intype="Int16_B"	inlength="1"	keyword="MR_imatrix_X"		dicomtype="?"	dicomtag="?"		#  Image matrix size - X
+block="MRHDR"  condition="ismr"	offset="32"	intype="Int16_B"	inlength="1"	keyword="MR_imatrix_Y"		dicomtype="?"	dicomtag="?"		#  Image matrix size - Y
+block="MRHDR"  condition="ismr"	offset="34"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dfov"		dicomtype="?"	dicomtag="?"		#  Display field of view - X (mm)
+block="MRHDR"  condition="ismr"	offset="38"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dfov_rect"		dicomtype="?"	dicomtag="?"		#  Display field of view - Y (if different)
+block="MRHDR"  condition="ismr"	offset="42"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dim_X"		dicomtype="?"	dicomtag="?"		#  Image dimension - X
+block="MRHDR"  condition="ismr"	offset="46"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_dim_Y"		dicomtype="?"	dicomtag="?"		#  Image dimension - Y
+block="MRHDR"  condition="ismr"	offset="50"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_pixsize_X"		dicomtype="?"	dicomtag="?"	#  Image pixel size - X
+block="MRHDR"  condition="ismr"	offset="54"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_pixsize_Y"		dicomtype="?"	dicomtag="?"	#  Image pixel size - Y
+block="MRHDR"  condition="ismr"	offset="58"	intype="String"	inlength="14"	name="MR_pdid"		dicomtype="?"	dicomtag="?"		#  Pixel Data ID
+block="MRHDR"  condition="ismr"	offset="72"	intype="String"	inlength="17"	name="MR_contrastIV"		dicomtype="?"	dicomtag="?"		#  IV Contrast Agent
+block="MRHDR"  condition="ismr"	offset="89"	intype="String"	inlength="17"	name="MR_contrastOral"	dicomtype="?"	dicomtag="?"		#  Oral Contrast Agent
+block="MRHDR"  condition="ismr"	offset="106"	intype="Int16_B"	inlength="1"	name="MR_contmode"		dicomtype="?"	dicomtag="?"	bitmap="0:none,oral;1:none,intravenous"	#  Image Contrast Mode
+block="MRHDR"  condition="ismr"	offset="108"	intype="Int16_B"	inlength="1"	name="MR_serrx"		dicomtype="?"	dicomtag="?"		#  Series from which prescribed
+block="MRHDR"  condition="ismr"	offset="110"	intype="Int16_B"	inlength="1"	name="MR_imgrx"		dicomtype="?"	dicomtag="?"		#  Image from which prescribed
+block="MRHDR"  condition="ismr"	offset="112"	intype="Int16_B"	inlength="1"	name="MR_screenformat"	dicomtype="?"	dicomtag="?"		#  Screen Format(8/16 bit)
+block="MRHDR"  condition="ismr"	offset="114"	intype="Int16_B"	inlength="1"	name="MR_plane"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Scout Plane(SCT);1:none,Axial Plane(Ax);2:none,Sagittal Plane(Sag);3:none,Coronal Plane(Cor);4:none,Oblique Plane(O);5:none,ParAxial Plane(PAX);6:none,Reformatted Plane(RFMT);7:none,Projected Plane(PJN);8:none,Mixed Plane(MIXED)"	#  Plane Type
+block="MRHDR"  condition="ismr"	offset="116"	intype="IEEE_Float32_B"	inlength="1"	name="MR_scanspacing"	dicomtype="DS"	dicomtag="SpacingBetweenSlices"	#  Spacing between scans (mm?)
+block="MRHDR"  condition="ismr"	offset="120"	intype="Int16_B"	inlength="1"	name="MR_im_compress"	dicomtype="?"	dicomtag="?"		#  Image compression type for allocation
+block="MRHDR"  condition="ismr"	offset="122"	intype="Int16_B"	inlength="1"	name="MR_im_scouttype"	dicomtype="?"	dicomtag="?"		#  Scout Type (AP or lateral)
+block="MRHDR"  condition="ismr"	offset="124"	intype="String"	inlength="1"	name="MR_loc_ras"		dicomtype="?"	dicomtag="?"		#  RAS letter of image location
+block="MRHDR"  condition="ismr"	offset="126"	intype="IEEE_Float32_B"	inlength="1"	name="MR_loc"		dicomtype="DS"	dicomtag="SliceLocation"	#  Image location
+block="MRHDR"  condition="ismr"	offset="130"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_ctr_R"		dicomtype="?"	dicomtag="?"		#  Center R coord of plane image
+block="MRHDR"  condition="ismr"	offset="134"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_ctr_A"		dicomtype="?"	dicomtag="?"		#  Center A coord of plane image
+block="MRHDR"  condition="ismr"	offset="138"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_ctr_S"		dicomtype="?"	dicomtag="?"		#  Center S coord of plane image
+block="MRHDR"  condition="ismr"	offset="142"	intype="IEEE_Float32_B"	inlength="1"	name="MR_norm_R"		dicomtype="?"	dicomtag="?"		#  Normal R coord
+block="MRHDR"  condition="ismr"	offset="146"	intype="IEEE_Float32_B"	inlength="1"	name="MR_norm_A"		dicomtype="?"	dicomtag="?"		#  Normal A coord
+block="MRHDR"  condition="ismr"	offset="150"	intype="IEEE_Float32_B"	inlength="1"	name="MR_norm_S"		dicomtype="?"	dicomtag="?"		#  Normal S coord
+block="MRHDR"  condition="ismr"	offset="154"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_tlhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Left Hand Corner
+block="MRHDR"  condition="ismr"	offset="158"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_tlhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Left Hand Corner
+block="MRHDR"  condition="ismr"	offset="162"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_tlhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Left Hand Corner
+block="MRHDR"  condition="ismr"	offset="166"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_trhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Top Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="170"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_trhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Top Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="174"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_trhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Top Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="178"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_brhc_R"		dicomtype="?"	dicomtag="?"		#  R Coord of Bottom Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="182"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_brhc_A"		dicomtype="?"	dicomtag="?"		#  A Coord of Bottom Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="186"	intype="IEEE_Float32_B"	inlength="1"	keyword="MR_brhc_S"		dicomtype="?"	dicomtag="?"		#  S Coord of Bottom Right Hand Corner
+block="MRHDR"  condition="ismr"	offset="190"	intype="String"	inlength="4"	name="MR_forimgrev"		dicomtype="?"	dicomtag="?"		#  Foreign Image Revision
+block="MRHDR"  condition="ismr"	offset="194"	intype="Int32_B"	inlength="1"	keyword="MR_tr"			dicomtype="?"	dicomtag="?"		#  Pulse repetition time(usec)
+block="MRHDR"  condition="ismr"	offset="198"	intype="Int32_B"	inlength="1"	keyword="MR_ti"			dicomtype="?"	dicomtag="?"		#  Pulse inversion time(usec)
+block="MRHDR"  condition="ismr"	offset="202"	intype="Int32_B"	inlength="1"	keyword="MR_te"			dicomtype="?"	dicomtag="?"		#  Pulse echo time(usec)
+block="MRHDR"  condition="ismr"	offset="206"	intype="Int32_B"	inlength="1"	name="MR_te2"			dicomtype="?"	dicomtag="?"		#  Second echo echo (usec)
+block="MRHDR"  condition="ismr"	offset="210"	intype="Int16_B"	inlength="1"	name="MR_numecho"		dicomtype="?"	dicomtag="?"	#  Number of echoes
+block="MRHDR"  condition="ismr"	offset="212"	intype="Int16_B"	inlength="1"	name="MR_echonum"		dicomtype="IS"	dicomtag="EchoNumbers"	#  Echo Number
+block="MRHDR"  condition="ismr"	offset="214"	intype="IEEE_Float32_B"	inlength="1"	name="MR_tbldlta"		dicomtype="?"	dicomtag="?"		#  Table Delta
+block="MRHDR"  condition="ismr"	offset="218"	intype="IEEE_Float32_B"	inlength="1"	name="MR_nex"		dicomtype="DS"	dicomtag="NumberOfAverages"	#  Number of Excitations
+block="MRHDR"  condition="ismr"	offset="222"	intype="Int16_B"	inlength="1"	name="MR_contig"		dicomtype="?"	dicomtag="?"	enum="0=No:/I,1=Yes:/C"	#  Continuous Slices Flag
+block="MRHDR"  condition="ismr"	offset="224"	intype="Int16_B"	inlength="1"	name="MR_hrtrate"		dicomtype="IS"	dicomtag="HeartRate"	#  Cardiac Heart Rate (bpm)
+block="MRHDR"  condition="ismr"	offset="226"	intype="Int32_B"	inlength="1"	name="MR_tdel"		dicomtype="?"	dicomtag="?"		#  Delay time after trigger (msec)
+block="MRHDR"  condition="ismr"	offset="230"	intype="IEEE_Float32_B"	inlength="1"	name="MR_saravg"		dicomtype="DS"	dicomtag="SAR"		#  Average SAR
+block="MRHDR"  condition="ismr"	offset="234"	intype="IEEE_Float32_B"	inlength="1"	name="MR_sarpeak"		dicomtype="?"	dicomtag="?"		#  Peak SAR
+block="MRHDR"  condition="ismr"	offset="238"	intype="Int16_B"	inlength="1"	name="MR_monsar"		dicomtype="?"	dicomtag="?"		#  Monitor SAR flag
+block="MRHDR"  condition="ismr"	offset="240"	intype="Int16_B"	inlength="1"	name="MR_trgwindow"		dicomtype="IS"	dicomtag="TriggerWindow"	#  Trigger window (% of R-R interval)
+block="MRHDR"  condition="ismr"	offset="242"	intype="IEEE_Float32_B"	inlength="1"	name="MR_reptime"		dicomtype="?"	dicomtag="?"		#  Cardiac repetition time
+block="MRHDR"  condition="ismr"	offset="246"	intype="Int16_B"	inlength="1"	name="MR_imgpcyc"		dicomtype="IS"	dicomtag="CardiacNumberOfImages"	#  Images per cardiac cycle
+block="MRHDR"  condition="ismr"	offset="248"	intype="Int16_B"	inlength="1"	name="MR_xmtgain"		dicomtype="?"	dicomtag="?"		#  Actual Transmit Gain (.1 db)
+block="MRHDR"  condition="ismr"	offset="250"	intype="Int16_B"	inlength="1"	name="MR_rcvgain1"		dicomtype="?"	dicomtag="?"		#  Actual Receive Gain Analog (.1 db)
+block="MRHDR"  condition="ismr"	offset="252"	intype="Int16_B"	inlength="1"	name="MR_rcvgain2"		dicomtype="?"	dicomtag="?"		#  Actual Receive Gain Digital (.1 db)
+block="MRHDR"  condition="ismr"	offset="254"	intype="Int16_B"	inlength="1"	name="MR_mr_flip"		dicomtype="DS"	dicomtag="FlipAngle"	#  Flip Angle for GRASS scans (deg.)
+block="MRHDR"  condition="ismr"	offset="256"	intype="Int32_B"	inlength="1"	name="MR_mindat"		dicomtype="?"	dicomtag="?"		#  Minimum Delay after Trigger (uSec)
+block="MRHDR"  condition="ismr"	offset="260"	intype="Int16_B"	inlength="1"	name="MR_cphase"		dicomtype="?"	dicomtag="?"		#  Total Cardiac Phase prescribed
+block="MRHDR"  condition="ismr"	offset="262"	intype="Int16_B"	inlength="1"	keyword="MR_swappf"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:SPF"	#  Swap Phase/Frequency Axis
+block="MRHDR"  condition="ismr"	offset="264"	intype="Int16_B"	inlength="1"	name="MR_pauseint"		dicomtype="?"	dicomtag="?"		#  Pause Interval (slices)
+block="MRHDR"  condition="ismr"	offset="266"	intype="IEEE_Float32_B"	inlength="1"	name="MR_pausetime"		dicomtype="?"	dicomtag="?"		#  Pause Time
+block="MRHDR"  condition="ismr"	offset="270"	intype="Int32_B"	inlength="1"	name="MR_obplane"		dicomtype="?"	dicomtag="?"		#  Oblique Plane
+block="MRHDR"  condition="ismr"	offset="274"	intype="Int32_B"	inlength="1"	name="MR_slocfov"		dicomtype="?"	dicomtag="?"		#  Slice Offsets on Freq axis
+block="MRHDR"  condition="ismr"	offset="278"	intype="Int32_B"	inlength="1"	keyword="MR_xmtfreq"		dicomtype="?"	dicomtag="?"		#  Center Frequency (0.1 Hz)
+block="MRHDR"  condition="ismr"	offset="282"	intype="Int32_B"	inlength="1"	name="MR_autoxmtfreq"	dicomtype="?"	dicomtag="?"		#  Auto Center Frequency (0.1 Hz)
+block="MRHDR"  condition="ismr"	offset="286"	intype="Int16_B"	inlength="1"	name="MR_autoxmtgain"	dicomtype="?"	dicomtag="?"		#  Auto Transmit Gain (0.1 dB)
+block="MRHDR"  condition="ismr"	offset="288"	intype="Int16_B"	inlength="1"	name="MR_prescan_r1"		dicomtype="?"	dicomtag="?"		#  PreScan R1 - Analog
+block="MRHDR"  condition="ismr"	offset="290"	intype="Int16_B"	inlength="1"	name="MR_prescan_r2"		dicomtype="?"	dicomtag="?"		#  PreScan R2 - Digital
+block="MRHDR"  condition="ismr"	offset="292"	intype="Int32_B"	inlength="1"	name="MR_user_bitmap"	dicomtype="?"	dicomtag="?"		#  Bitmap defining user CVs
+block="MRHDR"  condition="ismr"	offset="296"	intype="Int16_B"	inlength="1"	name="MR_cenfreq"		dicomtype="?"	dicomtag="?"		#  Center Frequency Method
+block="MRHDR"  condition="ismr"	offset="298"	intype="Int16_B"	inlength="1"	keyword="MR_imode"		dicomtype="?"	dicomtag="?"	enum="1=Two D:2D,2=Three D Volume:3D,3=Three D Fourier:none,4=Cine:Cine,5=Angiography:ANGIO,6=Spectroscopy:SPECT,7=Flouroscopy:FLOURO,8=Research Mode:RM"	#  Imaging Mode
+block="MRHDR"  condition="ismr"	offset="300"	intype="Int32_B"	inlength="1"	keyword="MR_iopt"		dicomtype="?"	dicomtag="?"	bitmap="0:none,EG;1:none,RESP;2:none,RC;3:none,FC;4:none,CL;5:none,ST;6:none,PG;7:none,NP;8:none,NF;9:none,RT;10:none,VB;11:none,ED;12:none,PM;13:none,SQ;14:none,CS;15:none,MP;16:none,SQPIX"	#  Imaging Options
+block="MRHDR"  condition="ismr"	offset="304"	intype="Int16_B"	inlength="1"	keyword="MR_pseq"		dicomtype="?"	dicomtag="?"	enum="0=SE,1=IR,2=RM:RM,3=RMGE:none,4=GRE:GR,5=MPGR,6=MPIRS:IR/s,7=MPIRI:IR,8=VOGRE:3D/GR,9=CINEGRE:Cine/GRE,10=SPGR,11=SSFP,12=TF:TOF,13=PC,14=CINSPGR:Cine/SPGR,15=TOFGR:TOG/GR,16=TOFSPGR:TOF/SPGR,17=PCGR:PC/GR,18=PCSPGR:PC/SPGR,19=FSE,20=FGR,21=FMPGR,22=FSPGR,23=FMPSPGR,24=SPECT,25=PSEQ_MIXED:MIXED,26=FMPIR,27=SPECSTEAM,28=SPECPRESS"	#  Pulse Sequence
+block="MRHDR"  condition="ismr"	offset="306"	intype="Int16_B"	inlength="1"	name="MR_pseqmode"		dicomtype="?"	dicomtag="?"	enum="1=Product,2=Research Mode,3=Research Mode GE"	#  Pulse Sequence Mode
+block="MRHDR"  condition="ismr"	offset="308"	intype="String"	inlength="33"	name="MR_psdname"		dicomtype="SH"	dicomtag="SequenceName"		#  Pulse Sequence Name
+block="MRHDR"  condition="ismr"	offset="342"	intype="Unix_DateTime_B"	inlength="1"	name="MR_psd_datetime"		dicomtype="?"	dicomtag="?"		#  PSD Creation Date and Time
+block="MRHDR"  condition="ismr"	offset="346"	intype="String"	inlength="13"	name="MR_psd_iname"		dicomtype="?"	dicomtag="?"		#  PSD name from inside PSD
+block="MRHDR"  condition="ismr"	offset="360"	intype="Int16_B"	inlength="1"	name="MR_ctyp"			dicomtype="?"	dicomtag="?"	enum="1=head,2=body,3=surface"	#  Coil Type
+block="MRHDR"  condition="ismr"	offset="362"	intype="String"	inlength="17"	name="MR_cname"			dicomtype="SH"	dicomtag="ReceiveCoilName"	#  Coil Name
+block="MRHDR"  condition="ismr"	offset="380"	intype="Int16_B"	inlength="1"	name="MR_surfctyp"		dicomtype="?"	dicomtag="?"		#  Surface Coil Type
+block="MRHDR"  condition="ismr"	offset="382"	intype="Int16_B"	inlength="1"	name="MR_surfcext"		dicomtype="?"	dicomtag="?"		#  Extremity Coil Flag
+block="MRHDR"  condition="ismr"	offset="384"	intype="Int32_B"	inlength="1"	name="MR_rawrunnum"		dicomtype="IS"	dicomtag="AcquisitionNumber"		#  RawData Run Number
+block="MRHDR"  condition="ismr"	offset="388"	intype="Uint32_B"	inlength="1"	name="MR_cal_fldstr"		dicomtype="?"	dicomtag="?"		#  Calibrated Field Strength (x10 uGauss)
+block="MRHDR"  condition="ismr"	offset="392"	intype="Int16_B"	inlength="1"	keyword="MR_supp_tech"		dicomtype="?"	dicomtag="?"	enum="0=none,1=fat:F,2=water:W"	#  SAT fat/water/none
+block="MRHDR"  condition="ismr"	offset="394"	intype="IEEE_Float32_B"	inlength="1"	name="MR_vbw"			dicomtype="?"	dicomtag="?"		#  Variable Bandwidth (Hz)
+block="MRHDR"  condition="ismr"	offset="398"	intype="Int16_B"	inlength="1"	name="MR_slquant"		dicomtype="?"	dicomtag="?"		#  Number of slices in this scan group
+block="MRHDR"  condition="ismr"	offset="400"	intype="Int16_B"	inlength="1"	name="MR_gpre"			dicomtype="?"	dicomtag="?"	enum="0=No GRX,1=GRX 1 localizer,2=GRX 2 localizers"	#  Graphically prescribed
+block="MRHDR"  condition="ismr"	offset="402"	intype="Int32_B"	inlength="1"	name="MR_intr_del"		dicomtype="?"	dicomtag="?"		#  Interimage/interloc delay (uSec)
+block="MRHDR"  condition="ismr"	offset="406"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user0"		dicomtype="?"	dicomtag="?"		#  User Variable 0
+block="MRHDR"  condition="ismr"	offset="410"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user1"		dicomtype="?"	dicomtag="?"		#  User Variable 1
+block="MRHDR"  condition="ismr"	offset="414"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user2"		dicomtype="?"	dicomtag="?"		#  User Variable 2
+block="MRHDR"  condition="ismr"	offset="418"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user3"		dicomtype="?"	dicomtag="?"		#  User Variable 3
+block="MRHDR"  condition="ismr"	offset="422"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user4"		dicomtype="?"	dicomtag="?"		#  User Variable 4
+block="MRHDR"  condition="ismr"	offset="426"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user5"		dicomtype="?"	dicomtag="?"		#  User Variable 5
+block="MRHDR"  condition="ismr"	offset="430"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user6"		dicomtype="?"	dicomtag="?"		#  User Variable 6
+block="MRHDR"  condition="ismr"	offset="434"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user7"		dicomtype="?"	dicomtag="?"		#  User Variable 7
+block="MRHDR"  condition="ismr"	offset="438"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user8"		dicomtype="?"	dicomtag="?"		#  User Variable 8
+block="MRHDR"  condition="ismr"	offset="442"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user9"		dicomtype="?"	dicomtag="?"		#  User Variable 9
+block="MRHDR"  condition="ismr"	offset="446"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user10"		dicomtype="?"	dicomtag="?"		#  User Variable 10
+block="MRHDR"  condition="ismr"	offset="450"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user11"		dicomtype="?"	dicomtag="?"		#  User Variable 11
+block="MRHDR"  condition="ismr"	offset="454"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user12"		dicomtype="?"	dicomtag="?"		#  User Variable 12
+block="MRHDR"  condition="ismr"	offset="458"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user13"		dicomtype="?"	dicomtag="?"		#  User Variable 13
+block="MRHDR"  condition="ismr"	offset="462"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user14"		dicomtype="?"	dicomtag="?"		#  User Variable 14
+block="MRHDR"  condition="ismr"	offset="466"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user15"		dicomtype="?"	dicomtag="?"		#  User Variable 15
+block="MRHDR"  condition="ismr"	offset="470"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user16"		dicomtype="?"	dicomtag="?"		#  User Variable 16
+block="MRHDR"  condition="ismr"	offset="474"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user17"		dicomtype="?"	dicomtag="?"		#  User Variable 17
+block="MRHDR"  condition="ismr"	offset="478"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user18"		dicomtype="?"	dicomtag="?"		#  User Variable 18
+block="MRHDR"  condition="ismr"	offset="482"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user19"		dicomtype="?"	dicomtag="?"		#  User Variable 19
+block="MRHDR"  condition="ismr"	offset="486"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user20"		dicomtype="?"	dicomtag="?"		#  User Variable 20
+block="MRHDR"  condition="ismr"	offset="490"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user21"		dicomtype="?"	dicomtag="?"		#  User Variable 21
+block="MRHDR"  condition="ismr"	offset="494"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user22"		dicomtype="?"	dicomtag="?"		#  User Variable 22
+block="MRHDR"  condition="ismr"	offset="498"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user23"		dicomtype="?"	dicomtag="?"		#  Projection Angle
+block="MRHDR"  condition="ismr"	offset="502"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user24"		dicomtype="?"	dicomtag="?"		#  Concat Sat Type Flag
+block="MRHDR"  condition="ismr"	offset="506"	intype="String"	inlength="13"	name="MR_im_alloc_key"	dicomtype="?"	dicomtag="?"			#  Process that allocated this record
+block="MRHDR"  condition="ismr"	offset="520"	intype="Unix_DateTime_B"	inlength="1"	keyword="MR_im_lastmod"		dicomtype="?"	dicomtag="?"		#  Date/Time of Last Change
+block="MRHDR"  condition="ismr"	offset="524"	intype="String"	inlength="2"	name="MR_im_verscre"		dicomtype="?"	dicomtag="?"		#  Genesis version - Created
+block="MRHDR"  condition="ismr"	offset="526"	intype="String"	inlength="2"	name="MR_im_verscur"		dicomtype="?"	dicomtag="?"		#  Genesis version - Now
+block="MRHDR"  condition="ismr"	offset="528"	intype="Int32_B"	inlength="1"	name="MR_im_pds_a"		dicomtype="?"	dicomtag="?"		#  PixelData size - as stored
+block="MRHDR"  condition="ismr"	offset="532"	intype="Int32_B"	inlength="1"	name="MR_im_pds_c"		dicomtype="?"	dicomtag="?"		#  PixelData size -Compressed
+block="MRHDR"  condition="ismr"	offset="536"	intype="Int32_B"	inlength="1"	name="MR_im_pds_u"		dicomtype="?"	dicomtag="?"		#  PixelData size -UnCompressed
+block="MRHDR"  condition="ismr"	offset="540"	intype="Uint32_B"	inlength="1"	name="MR_im_checksum"		dicomtype="?"	dicomtag="?"		#  AcqRecon record checksum
+block="MRHDR"  condition="ismr"	offset="544"	intype="Int32_B"	inlength="1"	name="MR_im_archived"		dicomtype="?"	dicomtag="?"		#  Image Archive Flag
+block="MRHDR"  condition="ismr"	offset="548"	intype="Int32_B"	inlength="1"	name="MR_im_complete"		dicomtype="?"	dicomtag="?"		#  Image Complete Flag
+block="MRHDR"  condition="ismr"	offset="552"	intype="Int16_B"	inlength="1"	keyword="MR_satbits"		dicomtype="?"	dicomtag="?"	bitmap="0:none,superior(S);1:none,inferior(I);2:none,right(R);3:none,left(R);4:none,anterior(A);5:none,posterior(P);6:none,superior(s);7:none,inferior(i);8:none,right(r);9:none,left(l);10:none,anterior(a);11:none,posterior(p)"	#  Bitmap of SAT selections
+block="MRHDR"  condition="ismr"	offset="554"	intype="Int16_B"	inlength="1"	keyword="MR_scic"		dicomtype="?"	dicomtag="?"	enum="0=Off,1=On:IIC"	#  Surface Coil Intensity Correction Flag
+block="MRHDR"  condition="ismr"	offset="556"	intype="Int16_B"	inlength="1"	name="MR_satxloc1"		dicomtype="?"	dicomtag="?"		#  R-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="558"	intype="Int16_B"	inlength="1"	name="MR_satxloc2"		dicomtype="?"	dicomtag="?"		#  L-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="560"	intype="Int16_B"	inlength="1"	name="MR_satyloc1"		dicomtype="?"	dicomtag="?"		#  A-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="562"	intype="Int16_B"	inlength="1"	name="MR_satyloc2"		dicomtype="?"	dicomtag="?"		#  P-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="564"	intype="Int16_B"	inlength="1"	name="MR_satzloc1"		dicomtype="?"	dicomtag="?"		#  S-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="566"	intype="Int16_B"	inlength="1"	name="MR_satzloc2"		dicomtype="?"	dicomtag="?"		#  I-side SAT pulse loc rel to lndmrk
+block="MRHDR"  condition="ismr"	offset="568"	intype="Int16_B"	inlength="1"	name="MR_satxthick"		dicomtype="?"	dicomtag="?"		#  Thickness of X-axis SAT pulse
+block="MRHDR"  condition="ismr"	offset="570"	intype="Int16_B"	inlength="1"	name="MR_satythick"		dicomtype="?"	dicomtag="?"		#  Thickness of Y-axis SAT pulse
+block="MRHDR"  condition="ismr"	offset="572"	intype="Int16_B"	inlength="1"	name="MR_satzthick"		dicomtype="?"	dicomtag="?"		#  Thickness of Z-axis SAT pulse
+block="MRHDR"  condition="ismr"	offset="574"	intype="Int16_B"	inlength="1"	keyword="MR_flax"		dicomtype="?"	dicomtag="?"	bitmap="0:none,S/I;1:none,A/P;2:none,R/L;3:none,SLC"	#  Phase contrast flow axis
+block="MRHDR"  condition="ismr"	offset="576"	intype="Int16_B"	inlength="1"	name="MR_venc"		dicomtype="?"	dicomtag="?"		#  Phase contrast velocity encoding
+block="MRHDR"  condition="ismr"	offset="578"	intype="Int16_B"	inlength="1"	name="MR_thk_disclmr"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#  Slice Thickness Disclaimer
+block="MRHDR"  condition="ismr"	offset="580"	intype="Int16_B"	inlength="1"	name="MR_ps_flag"		dicomtype="?"	dicomtag="?"	bitmap="0:none,AF(a);1:none,AS(A);2:none,M(M)"	#  Auto/Manual Prescan flag
+block="MRHDR"  condition="ismr"	offset="582"	intype="Int16_B"	inlength="1"	name="MR_ps_status"		dicomtype="?"	dicomtag="?"	bitmap="0:none,CF;1:none,TA;2:none,R1;3:none,R2"	#  Bitmap of changed values
+block="MRHDR"  condition="ismr"	offset="584"	intype="Int16_B"	inlength="1"	keyword="MR_image_type"		dicomtype="?"	dicomtag="?"	enum="0=Magnitude,1=Phase:PHASE,2=Real:REAL,3=Imaginary:IMAGINARY,4=Spectroscopy:SPECTRO"	#  Magnitude, Phase, Imaginary,Real,Spectroscopy
+block="MRHDR"  condition="ismr"	offset="586"	intype="Int16_B"	inlength="1"	keyword="MR_vas_collapse"	dicomtype="?"	dicomtag="?"	enum="0=Off,1=:COL,2=:MAG,3=:R/L,4=:A/P,5=:S/I,6=:PJN,7=:ALL"	#  Collapse Image
+block="MRHDR"  condition="ismr"	offset="588"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user23n"		dicomtype="?"	dicomtag="?"		#  User Variable 23
+block="MRHDR"  condition="ismr"	offset="592"	intype="IEEE_Float32_B"	inlength="1"	name="MR_user24n"		dicomtype="?"	dicomtag="?"		#  User Variable 24
+block="MRHDR"  condition="ismr"	offset="596"	intype="Int16_B"	inlength="1"	keyword="MR_proj_alg"	dicomtype="?"	dicomtag="?"	enum="0=None,1=Prototype,2=Minimum Pixel:Min,3=Maximum Pixel:Max"	#  Projection Algorithm
+block="MRHDR"  condition="ismr"	offset="598"	intype="String"	inlength="13"	name="MR_proj_name"		dicomtype="?"	dicomtag="?"		#  Projection Algorithm Name
+block="MRHDR"  condition="ismr"	offset="612"	intype="IEEE_Float32_B"	inlength="1"	name="MR_x_axis_rot"		dicomtype="?"	dicomtag="?"		#  X Axis Rotation
+block="MRHDR"  condition="ismr"	offset="616"	intype="IEEE_Float32_B"	inlength="1"	name="MR_y_axis_rot"		dicomtype="?"	dicomtag="?"		#  Y Axis Rotation
+block="MRHDR"  condition="ismr"	offset="620"	intype="IEEE_Float32_B"	inlength="1"	name="MR_z_axis_rot"		dicomtype="?"	dicomtag="?"		#  Z Axis Rotation
+block="MRHDR"  condition="ismr"	offset="624"	intype="Int32_B"	inlength="1"	name="MR_thresh_min1"	dicomtype="?"	dicomtag="?"		#  Lower Range of Pixels 1
+block="MRHDR"  condition="ismr"	offset="628"	intype="Int32_B"	inlength="1"	name="MR_thresh_max1"	dicomtype="?"	dicomtag="?"		#  Upper Range of Pixels 1
+block="MRHDR"  condition="ismr"	offset="632"	intype="Int32_B"	inlength="1"	name="MR_thresh_min2"	dicomtype="?"	dicomtag="?"		#  Lower Range of Pixels 2
+block="MRHDR"  condition="ismr"	offset="636"	intype="Int32_B"	inlength="1"	name="MR_thresh_max2"	dicomtype="?"	dicomtag="?"		#  Upper Range of Pixels 2
+block="MRHDR"  condition="ismr"	offset="640"	intype="Int16_B"	inlength="1"	keyword="MR_echo_trn_len"	dicomtype="?"	dicomtag="?"		#  Echo Train Length for Fast Spin Echo
+block="MRHDR"  condition="ismr"	offset="642"	intype="Int16_B"	inlength="1"	keyword="MR_frac_echo"		dicomtype="?"	dicomtag="?"	bitmap="0:none,Fractional(Fr);1:none,Effective(Ef)"	#  Effective TE Flag
+block="MRHDR"  condition="ismr"	offset="644"	intype="Int16_B"	inlength="1"	keyword="MR_prep_pulse"		dicomtype="?"	dicomtag="?"	enum="0=None,1=Inversion Recovery:IR,2=Driven Equilibrium:DE"	#  Preparatory Pulse Option
+block="MRHDR"  condition="ismr"	offset="646"	intype="Int16_B"	inlength="1"	name="MR_cphasenum"		dicomtype="?"	dicomtag="?"		#  Cardiac Phase Number
+block="MRHDR"  condition="ismr"	offset="648"	intype="Int16_B"	inlength="1"	keyword="MR_var_echo"		dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes:/V"	#  Variable Echo Flag
+block="MRHDR"  condition="ismr"	offset="650"	intype="String"	inlength="1"	name="MR_ref_img"		dicomtype="?"	dicomtag="?"		#  Reference Image Field
+block="MRHDR"  condition="ismr"	offset="651"	intype="String"	inlength="1"	name="MR_sum_img"		dicomtype="?"	dicomtag="?"		#  Summary Image Field
+block="MRHDR"  condition="ismr"	offset="652"	intype="Uint16_B"	inlength="1"	name="MR_img_window"		dicomtype="?"	dicomtag="?"		#  Window Value
+block="MRHDR"  condition="ismr"	offset="654"	intype="Int16_B"	inlength="1"	name="MR_img_level"		dicomtype="?"	dicomtag="?"		#  Level Value
+block="MRHDR"  condition="ismr"	offset="656"	intype="Int32_B"	inlength="1"	name="MR_slop_int_1"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 1
+block="MRHDR"  condition="ismr"	offset="660"	intype="Int32_B"	inlength="1"	name="MR_slop_int_2"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 2
+block="MRHDR"  condition="ismr"	offset="664"	intype="Int32_B"	inlength="1"	name="MR_slop_int_3"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 3
+block="MRHDR"  condition="ismr"	offset="668"	intype="Int32_B"	inlength="1"	name="MR_slop_int_4"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 4
+block="MRHDR"  condition="ismr"	offset="672"	intype="Int32_B"	inlength="1"	name="MR_slop_int_5"		dicomtype="?"	dicomtag="?"		#  Integer Slop Field 5
+block="MRHDR"  condition="ismr"	offset="676"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_1"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 1
+block="MRHDR"  condition="ismr"	offset="680"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_2"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 2
+block="MRHDR"  condition="ismr"	offset="684"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_3"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 3
+block="MRHDR"  condition="ismr"	offset="688"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_4"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 4
+block="MRHDR"  condition="ismr"	offset="692"	intype="IEEE_Float32_B"	inlength="1"	name="MR_slop_float_5"	dicomtype="?"	dicomtag="?"		#  Float Slop Field 5
+block="MRHDR"  condition="ismr"	offset="696"	intype="String"		inlength="16"	name="MR_slop_str_1"		dicomtype="?"	dicomtag="?"		#  String Slop Field 1
+block="MRHDR"  condition="ismr"	offset="712"	intype="String"		inlength="16"	name="MR_slop_str_2"		dicomtype="?"	dicomtag="?"		#  String Slop Field 2
+block="MRHDR"  condition="ismr"	offset="728"	intype="Int16_B"	inlength="1"	name="MR_scanactno"		dicomtype="?"	dicomtag="?"		#  Scan Acquisition Number
+block="MRHDR"  condition="ismr"	offset="730"	intype="Int16_B"	inlength="1"	name="MR_vasflags"		dicomtype="?"	dicomtag="?"	bitmap="0:none,NOFLAGS;1:none,MAGWEIGHT;2:none,CD RECON;3:none,PD RECON;4:none,PHASECOR OFF"	#  Magnitude Weighting Flag
+block="MRHDR"  condition="ismr"	offset="732"	intype="IEEE_Float32_B"	inlength="1"	name="MR_vencscale"		dicomtype="?"	dicomtag="?"		#  Scale Weighted Venc
+block="MRHDR"  condition="ismr"	offset="736"	intype="Int16_B"	inlength="1"	name="MR_integrity"		dicomtype="?"	dicomtag="?"	enum="0=GE Image,1=Imported Image"	#  GE Image Integrity
+block="MRHDR"  condition="ismr"	offset="738"	intype="Int32_B"	inlength="1"	name="MR_fphase"		dicomtype="?"	dicomtag="?"		#  Number Of Phases
+block="MRHDR"  condition="ismr"	offset="742"	intype="Int16_B"	inlength="1"	name="MR_freq_dir"		dicomtype="?"	dicomtag="?"	enum="0=Unknown,1=Row,2=Col"	#  Frequency Direction
+block="MRHDR"  condition="ismr"	offset="744"	intype="Int16_B"	inlength="1"	name="MR_vas_mode"		dicomtype="?"	dicomtag="?"	num="0=None,1=TOF,2=PC"	#  Vascular Mode
+block="MRHDR"  condition="ismr"	offset="746"	intype="String"		inlength="32"	name="MR_image_uid"		dicomtype="?"	dicomtag="?"		#  Image Unique ID
+block="MRHDR"  condition="ismr"	offset="778"	intype="String"		inlength="32"	name="MR_sop_uid"		dicomtype="?"	dicomtag="?"		#  Service Obj Class Unique ID
+block="MRHDR"  condition="ismr"	offset="810"	intype="String"		inlength="212"	name="MR_mr_padding"		dicomtype="?"	dicomtag="?"		#  Spare Space
+
+constant="16" 							dicomtype="US"	dicomtag="BitsAllocated"		#
+constant="1" 							dicomtype="US"	dicomtag="PixelRepresentation"		# Signed
+constant="1" 							dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 						dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="1" 							dicomtype="DS"	dicomtag="RescaleSlope"			# 
+constant="US" 				condition="ismr"	dicomtype="LO"	dicomtag="RescaleType"			# 
+constant="HU" 				condition="isct"	dicomtype="LO"	dicomtag="RescaleType"			# 
+constant="0" 							dicomtype="XS"	dicomtag="PixelPaddingValue"		# 
+constant=""							dicomtype="SH"	dicomtag="AccessionNumber"		# 
+constant=""							dicomtype="DA"	dicomtag="PatientBirthDate"		# 
+constant="GE Medical Systems"					dicomtype="LO"	dicomtag="Manufacturer"			# 
+constant="1.2.840.10008.5.1.4.1.1.4"	condition="ismr"	dicomtype="UI"	dicomtag="SOPClassUID"			# 
+constant="1.2.840.10008.5.1.4.1.1.2"	condition="isct"	dicomtype="UI"	dicomtag="SOPClassUID"			# 
+
diff --git a/libsrc/src/dconvert/gen/gencl.h b/libsrc/src/dconvert/gen/gencl.h
new file mode 100644
index 0000000..5e7464f
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gencl.h
@@ -0,0 +1,31 @@
+/* gencl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "geninfo.h"
+#include "genhdrp.h"
+#include "genhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class GEN_Header_BothClass : public GEN_HeaderClass
+{
+	GEN_FileStructureInformation fileinfo;
+public:
+	GEN_Header_BothClass(istream *ist,GEN_FileStructureInformation &info)
+		: GEN_HeaderClass(ist,info)
+		{
+			fileinfo=info;
+		}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/gen/genconv.cc b/libsrc/src/dconvert/gen/genconv.cc
new file mode 100644
index 0000000..155084b
--- /dev/null
+++ b/libsrc/src/dconvert/gen/genconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)genconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "gendc.h"
+#include "genptrs.h"
+#include "genconv.h"
diff --git a/libsrc/src/dconvert/gen/gendc.cc b/libsrc/src/dconvert/gen/gendc.cc
new file mode 100644
index 0000000..54f8005
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gendc.cc
@@ -0,0 +1,96 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gendc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gendc.h"
+#include "gen.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "gensrc.h"
+
+bool
+GEN_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!genhdr) genhdr=new GEN_Header_BothClass(in,fileinfo);
+	Assert(genhdr);
+
+	genhdr->ToDicom_Template(list);
+	genhdr->ToDicom_ManualMisc(list);
+	genhdr->ToDicom_ManualPlane(list);
+	genhdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in gen.h about the importance of the scope
+// of a GEN_Conversion object and AttributeList object
+
+bool
+GEN_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!genhdr) genhdr=new GEN_Header_BothClass(in,fileinfo);
+	Assert(genhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	// Manually expand the offsets
+
+	pixeldatasrc=new GEN_PixelDataSource(
+		*in,
+		GEN_Offset_FILEHDR_ptr+genhdr->GEN_HeaderInstance_FILEHDR->IH_img_hdr_length
+			 + (fileinfo.pixelDataLengthFieldPresent ? 4 : 0),
+		GEN_Offset_FILEHDR_ptr+genhdr->GEN_HeaderInstance_FILEHDR->IH_img_p_unpack,
+		genhdr->GEN_HeaderInstance_FILEHDR->IH_img_l_unpack,
+		genhdr->GEN_HeaderInstance_FILEHDR->IH_img_compress,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+GEN_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/gen/gendc.h b/libsrc/src/dconvert/gen/gendc.h
new file mode 100644
index 0000000..4a65ca6
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gendc.h
@@ -0,0 +1,7 @@
+/* gendc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "gencl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "genptrs.h"
diff --git a/libsrc/src/dconvert/gen/gendmp.cc b/libsrc/src/dconvert/gen/gendmp.cc
new file mode 100644
index 0000000..40f8682
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gendmp.cc
@@ -0,0 +1,23 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gendmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gendmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "gen.h"
+
+bool
+GEN_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!genhdr) genhdr=new GEN_Header_BothClass(in,fileinfo);
+	Assert(genhdr);
+
+	TextOutputStream out(o);
+
+	genhdr->DumpCommon(&out);
+
+	return true;
+}
+
+
diff --git a/libsrc/src/dconvert/gen/gendmp.h b/libsrc/src/dconvert/gen/gendmp.h
new file mode 100644
index 0000000..9a77957
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gendmp.h
@@ -0,0 +1,4 @@
+/* gendmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "gencl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/gen/gendmpf.cc b/libsrc/src/dconvert/gen/gendmpf.cc
new file mode 100644
index 0000000..55cc8d0
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gendmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)gendmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gendmp.h"
+#include "genptrs.h"
+#include "gendmpf.h"
diff --git a/libsrc/src/dconvert/gen/genhdrc.cc b/libsrc/src/dconvert/gen/genhdrc.cc
new file mode 100644
index 0000000..2ce34ba
--- /dev/null
+++ b/libsrc/src/dconvert/gen/genhdrc.cc
@@ -0,0 +1,8 @@
+static const char *CopyrightIdentifier(void) { return "@(#)genhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "geninfo.h"
+#include "genptrs.h"
+#include "genhdrp.h"
+#include "genhdrw.h"
+#include "genhdrc.h"
+
diff --git a/libsrc/src/dconvert/gen/geninfo.h b/libsrc/src/dconvert/gen/geninfo.h
new file mode 100644
index 0000000..fd493f9
--- /dev/null
+++ b/libsrc/src/dconvert/gen/geninfo.h
@@ -0,0 +1,45 @@
+/* geninfo.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_geninfo__
+#define __Header_geninfo__
+
+class GEN_FileStructureInformation  {
+public:
+	bool useExplicitOffsets;
+	bool pixelDataLengthFieldPresent;
+	Uint32 explicitFileHdrPtr;
+	Uint32 explicitSuiteHdrPtr;
+	Uint32 explicitExamHdrPtr;
+	Uint32 explicitSeriesHdrPtr;
+	Uint32 explicitImageHdrPtr;
+
+	GEN_FileStructureInformation(void)
+		{
+			useExplicitOffsets=false;
+			pixelDataLengthFieldPresent=false;
+			explicitFileHdrPtr=0;
+			explicitSuiteHdrPtr=0;
+			explicitExamHdrPtr=0;
+			explicitSeriesHdrPtr=0;
+			explicitImageHdrPtr=0;
+		}
+
+	GEN_FileStructureInformation(
+			bool explicitoff,
+			bool lengthpresent,
+			Uint32 fileptr,
+			Uint32 suiteptr,
+			Uint32 examptr,
+			Uint32 seriesptr,
+			Uint32 imageptr)
+		{
+			useExplicitOffsets=explicitoff;
+			pixelDataLengthFieldPresent=lengthpresent;
+			explicitFileHdrPtr=fileptr;
+			explicitSuiteHdrPtr=suiteptr;
+			explicitExamHdrPtr=examptr;
+			explicitSeriesHdrPtr=seriesptr;
+			explicitImageHdrPtr=imageptr;
+		}
+};
+
+#endif // __Header_geninfo__
diff --git a/libsrc/src/dconvert/gen/genmdt.cc b/libsrc/src/dconvert/gen/genmdt.cc
new file mode 100644
index 0000000..f35404b
--- /dev/null
+++ b/libsrc/src/dconvert/gen/genmdt.cc
@@ -0,0 +1,112 @@
+static const char *CopyrightIdentifier(void) { return "@(#)genmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gendc.h"
+#include "elmconst.h"
+
+void 
+GEN_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// ? should use EX_ex_lastmod ?
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),
+		Date(DateTime(GEN_HeaderInstance_EXAMHDR->EX_ex_datetime)));
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),
+		Time(DateTime(GEN_HeaderInstance_EXAMHDR->EX_ex_datetime)));
+
+	// ? should use SE_se_actual_dt ? SE_se_lastmod ?
+
+	// SeriesDate
+
+	(*list)+=new DateStringAttribute(TagFromName(SeriesDate),
+		Date(DateTime(GEN_HeaderInstance_SERIESHDR->SE_se_datetime)));
+
+	// SeriesTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(SeriesTime),
+		Time(DateTime(GEN_HeaderInstance_SERIESHDR->SE_se_datetime)));
+
+	// ? should use im_datetime ? im_lastmod ? im_actual_dt ?
+
+	// ContentDate (formerly Image)
+
+	if (GEN_isct)
+		(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+			Date(DateTime(GEN_HeaderInstance_CTHDR->CT_im_lastmod)));
+	else if (GEN_ismr)
+		(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+			Date(DateTime(GEN_HeaderInstance_MRHDR->MR_im_lastmod)));
+
+	// ContentTime (formerly Image)
+
+	if (GEN_isct)
+		(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+			Time(DateTime(GEN_HeaderInstance_CTHDR->CT_im_lastmod)));
+	else if (GEN_ismr)
+		(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+			Time(DateTime(GEN_HeaderInstance_MRHDR->MR_im_lastmod)));
+
+	// AcquisitionDate
+
+	if (GEN_isct)
+		(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),
+			Date(DateTime(GEN_HeaderInstance_CTHDR->CT_im_datetime)));
+	else if (GEN_ismr)
+		(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),
+			Date(DateTime(GEN_HeaderInstance_MRHDR->MR_im_datetime)));
+
+	// AcquisitionTime
+
+	if (GEN_isct)
+		(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),
+			Time(DateTime(GEN_HeaderInstance_CTHDR->CT_im_datetime)));
+	else if (GEN_ismr)
+		(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),
+			Time(DateTime(GEN_HeaderInstance_MRHDR->MR_im_datetime)));
+
+	{
+		// PatientSex
+
+		const char *str;
+		switch (GEN_HeaderInstance_EXAMHDR->EX_patsex) {
+			case 1:		str="M"; break;
+			case 2:		str="F"; break;
+			default:	str="";  break;
+		}
+
+		(*list)+=new CodeStringAttribute(TagFromName(PatientSex),str);
+	}
+
+	{
+		// PatientAge
+
+		ostrstream ost;
+		ost << setfill('0') << setw(3) << dec
+		    << GEN_HeaderInstance_EXAMHDR->EX_patage;
+		switch (GEN_HeaderInstance_EXAMHDR->EX_patian) {
+			case 0:	ost << "Y"; break;
+			case 1:	ost << "M"; break;
+			case 2:	ost << "D"; break;
+			case 3:	ost << "W"; break;
+		}
+		ost << ends;
+		char *agestr=ost.str();
+		if (agestr) {
+			if (strlen(agestr))
+				(*list)+=new AgeStringAttribute(
+					TagFromName(PatientAge),agestr);
+			delete[] agestr;
+		}
+	}
+
+	// PatientWeight
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PatientWeight),
+		Uint32(GEN_HeaderInstance_EXAMHDR->EX_patweight)/1000.0);
+}
+
diff --git a/libsrc/src/dconvert/gen/genmmsc.cc b/libsrc/src/dconvert/gen/genmmsc.cc
new file mode 100644
index 0000000..f553ad0
--- /dev/null
+++ b/libsrc/src/dconvert/gen/genmmsc.cc
@@ -0,0 +1,633 @@
+static const char *CopyrightIdentifier(void) { return "@(#)genmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gendc.h"
+#include "elmconst.h"
+
+void 
+GEN_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	{
+		//    Rows = IH_img_height ? IH_img_height : CT_ or MR_imatrix_Y
+		// Columns = IH_img_width  ? IH_img_width  : CT_ or MR_imatrix_X
+
+//		Uint16    rows = GEN_HeaderInstance_FILEHDR->IH_img_height
+//			? (Uint16)GEN_HeaderInstance_FILEHDR->IH_img_height
+//			: (GEN_ismr
+
+		Uint16 rows = (GEN_ismr
+				? GEN_HeaderInstance_MRHDR->MR_imatrix_Y
+				: GEN_HeaderInstance_CTHDR->CT_imatrix_Y);
+
+//		Uint16 columns = GEN_HeaderInstance_FILEHDR->IH_img_width  
+//			? (Uint16)GEN_HeaderInstance_FILEHDR->IH_img_width  
+//			: (GEN_ismr
+
+		Uint16 columns = (GEN_ismr
+				? GEN_HeaderInstance_MRHDR->MR_imatrix_X
+				: GEN_HeaderInstance_CTHDR->CT_imatrix_X);
+
+		(*list)+=new UnsignedShortAttribute(TagFromName(Rows),rows);
+		(*list)+=new UnsignedShortAttribute(TagFromName(Columns),columns);
+	}
+
+	{
+		// BitsStored = depth
+		// HighBit = depth - 1
+
+		Uint16 depth;
+#ifdef GENESISUSEDEPTHVALUE
+		if (GEN_hashisto && Uint16(GEN_HeaderInstance_HISTOHDR->HS_hs_max) < 4096u)
+			depth=12;
+		else if (GEN_HeaderInstance_FILEHDR->IH_img_depth)
+			depth=GEN_HeaderInstance_FILEHDR->IH_img_depth;
+		else
+#endif
+			depth=16;
+
+		(*list)+=new UnsignedShortAttribute(TagFromName(BitsStored),depth);
+		(*list)+=new UnsignedShortAttribute(TagFromName(HighBit),depth-1);
+	}
+
+	// ContrastBolus Module
+
+	{
+		bool oral=false;
+		const char *oralagent=0;
+		bool iv=false;
+		const char *ivagent=0;
+
+		if (GEN_ismr) {
+			if (GEN_HeaderInstance_MRHDR->MR_contmode & 0x1)
+				oral=true;
+			if (GEN_HeaderInstance_MRHDR->MR_contmode & 0x2)
+				iv=true;
+			oralagent=GEN_HeaderInstance_MRHDR->MR_contrastOral;
+			ivagent=GEN_HeaderInstance_MRHDR->MR_contrastIV;
+		}
+		if (GEN_isct) {
+			if (GEN_HeaderInstance_CTHDR->CT_contmode & 0x1)
+				oral=true;
+			if (GEN_HeaderInstance_CTHDR->CT_contmode & 0x2)
+				iv=true;
+			oralagent=GEN_HeaderInstance_CTHDR->CT_contrastOral;
+			ivagent=GEN_HeaderInstance_CTHDR->CT_contrastIV;
+		}
+
+		// NB. VM of ContrastBolusAgent, etc. is 1 :(
+
+		ostrstream oContrastBolusAgent;
+		ostrstream oContrastBolusRoute;
+
+		if (oral) {
+			oContrastBolusAgent <<
+			    (strlen(oralagent) ? oralagent : "ORAL AGENT UNKNOWN");
+			oContrastBolusRoute << "ORAL";
+		}
+		if (oral && iv) {
+			oContrastBolusAgent << " AND ";
+			oContrastBolusRoute << " AND ";
+		}
+		if (iv) {
+			oContrastBolusAgent <<
+			    (strlen(ivagent) ? ivagent : "IV AGENT UNKNOWN");
+			oContrastBolusRoute << "IV";
+		}
+		oContrastBolusAgent << ends;
+		oContrastBolusRoute << ends;
+		char *sContrastBolusAgent=oContrastBolusAgent.str();
+		char *sContrastBolusRoute=oContrastBolusRoute.str();
+
+		if (sContrastBolusAgent) {
+			if (strlen(sContrastBolusAgent)) {
+				(*list)+=new
+					LongStringAttribute(
+						TagFromName(ContrastBolusAgent),
+						sContrastBolusAgent);
+			}
+			delete[] sContrastBolusAgent;
+		}
+
+		if (sContrastBolusRoute) {
+			if (strlen(sContrastBolusRoute)) {
+				(*list)+=new
+					LongStringAttribute(
+						TagFromName(ContrastBolusRoute),
+						sContrastBolusRoute);
+			}
+			delete[] sContrastBolusRoute;
+		}
+	}
+
+	{
+		// ImageType
+
+		const char *value1,*value2,*value3;
+
+		switch (GEN_HeaderInstance_SERIESHDR->SE_se_typ) {
+			case 1:		// Prospective
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					if (GEN_isct) value3="AXIAL";
+					if (GEN_ismr) value3="OTHER";
+					break;
+			case 2:		// Retrospective
+					value1="ORIGINAL";
+					value2="SECONDARY";
+					if (GEN_isct) value3="AXIAL";
+					if (GEN_ismr) value3="OTHER";
+					break;
+			case 3:		// Scout
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="LOCALIZER";	// CT IOD
+					break;
+			case 4:		// Reformatted
+			case 5:		// Screensave
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="OTHER";		// MR IOD
+					break;
+			case 6:		// Xenon
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="AXIAL";		// CT IOD
+			case 7:		// Service
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="OTHER";		// MR IOD
+					break;
+			case 9:		// Projected
+					value1="DERIVED";
+					value2="SECONDARY";
+					value3="PROJECTION IMAGE"; // MR IOD
+					break;
+			default:
+					value1="UNKNOWN";
+					value2="UNKNOWN";
+					value3="UNKNOWN";
+					break;
+		}
+
+		(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+				value1,value2,value3);
+	}
+
+	if (GEN_isct) {
+		// ConvolutionKernel
+
+		const char *str;
+
+		// supposed to be a bitmap - we will assume enum :(
+
+		switch (GEN_HeaderInstance_CTHDR->CT_reconalg) {
+			case 1:		str="SMOOTH";
+					break;
+			case 2:		str="SOFT";
+					break;
+			case 4:		str="STANDARD";
+					break;
+			case 8:		str="DETAIL";
+					break;
+			case 16:	str="BONE";
+					break;
+			case 32:	str="EDGE";
+					break;
+			case 64:	str="SHARP";
+					break;
+			case 128:	str="EXP2";
+					break;
+			default:	str="UNKNOWN";
+					break;
+		}
+
+		// could also utilize CT_perisflag & CT_iboneflag ??
+
+		(*list)+=new ShortStringAttribute(TagFromName(ConvolutionKernel),str);
+
+		// FilterType
+
+		switch (GEN_HeaderInstance_CTHDR->CT_filttyp) {
+			case 1:		str="AIR"; break;
+			case 2:		str="BODY"; break;
+			case 3:		str="BOWTIE:ADLT HEAD"; break;
+			case 4:		str="FLAT"; break;
+			case 5:		str="HI:ADULT HEAD/HF"; break;
+			default:	str="UNKNOWN"; break;
+		}
+		(*list)+=new ShortStringAttribute(TagFromName(FilterType),str);
+
+		// RotationDirection
+
+		switch (GEN_HeaderInstance_CTHDR->CT_gandir) {
+			case 1:		str="CW"; break;
+			case 2:		str="CC"; break;
+			default:	str="UNKNOWN"; break;
+		}
+		(*list)+=new
+			CodeStringAttribute(TagFromName(RotationDirection),
+				str);
+
+		// ExposureTime
+		// Exposure
+
+		(*list)+=new
+			IntegerStringAttribute(TagFromName(ExposureTime),
+				Uint32(GEN_HeaderInstance_CTHDR->CT_sctime*1000.0));
+		(*list)+=new
+			IntegerStringAttribute(TagFromName(Exposure),
+				Uint32(GEN_HeaderInstance_CTHDR->CT_sctime
+					*GEN_HeaderInstance_CTHDR->CT_mamp));
+
+		// DistanceSourceToDetector
+		// DistanceSourceToPatient
+
+		// (these are here rather than in template to avoid inclusion in MR)
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(DistanceSourceToDetector),
+				GEN_HeaderInstance_EXAMHDR->EX_srctodet);
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(DistanceSourceToPatient),
+				GEN_HeaderInstance_EXAMHDR->EX_srctoiso);
+	}
+
+	if (GEN_ismr) {
+		// MagneticFieldStrength - Tesla
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(MagneticFieldStrength),
+				Uint32(GEN_HeaderInstance_EXAMHDR->EX_magstrength)/10000.0);
+
+		// ImagingFrequency MHz (Genesis is in .1 Hz)
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(ImagingFrequency),
+				Uint32(GEN_HeaderInstance_MRHDR->MR_xmtfreq)/10000000.0);
+
+		// RepetitionTime
+		// EchoTime
+		// InversionTime
+
+		Uint32 tr_us=GEN_HeaderInstance_MRHDR->MR_tr;
+		if (tr_us) (*list)+=new
+			DecimalStringAttribute(TagFromName(RepetitionTime),
+				tr_us/1000.0);
+
+
+		Uint32 te_us=GEN_HeaderInstance_MRHDR->MR_te;
+		if (te_us) (*list)+=new
+			DecimalStringAttribute(TagFromName(EchoTime),
+				te_us/1000.0);
+
+
+		Uint32 ti_us=GEN_HeaderInstance_MRHDR->MR_ti;
+		if (ti_us) (*list)+=new
+			DecimalStringAttribute(TagFromName(InversionTime),
+				ti_us/1000.0);
+
+		double sctime_fd=GEN_HeaderInstance_MRHDR->MR_sctime;
+		if (sctime_fd) (*list)+=new
+			FloatDoubleAttribute(TagFromName(AcquisitionDuration),
+				sctime_fd/1000000.0);
+
+		// EchoTrainLength
+
+		unsigned etl=GEN_HeaderInstance_MRHDR->MR_echo_trn_len;
+		unsigned numecho=GEN_HeaderInstance_MRHDR->MR_numecho;
+		unsigned useetl = etl ? etl : numecho;
+
+		if (useetl) (*list)+=new
+			IntegerStringAttribute(TagFromName(EchoTrainLength),
+				Uint32(useetl));
+	}
+
+	if (GEN_ismr) {
+		// ScanningSequence
+		// SequenceVariant
+		// ScanOptions
+
+		CodeStringAttribute *ScanningSequence =
+			new CodeStringAttribute(TagFromName(ScanningSequence));
+
+		CodeStringAttribute *SequenceVariant =
+			new CodeStringAttribute(TagFromName(SequenceVariant));
+
+		CodeStringAttribute *ScanOptions =
+			new CodeStringAttribute(TagFromName(ScanOptions));
+
+		switch (GEN_HeaderInstance_MRHDR->MR_pseq) {
+			case 0:			// SE
+					ScanningSequence->addValue("SE");
+					break;
+			case 1:			// IR
+					ScanningSequence->addValue("IR");
+					break;
+			case 2:			// RM:RM
+					ScanningSequence->addValue("RM");
+					break;
+			case 3:			// RMGE:none
+					ScanningSequence->addValue("RM");
+					break;
+			case 4:			// GRE:GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 5:			// MPGR
+					ScanningSequence->addValue("GR");
+					break;
+			case 6:			// MPIRS:IR/s
+					ScanningSequence->addValue("IR");
+					break;
+			case 7:			// MPIRI:IR
+					ScanningSequence->addValue("IR");
+					break;
+			case 8:			// VOGRE:3D/GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 9:			// CINEGRE:Cine/GRE
+					ScanningSequence->addValue("GR");
+					break;
+			case 10:		// SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 11:		// SSFP
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("TRSS");
+					break;
+			case 12:		// TF:TOF
+					ScanningSequence->addValue("GR");
+					break;
+			case 13:		// PC
+					ScanningSequence->addValue("GR");
+					break;
+			case 14:		// CINSPGR:Cine/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 15:		// TOFGR:TOG/GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 16:		// TOFSPGR:TOF/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 17:		// PCGR:PC/GR
+					ScanningSequence->addValue("GR");
+					break;
+			case 18:		// PCSPGR:PC/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 19:		// FSE
+					ScanningSequence->addValue("SE");
+					SequenceVariant->addValue("SK");
+					break;
+			case 20:		// FGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 21:		// FMPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 22:		// FSPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					SequenceVariant->addValue("SK");
+					break;
+			case 23:		// FMPSPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					SequenceVariant->addValue("SK");
+					break;
+			case 24:		// SPECT
+					break;
+			case 25:		// PSEQ_MIXED:MIXED
+					break;
+			default:	break;
+		}
+
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<0)) {	// EG - ECG Gated
+			ScanOptions->addValue("CG");
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<1)) {	// RESP - Resp Gated
+			ScanOptions->addValue("RG");
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<2)) {	// RC - Resp Compensated
+			ScanOptions->addValue("PER");
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<3)) {	// FC - Flow Compensated
+			ScanOptions->addValue("FC");
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<4)) {	// CL
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<5)		// ST - Sat parameters
+		 || GEN_HeaderInstance_MRHDR->MR_satbits) {		// if any sat bits set
+			ScanOptions->addValue("SP");			// spatial presaturation
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<6)) {	// PG - Periph Gated
+			ScanOptions->addValue("PPG");
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<7)) {	// NP - No Phase Wrap
+			SequenceVariant->addValue("OSP");
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<8)) {	// NF - ?
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<9)) {	// RT - Rect FOV
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<10)) {	// VB - Var Bandwidth
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<11)) {	// ED - Ext Dynamic Rng
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<12)) {	// PM - POMP
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<13)) {	// SQ - ?
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<14)) {	// CS - Contig Slice
+		}
+		if (GEN_HeaderInstance_MRHDR->MR_iopt & (1<<15)) {	// MP - Multiplanar
+		}
+
+		switch (GEN_HeaderInstance_MRHDR->MR_supp_tech) {
+			case 1:
+				ScanOptions->addValue("FS");		// fat saturation
+				break;
+			case 2:
+				ScanOptions->addValue("WS");		// water saturation
+				break;					// not DICOM def term
+			default:
+				break;
+		}
+
+		if (GEN_HeaderInstance_MRHDR->MR_scic) {
+			ScanOptions->addValue("IIC");			// intensity correction
+		}							// not DICOM def term
+
+		if (GEN_HeaderInstance_MRHDR->MR_frac_echo & 1<<0) {
+			ScanOptions->addValue("PFF");			// partial fourier freq
+		}
+
+		switch (GEN_HeaderInstance_MRHDR->MR_prep_pulse) {
+			case 1:						// Inversion Recovery:IR
+			case 2:						// Driven Equilibrium:DE
+				SequenceVariant->addValue("MP");	// mag prepared
+				break;
+			default:
+				break;
+		}
+
+		if (!SequenceVariant->getVM())
+			SequenceVariant->addValue("NONE");
+
+		(*list)+=ScanningSequence;
+		(*list)+=SequenceVariant;
+		(*list)+=ScanOptions;
+	}
+
+	if (GEN_ismr) {
+		// MRAcquisitionType
+
+		const char *str;
+		switch(GEN_HeaderInstance_MRHDR->MR_imode) {
+			case 1:			// Two D:2D
+				str="2D";
+				break;
+			case 2:			// Three D Volume:3D
+			case 3:			// Three D Fourier:
+				str="3D";
+				break;
+			case 4:			// Cine:Cine
+			case 5:			// Angiography:ANGIO
+			case 6:			// Spectroscopy:SPECT
+			case 7:			// Flouroscopy:FLOURO
+			case 8:			// Research Mode:RM
+			default:
+				str="UNKNOWN";
+				break;
+		}
+		(*list)+=new CodeStringAttribute(TagFromName(MRAcquisitionType),str);
+	}
+
+	if (GEN_ismr) {
+		// InPlanePhaseEncodingDirection
+
+		const char *str;
+
+		//if (GEN_HeaderInstance_MRHDR->MR_swappf)	// Swap Phase/Frequency:SPF
+		//	str="COL";
+		//else
+		//	str="ROW";
+		//(*list)+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),str);
+
+		if (GEN_HeaderInstance_MRHDR->MR_freq_dir == 1)
+			str="COL";
+		else if (GEN_HeaderInstance_MRHDR->MR_freq_dir == 2
+		      || GEN_HeaderInstance_MRHDR->MR_freq_dir == 0)	// assume "unknown" is row
+			str="ROW";
+		else
+			str=0;
+
+		if (str)
+			(*list)+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),str);
+	}
+
+	if (GEN_ismr) {
+		// Acquisition Matrix
+
+		Uint16 freq_rows=0;
+		Uint16 freq_cols=0;
+		Uint16 phase_rows=0;
+		Uint16 phase_cols=0;
+
+		if (GEN_HeaderInstance_MRHDR->MR_freq_dir == 1) {
+			freq_rows=GEN_HeaderInstance_MRHDR->MR_dim_X;
+			phase_cols=GEN_HeaderInstance_MRHDR->MR_dim_Y;
+		}
+		else if (GEN_HeaderInstance_MRHDR->MR_freq_dir == 2
+		      || GEN_HeaderInstance_MRHDR->MR_freq_dir == 0) {	// assume "unknown" is row
+			freq_cols=GEN_HeaderInstance_MRHDR->MR_dim_X;
+			phase_rows=GEN_HeaderInstance_MRHDR->MR_dim_Y;
+		}
+
+		if (freq_rows || freq_cols || phase_rows || phase_cols) {
+			Attribute *a=new UnsignedShortAttribute(TagFromName(AcquisitionMatrix));
+			Assert(a);
+			a->addValue(freq_rows);
+			a->addValue(freq_cols);
+			a->addValue(phase_rows);
+			a->addValue(phase_cols);
+			(*list)+=a;
+		}
+	}
+
+	if (GEN_ismr) {
+		// Number Of Phase Encoding Steps
+
+		(*list)+=new IntegerStringAttribute(TagFromName(NumberOfPhaseEncodingSteps),(Uint32)GEN_HeaderInstance_MRHDR->MR_dim_Y);
+	}
+
+	if (GEN_ismr) {
+		// MRAcquisitionPhaseEncodingStepsOutOfPlane (from new multiframe MR object)
+
+		if (GEN_HeaderInstance_MRHDR->MR_imode == 2		// 3D mode
+		 && GEN_HeaderInstance_MRHDR->MR_slquant > 0) {		// Number of slices in this scan group
+			(*list)+=new UnsignedShortAttribute(TagFromName(MRAcquisitionPhaseEncodingStepsOutOfPlane),(Uint16)GEN_HeaderInstance_MRHDR->MR_slquant);
+		}
+	}
+	
+	if (GEN_ismr) {
+		// AngioFlag
+
+		bool angio;
+		switch (GEN_HeaderInstance_MRHDR->MR_pseq) {
+			case 12:		// TF:TOF
+			case 13:		// PC
+			case 15:		// TOFGR:TOG/GR
+			case 16:		// TOFSPGR:TOF/SPGR
+			case 17:		// PCGR:PC/GR
+			case 18:		// PCSPGR:PC/SPGR
+				angio=true;
+				break;
+			default:
+				angio=false;
+				break;
+		}
+
+		bool projected;
+		switch (GEN_HeaderInstance_MRHDR->MR_proj_alg) {
+			case 0:			// none
+				projected=false;
+				break;
+			case 1:			// Prototype
+			case 2:			// Minimum Pixel:Min
+			case 3:			// Maximum Pixel:Max
+			default:
+				projected=true;
+				break;
+		}
+
+		// if any bits set ...
+
+		bool collapsed = GEN_HeaderInstance_MRHDR->MR_vas_collapse;
+
+
+		if (angio) {
+			const char *str;
+			if (!collapsed && !projected)
+				str="Y";
+			else
+				str="N";
+			(*list)+=new CodeStringAttribute(TagFromName(AngioFlag),str);
+		}
+		// else leave it out
+	}
+
+	if (GEN_ismr && GEN_HeaderInstance_MRHDR->MR_vbw != 0) {
+		// PixelBandwidth
+
+		(*list)+=new DecimalStringAttribute(TagFromName(PixelBandwidth),(Float32)GEN_HeaderInstance_MRHDR->MR_vbw*2*1000);
+	}
+	
+}
+
diff --git a/libsrc/src/dconvert/gen/genmpln.cc b/libsrc/src/dconvert/gen/genmpln.cc
new file mode 100644
index 0000000..1f0f6cb
--- /dev/null
+++ b/libsrc/src/dconvert/gen/genmpln.cc
@@ -0,0 +1,191 @@
+static const char *CopyrightIdentifier(void) { return "@(#)genmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "gendc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+GEN_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlaneHeadFeet headfeet;
+
+	switch (GEN_HeaderInstance_SERIESHDR->SE_entry) {
+		case 1:
+				hfff="HF";
+				headfeet=HeadFirst;
+				break;
+		case 2:
+				hfff="FF";
+				headfeet=FeetFirst;
+				break;
+		default:	hfff="UNKNOWN";		// :(
+				headfeet=HeadFirst;
+				break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (GEN_HeaderInstance_SERIESHDR->SE_position) {
+		case 1:
+				ap="S";
+				position=Supine;
+				break;
+		case 2:
+				ap="P";
+				position=Prone;
+				break;
+		case 4:
+				ap="DL";
+				position=LeftLateralDecubitus;
+				break;
+		case 8:
+				ap="DR";
+				position=RightLateralDecubitus;
+				break;
+		default:	ap="UNKNOWN";		// :(
+				position=Supine;
+				break;
+	}
+
+	ImagePlane imageplane(headfeet,position);
+
+	// get common definitions for CT or MR
+
+	double tlhc_R;
+	double tlhc_A;
+	double tlhc_S;
+	double trhc_R;
+	double trhc_A;
+	double trhc_S;
+	double brhc_R;
+	double brhc_A;
+	double brhc_S;
+	if (GEN_isct) {
+		tlhc_R=GEN_HeaderInstance_CTHDR->CT_tlhc_R;
+		tlhc_A=GEN_HeaderInstance_CTHDR->CT_tlhc_A;
+		tlhc_S=GEN_HeaderInstance_CTHDR->CT_tlhc_S;
+		trhc_R=GEN_HeaderInstance_CTHDR->CT_trhc_R;
+		trhc_A=GEN_HeaderInstance_CTHDR->CT_trhc_A;
+		trhc_S=GEN_HeaderInstance_CTHDR->CT_trhc_S;
+		brhc_R=GEN_HeaderInstance_CTHDR->CT_brhc_R;
+		brhc_A=GEN_HeaderInstance_CTHDR->CT_brhc_A;
+		brhc_S=GEN_HeaderInstance_CTHDR->CT_brhc_S;
+	}
+	if (GEN_ismr) {
+		tlhc_R=GEN_HeaderInstance_MRHDR->MR_tlhc_R;
+		tlhc_A=GEN_HeaderInstance_MRHDR->MR_tlhc_A;
+		tlhc_S=GEN_HeaderInstance_MRHDR->MR_tlhc_S;
+		trhc_R=GEN_HeaderInstance_MRHDR->MR_trhc_R;
+		trhc_A=GEN_HeaderInstance_MRHDR->MR_trhc_A;
+		trhc_S=GEN_HeaderInstance_MRHDR->MR_trhc_S;
+		brhc_R=GEN_HeaderInstance_MRHDR->MR_brhc_R;
+		brhc_A=GEN_HeaderInstance_MRHDR->MR_brhc_A;
+		brhc_S=GEN_HeaderInstance_MRHDR->MR_brhc_S;
+	}
+
+	// DICOM plane definitions are:
+	// - Left Pos Superior +ve
+
+	// The Genesis co-ordinates are:
+	// - Right Ant Superior +ve
+	// - Corners offset by center co-ordinates
+	// - already account for offset from isocenter/reference
+
+	// (NB. no effort is made to fix the sign of SliceLocation)
+
+	// Change sign of AP and LR from Genesis to DICOM...
+
+	Point3D TLHC(-tlhc_R,-tlhc_A, tlhc_S);
+	Point3D TRHC(-trhc_R,-trhc_A, trhc_S);
+	Point3D BRHC(-brhc_R,-brhc_A, brhc_S);
+
+	imageplane.PatientPlane::setCorners(TLHC,
+					    TRHC-TLHC,	// Row Vector
+					    BRHC-TRHC);	// Col Vector
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+
+
+	// PixelSpacing
+	// ReconstructionDiameter
+
+	double 	dfov       = 0;
+	double 	dfov_rect  = 0;
+	double 	pixsize_X  = 0;
+	double 	pixsize_Y  = 0;
+	if (GEN_isct) {
+		dfov     =GEN_HeaderInstance_CTHDR->CT_dfov;
+		dfov_rect=GEN_HeaderInstance_CTHDR->CT_dfov_rect;
+		pixsize_X=GEN_HeaderInstance_CTHDR->CT_pixsize_X;
+		pixsize_Y=GEN_HeaderInstance_CTHDR->CT_pixsize_Y;
+	}
+	if (GEN_ismr) {
+		dfov     =GEN_HeaderInstance_MRHDR->MR_dfov;
+		dfov_rect=GEN_HeaderInstance_MRHDR->MR_dfov_rect;
+		pixsize_X=GEN_HeaderInstance_MRHDR->MR_pixsize_X;
+		pixsize_Y=GEN_HeaderInstance_MRHDR->MR_pixsize_Y;
+	}
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+					pixsize_X,pixsize_Y);
+
+	// which Genesis tags to use for ReconstructionDiameter ?
+
+	// sample genesis mr sagittal:
+
+	// Image matrix size - X  <256>
+	// Image matrix size - Y  <256>
+	// Display field of view - X (mm) (MR_dfov)       <240.000000>
+	// Display field of view - Y (if different) (MR_dfov_rect)        <240.000000>
+	// Image dimension - X    <256.000000>
+	// Image dimension - Y    <192.000000>
+	// Image pixel size - X   <0.937500>
+	// Image pixel size - Y   <0.937500>
+
+	// sample genesis ct scout:
+
+	// Image matrix size - X  <512>
+	// Image matrix size - Y  <197>
+	// Display field of view - X (mm) (CT_dfov)       <496.375183>
+	// Display field of view - Y (if different) (CT_dfov_rect)        <199.890442>
+	// Image dimension - X    <496.375183>
+	// Image dimension - Y    <199.890442>
+	// Image pixel size - X   <0.969483>
+	// Image pixel size - Y   <1.014672>
+	// Scan field of view (mm)        <496.369995>
+
+	// it seems that imatrix_X*pixsize_X=dfov
+	// and           imatrix_Y*pixsize_Y=dfov_rect
+	//
+	// furthermore this matches the image co-ordinate values
+	//
+	// so use average or max of dfov and dfov_rect
+	//
+	// what then are dim_X and dim_Y ? (they are acquisition matrix)
+
+	// NB. the DataCollectionDiameter is done for CT in the
+	// template using CT_sfovmm
+
+	// NB. this highlights the fact that DICOM is wrong to
+	// use just a simple diameter and not a multivalued
+	// dimension ... therefore to be useful one has to use
+	// the pixel spacing times matrix size to be safe !
+
+	// should this be average or max  ... use max ?
+
+	(*list)+=new
+		DecimalStringAttribute(TagFromName(ReconstructionDiameter),
+			(dfov > dfov_rect) ? dfov : dfov_rect);
+}
+
diff --git a/libsrc/src/dconvert/gen/genptrs.h b/libsrc/src/dconvert/gen/genptrs.h
new file mode 100644
index 0000000..5827e9d
--- /dev/null
+++ b/libsrc/src/dconvert/gen/genptrs.h
@@ -0,0 +1,47 @@
+/* genptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	GEN_Offset_FILEHDR_ptr		(fileinfo.explicitFileHdrPtr)
+
+#define	GEN_Offset_UIDHDR_ptr		(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_id)
+#define	GEN_Offset_UNPACKHDR_ptr	(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_unpack)
+#define	GEN_Offset_COMPRESSHDR_ptr	(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_compress)
+#define	GEN_Offset_HISTOHDR_ptr		(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_histo)
+#define	GEN_Offset_TEXTHDR_ptr		(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_text)
+#define	GEN_Offset_GRAPHICSHDR_ptr	(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_graphics)
+#define	GEN_Offset_DBHDR_ptr		(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_dbHdr)
+#define	GEN_Offset_USERHDR_ptr		(fileinfo.explicitFileHdrPtr+GEN_HeaderInstance_FILEHDR->IH_img_p_user)
+
+#define	GEN_Offset_SUITEHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitSuiteHdrPtr  : Uint32(GEN_HeaderInstance_FILEHDR->IH_img_p_suite))
+#define	GEN_Offset_EXAMHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitExamHdrPtr   : Uint32(GEN_HeaderInstance_FILEHDR->IH_img_p_exam))
+#define	GEN_Offset_SERIESHDR_ptr	(fileinfo.useExplicitOffsets ? fileinfo.explicitSeriesHdrPtr : Uint32(GEN_HeaderInstance_FILEHDR->IH_img_p_series))
+
+#define	GEN_Offset_UIDHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_id
+#define	GEN_Offset_UNPACKHDR_lng	GEN_HeaderInstance_FILEHDR->IH_img_l_unpack
+#define	GEN_Offset_COMPRESSHDR_lng	GEN_HeaderInstance_FILEHDR->IH_img_l_compress
+#define	GEN_Offset_HISTOHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_histo
+#define	GEN_Offset_TEXTHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_text
+#define	GEN_Offset_GRAPHICSHDR_lng	GEN_HeaderInstance_FILEHDR->IH_img_l_graphics
+#define	GEN_Offset_DBHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_dbHdr
+#define	GEN_Offset_USERHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_user
+
+//#define	GEN_Offset_SUITEHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_suite
+//#define	GEN_Offset_EXAMHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_exam
+//#define	GEN_Offset_SERIESHDR_lng	GEN_HeaderInstance_FILEHDR->IH_img_l_series
+
+#define GEN_hasuid			(GEN_Offset_UIDHDR_lng      != 0)
+#define GEN_hasunpack			(GEN_Offset_UNPACKHDR_lng   != 0)
+#define GEN_hascompress			(GEN_Offset_COMPRESSHDR_lng != 0)
+#define GEN_hashisto			(GEN_Offset_HISTOHDR_lng    != 0)
+#define GEN_hastext			(GEN_Offset_TEXTHDR_lng     != 0)
+#define GEN_hasgraphics			(GEN_Offset_GRAPHICSHDR_lng != 0)
+#define GEN_hasuser			(GEN_Offset_USERHDR_lng     != 0)
+
+#define	GEN_Offset_MRHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitImageHdrPtr : Uint32(GEN_HeaderInstance_FILEHDR->IH_img_p_image))
+#define	GEN_Offset_CTHDR_ptr		(fileinfo.useExplicitOffsets ? fileinfo.explicitImageHdrPtr : Uint32(GEN_HeaderInstance_FILEHDR->IH_img_p_image))
+
+//#define	GEN_Offset_MRHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_image
+//#define	GEN_Offset_CTHDR_lng		GEN_HeaderInstance_FILEHDR->IH_img_l_image
+
+#define GEN_isct			(strcmp(GEN_HeaderInstance_EXAMHDR->EX_ex_typ,"CT") == 0)
+#define GEN_ismr			(strcmp(GEN_HeaderInstance_EXAMHDR->EX_ex_typ,"MR") == 0)
+
+#define	GEN_Offset_PixelData_ptr	GEN_HeaderInstance_FILEHDR->IH_img_hdr_length + (fileinfo.pixelDataLengthFieldPresent ? 4 : 0)
diff --git a/libsrc/src/dconvert/gen/gensrc.h b/libsrc/src/dconvert/gen/gensrc.h
new file mode 100644
index 0000000..ca1f33e
--- /dev/null
+++ b/libsrc/src/dconvert/gen/gensrc.h
@@ -0,0 +1,171 @@
+/* gensrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_gensrc__
+#define __Header_gensrc__
+
+class GEN_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long pixeloffset;
+	long mapoffset;
+	long maplength;
+	long offset;
+	Uint16 compress;
+	Uint16 rows;
+	Uint16 columns;
+
+	Int16 last_pixel;
+	Uint16 currentrow;
+	Uint16 *linebuffer;
+
+	Uint16	*map_left;
+	Uint16	*map_wide;
+
+	unsigned char ubuffer[2];
+
+	Uint16 readUint16(void)
+		{
+			Uint16 u;
+			istr->read((char *)ubuffer,2);
+			// Genesis is a sun3 which is a Big Endian machine
+			u =  (Uint16)ubuffer[0];
+			u <<= 8;
+			u |= (Uint16)ubuffer[1];
+			return u;
+	}
+
+	bool readMap(void)
+		{
+			Assert(maplength);
+			Assert(maplength == 4*rows);
+
+			istr->seekg(mapoffset,ios::beg);
+			if (!(istr && istr->good())) return false;
+
+			map_left=new Uint16[rows];
+			map_wide=new Uint16[rows];
+			if (!map_left || !map_wide) return false;
+			unsigned i;
+			for (i=0; i<rows; ++i) {
+				map_left[i]=readUint16();
+				map_wide[i]=readUint16();
+			}
+			return istr && istr->good();
+		}
+public:
+	GEN_PixelDataSource(istream& i,long pixoff,long mapoff,long maplng,Uint16 cflag,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			pixeloffset=pixoff;
+			mapoffset=mapoff;
+			maplength=maplng;
+			compress=cflag;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+
+			currentrow=0;		// used as index into map
+			last_pixel=0;		// used for DPCM decoding
+
+			linebuffer=new Uint16[columns];
+			Assert(linebuffer);
+
+			map_left=0;
+			map_wide=0;
+		}
+
+	~GEN_PixelDataSource()
+		{
+			if (linebuffer) delete[] linebuffer;
+			if (map_left) delete[] map_left;
+			if (map_wide) delete[] map_wide;
+		}
+
+	size_t read(void)
+		{
+			if (currentrow == 0) {
+				Assert(istr);
+				if (compress == 2 || compress == 4) { // packed or compacked
+					readMap();
+				}
+				istr->seekg(pixeloffset,ios::beg);
+			}
+
+			if (!good() || currentrow >= rows) return 0;
+
+			Uint16 *ptr=linebuffer;
+			unsigned start;
+			unsigned end;
+			unsigned j;
+
+			if (compress == 2 || compress == 4) { // packed or compacked
+				start=map_left[currentrow];
+				end=start+map_wide[currentrow];
+			}
+			else {
+				start=0;
+				end=columns;
+			}
+
+			Assert(start <= columns);
+			Assert(end <= columns);
+
+			// Pad the first "empty" part of the line ...
+			for (j=0; j<start; j++)*ptr++=0;
+
+			// Copy the middle of the line
+
+			if (compress == 3 || compress == 4) { // compressed or compacked
+				while (start<end) {
+					unsigned char byte;
+					istr->read((char *)&byte,1);
+					if (!istr) break;
+					if (byte & 0x80) {
+						unsigned char byte2;
+						istr->read((char *)&byte2,1);
+						if (!istr) break;
+						if (byte & 0x40) {	// next word
+							istr->read((char *)&byte,1);
+							if (!istr) break;
+							last_pixel=
+							    (((Uint16)byte2<<8)+byte);
+						}
+						else {			// 14 bit delta
+							if (byte & 0x20) byte|=0xe0;
+							else byte&=0x1f;
+							last_pixel+=
+							    (((Int16)byte<<8)+byte2);
+						}
+					}
+					else {				// 7 bit delta
+						if (byte & 0x40) byte|=0xc0;
+						last_pixel+=(signed char)byte;
+					}
+					*ptr++=(Uint16)last_pixel;
+					++start;
+				}
+			}
+			else {
+				while (start<end) {
+					Uint16 u=readUint16();
+					if (!istr) break;
+					*ptr++=u;
+					++start;
+				}
+			}
+
+			// Pad the last "empty" part of the line ...
+			for (j=end; j<columns; j++) *ptr++=0;
+
+			++currentrow;
+
+			return (istr && istr->good()) ? columns : 0;
+		}
+
+	const Uint16 *getBuffer(void)		{ return linebuffer; }
+	size_t getBufferCount(void) const	{ return columns; }
+
+	int good(void) const	{ return istr && istr->good() && currentrow < rows; }
+};
+
+#endif // __Header_gensrc__
diff --git a/libsrc/src/dconvert/himr/Imakefile b/libsrc/src/dconvert/himr/Imakefile
new file mode 100755
index 0000000..d66b01a
--- /dev/null
+++ b/libsrc/src/dconvert/himr/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = himrdc.cc himrconv.cc himrmpln.cc \
+		 himrmmsc.cc himrmdt.cc \
+		 himrdmp.cc himrdmpf.cc \
+		 himrhdrc.cc himr.cc
+
+OBJS = 		 himrdc.o  himrconv.o  himrmpln.o  \
+		 himrmmsc.o  himrmdt.o  \
+		 himrdmp.o  himrdmpf.o  \
+		 himrhdrc.o  himr.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdhimr.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(himr,dconvert)
+
+ProjectConvertTemplate(himrhdrp.h,himr,convert,prefix=HIMR_ role=headerpart)
+ProjectConvertTemplate(himrhdrw.h,himr,convert,prefix=HIMR_ role=wholeheader)
+ProjectConvertTemplate(himrhdrc.h,himr,convert,prefix=HIMR_ role=constructheader)
+ProjectConvertTemplate(himrconv.h,himr,convert,prefix=HIMR_ role=dicom)
+ProjectConvertTemplate(himrdmpf.h,himr,convert,prefix=HIMR_ role=dump)
+
+himrdmpf.o: himrdmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) himrdmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/himr/README b/libsrc/src/dconvert/himr/README
new file mode 100755
index 0000000..b6af03d
--- /dev/null
+++ b/libsrc/src/dconvert/himr/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"himr.h"
+		class HIMR_Conversion {
+			HIMR_Conversion(istream &i,ostream &e);
+			virtual ~HIMR_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"himr.cc"
+
+		HIMR_Conversion::HIMR_Conversion(istream &i,ostream &e);
+		HIMR_Conversion::~HIMR_Conversion();
+
+	"himrcl.h"
+
+		class HIMR_Header_BothClass  : public HIMR_HeaderClass
+		{
+		public:
+			HIMR_Header_BothClass(istream *ist) : HIMR_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"himrconv.cc"
+
+		#include "himrconv.h"
+
+	"himrdc.c"
+
+		bool HIMR_Conversion::convertHeader(AttributeList *list);
+		bool HIMR_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool HIMR_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"himrdc.h"
+
+	"himrdmp.cc"
+
+		bool HIMR_Conversion::dump(ostream &o);
+
+	"himrdmp.h"
+
+	"himrhdrc.cc"
+
+		#include "himrhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"himr.tpl"
+
+		The template "describing" the format for header generation
+
+	"himrmdt.cc"
+
+		void HIMR_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"himrmmsc.cc"
+
+		void HIMR_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"himrmpln.cc"
+
+		void HIMR_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"himrptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"himrsrc.h"
+
+		class HIMR_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			HIMR_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~HIMR_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from himr.tpl:
+
+	"himrhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class HIMR_HeaderClass_HDR1 {
+		public:
+			HIMR_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"himrhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class HIMR_HeaderClass
+		{
+		public:
+			HIMR_HeaderClass(istream *ist);
+
+			HIMR_HeaderClass_HDR1 *HIMR_HeaderInstance_HDR1;
+			HIMR_HeaderClass_HDR2 *HIMR_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"himrhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		HIMR_HeaderClass::HIMR_HeaderClass(istream *ist);
+
+	"himrconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void HIMR_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"himrdmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void HIMR_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "himrhdrm.h".
+
+	if you have special purpose code, then "himrhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "himrhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/himr/himr.cc b/libsrc/src/dconvert/himr/himr.cc
new file mode 100644
index 0000000..9d77c27
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himr.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "himr.h"
+#include "himrcl.h"
+#include "srcsink.h"
+#include "himrsrc.h"
+
+HIMR_Conversion::HIMR_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	himrhdr=0;
+	pixeldatasrc=0;
+}
+
+HIMR_Conversion::~HIMR_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (himrhdr) delete himrhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/himr/himr.h b/libsrc/src/dconvert/himr/himr.h
new file mode 100644
index 0000000..ebd8a4e
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himr.h
@@ -0,0 +1,39 @@
+/* himr.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_himr__
+#define __Header_himr__
+
+// NB. a HIMR_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~HIMR_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class HIMR_Header_BothClass;
+class HIMR_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class HIMR_Conversion {
+	HIMR_Header_BothClass *himrhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	HIMR_PixelDataSource *pixeldatasrc;
+public:
+	HIMR_Conversion(istream &i,ostream &e);
+
+	virtual ~HIMR_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out);
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax);
+
+	bool convertHeader(AttributeList *list);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax);
+};
+
+#endif /* __Header_himr__ */
+
diff --git a/libsrc/src/dconvert/himr/himr.tpl b/libsrc/src/dconvert/himr/himr.tpl
new file mode 100755
index 0000000..5db917c
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himr.tpl
@@ -0,0 +1,189 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="IMGHDR"	offset="0"	intype="String"		inlength="4"	keyword="CONT"		dicomtype="?"	dicomtag="?"		# Controller label
+block="IMGHDR"	offset="4"	intype="String"		inlength="16"	keyword="KKEYNAME"	dicomtype="?"	dicomtag="?"		# Retrieval key name
+block="IMGHDR"	offset="20"	intype="String"		inlength="8"	keyword="KKEYEXT"	dicomtype="?"	dicomtag="?"		# Retrieval key extension
+block="IMGHDR"	offset="28"	intype="Uint32_B"	inlength="1"	keyword="DATE"		dicomtype="?"	dicomtag="?"		# Date of preparation
+block="IMGHDR"	offset="32"	intype="Uint32_B"	inlength="1"	keyword="TIME"		dicomtype="?"	dicomtag="?"		# Time of preparation
+block="IMGHDR"	offset="36"	intype="Uint32_B"	inlength="1"	keyword="SLBN"		dicomtype="?"	dicomtag="?"		# Top logical block num in MD
+block="IMGHDR"	offset="40"	intype="Uint32_B"	inlength="1"	keyword="ELBN"		dicomtype="?"	dicomtag="?"		# End logical block num in MD
+block="IMGHDR"	offset="44"	intype="Uint32_B"	inlength="1"	keyword="BKSZ"		dicomtype="?"	dicomtag="?"		# Number of data-full blocks (256 byte)
+block="IMGHDR"	offset="48"	intype="Uint16_B"	inlength="1"	keyword="IDCT"		dicomtype="?"	dicomtag="?"		# Number of extensions IDs
+block="IMGHDR"	offset="50"	intype="Uint16_B"	inlength="1"	keyword="UTNO"		dicomtype="SH"	dicomtag="StationName"		# Unit number
+block="IMGHDR"	offset="52"	intype="Uint16_B"	inlength="1"	keyword="OPMD"		dicomtype="?"	dicomtag="?"		# Open mode
+block="IMGHDR"	offset="54"	intype="Uint32_B"	inlength="1"	keyword="USEB"		dicomtype="?"	dicomtag="?"		# End peak logical block number
+block="IMGHDR"	offset="58"	intype="String"		inlength="4"	keyword="OPSN"		dicomtype="?"	dicomtag="?"		# Open sign (== OPEN)
+block="IMGHDR"	offset="62"	intype="Uint16_B"	inlength="1"	keyword="BKSU"		dicomtype="?"	dicomtag="?"		# Number of blocks of one-data unit
+block="IMGHDR"	offset="64"	intype="Uint16_B"	inlength="1"	keyword="DTSU"		dicomtype="?"	dicomtag="?"		# Number of data units
+block="IMGHDR"	offset="66"	intype="Uint16_B"	inlength="1"	keyword="MATX"		dicomtype="US"	dicomtag="Columns"	# X-directional matrix size
+block="IMGHDR"	offset="68"	intype="Uint16_B"	inlength="1"	keyword="MATY"		dicomtype="US"	dicomtag="Rows"		# Y-directional matrix size
+block="IMGHDR"	offset="70"	intype="Uint8"		inlength="1"	keyword="DTTP"		dicomtype="?"	dicomtag="?"		# Attribute data type
+block="IMGHDR"	offset="71"	intype="Uint8"		inlength="1"	keyword="ASGF"		dicomtype="?"	dicomtag="?"		# Attribute compression method/pixel depth
+block="IMGHDR"	offset="72"	intype="Uint16_B"	inlength="1"	keyword="GASY"		dicomtype="?"	dicomtag="?"		# Attribute image kind
+block="IMGHDR"	offset="74"	intype="Uint16_B"	inlength="1"	keyword="GASZ"		dicomtype="?"	dicomtag="?"		# Attribute pixel size (um)
+block="IMGHDR"	offset="76"	intype="Uint8"		inlength="1"	keyword="RWMD"		dicomtype="?"	dicomtag="?"		# Image compression
+block="IMGHDR"	offset="77"	intype="Uint8"		inlength="1"	keyword="YOBI"		dicomtype="?"	dicomtag="?"		# spare
+block="IMGHDR"	offset="78"	intype="Uint16_B"	inlength="1"	keyword="PRCD"		dicomtype="?"	dicomtag="?"		# Process code
+block="IMGHDR"	offset="80"	intype="Uint16_B"	inlength="1"	keyword="MODE"		dicomtype="?"	dicomtag="?"		# Mode (open)
+block="IMGHDR"	offset="82"	intype="Uint16_B"	inlength="1"	keyword="FRAM"		dicomtype="?"	dicomtag="?"		# Frame number
+block="IMGHDR"	offset="84"	intype="Uint16_B"	inlength="1"	keyword="BUNK"		dicomtype="?"	dicomtag="?"		# Number of divisions
+block="IMGHDR"	offset="86"	intype="Uint16_B"	inlength="1"	keyword="SECT"		dicomtype="?"	dicomtag="?"		# Section number
+block="IMGHDR"	offset="88"	intype="Uint16_B"	inlength="1"	keyword="DMW6"		dicomtype="?"	dicomtag="?"		# -
+block="IMGHDR"	offset="90"	intype="Uint16_B"	inlength="1"	keyword="KMMR"		dicomtype="?"	dicomtag="?"		# Provisionally assigned record
+block="IMGHDR"	offset="92"	intype="Uint16_B"	inlength="1"	keyword="EFRA"		dicomtype="?"	dicomtag="?"		# Trimmed end frame
+block="IMGHDR"	offset="94"	intype="Uint16_B"	inlength="1"	keyword="DMW9"		dicomtype="?"	dicomtag="?"		# -
+block="IMGHDR"	offset="96"	intype="Uint16_B"	inlength="1"	keyword="DMWA"		dicomtype="?"	dicomtag="?"		# -
+block="IMGHDR"	offset="98"	intype="Uint16_B"	inlength="1"	keyword="RETS"		dicomtype="?"	dicomtag="?"		# Return status
+block="IMGHDR"	offset="100"	intype="String"		inlength="4"	keyword="XISYS"		dicomtype="?"	dicomtag="?"		# System ID
+block="IMGHDR"	offset="104"	intype="String"		inlength="4"	keyword="XIVN"		dicomtype="LO"	dicomtag="SoftwareVersions"		# Version number
+block="IMGHDR"	offset="108"	intype="String"		inlength="1"	keyword="XIKND"		dicomtype="?"	dicomtag="?"	enum="'I'=Image,'R'=Raw data"	# Data kind
+block="IMGHDR"	offset="109"	intype="String"		inlength="1"	keyword="XISCAN"	dicomtype="?"	dicomtag="?"	enum="'S'=Scanogram,'C'=Normal scan image"	# Scanogram code
+block="IMGHDR"	offset="110"	intype="String"		inlength="2"	keyword="MISQ"		dicomtype="?"	dicomtag="?"	enum="'SR'=SR sequence (same as SE),'SE'=Spin echo,'IR'=Inversion recovery,'GE'=Gradient echo,'GR'=Gradient echo with rephasing"	# Pulse sequence
+block="IMGHDR"	offset="112"	intype="String"		inlength="1"	keyword="MIITYP"	dicomtype="?"	dicomtag="?"	enum="'A'=Absolute value image,'R'=Real part image,'I'=Imaginary part image,'P'=Phase image"	# Image data type
+block="IMGHDR"	offset="113"	intype="String"		inlength="1"	keyword="MICAL"		dicomtype="?"	dicomtag="?"	enum="'0'=Proton density image,'1'=T1 value image,'2'=T2 value image,' '=Normal"	# Calculation image
+block="IMGHDR"	offset="114"	intype="String"		inlength="1"	keyword="XISUB"		dicomtype="?"	dicomtag="?"	enum="'S'=Subtraction image,' '=Normal"	# Subtraction image
+block="IMGHDR"	offset="115"	intype="String"		inlength="1"	keyword="MISYN"		dicomtype="?"	dicomtag="?"	enum="'S'=Synthesized image,' '=Normal"	# Synthesized image
+block="IMGHDR"	offset="116"	intype="String"		inlength="1"	keyword="MIANA"		dicomtype="?"	dicomtag="?"	enum="'A'=Analysis image,' '=Normal"	# Analysis image (3D display etc.)
+block="IMGHDR"	offset="117"	intype="String"		inlength="1"	keyword="XIY3"		dicomtype="?"	dicomtag="?"		# spare
+block="IMGHDR"	offset="118"	intype="String"		inlength="2"	keyword="MIICLS"	dicomtype="?"	dicomtag="?"	enum="'R '=Image with rephasing,'TF'=Image of TOF angiography"	# Image kind code
+block="IMGHDR"	offset="120"	intype="String"		inlength="1"	keyword="XIPRS"		dicomtype="?"	dicomtag="?"	enum="' '=normal"	# Image compression code (1 to 6)
+block="IMGHDR"	offset="121"	intype="String"		inlength="1"	keyword="XIY61"		dicomtype="?"	dicomtag="?"		# Orientation indication for MPR (R,L,A,P)
+block="IMGHDR"	offset="122"	intype="String"		inlength="4"	keyword="XISYTP"	dicomtype="LO"	dicomtag="ManufacturerModelName"	enum="'MR70'=MRP7000,'MR20'=MRP20"	# System type
+block="IMGHDR"	offset="126"	intype="String"		inlength="2"	keyword="XIY64"		dicomtype="?"	dicomtag="?"		# spare
+block="IMGHDR"	offset="128"	intype="String"		inlength="20"	keyword="XIHP"	dicomtype="LO"	dicomtag="InstitutionName"	# Hospital name
+block="IMGHDR"	offset="148"	intype="String"		inlength="26"	keyword="XINM"	dicomtype="PN"	dicomtag="PatientName"		# Patients name
+block="IMGHDR"	offset="174"	intype="String"		inlength="9"	keyword="XIPN"	dicomtype="?"	dicomtag="?"			# Patients ID number
+block="IMGHDR"	offset="183"	intype="String"		inlength="1"	keyword="XIY7"	dicomtype="?"	dicomtag="?"			# spare
+block="IMGHDR"	offset="184"	intype="String"		inlength="4"	keyword="XISN"	dicomtype="IS"	dicomtag="InstanceNumber"	# Slice number
+block="IMGHDR"	offset="188"	intype="String"		inlength="1"	keyword="XIAB"	dicomtype="?"	dicomtag="?"	enum="'H'=Cardiac gate,'R'=Respiratory gate,'T'=3D display,'W'=Contour image for 3D display,'A'=Angiogram,'M'=MPR image"	# Slice kind (for display)
+block="IMGHDR"	offset="189"	intype="String"		inlength="1"	keyword="XISX"	dicomtype="CS"	dicomtag="PatientSex"		# Patients sex
+block="IMGHDR"	offset="190"	intype="String"		inlength="2"	keyword="XIBYY"	dicomtype="?"	dicomtag="?"			# Birthday year
+block="IMGHDR"	offset="192"	intype="String"		inlength="2"	keyword="XIBMM"	dicomtype="?"	dicomtag="?"			# Birthday month
+block="IMGHDR"	offset="194"	intype="String"		inlength="2"	keyword="XIBDD"	dicomtype="?"	dicomtag="?"			# Birthday day
+block="IMGHDR"	offset="196"	intype="String"		inlength="2"	keyword="XIYY"	dicomtype="?"	dicomtag="?"			# Exam year
+block="IMGHDR"	offset="198"	intype="String"		inlength="2"	keyword="XIMM"	dicomtype="?"	dicomtag="?"			# Exam month
+block="IMGHDR"	offset="200"	intype="String"		inlength="2"	keyword="XIDD"	dicomtype="?"	dicomtag="?"			# Exam day
+block="IMGHDR"	offset="202"	intype="String"		inlength="2"	keyword="XITH"	dicomtype="?"	dicomtag="?"			# Hours (hours)
+block="IMGHDR"	offset="204"	intype="String"		inlength="2"	keyword="XITM"	dicomtype="?"	dicomtag="?"			# Hours (minutes)
+block="IMGHDR"	offset="206"	intype="String"		inlength="2"	keyword="XITS"	dicomtype="?"	dicomtag="?"			# Hours (seconds)
+block="IMGHDR"	offset="208"	intype="String"		inlength="2"	keyword="XISTH"	dicomtype="?"	dicomtag="?"			# Stopwatch (hours)
+block="IMGHDR"	offset="210"	intype="String"		inlength="2"	keyword="XISTM"	dicomtype="?"	dicomtag="?"			# Stopwatch (minutes)
+block="IMGHDR"	offset="212"	intype="String"		inlength="2"	keyword="XISTS"	dicomtype="?"	dicomtag="?"			# Stopwatch (seconds)
+block="IMGHDR"	offset="214"	intype="String"		inlength="4"	keyword="XISLS"	dicomtype="DS"	dicomtag="SliceThickness"	# Slice thickness (mm)
+block="IMGHDR"	offset="218"	intype="String"		inlength="4"	keyword="XITR"	dicomtype="DS"	dicomtag="RepetitionTime"	# TR (ms)
+block="IMGHDR"	offset="222"	intype="String"		inlength="1"	keyword="XIST"	dicomtype="?"	dicomtag="?"	enum="'S'=yes,' '=no"	# Stopwatch designation
+block="IMGHDR"	offset="223"	intype="String"		inlength="1"	keyword="XICM"	dicomtype="?"	dicomtag="?"	enum="'C'=yes,' '=no"	# Use of contrast media
+block="IMGHDR"	offset="224"	intype="String"		inlength="3"	keyword="MITE"	dicomtype="DS"	dicomtag="EchoTime"	# TE (ms)
+block="IMGHDR"	offset="227"	intype="String"		inlength="1"	keyword="MISNDRCT"	dicomtype="?"	dicomtag="?"		# Scan direction code
+block="IMGHDR"	offset="228"	intype="String"		inlength="3"	keyword="MITI"	dicomtype="DS"	dicomtag="InversionTime"	# TI (ms)
+block="IMGHDR"	offset="231"	intype="String"		inlength="1"	keyword="XIIROT"	dicomtype="?"	dicomtag="?"	enum="' '=initial,'0'=during processing,'1'=during processing,'2'=during processing,'3'=during processing"	# Image rotation state code
+block="IMGHDR"	offset="232"	intype="String"		inlength="6"	keyword="XIPOS"	dicomtype="?"	dicomtag="?"			# Slice position (0.1mm)
+
+
+block="IMGHDR"	offset="256"	intype="String"		inlength="3"	keyword="MIMSMAX"	dicomtype="IS"	dicomtag="ImagesInAcquisition"	# Number of multislices
+block="IMGHDR"	offset="259"	intype="String"		inlength="1"	keyword="MIMEMAX"	dicomtype="IS"	dicomtag="EchoTrainLength"	# Number of multiechoes
+block="IMGHDR"	offset="260"	intype="String"		inlength="3"	keyword="MIMS"		dicomtype="IS"	dicomtag="AcquisitionNumber"	# Multislices number
+block="IMGHDR"	offset="263"	intype="String"		inlength="1"	keyword="MIME"		dicomtype="IS"	dicomtag="EchoNumbers"		# Multiecho number
+block="IMGHDR"	offset="264"	intype="String"		inlength="4"	keyword="XIMTX"	dicomtype="?"	dicomtag="?"			# Reconstruction matrix
+block="IMGHDR"	offset="268"	intype="String"		inlength="1"	keyword="MISLPL"	dicomtype="?"	dicomtag="?"	enum="'S'=Sagittal,'C'=Coronal,'T'=Transverse"	# Slice plane
+block="IMGHDR"	offset="269"	intype="String"		inlength="1"	keyword="MIOBL"	dicomtype="?"	dicomtag="?"	enum="' '=Non oblique,'1'=Single oblique,'2'=Double oblique"	# Oblique flag
+block="IMGHDR"	offset="270"	intype="String"		inlength="1"	keyword="XIRL"	dicomtype="?"	dicomtag="?"	enum="' '=Not transverse,'L'=Right of image is left of patient,'R'=Right of image is right of patient"	# Oblique flag
+block="IMGHDR"	offset="271"	intype="String"		inlength="1"	keyword="XIHVIW"	dicomtype="?"	dicomtag="?"	enum="'H'=Toward head (top view),'B'=Toward foot (bottom view)"	# Display direction of head image
+block="IMGHDR"	offset="272"	intype="String"		inlength="2"	keyword="XIPSD"	dicomtype="?"	dicomtag="?"	enum="'HF'=Head first,'FF'=Feet first"	# Patient inserting direction
+block="IMGHDR"	offset="274"	intype="String"		inlength="2"	keyword="XIPSP"	dicomtype="?"	dicomtag="?"	enum="'S '=Supine,'P '=Prone,'LD'=Left decubitus,'RD'=Right decubitus"	# Patient position
+block="IMGHDR"	offset="276"	intype="String"		inlength="26"	keyword="XICMT1"	dicomtype="?"	dicomtag="?"		# Comment in 1st line
+block="IMGHDR"	offset="302"	intype="String"		inlength="26"	keyword="XICMT2"	dicomtype="?"	dicomtag="?"		# Comment in 2nd line
+block="IMGHDR"	offset="328"	intype="String"		inlength="26"	keyword="XICMT3"	dicomtype="?"	dicomtag="?"		# Comment in 3rd line
+block="IMGHDR"	offset="354"	intype="String"		inlength="26"	keyword="XICMT4"	dicomtype="?"	dicomtag="?"		# Comment in 4th line
+block="IMGHDR"	offset="380"	intype="String"		inlength="26"	keyword="XICMT5"	dicomtype="?"	dicomtag="?"		# Comment in 5th line
+block="IMGHDR"	offset="406"	intype="String"		inlength="1"	keyword="XIPROTS"	dicomtype="?"	dicomtag="?"		# Protocol Number 1st digit (Sequence)
+block="IMGHDR"	offset="407"	intype="String"		inlength="1"	keyword="XIPROTR"	dicomtype="?"	dicomtag="?"		# Protocol Number 2nd digit (Region)
+block="IMGHDR"	offset="408"	intype="Uint16_B"	inlength="1"	keyword="XIPUL"		dicomtype="?"	dicomtag="?"		# Protocol upper window level
+block="IMGHDR"	offset="410"	intype="Uint16_B"	inlength="1"	keyword="XIPUW"		dicomtype="?"	dicomtag="?"		# Protocol upper window width
+block="IMGHDR"	offset="412"	intype="Uint16_B"	inlength="1"	keyword="XIPLL"		dicomtype="?"	dicomtag="?"		# Protocol lower window level
+block="IMGHDR"	offset="414"	intype="Uint16_B"	inlength="1"	keyword="XIPLW"		dicomtype="?"	dicomtag="?"		# Protocol lower window width
+block="IMGHDR"	offset="416"	intype="Uint16_B"	inlength="1"	keyword="XIPSX"		dicomtype="?"	dicomtag="?"		# Original image pixel size X in um
+block="IMGHDR"	offset="418"	intype="Uint16_B"	inlength="1"	keyword="XIPSY"		dicomtype="?"	dicomtag="?"		# Original image pixel size Y in um
+block="IMGHDR"	offset="420"	intype="Uint16_B"	inlength="1"	keyword="XIMAG"		dicomtype="?"	dicomtag="?"		# Magnification factor x1000
+block="IMGHDR"	offset="422"	intype="Uint16_B"	inlength="1"	keyword="XIZCNX"		dicomtype="?"	dicomtag="?"		# X direction mag center deviation (in 512 matrix, x16)
+block="IMGHDR"	offset="424"	intype="Uint16_B"	inlength="1"	keyword="XIZCNY"		dicomtype="?"	dicomtag="?"		# Y direction mag center deviation (in 512 matrix, x16)
+block="IMGHDR"	offset="426"	intype="String"		inlength="2"	keyword="XISHAP"	dicomtype="?"	dicomtag="?"	enum="'+ '=Enhancement,'- '=Smoothing"	# Edge enhancement
+block="IMGHDR"	offset="428"	intype="String"		inlength="4"	keyword="XIDFOV"	dicomtype="DS"	dicomtag="ReconstructionDiameter"	# Display field of view
+block="IMGHDR"	offset="432"	intype="String"		inlength="1"	keyword="XILNNO"	dicomtype="?"	dicomtag="?"		# spare
+block="IMGHDR"	offset="433"	intype="String"		inlength="1"	keyword="XILNDP"	dicomtype="?"	dicomtag="?"	enum="'T'=slice position,'N'=slice number"	# scan line display class
+block="IMGHDR"	offset="434"	intype="String"		inlength="6"	keyword="XISPO"		dicomtype="?"	dicomtag="?"		# Start slice position
+
+block="IMGHDR"	offset="736"	intype="Uint32_B"	inlength="1"	keyword="MIFREQOE"	dicomtype="?"	dicomtag="?"		# Center frequency (END)
+block="IMGHDR"	offset="740"	intype="Uint16_B"	inlength="1"	keyword="MISMPLTM"	dicomtype="?"	dicomtag="?"		# Sample time (ms)
+block="IMGHDR"	offset="742"	intype="String"		inlength="4"	keyword="XISCSN1"	dicomtype="?"	dicomtag="?"		# 1st select slice number
+block="IMGHDR"	offset="746"	intype="String"		inlength="4"	keyword="XISCSN2"	dicomtype="?"	dicomtag="?"		# 2nd select slice number
+block="IMGHDR"	offset="750"	intype="String"		inlength="1"	keyword="XISCANO1"	dicomtype="?"	dicomtag="?"	enum="'A'=yes,'N'=no"	# 1st select slice flag
+block="IMGHDR"	offset="751"	intype="String"		inlength="1"	keyword="XISCANO2"	dicomtype="?"	dicomtag="?"	enum="'A'=yes,'N'=no"	# 2nd select slice flag
+
+
+block="IMGHDR"	offset="824"	intype="String"		inlength="2"	keyword="XISCSN"	dicomtype="?"	dicomtag="?"		# Slice number of positioning image
+block="IMGHDR"	offset="826"	intype="String"		inlength="1"	keyword="XISCANO"	dicomtype="?"	dicomtag="?"	enum="'A'=yes,'N'=no"	# Execution of positioning
+block="IMGHDR"	offset="827"	intype="Uint8"		inlength="1"	keyword="MIAVG"		dicomtype="DS"	dicomtag="NumberOfAverages"	# Number of signals averaged (NSA)
+block="IMGHDR"	offset="828"	intype="Uint32_B"	inlength="1"	keyword="MIFREQO"	dicomtype="?"	dicomtag="?"		# Center frequency (Hz)
+block="IMGHDR"	offset="832"	intype="Uint16_B"	inlength="1"	keyword="MIVRCAP"	dicomtype="?"	dicomtag="?"		# Value of variable capacitance
+block="IMGHDR"	offset="834"	intype="Uint16_B"	inlength="1"	keyword="MIGX"		dicomtype="?"	dicomtag="?"		# X gradient field strength	
+block="IMGHDR"	offset="836"	intype="Uint16_B"	inlength="1"	keyword="MIGY"		dicomtype="?"	dicomtag="?"		# Y gradient field strength	
+block="IMGHDR"	offset="838"	intype="Uint16_B"	inlength="1"	keyword="MIGZ"		dicomtype="?"	dicomtag="?"		# Z gradient field strength	
+block="IMGHDR"	offset="840"	intype="Uint16_B"	inlength="1"	keyword="MISHIFT"	dicomtype="?"	dicomtag="?"		# Number of bit shifts for 2DFT	
+block="IMGHDR"	offset="842"	intype="String"		inlength="2"	keyword="MIENCD"	dicomtype="?"	dicomtag="?"	enum="'AP'=anterior-posterior,'HF'=head-feet,'RL'=right-left"	# Frequency encoding direction
+block="IMGHDR"	offset="844"	intype="Uint16_B"	inlength="1"	keyword="MISMPL"	dicomtype="?"	dicomtag="?"		# Number of samples (frequency)	
+block="IMGHDR"	offset="846"	intype="Uint16_B"	inlength="1"	keyword="MIPROJ"	dicomtype="?"	dicomtag="?"		# Number of projections (phase)	
+block="IMGHDR"	offset="848"	intype="Uint16_B"	inlength="1"	keyword="MIGAIN"	dicomtype="?"	dicomtag="?"		# Signal attenuation (dB)	
+block="IMGHDR"	offset="850"	intype="Uint16_B"	inlength="1"	keyword="MIBO"		dicomtype="?"	dicomtag="?"		# Static field strength (0.01T)	
+block="IMGHDR"	offset="852"	intype="String"		inlength="1"	keyword="XICCT"	dicomtype="?"	dicomtag="?"	enum="'1'=cardiac gated,' '=normal"	# Cardiac gated image
+block="IMGHDR"	offset="853"	intype="Uint8"		inlength="1"	keyword="MIBPM"		dicomtype="?"	dicomtag="?"		# Heart rate beats per minute
+block="IMGHDR"	offset="854"	intype="Uint16_B"	inlength="1"	keyword="MIECGDL"	dicomtype="?"	dicomtag="?"		# Delay time from R-wave
+block="IMGHDR"	offset="856"	intype="String"		inlength="95"	keyword="XICOMNT"	dicomtype="?"	dicomtag="?"		# spare
+block="IMGHDR"	offset="951"	intype="String"		inlength="1"	keyword="XIY11"		dicomtype="?"	dicomtag="?"		# R-L RVSL, CLKW
+block="IMGHDR"	offset="952"	intype="String"		inlength="2"	keyword="MICOIL"	dicomtype="?"	dicomtag="?"		# Used receiver coil
+block="IMGHDR"	offset="954"	intype="Uint16_B"	inlength="1"	keyword="MIFLANG"	dicomtype="DS"	dicomtag="FlipAngle"	# Flip angle
+block="IMGHDR"	offset="956"	intype="Uint16_B"	inlength="1"	keyword="MINECNT"	dicomtype="?"	dicomtag="?"		# Number of noise elimination data
+block="IMGHDR"	offset="958"	intype="Uint16_B"	inlength="1"	keyword="MIGS"		dicomtype="?"	dicomtag="?"		# Slice encoding GC
+block="IMGHDR"	offset="960"	intype="Uint16_B"	inlength="1"	keyword="MIVFSIZE"	dicomtype="?"	dicomtag="?"		# Rectangular FOV size (phase encoding direction) 256 equals to XIFOV
+block="IMGHDR"	offset="962"	intype="Uint8"		inlength="1"	keyword="MIVFFG"	dicomtype="?"	dicomtag="?"	enum="0=Normal"	# Rectangular FOV execution code (1-6 is rectangular scan)
+block="IMGHDR"	offset="963"	intype="String"		inlength="1"	keyword="MIAWSET"	dicomtype="?"	dicomtag="?"	enum="' '=no,'1'=yes"	# Auto window process scan
+block="IMGHDR"	offset="964"	intype="Uint16_B"	inlength="1"	keyword="MIAWGAIN"	dicomtype="?"	dicomtag="?"		# Auto window scan
+block="IMGHDR"	offset="966"	intype="Uint16_B"	inlength="1"	keyword="MIVFOPRJ"	dicomtype="?"	dicomtag="?"		# Original number of projection effective in rectangular FOV
+block="IMGHDR"	offset="968"	intype="String"		inlength="1"	keyword="MI3D"		dicomtype="?"	dicomtag="?"	enum="'0'=no,'1'=yes"	# 3D acquisition
+block="IMGHDR"	offset="969"	intype="Uint8"		inlength="1"	keyword="MI3DSFT"	dicomtype="?"	dicomtag="?"		# Number of bit shifts for FFT of slice encoding
+block="IMGHDR"	offset="970"	intype="Uint8"		inlength="1"	keyword="MISLAB"	dicomtype="?"	dicomtag="?"		# Multislab number
+block="IMGHDR"	offset="971"	intype="Uint8"		inlength="1"	keyword="MISLABMX"	dicomtype="?"	dicomtag="?"		# Number of multislabs
+block="IMGHDR"	offset="972"	intype="Uint8"		inlength="1"	keyword="MISQNO"	dicomtype="?"	dicomtag="?"		# Sequence number
+block="IMGHDR"	offset="973"	intype="Uint8"		inlength="1"	keyword="MISQCODE"	dicomtype="?"	dicomtag="?"	enum="1=with rephasing pulse"	# Sequence code
+block="IMGHDR"	offset="974"	intype="Uint8"		inlength="1"	keyword="MIRJCTM"	dicomtype="?"	dicomtag="?"		# Rejection sequnec time (ms)
+block="IMGHDR"	offset="975"	intype="Uint8"		inlength="1"	keyword="MIECGGT"	dicomtype="?"	dicomtag="?"		# Number of gate counts effective in cardiac gate image
+block="IMGHDR"	offset="976"	intype="String"		inlength="1"	keyword="MIRESP"	dicomtype="?"	dicomtag="?"	enum="'I'=inspiration,'E'=expiration"	# Respiratory gating
+block="IMGHDR"	offset="977"	intype="Uint8"		inlength="1"	keyword="MIPSATNO"	dicomtype="?"	dicomtag="?"		# Number of pre-saturation pulses
+block="IMGHDR"	offset="978"	intype="Uint32_B"	inlength="1"	keyword="MISCANTM"	dicomtype="?"	dicomtag="?"		# Scan time (ms)
+block="IMGHDR"	offset="982"	intype="String"		inlength="16"	keyword="MICILNAM"	dicomtype="SH"	dicomtag="ReceiveCoilName"	# Name of receiver coil
+block="IMGHDR"	offset="998"	intype="String"		inlength="1"	keyword="MIRFATT"	dicomtype="?"	dicomtag="?"		# Signal attenuation for double RF receiver line (dB)
+block="IMGHDR"	offset="999"	intype="String"		inlength="1"	keyword="MIRFLINE"	dicomtype="?"	dicomtag="?"		# Selection of RF receiver line
+block="IMGHDR"	offset="1000"	intype="String"		inlength="1"	keyword="MIAGHV"	dicomtype="?"	dicomtag="?"	enum="'H'=horizontal,'V'=vertical"	# Rotation direction of angiogram
+block="IMGHDR"	offset="1001"	intype="Uint8"		inlength="1"	keyword="MIHFFG"	dicomtype="?"	dicomtag="?"		# Half scan flag
+block="IMGHDR"	offset="1002"	intype="Uint8"		inlength="1"	keyword="MIVFOAVG"	dicomtype="?"	dicomtag="?"		# NSA (before rectangular)
+block="IMGHDR"	offset="1003"	intype="Uint8"		inlength="1"	keyword="MIYOBI"	dicomtype="?"	dicomtag="?"		# spare
+block="IMGHDR"	offset="1004"	intype="String"		inlength="16"	keyword="XIFD16"	dicomtype="LO"	dicomtag="PatientID"	# Patient ID (16 digits)
+block="IMGHDR"	offset="1020"	intype="Uint16_B"	inlength="1"	keyword="XIWL1"		dicomtype="?"	dicomtag="?"		# Window level
+block="IMGHDR"	offset="1022"	intype="Uint16_B"	inlength="1"	keyword="XIWW1"		dicomtype="?"	dicomtag="?"		# Window width
+
+
+
+
+constant="16" 		dicomtype="US"	dicomtag="BitsStored"			# 
+constant="16" 		dicomtype="US"	dicomtag="BitsAllocated"		# 
+constant="15" 		dicomtype="US"	dicomtag="HighBit"			# 
+constant="0" 		dicomtype="US"	dicomtag="PixelRepresentation"		# 
+constant="0" 		dicomtype="US"	dicomtag="PixelPaddingValue"		# 
+constant="1" 		dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 	dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="0" 		dicomtype="DS"	dicomtag="RescaleIntercept"		# 
+constant="" 		dicomtype="PN"	dicomtag="ReferringPhysicianName"	# 
+constant="0" 		dicomtype="SH"	dicomtag="StudyID"			# 
+constant="Hitachi Medical Systems" 	dicomtype="LO"	dicomtag="Manufacturer"			# 
+
diff --git a/libsrc/src/dconvert/himr/himrcl.h b/libsrc/src/dconvert/himr/himrcl.h
new file mode 100644
index 0000000..3baff1a
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrcl.h
@@ -0,0 +1,25 @@
+/* himrcl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "himrhdrp.h"
+#include "himrhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class HIMR_Header_BothClass : public HIMR_HeaderClass
+{
+public:
+	HIMR_Header_BothClass(istream *ist) : HIMR_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/himr/himrconv.cc b/libsrc/src/dconvert/himr/himrconv.cc
new file mode 100644
index 0000000..6adb1bc
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "himrdc.h"
+#include "himrptrs.h"
+#include "himrconv.h"
diff --git a/libsrc/src/dconvert/himr/himrdc.cc b/libsrc/src/dconvert/himr/himrdc.cc
new file mode 100644
index 0000000..c444d5a
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrdc.cc
@@ -0,0 +1,86 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrdc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "himrdc.h"
+#include "himr.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "himrsrc.h"
+
+bool
+HIMR_Conversion::convertHeader(AttributeList *list)
+{
+	Assert(list);
+	Assert(in);
+	if (!himrhdr) himrhdr=new HIMR_Header_BothClass(in);
+	Assert(himrhdr);
+
+	himrhdr->ToDicom_Template(list);
+	himrhdr->ToDicom_ManualMisc(list);
+	himrhdr->ToDicom_ManualPlane(list);
+	himrhdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in himr.h about the importance of the scope
+// of a HIMR_Conversion object and AttributeList object
+
+bool
+HIMR_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax)
+{
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!himrhdr) himrhdr=new HIMR_Header_BothClass(in);
+	Assert(himrhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	pixeldatasrc=new HIMR_PixelDataSource(
+		*in,
+		HIMR_Offset_PixelData_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+HIMR_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax)
+{
+	if (!convertHeader(list)) return false;
+	if (!convertPixelData(list,transfersyntax)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/himr/himrdc.h b/libsrc/src/dconvert/himr/himrdc.h
new file mode 100644
index 0000000..223a17a
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrdc.h
@@ -0,0 +1,7 @@
+/* himrdc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "himrcl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "himrptrs.h"
diff --git a/libsrc/src/dconvert/himr/himrdmp.cc b/libsrc/src/dconvert/himr/himrdmp.cc
new file mode 100644
index 0000000..28b532d
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrdmp.cc
@@ -0,0 +1,37 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "himrdmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "himr.h"
+
+bool
+HIMR_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!himrhdr) himrhdr=new HIMR_Header_BothClass(in);
+	Assert(himrhdr);
+
+	TextOutputStream out(o);
+
+	himrhdr->DumpCommon(&out);
+
+	return true;
+}
+
+
+bool
+HIMR_Conversion::dumpSelectedImage(ostream &o)
+{
+	Assert(in);
+	if (!himrhdr) himrhdr=new HIMR_Header_BothClass(in);
+	Assert(himrhdr);
+
+	TextOutputStream out(o);
+
+	himrhdr->DumpSelectedImage(&out);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/himr/himrdmp.h b/libsrc/src/dconvert/himr/himrdmp.h
new file mode 100644
index 0000000..0996d87
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrdmp.h
@@ -0,0 +1,4 @@
+/* himrdmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "himrcl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/himr/himrdmpf.cc b/libsrc/src/dconvert/himr/himrdmpf.cc
new file mode 100644
index 0000000..6a1e31e
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrdmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrdmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "himrdmp.h"
+#include "himrptrs.h"
+#include "himrdmpf.h"
diff --git a/libsrc/src/dconvert/himr/himrhdrc.cc b/libsrc/src/dconvert/himr/himrhdrc.cc
new file mode 100644
index 0000000..8333637
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrhdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "himrptrs.h"
+#include "himrhdrp.h"
+#include "himrhdrw.h"
+#include "himrhdrc.h"
+
diff --git a/libsrc/src/dconvert/himr/himrmdt.cc b/libsrc/src/dconvert/himr/himrmdt.cc
new file mode 100644
index 0000000..62ab894
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrmdt.cc
@@ -0,0 +1,46 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "himrdc.h"
+#include "elmconst.h"
+
+void 
+HIMR_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	{
+		// PatientBirthDate
+
+		unsigned yy=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIBYY));
+		unsigned mm=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIBMM));
+		unsigned dd=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIBDD));
+
+		(*list)+=new DateStringAttribute(TagFromName(PatientBirthDate),Date(yy,mm,dd));
+	}
+	{
+		// StudyDate
+		// SeriesDate
+		// ContentDate (formerly Image)
+
+		unsigned yy=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIYY));
+		unsigned mm=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIMM));
+		unsigned dd=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIDD));
+
+		(*list)+=new DateStringAttribute(TagFromName(StudyDate),Date(yy,mm,dd));
+		(*list)+=new DateStringAttribute(TagFromName(SeriesDate),Date(yy,mm,dd));
+		(*list)+=new DateStringAttribute(TagFromName(ContentDate),Date(yy,mm,dd));
+	}
+	{
+		// StudyTime
+		// SeriesTime
+		// ContentTime (formerly Image)
+
+		unsigned hh=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XITH));
+		unsigned mm=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XITM));
+		unsigned ss=atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XITS));
+
+		(*list)+=new TimeStringAttribute(TagFromName(StudyTime),Time(hh,mm,ss));
+		(*list)+=new TimeStringAttribute(TagFromName(SeriesTime),Time(hh,mm,ss));
+		(*list)+=new TimeStringAttribute(TagFromName(ContentTime),Time(hh,mm,ss));
+
+		(*list)+=new IntegerStringAttribute(TagFromName(SeriesNumber),Uint32(hh*10000+mm*100+ss));
+	}
+}
+
diff --git a/libsrc/src/dconvert/himr/himrmmsc.cc b/libsrc/src/dconvert/himr/himrmmsc.cc
new file mode 100644
index 0000000..5d35955
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrmmsc.cc
@@ -0,0 +1,246 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "himrdc.h"
+#include "elmconst.h"
+
+void 
+HIMR_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Modality
+
+	(*list)+=new CodeStringAttribute(TagFromName(Modality),"MR");
+
+	// MagneticFieldStrength - Tesla
+
+	(*list)+=new
+		DecimalStringAttribute(TagFromName(MagneticFieldStrength),
+			Uint32(HIMR_HeaderInstance_IMGHDR->MIBO)/100.0);
+
+	// ImagingFrequency MHz
+
+	(*list)+=new
+		DecimalStringAttribute(TagFromName(ImagingFrequency),
+			Uint32(HIMR_HeaderInstance_IMGHDR->MIFREQO)/1000000.0);
+
+	{
+		// ImageType
+
+		char *value1,*value2,*value3;
+
+		value1="ORIGINAL";
+
+		value2="PRIMARY";
+
+		value3="MPR";
+
+		//value3=strncmp(HIMR_HeaderInstance_IMGHDR->XISCAN,"C",1) == 0
+		//	? "AXIAL" : "LOCALIZER";
+
+		(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+			value1,value2,value3);
+	}
+
+	// ScanOptions
+
+	(*list)+=new CodeStringAttribute(TagFromName(ScanOptions));
+
+	// SequenceVariant
+
+	(*list)+=new CodeStringAttribute(TagFromName(SequenceVariant),"NONE");
+
+	{
+		// ScanningSequence
+
+		const char *str=0;
+
+		if      (strncmp(HIMR_HeaderInstance_IMGHDR->MISQ,"SR",2) == 0) str="SE";
+		else if (strncmp(HIMR_HeaderInstance_IMGHDR->MISQ,"SE",2) == 0) str="SE";
+		else if (strncmp(HIMR_HeaderInstance_IMGHDR->MISQ,"IR",2) == 0) str="IR";
+		else if (strncmp(HIMR_HeaderInstance_IMGHDR->MISQ,"GE",2) == 0) str="GR";
+		else if (strncmp(HIMR_HeaderInstance_IMGHDR->MISQ,"GR",2) == 0) str="GR";
+
+		(*list)+=new CodeStringAttribute(TagFromName(ScanningSequence),str);
+	}
+
+	{
+		// MRAcquisitionType
+
+		const char *str=strncmp(HIMR_HeaderInstance_IMGHDR->MI3D,"1",1) == 0 ? "3D" : "2D";
+
+		(*list)+=new CodeStringAttribute(TagFromName(MRAcquisitionType),str);
+	}
+
+	// ContrastBolus Module
+
+	if (strncmp(HIMR_HeaderInstance_IMGHDR->XICM,"C",1) == 0) {
+
+		// ContrastBolusAgent ="Contrast"
+
+		(*list)+=new LongStringAttribute(TagFromName(ContrastBolusAgent),
+			"Contrast");
+	}
+
+	// Do the descriptions ...
+
+	class Description {
+		ostrstream ost;
+		int first;
+		char delim;
+	public:
+		Description(char d=0)	{ first=1; delim=d; }
+
+		void add(const char *desc,unsigned maxlength)
+			{
+				char *buf = new char[maxlength+1];
+				strncpy(buf,desc,maxlength); buf[maxlength]=0;
+				char *lastshimr=strrchr(buf,' ');
+				if (lastshimr && buf[maxlength-1] == ' ')
+					*lastshimr=0;
+				char *start = buf;
+				while (*start && *start == ' ') ++start;
+				if (*start) {
+					if (!first && delim) ost << delim;
+					ost << start;
+				}
+				first=0;
+				if (buf) delete[] buf;
+			}
+
+		char *get(void)		{ ost << ends; return ost.str(); }
+	};
+
+	{
+		// ImageComments
+
+		Description desc(' ');
+		desc.add(HIMR_HeaderInstance_IMGHDR->XICMT1,26);
+		desc.add(HIMR_HeaderInstance_IMGHDR->XICMT2,26);
+		desc.add(HIMR_HeaderInstance_IMGHDR->XICMT3,26);
+		desc.add(HIMR_HeaderInstance_IMGHDR->XICMT4,26);
+		desc.add(HIMR_HeaderInstance_IMGHDR->XICMT5,26);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(ImageComments),str);
+		if (str) delete[] str;
+	}
+
+#ifdef CRAP
+	// GeneratorPower
+
+	// Loose fractional part ...
+
+	(*list)+=new IntegerStringAttribute(TagFromName(GeneratorPower),
+		(unsigned short)(atof(HIMR_HeaderInstance_IMGHDR->IGENPOW)));
+
+	// Do the descriptions ...
+
+	class Description {
+		ostrstream ost;
+		int first;
+		char delim;
+	public:
+		Description(char d=0)	{ first=1; delim=d; }
+
+		void add(const char *desc,unsigned maxlength)
+			{
+				char *buf = new char[maxlength+1];
+				strncpy(buf,desc,maxlength); buf[maxlength]=0;
+				char *lastshimr=strrchr(buf,' ');
+				if (lastshimr && buf[maxlength-1] == ' ')
+					*lastshimr=0;
+				char *start = buf;
+				while (*start && *start == ' ') ++start;
+				if (*start) {
+					if (!first && delim) ost << delim;
+					ost << start;
+				}
+				first=0;
+				if (buf) delete[] buf;
+			}
+
+		char *get(void)		{ ost << ends; return ost.str(); }
+	};
+
+	{
+		// StudyDescription
+
+		Description desc(' ');
+		desc.add(HIMR_HeaderInstance_STDHDR->SDESC1,50);
+		desc.add(HIMR_HeaderInstance_STDHDR->SDESC2,50);
+		desc.add(HIMR_HeaderInstance_STDHDR->SDESC3,50);
+		desc.add(HIMR_HeaderInstance_STDHDR->SDESC4,50);
+		desc.add(HIMR_HeaderInstance_STDHDR->SDESC5,50);
+
+		char *str=desc.get();
+		unsigned length=strlen(str);
+		if (length > 64) {
+			str[64]=0;
+			length=64;
+		}
+
+		(*list)+=new LongStringAttribute(TagFromName(StudyDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// SeriesDescription
+
+		Description desc(' ');
+		desc.add(HIMR_HeaderInstance_IMGHDR2->ISRDESC1,16);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->ISRDESC2,14);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->ISRDESC3,12);
+
+		char *str=desc.get();
+
+		(*list)+=new LongStringAttribute(TagFromName(SeriesDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// ImageComments
+
+		Description desc(' ');
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IIMDESC1,10);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IIMDESC2,8);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IIMDESC3,7);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(ImageComments),str);
+		if (str) delete[] str;
+	}
+	{
+		// AdditionalPatientHistory
+
+		Description desc(' ');
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC1,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC2,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC3,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC4,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC5,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC6,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC7,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC8,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC9,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC10,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC11,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC12,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC13,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC14,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC15,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC16,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC17,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC18,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC19,17);
+		desc.add(HIMR_HeaderInstance_IMGHDR2->IEXDESC20,17);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(AdditionalPatientHistory),str);
+		if (str) delete[] str;
+	}
+#endif
+
+
+}
+
diff --git a/libsrc/src/dconvert/himr/himrmpln.cc b/libsrc/src/dconvert/himr/himrmpln.cc
new file mode 100644
index 0000000..845225d
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrmpln.cc
@@ -0,0 +1,133 @@
+static const char *CopyrightIdentifier(void) { return "@(#)himrmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "himrdc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+HIMR_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlanePlane plane;
+
+	// Determine the "machine" plane of the image ...
+
+	switch (((char *)(HIMR_HeaderInstance_IMGHDR->MISLPL))[0]) {
+		case 'T':
+			plane=Axial;
+			break;
+		case 'S':
+			plane=Sagittal;
+			break;
+		case 'C':
+			plane=Coronal;
+			break;
+		default:	// Yuck - just in case :(
+			plane=Axial;
+			break;
+	}
+
+	ImagePlaneHeadFeet orientation;
+
+	switch (((char *)(HIMR_HeaderInstance_IMGHDR->XIPSD))[0]) {
+		case 'H':
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+		case 'F':
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+		default:
+			hfff="";		// :(
+			orientation=HeadFirst;
+			break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (((char *)(HIMR_HeaderInstance_IMGHDR->XIPSP))[0]) {
+		case 'P':
+			ap="P";
+			position=Prone;
+			break;
+		case 'S':
+			ap="S";
+			position=Supine;
+			break;
+		case 'L':
+			ap="DL";
+			position=LeftLateralDecubitus;
+			break;
+		case 'R':
+			ap="DR";
+			position=RightLateralDecubitus;
+			break;
+		default:
+			ap="";			// :(
+			position=Supine;
+			break;
+	}
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+
+	double scanfov = atof(HIMR_HeaderInstance_IMGHDR->XIDFOV);	// mm
+
+	// Make a model of the image plane ...
+
+	ImagePlane imageplane(plane,scanfov,orientation,position);
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlane done" << endl;
+//imageplane.put(cerr);
+
+	double location=(double)atoi(String_Use(HIMR_HeaderInstance_IMGHDR->XIPOS))/10.0;	// header value in 0.1 mm
+
+	// Have no idea of the signs and whether in patient or machine space
+
+	double xcenter=0;
+	double ycenter=0;
+	double zcenter=0;
+
+	switch (plane) {
+		case Axial:	zcenter=location;		// should account for left/right flip view top or bottom
+				break;
+		case Coronal:	ycenter=location;
+				break;
+		case Sagittal:	xcenter=location;
+				break;
+	}
+
+	Vector3D offset(xcenter,ycenter,zcenter);
+	imageplane.MachinePlane::shift(offset);
+
+	// Haven't accounted for angulation
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+
+	// SliceLocation
+
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),location);
+
+	// PixelSpacing
+
+	double original_xsize=double(HIMR_HeaderInstance_IMGHDR->XIPSX)/1000.0;
+	double original_ysize=double(HIMR_HeaderInstance_IMGHDR->XIPSY)/1000.0;
+	double mag_factor=double(HIMR_HeaderInstance_IMGHDR->XIMAG)/1000.0;
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		original_ysize*mag_factor,
+		original_xsize*mag_factor);
+
+	// PositionReferenceIndicator
+
+	(*list)+=new LongStringAttribute(TagFromName(PositionReferenceIndicator));
+
+}
+
diff --git a/libsrc/src/dconvert/himr/himrptrs.h b/libsrc/src/dconvert/himr/himrptrs.h
new file mode 100644
index 0000000..daf075a
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrptrs.h
@@ -0,0 +1,4 @@
+/* himrptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	HIMR_Offset_IMGHDR_ptr		0
+
+#define	HIMR_Offset_PixelData_ptr	1024
diff --git a/libsrc/src/dconvert/himr/himrsrc.h b/libsrc/src/dconvert/himr/himrsrc.h
new file mode 100644
index 0000000..6d1072f
--- /dev/null
+++ b/libsrc/src/dconvert/himr/himrsrc.h
@@ -0,0 +1,61 @@
+/* himrsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_himrsrc__
+#define __Header_himrsrc__
+
+class HIMR_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	HIMR_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~HIMR_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Little endian ...
+				Uint16 pixel;
+				pixel=(bytes[0]<<8)|bytes[1];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_himrsrc__
diff --git a/libsrc/src/dconvert/imtn/Imakefile b/libsrc/src/dconvert/imtn/Imakefile
new file mode 100755
index 0000000..0ab62fe
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = imtndc.cc imtnconv.cc imtnmpln.cc \
+		 imtnmmsc.cc imtnmdt.cc \
+		 imtndmp.cc imtndmpf.cc \
+		 imtnhdrc.cc imtn.cc
+
+OBJS = 		 imtndc.o  imtnconv.o  imtnmpln.o  \
+		 imtnmmsc.o  imtnmdt.o  \
+		 imtndmp.o  imtndmpf.o  \
+		 imtnhdrc.o  imtn.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdimtn.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(imtn,dconvert)
+
+ProjectConvertTemplate(imtnhdrp.h,imtn,convert,prefix=IMTN_ role=headerpart)
+ProjectConvertTemplate(imtnhdrw.h,imtn,convert,prefix=IMTN_ role=wholeheader)
+ProjectConvertTemplate(imtnhdrc.h,imtn,convert,prefix=IMTN_ role=constructheader)
+ProjectConvertTemplate(imtnconv.h,imtn,convert,prefix=IMTN_ role=dicom)
+ProjectConvertTemplate(imtndmpf.h,imtn,convert,prefix=IMTN_ role=dump)
+
+imtndmpf.o: imtndmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) imtndmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/imtn/NOTES b/libsrc/src/dconvert/imtn/NOTES
new file mode 100755
index 0000000..6325728
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/NOTES
@@ -0,0 +1,240 @@
+Questions:
+
+	direction of table tilt and slew ??
+
+	sign of in-out and up-down ??
+
+
+
+C100 seems to be RT11 based
+
+Imatron files contain multiple images.
+
+Images are specified by numeric "level" and "time".
+
+Blocks are 
+
+Start with Image Block 0 ... array of 14 shorts (28 bytes long):
+
+  UINT16 *HeadTablePtr = &Ib0[0]; /* Pts to first block in file header table*/
+  UINT16 *HeadEntries = &Ib0[1];	/* number of header entries */
+  UINT16 *HeadDataPtr = &Ib0[2];	/* Points to where header data is */
+  UINT16 *SliceTablePtr = &Ib0[3];	/* Points to slice header table */
+  UINT16 *SliceEntries = &Ib0[4];      /* num of entires in the slice header */
+  UINT16 *SliceHPosTable = &Ib0[5]; /* points to slice header pos table */
+  UINT16 *HEntrySize = &Ib0[6];		/* slice header table size */
+  UINT16 *Version = &Ib0[7];		/* version number of this file */
+  UINT16 *ndoff = &Ib0[8];		/* N of blocks of detector offsets */
+  UINT16 *nfhtab = &Ib0[9];	/* N of rt11 blocks in file header table */
+  UINT16 *nfhdat = &Ib0[10];	/* N of rt11 blocks in file header data */
+  UINT16 *nshtab = &Ib0[11];	/* N of rt11 blocks in slice header table */
+  UINT16 *nshptr = &Ib0[12];	/* N of rt11 blocks in slice header pos tabl */
+  UINT16 *nshdat = &Ib0[13];	/* N of rt11 blocks in slice header data */
+
+
+
+Slice stuff
+
+	slice header table (nshtab blocks located at SliceTablePtr) (Fh->SHTable)
+	slice header data (nshdat blocks)
+
+	slice position table (nshptr blocks at SliceHPosTable) (SLPosTable)
+		contains Nslice by Uint32_L block ptrs (->Fh->SHPositions as byte)
+		at that location read 1 Uint16_L -> Fh->SliceTable[i]
+
+	the slice header table is the same for all images
+	the data it indexes is different for each slice, starts at Fh->SliceTable[i]
+	the size of each data group is Fh->SliceHDataSize == *nshdat * C100_BLOCK
+
+	offsets for each slice in slice position table ?
+
+#define C100_BLOCK    512       /* Number of bytes in C-100's disk block */
+
+
+
+./extractim
+Enter level (0 for all) [1]:0
+Enter input file name:testfile
+File Name          : 000795.1VM 
+Date               : 09-JAN-92  
+Time               : 34:53:14 
+Patient ID         :              
+Patient Name       : WATER TEST 6MM                 
+Comments           :  
+Pixel Length       : 0.683594 mm 
+Number of slices   : 1
+Number of levels   : 1
+N times per level  : 1
+Anatomical Ref.    :   
+Study Type         : 5: volume
+Contrast Type      :                     
+Contrast Dose      : 0.000000 CC
+Injection Site     :                     
+Stress Type        :                     
+Referring Doctor   :               
+Radiologist        :               
+Technician Initials:    
+Kernel Type        : 6: is kernel code
+Birth Date         :          
+Trigger Type       : 2: timed
+Patient Size       : 2: medium
+Diagnostic Comments:                                         
+Scanner Name       : ** SCANNER 99 **  
+Scanner Mode       : 6: single-slice mode
+Slice Thickness    : 6.000000 mm
+Bolus Time         : 0.000000 sec
+Contrast Density   : 5000.000000 units
+
+
+Enter output file name:testfile.out
+Extracting all 1 levels at time 1
+Extracting from testfile level 1 time 1 to testfile.out
+Data Location      : 8704 bytes
+Slice Size         : 524288 bytes
+Mu Water           : 0.000000 
+Scan Direction Flag: 1 
+Scan Voltage       : 130451.781250 V
+Scan Current       : 0.612000 A
+Detector 1         : 0
+Detector 2         : 1
+Hires Detector     : 0
+Target             : C
+N Rows             : 512
+N Columns          : 512
+N averaged         : 8
+Picture Radius     : 350.000000 mm
+X origin           : 0.000000 mm
+Y origin           : 0.000000
+Zoom Factor        : 0.000000
+Elapsed Time       : 0.131000 sec
+Table Position     : -452.000000 mm
+Table Height       : 157.000000 mm
+Table Tilt         : 0.000000 degrees
+Table Slew         : 0.000000 degrees
+R-R Interval       : 0.000000 % of cardiac phase
+Heart Beat No.     : 0
+Heart Rate         : 0.000000 bpm
+Patient Orientation: 1: supine head first
+britt{root}% 
+
+britt{dclunie}% dd if=images/imatron/testfile ibs=512 skip=16 count=1 | dumpwhat -p -2 -l -d | more
+[     0]               17
+[     2]            16204
+[     4]              257
+[     6]                1
+[     8]            17410
+[    10]                0
+[    12]            17410
+[    14]            29608
+[    16]              612
+[    18]            16888
+[    20]                0
+[    22]                0
+[    24]                0
+[    26]                0
+[    28]                0
+[    30]                2
+[    32]               67
+[    34]                8
+[    36]            17583
+[    38]                0
+[    40]                0
+[    42]                0
+[    44]                0
+[    46]                0
+[    48]                0
+[    50]                0
+[    52]              512
+[    54]              512
+[    56]            18815
+[    58]            61440
+[    60]                0
+[    62]                0
+[    64]                0
+[    66]                0
+[    68]                0
+[    70]                0
+[    72]                2
+[    74]            16134
+[    76]             9437
+[    78]                5
+[    80]            32767
+[    82]                0
+[    84]            61016
+[    86]              157
+[    88]                0
+[    90]                0
+[    92]                0
+[    94]                0
+[    96]                0
+[    98]                0
+[   100]                1
+[   102]                0
+[   104]                0
+[   106]                0
+[   108]                0
+[   110]                0
+[   112]                0
+[   114]               12
+[   115] to [   511] zeroes (   397)
+
+britt{dclunie}% dd if=images/imatron/testfile ibs=512 skip=16 count=1 | dumpwhat -p -2 -l -x | more
+[     0]         0x0011	ISDATP itemtype=I wordoffset=1 itemsize=1
+[     2]         0x3f4c	R1MU itemtype=F wordoffset=2 itemsize=1
+[     4]         0x0101	
+[     6]         0x0001	IROTA itemtype=I wordoffset=4 itemsize=1
+[     8]         0x4402	HVDES itemtype=F wordoffset=5 itemsize=1
+[    10]         0x0000	
+[    12]         0x4402	HVACT itemtype=F wordoffset=7 itemsize=1
+[    14]         0x73a8	
+[    16]         0x0264	ICURNT itemtype=I wordoffset=9 itemsize=1
+[    18]         0x41f8	FVDES itemtype=F wordoffset=10 itemsize=1
+[    20]         0x0000	
+[    22]         0x0000	FVACT itemtype=F wordoffset=12 itemsize=1
+[    24]         0x0000	
+[    26]         0x0000	FCACT itemtype=F wordoffset=14 itemsize=1
+[    28]         0x0000	
+[    30]         0x0002	IRING itemtype=I wordoffset=16 itemsize=1
+[    32]         0x0043	ITARGT itemtype=I wordoffset=17 itemsize=1
+[    34]         0x0008	NSLAVG itemtype=I wordoffset=18 itemsize=1
+[    36]         0x44af	PICRAD itemtype=F wordoffset=19 itemsize=1
+[    38]         0x0000	
+[    40]         0x0000	
+[    42]         0x0000	
+[    44]         0x0000	
+[    46]         0x0000	
+[    48]         0x0000	
+[    50]         0x0000	
+[    52]         0x0200	
+[    54]         0x0200	
+[    56]         0x497f	VALMAX itemtype=F wordoffset=29 itemsize=1
+[    58]         0xf000	
+[    60]         0x0000	VALMIN itemtype=F wordoffset=31 itemsize=1
+[    62]         0x0000	
+[    64]         0x0000	
+[    66]         0x0000	
+[    68]         0x0000	
+[    70]         0x0000	
+[    72]         0x0002	
+[    74]         0x3f06	
+[    76]         0x24dd	
+[    78]         0x0005	LEVELN itemtype=I wordoffset=40 itemsize=1
+[    80]         0x7fff	ISTAGE itemtype=I wordoffset=41 itemsize=2 ****
+[    82]         0x0000	
+[    84]         0xee58	INOUT itemtype=I wordoffset=43 itemsize=1
+[    86]         0x009d	IHITE itemtype=I wordoffset=44 itemsize=1
+[    88]         0x0000	
+[    90]         0x0000	
+[    92]         0x0000	
+[    94]         0x0000	
+[    96]         0x0000	
+[    98]         0x0000	
+[   100]         0x0001	IPATOR itemtype=I wordoffset=51 itemsize=1
+[   102]         0x0000	
+[   104]         0x0000	
+[   106]         0x0000	
+[   108]         0x0000	
+[   110]         0x0000	
+[   112]         0x0000	
+[   114]         0x000c	
+[   115] to [   511] zeroes (   397)
diff --git a/libsrc/src/dconvert/imtn/imtn.cc b/libsrc/src/dconvert/imtn/imtn.cc
new file mode 100644
index 0000000..92a6c0a
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtn.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "imtn.h"
+#include "imtncl.h"
+#include "srcsink.h"
+#include "imtnsrc.h"
+
+IMTN_Conversion::IMTN_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	imtnhdr=0;
+	pixeldatasrc=0;
+}
+
+IMTN_Conversion::~IMTN_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (imtnhdr) delete imtnhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtn.h b/libsrc/src/dconvert/imtn/imtn.h
new file mode 100644
index 0000000..e4925c0
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtn.h
@@ -0,0 +1,37 @@
+/* imtn.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_imtn__
+#define __Header_imtn__
+
+// NB. a IMTN_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~IMTN_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class IMTN_Header_BothClass;
+class IMTN_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class IMTN_Conversion {
+	IMTN_Header_BothClass *imtnhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	IMTN_PixelDataSource *pixeldatasrc;
+public:
+	IMTN_Conversion(istream &i,ostream &e);
+
+	virtual ~IMTN_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0);
+
+	bool convertAll(AttributeList *list,TransferSyntax *transfersyntax,unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax,unsigned imagenumber=0);
+};
+
+#endif /* __Header_imtn__ */
+
diff --git a/libsrc/src/dconvert/imtn/imtn.tpl b/libsrc/src/dconvert/imtn/imtn.tpl
new file mode 100755
index 0000000..27158de
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtn.tpl
@@ -0,0 +1,147 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="MAINHDR"	offset="0"	intype="Uint16_L"	inlength="1"	keyword="FHENTRIES"	dicomtype="?"	dicomtag="?"	# Pointer to first block in the file header
+block="MAINHDR"	offset="2"	intype="Uint16_L"	inlength="1"	keyword="FHCOUNT"	dicomtype="?"	dicomtag="?"	# Number of entries in the file header
+block="MAINHDR"	offset="4"	intype="Uint16_L"	inlength="1"	keyword="FHDATA"	dicomtype="?"	dicomtag="?"	# Pointer to first block of the file header data
+
+block="MAINHDR"	offset="6"	intype="Uint16_L"	inlength="1"	keyword="SLENTRIES"	dicomtype="?"	dicomtag="?"	# Pointer to first block in the slice header
+block="MAINHDR"	offset="8"	intype="Uint16_L"	inlength="1"	keyword="SLCOUNT"	dicomtype="?"	dicomtag="?"	# Number of entries in the slice header
+block="MAINHDR"	offset="10"	intype="Uint16_L"	inlength="1"	keyword="SLTBPOSN"	dicomtype="?"	dicomtag="?"	# Pointer to first block of the slice header position table
+block="MAINHDR"	offset="12"	intype="Uint16_L"	inlength="1"	keyword="SLTBSIZE"	dicomtype="?"	dicomtag="?"	# Number of words in a header table entry
+
+block="MAINHDR"	offset="14"	intype="Uint16_L"	inlength="1"	keyword="VERSION"	dicomtype="LO"	dicomtag="SoftwareVersions"	# File type version number
+
+block="MAINHDR"	offset="16"	intype="Uint16_L"	inlength="1"	keyword="BLKDETOFF"	dicomtype="?"	dicomtag="?"	# Number of 512 byte blocks of detector offset data
+block="MAINHDR"	offset="18"	intype="Uint16_L"	inlength="1"	keyword="BLKFHENTRIES"	dicomtype="?"	dicomtag="?"	# Number of 512 byte blocks in file header table
+block="MAINHDR"	offset="20"	intype="Uint16_L"	inlength="1"	keyword="BLKFHDATA"	dicomtype="?"	dicomtag="?"	# Number of 512 byte blocks of file header data
+block="MAINHDR"	offset="22"	intype="Uint16_L"	inlength="1"	keyword="BLKSLENTRIES"	dicomtype="?"	dicomtag="?"	# Number of 512 byte blocks in slice header
+block="MAINHDR"	offset="24"	intype="Uint16_L"	inlength="1"	keyword="BLKSLTBPOSN"	dicomtype="?"	dicomtag="?"	# Number of 512 byte blocks in slice header position table
+block="MAINHDR"	offset="26"	intype="Uint16_L"	inlength="1"	keyword="BLKSLTBDATA"	dicomtype="?"	dicomtag="?"	# Number of 512 byte blocks for each section of slice header data
+block="MAINHDR"	offset="28"	intype="Uint16_L"	inlength="1"	keyword="DETOFF"	dicomtype="?"	dicomtag="?"	# Pointer to start of detector offset blocks
+
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IFHLEN"	dicomtype="?"	dicomtag="?"	# number of 512 byte blocks in file header
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ISHLEN"	dicomtype="?"	dicomtag="?"	# number of 512 byte blocks in slice header
+block="FILEHDR" method="ExtractTaggedString"	keyword="IAFN"		dicomtype="?"	dicomtag="?"	# file descriptor nnnnnn.eee
+block="FILEHDR" method="ExtractTaggedString"	keyword="IADATE"	dicomtype="?"	dicomtag="?"	# date
+block="FILEHDR" method="ExtractTaggedString"	keyword="IATIME"	dicomtype="?"	dicomtag="?"	# time
+block="FILEHDR" method="ExtractTaggedString"	keyword="IPATID"	dicomtype="LO"	dicomtag="PatientID"		# patient ID
+block="FILEHDR" method="ExtractTaggedString"	keyword="IPATNA"	dicomtype="PN"	dicomtag="PatientName"		# patient name
+block="FILEHDR" method="ExtractTaggedString"	keyword="ICMNTS"	dicomtype="LO"	dicomtag="StudyDescription"	# comments
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NDETS"		dicomtype="US"	dicomtag="NumberOfDetectors"	# number of detectors (432 or 864)
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IDEMAP"	dicomtype="?"	dicomtag="?"	# detector status map (series of words, channel k IW=1+(k-1)/16,IBIT = k-(IW-1)*16-1))
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ISTOB"		dicomtype="?"	dicomtag="?"	# starting block for detector offset measurements (0 for none)
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NSLICE"	dicomtype="IS"	dicomtag="ImagesInAcquisition"	# number of slices in file
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IORGAN"	dicomtype="?"	dicomtag="?"	enum="-2=unsorted raw MM (AIR/PIN/OFFSET) ,-1=unsorted raw MM (Non-calibration),0=source-fan data1=detector-fan,2=image,3=tuning point,4=deflection buffer,5=processed calibration,6=processed AIR data,7=processed OFFSET"	# file organization code
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ITTICK"	dicomtype="?"	dicomtag="?"	# DAS clock period microseconds
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NPHVEW"	dicomtype="?"	dicomtag="?"	# number of phantoms
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IDATYP"	dicomtype="?"	dicomtag="?"	enum="0=DAS output words (all RAW data),1=Integer,2=Floating point (Sinogram/tuning/offsets),3=Scaled 11-bit integer data (image and screen save),4=AP400 block floating point mantissas,5=MM address data (calibration data),6=Octal data (deflection buffer files),7=Packed Fast Raw Averaged Data,8=Scaled 12-bit integer data (image and screen save)"	# data type
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NDETOM"	dicomtype="?"	dicomtag="?"	# Number of detector offset measurements
+block="FILEHDR" method="ExtractTaggedFloat"	keyword="XMMTMU"	dicomtype="?"	dicomtag="?"	# Scale factor to change mm to MIP machine units (units are m.u./mm)
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IREP"		dicomtype="?"	dicomtag="?"	enum="3=Multi-slice (50ms) scan,6=Single-slice (100ms) scan"	# number of DAS samples per detector per source fan
+block="FILEHDR" method="ExtractTaggedFloat"	keyword="PIXLEN"	dicomtype="?"	dicomtag="?"	# Pixel length mm from reconstruction
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NLEVEL"	dicomtype="?"	dicomtag="?"	# Number of levels in file
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NPLEVL"	dicomtype="?"	dicomtag="?"	# Number of images per level
+block="FILEHDR" method="ExtractTaggedString"	keyword="IREF"		dicomtype="LO"	dicomtag="PositionReferenceIndicator"	# description of the reference point
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ISTUDY"	dicomtype="?"	dicomtag="?"	enum="-1=Screen save,0=Special,1=Localization,2=Flow,3=Movie,4=Average volume,5=Volume,6=Average flow,51=Image averaging,52=Reformat,53=FIP Maximum Difference,54=FIP Time to Peak,55=FIP Area Under the Curve, 56=FIP Center of Mass,102=Image subtraction flow,103=Image subtraction movie,105=Image subtraction volume,106=Image subtraction average flow"	# study type
+block="FILEHDR" method="ExtractTaggedString"	keyword="ICONTR"	dicomtype="LO"	dicomtag="ContrastBolusAgent"	# Type of contrast
+block="FILEHDR" method="ExtractTaggedFloat"	keyword="DOSECN"	dicomtype="DS"	dicomtag="ContrastBolusVolume"	# Contrast dose in cc
+block="FILEHDR" method="ExtractTaggedString"	keyword="INJSIT"	dicomtype="LO"	dicomtag="ContrastBolusRoute"	# Injection Site
+block="FILEHDR" method="ExtractTaggedString"	keyword="ISTRES"	dicomtype="?"	dicomtag="?"	# Type of stress
+block="FILEHDR" method="ExtractTaggedString"	keyword="IRPHYS"	dicomtype="PN"	dicomtag="ReferringPhysicianName"	# Referring physician last name
+block="FILEHDR" method="ExtractTaggedString"	keyword="IRADIO"	dicomtype="PN"	dicomtag="PerformingPhysicianName"	# Radiologist last name
+block="FILEHDR" method="ExtractTaggedString"	keyword="ITECH"		dicomtype="PN"	dicomtag="OperatorsName"	# Radiation technologist initials
+block="FILEHDR" method="ExtractTaggedString"	keyword="IBDATE"	dicomtype="?"	dicomtag="?"	# patient DOB dd-mmm-yy
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ISTHCK"	dicomtype="DS"	dicomtag="SliceThickness"	# Slice thickness in mm
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ICALIB"	dicomtype="?"	dicomtag="?"	# Calibration number
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="KERNEL"	dicomtype="?"	dicomtag="?"	# Desired kernel flag
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ITRTYP"	dicomtype="?"	dicomtag="?"	enum="1=manual,2=timed,3=ecg without trace data,4=ecg with trace data,5=undefined"	# trigger type
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IPATSZ"	dicomtype="?"	dicomtag="?"	enum="1=small,2=medium,3=large,4=shoulder or pelvis"	# patient size
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IPRLVL"	dicomtype="?"	dicomtag="?"	enum="0=none"	# Regular reconstructions first level to reconstruct
+block="FILEHDR" method="ExtractTaggedString"	keyword="IDIAG"		dicomtype="LT"	dicomtag="PatientComments"	# Diagnosis comment
+block="FILEHDR" method="ExtractTaggedString"	keyword="IHOSP"		dicomtype="SH"	dicomtag="StationName"	# Hospital (actually scanner)
+block="FILEHDR" method="ExtractTaggedFloat"	keyword="BOLTIM"	dicomtype="?"	dicomtag="?"	# Bolus times
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NSPLIT"	dicomtype="?"	dicomtag="?"	# Number of images to be created from each raw slice
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IDLINP"	dicomtype="?"	dicomtag="?"	enum="0=do not delete after recon,1=delete after complete recon"	# Delete raw data flag
+block="FILEHDR" method="ExtractTaggedFloat"	keyword="CDENS"		dicomtype="?"	dicomtag="?"	# Density of contrast
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IOFMIN"	dicomtype="?"	dicomtag="?"	# Time since midnight in minutes of last offsets
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IOFDAT"	dicomtype="?"	dicomtag="?"	# Day since dec 31 of last offsets
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NRINGS"	dicomtype="?"	dicomtag="?"	# Number of detector rings used
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="NTARGT"	dicomtype="?"	dicomtag="?"	# Number of targets used
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ICNREC"	dicomtype="?"	dicomtag="?"	enum="0=not suitable,1=suitable,2=suitable and used"	# Cone beam algorithm
+block="FILEHDR" method="ExtractTaggedString"	keyword="KERNAM"	dicomtype="SH"	dicomtag="ConvolutionKernel"	# Kernel name used
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ISNTYP"	dicomtype="?"	dicomtag="?"	# Sinogram type
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="IANTYP"	dicomtype="?"	dicomtag="?"	enum="1=Cone analysis,2=Air analysis,3=Pin analysis"	# Analysis type for ASA
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ISTHCF"	dicomtype="?"	dicomtag="?"	# Slice thickness in .01 mm
+block="FILEHDR" method="ExtractTaggedInteger"	keyword="ICOLL"		dicomtype="?"	dicomtag="?"	enum="1=1.5mm,3=3mm,6=6mm"	# Collimator setting
+
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ISDATP"	dicomtype="?"	dicomtag="?"	# 512 byte block pointer to data for this slice
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="R1MU"		dicomtype="?"	dicomtag="?"	# Linear attenuation co-efficient for water at this energy and current, ring 1
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IROTA"		dicomtype="?"	dicomtag="?"	enum="1=clockwise,-1=counter-clockwise"	# rotation
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="HVDES"		dicomtype="?"	dicomtag="?"	# Desired high voltage for this scan, kV
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="HVACT"		dicomtype="DS"	dicomtag="KVP"	# Actual high voltage for this scan, kV
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ICURNT"	dicomtype="IS"	dicomtag="XRayTubeCurrent"	# Actual electron beam current, mA
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="FVDES"		dicomtype="?"	dicomtag="?"	# Desired filament voltage, volts
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="FVACT"		dicomtype="?"	dicomtag="?"	# Actual filament voltage, volts
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="FCACT"		dicomtype="?"	dicomtag="?"	# Actual filament current, mA
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IRING"		dicomtype="?"	dicomtag="?"	enum="0=raw slice with both rings interleaved,1=ring 1 (closest to gun),2=ring 2 (farther from gun)"	# detector ring
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ITARGT"	dicomtype="?"	dicomtag="?"	enum="65=A,66=B,67=C,68=D,69=E"	# target ring used
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="NSLAVG"	dicomtype="?"	dicomtag="?"	# number of scans averaged to produce this slice
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="PICRAD"	dicomtype="DS"	dicomtag="ReconstructionDiameter"	# Picture radius in mm
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="XORG"		dicomtype="?"	dicomtag="?"	# X coordinate of reconstruction center (0.0 is isocenter) in mm
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="YORG"		dicomtype="?"	dicomtag="?"	# Y coordinate of reconstruction center (0.0 is isocenter) in mm
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="ZOOM"		dicomtype="?"	dicomtag="?"	# Zoom factor (1.0 = no zoom) for reconstruction (also seems 0 = no zoom)
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="NROWS"		dicomtype="US"	dicomtag="Rows"		# rows
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="NCOLS"		dicomtype="US"	dicomtag="Columns"	# columns
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="VALMAX"	dicomtype="XS"	dicomtag="LargestImagePixelValue"	# Maximum value in the slice
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="VALMIN"	dicomtype="XS"	dicomtag="SmallestImagePixelValue"	# Minimum value in the slice
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="RSCALE"	dicomtype="?"	dicomtag="?"	# Data has been scaled and biased such that actual data = data/RSCALE + RMIN
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="RMIN"		dicomtype="?"	dicomtag="?"	# Data has been scaled and biased such that actual data = data/RSCALE + RMIN
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IPATH"		dicomtype="?"	dicomtag="?"	enum="0=path was holding path,1=path was the first for that pulse,2=slice was not the first of that pulse (slices 2-N for a movie or volume)"	# Holding path flag
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="ELAPSE"	dicomtype="?"	dicomtag="?"	# Time since the first scan, in seconds
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="LEVELN"	dicomtype="?"	dicomtag="?"	# Level number for a given slice
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ISTAGE"	dicomtype="?"	dicomtag="?"	# Old:2 word array,2nd word unused,1st word is >=0 if data is present and useful
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="INOUT"		dicomtype="?"	dicomtag="?"	# In-out table position relative to reference in .1 mm
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IHITE"		dicomtype="DS"	dicomtag="TableHeight"	# Up-down table position relative to referencein  mm
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ITILT"		dicomtype="DS"	dicomtag="GantryDetectorTilt"	# Table tilt relative to horizontal in degrees
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ISLEW"		dicomtype="DS"	dicomtag="GantryDetectorSlew"	# Table slew relative to straight in degrees
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ICPHAS"	dicomtype="DS"	dicomtag="TriggerWindow"	# cardiac phase (% of R-R interval)
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IBEAT"		dicomtype="?"	dicomtag="?"	# Heart beat number for this image
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="HRATE"		dicomtype="DS"	dicomtag="HeartRate"	# Heart rate in beats per minute
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IPATOR"	dicomtype="?"	dicomtag="?"	enum="-8=decubitus left feet first flipped,-7=decubitus right feet first flipped,-6=prone feet first flipped,-5=supine feet first flipped,0=unknown,1=supine head first,2=prone head first,3=decubitus right head first,4=decubitus left head first,5=prone head first flipped"	# Patient orientation
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="SLSIZE"	dicomtype="?"	dicomtag="?"	# Size of slice in words
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="ITN"		dicomtype="?"	dicomtag="?"	# Order of Chebychev polynomial applied to data (only if valid during calibration, 0 for normal recon)
+block="SLICEHDR" select="image"	method="ExtractTaggedFloat"	keyword="R2MU"		dicomtype="?"	dicomtag="?"	# Linear attenuation coefficient for water at this energy and current, ring 2
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="IVMFLG"	dicomtype="?"	dicomtag="?"	# Bit-map of flags used by recon
+block="SLICEHDR" select="image"	method="ExtractTaggedInteger"	keyword="NTARGS"	dicomtype="?"	dicomtag="?"	# Number of target sections of this target ring
+
+constant="0" 			dicomtype="US"	dicomtag="PixelPaddingValue"		# 
+constant="16" 			dicomtype="US"	dicomtag="BitsAllocated"		# 
+constant="16" 			dicomtype="US"	dicomtag="BitsStored"			# 
+constant="15" 			dicomtype="US"	dicomtag="HighBit"			# 
+constant="0" 			dicomtype="US"	dicomtag="PixelRepresentation"		# Unsigned
+constant="1" 			dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 		dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="-1000" 		dicomtype="DS"	dicomtag="RescaleIntercept"		# 
+constant="1" 			dicomtype="DS"	dicomtag="RescaleSlope"			# 
+constant="Hounsfield Units" 	dicomtype="LO"	dicomtag="RescaleType"			# 
+constant="30"			dicomtype="DS"	dicomtag="WindowCenter"			# 
+constant="250"			dicomtype="DS"	dicomtag="WindowWidth"			# 
+constant="Soft tissue"		dicomtype="LO"	dicomtag="WindowCenterWidthExplanation"	# 
+
+constant=""			dicomtype="SH"	dicomtag="AccessionNumber"		# 
+constant="1"			dicomtype="IS"	dicomtag="SeriesInStudy"		# 
+constant="1"			dicomtype="IS"	dicomtag="AcquisitionsInStudy"		# 
+constant=""			dicomtype="SH"	dicomtag="StudyID"			#
+constant="1"			dicomtype="IS"	dicomtag="SeriesNumber"			# 
+constant=""			dicomtype="IS"	dicomtag="InstanceNumber"			# 
+
+constant=""			dicomtype="LO"	dicomtag="DeviceSerialNumber"		# 
+constant=""			dicomtype="DS"	dicomtag="PatientWeight"		# 
+constant=""			dicomtype="CS"	dicomtag="PatientSex"			# 
+constant="IMATRON"		dicomtype="LO"	dicomtag="Manufacturer"			# 
+constant="C-100/150"		dicomtype="LO"	dicomtag="ManufacturerModelName"	# 
+
+constant=""			dicomtype="CS"	dicomtag="BodyPartExamined"		# 
+constant=""			dicomtype="SH"	dicomtag="FilterType"			# 
+constant="CT"			dicomtype="CS"	dicomtag="Modality"			# 
diff --git a/libsrc/src/dconvert/imtn/imtncl.h b/libsrc/src/dconvert/imtn/imtncl.h
new file mode 100644
index 0000000..9221a00
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtncl.h
@@ -0,0 +1,23 @@
+/* imtncl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "imtnhdrm.h"
+#include "imtnhdrp.h"
+#include "imtnhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class IMTN_Header_BothClass : public IMTN_HeaderClass
+{
+public:
+	IMTN_Header_BothClass(istream *ist) : IMTN_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0);
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/imtn/imtnconv.cc b/libsrc/src/dconvert/imtn/imtnconv.cc
new file mode 100644
index 0000000..68ac254
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtnconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "imtndc.h"
+#include "imtnptrs.h"
+#include "imtnconv.h"
diff --git a/libsrc/src/dconvert/imtn/imtndc.cc b/libsrc/src/dconvert/imtn/imtndc.cc
new file mode 100644
index 0000000..bc0d9d3
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtndc.cc
@@ -0,0 +1,85 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtndc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "imtndc.h"
+#include "imtn.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "imtnsrc.h"
+
+bool
+IMTN_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(list);
+	Assert(in);
+	if (!imtnhdr) imtnhdr=new IMTN_Header_BothClass(in);
+	Assert(imtnhdr);
+
+	imtnhdr->ToDicom_Template(list,imagenumber);
+	imtnhdr->ToDicom_ManualMisc(list,imagenumber);
+	imtnhdr->ToDicom_ManualPlane(list,imagenumber);
+	imtnhdr->ToDicom_ManualDates(list,imagenumber);
+
+	return true;
+}
+
+// See comments in imtn.h about the importance of the scope
+// of a IMTN_Conversion object and AttributeList object
+
+bool
+IMTN_Conversion::convertPixelData(AttributeList *list,
+		TransferSyntax *transfersyntax,unsigned imagenumber)
+{
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!imtnhdr) imtnhdr=new IMTN_Header_BothClass(in);
+	Assert(imtnhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+	pixeldatasrc=new IMTN_PixelDataSource(
+		*in,
+		IMTN_Offset_PixelData_ptr,
+		rows,
+		cols);
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+IMTN_Conversion::convertAll(AttributeList *list,
+	TransferSyntax *transfersyntax,
+	unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtndc.h b/libsrc/src/dconvert/imtn/imtndc.h
new file mode 100644
index 0000000..bb50003
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtndc.h
@@ -0,0 +1,7 @@
+/* imtndc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "imtncl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "imtnptrs.h"
diff --git a/libsrc/src/dconvert/imtn/imtndmp.cc b/libsrc/src/dconvert/imtn/imtndmp.cc
new file mode 100644
index 0000000..b7db527
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtndmp.cc
@@ -0,0 +1,36 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtndmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "imtndmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "imtn.h"
+
+bool
+IMTN_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!imtnhdr) imtnhdr=new IMTN_Header_BothClass(in);
+	Assert(imtnhdr);
+
+	TextOutputStream out(o);
+
+	imtnhdr->DumpCommon(&out);
+
+	return true;
+}
+
+bool
+IMTN_Conversion::dumpSelectedImage(ostream &o,unsigned imagenumber)
+{
+	Assert(in);
+	if (!imtnhdr) imtnhdr=new IMTN_Header_BothClass(in);
+	Assert(imtnhdr);
+
+	TextOutputStream out(o);
+
+	imtnhdr->DumpSelectedImage(&out,imagenumber);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtndmp.h b/libsrc/src/dconvert/imtn/imtndmp.h
new file mode 100644
index 0000000..742fea2
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtndmp.h
@@ -0,0 +1,4 @@
+/* imtndmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "imtncl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/imtn/imtndmpf.cc b/libsrc/src/dconvert/imtn/imtndmpf.cc
new file mode 100644
index 0000000..4f35c93
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtndmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtndmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "imtndmp.h"
+#include "imtnptrs.h"
+#include "imtndmpf.h"
diff --git a/libsrc/src/dconvert/imtn/imtnhdrc.cc b/libsrc/src/dconvert/imtn/imtnhdrc.cc
new file mode 100644
index 0000000..4515d8a
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnhdrc.cc
@@ -0,0 +1,361 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtnhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "imtnptrs.h"
+#include "imtnhdrm.h"
+#include "imtnhdrp.h"
+#include "imtnhdrw.h"
+#include "imtnhdrc.h"
+
+#include "fltype.h"
+
+const Uint16 IMTN_BlockSize = 512;
+
+// Manually generated constructors for "method" based classes declared in imtnhdrm.h
+
+// If the args are changed here, change the IMTN_MethodConstructorArgs macros in imtnptrs.h
+
+/* ------------------------------ File Header ------------------------------ */
+
+IMTN_HeaderClass_FILEHDR::IMTN_HeaderClass_FILEHDR(istream *istr,
+	Uint16 fhentries,Uint16 fhcount,Uint16 fhdata,Uint16 blkfhdata)
+{
+	// Load the file header parts ...
+
+	nEntries=0;
+
+	unsigned long offset=fhentries*IMTN_BlockSize;
+	size_t length=fhcount*sizeof(IMTN_HeaderClass_FILEHDR_Entry);
+//cerr << "IMTN_HeaderClass_FILEHDR::IMTN_HeaderClass_FILEHDR: entry offset=" << dec << offset << endl;
+//cerr << "IMTN_HeaderClass_FILEHDR::IMTN_HeaderClass_FILEHDR: entry length=" << dec << length << endl;
+	Assert(sizeof(IMTN_HeaderClass_FILEHDR_Entry) == 12);
+	entry=new IMTN_HeaderClass_FILEHDR_Entry[fhcount];
+	Assert(entry);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+
+	// Since the entries are 12 bytes and the blocks are 512 bytes,
+	// there are 42 entries per block, with 8 bytes of padding to
+	// prevent an entry spanning a block boundary (grump)
+
+	unsigned entriesleft=fhcount;
+	const unsigned entriesperblock=IMTN_BlockSize/sizeof(IMTN_HeaderClass_FILEHDR_Entry);
+	const unsigned npadbytes=IMTN_BlockSize-entriesperblock*sizeof(IMTN_HeaderClass_FILEHDR_Entry);
+	Assert(entriesperblock == 42);
+	Assert(npadbytes == 8);
+	IMTN_HeaderClass_FILEHDR_Entry *entryptr=entry;
+	while (entriesleft) {
+		unsigned entriesthistry=entriesleft > entriesperblock ? entriesperblock : entriesleft;
+
+		istr->read((char*)entryptr,entriesthistry*sizeof(IMTN_HeaderClass_FILEHDR_Entry));
+		if (!istr->good()) return;
+
+		entriesleft-=entriesthistry;
+		entryptr+=entriesthistry;
+
+		char dummy[npadbytes];
+		istr->read(dummy,npadbytes);
+		if (!istr->good()) return;
+	}
+
+	offset=fhdata*IMTN_BlockSize;
+	length=blkfhdata*IMTN_BlockSize;
+//cerr << "IMTN_HeaderClass_FILEHDR::IMTN_HeaderClass_FILEHDR: data offset=" << dec << offset << endl;
+//cerr << "IMTN_HeaderClass_FILEHDR::IMTN_HeaderClass_FILEHDR: data length=" << dec << length << endl;
+	data=new char[length];
+	Assert(data);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+	istr->read(data,length);
+	if (!istr->good()) return;
+
+	nEntries=fhcount;
+
+	// Think about how caller handles errors ...
+	// see what ReadProprietaryHeader() would do
+
+//	int i;
+//	IMTN_HeaderClass_FILEHDR_Entry *ptr;
+//	for (i=0,ptr=entry; i<nEntries; ++i,++ptr) {
+//		cerr << "IMTN_HeaderClass_FILEHDR::IMTN_HeaderClass_FILEHDR: "
+//		     << "[" << dec << i << "]"
+//		     << " itemname=" << ptr->itemname
+//		     << " itemtype=" << ptr->itemtype
+//		     << " wordoffset=" << ptr->wordoffset
+//		     << " itemsize=" << ptr->itemsize
+//		     << endl;
+//	}
+}
+
+const IMTN_HeaderClass_FILEHDR_Entry *
+IMTN_HeaderClass_FILEHDR::operator[](const char *index) const
+{
+	Assert(index);
+	int i=0;
+	IMTN_HeaderClass_FILEHDR_Entry *ptr=entry;
+	while (i<nEntries && ptr && ptr->itemname && strcmp(ptr->itemname,index) != 0) { ++i; ++ptr; }
+	return i<nEntries ? entry+i : 0;
+}
+
+char *
+IMTN_HeaderClass_FILEHDR::IMTN_Method_ExtractTaggedString(const char *index) const
+{
+	const IMTN_HeaderClass_FILEHDR_Entry *ptr=(*this)[index];
+	char *s;
+	if (ptr && ptr->itemtype == 'B') {
+		s=new char[ptr->itemsize+1];
+		strncpy(s,data+(ptr->wordoffset-1)*2,ptr->itemsize);
+		s[ptr->itemsize]='\0';
+	}
+	else
+		s=0;
+
+	return s;
+}
+
+Int16
+IMTN_HeaderClass_FILEHDR::IMTN_Method_ExtractTaggedInteger(const char *index) const
+{
+	// Item size > 1 NYI
+	// ... IDEMAP itemtype=I wordoffset=79 itemsize=63
+
+	const IMTN_HeaderClass_FILEHDR_Entry *ptr=(*this)[index];
+	Uint16 u;
+	if (ptr && ptr->itemtype == 'I' && ptr->itemsize == 1) {
+		// little endian ...
+		// used unsigned char * else will sign extend :(
+		u=(*((unsigned char *)data+(ptr->wordoffset-1)*2+1) << 8)
+		 +(*((unsigned char *)data+(ptr->wordoffset-1)*2));
+	}
+	else
+		u=0xfffe;
+
+//cerr << "IMTN_HeaderClass_FILEHDR::IMTN_Method_ExtractTaggedInteger:"
+//     << " index=" << (index ? index : "")
+//     << " returns " << dec << u
+//     << endl;
+
+	return Int16(u);
+}
+
+Float64
+IMTN_HeaderClass_FILEHDR::IMTN_Method_ExtractTaggedFloat(const char *index) const
+{
+	// Item size > 1 NYI
+	// ... BOLTIM itemtype=F wordoffset=246 itemsize=2
+
+	const IMTN_HeaderClass_FILEHDR_Entry *ptr=(*this)[index];
+
+	if (ptr && ptr->itemtype == 'F' && ptr->itemsize == 1) {
+		return *(const Vax_Float_F *)(data+(ptr->wordoffset-1)*2);
+	}
+	else
+		return 9999;
+}
+
+/* ------------------------------ Slice Header ------------------------------ */
+
+IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR(istream *istr,
+		Uint16 nslices,
+		Uint16 slentries,Uint16 slcount,
+		Uint16 sltbposn,Uint16 sltbsize,
+		Uint16 blkslentries,Uint16 blksltbposn,
+		Uint16 blksltbdata)
+{
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start nslices=" << dec << nslices << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start slentries=" << dec << slentries << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start slcount=" << dec << slcount << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start sltbposn=" << dec << sltbposn << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start sltbsize=" << dec << sltbsize << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start blkslentries=" << dec << blkslentries << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start blksltbposn=" << dec << blksltbposn << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: start blksltbdata=" << dec << blksltbdata << endl;
+
+	(void)sltbsize;
+	(void)blkslentries;
+	(void)blksltbposn;
+
+	// Load the slice header parts ...
+
+	nEntries=0;
+	nSlices=0;
+
+	unsigned long offset=slentries*IMTN_BlockSize;
+	size_t length=slcount*sizeof(IMTN_HeaderClass_SLICEHDR_Entry);
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: entry offset=" << dec << offset << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: entry length=" << dec << length << endl;
+	Assert(sizeof(IMTN_HeaderClass_SLICEHDR_Entry) == 12);
+	entry=new IMTN_HeaderClass_SLICEHDR_Entry[slcount];
+	Assert(entry);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+
+	// Since the entries are 12 bytes and the blocks are 512 bytes,
+	// there are 42 entries per block, with 8 bytes of padding to
+	// prevent an entry spanning a block boundary (grump)
+
+	unsigned entriesleft=slcount;
+	const unsigned entriesperblock=IMTN_BlockSize/sizeof(IMTN_HeaderClass_SLICEHDR_Entry);
+	const unsigned npadbytes=IMTN_BlockSize-entriesperblock*sizeof(IMTN_HeaderClass_SLICEHDR_Entry);
+	Assert(entriesperblock == 42);
+	Assert(npadbytes == 8);
+	IMTN_HeaderClass_SLICEHDR_Entry *entryptr=entry;
+	while (entriesleft) {
+		unsigned entriesthistry=entriesleft > entriesperblock ? entriesperblock : entriesleft;
+
+		istr->read((char*)entryptr,entriesthistry*sizeof(IMTN_HeaderClass_SLICEHDR_Entry));
+		if (!istr->good()) return;
+
+		entriesleft-=entriesthistry;
+		entryptr+=entriesthistry;
+
+		char dummy[npadbytes];
+		istr->read(dummy,npadbytes);
+		if (!istr->good()) return;
+	}
+
+	// read the slice position table
+
+	offset=sltbposn*IMTN_BlockSize;
+	length=nslices*sizeof(Uint16_L);
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: position offset=" << dec << offset << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: position length=" << dec << length << endl;
+	sliceposition=new Uint16_L[nslices];
+	Assert(sliceposition);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+	
+	unsigned i;
+
+	istr->read((char *)sliceposition,length);
+	if (!istr->good()) return;
+
+//	for (i=0; i<nslices; ++i) {
+//		cerr << "sliceposition[" << dec << i << "]=" << dec << sliceposition[i] << endl;
+//	}
+
+	// read the offsets of the slice header data
+	// by dereferencing the slice position table block pointers
+
+	headerdata=new char *[nslices];
+	Assert(headerdata);
+
+	for (i=0; i<nslices; ++i) {
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: " 
+//     << "[" << dec << i << "]"
+//     << " dereference the slice position table block pointers"
+//     << endl;
+		// dereference the slice position table block pointers ...
+
+		offset=sliceposition[i]*IMTN_BlockSize;
+		length=blksltbdata*IMTN_BlockSize;
+		headerdata[i]=new char[length];
+
+//cerr << " sliceposition[i]=" << dec << sliceposition[i] << endl;
+//cerr << " offset=" << dec << offset << endl;
+//cerr << " blksltbdata=" << dec << blksltbdata << endl;
+//cerr << " length=" << dec << length << endl;
+
+		istr->seekg(offset,ios::beg);
+		if (!istr->good()) return;
+		istr->read(headerdata[i],length);
+		if (!istr->good()) return;
+	}
+
+	nEntries=slcount;
+	nSlices=nslices;
+
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: end nEntries=" << dec << nEntries << endl;
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: end nSlices=" << dec << nSlices << endl;
+
+	// Think about how caller handles errors ...
+	// see what ReadProprietaryHeader() would do
+
+//	IMTN_HeaderClass_SLICEHDR_Entry *ptr;
+//	for (i=0,ptr=entry; i<nEntries; ++i,++ptr) {
+//		cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: "
+//		     << "[" << dec << i << "]"
+//		     << " itemname=" << ptr->itemname
+//		     << " itemtype=" << ptr->itemtype
+//		     << " wordoffset=" << ptr->wordoffset
+//		     << " itemsize=" << ptr->itemsize
+//		     << endl;
+//	}
+
+//	for (i=0; i<nSlices; ++i) {
+//		cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_HeaderClass_SLICEHDR: " 
+//		     << "[" << dec << i << "]"
+//		     << " sliceposition=" << sliceposition[i]
+//		     << endl;
+//	}
+
+	// BTW. the first Uint16_L field of the headerdata for each slice
+	// is ISDATP which is 512 byte block offset to slice image data
+}
+
+const IMTN_HeaderClass_SLICEHDR_Entry *
+IMTN_HeaderClass_SLICEHDR::operator[](const char *index) const
+{
+	Assert(index);
+	int i=0;
+	IMTN_HeaderClass_SLICEHDR_Entry *ptr=entry;
+	while (i<nEntries && ptr && ptr->itemname && strcmp(ptr->itemname,index) != 0) { ++i; ++ptr; }
+	return i<nEntries ? entry+i : 0;
+}
+
+char *
+IMTN_HeaderClass_SLICEHDR::IMTN_Method_ExtractTaggedString(unsigned slice,const char *index) const
+{
+	Assert(slice < nSlices);
+	const IMTN_HeaderClass_SLICEHDR_Entry *ptr=(*this)[index];
+	char *s;
+	if (ptr && ptr->itemtype == 'B') {
+		s=new char[ptr->itemsize+1];
+		strncpy(s,headerdata[slice]+(ptr->wordoffset-1)*2,ptr->itemsize);
+		s[ptr->itemsize]='\0';
+	}
+	else
+		s=0;
+
+	return s;
+}
+
+Int16
+IMTN_HeaderClass_SLICEHDR::IMTN_Method_ExtractTaggedInteger(unsigned slice,const char *index) const
+{
+//cerr << "IMTN_HeaderClass_SLICEHDR::IMTN_Method_ExtractTaggedInteger:"
+//     << " nSlices=" << dec << nSlices
+//     << " slice=" << dec << slice
+//     << " index=" << (index ? index : "")
+//     << endl;
+	Assert(slice < nSlices);
+	// Item size > 1 NYI
+
+	const IMTN_HeaderClass_SLICEHDR_Entry *ptr=(*this)[index];
+	Uint16 u;
+	if (ptr && ptr->itemtype == 'I' && ptr->itemsize == 1) {
+		// little endian ...
+		// used unsigned char * else will sign extend :(
+		u=(*((unsigned char *)headerdata[slice]+(ptr->wordoffset-1)*2+1) << 8)
+		 +(*((unsigned char *)headerdata[slice]+(ptr->wordoffset-1)*2));
+	}
+	else
+		u=0xffe0;
+
+	return Int16(u);
+}
+
+Float64
+IMTN_HeaderClass_SLICEHDR::IMTN_Method_ExtractTaggedFloat(unsigned slice,const char *index) const
+{
+	Assert(slice < nSlices);
+	// Item size > 1 NYI
+
+	const IMTN_HeaderClass_SLICEHDR_Entry *ptr=(*this)[index];
+
+	if (ptr && ptr->itemtype == 'F' && ptr->itemsize == 1) {
+		return *(const Vax_Float_F *)(headerdata[slice]+(ptr->wordoffset-1)*2);
+	}
+	else
+		return 9999;
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtnhdrm.h b/libsrc/src/dconvert/imtn/imtnhdrm.h
new file mode 100644
index 0000000..857fdc7
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnhdrm.h
@@ -0,0 +1,55 @@
+/* imtnhdrm.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// Manually define classes to handle "method" based blocks
+// (equivalent to automatically generated stuff in imtnhdrp.h)
+
+struct IMTN_HeaderClass_FILEHDR_Entry {
+	char		itemname[7];
+	char 		itemtype;	// 'B' or'I' or 'F'
+	Uint16_L	wordoffset;	// from 1
+	Uint16_L	itemsize;	// number of itemtype elements
+};
+
+class IMTN_HeaderClass_FILEHDR {
+	IMTN_HeaderClass_FILEHDR_Entry *entry;
+	char *data;
+	unsigned nEntries;
+
+	const IMTN_HeaderClass_FILEHDR_Entry *operator[](const char *index) const;
+public:
+	IMTN_HeaderClass_FILEHDR(istream *ist,
+		Uint16 fhentries,Uint16 fhcount,
+		Uint16 fhdata,Uint16 blkfhdata); // Defined in imtnhdrc.cc
+
+	char   *IMTN_Method_ExtractTaggedString (const char *index) const;
+	Int16   IMTN_Method_ExtractTaggedInteger(const char *index) const;
+	Float64 IMTN_Method_ExtractTaggedFloat  (const char *index) const;
+};
+
+struct IMTN_HeaderClass_SLICEHDR_Entry {
+	char		itemname[7];
+	char 		itemtype;	// 'B' or'I' or 'F'
+	Uint16_L	wordoffset;	// from 1
+	Uint16_L	itemsize;	// number of itemtype elements
+};
+
+class IMTN_HeaderClass_SLICEHDR {
+	IMTN_HeaderClass_SLICEHDR_Entry *entry;
+	Uint16_L *sliceposition;
+	char **headerdata;
+	unsigned nEntries;
+	unsigned nSlices;
+
+	const IMTN_HeaderClass_SLICEHDR_Entry *operator[](const char *index) const;
+public:
+	IMTN_HeaderClass_SLICEHDR(istream *ist,
+		Uint16 nslices,
+		Uint16 slentries,Uint16 slcount,
+		Uint16 sltbposn,Uint16 sltbsize,
+		Uint16 blkslentries,Uint16 blksltbposn,
+		Uint16 blksltbdata); // Defined in imtnhdrc.cc
+
+	char   *IMTN_Method_ExtractTaggedString (unsigned slice,const char *index) const;
+	Int16   IMTN_Method_ExtractTaggedInteger(unsigned slice,const char *index) const;
+	Float64 IMTN_Method_ExtractTaggedFloat  (unsigned slice,const char *index) const;
+};
+
diff --git a/libsrc/src/dconvert/imtn/imtnmdt.cc b/libsrc/src/dconvert/imtn/imtnmdt.cc
new file mode 100644
index 0000000..1e779fa
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnmdt.cc
@@ -0,0 +1,56 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtnmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "imtndc.h"
+#include "elmconst.h"
+
+void 
+IMTN_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Date thedate=Date(String_Use(IMTN_HeaderInstance_FILEHDR->
+			IMTN_Method_ExtractTaggedString("IADATE")));
+
+	Time thetime=Time(String_Use(IMTN_HeaderInstance_FILEHDR->
+			IMTN_Method_ExtractTaggedString("IATIME")));
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),thedate);
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),thetime);
+
+	// SeriesDate
+
+	(*list)+=new DateStringAttribute(TagFromName(SeriesDate),thedate);
+
+	// SeriesTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(SeriesTime),thetime);
+
+	// AcquisitionDate
+
+	(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),thedate);
+
+	// AcquisitionTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),thetime);
+
+	// ContentDate (formerly Image)
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),thedate);
+
+	// ContentTime (formerly Image) ... won't wrap around 24 hours :(
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+		Time(Uint32(thetime)
+		   + Uint32(IMTN_HeaderInstance_SLICEHDR->
+			IMTN_Method_ExtractTaggedFloat(imagenumber,"ELAPSE")*1000)
+		));
+
+	// PatientBirthDate
+
+	(*list)+=new DateStringAttribute(TagFromName(PatientBirthDate),
+		Date(String_Use(IMTN_HeaderInstance_FILEHDR->
+			IMTN_Method_ExtractTaggedString("IBDATE"))));
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtnmmsc.cc b/libsrc/src/dconvert/imtn/imtnmmsc.cc
new file mode 100644
index 0000000..3a0420b
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnmmsc.cc
@@ -0,0 +1,192 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtnmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "imtndc.h"
+#include "elmconst.h"
+
+void 
+IMTN_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	ostrstream imagecommentstream;
+
+	// ImageType
+
+	const char *value1,*value2,*value3;
+
+	int istudy=IMTN_HeaderInstance_FILEHDR->IMTN_Method_ExtractTaggedInteger("ISTUDY");
+	imagecommentstream << "ISTUDY == " << dec << istudy << " is ";
+
+	switch (istudy) {
+		case  1:	// localization
+			imagecommentstream << "LOCALIZATION";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="LOCALIZER";
+			break;
+		case  2:	// flow study
+			imagecommentstream << "FLOW STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  3:	// movie study
+			imagecommentstream << "MOVIE STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  4:	// average volume study
+			imagecommentstream << "AVERAGE VOLUME STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  5:	// volume study
+			imagecommentstream << "VOLUME STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  6:	// average flow study
+			imagecommentstream << "AVERAGE FLOW STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  7:	// continuous volume study
+			imagecommentstream << "CONTNUOUS VOLUME STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  51:	// image averaging
+			imagecommentstream << "IMAGE AVERAGING";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  52:	// reformat
+			imagecommentstream << "REFORMAT";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="REFORMAT";			// my own :(
+			break;
+		case  53:	// FIP Maximum Difference
+			imagecommentstream << "FIP MAXIMUM DIFFERENCE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  54:	// FIP Time to Peak
+			imagecommentstream << "FIP TIME TO PEAK";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  55:	// FIP Area Under Curve
+			imagecommentstream << "FIP AREA UNDER CURVE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  56:	// FIP Center of Mass
+			imagecommentstream << "FIP CENTER OF MASS";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+
+		case  102:	// image subtraction flow
+			imagecommentstream << "IMAGE SUBTRACTION FLOW";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  103:	// image subtraction movie
+			imagecommentstream << "IMAGE SUBTRACTION MOVIE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  105:	// image subtraction volume
+			imagecommentstream << "IMAGE SUBTRACTION VOLUME";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  106:	// image subtraction average flow
+			imagecommentstream << "IMAGE SUBTRACTION AVERAGE FLOW";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+
+		case -1:	// screen save
+			imagecommentstream << "SCREEN SAVE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  0:	// special
+			imagecommentstream << "SPECIAL CASE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		default:
+			imagecommentstream << "UNRECOGNIZED";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+	}
+
+	(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+		value1,value2,value3);
+
+	imagecommentstream << ", ";
+
+	// RotationDirection
+
+	const char *rotationdirection;
+
+	switch(IMTN_HeaderInstance_SLICEHDR->
+			IMTN_Method_ExtractTaggedInteger(imagenumber,"IROTA")) {
+		case -1:	rotationdirection="CC"; break;
+		case  1:	rotationdirection="CW"; break;
+		default:	rotationdirection="";   break;
+	}
+
+	(*list)+=new CodeStringAttribute(TagFromName(RotationDirection),rotationdirection);
+
+	// ExposureTime
+
+	// derive from number of DAS samples per detector per source fan
+	// and number of averages per slice
+
+	Float64 exposuretime;
+	Float64 numberofaveragesperslice=IMTN_HeaderInstance_FILEHDR->IMTN_Method_ExtractTaggedInteger("NSLAVG");
+
+	int irep=IMTN_HeaderInstance_FILEHDR->IMTN_Method_ExtractTaggedInteger("IREP");
+	imagecommentstream << "IREP == " << dec << irep << " is ";
+
+	switch (irep) {
+		case 3:	// Multi-Slice Mode
+			imagecommentstream << "MULTI-SLICE MODE";
+			exposuretime=50*numberofaveragesperslice;
+			break;
+		case 6:	// Single-Slice Mode
+			imagecommentstream << "SINGLE-SLICE MODE";
+			exposuretime=100*numberofaveragesperslice;
+			break;
+		default:
+			imagecommentstream << "UNRECOGNIZED MODE";
+			exposuretime=0;
+			break;
+	}
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ExposureTime),exposuretime);
+
+	char *imagecommentstring=imagecommentstream.str();
+	(*list)+=new LongTextAttribute(TagFromName(ImageComments),imagecommentstring);
+	if (imagecommentstring) delete[] imagecommentstring;
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtnmpln.cc b/libsrc/src/dconvert/imtn/imtnmpln.cc
new file mode 100644
index 0000000..61d6006
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnmpln.cc
@@ -0,0 +1,224 @@
+static const char *CopyrightIdentifier(void) { return "@(#)imtnmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "imtndc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+IMTN_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	// PixelSpacing
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		IMTN_HeaderInstance_FILEHDR->
+			IMTN_Method_ExtractTaggedFloat("PIXLEN"),
+		IMTN_HeaderInstance_FILEHDR->
+			IMTN_Method_ExtractTaggedFloat("PIXLEN"));
+
+	// ZoomFactor
+
+	double zoomfactor=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedFloat(imagenumber,"ZOOM");
+
+	if (fabs(zoomfactor) < .0001) zoomfactor=1;	// ie. zero
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomFactor),zoomfactor,zoomfactor);
+
+	// ZoomCenter
+
+	double reconcenterhorizontal=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedFloat(imagenumber,"XORG");
+	double reconcentervertical  =IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedFloat(imagenumber,"YORG");
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomCenter),reconcenterhorizontal,reconcentervertical);
+
+	// SliceLocation
+
+	double slicelocation=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedInteger(imagenumber,"INOUT")/10.0;
+
+	int irep=IMTN_HeaderInstance_FILEHDR->IMTN_Method_ExtractTaggedInteger("IREP");
+	if (irep == 3) {
+		// Multi-Slice mode
+		double targetoffset;
+		int target=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedInteger(imagenumber,"ITARGET");
+		switch (target) {
+			case 'A':	targetoffset=40;
+					break;
+			case 'B':	targetoffset=20;
+					break;
+			case 'C':	targetoffset=0;
+					break;
+			case 'D':	targetoffset=-20;
+					break;
+			default:	// blech :(
+					targetoffset=0;
+					break;
+		}
+		int ring=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedInteger(imagenumber,"IRING");
+		double detectoroffset=(ring%2)*8;
+
+		slicelocation+=targetoffset+detectoroffset;
+	}
+	// assume IREP == 6, Single-Slice mode, which just uses INOUT and is relative to Target C, Detector Ring 2
+
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),slicelocation);
+
+	// Trying to derive Image Plane Module ...
+
+	ImagePlanePlane plane=Axial;
+
+	char *hfff,*ap;
+	ImagePlaneHeadFeet orientation;
+	ImagePlanePosition position;
+
+	// The Imatron may already have flipped the image pixel data,
+	// so record the position and orientation in the descriptive DICOM tags
+	// but tell the ImagePlane module generator the flipped not the physical position
+
+	// Is this going to mess up the relationship between machine plane and patient plane ?
+
+	switch (IMTN_HeaderInstance_SLICEHDR->
+			IMTN_Method_ExtractTaggedInteger(imagenumber,"IPATOR")) {
+
+		case -5:	// Supine feet first, flipped to match supine head first
+			ap="S";
+			position=Supine;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case -6:	// Prone feet first, flipped to match prone head first
+			ap="P";
+			position=Prone;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case -7:	// Decubitus right feet first, flipped to match decubitus right head first
+			ap="DR";
+			position=RightLateralDecubitus;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case -8:	// Decubitus left feet first, flipped to match decubitus left head first
+			ap="DL";
+			position=LeftLateralDecubitus;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case  -1:	// Supine feet first
+			ap="S";
+			position=Supine;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+
+		case  -2:	// Prone feet first
+			ap="P";
+			position=Prone;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+
+		case  -3:	// Decubitus right feet first
+			ap="DR";
+			position=RightLateralDecubitus;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+
+		case  -4:	// Decubitus left feet first
+			ap="DL";
+			position=LeftLateralDecubitus;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+		case  1:	// Supine head first
+			ap="S";
+			position=Supine;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  2:	// Prone head first
+			ap="P";
+			position=Prone;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  3:	// Decubitus right head first
+			ap="DR";
+			position=RightLateralDecubitus;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  4:	// Decubitus left head first
+			ap="DL";
+			position=LeftLateralDecubitus;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  5:	// Prone head first flipped (assume to match supine ? not specified in format)
+			ap="P";
+			position=Supine;	// Not Prone ... already flipped
+			hfff="HF";
+			orientation=HeadFirst;
+
+		case  0:	// Special case :(
+			Assert(0);
+			ap="S";
+			position=Supine;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+	}
+
+	double scanfov=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedFloat(imagenumber,"PICRAD");
+
+	// Make a model of the image plane ...
+
+	ImagePlane imageplane(plane,scanfov,orientation,position);
+
+	// While we are in the "display" or "gantry plane ...
+	// (before angulation) 
+
+	// Apply any transformations specified in the
+	// display/gantry plane, such as magnification and
+	// reconstruction target offsets ...
+
+	// Assume that these are machine rather than body relative	DON'T KNOW IF THIS IS CORRECT :(
+
+//	imageplane.MachinePlane::scale(zoomfactor);			// Leave out - assume for now that PICRAD is DFOV
+
+	// Always axial so X and Y are really X and Y
+	// Don't forget sign changes ...				DON'T KNOW IF THIS IS CORRECT :(
+
+	Vector3D reconoffset(reconcenterhorizontal,reconcentervertical,0);
+
+	imageplane.MachinePlane::shift(reconoffset);
+
+	// Account for angulation ...
+
+	double gantrytilt=IMTN_HeaderInstance_SLICEHDR->IMTN_Method_ExtractTaggedInteger(imagenumber,"ITILT");
+
+	// +ve is top towards table					DON'T KNOW IF THIS IS CORRECT :(
+	imageplane.MachinePlane::angle(LeftRight,gantrytilt);
+
+	// Account for physical offsets after angulation
+
+	// Assume no sign difference Imtn vs. Dicom for Z		DON'T KNOW IF THIS IS CORRECT :(
+	// Assume that these are machine rather than body relative	DON'T KNOW IF THIS IS CORRECT :(
+
+	Vector3D offset(0,0,slicelocation);
+	imageplane.MachinePlane::shift(offset);
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),String_Cat_Use(hfff,ap));
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+}
+
diff --git a/libsrc/src/dconvert/imtn/imtnptrs.h b/libsrc/src/dconvert/imtn/imtnptrs.h
new file mode 100644
index 0000000..3302b94
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnptrs.h
@@ -0,0 +1,23 @@
+/* imtnptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	IMTN_Offset_MAINHDR_ptr	0
+
+// note the comma preceeding the constructor args ...
+
+#define	IMTN_MethodConstructorArgs_FILEHDR			\
+		,IMTN_HeaderInstance_MAINHDR->FHENTRIES,	\
+		 IMTN_HeaderInstance_MAINHDR->FHCOUNT,		\
+		 IMTN_HeaderInstance_MAINHDR->FHDATA,		\
+		 IMTN_HeaderInstance_MAINHDR->BLKFHDATA
+
+#define	IMTN_MethodConstructorArgs_SLICEHDR			\
+		,IMTN_HeaderInstance_FILEHDR->IMTN_Method_ExtractTaggedInteger("NSLICE"),	\
+		 IMTN_HeaderInstance_MAINHDR->SLENTRIES,	\
+		 IMTN_HeaderInstance_MAINHDR->SLCOUNT,		\
+		 IMTN_HeaderInstance_MAINHDR->SLTBPOSN,		\
+		 IMTN_HeaderInstance_MAINHDR->SLTBSIZE,  	\
+		 IMTN_HeaderInstance_MAINHDR->BLKSLENTRIES,	\
+		 IMTN_HeaderInstance_MAINHDR->BLKSLTBPOSN,	\
+		 IMTN_HeaderInstance_MAINHDR->BLKSLTBDATA
+
+#define	IMTN_Offset_PixelData_ptr	(imtnhdr->IMTN_HeaderInstance_SLICEHDR \
+		->IMTN_Method_ExtractTaggedInteger(imagenumber,"ISDATP")*512)
diff --git a/libsrc/src/dconvert/imtn/imtnsrc.h b/libsrc/src/dconvert/imtn/imtnsrc.h
new file mode 100644
index 0000000..cfc9e29
--- /dev/null
+++ b/libsrc/src/dconvert/imtn/imtnsrc.h
@@ -0,0 +1,61 @@
+/* imtnsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_imtnsrc__
+#define __Header_imtnsrc__
+
+class IMTN_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	IMTN_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~IMTN_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Little endian ...
+				Uint16 pixel;
+				pixel=(bytes[1]<<8)|bytes[0];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_imtnsrc__
diff --git a/libsrc/src/dconvert/pace/Imakefile b/libsrc/src/dconvert/pace/Imakefile
new file mode 100755
index 0000000..76419a1
--- /dev/null
+++ b/libsrc/src/dconvert/pace/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = pacedc.cc paceconv.cc pacempln.cc \
+		 pacemmsc.cc pacemdt.cc \
+		 pacedmp.cc pacedmpf.cc \
+		 pacehdrc.cc pace.cc
+
+OBJS = 		 pacedc.o  paceconv.o  pacempln.o  \
+		 pacemmsc.o  pacemdt.o  \
+		 pacedmp.o  pacedmpf.o  \
+		 pacehdrc.o  pace.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdpace.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(pace,dconvert)
+
+ProjectConvertTemplate(pacehdrp.h,pace,convert,prefix=PACE_ role=headerpart offsetwarning=off)
+ProjectConvertTemplate(pacehdrw.h,pace,convert,prefix=PACE_ role=wholeheader)
+ProjectConvertTemplate(pacehdrc.h,pace,convert,prefix=PACE_ role=constructheader)
+ProjectConvertTemplate(paceconv.h,pace,convert,prefix=PACE_ role=dicom)
+ProjectConvertTemplate(pacedmpf.h,pace,convert,prefix=PACE_ role=dump)
+
+pacedmpf.o: pacedmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) pacedmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/pace/pace.cc b/libsrc/src/dconvert/pace/pace.cc
new file mode 100644
index 0000000..b5bd630
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pace.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pace.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "pace.h"
+#include "pacecl.h"
+#include "srcsink.h"
+#include "pacesrc.h"
+
+PACE_Conversion::PACE_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	pacehdr=0;
+	pixeldatasrc=0;
+}
+
+PACE_Conversion::~PACE_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (pacehdr) delete pacehdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/pace/pace.h b/libsrc/src/dconvert/pace/pace.h
new file mode 100644
index 0000000..c3732c4
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pace.h
@@ -0,0 +1,45 @@
+/* pace.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_pace__
+#define __Header_pace__
+
+// NB. a PACE_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~PACE_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class PACE_Header_BothClass;
+class PACE_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class PACE_Conversion {
+	PACE_Header_BothClass *pacehdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	PACE_PixelDataSource *pixeldatasrc;
+public:
+	PACE_Conversion(istream &i,ostream &e);
+
+	virtual ~PACE_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0)
+		{
+			(void)out; (void)imagenumber;
+			return true;
+		}
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_pace__ */
+
diff --git a/libsrc/src/dconvert/pace/pace.tpl b/libsrc/src/dconvert/pace/pace.tpl
new file mode 100755
index 0000000..e8250d2
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pace.tpl
@@ -0,0 +1,222 @@
+# Offsets are in bytes from 0
+
+# Lengths are in intype words
+
+# Block sizes are 1024 bytes (for image header)
+
+# data types are shared with Sytec
+
+block="STDHDR"	offset="0"	intype="String"	inlength="4"	keyword="STUDY"		dicomtype="?"	dicomtag="?"	# Eyecatcher !STD
+block="STDHDR"	offset="6"	intype="Uint8"	inlength="1"	keyword="SMODELNO_Mod"	dicomtype="?"	dicomtag="?"	enum="1=CT,2=MR,3=Reserved"	# Model Number of Device - Modality
+block="STDHDR"	offset="7"	intype="Uint8"	inlength="1"	keyword="SMODELNO_Mac"	dicomtype="?"	dicomtag="?"	enum="1=CT8600,2=CT8800,3=CT9000,4=EMI,5=ImageMax,6=Resona(MR MAX),7=Quantex(Pace),8=Reserved"	# Model Number of Device - Machine
+block="STDHDR"	offset="8"	intype="Uint16_B"	inlength="1"	keyword="SMACHINE"	dicomtype="LO"	dicomtag="DeviceSerialNumber"	# Manufacturers Serial Number
+block="STDHDR"	offset="10"	intype="String"	inlength="5"	keyword="SSTUDYNO"	dicomtype="SH"	dicomtag="StudyID"	# Study Number
+block="STDHDR"	offset="16"	intype="String_Date_YMD"	inlength="10"	keyword="SDATE"		dicomtype="?"	dicomtag="?"	# Study Date yyyy/mm/dd
+block="STDHDR"	offset="26"	intype="String_Time"	inlength="12"	keyword="STIME"		dicomtype="?"	dicomtag="?"	# Study Time hh/mm/ss.xxx
+block="STDHDR"	offset="38"	intype="String"	inlength="12"	keyword="SPATID"	dicomtype="LO"	dicomtag="PatientID"	# Patient ID
+block="STDHDR"	offset="54"	intype="String"	inlength="12"	keyword="SPATNAME"	dicomtype="PN"	dicomtag="PatientName"	# Patient Name
+block="STDHDR"	offset="80"	intype="String"	inlength="6"	keyword="SAGE"		dicomtype="?"	dicomtag="?"	# Patient Age yyy;mm
+block="STDHDR"	offset="86"	intype="String"	inlength="5"	keyword="SWEIGHT"	dicomtype="DS"	dicomtag="PatientWeight"	# Patient weight kg
+block="STDHDR"	offset="92"	intype="String"	inlength="2"	keyword="SSEX"		dicomtype="CS"	dicomtag="PatientSex"	enum="'M '=Male,'F '=Female"	# Patient sex
+block="STDHDR"	offset="96"	intype="String"	inlength="24"	keyword="SMAKER"	dicomtype="LO"	dicomtag="Manufacturer"			# Manufacturers name
+block="STDHDR"	offset="120"	intype="String"	inlength="14"	keyword="SMODELNM"	dicomtype="LO"	dicomtag="ManufacturerModelName"	# Model name
+block="STDHDR"	offset="144"	intype="String"	inlength="32"	keyword="SHOSP"		dicomtype="LO"	dicomtag="InstitutionName"		# Hospital name
+block="STDHDR"	offset="176"	intype="Uint8"	inlength="1"	keyword="SSYSVNO"	dicomtype="?"	dicomtag="?"	# System version
+block="STDHDR"	offset="177"	intype="Uint8"	inlength="1"	keyword="SSYSRNO"	dicomtype="?"	dicomtag="?"	# System revision
+block="STDHDR"	offset="178"	intype="Uint8"	inlength="1"	keyword="SDATVNO"	dicomtype="?"	dicomtag="?"	# Database version
+block="STDHDR"	offset="179"	intype="Uint8"	inlength="1"	keyword="SDATRNO"	dicomtype="?"	dicomtag="?"	# Database revision
+block="STDHDR"	offset="180"	intype="Uint16_B"	inlength="1"	keyword="SATFRB"	dicomtype="?"	dicomtag="?"	bitmap="0:none,SATNOWT;1:none,SATDUMP;2:none,SATOLD;3:none,SATOFF;4:none,SATNODL"	# Study attributes
+block="STDHDR"	offset="188"	intype="String"	inlength="4"	keyword="SENHANCE"	dicomtype="?"	dicomtag="?"	enum="'NO C'=No Contrast,'+C  '=With Contrast"	# Contrast media
+block="STDHDR"	offset="206"	intype="Pace_Date"	inlength="1"	keyword="SDATEOD"	dicomtype="?"	dicomtag="?"	# Optical Disk: Date for identification check of image number
+block="STDHDR"	offset="210"	intype="Time_Milliseconds_B"	inlength="1"	keyword="STIMEOD"	dicomtype="?"	dicomtag="?"	# Optical Disk: Time for identification check of image number
+block="STDHDR"	offset="214"	intype="Uint32_B"	inlength="1"	keyword="SSELFOD"	dicomtype="?"	dicomtag="?"	# Optical Disk: Number of start sectors in study information file
+block="STDHDR"	offset="218"	intype="Uint16_B"	inlength="1"	keyword="SNOBLK"	dicomtype="?"	dicomtag="?"	# Number of image information blocks
+block="STDHDR"	offset="220"	intype="String"	inlength="4"	keyword="SIMINFFL_Vol"	dicomtype="?"	dicomtag="?"	# File name of image information - volume name
+block="STDHDR"	offset="224"	intype="Uint16_B"	inlength="1"	keyword="SIMINFFL_User"	dicomtype="?"	dicomtag="?"	# File name of image information - user number
+block="STDHDR"	offset="226"	intype="String"	inlength="8"	keyword="SIMINFFL_Cat"	dicomtype="?"	dicomtag="?"	# File name of image information - catalog name
+block="STDHDR"	offset="234"	intype="String"	inlength="8"	keyword="SIMINFFL_File"	dicomtype="?"	dicomtag="?"	# File name of image information - file name
+block="STDHDR"	offset="242"	intype="String"	inlength="2"	keyword="SIMINFFL_Ext"	dicomtype="?"	dicomtag="?"	# File name of image information - extension
+block="STDHDR"	offset="244"	intype="Uint32_B"	inlength="1"	keyword="SPOINTIM"	dicomtype="?"	dicomtag="?"	# Relative sector number of image information
+block="STDHDR"	offset="248"	intype="Uint16_B"	inlength="1"	keyword="SNOSER"	dicomtype="IS"	dicomtag="SeriesInStudy"	# Number of series in study
+block="STDHDR"	offset="250"	intype="Uint16_B"	inlength="1"	keyword="SNOACQ"	dicomtype="IS"	dicomtag="AcquisitionsInStudy"	# Number of acquisitions in study
+block="STDHDR"	offset="252"	intype="Uint16_B"	inlength="1"	keyword="SNOIMG"	dicomtype="IS"	dicomtag="ImagesInAcquisition"	# Number of images in study
+block="STDHDR"	offset="254"	intype="Uint16_B"	inlength="1"	keyword="SNEXTOD"	dicomtype="?"	dicomtag="?"	# Optical Disk: Start sector to write next image
+block="STDHDR"	offset="256"	intype="String"	inlength="50"	keyword="SDESC1"	dicomtype="?"	dicomtag="?"	# Study description - line 1
+block="STDHDR"	offset="306"	intype="String"	inlength="50"	keyword="SDESC2"	dicomtype="?"	dicomtag="?"	# Study description - line 2
+block="STDHDR"	offset="356"	intype="String"	inlength="50"	keyword="SDESC3"	dicomtype="?"	dicomtag="?"	# Study description - line 3
+block="STDHDR"	offset="406"	intype="String"	inlength="50"	keyword="SDESC4"	dicomtype="?"	dicomtag="?"	# Study description - line 4
+block="STDHDR"	offset="456"	intype="String"	inlength="50"	keyword="SDESC5"	dicomtype="?"	dicomtag="?"	# Study description - line 5
+
+block="IMGHDR"	offset="0"	intype="String"	inlength="4"	keyword="IMAGE"		dicomtype="?"	dicomtag="?"	# Eyecatcher !IMG
+block="IMGHDR"	offset="4"	intype="Uint16_B"	inlength="1"	keyword="IBLOCK"	dicomtype="?"	dicomtag="?"	# Number of blocks of image information
+block="IMGHDR"	offset="6"	intype="Uint8"	inlength="1"	keyword="IMODELNO_Mod"	dicomtype="?"	dicomtag="?"	enum="1=CT,2=MR,3=Reserved"	# Model Number of Device - Modality
+block="IMGHDR"	offset="7"	intype="Uint8"	inlength="1"	keyword="IMODELNO_Mac"	dicomtype="?"	dicomtag="?"	enum="1=CT8600,2=CT8800,3=CT9000,4=EMI,5=ImageMax,6=Resona(MR MAX),7=Quantex(Pace),8=Reserved"	# Model Number of Device - Machine
+block="IMGHDR"	offset="8"	intype="Uint16_B"	inlength="1"	keyword="IMACHINE"	dicomtype="?"	dicomtag="?"	# Manufacturers Serial Number
+block="IMGHDR"	offset="10"	intype="String"	inlength="5"	keyword="ISTUDYNO"	dicomtype="?"	dicomtag="?"	# Study Number
+block="IMGHDR"	offset="16"	intype="String"	inlength="2"	keyword="ISERNO"	dicomtype="IS"	dicomtag="SeriesNumber"	# Series Number
+block="IMGHDR"	offset="18"	intype="String"	inlength="2"	keyword="IACQNO"	dicomtype="IS"	dicomtag="AcquisitionNumber"	# Acquisition Number
+block="IMGHDR"	offset="20"	intype="String"	inlength="2"	keyword="IIMGNO"	dicomtype="IS"	dicomtag="InstanceNumber"	# Image Number
+block="IMGHDR"	offset="28"	intype="Uint8"	inlength="1"	keyword="ISYSVNO"	dicomtype="?"	dicomtag="?"	# System version
+block="IMGHDR"	offset="29"	intype="Uint8"	inlength="1"	keyword="ISYSRNO"	dicomtype="?"	dicomtag="?"	# System revision
+block="IMGHDR"	offset="30"	intype="Uint8"	inlength="1"	keyword="IDATVNO"	dicomtype="?"	dicomtag="?"	# Database version
+block="IMGHDR"	offset="31"	intype="Uint8"	inlength="1"	keyword="IDATRNO"	dicomtype="?"	dicomtag="?"	# Database revision
+block="IMGHDR"	offset="32"	intype="String_Date_YMD"	inlength="10"	keyword="IDATE"		dicomtype="?"	dicomtag="?"	# Image Date yyyy/mm/dd
+block="IMGHDR"	offset="42"	intype="String_Time"	inlength="12"	keyword="ITIME"		dicomtype="?"	dicomtag="?"	# Image Time hh/mm/ss.xxx
+block="IMGHDR"	offset="64"	intype="String"	inlength="2"	keyword="IHFFIRST"	dicomtype="?"	dicomtag="?"	enum="'H '=Head First,'F '=Feet First"	#  Patient position
+block="IMGHDR"	offset="66"	intype="String"	inlength="2"	keyword="IPATORI"	dicomtype="?"	dicomtag="?"	enum="'SP'=Supine,'PR'=Prone,'LL'=Left Lateral Decubitus,'RL'=Right Lateral Decubitus,'OT'=Other"	# Patient orientation
+block="IMGHDR"	offset="68"	intype="String"	inlength="6"	keyword="IANATOMY"	dicomtype="CS"	dicomtag="BodyPartExamined"	# Anatomic location
+block="IMGHDR"	offset="74"	intype="String"	inlength="2"	keyword="IAREFHF"	dicomtype="LO"	dicomtag="PositionReferenceIndicator"	# Anatomic reference HF
+block="IMGHDR"	offset="76"	intype="String"	inlength="2"	keyword="IAREFAP"	dicomtype="?"	dicomtag="?"	# Anatomic reference AP
+block="IMGHDR"	offset="78"	intype="String"	inlength="2"	keyword="IAREFLR"	dicomtype="?"	dicomtag="?"	# Anatomic reference LR
+block="IMGHDR"	offset="80"	intype="String"	inlength="4"	keyword="IPLANE"	dicomtype="?"	dicomtag="?"	enum="'AX  '=Axial,'SAG '=Sagittal,'COR '=Coronal"	# Datum plane
+block="IMGHDR"	offset="84"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISLPOSHF"	dicomtype="?"	dicomtag="?"	# Slice position by body coords HF mm
+block="IMGHDR"	offset="88"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISLPOSAP"	dicomtype="?"	dicomtag="?"	# Slice position by body coords AP mm
+block="IMGHDR"	offset="92"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISLPOSLR"	dicomtype="?"	dicomtag="?"	# Slice position by body coords LR mm
+block="IMGHDR"	offset="96"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISCENTX"	dicomtype="?"	dicomtag="?"	# Scan center by machine coords X mm
+block="IMGHDR"	offset="100"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISCENTY"	dicomtype="?"	dicomtag="?"	# Scan center by machine coords Y mm
+block="IMGHDR"	offset="104"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISCENTZ"	dicomtype="?"	dicomtag="?"	# Scan center by machine coords Z mm
+block="IMGHDR"	offset="108"	intype="String"	inlength="4"	keyword="ISFOV"		dicomtype="?"	dicomtag="?"	# Scan fov cm
+block="IMGHDR"	offset="112"	intype="String"	inlength="4"	keyword="ISTHICK"	dicomtype="DS"	dicomtag="SliceThickness"	# Scan thickness mm
+block="IMGHDR"	offset="124"	intype="IEEE_Float32_B"	inlength="1"	keyword="ITBLPOS"	dicomtype="?"	dicomtag="?"	# Table position measured from gantry (machine coords)
+block="IMGHDR"	offset="128"	intype="String"	inlength="6"	keyword="ISCANSEQ"	dicomtype="?"	dicomtag="?"	# Scan sequence
+block="IMGHDR"	offset="144"	intype="String"	inlength="5"	keyword="ISCANTM"	dicomtype="?"	dicomtag="?"	# Scan time CT xxx.x seconds MR mm:ss
+block="IMGHDR"	offset="150"	intype="String"	inlength="4"	keyword="IMTYPE"	dicomtype="?"	dicomtag="?"	# Image type
+block="IMGHDR"	offset="160"	intype="String"	inlength="4"	keyword="IENHANCE"	dicomtype="?"	dicomtag="?"	enum="'NO C'=No Contrast,'+C  '=With Contrast"	# Contrast media
+block="IMGHDR"	offset="164"	intype="String_Time"	inlength="12"	keyword="ICETIME"	dicomtype="?"	dicomtag="?"	# Start Injection Time hh/mm/ss.xxx
+block="IMGHDR"	offset="176"	intype="String"	inlength="4"	keyword="IGENPOW"	dicomtype="?"	dicomtag="?"	# Generator power CT xx.x kW MR xxxx W
+block="IMGHDR"	offset="180"	intype="String"	inlength="4"	keyword="ITRIGGER"	dicomtype="?"	dicomtag="?"	# Trigger time: start of R wave to first data mS
+block="IMGHDR"	offset="188"	intype="Uint16_B"	inlength="1"	keyword="IOVERCNT"	dicomtype="?"	dicomtag="?"	# Over range count
+block="IMGHDR"	offset="190"	intype="Uint16_B"	inlength="1"	keyword="IZEROCNT"	dicomtype="?"	dicomtag="?"	# Zero detect count
+
+block="CTHDR"  condition="isct"	offset="0"	intype="IEEE_Float32_B"	inlength="1"	keyword="ITBLHGT"	dicomtype="?"	dicomtag="?"	# Table height machine coords mm
+block="CTHDR"  condition="isct"	offset="4"	intype="String"	inlength="3"	keyword="IAZIMUTH"	dicomtype="?"	dicomtag="?"	# Azimuth of scout degrees
+block="CTHDR"  condition="isct"	offset="8"	intype="String"	inlength="5"	keyword="IGTILT"	dicomtype="DS"	dicomtag="GantryDetectorTilt"	# Gantry tilt machine coords degrees
+block="CTHDR"  condition="isct"	offset="16"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISCSTAPS"	dicomtype="?"	dicomtag="?"	# Initial location at scout body coords mm
+block="CTHDR"  condition="isct"	offset="20"	intype="IEEE_Float32_B"	inlength="1"	keyword="ISCENDPS"	dicomtype="?"	dicomtag="?"	# Final location at scout body coords mm
+block="CTHDR"  condition="isct"	offset="24"	intype="String"	inlength="5"	keyword="IGTILTB"	dicomtype="?"	dicomtag="?"	# Gantry tilt body coords degrees
+block="CTHDR"  condition="isct"	offset="32"	intype="String"	inlength="5"	keyword="IEXPTIME"	dicomtype="IS"	dicomtag="ExposureTime"	# Exposure time ms
+block="CTHDR"  condition="isct"	offset="38"	intype="String"	inlength="3"	keyword="IEXPRATE"	dicomtype="IS"	dicomtag="XRayTubeCurrent"	# Tube current mA
+block="CTHDR"  condition="isct"	offset="42"	intype="String"	inlength="5"	keyword="IEXPOSE"	dicomtype="IS"	dicomtag="Exposure"	# Exposure mAS
+block="CTHDR"  condition="isct"	offset="48"	intype="String"	inlength="3"	keyword="IKVP"		dicomtype="DS"	dicomtag="KVP"	# Generator output
+block="CTHDR"  condition="isct"	offset="52"	intype="String"	inlength="2"	keyword="IROTDIR"	dicomtype="CS"	dicomtag="RotationDirection"	enum="'CW'=Clockwise,'CC'=CounterClockwise"	# Direction of rotation
+block="CTHDR"  condition="isct"	offset="54"	intype="String"	inlength="1"	keyword="IFILTER"	dicomtype="SH"	dicomtag="FilterType"	# XRay filter
+block="CTHDR"  condition="isct"	offset="56"	intype="Pace_Date"	inlength="1"	keyword="IDATEC"	dicomtype="?"	dicomtag="?"	# Middle date of scan
+block="CTHDR"  condition="isct"	offset="60"	intype="Time_Milliseconds_B"	inlength="1"	keyword="ITIMEC"	dicomtype="?"	dicomtag="?"	# Middle time of scan
+
+block="MRHDR"  condition="ismr"	offset="0"	intype="String"	inlength="5"	keyword="IMRTILT"	dicomtype="?"	dicomtag="?"	# Tilt ordered by user Axis+/-Angle [xx+/-xx]
+block="MRHDR"  condition="ismr"	offset="64"	intype="String"	inlength="2"	keyword="IECHO"		dicomtype="IS"	dicomtag="EchoNumbers"	# Echo number
+block="MRHDR"  condition="ismr"	offset="66"	intype="String"	inlength="2"	keyword="INOOFECH"	dicomtype="IS"	dicomtag="EchoTrainLength"	# Number of echoes
+block="MRHDR"  condition="ismr"	offset="68"	intype="String"	inlength="2"	keyword="ISLICE"	dicomtype="?"	dicomtag="?"	# Slice number
+block="MRHDR"  condition="ismr"	offset="70"	intype="String"	inlength="2"	keyword="INOOFSL"	dicomtype="?"	dicomtag="?"	# Number of slices
+block="MRHDR"  condition="ismr"	offset="72"	intype="String"	inlength="2"	keyword="INEX"		dicomtype="DS"	dicomtag="NumberOfAverages"	# Number of excitations
+block="MRHDR"  condition="ismr"	offset="74"	intype="String"	inlength="5"	keyword="ITR"		dicomtype="DS"	dicomtag="RepetitionTime"	# Repetition time ms
+block="MRHDR"  condition="ismr"	offset="80"	intype="String"	inlength="5"	keyword="ITI"		dicomtype="DS"	dicomtag="InversionTime"	# Inversion time ms
+block="MRHDR"  condition="ismr"	offset="85"	intype="String"	inlength="5"	keyword="ITE"		dicomtype="DS"	dicomtag="EchoTime"	# Echo time ms
+block="MRHDR"  condition="ismr"	offset="92"	intype="String"	inlength="4"	keyword="IMATRIXH"	dicomtype="?"	dicomtag="?"	# Matrix horizontal [xxxH]
+block="MRHDR"  condition="ismr"	offset="96"	intype="String"	inlength="4"	keyword="IMATRIXV"	dicomtype="?"	dicomtag="?"	# Matrix vertical [xxxV]
+block="MRHDR"  condition="ismr"	offset="100"	intype="String"	inlength="4"	keyword="IMATRIXD"	dicomtype="?"	dicomtag="?"	# Matrix depth [xxxD]
+block="MRHDR"  condition="ismr"	offset="104"	intype="String"	inlength="1"	keyword="IRCVCOIL_Type"	dicomtype="?"	dicomtag="?"	enum="'H'=Head,'B'=Body,'S'=Surface"	# Receiving coil type
+block="MRHDR"  condition="ismr"	offset="105"	intype="String"	inlength="2"	keyword="IRCVCOIL_Num"	dicomtype="?"	dicomtag="?"	# Receiving coil number
+block="MRHDR"  condition="ismr"	offset="108"	intype="String"	inlength="1"	keyword="ITRSCOIL_Type"	dicomtype="?"	dicomtag="?"	enum="'H'=Head,'B'=Body,'S'=Surface"	# Transmitting coil type
+block="MRHDR"  condition="ismr"	offset="109"	intype="String"	inlength="2"	keyword="ITRSCOIL_Num"	dicomtype="?"	dicomtag="?"	# Transmitting coil number
+block="MRHDR"  condition="ismr"	offset="112"	intype="String"	inlength="4"	keyword="IMAGNET"	dicomtype="DS"	dicomtag="MagneticFieldStrength"	# Magnetic flux density (T)
+
+block="IMGHDR2"	offset="0"	intype="Pace_Date"	inlength="1"	keyword="ICALDATE"	dicomtype="DA"	dicomtag="DateOfLastCalibration"	# Calibration date
+block="IMGHDR2"	offset="4"	intype="Time_Milliseconds_B"	inlength="1"	keyword="ICALTIME"	dicomtype="TM"	dicomtag="TimeOfLastCalibration"	# Calibration time
+block="IMGHDR2"	offset="8"	intype="String"	inlength="6"	keyword="ICALFOV"	dicomtype="?"	dicomtag="?"	# Calibration FOV name
+block="IMGHDR2"	offset="16"	intype="String"	inlength="3"	keyword="IIMDIR_NX"	dicomtype="?"	dicomtag="?"	# Direction of patient on -X axis [HFAPLR]
+block="IMGHDR2"	offset="19"	intype="String"	inlength="3"	keyword="IIMDIR_PY"	dicomtype="?"	dicomtag="?"	# Direction of patient on +Y axis [HFAPLR]
+block="IMGHDR2"	offset="22"	intype="String"	inlength="3"	keyword="IIMDIR_PX"	dicomtype="?"	dicomtag="?"	# Direction of patient on +X axis [HFAPLR]
+block="IMGHDR2"	offset="25"	intype="String"	inlength="3"	keyword="IIMDIR_NY"	dicomtype="?"	dicomtag="?"	# Direction of patient on -Y axis [HFAPLR]
+block="IMGHDR2"	offset="28"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMPOSX"	dicomtype="?"	dicomtag="?"	# Image center X machine coords mm
+block="IMGHDR2"	offset="32"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMPOSY"	dicomtype="?"	dicomtag="?"	# Image center Y machine coords mm
+block="IMGHDR2"	offset="36"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMPOSZ"	dicomtype="?"	dicomtag="?"	# Image center Z machine coords mm
+block="IMGHDR2"	offset="40"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMORIHX"	dicomtype="?"	dicomtag="?"	# Direction cosine of display horizontal vs. X machine coords
+block="IMGHDR2"	offset="44"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMORIHY"	dicomtype="?"	dicomtag="?"	# Direction cosine of display horizontal vs. Y machine coords
+block="IMGHDR2"	offset="48"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMORIHZ"	dicomtype="?"	dicomtag="?"	# Direction cosine of display horizontal vs. Z machine coords
+block="IMGHDR2"	offset="52"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMORIVX"	dicomtype="?"	dicomtag="?"	# Direction cosine of display vertical vs. X machine coords
+block="IMGHDR2"	offset="56"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMORIVY"	dicomtype="?"	dicomtag="?"	# Direction cosine of display vertical vs. Y machine coords
+block="IMGHDR2"	offset="60"	intype="IEEE_Float32_B"	inlength="1"	keyword="IIMORIVZ"	dicomtype="?"	dicomtag="?"	# Direction cosine of display vertical vs. Z machine coords
+block="IMGHDR2"	offset="64"	intype="String"	inlength="1"	keyword="ITCTYPE"	dicomtype="?"	dicomtag="?"	enum="'P'=Prospective,'R'=Retrospective"	# Target type
+block="IMGHDR2"	offset="66"	intype="String"	inlength="6"	keyword="IRMODE"	dicomtype="SH"	dicomtag="ConvolutionKernel"	enum="'STND  '=Standard,'BONY-X'=Bony,'SOFT  '=Soft Tissue"	# Reconstruction mode
+block="IMGHDR2"	offset="72"	intype="IEEE_Float32_B"	inlength="1"	keyword="IRCENTX"	dicomtype="?"	dicomtag="?"	# Recon center X mm (CT: gantry coords, MR: display coords)
+block="IMGHDR2"	offset="76"	intype="IEEE_Float32_B"	inlength="1"	keyword="IRCENTY"	dicomtype="?"	dicomtag="?"	# Recon center Y mm (CT: gantry coords, MR: display coords)
+block="IMGHDR2"	offset="80"	intype="String"	inlength="4"	keyword="IRFOV"		dicomtype="?"	dicomtag="?"	# Recon FOV cm [xx.x]
+block="IMGHDR2"	offset="96"	intype="Uint16_B"	inlength="1"	keyword="IXAXIS"	dicomtype="US"	dicomtag="Columns"	# Pixels in X-axis
+block="IMGHDR2"	offset="98"	intype="Uint16_B"	inlength="1"	keyword="IYAXIS"	dicomtype="US"	dicomtag="Rows"		# Pixels in Y-axis
+block="IMGHDR2"	offset="100"	intype="IEEE_Float32_B"	inlength="1"	keyword="IPIXSIZE"	dicomtype="?"	dicomtag="?"	# Pixel size mm
+block="IMGHDR2"	offset="104"	intype="Int16_B"	inlength="1"	keyword="IWINDOWC"	dicomtype="DS"	dicomtag="WindowCenter"	# Window center
+block="IMGHDR2"	offset="106"	intype="Int16_B"	inlength="1"	keyword="IWINDOWL"	dicomtype="DS"	dicomtag="WindowWidth"	# Window level
+block="IMGHDR2"	offset="108"	intype="Uint16_B"	inlength="1"	keyword="IATTRB"	dicomtype="?"	dicomtag="?"	bitmap="0:none,IATDUMP - Dumping is over;1:none,IATOLD - Old image reloading;2:none,IATOFFR - Off center recon;3:IATWLED - Window level enable,IATWLED - Window level disable;4:none,IATNOWT - Image exists on OD;5:ATPTYP - DPCM,ATPTYP - ORIGINAL;15:IATHZ - 50Hz,IATHZ - 60Hz"	# Image attributes
+block="IMGHDR2"	offset="112"	intype="IEEE_Float32_B"	inlength="1"	keyword="IMAGCX"	dicomtype="?"	dicomtag="?"	# Mag center X mm display coords
+block="IMGHDR2"	offset="116"	intype="IEEE_Float32_B"	inlength="1"	keyword="IMAGCY"	dicomtype="?"	dicomtag="?"	# Mag center Y mm display coords
+block="IMGHDR2"	offset="120"	intype="IEEE_Float32_B"	inlength="1"	keyword="IMAGFACT"	dicomtype="?"	dicomtag="?"	# Mag factor
+block="IMGHDR2"	offset="124"	intype="Uint16_B"	inlength="1"	keyword="ITRANS"	dicomtype="?"	dicomtag="?"	bitmap="0:none,ITRRVSRL - R/L reverse;1:none,ITRRVSTB - T/B reverse;2:none,ITRROTCW - Clockwise 90 rotate;3:none,ITRROTCCW - CounterClockwise 90 rotate"	# Transient information - orientation of display image
+block="IMGHDR2"	offset="128"	intype="String"	inlength="2"	keyword="IREFIMG1_Ser"	dicomtype="?"	dicomtag="?"	# ID of reference image 1 - series
+block="IMGHDR2"	offset="131"	intype="String"	inlength="2"	keyword="IREFIMG1_Acq"	dicomtype="?"	dicomtag="?"	# ID of reference image 1 - acquisition
+block="IMGHDR2"	offset="134"	intype="String"	inlength="2"	keyword="IREFIMG1_Img"	dicomtype="?"	dicomtag="?"	# ID of reference image 1 - image
+block="IMGHDR2"	offset="136"	intype="String"	inlength="2"	keyword="IREFIMG2_Ser"	dicomtype="?"	dicomtag="?"	# ID of reference image 2 - series
+block="IMGHDR2"	offset="139"	intype="String"	inlength="2"	keyword="IREFIMG2_Acq"	dicomtype="?"	dicomtag="?"	# ID of reference image 2 - acquisition
+block="IMGHDR2"	offset="142"	intype="String"	inlength="2"	keyword="IREFIMG2_Img"	dicomtype="?"	dicomtag="?"	# ID of reference image 2 - image
+block="IMGHDR2"	offset="144"	intype="String"	inlength="2"	keyword="IREFIMG3_Ser"	dicomtype="?"	dicomtag="?"	# ID of reference image 3 - series
+block="IMGHDR2"	offset="147"	intype="String"	inlength="2"	keyword="IREFIMG3_Acq"	dicomtype="?"	dicomtag="?"	# ID of reference image 3 - acquisition
+block="IMGHDR2"	offset="150"	intype="String"	inlength="2"	keyword="IREFIMG3_Img"	dicomtype="?"	dicomtag="?"	# ID of reference image 3 - image
+block="IMGHDR2"	offset="152"	intype="Uint8"	inlength="1"	keyword="IMASKIMG_Modality"	dicomtype="?"	dicomtag="?"	enum="1=CT,2=MR,3=Reserved"	# ID of mask image - modality
+block="IMGHDR2"	offset="153"	intype="Uint8"	inlength="1"	keyword="IMASKIMG_Model"	dicomtype="?"	dicomtag="?"	enum="1=CT8600,2=CT8800,3=CT9000,4=EMI,5=ImageMax,6=Resona(MR MAX),7=Quantex(Pace),8=Reserved"	# ID of mask image - model number
+block="IMGHDR2"	offset="154"	intype="Uint16_B"	inlength="1"	keyword="IMASKIMG_Serial"	dicomtype="?"	dicomtag="?"	# ID of mask image - serial number
+block="IMGHDR2"	offset="156"	intype="String"	inlength="3"	keyword="IMASKIMG_Std"		dicomtype="?"	dicomtag="?"	# ID of mask image - study
+block="IMGHDR2"	offset="159"	intype="Uint8"	inlength="1"	keyword="IMASKIMG_Ser"		dicomtype="?"	dicomtag="?"	# ID of mask image - series
+block="IMGHDR2"	offset="160"	intype="Uint8"	inlength="1"	keyword="IMASKIMG_Acq"		dicomtype="?"	dicomtag="?"	# ID of mask image - acquisition
+block="IMGHDR2"	offset="161"	intype="Uint8"	inlength="1"	keyword="IMASKIMG_Img"		dicomtype="?"	dicomtag="?"	# ID of mask image - image
+block="IMGHDR2"	offset="210"	intype="Uint32_B"	inlength="1"	keyword="ISELFOD"	dicomtype="?"	dicomtag="?"	# OD: Start sector of image information
+block="IMGHDR2"	offset="214"	intype="Uint16_B"	inlength="1"	keyword="IBITPLNH"	dicomtype="?"	dicomtag="?"	# Screen save bitplane pixels horizontal
+block="IMGHDR2"	offset="216"	intype="Uint16_B"	inlength="1"	keyword="IBITPLNV"	dicomtype="?"	dicomtag="?"	# Screen save bitplane pixels vertical
+block="IMGHDR2"	offset="218"	intype="Uint32_B"	inlength="1"	keyword="IPACKIM"	dicomtype="?"	dicomtag="?"	# Bytes of packed image data
+block="IMGHDR2"	offset="224"	intype="Uint32_B"	inlength="1"	keyword="IPACKSZ"	dicomtype="?"	dicomtag="?"	# Bytes of packed image file
+block="IMGHDR2"	offset="228"	intype="String"	inlength="4"	keyword="IIMFILE_Vol"	dicomtype="?"	dicomtag="?"	# File name of image information - volume name
+block="IMGHDR2"	offset="232"	intype="Uint16_B"	inlength="1"	keyword="IIMFILE_User"	dicomtype="?"	dicomtag="?"	# File name of image information - user number
+block="IMGHDR2"	offset="234"	intype="String"	inlength="8"	keyword="IIMFILE_Cat"	dicomtype="?"	dicomtag="?"	# File name of image information - catalog name
+block="IMGHDR2"	offset="242"	intype="String"	inlength="8"	keyword="IIMFILE_File"	dicomtype="?"	dicomtag="?"	# File name of image information - file name
+block="IMGHDR2"	offset="250"	intype="String"	inlength="2"	keyword="IIMFILE_Ext"	dicomtype="?"	dicomtag="?"	# File name of image information - extension
+block="IMGHDR2"	offset="252"	intype="Uint32_B"	inlength="1"	keyword="IPOINTIM"	dicomtype="?"	dicomtag="?"	# Disk: image pointer number; OD: relative sector number of image data
+block="IMGHDR2"	offset="256"	intype="String"	inlength="16"	keyword="ISRDESC1"	dicomtype="?"	dicomtag="?"	# Series description - part 1
+block="IMGHDR2"	offset="272"	intype="String"	inlength="14"	keyword="ISRDESC2"	dicomtype="?"	dicomtag="?"	# Series description - part 2
+block="IMGHDR2"	offset="286"	intype="String"	inlength="12"	keyword="ISRDESC3"	dicomtype="?"	dicomtag="?"	# Series description - part 3
+block="IMGHDR2"	offset="298"	intype="String"	inlength="10"	keyword="IIMDESC1"	dicomtype="?"	dicomtag="?"	# Image description - part 1
+block="IMGHDR2"	offset="308"	intype="String"	inlength="8"	keyword="IIMDESC2"	dicomtype="?"	dicomtag="?"	# Image description - part 2
+block="IMGHDR2"	offset="316"	intype="String"	inlength="7"	keyword="IIMDESC3"	dicomtype="?"	dicomtag="?"	# Image description - part 3
+block="IMGHDR2"	offset="324"	intype="String"	inlength="17"	keyword="IEXDESC1"	dicomtype="?"	dicomtag="?"	# Extension description - line 1
+block="IMGHDR2"	offset="341"	intype="String"	inlength="17"	keyword="IEXDESC2"	dicomtype="?"	dicomtag="?"	# Extension description - line 2
+block="IMGHDR2"	offset="358"	intype="String"	inlength="17"	keyword="IEXDESC3"	dicomtype="?"	dicomtag="?"	# Extension description - line 3
+block="IMGHDR2"	offset="375"	intype="String"	inlength="17"	keyword="IEXDESC4"	dicomtype="?"	dicomtag="?"	# Extension description - line 4
+block="IMGHDR2"	offset="392"	intype="String"	inlength="17"	keyword="IEXDESC5"	dicomtype="?"	dicomtag="?"	# Extension description - line 5
+block="IMGHDR2"	offset="409"	intype="String"	inlength="17"	keyword="IEXDESC6"	dicomtype="?"	dicomtag="?"	# Extension description - line 6
+block="IMGHDR2"	offset="426"	intype="String"	inlength="17"	keyword="IEXDESC7"	dicomtype="?"	dicomtag="?"	# Extension description - line 7
+block="IMGHDR2"	offset="443"	intype="String"	inlength="17"	keyword="IEXDESC8"	dicomtype="?"	dicomtag="?"	# Extension description - line 8
+block="IMGHDR2"	offset="460"	intype="String"	inlength="17"	keyword="IEXDESC9"	dicomtype="?"	dicomtag="?"	# Extension description - line 9
+block="IMGHDR2"	offset="477"	intype="String"	inlength="17"	keyword="IEXDESC10"	dicomtype="?"	dicomtag="?"	# Extension description - line 10
+block="IMGHDR2"	offset="494"	intype="String"	inlength="17"	keyword="IEXDESC11"	dicomtype="?"	dicomtag="?"	# Extension description - line 11
+block="IMGHDR2"	offset="511"	intype="String"	inlength="17"	keyword="IEXDESC12"	dicomtype="?"	dicomtag="?"	# Extension description - line 12
+block="IMGHDR2"	offset="528"	intype="String"	inlength="17"	keyword="IEXDESC13"	dicomtype="?"	dicomtag="?"	# Extension description - line 13
+block="IMGHDR2"	offset="545"	intype="String"	inlength="17"	keyword="IEXDESC14"	dicomtype="?"	dicomtag="?"	# Extension description - line 14
+block="IMGHDR2"	offset="562"	intype="String"	inlength="17"	keyword="IEXDESC15"	dicomtype="?"	dicomtag="?"	# Extension description - line 15
+block="IMGHDR2"	offset="579"	intype="String"	inlength="17"	keyword="IEXDESC16"	dicomtype="?"	dicomtag="?"	# Extension description - line 16
+block="IMGHDR2"	offset="596"	intype="String"	inlength="17"	keyword="IEXDESC17"	dicomtype="?"	dicomtag="?"	# Extension description - line 17
+block="IMGHDR2"	offset="613"	intype="String"	inlength="17"	keyword="IEXDESC18"	dicomtype="?"	dicomtag="?"	# Extension description - line 18
+block="IMGHDR2"	offset="630"	intype="String"	inlength="17"	keyword="IEXDESC19"	dicomtype="?"	dicomtag="?"	# Extension description - line 19
+block="IMGHDR2"	offset="647"	intype="String"	inlength="17"	keyword="IEXDESC20"	dicomtype="?"	dicomtag="?"	# Extension description - line 20
+
+constant="0" 		dicomtype="US"	dicomtag="PixelPaddingValue"		# 
+constant="16" 		dicomtype="US"	dicomtag="BitsAllocated"		# 
+constant="16" 		dicomtype="US"	dicomtag="BitsStored"			# 
+constant="15" 		dicomtype="US"	dicomtag="HighBit"			# 
+constant="1" 		dicomtype="US"	dicomtag="PixelRepresentation"		# Signed
+constant="1" 		dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 	dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="0" 		dicomtype="DS"	dicomtag="RescaleIntercept"		# 
+constant="1" 		dicomtype="DS"	dicomtag="RescaleSlope"			# 
+constant="" 		dicomtype="PN"	dicomtag="ReferringPhysicianName"	# 
+constant=""		dicomtype="PN"	dicomtag="PerformingPhysicianName"	# 
+constant=""		dicomtype="PN"	dicomtag="OperatorsName"			# 
+constant=""		dicomtype="SH"	dicomtag="AccessionNumber"		# 
+constant=""		dicomtype="DA"	dicomtag="PatientBirthDate"		# 
diff --git a/libsrc/src/dconvert/pace/pacecl.h b/libsrc/src/dconvert/pace/pacecl.h
new file mode 100644
index 0000000..3008b27
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacecl.h
@@ -0,0 +1,25 @@
+/* pacecl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "pacehdrp.h"
+#include "pacehdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class PACE_Header_BothClass : public PACE_HeaderClass
+{
+public:
+	PACE_Header_BothClass(istream *ist) : PACE_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/pace/paceconv.cc b/libsrc/src/dconvert/pace/paceconv.cc
new file mode 100644
index 0000000..83c5290
--- /dev/null
+++ b/libsrc/src/dconvert/pace/paceconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)paceconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "pacedc.h"
+#include "paceptrs.h"
+#include "paceconv.h"
diff --git a/libsrc/src/dconvert/pace/pacedc.cc b/libsrc/src/dconvert/pace/pacedc.cc
new file mode 100644
index 0000000..726230a
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacedc.cc
@@ -0,0 +1,91 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacedc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pacedc.h"
+#include "pace.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "pacesrc.h"
+
+
+bool
+PACE_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!pacehdr) pacehdr=new PACE_Header_BothClass(in);
+	Assert(pacehdr);
+
+	pacehdr->ToDicom_Template(list);
+	pacehdr->ToDicom_ManualMisc(list);
+	pacehdr->ToDicom_ManualPlane(list);
+	pacehdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in pac.he about the importance of the scope
+// of a PACE_Conversion object and AttributeList object
+
+bool
+PACE_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!pacehdr) pacehdr=new PACE_Header_BothClass(in);
+	Assert(pacehdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	pixeldatasrc=new PACE_PixelDataSource(
+		*in,
+		PACE_Offset_PixelData_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+PACE_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/pace/pacedc.h b/libsrc/src/dconvert/pace/pacedc.h
new file mode 100644
index 0000000..5c376b2
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacedc.h
@@ -0,0 +1,7 @@
+/* pacedc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "pacecl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "paceptrs.h"
diff --git a/libsrc/src/dconvert/pace/pacedmp.cc b/libsrc/src/dconvert/pace/pacedmp.cc
new file mode 100644
index 0000000..21f9a9e
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacedmp.cc
@@ -0,0 +1,22 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacedmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pacedmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "pace.h"
+
+bool
+PACE_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!pacehdr) pacehdr=new PACE_Header_BothClass(in);
+	Assert(pacehdr);
+
+	TextOutputStream out(o);
+
+	pacehdr->DumpCommon(&out);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/pace/pacedmp.h b/libsrc/src/dconvert/pace/pacedmp.h
new file mode 100644
index 0000000..07450f0
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacedmp.h
@@ -0,0 +1,4 @@
+/* pacedmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "pacecl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/pace/pacedmpf.cc b/libsrc/src/dconvert/pace/pacedmpf.cc
new file mode 100644
index 0000000..299dd6f
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacedmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacedmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pacedmp.h"
+#include "paceptrs.h"
+#include "pacedmpf.h"
diff --git a/libsrc/src/dconvert/pace/pacehdrc.cc b/libsrc/src/dconvert/pace/pacehdrc.cc
new file mode 100644
index 0000000..ae2145f
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacehdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacehdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "paceptrs.h"
+#include "pacehdrp.h"
+#include "pacehdrw.h"
+#include "pacehdrc.h"
+
diff --git a/libsrc/src/dconvert/pace/pacemdt.cc b/libsrc/src/dconvert/pace/pacemdt.cc
new file mode 100644
index 0000000..840f6a3
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacemdt.cc
@@ -0,0 +1,51 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacemdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pacedc.h"
+#include "elmconst.h"
+
+void 
+PACE_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	{
+		// PatientAge
+
+		// Pace is yyy;mm
+		unsigned yyy=atoi(String_Use(PACE_HeaderInstance_STDHDR->SAGE));
+		unsigned mm =atoi((const char *)(String_Use(PACE_HeaderInstance_STDHDR->SAGE))+4);
+
+		ostrstream ost;
+		if (yyy)
+			ost << setw(3) << setfill('0')
+			    << yyy << 'Y' << ends;	// blow off months
+		else
+			ost << setw(3) << setfill('0')
+			    << mm  << 'M' << ends;	// a baby presumably
+
+		char *agestr=ost.str();
+		(*list)+=new AgeStringAttribute(TagFromName(PatientAge),agestr);
+		if (agestr) delete[] agestr;
+	}
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),
+		Date(String_Use(PACE_HeaderInstance_STDHDR->SDATE)));
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),
+		Time(String_Use(PACE_HeaderInstance_STDHDR->STIME)));
+
+	// ContentDate (formerly Image)
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+		Date(String_Use(PACE_HeaderInstance_IMGHDR->IDATE)));
+
+	// ContentTime (formerly Image)
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+		Time(String_Use(PACE_HeaderInstance_IMGHDR->ITIME)));
+
+}
+
diff --git a/libsrc/src/dconvert/pace/pacemmsc.cc b/libsrc/src/dconvert/pace/pacemmsc.cc
new file mode 100644
index 0000000..5c7b3ac
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacemmsc.cc
@@ -0,0 +1,199 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacemmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pacedc.h"
+#include "elmconst.h"
+
+void 
+PACE_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Modality
+
+	switch (PACE_HeaderInstance_STDHDR->SMODELNO_Mod) {
+		case 1:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"CT");
+			break;
+		case 2:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"MR");
+			break;
+		default:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"SC");
+			break;
+	}
+
+	// ImageType
+
+	const char *value1,*value2,*value3;
+
+	value1="ORIGINAL";
+
+	// P is prospective, R is retrospective ...
+
+	value2=strncmp(PACE_HeaderInstance_IMGHDR2->ITCTYPE,"P",1) == 0
+		? "PRIMARY" : "SECONDARY";
+
+	value3=strncmp(PACE_HeaderInstance_IMGHDR->IMTYPE,"AX",2) == 0
+		? "AXIAL" : "LOCALIZER";
+
+	(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+		value1,value2,value3);
+
+	// ContrastBolus Module
+
+	if (strncmp(PACE_HeaderInstance_IMGHDR->IENHANCE,"+C",2) == 0) {
+
+		// ContrastBolusAgent ="Contrast"
+		// ContrastBolusStartTime
+
+		(*list)+=new LongStringAttribute(TagFromName(ContrastBolusAgent),
+			"Contrast");
+
+		(*list)+=new TimeStringAttribute(TagFromName(ContrastBolusStartTime),
+			Time(String_Use(PACE_HeaderInstance_IMGHDR->ICETIME)));
+	}
+
+	// GeneratorPower
+
+	// Loose fractional part ...
+
+	(*list)+=new IntegerStringAttribute(TagFromName(GeneratorPower),
+		(unsigned short)(atof(PACE_HeaderInstance_IMGHDR->IGENPOW)));
+
+	{
+		// SoftwareVersions
+
+		ostrstream ost;
+		ost << "System "    << PACE_HeaderInstance_STDHDR->SSYSVNO
+		    << "."          << PACE_HeaderInstance_STDHDR->SSYSRNO
+		    << " Database " << PACE_HeaderInstance_STDHDR->SDATVNO
+		    << "."          << PACE_HeaderInstance_STDHDR->SDATRNO
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new LongStringAttribute(TagFromName(SoftwareVersions),str);
+		if (str) delete[] str;
+	}
+	{
+		// StationName 
+
+		ostrstream ost;
+		ost << PACE_HeaderInstance_STDHDR->SMODELNO_Mod << "."
+		    << PACE_HeaderInstance_STDHDR->SMODELNO_Mac << "."
+		    << PACE_HeaderInstance_STDHDR->SMACHINE
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new ShortStringAttribute(TagFromName(StationName),str);
+		if (str) delete[] str;
+	}
+
+	// Do the descriptions ...
+
+	class Description {
+		ostrstream ost;
+		int first;
+		char delim;
+	public:
+		Description(char d=0)	{ first=1; delim=d; }
+
+		void add(const char *desc,unsigned maxlength)
+			{
+				char *buf = new char[maxlength+1];
+				strncpy(buf,desc,maxlength); buf[maxlength]=0;
+				char *lastspace=strrchr(buf,' ');
+				if (lastspace && buf[maxlength-1] == ' ')
+					*lastspace=0;
+				char *start = buf;
+				while (*start && *start == ' ') ++start;
+				if (*start) {
+					if (!first && delim) ost << delim;
+					ost << start;
+				}
+				first=0;
+				if (buf) delete[] buf;
+			}
+
+		char *get(void)		{ ost << ends; return ost.str(); }
+	};
+
+	{
+		// StudyDescription
+
+		Description desc(' ');
+		desc.add(PACE_HeaderInstance_STDHDR->SDESC1,50);
+		desc.add(PACE_HeaderInstance_STDHDR->SDESC2,50);
+		desc.add(PACE_HeaderInstance_STDHDR->SDESC3,50);
+		desc.add(PACE_HeaderInstance_STDHDR->SDESC4,50);
+		desc.add(PACE_HeaderInstance_STDHDR->SDESC5,50);
+
+		char *str=desc.get();
+		unsigned length=strlen(str);
+		if (length > 64) {
+			str[64]=0;
+			length=64;
+		}
+
+		(*list)+=new LongStringAttribute(TagFromName(StudyDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// SeriesDescription
+
+		Description desc(' ');
+		desc.add(PACE_HeaderInstance_IMGHDR2->ISRDESC1,16);
+		desc.add(PACE_HeaderInstance_IMGHDR2->ISRDESC2,14);
+		desc.add(PACE_HeaderInstance_IMGHDR2->ISRDESC3,12);
+
+		char *str=desc.get();
+
+		(*list)+=new LongStringAttribute(TagFromName(SeriesDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// ImageComments
+
+		Description desc(' ');
+		desc.add(PACE_HeaderInstance_IMGHDR2->IIMDESC1,10);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IIMDESC2,8);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IIMDESC3,7);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(ImageComments),str);
+		if (str) delete[] str;
+	}
+	{
+		// AdditionalPatientHistory
+
+		Description desc(' ');
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC1,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC2,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC3,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC4,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC5,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC6,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC7,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC8,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC9,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC10,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC11,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC12,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC13,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC14,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC15,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC16,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC17,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC18,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC19,17);
+		desc.add(PACE_HeaderInstance_IMGHDR2->IEXDESC20,17);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(AdditionalPatientHistory),str);
+		if (str) delete[] str;
+	}
+
+}
+
diff --git a/libsrc/src/dconvert/pace/pacempln.cc b/libsrc/src/dconvert/pace/pacempln.cc
new file mode 100644
index 0000000..7059eb2
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacempln.cc
@@ -0,0 +1,323 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pacempln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pacedc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+PACE_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlanePlane plane;
+
+	// Determine the "machine" plane of the image ...
+
+	// (Doesn't handle scout azimuth yet)
+	// Same for CT and MR (CT seems to set IMTYPE "AX  ")
+	switch (((char *)(PACE_HeaderInstance_IMGHDR->IPLANE))[0]) {
+		case 'A':	// "AX  "
+			plane=Axial;
+			break;
+		case 'S':	// "SAG "
+			plane=Sagittal;
+			break;
+		case 'C':	// "COR "
+			plane=Coronal;
+			break;
+		default:	// Yuck - just in case :(
+			plane=Axial;
+			break;
+	}
+
+	ImagePlaneHeadFeet orientation;
+
+	switch (((char *)(PACE_HeaderInstance_IMGHDR->IHFFIRST))[0]) {
+		case 'H':
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+		case 'F':
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+		default:
+			hfff="";		// :(
+			orientation=HeadFirst;
+			break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (((char *)(PACE_HeaderInstance_IMGHDR->IPATORI))[0]) {
+		case 'P':
+			ap="P";
+			position=Prone;
+			break;
+		case 'S':
+			ap="S";
+			position=Supine;
+			break;
+		case 'L':
+			ap="DL";
+			position=LeftLateralDecubitus;
+			break;
+		case 'R':
+			ap="DR";
+			position=RightLateralDecubitus;
+			break;
+		default:
+			ap="";			// :(
+			position=Supine;
+			break;
+	}
+
+	double scanfov = atof(PACE_HeaderInstance_IMGHDR->ISFOV)*10;	// cm -> mm
+
+	// Make a model of the image plane ...
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlanet" << endl;
+
+	ImagePlane imageplane(plane,scanfov,orientation,position);
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlane done" << endl;
+//imageplane.put(cerr);
+
+	// While we are in the "display" or "gantry plane ...
+	// (before angulation) 
+
+	// Apply any transformations specified in the
+	// display/gantry plane, such as magnification and
+	// reconstruction target offsets ...
+
+	// Assume that these are machine rather than body relative
+
+	double reconfov	= atof(PACE_HeaderInstance_IMGHDR2->IRFOV)*10;	// cm -> mm
+	double reconch	= PACE_HeaderInstance_IMGHDR2->IRCENTX;
+	double reconcv	= PACE_HeaderInstance_IMGHDR2->IRCENTY;
+
+	double magfact 	= PACE_HeaderInstance_IMGHDR2->IMAGFACT;
+	double magch	= PACE_HeaderInstance_IMGHDR2->IMAGCX;
+	double magcv	= PACE_HeaderInstance_IMGHDR2->IMAGCY;
+
+	Vector3D reconoffset;
+	Vector3D magoffset;
+
+	// Determine which axes are "horizontal" & "vertical" ...
+	// Don't forget sign changes ...
+
+	switch (plane) {
+		case Axial:
+			reconoffset=Vector3D(reconch,-reconcv,0);
+			magoffset  =Vector3D(magch,    -magcv,0);
+			break;
+		case Sagittal:
+			reconoffset=Vector3D(0,-reconch,reconcv);
+			magoffset  =Vector3D(0,  -magch,  magcv);
+			break;
+		case Coronal:
+			reconoffset=Vector3D(reconch,0,reconcv);
+			magoffset  =Vector3D(magch  ,0,  magcv);
+			break;
+	}
+
+//cerr << "ToDicom_ManualPlane::reconoffset is:" << endl;
+//reconoffset.put(cerr);
+//cerr << "ToDicom_ManualPlane::magoffset is:" << endl;
+//magoffset.put(cerr);
+
+//cerr << "ToDicom_ManualPlane::scale:" << endl;
+	imageplane.MachinePlane::scale(magfact*reconfov/scanfov);
+//cerr << "ToDicom_ManualPlane::scale result:" << endl;
+//imageplane.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by reconoffset:" << endl;
+	imageplane.MachinePlane::shift(reconoffset);
+//cerr << "ToDicom_ManualPlane::shift by reconoffset result:" << endl;
+//imageplane.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by magoffset:" << endl;
+	imageplane.MachinePlane::shift(magoffset);
+//cerr << "ToDicom_ManualPlane::shift by magoffset result:" << endl;
+//imageplane.put(cerr);
+
+	// Account for angulation ...
+
+	if (PACE_isct) {
+//cerr << "ToDicom_ManualPlane::angling:" << endl;
+#ifdef PACETILTCTUSINGMACHINECORDS
+		// +ve is top towards table
+		// whereas Z is positive into gantry so change sign
+		imageplane.MachinePlane::angle(
+			LeftRight,-PACE_HeaderInstance_CTHDR->IGTILT);
+#else // PACETILTCTUSINGMACHINECORDS
+		// +ve is always towards front of head
+		imageplane.PatientPlane::angle(
+			LeftRight,atof(PACE_HeaderInstance_CTHDR->IGTILTB));
+#endif // PACETILTCTUSINGMACHINECORDS
+//cerr << "ToDicom_ManualPlane::angling result:" << endl;
+//imageplane.put(cerr);
+	}
+
+	if (PACE_ismr) {
+		// Not yet tested ... no samples available ...
+
+		// Tilt is specified as none or relative to axis
+		// Axis+/-Angle [xx+/-xx]
+		// NB. in body not machine coordinates **********
+
+		char *str=PACE_HeaderInstance_MRHDR->IMRTILT;
+		char axis[3]; strncpy(axis,str,2); axis[2]=0;
+		int angle=str[2] ? atoi(str+2) : 0;
+
+		// in Japanese docs, text contradicts drawing so
+		// go with drawing ...
+
+		ImagePlaneAxis planeaxis;
+
+		if (angle) {
+			switch (axis[0]) {
+				case 'A':
+				case 'P':
+					planeaxis=AnteriorPosterior;
+					// Pace CW +ve facing posterior
+					// angle=angle;
+					break;
+				case 'R':
+				case 'L':
+					planeaxis=LeftRight;
+					// Pace CW +ve facing right lat
+					angle=-angle;
+					break;
+				case 'H':
+				case 'F':
+					planeaxis=HeadFeet;
+					// Pace CW +ve facing head
+					// angle=angle;
+					break;
+			}
+		}
+		imageplane.PatientPlane::angle(planeaxis,angle);
+	}
+
+	// Account for physical offsets in the body plane ...
+	// (after angulation)
+
+	// For Pace the only difference between slices seems to be
+	// in the "Slice position by body coords" (ISLPOSxx) fields
+	// These do NOT include recon center offset and gantry tilt
+
+	// NB. The "Image center machine coords" (IIMPOSx) already
+	// account for both the recon center offset and the gantry
+	// tilt. They do NOT however handle the change between
+	// slices in the Z direction (what I would expect to be
+	// in ITBLPOS but is not ... it is zero in every slice :()
+	// so we can't use them.
+
+	double xcenter=PACE_HeaderInstance_IMGHDR->ISLPOSLR;
+	double ycenter=PACE_HeaderInstance_IMGHDR->ISLPOSAP;
+	double zcenter=PACE_HeaderInstance_IMGHDR->ISLPOSHF;
+
+	// Consider sign difference Pace vs. Dicom for Y
+
+//cerr << "ToDicom_ManualPlane::physical offset is" << endl;
+	Vector3D offset(xcenter,-ycenter,zcenter);
+//offset.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by physical offset" << endl;
+	imageplane.PatientPlane::shift(offset);
+//cerr << "ToDicom_ManualPlane::shift by physical offset result:" << endl;
+//imageplane.put(cerr);
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+//cerr << "ToDicom_ManualPlane::addPlaneToList:" << endl;
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+//cerr << "ToDicom_ManualPlane::addPlaneToList done:" << endl;
+
+	// SliceLocation
+
+	// ITBLPOS always seems to be zero, so use IPLANE to
+	// decide which slice position value to use
+
+	// Pace slice position values are in body coordinates.
+	// Neither DICOM PS3 nor ACR/NEMA 2 define sign of
+	// SliceLocation, but seeing as it is an old element
+	// it seems appropriate to use machine coordinates
+
+	// Don't want to use the angled, magnified, targeted
+	// imageplane because it is in the axis of the
+	// image center rather than the axis at isocenter
+	// and is slightly different from the conventional
+	// interpretation of table position if an offset
+	// in the display/gantry plane has been applied.
+
+	// So set up a new imageplane just to convert from
+	// body to machine cordinates, and apply physical
+	// offset without angulation or recon or zoom ...
+
+//cerr << "ToDicom_ManualPlane::Use a new image plane for rest:" << endl;
+
+	ImagePlane locationimageplane(plane,scanfov,orientation,position);
+
+	locationimageplane.PatientPlane::shift(offset);
+
+	Point3D center=locationimageplane.MachinePlane::getCenter();
+
+	double location;
+
+	switch (plane) {
+		case Axial:
+			location=center.getZ();
+			break;
+		case Sagittal:
+			location=center.getX();
+			break;
+		case Coronal:
+			location=center.getY();
+			break;
+	}
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),location);
+
+	// TableHeight
+
+	// DICOM ...+ve is below center
+	// Pace is in machine co-ordinates ... +ve is up
+
+	if (PACE_isct) (*list)+=new
+		DecimalStringAttribute(TagFromName(TableHeight),
+			double(-double(PACE_HeaderInstance_CTHDR->ITBLHGT)));
+
+	// PixelSpacing
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		PACE_HeaderInstance_IMGHDR2->IPIXSIZE,
+		PACE_HeaderInstance_IMGHDR2->IPIXSIZE);
+
+	// ZoomFactor
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomFactor),
+		PACE_HeaderInstance_IMGHDR2->IMAGFACT,
+		PACE_HeaderInstance_IMGHDR2->IMAGFACT);
+
+	// ZoomCenter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomCenter),
+			PACE_HeaderInstance_IMGHDR2->IMAGCX,
+			PACE_HeaderInstance_IMGHDR2->IMAGCY);
+
+	// ReconstructionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),
+		atof(PACE_HeaderInstance_IMGHDR2->IRFOV)*10);
+
+	// DataCollectionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(DataCollectionDiameter),
+		atof(PACE_HeaderInstance_IMGHDR->ISFOV)*10);
+}
+
diff --git a/libsrc/src/dconvert/pace/paceptrs.h b/libsrc/src/dconvert/pace/paceptrs.h
new file mode 100644
index 0000000..4c3058f
--- /dev/null
+++ b/libsrc/src/dconvert/pace/paceptrs.h
@@ -0,0 +1,12 @@
+/* paceptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	PACE_Offset_STDHDR_ptr	256
+#define	PACE_Offset_IMGHDR_ptr	768
+#define	PACE_Offset_MRHDR_ptr	(PACE_Offset_IMGHDR_ptr+192)
+#define	PACE_Offset_CTHDR_ptr	(PACE_Offset_IMGHDR_ptr+192)
+#define	PACE_Offset_IMGHDR2_ptr	(PACE_Offset_IMGHDR_ptr+320)
+
+#define	PACE_isct	(PACE_HeaderInstance_IMGHDR->IMODELNO_Mod == 1)
+#define	PACE_ismr	(PACE_HeaderInstance_IMGHDR->IMODELNO_Mod == 2)
+
+#define	PACE_Offset_PixelData_ptr	(PACE_Offset_IMGHDR_ptr \
+			+pacehdr->PACE_HeaderInstance_IMGHDR->IBLOCK*1024)
diff --git a/libsrc/src/dconvert/pace/pacesrc.h b/libsrc/src/dconvert/pace/pacesrc.h
new file mode 100644
index 0000000..49a8a29
--- /dev/null
+++ b/libsrc/src/dconvert/pace/pacesrc.h
@@ -0,0 +1,96 @@
+/* pacesrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_pacesrc__
+#define __Header_pacesrc__
+
+class PACE_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Int16	pixel;
+	unsigned runlengthleftover;
+	enum { Difference, Reference } mode;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	PACE_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			pixel=0;
+			runlengthleftover=0;
+			mode=Reference;
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~PACE_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				if (runlengthleftover) {
+					unsigned colsleft=columns-col;
+					unsigned runinthisline = (runlengthleftover > colsleft)
+						? colsleft : runlengthleftover;
+					runlengthleftover-=runinthisline;
+					col+=runinthisline;
+					while (runinthisline--) *ptr++=pixel;
+				}
+				else {
+					unsigned char byte;
+					istr->read((char *)&byte,1);
+					if (!istr->good()) break;
+					if (byte == 0x80) {		// Mode switch
+						if (mode == Difference)
+							mode=Reference;
+						else
+							mode=Difference;
+					}
+					else if (byte == 0x81) {	// Run length flag
+						istr->read((char *)&byte,1);
+						if (!istr->good()) break;
+						runlengthleftover=byte;
+					}
+					else {
+						if (mode == Difference) {
+							pixel+=(signed char)byte;
+						}
+						else {
+							pixel=byte<<8;
+							istr->read((char *)&byte,1);
+							if (!istr->good()) break;
+							pixel|=byte;
+						}
+						*ptr++=pixel; ++col;
+					}
+				}
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_pacesrc__
diff --git a/libsrc/src/dconvert/pq/Imakefile b/libsrc/src/dconvert/pq/Imakefile
new file mode 100755
index 0000000..16b88bf
--- /dev/null
+++ b/libsrc/src/dconvert/pq/Imakefile
@@ -0,0 +1,24 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = pqdc.cc pqconv.cc pqmpln.cc \
+		 pqmmsc.cc pqmdt.cc \
+		 pqdmp.cc pqdmpf.cc \
+		 pqhdrc.cc pq.cc
+
+OBJS = 		 pqdc.o  pqconv.o  pqmpln.o  \
+		 pqmmsc.o  pqmdt.o  \
+		 pqdmp.o  pqdmpf.o  \
+		 pqhdrc.o  pq.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdpq.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(pq,dconvert)
+
+pqdmpf.o: pqdmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) pqdmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/pq/README b/libsrc/src/dconvert/pq/README
new file mode 100755
index 0000000..31ba0bc
--- /dev/null
+++ b/libsrc/src/dconvert/pq/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"pq.h"
+		class PQ_Conversion {
+			PQ_Conversion(istream &i,ostream &e);
+			virtual ~PQ_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"pq.cc"
+
+		PQ_Conversion::PQ_Conversion(istream &i,ostream &e);
+		PQ_Conversion::~PQ_Conversion();
+
+	"pqcl.h"
+
+		class PQ_Header_BothClass  : public PQ_HeaderClass
+		{
+		public:
+			PQ_Header_BothClass(istream *ist) : PQ_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"pqconv.cc"
+
+		#include "pqconv.h"
+
+	"pqdc.c"
+
+		bool PQ_Conversion::convertHeader(AttributeList *list);
+		bool PQ_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool PQ_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"pqdc.h"
+
+	"pqdmp.cc"
+
+		bool PQ_Conversion::dump(ostream &o);
+
+	"pqdmp.h"
+
+	"pqhdrc.cc"
+
+		#include "pqhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"pq.tpl"
+
+		The template "describing" the format for header generation
+
+	"pqmdt.cc"
+
+		void PQ_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"pqmmsc.cc"
+
+		void PQ_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"pqmpln.cc"
+
+		void PQ_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"pqptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"pqsrc.h"
+
+		class PQ_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			PQ_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~PQ_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from pq.tpl:
+
+	"pqhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class PQ_HeaderClass_HDR1 {
+		public:
+			PQ_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"pqhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class PQ_HeaderClass
+		{
+		public:
+			PQ_HeaderClass(istream *ist);
+
+			PQ_HeaderClass_HDR1 *PQ_HeaderInstance_HDR1;
+			PQ_HeaderClass_HDR2 *PQ_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"pqhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		PQ_HeaderClass::PQ_HeaderClass(istream *ist);
+
+	"pqconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void PQ_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"pqdmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void PQ_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "pqhdrm.h".
+
+	if you have special purpose code, then "pqhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "pqhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/pq/pq.cc b/libsrc/src/dconvert/pq/pq.cc
new file mode 100644
index 0000000..5b3bd03
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pq.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pq.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "pq.h"
+#include "pqcl.h"
+#include "srcsink.h"
+#include "pqsrc.h"
+
+PQ_Conversion::PQ_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	pqhdr=0;
+	pixeldatasrc=0;
+}
+
+PQ_Conversion::~PQ_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (pqhdr) delete pqhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/pq/pq.h b/libsrc/src/dconvert/pq/pq.h
new file mode 100644
index 0000000..8dea552
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pq.h
@@ -0,0 +1,39 @@
+/* pq.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_pq__
+#define __Header_pq__
+
+// NB. a PQ_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~PQ_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class PQ_Header_BothClass;
+class PQ_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class PQ_Conversion {
+	PQ_Header_BothClass *pqhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	PQ_PixelDataSource *pixeldatasrc;
+public:
+	PQ_Conversion(istream &i,ostream &e);
+
+	virtual ~PQ_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out);
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax);
+
+	bool convertHeader(AttributeList *list);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax);
+};
+
+#endif /* __Header_pq__ */
+
diff --git a/libsrc/src/dconvert/pq/pqcl.h b/libsrc/src/dconvert/pq/pqcl.h
new file mode 100644
index 0000000..33da424
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqcl.h
@@ -0,0 +1,25 @@
+/* pqcl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "pqhdrp.h"
+#include "pqhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class PQ_Header_BothClass : public PQ_HeaderClass
+{
+public:
+	PQ_Header_BothClass(istream *ist) : PQ_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log)
+		{
+			(void)log;
+		}
+
+	void ToDicom_Template   (AttributeList *list);
+	void ToDicom_ManualMisc (AttributeList *list);
+	void ToDicom_ManualPlane(AttributeList *list);
+	void ToDicom_ManualDates(AttributeList *list);
+};
+
diff --git a/libsrc/src/dconvert/pq/pqconv.cc b/libsrc/src/dconvert/pq/pqconv.cc
new file mode 100644
index 0000000..d02b568
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "pqdc.h"
+#include "pqptrs.h"
+#include "pqconv.h"
diff --git a/libsrc/src/dconvert/pq/pqconv.h b/libsrc/src/dconvert/pq/pqconv.h
new file mode 100644
index 0000000..00b2d6d
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqconv.h
@@ -0,0 +1,65 @@
+/* pqconv.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifdef CRAP
+// Automatically generated from template - EDITS WILL BE LOST
+//
+// Generated by tpltohdr.awk with options or defaults ...
+//
+// 	 role=dicom
+// 	 prefix=PQ_
+// 	 dicomfunctionname=ToDicom_Template
+// 	 dumpcommonfunctionname=DumpCommon
+// 	 dumpselectedimagefunctionname=DumpSelectedImage
+// 	 headeroffsetprefix=PQ_Offset
+// 	 headeroffsetsuffix=ptr
+// 	 headerclassprefix=PQ_HeaderClass
+// 	 headerdicomclassprefix=PQ_Header_BothClass
+// 	 headerdumpclassprefix=PQ_Header_BothClass
+// 	 headerinstanceprefix=PQ_HeaderInstance
+// 	 methodnameprefix=PQ_Method
+// 	 methodconstructorargsprefix=PQ_MethodConstructorArgs
+// 	 headerclassparameters=
+
+void 
+PQ_Header_BothClass::ToDicom_Template(AttributeList *list)
+{
+	(*list)+=new UnsignedShortAttribute(
+		TagFromName(PixelPaddingValue),0);
+
+	(*list)+=new CodeStringAttribute(
+		TagFromName(PhotometricInterpretation),"MONOCHROME2");
+
+	(*list)+=new DecimalStringAttribute(
+		TagFromName(RescaleIntercept),"0");
+
+	(*list)+=new PersonNameAttribute(
+		TagFromName(ReferringPhysicianName));
+
+}
+
+#endif
+
+void 
+PQ_Header_BothClass::ToDicom_Template(AttributeList *list)
+{
+	// constant stuff
+
+	(*list)+=new UnsignedShortAttribute(TagFromName(BitsAllocated),16);
+	(*list)+=new UnsignedShortAttribute(TagFromName(BitsStored),16);
+	(*list)+=new UnsignedShortAttribute(TagFromName(HighBit),15);
+	(*list)+=new UnsignedShortAttribute(TagFromName(PixelPaddingValue),0);
+	(*list)+=new UnsignedShortAttribute(TagFromName(SamplesPerPixel),1);
+	(*list)+=new UnsignedShortAttribute(TagFromName(PixelRepresentation),1);
+	(*list)+=new CodeStringAttribute(TagFromName(PhotometricInterpretation),"MONOCHROME2");
+
+	(*list)+=new DecimalStringAttribute(TagFromName(RescaleIntercept),"0");
+	(*list)+=new DecimalStringAttribute(TagFromName(RescaleSlope),"1");
+	(*list)+=new LongStringAttribute(TagFromName(RescaleType),"HU");
+
+	{
+		Int32 recon_matrix;
+		bool found=getIntegerAttribute("RCNMTRX",recon_matrix);
+		Assert(found);
+		(*list)+=new UnsignedShortAttribute(TagFromName(Rows),Uint16(recon_matrix));
+		(*list)+=new UnsignedShortAttribute(TagFromName(Columns),Uint16(recon_matrix));
+	}
+}
diff --git a/libsrc/src/dconvert/pq/pqdc.cc b/libsrc/src/dconvert/pq/pqdc.cc
new file mode 100644
index 0000000..5c20077
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqdc.cc
@@ -0,0 +1,86 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqdc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pqdc.h"
+#include "pq.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "pqsrc.h"
+
+bool
+PQ_Conversion::convertHeader(AttributeList *list)
+{
+	Assert(list);
+	Assert(in);
+	if (!pqhdr) pqhdr=new PQ_Header_BothClass(in);
+	Assert(pqhdr);
+
+	pqhdr->ToDicom_Template(list);
+	pqhdr->ToDicom_ManualMisc(list);
+	pqhdr->ToDicom_ManualPlane(list);
+	pqhdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in pq.h about the importance of the scope
+// of a PQ_Conversion object and AttributeList object
+
+bool
+PQ_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax)
+{
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!pqhdr) pqhdr=new PQ_Header_BothClass(in);
+	Assert(pqhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	pixeldatasrc=new PQ_PixelDataSource(
+		*in,
+		PQ_Offset_PixelData_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+PQ_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax)
+{
+	if (!convertHeader(list)) return false;
+	if (!convertPixelData(list,transfersyntax)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/pq/pqdc.h b/libsrc/src/dconvert/pq/pqdc.h
new file mode 100644
index 0000000..06e2071
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqdc.h
@@ -0,0 +1,7 @@
+/* pqdc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "pqcl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "pqptrs.h"
diff --git a/libsrc/src/dconvert/pq/pqdmp.cc b/libsrc/src/dconvert/pq/pqdmp.cc
new file mode 100644
index 0000000..72fd628
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqdmp.cc
@@ -0,0 +1,37 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pqdmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "pq.h"
+
+bool
+PQ_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!pqhdr) pqhdr=new PQ_Header_BothClass(in);
+	Assert(pqhdr);
+
+	TextOutputStream out(o);
+
+	pqhdr->DumpCommon(&out);
+
+	return true;
+}
+
+
+bool
+PQ_Conversion::dumpSelectedImage(ostream &o)
+{
+	Assert(in);
+	if (!pqhdr) pqhdr=new PQ_Header_BothClass(in);
+	Assert(pqhdr);
+
+	TextOutputStream out(o);
+
+	pqhdr->DumpSelectedImage(&out);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/pq/pqdmp.h b/libsrc/src/dconvert/pq/pqdmp.h
new file mode 100644
index 0000000..6c5e596
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqdmp.h
@@ -0,0 +1,4 @@
+/* pqdmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "pqcl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/pq/pqdmpf.cc b/libsrc/src/dconvert/pq/pqdmpf.cc
new file mode 100644
index 0000000..3dc76cb
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqdmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqdmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pqdmp.h"
+#include "pqptrs.h"
+#include "pqdmpf.h"
diff --git a/libsrc/src/dconvert/pq/pqdmpf.h b/libsrc/src/dconvert/pq/pqdmpf.h
new file mode 100644
index 0000000..0a6fe13
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqdmpf.h
@@ -0,0 +1,336 @@
+/* pqdmpf.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifdef CRAP
+
+// Automatically generated from template - EDITS WILL BE LOST
+//
+// Generated by tpltohdr.awk with options or defaults ...
+//
+// 	 role=dump
+// 	 prefix=PQ_
+// 	 dicomfunctionname=ToDicom_Template
+// 	 dumpcommonfunctionname=DumpCommon
+// 	 dumpselectedimagefunctionname=DumpSelectedImage
+// 	 headeroffsetprefix=PQ_Offset
+// 	 headeroffsetsuffix=ptr
+// 	 headerclassprefix=PQ_HeaderClass
+// 	 headerdicomclassprefix=PQ_Header_BothClass
+// 	 headerdumpclassprefix=PQ_Header_BothClass
+// 	 headerinstanceprefix=PQ_HeaderInstance
+// 	 methodnameprefix=PQ_Method
+// 	 methodconstructorargsprefix=PQ_MethodConstructorArgs
+// 	 headerclassparameters=
+
+void 
+PQ_Header_BothClass::DumpCommon(TextOutputStream *log)
+{
+}
+#endif
+
+struct PQ_Data_Dictionary_Entry {
+	const char *name;
+	const char *desc;
+};
+
+static struct PQ_Data_Dictionary_Entry PQ_Data_Dictionary[] = {
+
+"AAA_DEL",	"Deleted_Flag",
+"AAA_FNU",	"File_Seq_in_Study",
+"AAA_GAP",	"SDR/RDB_Gap",
+"AAA_MSK",	"Access_Mask",
+"AAA_NXT",	"O-Disk_Study_Next_Pos",
+"AAA_POS",	"O-Disk_Study_Pos_Sect",
+"AAA_SEQ",	"Study_Seq_on_Tape",
+"ACQTAG",	"Acquisition_Tag",
+"ACQ_BAT",	"Batch_Acquisition_Set",
+"AIRINTP",	"Aircal_Interpolated",
+"ANATOMY",	"Anatomy",
+"BEAMLIM",	"Beam_Limiter_On_Off",
+"CALSRC",	"Cal Source",
+"COMNT_1",	"Comments_1",
+"COMNT_2",	"Comments_2",
+"COMNT_3",	"Comments_3",
+"COMNT_4",	"Comments_4",
+"COMNT_A",	"Acquisition_Comments",
+"COMNT_D",	"Display_Brief_Commnt",
+"COMNT_F",	"Folder_Comments",
+"COMNT_I",	"Image_Comments",
+"COMNT_P",	"Patient_Comments",
+"COMNT_S",	"Study_Comments",
+"CONTR",	"Contrast",
+"COUCH",	"Couch_Posit_1234.12",
+"COUCHAQ",	"Init_Couch_Pos_1234.12",
+"COUCHHT",	"Couch_Height",
+"COUCHIM",	"Couch_Index_Multiplier",
+"COUCHIX",	"Couch_Index",
+"CREDATE",	"Create_Date_-_YYMMDD",
+"CRETIME",	"Create_Time=HHMMSShh",
+"DBREVL",	"Dbase_Rev_Level",
+"DDREVL",	"Data_Dict._Rev_Level",
+"DICOM3",	"DICOM3",
+"DICONTX",	"Display_Context",
+"DRGCODE",	"DRG_Code",
+"FA_HLMN",	"HL_Manual_Xmit_Flg[]",
+"FA_HLMN",	"Manual_Archive_Flags_Array",
+"FLATSRC",	"FLATSS_Source",
+"FOLDER",	"Folder_Name",
+"F_ARANY",	"Is_Archivd_Somewhere",
+"F_ARCH",	"Manual_Archived_Flag",
+"F_ARCOK",	"Manual_Archive_OK_Fl",
+"F_ARCOK",	"Manual_Tape_Retriev_Fl",
+"F_AUTO",	"Image_Auto_Archvd_Fl",
+"F_AUTOK",	"Image_Auto_ArchOK_Fl",
+"F_A_EXB",	"Exabyte_Auto_Arch_Fl",
+"F_A_OPD",	"O-Disk_Auto_Arch_Fl",
+"F_CMPRS",	"Image_Compressed_Flg",
+"F_COMPL",	"Image_Complete_Flag",
+"F_DELOK",	"Image_Delete_OK_Flag",
+"F_FILMD",	"Image_Filmed_Flag",
+"F_FILOK",	"Image_Film_OK_Flag",
+"F_HLANY",	"Any_Archive_Flags_Set",
+"F_HLANY",	"HL_Any_Manual_Flags",
+"F_HLAUT",	"Auto_Xmit_Requested",
+"F_HLAUT",	"HL_Auto_Xmit_Flag",
+"F_M_EXB",	"Exabyte_Manual_Arch_Fl",
+"F_M_FLP",	"Floppy_Manual_Arch_Fl",
+"F_M_OPD",	"Disk_Manual_Arch_Fl",
+"F_N_DEL",	"Non-Deletable",
+"F_REVU",	"Image_Reviewed_Flag",
+"F_RPROK",	"Image_Reproc_OK_Flag",
+"F_SHAPE",	"Image_Shaped_Flag",
+"GNTNDET",	"#_Dets_on_Gantry",
+"GTILT",	"Gantry_Tilt_-12.1",
+"IMFCLAS",	"Img_File_Class_Flg",
+"IMFICON",	"Img_File_Contg_Flg",
+"IMFILE",	"Image_File_Name",
+"IMFIOFS",	"Img_File_Hdr_Ofs_Byt",
+"IMFISHP",	"Img_File_Shape_Table",
+"IMFISIZ",	"Img_File_Size_Bytes",
+"IMFI_X",	"Img_File_X_Width",
+"IMFI_Y",	"Img_File_Y_Height",
+"IMFPATH",	"Image_File_Path",
+"IMFPSIZ",	"Img_Fil_PhySize_Bytes",
+"IMFTYPE",	"File_Data_Type",
+"IMGFLIP",	"Image_Flipped_Yes_No",
+"IMNUM",	"Image_Numbr_In_Study",
+"IMNUMAB",	"Image_Number_Absol.",
+"IMNUMAQ",	"Image_Number_In_Acq",
+"IMTYPE",	"Image_Type",
+"IMTYPSY",	"Synthetic_Image_Type",
+"LABBOTT",	"Bottom_Label",
+"LABLEFT",	"Left_Side_Label",
+"LABRGHT",	"Right_Side_Label",
+"LABTOP",	"Top_Label",
+"LEVEL",	"Level",
+"L_ALG",	"Lng_Algorithm",
+"L_BADET",	"Lng_Bad_Detectors",
+"L_BANDW",	"Lng_Bandwidth",
+"L_CAL",	"Lng_Calib_Overall",
+"L_CENTR",	"Lng_Centering",
+"L_COEFS",	"Lng_nth_Ord_Coef",
+"L_GEO_C",	"Lng_Geom_Correct",
+"L_HUMPV",	"Lng_Hump_Vector",
+"L_LINZT",	"Lng_Linearization",
+"L_LMPRF",	"Lng_Lump_Profile",
+"L_LMSFT",	"Lng_Lump_Shift_Pos",
+"L_OFFS",	"Lng_AirCal_Offs",
+"L_PICOL",	"Pilot_Col_Alg_Length",
+"L_PIROW",	"Pilot_Row_Alg_Length",
+"L_PROFL",	"Lng_AirCal_Profile",
+"L_REF",	"Lng_Refer._Vector",
+"L_RIPPL",	"Lng_Ripple_Vector",
+"L_RRIPL",	"Lng_Resolver_Ripple",
+"MODAL",	"Modality",
+"N_IMDIS",	"#_Images_Displayable",
+"N_IMRAW",	"#_Img_Raw_Data",
+"N_IMSLC",	"#_Images_Slices",
+"N_IMTOT",	"#_Images_Total",
+"OPERID",	"Operator_ID",
+"O_1ORDC",	"Ofs_1st_Ord",
+"O_2ORDC",	"Ofs_2nd_Ord",
+"O_3ORDC",	"Ofs_3rd_Ord",
+"O_4ORDC",	"Ofs_4th_Ord",
+"O_ALG",	"Ofs_Algorithm",
+"O_BADET",	"Ofs_Bad_Detectors",
+"O_BANDW",	"Ofs_Bandwidth",
+"O_CAL",	"Ofs_Calib_Overall",
+"O_CENTR",	"Ofs_Centering",
+"O_GEO_C",	"Ofs_Geom_Correct",
+"O_HUMPV",	"Ofs_Hump_Vector",
+"O_LINZT",	"Ofs_Linearization",
+"O_LMPRF",	"Ofs_Lump_Profile",
+"O_LMSFT",	"Ofs_Lump_Shift_Pos",
+"O_LREF",	"Ofs_Left_Ref_Vector",
+"O_OFFS",	"Ofs_AirCal_Offs",
+"O_PICOL",	"Pilot_Col_Alg_Offset",
+"O_PIROW",	"Pilot_Row_Alg_Offset",
+"O_PROFL",	"Ofs_AirCal_Profile",
+"O_RIPPL",	"Ofs_Ripple_Vector",
+"O_RREF",	"Ofs_Right_Ref_Vector",
+"O_RRIPL",	"Ofs_Resolver_Ripple",
+"O_VIEWS",	"Ofs_Views",
+"PATAGDA",	"Patient_Age_Days",
+"PATAGE",	"Patient_Age (obsolete)",
+"PATAGHR",	"Patient_Age_Hours",
+"PATAGMO",	"Patient_Age_Months",
+"PATAGTY",	"Patient_age_Units",
+"PATAGYR",	"Patient_Age_Years",
+"PATDOB",	"Patient_DOB_YYMMDD",
+"PATFNAM",	"Patient_First_Name",
+"PATID",	"Patient_ID",
+"PATNAM",	"Patient_Last_Name",
+"PATSEX",	"Patient_Sex",
+"PICOLLG",	"Pilot_Col_Alg_Length",
+"PICOLOF",	"Pilot_Col_Alg_Offset",
+"PILTANG",	"Pilot_Angle",
+"PILTENH",	"Pilot_Edge_Enhanced",
+"PILTFLD",	"Pilot_Half/Full",
+"PILTFSZ",	"Pilot_Field_Size",
+"PILTHKN",	"Pilot_Scan_Thickn",
+"PILTKV",	"Pilot_KV",
+"PILTLNG",	"Pilot_Length_mm",
+"PILTMA",	"Pilot_Ma",
+"PILTMAS",	"Pilot_Mas",
+"PILTORG",	"Pilot_Org_Pixels",
+"PILTPPM",	"Pilot_Pixel/mm",
+"PILTWID",	"Pilot_Width_mm",
+"PILTYPE",	"Pilot_horz/vert/obl",
+"PIROWLG",	"Pilot_Row_Alg_Length",
+"PIROWOF",	"Pilot_Row_Alg_Offset",
+"POSHF",	"Position_Head/Feet",
+"POSPRN",	"Position_Prone/Supine",
+"PROCNUM",	"Procedure_Number",
+"PRTMOD",	"Protocol_Modified",
+"PRTRECN",	"Recon_Protocol",
+"PRTSCAN",	"Scan_Protocol",
+"PVRFLAG",	"Pvr_flag",
+"RCNALG",	"Recon_Algorithm",
+"RCNALGD",	"Recon_Algorithm_Desc",
+"RCNALGF",	"Recon_Algorithm_Filename",
+"RCNAVGN",	"Recon_Averag_N_Views",
+"RCNCVCT",	"Recon_Custom_Vector",
+"RCNCX",	"Recon_X_Centr_-123mm",
+"RCNCY",	"Recon_Y_Centr_-123mm",
+"RCNDATE",	"Recon_Date_-_YYMMDD",
+"RCNFILT",	"Recon_Filter",
+"RCNFLD",	"Recon_Fld_Sz_mm (obsolete)",
+"RCNFSIZ",	"Recon_Fld_Size_mm",
+"RCNIMRT",	"Recon_Image_Rotation",
+"RCNMTRX",	"Recon_Matrix_Pixels",
+"RCNNVUE",	"Number_Of_Views",
+"RCNNXVU",	"Recon_Next_View_Offset",
+"RCNREVL",	"Recon_Rev_Level",
+"RCNRIPL",	"Recon_Ripple_Float",
+"RCNSQNA",	"Recon_Sequence_Name",
+"RCNTIME",	"Recon_Time=HHMMSS.hh",
+"RCNWGTF",	"Vol_Weighting_Filename",
+"REFPHY",	"Referring_Physician",
+"REFRAD",	"Referring_Radiologist",
+"REVPHY",	"Reviewing_Physician",
+"RPRFLAG",	"Reprocessed_Flag",
+"RPRTAG",	"Reprocess_Seq_Tag",
+"SCATFLG",	"Scatter_Correct_flag",
+"SCNANGL",	"Scan_Angle",
+"SCNANSP",	"Scan_Anode_Speed",
+"SCNAQTM",	"Acq_Strt_Time=HHMMSShh",
+"SCNCOLL",	"Scan_collimation",
+"SCNCOMP",	"Scan_Compensator",
+"SCNCSPD",	"Scan_Couch_Speed",
+"SCNDATE",	"Scan_Acq_Date_-_YYMMDD",
+"SCNDELT",	"Scan_Delta_Mode",
+"SCNDETN",	"Scan_Offs_to_Det#",
+"SCNDODG",	"Scan_Dodger=???",
+"SCNDTYP",	"Scan_Data_Type/= float, int, long,...",
+"SCNEXPT",	"Scan_Expose_Time",
+"SCNEXRV",	"Scan_Extra_Revs",
+"SCNFAN",	"Scan_Fan_#_Dets",
+"SCNFILT",	"Scan_Filter",
+"SCNFLD",	"Scan_Fld_[HALF|FULL]",
+"SCNFLDX",	"Scan_Fld_[FULLCTR]",
+"SCNFSIZ",	"Scan_Fld_Siz_mm",
+"SCNGAP",	"Scan_Gap_#_Dets",
+"SCNGBCN",	"Scan_Global_Centrng",
+"SCNHOSP",	"Scan_Hospital_Name",
+"SCNINTM",	"Scan_Integ_Period",
+"SCNKV",	"Scan_KV",
+"SCNLPTS",	"Scan_#_Byt_Preceedg",
+"SCNMA",	"Scan_MA",
+"SCNMAOF",	"Scan_Ma_Offset",
+"SCNMAS",	"Scan_MAS",
+"SCNNREC",	"Scan_#_Records/File",
+"SCNNREF",	"Scan_#_Ref_Dets",
+"SCNNREV",	"Scan_#_Revs",
+"SCNOVER",	"Scan_#_Overscan_Dets",
+"SCNPACK",	"Scan_Data_Packing",
+"SCNPART",	"#_of_PAR_Detectors",
+"SCNPITC",	"Spiral_Pitch_Factor",
+"SCNRCSZ",	"Scan_Record_Size_Byte",
+"SCNRESO",	"Scan_Resolution",
+"SCNREVL",	"Scan_Rev_Level",
+"SCNSAMP",	"Scan_Sample",
+"SCNSOF",	"Start_of_Field",
+"SCNSPED",	"Scan_Speed",
+"SCNSPOT",	"Scan_Focal_Spot",
+"SCNSRCD",	"Source_Distance",
+"SCNSTIM",	"Scan_Slice_Time_Delta",
+"SCNSTRT",	"Scan_Start_???_<TBD>",
+"SCNTHKM",	"Scan_Thickness_Multplr",
+"SCNTHKN",	"Scan_Thickness",
+"SCNTIME",	"Scan_Acq_Time=HHMMSShh",
+"SCNTPTS",	"Scan_#_Byt_Trailing",
+"SRCE",		"Source_SCAN/TAPE/NET",
+"STNUM",	"Study_Number",
+"STNUM_X",	"Recip._Study_Number",
+"ST_UNIQ",	"Study_Collis_Resolvr",
+"S_N_CPU",	"CPU_Serial_#",
+"S_N_GNT",	"Gantry_Serial_#",
+"TMP_GN1",	"Gantry_Temp_1",
+"TMP_GN2",	"Gantry_Temp_2",
+"TMP_GN3",	"Gantry_Temp_3",
+"TMP_GN4",	"Gantry_Temp_4",
+"TYP_CPU",	"CPU_Type",
+"TYP_GNT",	"Gantry_Type",
+"TYP_TUB",	"X-Tube_Type",
+"UPDDATE",	"Update_Date_-_YYMMDD",
+"UPDTIME",	"Update_Time=HHMMSShh",
+"USDGRP",	"User_Defined_Group",
+"VOLUSED",	"Volume_Datafile_Used",
+"WINDOW",	"Window",
+"ZSCNINX",	"Spiral_Acq_Lngth",
+0,0
+
+};
+
+
+void 
+PQ_Header_BothClass::DumpCommon(TextOutputStream *log)
+{
+	Assert(log);
+
+	int i;
+	for (i=0; i < dbrec_nrec; ++i) {
+		char *vtype_label;
+		switch (db_vtype[i]) {
+			case 0:	vtype_label="asc"; break;
+			case 1:	vtype_label="int"; break;
+			case 2:	vtype_label="dat"; break;
+			case 3:	vtype_label="tim"; break;
+			case 4:	vtype_label="fil"; break;
+			case 5:	vtype_label="flg"; break;
+			case 6:	vtype_label="flt"; break;
+			default:
+				vtype_label="???"; break;
+		}
+
+		struct PQ_Data_Dictionary_Entry *ptr;
+		for (ptr=PQ_Data_Dictionary; ptr->name != 0 && strcmp(ptr->name,db_fieldname[i]) != 0; ++ptr);
+
+		(*log) << "<" << db_fieldname[i] << ">"
+		       << "\t (" << (ptr->name ? ptr->desc : "-- unrecognized --") << ")"
+		       << "\t = " << db_offset[i]
+		       << " [" << db_length[i] << "]"
+		       << " [" << db_vtype[i] << "]" << " " << vtype_label
+		       << "\t = <" << db_value[i] << ">" << endl;
+
+	}
+}
+
diff --git a/libsrc/src/dconvert/pq/pqhdrc.cc b/libsrc/src/dconvert/pq/pqhdrc.cc
new file mode 100644
index 0000000..b305bd0
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqhdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "pqptrs.h"
+#include "pqhdrp.h"
+#include "pqhdrw.h"
+#include "pqhdrc.h"
+
diff --git a/libsrc/src/dconvert/pq/pqhdrc.h b/libsrc/src/dconvert/pq/pqhdrc.h
new file mode 100644
index 0000000..7d5bf46
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqhdrc.h
@@ -0,0 +1,400 @@
+/* pqhdrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// For the Picker PQ CT format, the header is not simple enough to use
+// the template based header mechanism
+
+// The format consists of a table of attribute names, offsets, lengths and
+// types, and then an area into which this table points to get the values
+
+// The approach used here is to read those tables and values into the
+// PQ_HeaderClass, and take note of where the pixel data starts after
+// all that stuff ...
+
+PQ_HeaderClass::PQ_HeaderClass(istream *ist)
+{
+	Assert(ist);
+
+	long file_offset = 0;
+
+	// Search for "<<< Resynch field >>>" then skip to line after next '\n' ...
+
+	char c;
+	do {
+		ist->read(&c,1);
+		++file_offset;
+//cerr << "c: " << c << endl;
+	} while (c != '<' && ist->good());
+	do {
+		ist->read(&c,1);
+		++file_offset;
+//cerr << "c: " << c << endl;
+	} while (c == '<' && ist->good());
+	do {
+		ist->read(&c,1);
+		++file_offset;
+//cerr << "c: " << c << endl;
+	} while (c != '>' && ist->good());
+	do {
+		ist->read(&c,1);
+		++file_offset;
+//cerr << "c: " << c << endl;
+	} while (c == '>' && ist->good());
+	do {
+		ist->read(&c,1);
+		++file_offset;
+//cerr << "c: " << c << endl;
+	} while (c != '\n' && ist->good());
+
+	if (!ist->good()) return;
+
+	char textline2[512];
+	ist->getline(textline2,512,'\n');
+	file_offset+=ist->gcount();
+//cerr << "textline2: " << textline2 << endl;
+	char textline3[512];
+	ist->getline(textline3,512,'\n');
+	file_offset+=ist->gcount();
+//cerr << "textline3: " << textline3 << endl;
+	char textline4[512];
+	ist->getline(textline4,512,'\n');
+	file_offset+=ist->gcount();
+//cerr << "textline4: " << textline4 << endl;
+	char textline5[512];
+	ist->getline(textline5,512,'\n');
+	file_offset+=ist->gcount();
+//cerr << "textline5: " << textline5 << endl;
+
+	char *ptr;
+	char *newptr;
+
+	// e.g. "dbrec recsz:  32 nrecs: 193"
+
+	int dbrec_recsz = 0;
+	dbrec_nrec = 0;		// kept as part of class state
+
+	newptr=strdup(textline3);
+	assert(newptr);
+	if ((ptr=strtok(newptr," ")) && strncmp(ptr,"dbrec",strlen("dbrec")) == 0
+	 && (ptr=strtok(0," ")) && strncmp(ptr,"recsz:",strlen("recsz:")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		dbrec_recsz=atoi(ptr);
+	}
+	if ((ptr=strtok(0," ")) && strncmp(ptr,"nrecs:",strlen("nrecs:")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		dbrec_nrec=atoi(ptr);
+	}
+
+//cerr << "dbrec_recsz: " << dbrec_recsz << endl;
+//cerr << "dbrec_nrec: " << dbrec_nrec << endl;
+
+	if (newptr) free(newptr);
+
+	int rdb_recsz = 0;
+	int rdb_nrec = 0;
+
+	// e.g. "rdb   recsz:  64 nrecs:  25"
+
+	newptr=strdup(textline4);
+	assert(newptr);
+	if ((ptr=strtok(newptr," ")) && strncmp(ptr,"rdb",strlen("rdb")) == 0
+	 && (ptr=strtok(0," ")) && strncmp(ptr,"recsz:",strlen("recsz:")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		rdb_recsz=atoi(ptr);
+	}
+	if ((ptr=strtok(0," ")) && strncmp(ptr,"nrecs:",strlen("nrecs:")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		rdb_nrec=atoi(ptr);
+	}
+
+//cerr << "rdb_recsz: " << rdb_recsz << endl;
+//cerr << "rdb_nrec: " << rdb_nrec << endl;
+
+	if (newptr) free(newptr);
+
+	int data_offset = 0;
+	int data_offset_actual = 0;
+	int magic_num_data_dict = 0;
+	int num_sdr_fields = 0;
+
+	// e.g. "8192 =data_offset  8056 =actual; 877355679 =magic_#_data_dict; 83 =#_sdr_flds"
+
+	newptr=strdup(textline5);
+	assert(newptr);
+	if ((ptr=strtok(newptr," "))
+	) {
+		data_offset=atoi(ptr);
+	}
+
+	if ((ptr=strtok(0," ")) && strncmp(ptr,"=data_offset",strlen("=data_offset")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		data_offset_actual=atoi(ptr);
+	}
+	if ((ptr=strtok(0," ")) && strncmp(ptr,"=actual;",strlen("=actual;")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		magic_num_data_dict=atoi(ptr);
+	}
+	if ((ptr=strtok(0," ")) && strncmp(ptr,"=magic_#_data_dict;",strlen("=magic_#_data_dict;")) == 0
+	 && (ptr=strtok(0," "))
+	) {
+		num_sdr_fields=atoi(ptr);
+	}
+	// don't bother checking for trailing "=#_sdr_flds;"
+
+//cerr << "data_offset: " << data_offset << endl;
+//cerr << "data_offset_actual: " << data_offset_actual << endl;
+//cerr << "magic_num_data_dict: " << magic_num_data_dict << endl;
+//cerr << "num_sdr_fields: " << num_sdr_fields << endl;
+
+	if (newptr) free(newptr);
+
+//cerr << "file_offset (start of db records): " << file_offset << endl;
+
+	// read the db records, i.e. the table of attributes and their names/offsets/lengths/types
+
+	// (this represents the persistent state in the class)
+
+	db_fieldname = new char *  [dbrec_nrec];
+	db_offset    = new unsigned[dbrec_nrec];
+	db_length    = new unsigned[dbrec_nrec];
+	db_vtype     = new unsigned[dbrec_nrec];
+	db_value     = new char *  [dbrec_nrec];
+
+	Assert(db_fieldname);
+	Assert(db_offset);
+	Assert(db_length);
+	Assert(db_vtype);
+	Assert(db_value);
+
+	int i;
+	for (i=0; i < dbrec_nrec; ++i) {
+		char s_fieldname[9];
+		unsigned char s_offset[2];
+		unsigned char s_length[2];
+		unsigned char s_field3[2];
+		unsigned char s_field4[2];
+		unsigned char s_vtype[2];
+		char s_filler[64];		// actually only need dbrec_recsz-18 (should be 14)
+
+		long file_offset_start=file_offset;
+
+		ist->read(s_fieldname,8); s_fieldname[8]=0;
+		file_offset+=ist->gcount();
+		ist->read((char *)s_offset,2);
+		file_offset+=ist->gcount();
+		ist->read((char *)s_length,2);
+		file_offset+=ist->gcount();
+		ist->read((char *)s_field3,2);
+		file_offset+=ist->gcount();
+		ist->read((char *)s_field4,2);
+		file_offset+=ist->gcount();
+		ist->read((char *)s_vtype,2);
+		file_offset+=ist->gcount();
+		ist->read(s_filler,dbrec_recsz-18);
+		file_offset+=ist->gcount();
+
+		db_fieldname[i]=new char[strlen(s_fieldname)+1];
+		strcpy(db_fieldname[i],s_fieldname);
+
+		db_offset[i]=((unsigned)s_offset[0]<<8)+s_offset[1];
+		db_length[i]=((unsigned)s_length[0]<<8)+s_length[1];
+		db_vtype[i]=((unsigned)s_vtype[0] <<8)+s_vtype[1];
+#ifdef CRAP
+		cerr << file_offset_start << ": "
+		     << "<" << db_fieldname[i] << ">"
+		     << "\t = " << db_offset[i]
+		     << " [" << db_length[i] << "]"
+		     << " [" << db_vtype[i] << "]"
+		     << endl;
+#endif
+	}
+
+	// read the rdb records (i.e. the actual values of the attributes) ...
+
+	int rdb_length = rdb_recsz*rdb_nrec;
+	char *rdb_values = new char[rdb_length];
+	Assert(rdb_values);
+	ist->read(rdb_values,rdb_length);
+	Assert(ist->gcount() == rdb_length);
+	file_offset+=rdb_length;
+
+	// fill in the attribute table with values ...
+
+	for (i=0; i < dbrec_nrec; ++i) {
+		char *vtype_label;
+		switch (db_vtype[i]) {
+			case 0:	vtype_label="asc"; break;
+			case 1:	vtype_label="int"; break;
+			case 2:	vtype_label="dat"; break;
+			case 3:	vtype_label="tim"; break;
+			case 4:	vtype_label="fil"; break;
+			case 5:	vtype_label="flg"; break;
+			case 6:	vtype_label="flt"; break;
+			default:
+				vtype_label="???"; break;
+		}
+		char *value=new char[db_length[i]+1];
+		Assert(value);
+		Assert(db_offset[i]+db_length[i] <= rdb_length);
+		strncpy(value,rdb_values+db_offset[i],db_length[i]);
+		value[db_length[i]]=0;
+
+		db_value[i]=value;
+#ifdef CRAP
+
+		cerr << "<" << db_fieldname[i] << ">"
+		     << "\t = " << db_offset[i]
+		     << " [" << db_length[i] << "]"
+		     << " [" << db_vtype[i] << "]" << " " << vtype_label
+		     << "\t = <" << db_value[i] << ">" << endl;
+#endif
+	}
+
+	if (rdb_values) delete[] rdb_values;	// anything useful already copied out
+
+//cerr << "file_offset (end of db records): " << file_offset << endl;
+
+	//pixel_offset=file_offset+8;		// skip the "\nEND=\n--"
+	pixel_offset=file_offset+(data_offset-data_offset_actual);
+
+//cerr << "pixel_offset: " << pixel_offset << endl;
+}
+
+PQ_HeaderClass::~PQ_HeaderClass(void)
+{
+	// all strings were copied ...
+
+	if (db_fieldname) {
+		int i;
+		for (i=0; i < dbrec_nrec; ++i) {
+			if (db_fieldname[i]) delete[] db_fieldname[i];
+		}
+		delete[] db_fieldname;
+	}
+	if (db_value) {
+		int i;
+		for (i=0; i < dbrec_nrec; ++i) {
+			if (db_value[i]) delete[] db_value[i];
+		}
+		delete[] db_value;
+	}
+	if (db_offset) delete[] db_offset;
+	if (db_length) delete[] db_length;
+	if (db_vtype) delete[] db_vtype;
+}
+
+bool
+PQ_HeaderClass::getAttributeEntry(const char *name,int &index) const
+{
+	Assert(name);
+	int i;
+	for (i=0; i < dbrec_nrec; ++i) {
+		if (strcmp(db_fieldname[i],name) == 0) {
+			Assert(db_value[i] != 0);
+			index=i;
+			return true;
+		}
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getStringAttribute(const char *name,int &index,char *&value,int &length) const
+{
+	if (getAttributeEntry(name,index)) {
+		length=db_length[index];
+		value=new char[length+1];
+		Assert(value);
+		strcpy(value,db_value[index]);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getAsciiAttribute(const char *name,char *&value,int &length) const
+{
+	int index;
+	if (getStringAttribute(name,index,value,length)) {
+		//Assert(db_vtype[index] == 0);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getIntegerAttribute(const char *name,Int32 &value) const
+{
+	int index;
+	if (getAttributeEntry(name,index)) {
+		//Assert(db_vtype[index] == 1 || db_vtype[index] == 6);	// allow float to int conversion
+		Assert(db_length[index] > 0);
+		Assert(*(db_value[index]));
+		value=atoi(db_value[index]);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getDateAttribute(const char *name,char *&value,int &length) const
+{
+	int index;
+	if (getStringAttribute(name,index,value,length)) {
+		//Assert(db_vtype[index] == 2);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getTimeAttribute(const char *name,char *&value,int &length) const
+{
+	int index;
+	if (getStringAttribute(name,index,value,length)) {
+		//Assert(db_vtype[index] == 3);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getFileAttribute(const char *name,char *&value,int &length) const
+{
+	int index;
+	if (getStringAttribute(name,index,value,length)) {
+		//Assert(db_vtype[index] == 4);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getFlagAttribute(const char *name,char *&value,int &length) const
+{
+	int index;
+	if (getStringAttribute(name,index,value,length)) {
+		//Assert(db_vtype[index] == 5);
+		return true;
+	}
+	return false;
+}
+
+bool
+PQ_HeaderClass::getFloatAttribute(const char *name,Float64 &value) const
+{
+	int index;
+	if (getAttributeEntry(name,index)) {
+		//Assert(db_vtype[index] == 6 || db_vtype[index] == 1);	// allow int to float conversion
+		Assert(db_length[index] > 0);
+		Assert(*(db_value[index]));
+		value=atof(db_value[index]);
+		return true;
+	}
+	return false;
+}
+
diff --git a/libsrc/src/dconvert/pq/pqhdrp.h b/libsrc/src/dconvert/pq/pqhdrp.h
new file mode 100644
index 0000000..6d779f9
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqhdrp.h
@@ -0,0 +1,47 @@
+/* pqhdrp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifdef CRAP
+
+// Automatically generated from template - EDITS WILL BE LOST
+//
+// Generated by tpltohdr.awk with options or defaults ...
+//
+// 	 role=headerpart
+// 	 prefix=PQ_
+// 	 dicomfunctionname=ToDicom_Template
+// 	 dumpcommonfunctionname=DumpCommon
+// 	 dumpselectedimagefunctionname=DumpSelectedImage
+// 	 headeroffsetprefix=PQ_Offset
+// 	 headeroffsetsuffix=ptr
+// 	 headerclassprefix=PQ_HeaderClass
+// 	 headerdicomclassprefix=PQ_Header_BothClass
+// 	 headerdumpclassprefix=PQ_Header_BothClass
+// 	 headerinstanceprefix=PQ_HeaderInstance
+// 	 methodnameprefix=PQ_Method
+// 	 methodconstructorargsprefix=PQ_MethodConstructorArgs
+// 	 headerclassparameters=
+
+class PQ_HeaderClass_STDHDR {
+public:
+	PQ_HeaderClass_STDHDR(istream *ist,long offset)
+		 { ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+};
+
+class PQ_HeaderClass_IMGHDR {
+public:
+	PQ_HeaderClass_IMGHDR(istream *ist,long offset)
+		 { ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+};
+
+class PQ_HeaderClass_IMGHDR2 {
+public:
+	PQ_HeaderClass_IMGHDR2(istream *ist,long offset)
+		 { ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+};
+
+#endif
+
+// empty
+
diff --git a/libsrc/src/dconvert/pq/pqhdrw.h b/libsrc/src/dconvert/pq/pqhdrw.h
new file mode 100644
index 0000000..2d2c907
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqhdrw.h
@@ -0,0 +1,62 @@
+/* pqhdrw.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifdef CRAP
+
+// Automatically generated from template - EDITS WILL BE LOST
+//
+// Generated by tpltohdr.awk with options or defaults ...
+//
+// 	 role=wholeheader
+// 	 prefix=PQ_
+// 	 dicomfunctionname=ToDicom_Template
+// 	 dumpcommonfunctionname=DumpCommon
+// 	 dumpselectedimagefunctionname=DumpSelectedImage
+// 	 headeroffsetprefix=PQ_Offset
+// 	 headeroffsetsuffix=ptr
+// 	 headerclassprefix=PQ_HeaderClass
+// 	 headerdicomclassprefix=PQ_Header_BothClass
+// 	 headerdumpclassprefix=PQ_Header_BothClass
+// 	 headerinstanceprefix=PQ_HeaderInstance
+// 	 methodnameprefix=PQ_Method
+// 	 methodconstructorargsprefix=PQ_MethodConstructorArgs
+// 	 headerclassparameters=
+
+class PQ_HeaderClass
+{
+public:
+	PQ_HeaderClass(istream *ist);
+
+	PQ_HeaderClass_STDHDR *PQ_HeaderInstance_STDHDR;
+	PQ_HeaderClass_IMGHDR *PQ_HeaderInstance_IMGHDR;
+	PQ_HeaderClass_IMGHDR2 *PQ_HeaderInstance_IMGHDR2;
+};
+
+#endif
+
+class PQ_HeaderClass
+{
+protected: 
+	int dbrec_nrec;
+	char **db_fieldname;
+	unsigned *db_offset;
+	unsigned *db_length;
+	unsigned *db_vtype;
+	char **db_value;
+	long pixel_offset;
+
+	bool getAttributeEntry(const char *name,int &index) const;
+	bool getStringAttribute(const char *name,int &index,char *&value,int &length) const;
+public:
+	PQ_HeaderClass(istream *ist);
+	~PQ_HeaderClass();
+
+	bool getAsciiAttribute(const char *name,char *&value,int &length) const;
+	bool getIntegerAttribute(const char *name,Int32 &value) const;
+	bool getDateAttribute(const char *name,char *&value,int &length) const;
+	bool getTimeAttribute(const char *name,char *&value,int &length) const;
+	bool getFileAttribute(const char *name,char *&value,int &length) const;
+	bool getFlagAttribute(const char *name,char *&value,int &length) const;
+	bool getFloatAttribute(const char *name,Float64 &value) const;
+
+	long getPixelOffset(void) const { return pixel_offset; }
+};
+
diff --git a/libsrc/src/dconvert/pq/pqmdt.cc b/libsrc/src/dconvert/pq/pqmdt.cc
new file mode 100644
index 0000000..a4cef43
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqmdt.cc
@@ -0,0 +1,111 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pqdc.h"
+#include "elmconst.h"
+
+void 
+PQ_Header_BothClass::ToDicom_ManualDates(AttributeList *list)
+{
+	{
+		// ContentDate (formerly Image)
+
+		char *pq_recon_date;
+		int length;
+		if (getDateAttribute("RCNDATE",pq_recon_date,length) && length >= 6) {
+			char *withdelim=new char[length+4];
+			Assert(withdelim);
+			strncpy(withdelim,pq_recon_date,2);
+			withdelim[2]='/';
+			strncpy(withdelim+3,pq_recon_date+2,2);
+			withdelim[5]='/';
+			strncpy(withdelim+6,pq_recon_date+4,length-4);
+			withdelim[length+3]=0;
+
+			(*list)+=new DateStringAttribute(TagFromName(ContentDate),Date(withdelim,DateOrderMonthMiddleYearFirst));
+
+			if (pq_recon_date) delete[] pq_recon_date;
+			if (withdelim) delete[] withdelim;
+		}
+		else {
+			(*list)+=new DateStringAttribute(TagFromName(ContentDate));	// Type 2
+		}
+	}
+	{
+		// ContentTime (formerly Image)
+
+		char *pq_recon_time;	// in hundredths of a second
+		int length;
+		if (getTimeAttribute("RCNTIME",pq_recon_time,length) && length >= 6) {
+			char *withdelim=new char[length+4];
+			Assert(withdelim);
+			strncpy(withdelim,pq_recon_time,2);
+			withdelim[2]=':';
+			strncpy(withdelim+3,pq_recon_time+2,2);
+			withdelim[5]=':';
+			strncpy(withdelim+6,pq_recon_time+4,2);
+			withdelim[8]='.';
+			strncpy(withdelim+9,pq_recon_time+6,length-6);
+			withdelim[length+3]=0;
+
+			(*list)+=new TimeStringAttribute(TagFromName(ContentTime),Time(withdelim));
+			if (pq_recon_time) delete[] pq_recon_time;
+			if (withdelim) delete[] withdelim;
+		}
+		else {
+			(*list)+=new TimeStringAttribute(TagFromName(ContentTime));	// Type 2
+		}
+	}
+	{
+		// AcquisitionDate, StudyDate
+
+		char *pq_scan_acq_date;
+		int length;
+		if (getDateAttribute("SCNDATE",pq_scan_acq_date,length) && length >= 6) {
+
+			char *withdelim=new char[length+4];
+			Assert(withdelim);
+			strncpy(withdelim,pq_scan_acq_date,2);
+			withdelim[2]='/';
+			strncpy(withdelim+3,pq_scan_acq_date+2,2);
+			withdelim[5]='/';
+			strncpy(withdelim+6,pq_scan_acq_date+4,length-4);
+			withdelim[length+3]=0;
+
+			(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),Date(withdelim,DateOrderMonthMiddleYearFirst));
+			(*list)+=new DateStringAttribute(TagFromName(StudyDate),Date(withdelim,DateOrderMonthMiddleYearFirst));
+			if (pq_scan_acq_date) delete[] pq_scan_acq_date;
+			if (withdelim) delete[] withdelim;
+		}
+		else {
+			(*list)+=new DateStringAttribute(TagFromName(StudyDate));	// Type 2
+		}
+	}
+	{
+		// AcquisitionTime, StudyTime
+
+		char *pq_scan_acq_time;	// in hundredths of a second
+		int length;
+		if (getTimeAttribute("SCNTIME",pq_scan_acq_time,length) && length >= 6) {
+			char *withdelim=new char[length+4];
+			Assert(withdelim);
+			strncpy(withdelim,pq_scan_acq_time,2);
+			withdelim[2]=':';
+			strncpy(withdelim+3,pq_scan_acq_time+2,2);
+			withdelim[5]=':';
+			strncpy(withdelim+6,pq_scan_acq_time+4,2);
+			withdelim[8]='.';
+			strncpy(withdelim+9,pq_scan_acq_time+6,length-6);
+			withdelim[length+3]=0;
+
+			(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),Time(withdelim));
+			(*list)+=new TimeStringAttribute(TagFromName(StudyTime),Time(withdelim));
+			if (pq_scan_acq_time) delete[] pq_scan_acq_time;
+			if (withdelim) delete[] withdelim;
+		}
+		else {
+			(*list)+=new TimeStringAttribute(TagFromName(StudyTime));	// Type 2
+		}
+	}
+
+	// forget about Series Date/Time
+}
+
diff --git a/libsrc/src/dconvert/pq/pqmmsc.cc b/libsrc/src/dconvert/pq/pqmmsc.cc
new file mode 100644
index 0000000..7d820c9
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqmmsc.cc
@@ -0,0 +1,831 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pqdc.h"
+#include "elmconst.h"
+
+void 
+PQ_Header_BothClass::ToDicom_ManualMisc(AttributeList *list)
+{
+	// General Patient and Patient Study Modules
+
+	{
+		// PatientID
+
+		char *pq_patient_id;
+		int length;
+		if (getAsciiAttribute("PATID",pq_patient_id,length)) {
+			(*list)+=new LongStringAttribute(TagFromName(PatientID),pq_patient_id);
+			if (pq_patient_id) delete[] pq_patient_id;
+		}
+		else {
+			(*list)+=new LongStringAttribute(TagFromName(PatientID));	// Type 2
+		}
+	}
+	{
+		// PatientName
+
+		char *pq_patient_last_name;
+		int length;
+		if (getAsciiAttribute("PATNAM",pq_patient_last_name,length)) {
+			(*list)+=new PersonNameAttribute(TagFromName(PatientName),pq_patient_last_name);
+			if (pq_patient_last_name) delete[] pq_patient_last_name;
+		}
+		else {
+			(*list)+=new PersonNameAttribute(TagFromName(PatientName));	// Type 2
+		}
+	}
+	{
+		// PatientBirthDate
+
+		(*list)+=new DateStringAttribute(TagFromName(PatientBirthDate));	// Type 2
+	}
+	{
+		// PatientAge
+
+		Int32 pq_patient_age;
+		int length;
+		ostrstream ost;
+		ost << setfill('0') << setw(3) << dec;
+		if (getIntegerAttribute("PATAGYR",pq_patient_age) || getIntegerAttribute("PATAGE",pq_patient_age)) {
+			ost << pq_patient_age << "Y";
+		}
+		else if (getIntegerAttribute("PATAGMO",pq_patient_age)) {
+			ost << pq_patient_age << "M";
+		}
+		else if (getIntegerAttribute("PATAGDA",pq_patient_age)) {
+			ost << pq_patient_age << "D";
+		}
+		else if (getIntegerAttribute("PATAGHR",pq_patient_age)) {
+			ost << unsigned(pq_patient_age/24) << "D";		// no hours in DICOM
+		}
+		ost << ends;
+		char *agestr=ost.str();
+		if (agestr) {
+			if (strlen(agestr)) (*list)+=new AgeStringAttribute(TagFromName(PatientAge),agestr);
+			delete[] agestr;
+		}
+	}
+	{
+/*
+* Valid Values of: Patient_Sex == PATSEX
+*=RNG PATSEX
+Female
+*=RNG PATSEX
+Male
+*=RNG PATSEX
+Other
+*/
+		// PatientSex
+
+		const char *patient_sex = 0;
+		char *pq_patient_sex;
+		int length;
+		if (getAsciiAttribute("PATSEX",pq_patient_sex,length)) {
+			if (length >= 1 && strncmp(pq_patient_sex,"M",1) == 0) {
+				patient_sex="M";
+			}
+			else if (length >= 1 && strncmp(pq_patient_sex,"F",1) == 0) {
+				patient_sex="F";
+			}
+			else if (length >= 1 && strncmp(pq_patient_sex,"O",1) == 0) {
+				patient_sex="O";
+			}
+			if (pq_patient_sex) delete[] pq_patient_sex;
+		}
+		if (!patient_sex) patient_sex="";	// Type 2
+		(*list)+=new CodeStringAttribute(TagFromName(PatientSex),patient_sex);
+	}
+
+	// General Study Module
+
+	{
+		// StudyID
+
+		Int32 pq_study_number;
+		int length;
+		if (getIntegerAttribute("STNUM",pq_study_number)) {
+			(*list)+=new ShortStringAttribute(TagFromName(StudyID),pq_study_number);
+		}
+		else {
+			(*list)+=new ShortStringAttribute(TagFromName(StudyID));
+		}
+	}
+	
+	// AccessionNumber
+
+	(*list)+=new ShortStringAttribute(TagFromName(AccessionNumber));	// Type 2
+
+	{
+		// ReferringPhysicianName
+
+		char *pq_referring_physician;
+		int length;
+		if (getAsciiAttribute("REFPHY",pq_referring_physician,length)) {
+			(*list)+=new PersonNameAttribute(TagFromName(ReferringPhysicianName),pq_referring_physician);
+			if (pq_referring_physician) delete[] pq_referring_physician;
+		}
+		else {
+			(*list)+=new PersonNameAttribute(TagFromName(ReferringPhysicianName));	// Type 2
+		}
+	}
+	{
+		// NameOfPhysiciansReadingStudy
+
+		char *pq_referring_radiologist;
+		int length;
+		if (getAsciiAttribute("REFRAD",pq_referring_radiologist,length)) {
+			(*list)+=new PersonNameAttribute(TagFromName(NameOfPhysiciansReadingStudy),pq_referring_radiologist);
+			if (pq_referring_radiologist) delete[] pq_referring_radiologist;
+		}
+		// Type 3
+	}
+
+	// General Series Module
+
+	{
+
+		// SeriesNumber
+
+		// PQ header doesn't have a series number ... put in different
+		// series based on recon algorithm (since image numbers duplicated)
+		
+		Uint16 series_number=0;
+
+		char *pq_recon_algorithm;
+		int length;
+		if (getAsciiAttribute("RCNALG",pq_recon_algorithm,length)) {
+			if (length >= 4 && strncmp(pq_recon_algorithm,"????",4) == 0) series_number=1;	// localizer
+			else if (length >= 4 && strncmp(pq_recon_algorithm,"STD",3) == 0) series_number=2;
+			else if (length >= 4 && strncmp(pq_recon_algorithm,"BONE",4) == 0) series_number=3;
+			else if (length >= 1) series_number=4;						// don't know
+			if (pq_recon_algorithm) delete[] pq_recon_algorithm;
+		}
+
+		(*list)+=new IntegerStringAttribute(TagFromName(SeriesNumber),series_number);
+	}
+
+	// Laterality
+
+	(*list)+=new CodeStringAttribute(TagFromName(Laterality));	// Type 2C
+
+	// Modality
+
+	{
+/*
+* Valid Values of: Modality == MODAL:
+*=RNG MODAL
+CT Scanner (includes CT Pilots?)
+*=RNG MODAL
+EKG 
+*=RNG MODAL
+*=RNG MODAL
+NUCL
+Nuclear Medicine
+*=RNG MODAL
+PET Scan
+*=RNG MODAL
+Projection Radiography
+*/
+		char *pq_modality;
+		int length;
+		const char *modality;
+		if (getAsciiAttribute("MODAL",pq_modality,length)) {
+			if (length >= 2 && strncmp(pq_modality,"CT",2) == 0) {
+				modality="CT";
+			}
+			if (pq_modality) delete[] pq_modality;
+		}
+		if (!modality) modality="OT";
+		(*list)+=new CodeStringAttribute(TagFromName(Modality),modality);
+	}
+
+	{
+		// OperatorsName
+
+		char *pq_operator_id;
+		int length;
+		if (getAsciiAttribute("OPERID",pq_operator_id,length)) {
+			(*list)+=new PersonNameAttribute(TagFromName(OperatorsName),pq_operator_id);
+			if (pq_operator_id) delete[] pq_operator_id;
+		}
+		// Type 3
+	}
+
+	{
+		// ProtocolName
+
+		char *pq_scan_protocol;
+		int length;
+		if (getAsciiAttribute("PRTSCAN",pq_scan_protocol,length)) {
+			(*list)+=new LongStringAttribute(TagFromName(ProtocolName),pq_scan_protocol);
+			if (pq_scan_protocol) delete[] pq_scan_protocol;
+		}
+		// Type 3
+	}
+
+
+	// General Equipment Module
+
+	// Manufacturer
+
+	(*list)+=new LongStringAttribute(TagFromName(Manufacturer),"Picker");
+
+	{
+		// InstitutionName
+
+		char *pq_hospital_name;
+		int length;
+		if (getAsciiAttribute("SCNHOSP",pq_hospital_name,length)) {
+			(*list)+=new LongStringAttribute(TagFromName(InstitutionName),pq_hospital_name);
+			if (pq_hospital_name) delete[] pq_hospital_name;
+		}
+		// Type 3
+	}
+
+	{
+		// ManufacturerModelName
+
+		char *pq_gantry_type;
+		int length;
+		if (getAsciiAttribute("TYP_GNT",pq_gantry_type,length)) {
+			(*list)+=new LongStringAttribute(TagFromName(ManufacturerModelName),pq_gantry_type);
+			if (pq_gantry_type) delete[] pq_gantry_type;
+		}
+		// Type 3
+	}
+
+	{
+		// DeviceSerialNumber
+
+		Int32 pq_gantry_serial_number;
+		if (getIntegerAttribute("S_N_GNT",pq_gantry_serial_number)) {
+			(*list)+=new LongStringAttribute(TagFromName(DeviceSerialNumber),pq_gantry_serial_number);
+		}
+		// Type 3
+	}
+
+	{
+		// SoftwareVersions
+
+		char *pq_scanner_rev_level;
+		int length;
+		if (getAsciiAttribute("SCNREVL",pq_scanner_rev_level,length)) {
+			(*list)+=new LongStringAttribute(TagFromName(SoftwareVersions),pq_scanner_rev_level);
+			if (pq_scanner_rev_level) delete[] pq_scanner_rev_level;
+		}
+		// Type 3
+	}
+
+	// General Image Module
+
+	{
+		// InstanceNumber
+
+		Int32 pq_image_number;
+		if (getIntegerAttribute("IMNUM",pq_image_number)) {
+			(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber),pq_image_number);
+		}
+		else {
+			(*list)+=new IntegerStringAttribute(TagFromName(InstanceNumber));	// Type 2
+		}
+	}
+
+	// AcquisitionNumber
+
+	(*list)+=new IntegerStringAttribute(TagFromName(AcquisitionNumber));	// Type 3, but 2 in CT Image
+
+	// ImageType
+
+	{
+/*
+* Valid Values of: Image Type == IMTYPE:
+*=RNG IMTYPE
+SLIC
+Slice
+*=RNG IMTYPE
+PILT
+Pilot
+*=RNG IMTYPE
+SYNT
+Synthetic, look at IMTYPSY for details
+*=RNG IMTYPE
+DATA
+Non-Image Data (Text, EKG, etc)
+*/
+		const char *value1="ORIGINAL";
+		const char *value2="PRIMARY";
+		const char *value3=0;
+
+		char *pq_image_type;
+		int length;
+		if (getAsciiAttribute("IMTYPE",pq_image_type,length)) {
+			if (length >= 4
+			&& (strncmp(pq_image_type,"SLIC",4) == 0
+			 || strncmp(pq_image_type,"SPIR",4) == 0) ) {
+				value3="AXIAL";
+			}
+			else if (length >= 3 && strncmp(pq_image_type,"PIL",3) == 0) {	// db says PILT, files contain PILO
+				value3="LOCALIZER";
+			}
+			if (pq_image_type) delete[] pq_image_type;
+		}
+		if (!value3) value3="";
+
+		(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+			value1,value2,value3);
+	}
+
+	// ContrastBolus Module
+
+	{
+		// ContrastBolusAgent
+
+		char *pq_contrast;
+		int length;
+		if (getAsciiAttribute("CONTR",pq_contrast,length)) {
+			if (length >= 2 && strncmp(pq_contrast,"C+",2) == 0) {
+				(*list)+=new LongStringAttribute(TagFromName(ContrastBolusAgent),"C+");
+			}
+			if (pq_contrast) delete[] pq_contrast;
+		}
+	}
+
+	// CT Image Module
+
+	{
+		// KVP, XRayTubeCurrent, Exposure
+
+		// ? need to check pilot values PILTKV, PILTMA, PILTMAS
+
+		Int32 pq_kv;
+		if (getIntegerAttribute("SCNKV",pq_kv))
+			(*list)+=new DecimalStringAttribute(TagFromName(KVP),pq_kv);
+
+		Int32 pq_ma;
+		if (getIntegerAttribute("SCNMA",pq_ma))
+			(*list)+=new IntegerStringAttribute(TagFromName(XRayTubeCurrent),pq_ma);
+
+		Int32 pq_mas;
+		if (getIntegerAttribute("SCNMAS",pq_mas))
+			(*list)+=new IntegerStringAttribute(TagFromName(Exposure),pq_mas);
+
+		// DistanceSourceToDetector
+
+		Float64 pq_source_distance;
+		if (getFloatAttribute("SCNSRCD",pq_source_distance))
+			(*list)+=new DecimalStringAttribute(TagFromName(DistanceSourceToDetector),pq_source_distance);
+
+		// ConvolutionKernel
+
+		char *pq_recon_algorithm;
+		int length;
+		if (getAsciiAttribute("RCNALG",pq_recon_algorithm,length)) {
+			(*list)+=new ShortStringAttribute(TagFromName(ConvolutionKernel),pq_recon_algorithm);
+			if (pq_recon_algorithm) delete[] pq_recon_algorithm;
+		}
+
+		// DataCollectionDiameter
+		// ReconstructionDiameter
+		// GantryDetectorTilt
+		// TableHeight
+
+		// .. see pqmpln.h
+	}
+
+#ifdef CRAP
+	// GeneratorPower
+
+	// Loose fractional part ...
+
+	(*list)+=new IntegerStringAttribute(TagFromName(GeneratorPower),
+		(unsigned short)(atof(PQ_HeaderInstance_IMGHDR->IGENPOW)));
+
+	{
+		// SoftwareVersions
+
+		ostrstream ost;
+		ost << "System "    << PQ_HeaderInstance_STDHDR->SSYSVNO
+		    << "."          << PQ_HeaderInstance_STDHDR->SSYSRNO
+		    << " Database " << PQ_HeaderInstance_STDHDR->SDATVNO
+		    << "."          << PQ_HeaderInstance_STDHDR->SDATRNO
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new LongStringAttribute(TagFromName(SoftwareVersions),str);
+		if (str) delete[] str;
+	}
+	{
+		// StationName 
+
+		ostrstream ost;
+		ost << PQ_HeaderInstance_STDHDR->SMODELNO_Mod << "."
+		    << PQ_HeaderInstance_STDHDR->SMODELNO_Mac << "."
+		    << PQ_HeaderInstance_STDHDR->SMACHINE
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new ShortStringAttribute(TagFromName(StationName),str);
+		if (str) delete[] str;
+	}
+
+	// Do the descriptions ...
+
+	class Description {
+		ostrstream ost;
+		int first;
+		char delim;
+	public:
+		Description(char d=0)	{ first=1; delim=d; }
+
+		void add(const char *desc,unsigned maxlength)
+			{
+				char *buf = new char[maxlength+1];
+				strncpy(buf,desc,maxlength); buf[maxlength]=0;
+				char *lastspq=strrchr(buf,' ');
+				if (lastspq && buf[maxlength-1] == ' ')
+					*lastspq=0;
+				char *start = buf;
+				while (*start && *start == ' ') ++start;
+				if (*start) {
+					if (!first && delim) ost << delim;
+					ost << start;
+				}
+				first=0;
+				if (buf) delete[] buf;
+			}
+
+		char *get(void)		{ ost << ends; return ost.str(); }
+	};
+
+	{
+		// StudyDescription
+
+		Description desc(' ');
+		desc.add(PQ_HeaderInstance_STDHDR->SDESC1,50);
+		desc.add(PQ_HeaderInstance_STDHDR->SDESC2,50);
+		desc.add(PQ_HeaderInstance_STDHDR->SDESC3,50);
+		desc.add(PQ_HeaderInstance_STDHDR->SDESC4,50);
+		desc.add(PQ_HeaderInstance_STDHDR->SDESC5,50);
+
+		char *str=desc.get();
+		unsigned length=strlen(str);
+		if (length > 64) {
+			str[64]=0;
+			length=64;
+		}
+
+		(*list)+=new LongStringAttribute(TagFromName(StudyDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// SeriesDescription
+
+		Description desc(' ');
+		desc.add(PQ_HeaderInstance_IMGHDR2->ISRDESC1,16);
+		desc.add(PQ_HeaderInstance_IMGHDR2->ISRDESC2,14);
+		desc.add(PQ_HeaderInstance_IMGHDR2->ISRDESC3,12);
+
+		char *str=desc.get();
+
+		(*list)+=new LongStringAttribute(TagFromName(SeriesDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// ImageComments
+
+		Description desc(' ');
+		desc.add(PQ_HeaderInstance_IMGHDR2->IIMDESC1,10);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IIMDESC2,8);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IIMDESC3,7);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(ImageComments),str);
+		if (str) delete[] str;
+	}
+	{
+		// AdditionalPatientHistory
+
+		Description desc(' ');
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC1,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC2,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC3,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC4,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC5,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC6,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC7,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC8,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC9,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC10,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC11,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC12,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC13,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC14,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC15,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC16,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC17,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC18,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC19,17);
+		desc.add(PQ_HeaderInstance_IMGHDR2->IEXDESC20,17);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(AdditionalPatientHistory),str);
+		if (str) delete[] str;
+	}
+#endif
+}
+
+#ifdef CRAP
+<COMNT_D>	 (Display_Brief_Commnt)	 = 1 [24] [0] asc	 = <HEAD                    >
+<COMNT_1>	 (Comments_1)	 = 530 [60] [0] asc	 = <HEAD                                                        >
+<COMNT_2>	 (Comments_2)	 = 590 [60] [0] asc	 = <                                                            >
+<COMNT_3>	 (Comments_3)	 = 650 [60] [0] asc	 = <                                                            >
+<COMNT_4>	 (Comments_4)	 = 710 [60] [0] asc	 = <                                                            >
+
+
+<COUCHAQ>	 (Init_Couch_Pos_1234.12)	 = 37 [8] [1] int	 = <   22900>
+<COUCHHT>	 (Couch_Height)	 = 45 [4] [1] int	 = < 343>
+<COUCHIM>	 (Couch_Index_Multiplier)	 = 49 [3] [1] int	 = < 10>
+<COUCHIX>	 (Couch_Index)	 = 52 [6] [1] int	 = <   -50>
+<COUCH>	 (Couch_Posit_1234.12)	 = 29 [8] [1] int	 = <   22900>
+
+<GTILT>	 (Gantry_Tilt_-12.1)	 = 98 [4] [1] int	 = <-240>
+
+<POSHF>	 (Position_Head/Feet)	 = 300 [4] [0] asc	 = <HEAD>
+<POSPRN>	 (Position_Prone/Supine)	 = 304 [4] [0] asc	 = <SUPI>
+
+<SCNFSIZ>	 (Scan_Fld_Siz_mm)	 = 400 [4] [1] int	 = < 240>
+<SCNTHKM>	 (Scan_Thickness_Multplr)	 = 446 [3] [1] int	 = < 10>
+<SCNTHKN>	 (Scan_Thickness)	 = 449 [4] [1] int	 = <  50>
+
+<RCNFSIZ>	 (Recon_Fld_Size_mm)	 = 343 [4] [1] int	 = < 240>
+<RCNMTRX>	 (Recon_Matrix_Pixels)	 = 347 [4] [1] int	 = < 512>
+
+<RCNALG>	 (Recon_Algorithm)	 = 1138 [4] [0] asc	 = <BONE>
+
+
+
+<SCNSPED>	 (Scan_Speed)	 = 1535 [4] [1] int	 = <  15>
+<SCNSPOT>	 (Scan_Focal_Spot)	 = 1539 [4] [1] int	 = <   1>
+<SCNSRCD>	 (Source_Distance)	 = 1543 [16] [6] flt	 = <635.359924      >
+
+
+
+<AAA_DEL>	 (Deleted_Flag)	 = 0 [1] [5] flg	 = <?>
+<DICONTX>	 (Display_Context)	 = 58 [2] [0] asc	 = < A>
+<FA_HLMN>	 (HL_Manual_Xmit_Flg[])	 = 60 [16] [5] flg	 = <????????????????>
+<FOLDER>	 (Folder_Name)	 = 76 [8] [0] asc	 = <TAPE    >
+<F_A_EXB>	 (Exabyte_Auto_Arch_Fl)	 = 84 [1] [5] flg	 = <X>
+<F_A_OPD>	 (O-Disk_Auto_Arch_Fl)	 = 85 [1] [5] flg	 = < >
+<F_CMPRS>	 (Image_Compressed_Flg)	 = 86 [1] [5] flg	 = <0>
+<F_COMPL>	 (Image_Complete_Flag)	 = 87 [1] [5] flg	 = <C>
+<F_DELOK>	 (Image_Delete_OK_Flag)	 = 88 [1] [5] flg	 = < >
+<F_FILMD>	 (Image_Filmed_Flag)	 = 89 [1] [5] flg	 = <?>
+<F_FILOK>	 (Image_Film_OK_Flag)	 = 90 [1] [5] flg	 = < >
+<F_HLANY>	 (Any_Archive_Flags_Set)	 = 91 [1] [5] flg	 = <?>
+<F_HLAUT>	 (Auto_Xmit_Requested)	 = 92 [1] [5] flg	 = < >
+<F_M_EXB>	 (Exabyte_Manual_Arch_Fl)	 = 93 [1] [5] flg	 = < >
+<F_M_OPD>	 (Disk_Manual_Arch_Fl)	 = 94 [1] [5] flg	 = < >
+<F_N_DEL>	 (Non-Deletable)	 = 95 [1] [5] flg	 = < >
+<F_RPROK>	 (Image_Reproc_OK_Flag)	 = 96 [1] [5] flg	 = < >
+<F_SHAPE>	 (Image_Shaped_Flag)	 = 97 [1] [5] flg	 = <S>
+<IMFCLAS>	 (Img_File_Class_Flg)	 = 102 [1] [5] flg	 = <I>
+<IMFICON>	 (Img_File_Contg_Flg)	 = 103 [1] [5] flg	 = <C>
+<IMFILE>	 (Image_File_Name)	 = 104 [12] [4] fil	 = <IM.000012070>
+<IMFIOFS>	 (Img_File_Hdr_Ofs_Byt)	 = 116 [5] [1] int	 = < 8192>
+<IMFISIZ>	 (Img_File_Size_Bytes)	 = 121 [10] [1] int	 = <    532480>
+<IMFPATH>	 (Image_File_Path)	 = 131 [20] [0] asc	 = </usr/IQ/datad/      >
+<LABBOTT>	 (Bottom_Label)	 = 163 [12] [0] asc	 = <POSTERIOR   >
+<LABLEFT>	 (Left_Side_Label)	 = 175 [12] [0] asc	 = <RIGHT       >
+<LABRGHT>	 (Right_Side_Label)	 = 187 [12] [0] asc	 = <LEFT        >
+<LABTOP>	 (Top_Label)	 = 199 [12] [0] asc	 = <ANTERIOR    >
+<PILTANG>	 (Pilot_Angle)	 = 251 [3] [1] int	 = <???>
+<PILTFLD>	 (Pilot_Half/Full)	 = 254 [4] [0] asc	 = <HALF>
+<PILTFSZ>	 (Pilot_Field_Size)	 = 258 [4] [1] int	 = < 256>
+<PILTHKN>	 (Pilot_Scan_Thickn)	 = 262 [4] [1] int	 = <  50>
+<PILTLNG>	 (Pilot_Length_mm)	 = 270 [6] [1] int	 = <     0>
+<PILTORG>	 (Pilot_Org_Pixels)	 = 284 [4] [1] int	 = <   0>
+<PILTPPM>	 (Pilot_Pixel/mm)	 = 288 [8] [1] int	 = <       2>
+<PILTYPE>	 (Pilot_horz/vert/obl)	 = 296 [4] [0] asc	 = <OFF >
+<PVRFLAG>	 (Pvr_flag)	 = 332 [3] [0] asc	 = <OFF>
+<RCNCX>	 (Recon_X_Centr_-123mm)	 = 335 [4] [1] int	 = <   0>
+<RCNCY>	 (Recon_Y_Centr_-123mm)	 = 339 [4] [1] int	 = <   0>
+<RPRFLAG>	 (Reprocessed_Flag)	 = 375 [1] [5] flg	 = <R>
+<RPRTAG>	 (Reprocess_Seq_Tag)	 = 376 [2] [0] asc	 = <A >
+<SCATFLG>	 (Scatter_Correct_flag)	 = 378 [1] [5] flg	 = <H>
+<SCNCOLL>	 (Scan_collimation)	 = 379 [4] [1] int	 = <  50>
+<SCNFLD>	 (Scan_Fld_[HALF|FULL])	 = 389 [4] [0] asc	 = <HALF>
+<SCNFLDX>	 (Scan_Fld_[FULLCTR])	 = 393 [7] [0] asc	 = <HALF   >
+<SCNSOF>	 (Start_of_Field)	 = 440 [6] [1] int	 = < 36968>
+<SRCE>	 (Source_SCAN/TAPE/NET)	 = 461 [4] [0] asc	 = <tape>
+<ST_UNIQ>	 (Study_Collis_Resolvr)	 = 481 [2] [0] asc	 = <  >
+<VOLUSED>	 (Volume_Datafile_Used)	 = 483 [4] [0] asc	 = <    >
+<AAA_FNU>	 (File_Seq_in_Study)	 = 488 [6] [1] int	 = <??????>
+<AAA_NXT>	 (O-Disk_Study_Next_Pos)	 = 494 [10] [1] int	 = <??????????>
+<AAA_POS>	 (O-Disk_Study_Pos_Sect)	 = 504 [10] [1] int	 = <??????????>
+<AAA_SEQ>	 (Study_Seq_on_Tape)	 = 514 [6] [1] int	 = <??????>
+<ACQTAG>	 (Acquisition_Tag)	 = 520 [2] [0] asc	 = < A>
+<ACQ_BAT>	 (Batch_Acquisition_Set)	 = 522 [2] [0] asc	 = <??>
+<AIRINTP>	 (Aircal_Interpolated)	 = 524 [1] [0] asc	 = <?>
+<BEAMLIM>	 (Beam_Limiter_On_Off)	 = 525 [4] [0] asc	 = <????>
+<CALSRC>	 (Cal Source)	 = 529 [1] [0] asc	 = <S>
+<DICOM3>	 (DICOM3)	 = 770 [16] [0] asc	 = <                >
+<DRGCODE>	 (DRG_Code)	 = 786 [12] [0] asc	 = <            >
+<FLATSRC>	 (FLATSS_Source)	 = 798 [1] [0] asc	 = <?>
+<F_ARCOK>	 (Manual_Archive_OK_Fl)	 = 799 [1] [5] flg	 = < >
+<F_M_FLP>	 (Floppy_Manual_Arch_Fl)	 = 800 [1] [5] flg	 = <?>
+<F_REVU>	 (Image_Reviewed_Flag)	 = 801 [1] [5] flg	 = <?>
+<GNTNDET>	 (#_Dets_on_Gantry)	 = 802 [4] [1] int	 = <4800>
+<IMFISHP>	 (Img_File_Shape_Table)	 = 806 [8] [0] asc	 = <????????>
+<IMFI_X>	 (Img_File_X_Width)	 = 814 [4] [1] int	 = <????>
+<IMFI_Y>	 (Img_File_Y_Height)	 = 818 [4] [1] int	 = <????>
+<IMFPSIZ>	 (Img_Fil_PhySize_Bytes)	 = 822 [10] [1] int	 = <    532480>
+<IMGFLIP>	 (Image_Flipped_Yes_No)	 = 832 [3] [0] asc	 = <NO >
+<LEVEL>	 (Level)	 = 835 [6] [1] int	 = <   400>
+<L_ALG>	 (Lng_Algorithm)	 = 841 [8] [1] int	 = <????????>
+<L_BADET>	 (Lng_Bad_Detectors)	 = 849 [8] [1] int	 = <????????>
+<L_CAL>	 (Lng_Calib_Overall)	 = 857 [8] [1] int	 = <????????>
+<L_CENTR>	 (Lng_Centering)	 = 865 [8] [1] int	 = <????????>
+<L_COEFS>	 (Lng_nth_Ord_Coef)	 = 873 [8] [1] int	 = <????????>
+<L_GEO_C>	 (Lng_Geom_Correct)	 = 881 [8] [1] int	 = <????????>
+<L_LINZT>	 (Lng_Linearization)	 = 889 [8] [1] int	 = <????????>
+<L_LMPRF>	 (Lng_Lump_Profile)	 = 897 [8] [1] int	 = <????????>
+<L_LMSFT>	 (Lng_Lump_Shift_Pos)	 = 905 [8] [1] int	 = <????????>
+<L_OFFS>	 (Lng_AirCal_Offs)	 = 913 [8] [1] int	 = <????????>
+<L_PICOL>	 (Pilot_Col_Alg_Length)	 = 921 [8] [1] int	 = <????????>
+<L_PIROW>	 (Pilot_Row_Alg_Length)	 = 929 [8] [1] int	 = <????????>
+<L_PROFL>	 (Lng_AirCal_Profile)	 = 937 [8] [1] int	 = <????????>
+<L_RIPPL>	 (Lng_Ripple_Vector)	 = 945 [8] [1] int	 = <????????>
+<N_IMDIS>	 (#_Images_Displayable)	 = 953 [3] [1] int	 = <???>
+<N_IMRAW>	 (#_Img_Raw_Data)	 = 956 [3] [1] int	 = <???>
+<N_IMTOT>	 (#_Images_Total)	 = 959 [3] [1] int	 = <???>
+<O_1ORDC>	 (Ofs_1st_Ord)	 = 974 [10] [1] int	 = <??????????>
+<O_ALG>	 (Ofs_Algorithm)	 = 984 [10] [1] int	 = <??????????>
+<O_BADET>	 (Ofs_Bad_Detectors)	 = 994 [10] [1] int	 = <??????????>
+<O_CAL>	 (Ofs_Calib_Overall)	 = 1004 [10] [1] int	 = <??????????>
+<O_CENTR>	 (Ofs_Centering)	 = 1014 [10] [1] int	 = <??????????>
+<O_GEO_C>	 (Ofs_Geom_Correct)	 = 1024 [10] [1] int	 = <??????????>
+<O_LINZT>	 (Ofs_Linearization)	 = 1034 [10] [1] int	 = <??????????>
+<O_LMPRF>	 (Ofs_Lump_Profile)	 = 1044 [10] [1] int	 = <??????????>
+<O_LMSFT>	 (Ofs_Lump_Shift_Pos)	 = 1054 [10] [1] int	 = <??????????>
+<O_OFFS>	 (Ofs_AirCal_Offs)	 = 1064 [10] [1] int	 = <??????????>
+<O_PICOL>	 (Pilot_Col_Alg_Offset)	 = 1074 [10] [1] int	 = <??????????>
+<O_PIROW>	 (Pilot_Row_Alg_Offset)	 = 1084 [10] [1] int	 = <??????????>
+<O_PROFL>	 (Ofs_AirCal_Profile)	 = 1094 [10] [1] int	 = <??????????>
+<O_RIPPL>	 (Ofs_Ripple_Vector)	 = 1104 [10] [1] int	 = <??????????>
+<O_VIEWS>	 (Ofs_Views)	 = 1114 [10] [1] int	 = <??????????>
+<PILTENH>	 (Pilot_Edge_Enhanced)	 = 1133 [4] [0] asc	 = <ON  >
+<RCNAVGN>	 (Recon_Averag_N_Views)	 = 1254 [4] [1] int	 = <   4>
+<RCNIMRT>	 (Recon_Image_Rotation)	 = 1264 [4] [1] int	 = <   0>
+<RCNNVUE>	 (Number_Of_Views)	 = 1268 [4] [1] int	 = <1200>
+<RCNNXVU>	 (Recon_Next_View_Offset)	 = 1272 [8] [1] int	 = <     960>
+<RCNSQNA>	 (Recon_Sequence_Name)	 = 1288 [12] [0] asc	 = <2STD        >
+<RCNWGTF>	 (Vol_Weighting_Filename)	 = 1308 [80] [0] asc	 = <????????????????????????????????????????????????????????????????????????????????>
+<SCNANSP>	 (Scan_Anode_Speed)	 = 1388 [4] [0] asc	 = <????>
+<SCNCOMP>	 (Scan_Compensator)	 = 1400 [4] [0] asc	 = <HALF>
+<SCNCSPD>	 (Scan_Couch_Speed)	 = 1404 [10] [6] flt	 = <??????????>
+<SCNDELT>	 (Scan_Delta_Mode)	 = 1414 [4] [0] asc	 = <ON  >
+<SCNDETN>	 (Scan_Offs_to_Det#)	 = 1418 [4] [1] int	 = <   0>
+<SCNDTYP>	 (Scan_Data_Type/= float, int, long,...)	 = 1422 [1] [5] flg	 = <I>
+<SCNEXRV>	 (Scan_Extra_Revs)	 = 1423 [6] [6] flt	 = <0.7500>
+<SCNFAN>	 (Scan_Fan_#_Dets)	 = 1429 [4] [1] int	 = < 680>
+<SCNFILT>	 (Scan_Filter)	 = 1433 [8] [0] asc	 = <       0>
+<SCNGAP>	 (Scan_Gap_#_Dets)	 = 1441 [4] [1] int	 = <  64>
+<SCNGBCN>	 (Scan_Global_Centrng)	 = 1445 [16] [6] flt	 = <0.250000        >
+<SCNINTM>	 (Scan_Integ_Period)	 = 1461 [4] [1] int	 = <5243>
+<SCNLPTS>	 (Scan_#_Byt_Preceedg)	 = 1465 [4] [1] int	 = <   8>
+<SCNMAOF>	 (Scan_Ma_Offset)	 = 1469 [16] [6] flt	 = <-2705.729980    >
+<SCNNREC>	 (Scan_#_Records/File)	 = 1485 [8] [1] int	 = <     512>
+<SCNNREF>	 (Scan_#_Ref_Dets)	 = 1493 [4] [1] int	 = <  20>
+<SCNNREV>	 (Scan_#_Revs)	 = 1497 [4] [1] int	 = <   1>
+<SCNOVER>	 (Scan_#_Overscan_Dets)	 = 1501 [4] [1] int	 = < 256>
+<SCNPACK>	 (Scan_Data_Packing)	 = 1505 [4] [0] asc	 = <ON  >
+<SCNPART>	 (#_of_PAR_Detectors)	 = 1509 [4] [0] asc	 = <   0>
+<SCNPITC>	 (Spiral_Pitch_Factor)	 = 1513 [6] [6] flt	 = <??????>
+<SCNRCSZ>	 (Scan_Record_Size_Byte)	 = 1519 [4] [1] int	 = <1024>
+<SCNSAMP>	 (Scan_Sample)	 = 1531 [4] [1] int	 = <1024>
+<SCNTPTS>	 (Scan_#_Byt_Trailing)	 = 1559 [4] [1] int	 = <????>
+<S_N_CPU>	 (CPU_Serial_#)	 = 1563 [4] [1] int	 = <????>
+<TYP_CPU>	 (CPU_Type)	 = 1571 [4] [0] asc	 = <????>
+<TYP_TUB>	 (X-Tube_Type)	 = 1587 [4] [1] int	 = <   6>
+<WINDOW>	 (Window)	 = 1591 [6] [1] int	 = <  4000>
+<ZSCNINX>	 (Spiral_Acq_Lngth)	 = 1597 [8] [6] flt	 = <0.000000>
+
+
+
+
+
+
+* Valid Values of: Image File Type == IMFTYPE:
+* --- Values for CT Scan Image Data:
+*=RNG IMFTYPE
+SRCF
+Source Fan Data
+*=RNG IMFTYPE
+DETF
+Detector Fan Data
+*=RNG IMFTYPE
+RIPV
+Ripple Vector
+*=RNG IMFTYPE
+AIRC
+Air Wing Corrected Data
+*=RNG IMFTYPE
+RIPC
+Ripple Corrected Data
+*=RNG IMFTYPE
+CENC
+Fan Centered Data
+*=RNG IMFTYPE
+BDDC
+Bad Detector Replacement
+*=RNG IMFTYPE
+CAIR
+Compressed Air Cal Data
+*=RNG IMFTYPE
+SPEC
+Spectrum Corrected Data
+*=RNG IMFTYPE
+RFAN
+Refanned Data (Linearization Vector)
+*=RNG IMFTYPE
+GEOC
+Geometric Corrected Data
+*=RNG IMFTYPE
+PCOM
+Projection Completion or Zero Fill
+*=RNG IMFTYPE
+FDAT
+Filtered Data
+*=RNG IMFTYPE
+BPVW
+Views for Backprojection
+*=RNG IMFTYPE
+IMAG
+Image Data
+*=RNG IMFTYPE
+PRAW
+Pilot Raw Data
+* --- Other Image File Types:
+*=RNG IMFTYPE
+EKG Data File
+*=RNG IMFTYPE
+TEXT
+Text File
+* Valid Values of: Image Type == IMTYPE:
+*=RNG IMTYPE
+SLIC
+Slice
+*=RNG IMTYPE
+PILT
+Pilot
+*=RNG IMTYPE
+SYNT
+Synthetic, look at IMTYPSY for details
+*=RNG IMTYPE
+DATA
+Non-Image Data (Text, EKG, etc)
+* Valid Values of: Modality == MODAL:
+*=RNG MODAL
+CT Scanner (includes CT Pilots?)
+*=RNG MODAL
+EKG 
+*=RNG MODAL
+*=RNG MODAL
+NUCL
+Nuclear Medicine
+*=RNG MODAL
+PET Scan
+*=RNG MODAL
+Projection Radiography
+* Valid Values of: Patient_Sex == PATSEX
+*=RNG PATSEX
+Female
+*=RNG PATSEX
+Male
+*=RNG PATSEX
+Other
+* Valid Values of: Position_Head/Feet == POSHF:
+*=RNG POSHF
+FEET
+Feet Toward Gantry
+*=RNG POSHF
+HEAD
+Head Toward Gantry
+* Valid Values of: Source_SCAN/TAPE/NET == SRCE    
+*=RNG SRCE
+SCAN
+Scanned on this machine
+*=RNG SRCE
+TAPE
+Retrieved from tape
+*=RNG SRCE
+ODSK
+Retrieved from optical disk
+*=RNG SRCE
+NETW
+Recieved from network
+
+#endif
diff --git a/libsrc/src/dconvert/pq/pqmpln.cc b/libsrc/src/dconvert/pq/pqmpln.cc
new file mode 100644
index 0000000..78094b2
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqmpln.cc
@@ -0,0 +1,229 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pqmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "pqdc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+PQ_Header_BothClass::ToDicom_ManualPlane(AttributeList *list)
+{
+	// Derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlaneHeadFeet orientation;
+
+	{
+		hfff="";		// default :(
+		orientation=HeadFirst;
+
+		char *pq_poshf;
+		int length;
+		if (getAsciiAttribute("POSHF",pq_poshf,length)) {
+			if (length >= 4 && strncmp(pq_poshf,"HEAD",4) == 0) {
+				hfff="HF";
+				orientation=HeadFirst;
+			}
+			else if (length >= 4 && strncmp(pq_poshf,"FEET",4) == 0) {
+				hfff="FF";
+				orientation=FeetFirst;
+			}
+			if (pq_poshf) delete[] pq_poshf;
+		}
+	}
+
+	ImagePlanePosition position;
+
+	{
+		ap="";			// default :(
+		position=Supine;
+
+		char *pq_posprn;
+		int length;
+		if (getAsciiAttribute("POSPRN",pq_posprn,length)) {
+			if (length >= 4 && strncmp(pq_posprn,"SUPI",4) == 0) {
+				ap="S";
+				position=Supine;
+			}
+			else if (length >= 4 && strncmp(pq_posprn,"PRON",4) == 0) {	// Need to check this term
+				ap="P";
+				position=Prone;
+			}
+			//ap="DL";
+			//position=LeftLateralDecubitus;
+			//ap="DR";
+			//position=RightLateralDecubitus;
+
+			if (pq_posprn) delete[] pq_posprn;
+		}
+	}
+
+	ImagePlanePlane plane;		// Determine the "machine" plane of the image ...
+					// CT slices are axial, pilots are coronal or sagittal
+
+	bool ispilot=false;
+	bool isslice=false;
+	Int32 pq_pilot_angle;
+	Int32 pq_pilot_length;
+	Int32 pq_pilot_origin_pixels;
+	Int32 pq_pilot_pixels_per_mm;
+	Int32 pq_pilot_field_size=0;
+	char *pilot_type=0;		// HORZ,VERT,OBL	// need to delete[] later if not zero
+	int pilot_type_length=0;
+
+	Int32 pq_recon_field_size=0;
+	Int32 pq_recon_matrix_size;
+	{
+		plane=Axial;	// default :(
+
+		char *pq_image_type;
+		int length;
+		if (getAsciiAttribute("IMTYPE",pq_image_type,length)) {
+			if (length >= 4 && (strncmp(pq_image_type,"SLIC",4) == 0
+					 || strncmp(pq_image_type,"SPIR",4) == 0) ) {
+				isslice=true;
+				plane=Axial;
+
+				if (!getIntegerAttribute("RCNFSIZ",pq_recon_field_size)) Assert(0);
+				if (!getIntegerAttribute("RCNMTRX",pq_recon_matrix_size)) Assert(0);
+			}
+			else if (length >= 3 && strncmp(pq_image_type,"PIL",3) == 0) {	// db says PILT, files contain PILO
+				ispilot=true;
+
+				// this needs serious work when more examples are available ...
+
+				if (getIntegerAttribute("PILTANG",pq_pilot_angle)
+				 && getAsciiAttribute("PILTYPE",pilot_type,pilot_type_length)) {
+					if (pq_pilot_angle == 90 && strncmp(pilot_type,"VERT",4) == 0)
+						plane=Coronal;
+					else if (pq_pilot_angle == 0 && strncmp(pilot_type,"HORZ",4) == 0)
+						plane=SagittalIP;
+				}
+				if (!getIntegerAttribute("PILTLNG",pq_pilot_length)) Assert(0);
+				if (!getIntegerAttribute("PILTORG",pq_pilot_origin_pixels)) Assert(0);
+				if (!getIntegerAttribute("PILTPPM",pq_pilot_pixels_per_mm)) Assert(0);
+				if (!getIntegerAttribute("PILTFSZ",pq_pilot_field_size)) Assert(0);
+			}
+			else {
+				Assert(0);	// other types not supported
+			}
+			if (pq_image_type) delete[] pq_image_type;
+		}
+	}
+
+	// if (pilot_type) delete[] pilot_type;		// put this later when no longer needed
+
+	// Make a model of the image plane ...
+
+	ImagePlane imageplane(plane,ispilot ? pq_pilot_field_size : pq_recon_field_size,orientation,position);
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlane done" << endl;
+//imageplane.put(cerr);
+
+	// While we are in the "display" or "gantry plane ...
+	// (before angulation) 
+
+	// Account for angulation ...
+
+	double gantry_tilt;
+	{
+		Int32 pq_gantry_tilt_times_ten;
+		if (!getIntegerAttribute("GTILT",pq_gantry_tilt_times_ten)) pq_gantry_tilt_times_ten=0;
+		gantry_tilt=double(pq_gantry_tilt_times_ten)/10.0;
+
+		// assume +ve tilt is always top of gantry towards the foot of the table
+		// DICOM Z is positive into gantry (towards head)
+		imageplane.MachinePlane::angle(LeftRight,-gantry_tilt);
+
+//cerr << "ToDicom_ManualPlane::angling result:" << endl;
+//imageplane.put(cerr);
+	}
+
+	// Account for physical offsets in the gantry plane ...
+	// (after angulation)
+
+	double couch_position;
+	Int32 pq_couch_height;
+	{
+		Int32 pq_couch_position_times_100;
+		if (!getIntegerAttribute("COUCH",pq_couch_position_times_100)) pq_couch_position_times_100=0;
+		couch_position=double(pq_couch_position_times_100)/100.0;
+
+		if (!getIntegerAttribute("COUCHHT",pq_couch_height)) pq_couch_height=0;
+
+		// assume couch position is +ve out of gantry (towards feet in supine/hf)
+		// assume couch height is +ve above table (towards anterior in supine/hf)
+		// make DICOM Y coordinates around an arbitrary height of 300mm (rather than the floor !)
+		// DICOM is +LPH
+
+		// Note that the pilot correction needs to be calculated for the center of the image
+
+		double couch_position_correction = ispilot
+			? double(pq_pilot_origin_pixels)/double(pq_pilot_pixels_per_mm) - pq_pilot_field_size/2.0
+			: 0.0;
+
+//cerr << "couch_position_correction=" << couch_position_correction << endl;
+
+		Vector3D offset(0,300-pq_couch_height,-(couch_position-couch_position_correction));
+
+		imageplane.MachinePlane::shift(offset);
+	}
+
+	// Now build the DICOM attributes ...
+
+	// PatientPosition
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),String_Cat_Use(hfff,ap));
+
+	// ImageOrientationPatient and ImagePositionPatient
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+
+	// SliceLocation
+
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),couch_position);
+
+	// TableHeight
+
+	(*list)+=new DecimalStringAttribute(TagFromName(TableHeight),double(pq_couch_height));
+
+	// GantryDetectorTilt
+
+	(*list)+=new DecimalStringAttribute(TagFromName(GantryDetectorTilt),gantry_tilt);
+
+	// PixelSpacing
+
+	double pixel_spacing = ispilot
+			? 1.0/double(pq_pilot_pixels_per_mm)
+			: double(pq_recon_field_size)/double(pq_recon_matrix_size);
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),pixel_spacing,pixel_spacing);
+
+	// ReconstructionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),
+		double(ispilot ? pq_pilot_field_size : pq_recon_field_size));
+
+	// DataCollectionDiameter
+
+	Int32 pq_scan_field_size;
+	if (getIntegerAttribute("SCNFSIZ",pq_scan_field_size)) {
+		(*list)+=new DecimalStringAttribute(TagFromName(DataCollectionDiameter),
+			double(pq_scan_field_size));
+	}
+
+	// SliceThickness
+
+	Int32 pq_scan_thickness_multiplier;
+	Int32 pq_scan_thickness_value;
+	if (getIntegerAttribute("SCNTHKM",pq_scan_thickness_multiplier)
+	 && getIntegerAttribute("SCNTHKN",pq_scan_thickness_value)) {
+		(*list)+=new DecimalStringAttribute(TagFromName(SliceThickness),
+			double(pq_scan_thickness_value)/double(pq_scan_thickness_multiplier));
+	}
+
+	// PositionReferenceIndicator
+
+	(*list)+=new LongStringAttribute(TagFromName(PositionReferenceIndicator));
+}
+
diff --git a/libsrc/src/dconvert/pq/pqptrs.h b/libsrc/src/dconvert/pq/pqptrs.h
new file mode 100644
index 0000000..3b13d6c
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqptrs.h
@@ -0,0 +1,2 @@
+/* pqptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	PQ_Offset_PixelData_ptr	(pqhdr->getPixelOffset())
diff --git a/libsrc/src/dconvert/pq/pqsrc.h b/libsrc/src/dconvert/pq/pqsrc.h
new file mode 100644
index 0000000..edbc23b
--- /dev/null
+++ b/libsrc/src/dconvert/pq/pqsrc.h
@@ -0,0 +1,61 @@
+/* pqsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_pqsrc__
+#define __Header_pqsrc__
+
+class PQ_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	PQ_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~PQ_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Little endian ...
+				Uint16 pixel;
+				pixel=(bytes[0]<<8)|bytes[1];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_pqsrc__
diff --git a/libsrc/src/dconvert/shim/Imakefile b/libsrc/src/dconvert/shim/Imakefile
new file mode 100755
index 0000000..450d3f0
--- /dev/null
+++ b/libsrc/src/dconvert/shim/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = shimdc.cc shimconv.cc shimmpln.cc \
+		 shimmmsc.cc shimmdt.cc \
+		 shimdmp.cc shimdmpf.cc \
+		 shimhdrc.cc shim.cc
+
+OBJS = 		 shimdc.o  shimconv.o  shimmpln.o  \
+		 shimmmsc.o  shimmdt.o  \
+		 shimdmp.o  shimdmpf.o  \
+		 shimhdrc.o  shim.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdshim.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(shim,dconvert)
+
+ProjectConvertTemplate(shimhdrp.h,shim,convert,prefix=SHIM_ role=headerpart)
+ProjectConvertTemplate(shimhdrw.h,shim,convert,prefix=SHIM_ role=wholeheader)
+ProjectConvertTemplate(shimhdrc.h,shim,convert,prefix=SHIM_ role=constructheader)
+ProjectConvertTemplate(shimconv.h,shim,convert,prefix=SHIM_ role=dicom)
+ProjectConvertTemplate(shimdmpf.h,shim,convert,prefix=SHIM_ role=dump)
+
+shimdmpf.o: shimdmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) shimdmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/shim/README b/libsrc/src/dconvert/shim/README
new file mode 100755
index 0000000..043d8b8
--- /dev/null
+++ b/libsrc/src/dconvert/shim/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"shim.h"
+		class SHIM_Conversion {
+			SHIM_Conversion(istream &i,ostream &e);
+			virtual ~SHIM_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"shim.cc"
+
+		SHIM_Conversion::SHIM_Conversion(istream &i,ostream &e);
+		SHIM_Conversion::~SHIM_Conversion();
+
+	"shimcl.h"
+
+		class SHIM_Header_BothClass  : public SHIM_HeaderClass
+		{
+		public:
+			SHIM_Header_BothClass(istream *ist) : SHIM_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"shimconv.cc"
+
+		#include "shimconv.h"
+
+	"shimdc.c"
+
+		bool SHIM_Conversion::convertHeader(AttributeList *list);
+		bool SHIM_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool SHIM_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"shimdc.h"
+
+	"shimdmp.cc"
+
+		bool SHIM_Conversion::dump(ostream &o);
+
+	"shimdmp.h"
+
+	"shimhdrc.cc"
+
+		#include "shimhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"shim.tpl"
+
+		The template "describing" the format for header generation
+
+	"shimmdt.cc"
+
+		void SHIM_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"shimmmsc.cc"
+
+		void SHIM_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"shimmpln.cc"
+
+		void SHIM_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"shimptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"shimsrc.h"
+
+		class SHIM_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			SHIM_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~SHIM_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from shim.tpl:
+
+	"shimhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class SHIM_HeaderClass_HDR1 {
+		public:
+			SHIM_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"shimhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class SHIM_HeaderClass
+		{
+		public:
+			SHIM_HeaderClass(istream *ist);
+
+			SHIM_HeaderClass_HDR1 *SHIM_HeaderInstance_HDR1;
+			SHIM_HeaderClass_HDR2 *SHIM_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"shimhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		SHIM_HeaderClass::SHIM_HeaderClass(istream *ist);
+
+	"shimconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void SHIM_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"shimdmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void SHIM_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "shimhdrm.h".
+
+	if you have special purpose code, then "shimhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "shimhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/shim/shim.cc b/libsrc/src/dconvert/shim/shim.cc
new file mode 100644
index 0000000..d4e8b6d
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shim.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shim.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "shim.h"
+#include "shimcl.h"
+#include "srcsink.h"
+#include "shimsrc.h"
+
+SHIM_Conversion::SHIM_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	shimhdr=0;
+	pixeldatasrc=0;
+}
+
+SHIM_Conversion::~SHIM_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (shimhdr) delete shimhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/shim/shim.h b/libsrc/src/dconvert/shim/shim.h
new file mode 100644
index 0000000..9ece989
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shim.h
@@ -0,0 +1,37 @@
+/* shim.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_shim__
+#define __Header_shim__
+
+// NB. a SHIM_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~SHIM_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class SHIM_Header_BothClass;
+class SHIM_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class SHIM_Conversion {
+	SHIM_Header_BothClass *shimhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	SHIM_PixelDataSource *pixeldatasrc;
+public:
+	SHIM_Conversion(istream &i,ostream &e);
+
+	virtual ~SHIM_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0);
+
+	bool convertAll(AttributeList *list,TransferSyntax *transfersyntax,unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax,unsigned imagenumber=0);
+};
+
+#endif /* __Header_shim__ */
+
diff --git a/libsrc/src/dconvert/shim/shim.tpl b/libsrc/src/dconvert/shim/shim.tpl
new file mode 100755
index 0000000..0006c4d
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shim.tpl
@@ -0,0 +1,160 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="MAINHDR"	offset="0"   intype="String"   inlength="8"  keyword="ZASYSID"	dicomtype="?"	dicomtag="?"	# SYS-ID
+block="MAINHDR"	offset="8"   intype="String"   inlength="16" keyword="ZANAME"	dicomtype="PN"	dicomtag="PatientName"	# Name
+block="MAINHDR"	offset="24"  intype="String"   inlength="12" keyword="ZAID"	dicomtype="LO"	dicomtag="PatientID"	# ID
+block="MAINHDR"	offset="36"  intype="String"   inlength="2"  keyword="ZASEX"	dicomtype="CS"	dicomtag="PatientSex"	enum="'M'=Male,'F'=Female"	# Sex
+block="MAINHDR"	offset="38"  intype="String"   inlength="4"  keyword="ZAAGE"	dicomtype="?"	dicomtag="?"	# AGE years
+block="MAINHDR"	offset="42"  intype="String"   inlength="2"  keyword="ZACOMM"	dicomtype="LT"	dicomtag="StudyComments"	# Comment
+block="MAINHDR"	offset="62"  intype="String"   inlength="18" keyword="ZAHOSP"	dicomtype="LO"	dicomtag="InstitutionName"	# Hospital
+block="MAINHDR"	offset="80"  intype="String"   inlength="8"  keyword="ZADATW"	dicomtype="?"	dicomtag="?"	# Date 'YY-MM-DD'
+block="MAINHDR"	offset="88"  intype="String"   inlength="8"  keyword="ZATIME"	dicomtype="?"	dicomtag="?"	# Time 'HH:MM:SS'
+block="MAINHDR"	offset="96"  intype="String"   inlength="8"  keyword="ZAAREA"	dicomtype="?"	dicomtag="?"	# Zoom Size/NSlices 'n.nX/nn' enum='ES'=100mm,'VS'=150mm,'SS'=200mm,' S'=250mm,' M'=300mm,' L'=350mm,'LL'=400mm	
+block="MAINHDR"	offset="104" intype="String"   inlength="2"  keyword="ZASEQT"	dicomtype="?"	dicomtag="?"	enum="'IR'=Inversion Recovery,'SE'=Spin Echo,'FE'=Field Echo"	# TYPE/MODE 'XX/nnn' where nnn is Max(Nx,Ny)
+block="MAINHDR"	offset="107" intype="String"   inlength="5"  keyword="ZASEQM"	dicomtype="?"	dicomtag="?"	# TYPE/MODE 'XX/nnn' where nnn is Max(Nx,Ny)
+block="MAINHDR"	offset="112" intype="String"   inlength="8"  keyword="ZATR"	dicomtype="?"	dicomtag="?"	# TR mS 'TR=nnnn'
+block="MAINHDR"	offset="120" intype="String"   inlength="8"  keyword="ZATE"	dicomtype="?"	dicomtag="?"	# TE mS 'TE=nnn'
+block="MAINHDR"	offset="128" intype="String"   inlength="8"  keyword="ZATI"	dicomtype="?"	dicomtag="?"	# TI mS 'TI=nnn'
+block="MAINHDR"	offset="136" intype="String"   inlength="8"  keyword="ZALOK"	dicomtype="?"	dicomtag="?"	# Location mm 'OM+nnn','CN+nn'
+block="MAINHDR"	offset="144" intype="String"   inlength="8"  keyword="ZAECG"	dicomtype="?"	dicomtag="?"	# ECG 'ECG=nnn'
+block="MAINHDR"	offset="152" intype="String"   inlength="6"  keyword="ZADIRL"	dicomtype="?"	dicomtag="?"	enum="'RIGHT '=Right,'LEFT  '=Left,'ANTR  '=Anterior,'POSTR '=Posterior,'HEAD  '=Head,'FEET  '=Feet"	# Left side of image
+block="MAINHDR"	offset="158" intype="String"   inlength="6"  keyword="ZADIRB"	dicomtype="?"	dicomtag="?"	enum="'RIGHT '=Right,'LEFT  '=Left,'ANTR  '=Anterior,'POSTR '=Posterior,'HEAD  '=Head,'FEET  '=Feet"	# Bottom side of image
+block="MAINHDR"	offset="164" intype="String"   inlength="4"  keyword="ZATCS"	dicomtype="?"	dicomtag="?"	enum="'TRN '=Transverse,'COR '=Coronal,'SAG '=Sagittal"	# 
+block="MAINHDR"	offset="168" intype="String"   inlength="8"  keyword="ZAMTE"	dicomtype="?"	dicomtag="?"	# Interslice rest ms 'MTE=nn'
+block="MAINHDR"	offset="176" intype="String"   inlength="6"  keyword="ZAPIT"	dicomtype="?"	dicomtag="?"	# Interslice skip mm 'PT=nn'
+block="MAINHDR"	offset="182" intype="String"   inlength="8"  keyword="ZAFLIP"	dicomtype="?"	dicomtag="?"	# Flip angle degress 'FLIP=nn'
+block="MAINHDR"	offset="190" intype="String"   inlength="8"  keyword="ZAENCD"	dicomtype="?"	dicomtag="?"	# Encode % 'ECD=nn%'
+block="MAINHDR"	offset="198" intype="String"   inlength="6"  keyword="ZADIREP"	dicomtype="?"	dicomtag="?"	enum="'(P,F) '=?,'(F,P) '=?"	# 
+block="MAINHDR"	offset="204" intype="String"   inlength="8"  keyword="ZANSEQ"	dicomtype="SH"	dicomtag="SequenceName"	# Sequence Name
+block="MAINHDR"	offset="212" intype="String"   inlength="8"  keyword="ZAMATER1"	dicomtype="?"	dicomtag="?"	# SYSTEM-ID 1
+block="MAINHDR"	offset="220" intype="String"   inlength="8"  keyword="ZAMATER2"	dicomtype="?"	dicomtag="?"	# SYSTEM-ID 2
+block="MAINHDR"	offset="228" intype="String"   inlength="8"  keyword="ZAMATER3"	dicomtype="?"	dicomtag="?"	# SYSTEM-ID 3
+block="MAINHDR"	offset="236" intype="String"   inlength="2"  keyword="ZASITE"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="238" intype="String"   inlength="8"  keyword="ZAAVG"	dicomtype="?"	dicomtag="?"	# Averages 'NEX=n'
+block="MAINHDR"	offset="246" intype="String"   inlength="2"  keyword="ZADIRL2"	dicomtype="?"	dicomtag="?"	enum="'RT'=Right,'LT'=Left,'HD'=Head,'FT'=Feet,'PO'=Posterior,'AN'=Anterior"	# Left direction
+block="MAINHDR"	offset="248" intype="String"   inlength="2"  keyword="ZADIRB2"	dicomtype="?"	dicomtag="?"	# Down direction
+block="MAINHDR"	offset="250" intype="String"   inlength="6"  name="Unknown250"	dicomtype="?"	dicomtag="?"	# SCAN (?)
+block="MAINHDR"	offset="256" intype="Int16_B"  inlength="1"  keyword="ZMAGN"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="258" intype="Int16_B"  inlength="1"  keyword="ZSCSW"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="260" intype="Int16_B"  inlength="1"  keyword="ZIMAGE"	dicomtype="IS"	dicomtag="ImagesInAcquisition"	# Images in series
+block="MAINHDR"	offset="262" intype="Int16_B"  inlength="1"  keyword="ZSLICE"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="264" intype="Int16_B"  inlength="1"  keyword="ZECHO"	dicomtype="?"	dicomtag="?"	# 1,2,4
+block="MAINHDR"	offset="266" intype="Int16_B"  inlength="1"  keyword="ZXSIZE"	dicomtype="US"	dicomtag="Columns"	#
+block="MAINHDR"	offset="268" intype="Int16_B"  inlength="1"  keyword="ZYSIZE"	dicomtype="US"	dicomtag="Rows"	#
+block="MAINHDR"	offset="270" intype="Int16_B"  inlength="1"  keyword="ZTBLK"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="272" intype="Int16_B"  inlength="1"  keyword="ZNEGSW"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	# Even line DC neg
+block="MAINHDR"	offset="274" intype="Int16_B"  inlength="1"  keyword="ZFTYPE"	dicomtype="?"	dicomtag="?"	enum="0=0,1=1,2=2,3=1+2"	#
+block="MAINHDR"	offset="276" intype="Int16_B"  inlength="1"  keyword="ZCALB"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	# Max
+block="MAINHDR"	offset="278" intype="Int16_B"  inlength="1"  keyword="ZLBLK"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="280" intype="Int16_B"  inlength="1"  keyword="ZRBLK"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="282" intype="Int16_B"  inlength="1"  keyword="ZIBLKA"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="284" intype="Int16_B"  inlength="1"  keyword="ZCOIL"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="286" intype="Int16_B"  inlength="1"  keyword="ZDTYPE"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="288" intype="Int16_B"  inlength="1"  keyword="ZETYPE"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="290" intype="Int16_B"  inlength="1"  keyword="ZKRNL"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="292" intype="Int16_B"  inlength="1"  keyword="ZPTOR1"	dicomtype="?"	dicomtag="?"	enum="0=head first,1=feet first"	#
+block="MAINHDR"	offset="294" intype="Int16_B"  inlength="1"  keyword="ZPTOR2"	dicomtype="?"	dicomtag="?"	enum="0=supine,1=prone,2=right side down,3=left side down,4=other"	#
+block="MAINHDR"	offset="296" intype="Int16_B"  inlength="1"  keyword="ZLRVS"	dicomtype="?"	dicomtag="?"	enum="0=Up,1=Down"	#
+block="MAINHDR"	offset="298" intype="Int16_B"  inlength="1"  name="Unknown298"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="300" intype="Int16_B"  inlength="1"  keyword="ZRCDMODE"	dicomtype="?"	dicomtag="?"	# Mode
+block="MAINHDR"	offset="302" intype="Int16_B"  inlength="1"  keyword="ZVDBAND"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="304" intype="Int16_B"  inlength="1"  keyword="ZYSTL"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="306" intype="Int16_B"  inlength="1"  keyword="ZPWGHT"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="308" intype="Int16_B"  inlength="1"  keyword="ZPFUSE"	dicomtype="?"	dicomtag="?"	# RF power ratio  %
+block="MAINHDR"	offset="310" intype="String"   inlength="2"  keyword="ZSATON"	dicomtype="?"	dicomtag="?"	enum="'P '=Potassium,'H '=Hydrogen,'Na'=Sodium"	#
+block="MAINHDR"	offset="312" intype="Int16_B"  inlength="1"  keyword="ZSFREQ"	dicomtype="?"	dicomtag="?"	# 10kHz
+block="MAINHDR"	offset="314" intype="Int16_B"  inlength="1"  keyword="ZIMFLT"	dicomtype="?"	dicomtag="?"	enum="0=No"	#
+block="MAINHDR"	offset="316" intype="Int16_B"  inlength="1"  keyword="ZSLANT2"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="318" intype="Int16_B"  inlength="1"  keyword="ZROTPHS"	dicomtype="?"	dicomtag="?"	# Recon
+block="MAINHDR"	offset="320" intype="Int16_B"  inlength="1"  keyword="ZWIDE"	dicomtype="?"	dicomtag="?"	# Slice width     *10mm
+block="MAINHDR"	offset="322" intype="Int16_B"  inlength="1"  keyword="ZPITCH"	dicomtype="?"	dicomtag="?"	# Interslice skip *10mm
+block="MAINHDR"	offset="324" intype="Int16_B"  inlength="1"  keyword="ZCLOC"	dicomtype="?"	dicomtag="?"	# Center location *10mm offset from isocenter in ZDIR direction (SAG L+,COR A+,TRN F+) FOR CENTER OF SERIES
+block="MAINHDR"	offset="326" intype="Int16_B"  inlength="1"  keyword="ZMAG"	dicomtype="?"	dicomtag="?"	# *100
+block="MAINHDR"	offset="328" intype="Int16_B"  inlength="1"  keyword="ZCNTX"	dicomtype="?"	dicomtag="?"	# X mm
+block="MAINHDR"	offset="330" intype="Int16_B"  inlength="1"  keyword="ZCNTY"	dicomtype="?"	dicomtag="?"	# Y mm
+block="MAINHDR"	offset="332" intype="Int16_B"  inlength="1"  keyword="ZVIEW"	dicomtype="?"	dicomtag="?"	# *10
+block="MAINHDR"	offset="334" intype="Int16_B"  inlength="1"  keyword="ZDIR"	dicomtype="?"	dicomtag="?"	enum="1=Trn,2=Cor,3=Sag,6=Non,7=Point"	# Orientation
+block="MAINHDR"	offset="336" intype="Int16_B"  inlength="1"  keyword="ZANG1"	dicomtype="?"	dicomtag="?"	# Alpha *10 degrees (tilt angle of vertical, up-to-down direction relative to base plane (C,S,T))
+block="MAINHDR"	offset="338" intype="Int16_B"  inlength="1"  keyword="ZANG2"	dicomtype="?"	dicomtag="?"	# Beta *10 degrees (tilt angle of horizontal, left-to-right direction)
+block="MAINHDR"	offset="340" intype="String"   inlength="8"  keyword="ZPSID1"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="348" intype="String"   inlength="2"  keyword="ZPSIM1"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="350" intype="String"   inlength="2"  keyword="ZPSCR1"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="352" intype="String"   inlength="8"  keyword="ZPSID2"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="360" intype="String"   inlength="2"  keyword="ZPSIM2"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="362" intype="String"   inlength="2"  keyword="ZPSCR2"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="364" intype="Int16_B"  inlength="1"  keyword="ZANG3S"	dicomtype="?"	dicomtag="?"	# system *10 degrees
+block="MAINHDR"	offset="366" intype="Int16_B"  inlength="1"  keyword="ZANG3U"	dicomtype="?"	dicomtag="?"	# user *10 degrees
+block="MAINHDR"	offset="368" intype="Int16_B"  inlength="1"  keyword="ZTILTSW"	dicomtype="?"	dicomtag="?"	enum="1=1,2=2,3=Trn,4=Cor"	# Tilt
+block="MAINHDR"	offset="370" intype="Int16_B"  inlength="1"  keyword="ZPSOR1"	dicomtype="?"	dicomtag="?"	# location +/-512
+block="MAINHDR"	offset="372" intype="Int16_B"  inlength="1"  keyword="ZPSOA1"	dicomtype="?"	dicomtag="?"	# location *10 degrees
+block="MAINHDR"	offset="374" intype="Int16_B"  inlength="1"  keyword="ZPSOR2"	dicomtype="?"	dicomtag="?"	# location +/-512
+block="MAINHDR"	offset="376" intype="Int16_B"  inlength="1"  keyword="ZPSOA2"	dicomtype="?"	dicomtag="?"	# location *10 degrees
+block="MAINHDR"	offset="378" intype="Int16_B"  inlength="1"  keyword="ZPSOD1"	dicomtype="?"	dicomtag="?"	# loc 0-100mm
+block="MAINHDR"	offset="380" intype="Int16_B"  inlength="1"  keyword="ZPSOD2"	dicomtype="?"	dicomtag="?"	# loc 0-100mm
+block="MAINHDR"	offset="382" intype="Int16_B"  inlength="1"  keyword="ZSLANT"	dicomtype="?"	dicomtag="?"	# orthog=10000
+block="MAINHDR"	offset="384" intype="String"   inlength="2"  keyword="ZPMOD"	dicomtype="?"	dicomtag="?"	enum="'IR'=Inversion Recovery,'SE'=Spin Echo,'FE'=Field Echo"	#
+block="MAINHDR"	offset="386" intype="Int16_B"  inlength="1"  keyword="ZTR"	dicomtype="?"	dicomtag="?"	# TR ms
+block="MAINHDR"	offset="388" intype="Int16_B"  inlength="1"  keyword="ZTE"	dicomtype="?"	dicomtag="?"	# TE ms
+block="MAINHDR"	offset="390" intype="Int16_B"  inlength="1"  keyword="ZTI"	dicomtype="?"	dicomtag="?"	# TI ms
+block="MAINHDR"	offset="392" intype="Int16_B"  inlength="1"  keyword="ZNX"	dicomtype="?"	dicomtag="?"	# X Encode
+block="MAINHDR"	offset="394" intype="Int16_B"  inlength="1"  keyword="ZNY"	dicomtype="?"	dicomtag="?"	# Y Encode
+block="MAINHDR"	offset="396" intype="Int16_B"  inlength="1"  keyword="ZXAV"	dicomtype="?"	dicomtag="?"	# X NEX
+block="MAINHDR"	offset="398" intype="Int16_B"  inlength="1"  keyword="ZYAV"	dicomtype="?"	dicomtag="?"	# Y NEX
+block="MAINHDR"	offset="400" intype="Int16_B"  inlength="1"  keyword="ZEAV"	dicomtype="?"	dicomtag="?"	# Echo
+block="MAINHDR"	offset="402" intype="Int16_B"  inlength="1"  keyword="ZSTIM"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="404" intype="String"   inlength="2"  keyword="ZCONST"	dicomtype="?"	dicomtag="?"	enum="'2D'=2D,'3D'=3D"	#
+block="MAINHDR"	offset="406" intype="Int16_B"  inlength="1"  keyword="ZFLIP"	dicomtype="?"	dicomtag="?"	# degrees
+block="MAINHDR"	offset="408" intype="Int16_B"  inlength="1"  keyword="ZRESP"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#
+block="MAINHDR"	offset="410" intype="Int16_B"  inlength="1"  keyword="ZECG"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#
+block="MAINHDR"	offset="412" intype="Int16_B"  inlength="1"  keyword="ZDIXON "	dicomtype="?"	dicomtag="?"	# Chemical Shift *10ppm
+block="MAINHDR"	offset="414" intype="Int16_B"  inlength="1"  keyword="ZMTE"	dicomtype="?"	dicomtag="?"	# Interslice rest (mS ?)
+block="MAINHDR"	offset="416" intype="Int16_B"  inlength="1"  keyword="ZHALF"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="418" intype="Int16_B"  inlength="1"  keyword="ZSGNSW"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="420" intype="Int16_B"  inlength="1"  keyword="ZCINE"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="422" intype="Int16_B"  inlength="1"  keyword="ZPKZ"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="424" intype="Int16_B"  inlength="1"  keyword="ZTEALN"	dicomtype="?"	dicomtag="?"	enum="0=In phase,1=Opposed"	# TE Align
+block="MAINHDR"	offset="426" intype="Int16_B"  inlength="1"  keyword="ZCSSW"	dicomtype="?"	dicomtag="?"	# Chemical Shift Switch
+block="MAINHDR"	offset="428" intype="Int16_B"  inlength="1"  keyword="ZIMDIR"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="430" intype="Int16_B"  inlength="1"  keyword="ZPSSP1"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="432" intype="Int16_B"  inlength="1"  keyword="ZPSSP2"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="434" intype="Int16_B"  inlength="1"  keyword="ZXWD"	dicomtype="?"	dicomtag="?"	# X Dimension *10mm
+block="MAINHDR"	offset="436" intype="Int16_B"  inlength="1"  keyword="ZXLOC1"	dicomtype="?"	dicomtag="?"	# *10mm
+block="MAINHDR"	offset="438" intype="Int16_B"  inlength="1"  keyword="ZXLOC2"	dicomtype="?"	dicomtag="?"	# *10mm
+block="MAINHDR"	offset="440" intype="Int16_B"  inlength="1"  keyword="ZYWD"	dicomtype="?"	dicomtag="?"	# Y Dimension *10mm
+block="MAINHDR"	offset="442" intype="Int16_B"  inlength="1"  keyword="ZYLOC1"	dicomtype="?"	dicomtag="?"	# *10mm
+block="MAINHDR"	offset="444" intype="Int16_B"  inlength="1"  keyword="ZYLOC2"	dicomtype="?"	dicomtag="?"	# *10mm
+block="MAINHDR"	offset="446" intype="Int16_B"  inlength="1"  keyword="ZHREV"	dicomtype="?"	dicomtag="?"	# Header Revision
+block="MAINHDR"	offset="448" intype="Int16_B"  inlength="1"  keyword="ZSYSMAG"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="450" intype="Int16_B"  inlength="1"  keyword="ZSCOPT"	dicomtype="?"	dicomtag="?"	# Optional Control
+block="MAINHDR"	offset="452" intype="Int16_B"  inlength="1"  keyword="ZANGIO"	dicomtype="?"	dicomtag="?"	enum="0=No,1=Yes"	#
+block="MAINHDR"	offset="454" intype="Int16_B"  inlength="1"  name="Unknown454"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="456" intype="Int16_B"  inlength="1"  name="Unknown456"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="458" intype="Int16_B"  inlength="1"  name="Unknown458"	dicomtype="?"	dicomtag="?"	#
+block="MAINHDR"	offset="460" intype="Int16_B"  inlength="1"  keyword="ZSXADR"	dicomtype="?"	dicomtag="?"	# blk#
+block="MAINHDR"	offset="462" intype="Int16_B"  inlength="1"  keyword="ZSPMOD"	dicomtype="?"	dicomtag="?"	# KSPM
+block="MAINHDR"	offset="464" intype="String"   inlength="48" keyword="ZIMINF"	dicomtype="?"	dicomtag="?"	#
+
+constant="0" 			dicomtype="US"	dicomtag="PixelPaddingValue"		# 
+constant="16" 			dicomtype="US"	dicomtag="BitsAllocated"		# 
+constant="16" 			dicomtype="US"	dicomtag="BitsStored"			# 
+constant="15" 			dicomtype="US"	dicomtag="HighBit"			# 
+constant="0" 			dicomtype="US"	dicomtag="PixelRepresentation"		# Unsigned
+constant="1" 			dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 		dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+
+constant=""			dicomtype="DA"	dicomtag="PatientBirthDate"		# 
+constant=""			dicomtype="SH"	dicomtag="AccessionNumber"		# 
+constant="1"			dicomtype="IS"	dicomtag="SeriesInStudy"		# 
+constant="1"			dicomtype="IS"	dicomtag="AcquisitionsInStudy"		# 
+constant=""			dicomtype="SH"	dicomtag="StudyID"			#
+constant="1"			dicomtype="IS"	dicomtag="SeriesNumber"			# 
+constant=""			dicomtype="IS"	dicomtag="InstanceNumber"			# 
+
+constant=""			dicomtype="LO"	dicomtag="DeviceSerialNumber"		# 
+constant=""			dicomtype="DS"	dicomtag="PatientWeight"		# 
+constant="SHIMADZU"		dicomtype="LO"	dicomtag="Manufacturer"			# 
+constant=""			dicomtype="LO"	dicomtag="ManufacturerModelName"	# 
+
+constant=""			dicomtype="CS"	dicomtag="BodyPartExamined"		# 
+constant="MR"			dicomtype="CS"	dicomtag="Modality"			# 
diff --git a/libsrc/src/dconvert/shim/shimcl.h b/libsrc/src/dconvert/shim/shimcl.h
new file mode 100644
index 0000000..ca3a881
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimcl.h
@@ -0,0 +1,23 @@
+/* shimcl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "shimhdrm.h"
+#include "shimhdrp.h"
+#include "shimhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class SHIM_Header_BothClass : public SHIM_HeaderClass
+{
+public:
+	SHIM_Header_BothClass(istream *ist) : SHIM_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0);
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/shim/shimconv.cc b/libsrc/src/dconvert/shim/shimconv.cc
new file mode 100644
index 0000000..01d24e2
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "shimdc.h"
+#include "shimptrs.h"
+#include "shimconv.h"
diff --git a/libsrc/src/dconvert/shim/shimdc.cc b/libsrc/src/dconvert/shim/shimdc.cc
new file mode 100644
index 0000000..aba9145
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimdc.cc
@@ -0,0 +1,94 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimdc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "shimdc.h"
+#include "shim.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "shimsrc.h"
+
+bool
+SHIM_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(list);
+	Assert(in);
+	if (!shimhdr) shimhdr=new SHIM_Header_BothClass(in);
+	Assert(shimhdr);
+
+	shimhdr->ToDicom_Template(list,imagenumber);
+	shimhdr->ToDicom_ManualMisc(list,imagenumber);
+	shimhdr->ToDicom_ManualPlane(list,imagenumber);
+	shimhdr->ToDicom_ManualDates(list,imagenumber);
+
+	return true;
+}
+
+// See comments in shim.h about the importance of the scope
+// of a SHIM_Conversion object and AttributeList object
+
+bool
+SHIM_Conversion::convertPixelData(AttributeList *list,
+		TransferSyntax *transfersyntax,unsigned imagenumber)
+{
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!shimhdr) shimhdr=new SHIM_Header_BothClass(in);
+	Assert(shimhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	in->seekg(SHIM_Offset_IndexEntry_ptr(imagenumber),ios::beg);
+	if (!in->good()) return false;
+	unsigned char *indexentry = new unsigned char[SHIM_IndexEntry_lng];
+	Assert(indexentry);
+	in->read((char *)indexentry,SHIM_IndexEntry_lng);
+	if (!in->good()) return false;
+
+	Assert(pixeldatasrc==0);
+	pixeldatasrc=new SHIM_PixelDataSource(
+		*in,
+		SHIM_Offset_PixelData_ptr(indexentry),
+		rows,
+		cols);
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	if (indexentry) delete[] indexentry;
+
+	return true;
+}
+
+bool
+SHIM_Conversion::convertAll(AttributeList *list,
+	TransferSyntax *transfersyntax,
+	unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/shim/shimdc.h b/libsrc/src/dconvert/shim/shimdc.h
new file mode 100644
index 0000000..c02d3e9
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimdc.h
@@ -0,0 +1,7 @@
+/* shimdc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "shimcl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "shimptrs.h"
diff --git a/libsrc/src/dconvert/shim/shimdmp.cc b/libsrc/src/dconvert/shim/shimdmp.cc
new file mode 100644
index 0000000..ef026b4
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimdmp.cc
@@ -0,0 +1,36 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "shimdmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "shim.h"
+
+bool
+SHIM_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!shimhdr) shimhdr=new SHIM_Header_BothClass(in);
+	Assert(shimhdr);
+
+	TextOutputStream out(o);
+
+	shimhdr->DumpCommon(&out);
+
+	return true;
+}
+
+bool
+SHIM_Conversion::dumpSelectedImage(ostream &o,unsigned imagenumber)
+{
+	Assert(in);
+	if (!shimhdr) shimhdr=new SHIM_Header_BothClass(in);
+	Assert(shimhdr);
+
+	TextOutputStream out(o);
+
+	shimhdr->DumpSelectedImage(&out,imagenumber);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/shim/shimdmp.h b/libsrc/src/dconvert/shim/shimdmp.h
new file mode 100644
index 0000000..bb515b9
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimdmp.h
@@ -0,0 +1,4 @@
+/* shimdmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "shimcl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/shim/shimdmpf.cc b/libsrc/src/dconvert/shim/shimdmpf.cc
new file mode 100644
index 0000000..ba8d63e
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimdmpf.cc
@@ -0,0 +1,12 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimdmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "shimdmp.h"
+#include "shimptrs.h"
+#include "shimdmpf.h"
+
+// shim.tpl currently has no select="image" entries so
+// the following doesn't make it into shimdmpf.h ...
+
+void
+SHIM_Header_BothClass::DumpSelectedImage(TextOutputStream *,unsigned)
+{
+}
diff --git a/libsrc/src/dconvert/shim/shimhdrc.cc b/libsrc/src/dconvert/shim/shimhdrc.cc
new file mode 100644
index 0000000..6d44eaf
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimhdrc.cc
@@ -0,0 +1,361 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "shimptrs.h"
+#include "shimhdrm.h"
+#include "shimhdrp.h"
+#include "shimhdrw.h"
+#include "shimhdrc.h"
+
+#include "fltype.h"
+
+const Uint16 SHIM_BlockSize = 512;
+
+// Manually generated constructors for "method" based classes declared in shimhdrm.h
+
+// If the args are changed here, change the SHIM_MethodConstructorArgs macros in shimptrs.h
+
+/* ------------------------------ File Header ------------------------------ */
+
+SHIM_HeaderClass_FILEHDR::SHIM_HeaderClass_FILEHDR(istream *istr,
+	Uint16 fhentries,Uint16 fhcount,Uint16 fhdata,Uint16 blkfhdata)
+{
+	// Load the file header parts ...
+
+	nEntries=0;
+
+	unsigned long offset=fhentries*SHIM_BlockSize;
+	size_t length=fhcount*sizeof(SHIM_HeaderClass_FILEHDR_Entry);
+//cerr << "SHIM_HeaderClass_FILEHDR::SHIM_HeaderClass_FILEHDR: entry offset=" << dec << offset << endl;
+//cerr << "SHIM_HeaderClass_FILEHDR::SHIM_HeaderClass_FILEHDR: entry length=" << dec << length << endl;
+	Assert(sizeof(SHIM_HeaderClass_FILEHDR_Entry) == 12);
+	entry=new SHIM_HeaderClass_FILEHDR_Entry[fhcount];
+	Assert(entry);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+
+	// Since the entries are 12 bytes and the blocks are 512 bytes,
+	// there are 42 entries per block, with 8 bytes of padding to
+	// prevent an entry spanning a block boundary (grump)
+
+	unsigned entriesleft=fhcount;
+	const unsigned entriesperblock=SHIM_BlockSize/sizeof(SHIM_HeaderClass_FILEHDR_Entry);
+	const unsigned npadbytes=SHIM_BlockSize-entriesperblock*sizeof(SHIM_HeaderClass_FILEHDR_Entry);
+	Assert(entriesperblock == 42);
+	Assert(npadbytes == 8);
+	SHIM_HeaderClass_FILEHDR_Entry *entryptr=entry;
+	while (entriesleft) {
+		unsigned entriesthistry=entriesleft > entriesperblock ? entriesperblock : entriesleft;
+
+		istr->read((char*)entryptr,entriesthistry*sizeof(SHIM_HeaderClass_FILEHDR_Entry));
+		if (!istr->good()) return;
+
+		entriesleft-=entriesthistry;
+		entryptr+=entriesthistry;
+
+		char dummy[npadbytes];
+		istr->read(dummy,npadbytes);
+		if (!istr->good()) return;
+	}
+
+	offset=fhdata*SHIM_BlockSize;
+	length=blkfhdata*SHIM_BlockSize;
+//cerr << "SHIM_HeaderClass_FILEHDR::SHIM_HeaderClass_FILEHDR: data offset=" << dec << offset << endl;
+//cerr << "SHIM_HeaderClass_FILEHDR::SHIM_HeaderClass_FILEHDR: data length=" << dec << length << endl;
+	data=new char[length];
+	Assert(data);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+	istr->read(data,length);
+	if (!istr->good()) return;
+
+	nEntries=fhcount;
+
+	// Think about how caller handles errors ...
+	// see what ReadProprietaryHeader() would do
+
+//	int i;
+//	SHIM_HeaderClass_FILEHDR_Entry *ptr;
+//	for (i=0,ptr=entry; i<nEntries; ++i,++ptr) {
+//		cerr << "SHIM_HeaderClass_FILEHDR::SHIM_HeaderClass_FILEHDR: "
+//		     << "[" << dec << i << "]"
+//		     << " itemname=" << ptr->itemname
+//		     << " itemtype=" << ptr->itemtype
+//		     << " wordoffset=" << ptr->wordoffset
+//		     << " itemsize=" << ptr->itemsize
+//		     << endl;
+//	}
+}
+
+const SHIM_HeaderClass_FILEHDR_Entry *
+SHIM_HeaderClass_FILEHDR::operator[](const char *index) const
+{
+	Assert(index);
+	int i=0;
+	SHIM_HeaderClass_FILEHDR_Entry *ptr=entry;
+	while (i<nEntries && ptr && ptr->itemname && strcmp(ptr->itemname,index) != 0) { ++i; ++ptr; }
+	return i<nEntries ? entry+i : 0;
+}
+
+char *
+SHIM_HeaderClass_FILEHDR::SHIM_Method_ExtractTaggedString(const char *index) const
+{
+	const SHIM_HeaderClass_FILEHDR_Entry *ptr=(*this)[index];
+	char *s;
+	if (ptr && ptr->itemtype == 'B') {
+		s=new char[ptr->itemsize+1];
+		strncpy(s,data+(ptr->wordoffset-1)*2,ptr->itemsize);
+		s[ptr->itemsize]='\0';
+	}
+	else
+		s=0;
+
+	return s;
+}
+
+Int16
+SHIM_HeaderClass_FILEHDR::SHIM_Method_ExtractTaggedInteger(const char *index) const
+{
+	// Item size > 1 NYI
+	// ... IDEMAP itemtype=I wordoffset=79 itemsize=63
+
+	const SHIM_HeaderClass_FILEHDR_Entry *ptr=(*this)[index];
+	Uint16 u;
+	if (ptr && ptr->itemtype == 'I' && ptr->itemsize == 1) {
+		// little endian ...
+		// used unsigned char * else will sign extend :(
+		u=(*((unsigned char *)data+(ptr->wordoffset-1)*2+1) << 8)
+		 +(*((unsigned char *)data+(ptr->wordoffset-1)*2));
+	}
+	else
+		u=0xfffe;
+
+//cerr << "SHIM_HeaderClass_FILEHDR::SHIM_Method_ExtractTaggedInteger:"
+//     << " index=" << (index ? index : "")
+//     << " returns " << dec << u
+//     << endl;
+
+	return Int16(u);
+}
+
+Float64
+SHIM_HeaderClass_FILEHDR::SHIM_Method_ExtractTaggedFloat(const char *index) const
+{
+	// Item size > 1 NYI
+	// ... BOLTIM itemtype=F wordoffset=246 itemsize=2
+
+	const SHIM_HeaderClass_FILEHDR_Entry *ptr=(*this)[index];
+
+	if (ptr && ptr->itemtype == 'F' && ptr->itemsize == 1) {
+		return *(const Vax_Float_F *)(data+(ptr->wordoffset-1)*2);
+	}
+	else
+		return 9999;
+}
+
+/* ------------------------------ Slice Header ------------------------------ */
+
+SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR(istream *istr,
+		Uint16 nslices,
+		Uint16 slentries,Uint16 slcount,
+		Uint16 sltbposn,Uint16 sltbsize,
+		Uint16 blkslentries,Uint16 blksltbposn,
+		Uint16 blksltbdata)
+{
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start nslices=" << dec << nslices << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start slentries=" << dec << slentries << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start slcount=" << dec << slcount << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start sltbposn=" << dec << sltbposn << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start sltbsize=" << dec << sltbsize << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start blkslentries=" << dec << blkslentries << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start blksltbposn=" << dec << blksltbposn << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: start blksltbdata=" << dec << blksltbdata << endl;
+
+	(void)sltbsize;
+	(void)blkslentries;
+	(void)blksltbposn;
+
+	// Load the slice header parts ...
+
+	nEntries=0;
+	nSlices=0;
+
+	unsigned long offset=slentries*SHIM_BlockSize;
+	size_t length=slcount*sizeof(SHIM_HeaderClass_SLICEHDR_Entry);
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: entry offset=" << dec << offset << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: entry length=" << dec << length << endl;
+	Assert(sizeof(SHIM_HeaderClass_SLICEHDR_Entry) == 12);
+	entry=new SHIM_HeaderClass_SLICEHDR_Entry[slcount];
+	Assert(entry);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+
+	// Since the entries are 12 bytes and the blocks are 512 bytes,
+	// there are 42 entries per block, with 8 bytes of padding to
+	// prevent an entry spanning a block boundary (grump)
+
+	unsigned entriesleft=slcount;
+	const unsigned entriesperblock=SHIM_BlockSize/sizeof(SHIM_HeaderClass_SLICEHDR_Entry);
+	const unsigned npadbytes=SHIM_BlockSize-entriesperblock*sizeof(SHIM_HeaderClass_SLICEHDR_Entry);
+	Assert(entriesperblock == 42);
+	Assert(npadbytes == 8);
+	SHIM_HeaderClass_SLICEHDR_Entry *entryptr=entry;
+	while (entriesleft) {
+		unsigned entriesthistry=entriesleft > entriesperblock ? entriesperblock : entriesleft;
+
+		istr->read((char*)entryptr,entriesthistry*sizeof(SHIM_HeaderClass_SLICEHDR_Entry));
+		if (!istr->good()) return;
+
+		entriesleft-=entriesthistry;
+		entryptr+=entriesthistry;
+
+		char dummy[npadbytes];
+		istr->read(dummy,npadbytes);
+		if (!istr->good()) return;
+	}
+
+	// read the slice position table
+
+	offset=sltbposn*SHIM_BlockSize;
+	length=nslices*sizeof(Uint16_L);
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: position offset=" << dec << offset << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: position length=" << dec << length << endl;
+	sliceposition=new Uint16_L[nslices];
+	Assert(sliceposition);
+	istr->seekg(offset,ios::beg);
+	if (!istr->good()) return;
+	
+	unsigned i;
+
+	istr->read((char *)sliceposition,length);
+	if (!istr->good()) return;
+
+//	for (i=0; i<nslices; ++i) {
+//		cerr << "sliceposition[" << dec << i << "]=" << dec << sliceposition[i] << endl;
+//	}
+
+	// read the offsets of the slice header data
+	// by dereferencing the slice position table block pointers
+
+	headerdata=new char *[nslices];
+	Assert(headerdata);
+
+	for (i=0; i<nslices; ++i) {
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: " 
+//     << "[" << dec << i << "]"
+//     << " dereference the slice position table block pointers"
+//     << endl;
+		// dereference the slice position table block pointers ...
+
+		offset=sliceposition[i]*SHIM_BlockSize;
+		length=blksltbdata*SHIM_BlockSize;
+		headerdata[i]=new char[length];
+
+//cerr << " sliceposition[i]=" << dec << sliceposition[i] << endl;
+//cerr << " offset=" << dec << offset << endl;
+//cerr << " blksltbdata=" << dec << blksltbdata << endl;
+//cerr << " length=" << dec << length << endl;
+
+		istr->seekg(offset,ios::beg);
+		if (!istr->good()) return;
+		istr->read(headerdata[i],length);
+		if (!istr->good()) return;
+	}
+
+	nEntries=slcount;
+	nSlices=nslices;
+
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: end nEntries=" << dec << nEntries << endl;
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: end nSlices=" << dec << nSlices << endl;
+
+	// Think about how caller handles errors ...
+	// see what ReadProprietaryHeader() would do
+
+//	SHIM_HeaderClass_SLICEHDR_Entry *ptr;
+//	for (i=0,ptr=entry; i<nEntries; ++i,++ptr) {
+//		cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: "
+//		     << "[" << dec << i << "]"
+//		     << " itemname=" << ptr->itemname
+//		     << " itemtype=" << ptr->itemtype
+//		     << " wordoffset=" << ptr->wordoffset
+//		     << " itemsize=" << ptr->itemsize
+//		     << endl;
+//	}
+
+//	for (i=0; i<nSlices; ++i) {
+//		cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_HeaderClass_SLICEHDR: " 
+//		     << "[" << dec << i << "]"
+//		     << " sliceposition=" << sliceposition[i]
+//		     << endl;
+//	}
+
+	// BTW. the first Uint16_L field of the headerdata for each slice
+	// is ISDATP which is 512 byte block offset to slice image data
+}
+
+const SHIM_HeaderClass_SLICEHDR_Entry *
+SHIM_HeaderClass_SLICEHDR::operator[](const char *index) const
+{
+	Assert(index);
+	int i=0;
+	SHIM_HeaderClass_SLICEHDR_Entry *ptr=entry;
+	while (i<nEntries && ptr && ptr->itemname && strcmp(ptr->itemname,index) != 0) { ++i; ++ptr; }
+	return i<nEntries ? entry+i : 0;
+}
+
+char *
+SHIM_HeaderClass_SLICEHDR::SHIM_Method_ExtractTaggedString(unsigned slice,const char *index) const
+{
+	Assert(slice < nSlices);
+	const SHIM_HeaderClass_SLICEHDR_Entry *ptr=(*this)[index];
+	char *s;
+	if (ptr && ptr->itemtype == 'B') {
+		s=new char[ptr->itemsize+1];
+		strncpy(s,headerdata[slice]+(ptr->wordoffset-1)*2,ptr->itemsize);
+		s[ptr->itemsize]='\0';
+	}
+	else
+		s=0;
+
+	return s;
+}
+
+Int16
+SHIM_HeaderClass_SLICEHDR::SHIM_Method_ExtractTaggedInteger(unsigned slice,const char *index) const
+{
+//cerr << "SHIM_HeaderClass_SLICEHDR::SHIM_Method_ExtractTaggedInteger:"
+//     << " nSlices=" << dec << nSlices
+//     << " slice=" << dec << slice
+//     << " index=" << (index ? index : "")
+//     << endl;
+	Assert(slice < nSlices);
+	// Item size > 1 NYI
+
+	const SHIM_HeaderClass_SLICEHDR_Entry *ptr=(*this)[index];
+	Uint16 u;
+	if (ptr && ptr->itemtype == 'I' && ptr->itemsize == 1) {
+		// little endian ...
+		// used unsigned char * else will sign extend :(
+		u=(*((unsigned char *)headerdata[slice]+(ptr->wordoffset-1)*2+1) << 8)
+		 +(*((unsigned char *)headerdata[slice]+(ptr->wordoffset-1)*2));
+	}
+	else
+		u=0xffe0;
+
+	return Int16(u);
+}
+
+Float64
+SHIM_HeaderClass_SLICEHDR::SHIM_Method_ExtractTaggedFloat(unsigned slice,const char *index) const
+{
+	Assert(slice < nSlices);
+	// Item size > 1 NYI
+
+	const SHIM_HeaderClass_SLICEHDR_Entry *ptr=(*this)[index];
+
+	if (ptr && ptr->itemtype == 'F' && ptr->itemsize == 1) {
+		return *(const Vax_Float_F *)(headerdata[slice]+(ptr->wordoffset-1)*2);
+	}
+	else
+		return 9999;
+}
+
diff --git a/libsrc/src/dconvert/shim/shimhdrm.h b/libsrc/src/dconvert/shim/shimhdrm.h
new file mode 100644
index 0000000..aefb23d
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimhdrm.h
@@ -0,0 +1,55 @@
+/* shimhdrm.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// Manually define classes to handle "method" based blocks
+// (equivalent to automatically generated stuff in shimhdrp.h)
+
+struct SHIM_HeaderClass_FILEHDR_Entry {
+	char		itemname[7];
+	char 		itemtype;	// 'B' or'I' or 'F'
+	Uint16_L	wordoffset;	// from 1
+	Uint16_L	itemsize;	// number of itemtype elements
+};
+
+class SHIM_HeaderClass_FILEHDR {
+	SHIM_HeaderClass_FILEHDR_Entry *entry;
+	char *data;
+	unsigned nEntries;
+
+	const SHIM_HeaderClass_FILEHDR_Entry *operator[](const char *index) const;
+public:
+	SHIM_HeaderClass_FILEHDR(istream *ist,
+		Uint16 fhentries,Uint16 fhcount,
+		Uint16 fhdata,Uint16 blkfhdata); // Defined in shimhdrc.cc
+
+	char   *SHIM_Method_ExtractTaggedString (const char *index) const;
+	Int16   SHIM_Method_ExtractTaggedInteger(const char *index) const;
+	Float64 SHIM_Method_ExtractTaggedFloat  (const char *index) const;
+};
+
+struct SHIM_HeaderClass_SLICEHDR_Entry {
+	char		itemname[7];
+	char 		itemtype;	// 'B' or'I' or 'F'
+	Uint16_L	wordoffset;	// from 1
+	Uint16_L	itemsize;	// number of itemtype elements
+};
+
+class SHIM_HeaderClass_SLICEHDR {
+	SHIM_HeaderClass_SLICEHDR_Entry *entry;
+	Uint16_L *sliceposition;
+	char **headerdata;
+	unsigned nEntries;
+	unsigned nSlices;
+
+	const SHIM_HeaderClass_SLICEHDR_Entry *operator[](const char *index) const;
+public:
+	SHIM_HeaderClass_SLICEHDR(istream *ist,
+		Uint16 nslices,
+		Uint16 slentries,Uint16 slcount,
+		Uint16 sltbposn,Uint16 sltbsize,
+		Uint16 blkslentries,Uint16 blksltbposn,
+		Uint16 blksltbdata); // Defined in shimhdrc.cc
+
+	char   *SHIM_Method_ExtractTaggedString (unsigned slice,const char *index) const;
+	Int16   SHIM_Method_ExtractTaggedInteger(unsigned slice,const char *index) const;
+	Float64 SHIM_Method_ExtractTaggedFloat  (unsigned slice,const char *index) const;
+};
+
diff --git a/libsrc/src/dconvert/shim/shimmdt.cc b/libsrc/src/dconvert/shim/shimmdt.cc
new file mode 100644
index 0000000..03501e0
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimmdt.cc
@@ -0,0 +1,47 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "shimdc.h"
+#include "elmconst.h"
+
+void 
+SHIM_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	(void)imagenumber;
+
+	Date thedate=Date(String_Use(SHIM_HeaderInstance_MAINHDR->ZADATW));
+
+	Time thetime=Time(String_Use(SHIM_HeaderInstance_MAINHDR->ZATIME));
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),thedate);
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),thetime);
+
+	// SeriesDate
+
+	(*list)+=new DateStringAttribute(TagFromName(SeriesDate),thedate);
+
+	// SeriesTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(SeriesTime),thetime);
+
+	// AcquisitionDate
+
+	(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),thedate);
+
+	// AcquisitionTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),thetime);
+
+	// ContentDate (formerly Image)
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),thedate);
+
+	// ContentTime (formerly Image)
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),thetime);
+
+}
+
diff --git a/libsrc/src/dconvert/shim/shimmmsc.cc b/libsrc/src/dconvert/shim/shimmmsc.cc
new file mode 100644
index 0000000..727bc44
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimmmsc.cc
@@ -0,0 +1,195 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "shimdc.h"
+#include "elmconst.h"
+
+void 
+SHIM_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	(void)list; (void)imagenumber;
+#ifdef CRAP
+	ostrstream imagecommentstream;
+
+	// ImageType
+
+	const char *value1,*value2,*value3;
+
+	int istudy=SHIM_HeaderInstance_FILEHDR->SHIM_Method_ExtractTaggedInteger("ISTUDY");
+	imagecommentstream << "ISTUDY == " << dec << istudy << " is ";
+
+	switch (istudy) {
+		case  1:	// localization
+			imagecommentstream << "LOCALIZATION";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="LOCALIZER";
+			break;
+		case  2:	// flow study
+			imagecommentstream << "FLOW STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  3:	// movie study
+			imagecommentstream << "MOVIE STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  4:	// average volume study
+			imagecommentstream << "AVERAGE VOLUME STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  5:	// volume study
+			imagecommentstream << "VOLUME STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  6:	// average flow study
+			imagecommentstream << "AVERAGE FLOW STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  7:	// continuous volume study
+			imagecommentstream << "CONTNUOUS VOLUME STUDY";
+			value1="ORIGINAL";
+			value2="PRIMARY";
+			value3="AXIAL";
+			break;
+		case  51:	// image averaging
+			imagecommentstream << "IMAGE AVERAGING";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  52:	// reformat
+			imagecommentstream << "REFORMAT";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="REFORMAT";			// my own :(
+			break;
+		case  53:	// FIP Maximum Difference
+			imagecommentstream << "FIP MAXIMUM DIFFERENCE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  54:	// FIP Time to Peak
+			imagecommentstream << "FIP TIME TO PEAK";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  55:	// FIP Area Under Curve
+			imagecommentstream << "FIP AREA UNDER CURVE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  56:	// FIP Center of Mass
+			imagecommentstream << "FIP CENTER OF MASS";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+
+		case  102:	// image subtraction flow
+			imagecommentstream << "IMAGE SUBTRACTION FLOW";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  103:	// image subtraction movie
+			imagecommentstream << "IMAGE SUBTRACTION MOVIE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  105:	// image subtraction volume
+			imagecommentstream << "IMAGE SUBTRACTION VOLUME";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+		case  106:	// image subtraction average flow
+			imagecommentstream << "IMAGE SUBTRACTION AVERAGE FLOW";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="AXIAL";
+			break;
+
+		case -1:	// screen save
+			imagecommentstream << "SCREEN SAVE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		case  0:	// special
+			imagecommentstream << "SPECIAL CASE";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+		default:
+			imagecommentstream << "UNRECOGNIZED";
+			value1="DERIVED";
+			value2="SECONDARY";
+			value3="UNKNOWN";			// my own :(
+			break;
+	}
+
+	(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+		value1,value2,value3);
+
+	imagecommentstream << ", ";
+
+	// RotationDirection
+
+	const char *rotationdirection;
+
+	switch(SHIM_HeaderInstance_SLICEHDR->
+			SHIM_Method_ExtractTaggedInteger(imagenumber,"IROTA")) {
+		case -1:	rotationdirection="CC"; break;
+		case  1:	rotationdirection="CW"; break;
+		default:	rotationdirection="";   break;
+	}
+
+	(*list)+=new CodeStringAttribute(TagFromName(RotationDirection),rotationdirection);
+
+	// ExposureTime
+
+	// derive from number of DAS samples per detector per source fan
+	// and number of averages per slice
+
+	Float64 exposuretime;
+	Float64 numberofaveragesperslice=SHIM_HeaderInstance_FILEHDR->SHIM_Method_ExtractTaggedInteger("NSLAVG");
+
+	int irep=SHIM_HeaderInstance_FILEHDR->SHIM_Method_ExtractTaggedInteger("IREP");
+	imagecommentstream << "IREP == " << dec << irep << " is ";
+
+	switch (irep) {
+		case 3:	// Multi-Slice Mode
+			imagecommentstream << "MULTI-SLICE MODE";
+			exposuretime=50*numberofaveragesperslice;
+			break;
+		case 6:	// Single-Slice Mode
+			imagecommentstream << "SINGLE-SLICE MODE";
+			exposuretime=100*numberofaveragesperslice;
+			break;
+		default:
+			imagecommentstream << "UNRECOGNIZED MODE";
+			exposuretime=0;
+			break;
+	}
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ExposureTime),exposuretime);
+
+	char *imagecommentstring=imagecommentstream.str();
+	(*list)+=new LongTextAttribute(TagFromName(ImageComments),imagecommentstring);
+	if (imagecommentstring) delete[] imagecommentstring;
+#endif /* CRAP */
+}
+
diff --git a/libsrc/src/dconvert/shim/shimmpln.cc b/libsrc/src/dconvert/shim/shimmpln.cc
new file mode 100644
index 0000000..208de0d
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimmpln.cc
@@ -0,0 +1,229 @@
+static const char *CopyrightIdentifier(void) { return "@(#)shimmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "shimdc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+SHIM_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	// Not yet implemented
+	(void)list; (void)imagenumber;
+#ifdef CRAP
+	// PixelSpacing
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		SHIM_HeaderInstance_FILEHDR->
+			SHIM_Method_ExtractTaggedFloat("PIXLEN"),
+		SHIM_HeaderInstance_FILEHDR->
+			SHIM_Method_ExtractTaggedFloat("PIXLEN"));
+
+	// ZoomFactor
+
+	double zoomfactor=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedFloat(imagenumber,"ZOOM");
+
+	if (fabs(zoomfactor) < .0001) zoomfactor=1;	// ie. zero
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomFactor),zoomfactor,zoomfactor);
+
+	// ZoomCenter
+
+	double reconcenterhorizontal=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedFloat(imagenumber,"XORG");
+	double reconcentervertical  =SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedFloat(imagenumber,"YORG");
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomCenter),reconcenterhorizontal,reconcentervertical);
+
+	// SliceLocation
+
+	double slicelocation=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedInteger(imagenumber,"INOUT")/10.0;
+
+	int irep=SHIM_HeaderInstance_FILEHDR->SHIM_Method_ExtractTaggedInteger("IREP");
+	if (irep == 3) {
+		// Multi-Slice mode
+		double targetoffset;
+		int target=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedInteger(imagenumber,"ITARGET");
+		switch (target) {
+			case 'A':	targetoffset=40;
+					break;
+			case 'B':	targetoffset=20;
+					break;
+			case 'C':	targetoffset=0;
+					break;
+			case 'D':	targetoffset=-20;
+					break;
+			default:	// blech :(
+					targetoffset=0;
+					break;
+		}
+		int ring=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedInteger(imagenumber,"IRING");
+		double detectoroffset=(ring%2)*8;
+
+		slicelocation+=targetoffset+detectoroffset;
+	}
+	// assume IREP == 6, Single-Slice mode, which just uses INOUT and is relative to Target C, Detector Ring 2
+
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),slicelocation);
+
+	// Trying to derive Image Plane Module ...
+
+	ImagePlanePlane plane=Axial;
+
+	char *hfff,*ap;
+	ImagePlaneHeadFeet orientation;
+	ImagePlanePosition position;
+
+	// The Imatron may already have flipped the image pixel data,
+	// so record the position and orientation in the descriptive DICOM tags
+	// but tell the ImagePlane module generator the flipped not the physical position
+
+	// Is this going to mess up the relationship between machine plane and patient plane ?
+
+	switch (SHIM_HeaderInstance_SLICEHDR->
+			SHIM_Method_ExtractTaggedInteger(imagenumber,"IPATOR")) {
+
+		case -5:	// Supine feet first, flipped to match supine head first
+			ap="S";
+			position=Supine;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case -6:	// Prone feet first, flipped to match prone head first
+			ap="P";
+			position=Prone;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case -7:	// Decubitus right feet first, flipped to match decubitus right head first
+			ap="DR";
+			position=RightLateralDecubitus;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case -8:	// Decubitus left feet first, flipped to match decubitus left head first
+			ap="DL";
+			position=LeftLateralDecubitus;
+			hfff="FF";
+			orientation=HeadFirst;	// Not FeetFirst ... already flipped
+			break;
+
+		case  -1:	// Supine feet first
+			ap="S";
+			position=Supine;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+
+		case  -2:	// Prone feet first
+			ap="P";
+			position=Prone;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+
+		case  -3:	// Decubitus right feet first
+			ap="DR";
+			position=RightLateralDecubitus;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+
+		case  -4:	// Decubitus left feet first
+			ap="DL";
+			position=LeftLateralDecubitus;
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+		case  1:	// Supine head first
+			ap="S";
+			position=Supine;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  2:	// Prone head first
+			ap="P";
+			position=Prone;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  3:	// Decubitus right head first
+			ap="DR";
+			position=RightLateralDecubitus;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  4:	// Decubitus left head first
+			ap="DL";
+			position=LeftLateralDecubitus;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+
+		case  5:	// Prone head first flipped (assume to match supine ? not specified in format)
+			ap="P";
+			position=Supine;	// Not Prone ... already flipped
+			hfff="HF";
+			orientation=HeadFirst;
+
+		case  0:	// Special case :(
+			Assert(0);
+			ap="S";
+			position=Supine;
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+	}
+
+	double scanfov=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedFloat(imagenumber,"PICRAD");
+
+	// Make a model of the image plane ...
+
+	ImagePlane imageplane(plane,scanfov,orientation,position);
+
+	// While we are in the "display" or "gantry plane ...
+	// (before angulation) 
+
+	// Apply any transformations specified in the
+	// display/gantry plane, such as magnification and
+	// reconstruction target offsets ...
+
+	// Assume that these are machine rather than body relative	DON'T KNOW IF THIS IS CORRECT :(
+
+//	imageplane.MachinePlane::scale(zoomfactor);			// Leave out - assume for now that PICRAD is DFOV
+
+	// Always axial so X and Y are really X and Y
+	// Don't forget sign changes ...				DON'T KNOW IF THIS IS CORRECT :(
+
+	Vector3D reconoffset(reconcenterhorizontal,reconcentervertical,0);
+
+	imageplane.MachinePlane::shift(reconoffset);
+
+	// Account for angulation ...
+
+	double gantrytilt=SHIM_HeaderInstance_SLICEHDR->SHIM_Method_ExtractTaggedInteger(imagenumber,"ITILT");
+
+	// +ve is top towards table					DON'T KNOW IF THIS IS CORRECT :(
+	imageplane.MachinePlane::angle(LeftRight,gantrytilt);
+
+	// Account for physical offsets after angulation
+
+	// Assume no sign difference Shim vs. Dicom for Z		DON'T KNOW IF THIS IS CORRECT :(
+	// Assume that these are machine rather than body relative	DON'T KNOW IF THIS IS CORRECT :(
+
+	Vector3D offset(0,0,slicelocation);
+	imageplane.MachinePlane::shift(offset);
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),String_Cat_Use(hfff,ap));
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+
+#endif /* CRAP */
+}
+
diff --git a/libsrc/src/dconvert/shim/shimptrs.h b/libsrc/src/dconvert/shim/shimptrs.h
new file mode 100644
index 0000000..1271e07
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimptrs.h
@@ -0,0 +1,14 @@
+/* shimptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	SHIM_Offset_MAINHDR_ptr	0
+
+#define	SHIM_isExtendedHeader			(shimhdr->SHIM_HeaderInstance_MAINHDR->ZHREV > 255)
+#define SHIM_MAINHDR_lng			(SHIM_isExtendedHeader ? 2048 : 512)
+#define SHIM_IndexEntry_lng			(SHIM_isExtendedHeader ? 256 : 48)
+#define SHIM_Offset_IndexEntry_ptr(image)	(SHIM_MAINHDR_lng+image*SHIM_IndexEntry_lng)
+
+#define SHIM_Offset_PixelData_ptr(entry)	((shimhdr->SHIM_HeaderInstance_MAINHDR->ZIBLKA - 1 \
+						  + (SHIM_isExtendedHeader \
+							? ((Uint32(*(entry+50))<<24) + (Uint32(*(entry+51))<<16) + (Uint32(*(entry+48))<< 8) + Uint32(*(entry+49))) \
+							: ((Uint32(*(entry+28))<< 8) +  Uint32(*(entry+29)) ) ) \
+						 ) * 512)
+
diff --git a/libsrc/src/dconvert/shim/shimsrc.h b/libsrc/src/dconvert/shim/shimsrc.h
new file mode 100644
index 0000000..5e0b92c
--- /dev/null
+++ b/libsrc/src/dconvert/shim/shimsrc.h
@@ -0,0 +1,61 @@
+/* shimsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_shimsrc__
+#define __Header_shimsrc__
+
+class SHIM_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	SHIM_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~SHIM_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Big endian ...
+				Uint16 pixel;
+				pixel=(bytes[0]<<8)|bytes[1];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_shimsrc__
diff --git a/libsrc/src/dconvert/signa/Imakefile b/libsrc/src/dconvert/signa/Imakefile
new file mode 100755
index 0000000..4fa6768
--- /dev/null
+++ b/libsrc/src/dconvert/signa/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = sgndc.cc sgnconv.cc sgnmpln.cc \
+		 sgnmmsc.cc sgnmdt.cc \
+		 sgndmp.cc sgndmpf.cc \
+		 sgnhdrc.cc sgn.cc
+
+OBJS = 		 sgndc.o  sgnconv.o  sgnmpln.o  \
+		 sgnmmsc.o  sgnmdt.o  \
+		 sgndmp.o  sgndmpf.o  \
+		 sgnhdrc.o  sgn.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdsgn.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(signa,dconvert)
+
+ProjectConvertTemplate(sgnhdrp.h,signa,convert,prefix=SGN_ role=headerpart offsetwarning=off)
+ProjectConvertTemplate(sgnhdrw.h,signa,convert,prefix=SGN_ role=wholeheader)
+ProjectConvertTemplate(sgnhdrc.h,signa,convert,prefix=SGN_ role=constructheader)
+ProjectConvertTemplate(sgnconv.h,signa,convert,prefix=SGN_ role=dicom)
+ProjectConvertTemplate(sgndmpf.h,signa,convert,prefix=SGN_ role=dump)
+
+sgndmpf.o: sgndmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) sgndmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/signa/README b/libsrc/src/dconvert/signa/README
new file mode 100755
index 0000000..a13b104
--- /dev/null
+++ b/libsrc/src/dconvert/signa/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"signa.h"
+		class SGN_Conversion {
+			SGN_Conversion(istream &i,ostream &e);
+			virtual ~SGN_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"sgn.cc"
+
+		SGN_Conversion::SGN_Conversion(istream &i,ostream &e);
+		SGN_Conversion::~SGN_Conversion();
+
+	"sgncl.h"
+
+		class SGN_Header_BothClass  : public SGN_HeaderClass
+		{
+		public:
+			SGN_Header_BothClass(istream *ist) : SGN_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"sgnconv.cc"
+
+		#include "sgnconv.h"
+
+	"sgndc.c"
+
+		bool SGN_Conversion::convertHeader(AttributeList *list);
+		bool SGN_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool SGN_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"sgndc.h"
+
+	"sgndmp.cc"
+
+		bool SGN_Conversion::dump(ostream &o);
+
+	"sgndmp.h"
+
+	"sgnhdrc.cc"
+
+		#include "sgnhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"sgn.tpl"
+
+		The template "describing" the format for header generation
+
+	"sgnmdt.cc"
+
+		void SGN_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"sgnmmsc.cc"
+
+		void SGN_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"sgnmpln.cc"
+
+		void SGN_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"sgnptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"sgnsrc.h"
+
+		class SGN_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			SGN_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~SGN_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from gen.tpl:
+
+	"sgnhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class SGN_HeaderClass_HDR1 {
+		public:
+			SGN_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"sgnhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class SGN_HeaderClass
+		{
+		public:
+			SGN_HeaderClass(istream *ist);
+
+			SGN_HeaderClass_HDR1 *SGN_HeaderInstance_HDR1;
+			SGN_HeaderClass_HDR2 *SGN_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"sgnhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		SGN_HeaderClass::SGN_HeaderClass(istream *ist);
+
+	"sgnconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void SGN_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"sgndmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void SGN_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "sgnhdrm.h".
+
+	if you have special purpose code, then "sgnhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "sgnhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/signa/sgn.cc b/libsrc/src/dconvert/signa/sgn.cc
new file mode 100644
index 0000000..75c26eb
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgn.cc
@@ -0,0 +1,35 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "signa.h"
+#include "sgncl.h"
+#include "srcsink.h"
+#include "sgnsrc.h"
+
+void
+SGN_Conversion::init(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	sgnhdr=0;
+	pixeldatasrc=0;
+}
+
+SGN_Conversion::SGN_Conversion(istream &i,ostream &e)
+{
+	init(i,e);
+	// use SGN_FileStructureInformation as constructed already
+}
+
+SGN_Conversion::~SGN_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (sgnhdr) delete sgnhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/signa/sgncl.h b/libsrc/src/dconvert/signa/sgncl.h
new file mode 100644
index 0000000..91bc969
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgncl.h
@@ -0,0 +1,28 @@
+/* sgncl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "sgnhdrp.h"
+#include "sgnhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class SGN_Header_BothClass : public SGN_HeaderClass
+{
+public:
+	SGN_Header_BothClass(istream *ist)
+		: SGN_HeaderClass(ist)
+		{
+		}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/signa/sgnconv.cc b/libsrc/src/dconvert/signa/sgnconv.cc
new file mode 100644
index 0000000..0584318
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgnconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "sgndc.h"
+#include "sgnptrs.h"
+#include "sgnconv.h"
diff --git a/libsrc/src/dconvert/signa/sgndc.cc b/libsrc/src/dconvert/signa/sgndc.cc
new file mode 100644
index 0000000..f3b385c
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgndc.cc
@@ -0,0 +1,92 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgndc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sgndc.h"
+#include "signa.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "sgnsrc.h"
+
+bool
+SGN_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!sgnhdr) sgnhdr=new SGN_Header_BothClass(in);
+	Assert(sgnhdr);
+
+	sgnhdr->ToDicom_Template(list);
+	sgnhdr->ToDicom_ManualMisc(list);
+	sgnhdr->ToDicom_ManualPlane(list);
+	sgnhdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in signa.h about the importance of the scope
+// of a SGN_Conversion object and AttributeList object
+
+bool
+SGN_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!sgnhdr) sgnhdr=new SGN_Header_BothClass(in);
+	Assert(sgnhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	// Manually expand the offsets
+
+	pixeldatasrc=new SGN_PixelDataSource(
+		*in,
+		SGN_Offset_IMAGEDATA_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+SGN_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/signa/sgndc.h b/libsrc/src/dconvert/signa/sgndc.h
new file mode 100644
index 0000000..c86d67b
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgndc.h
@@ -0,0 +1,7 @@
+/* sgndc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "sgncl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "sgnptrs.h"
diff --git a/libsrc/src/dconvert/signa/sgndmp.cc b/libsrc/src/dconvert/signa/sgndmp.cc
new file mode 100644
index 0000000..febf7ac
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgndmp.cc
@@ -0,0 +1,23 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgndmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sgndmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "signa.h"
+
+bool
+SGN_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!sgnhdr) sgnhdr=new SGN_Header_BothClass(in);
+	Assert(sgnhdr);
+
+	TextOutputStream out(o);
+
+	sgnhdr->DumpCommon(&out);
+
+	return true;
+}
+
+
diff --git a/libsrc/src/dconvert/signa/sgndmp.h b/libsrc/src/dconvert/signa/sgndmp.h
new file mode 100644
index 0000000..f7aa123
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgndmp.h
@@ -0,0 +1,4 @@
+/* sgndmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "sgncl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/signa/sgndmpf.cc b/libsrc/src/dconvert/signa/sgndmpf.cc
new file mode 100644
index 0000000..d1bc774
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgndmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgndmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sgndmp.h"
+#include "sgnptrs.h"
+#include "sgndmpf.h"
diff --git a/libsrc/src/dconvert/signa/sgnhdrc.cc b/libsrc/src/dconvert/signa/sgnhdrc.cc
new file mode 100644
index 0000000..92b21f3
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnhdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgnhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "sgnptrs.h"
+#include "sgnhdrp.h"
+#include "sgnhdrw.h"
+#include "sgnhdrc.h"
+
diff --git a/libsrc/src/dconvert/signa/sgnmdt.cc b/libsrc/src/dconvert/signa/sgnmdt.cc
new file mode 100644
index 0000000..ba04698
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnmdt.cc
@@ -0,0 +1,83 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgnmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sgndc.h"
+#include "elmconst.h"
+
+void 
+SGN_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),Date(
+		SGN_HeaderInstance_STUDYHDR->StudyDateYear,
+		SGN_HeaderInstance_STUDYHDR->StudyDateMonth,
+		SGN_HeaderInstance_STUDYHDR->StudyDateDay
+	));
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),Time(
+		SGN_HeaderInstance_STUDYHDR->StudyTimeHour,
+		SGN_HeaderInstance_STUDYHDR->StudyTimeMin,
+		SGN_HeaderInstance_STUDYHDR->StudyTimeSec
+	));
+
+	(*list)+=new DateStringAttribute(TagFromName(SeriesDate),Date(
+		SGN_HeaderInstance_SERIESHDR->SeriesDateYear,
+		SGN_HeaderInstance_SERIESHDR->SeriesDateMonth,
+		SGN_HeaderInstance_SERIESHDR->SeriesDateDay
+	));
+
+	(*list)+=new TimeStringAttribute(TagFromName(SeriesTime),Time(
+		SGN_HeaderInstance_SERIESHDR->SeriesTimeHour,
+		SGN_HeaderInstance_SERIESHDR->SeriesTimeMin,
+		SGN_HeaderInstance_SERIESHDR->SeriesTimeSec
+	));
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),Date(
+		SGN_HeaderInstance_IMAGEHDR->ImageDateYear,
+		SGN_HeaderInstance_IMAGEHDR->ImageDateMonth,
+		SGN_HeaderInstance_IMAGEHDR->ImageDateDay
+	));
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),Time(
+		SGN_HeaderInstance_IMAGEHDR->ImageTimeHour,
+		SGN_HeaderInstance_IMAGEHDR->ImageTimeMin,
+		SGN_HeaderInstance_IMAGEHDR->ImageTimeSec
+	));
+
+	(*list)+=new DateStringAttribute(TagFromName(AcquisitionDate),Date(
+		SGN_HeaderInstance_IMAGEHDR->ImageDateYear,
+		SGN_HeaderInstance_IMAGEHDR->ImageDateMonth,
+		SGN_HeaderInstance_IMAGEHDR->ImageDateDay
+	));
+
+	(*list)+=new TimeStringAttribute(TagFromName(AcquisitionTime),Time(
+		SGN_HeaderInstance_IMAGEHDR->ImageTimeHour,
+		SGN_HeaderInstance_IMAGEHDR->ImageTimeMin,
+		SGN_HeaderInstance_IMAGEHDR->ImageTimeSec
+	));
+
+	{
+		// PatientAge
+
+		char *str = SGN_HeaderInstance_STUDYHDR->PatientAge;
+		ostrstream ost;
+		ost << setfill('0') << setw(3)  << dec << atoi(str);
+		if      (strchr(str,'d') || strchr(str,'D')) ost << "D";
+		else if (strchr(str,'w') || strchr(str,'W')) ost << "W";
+		else if (strchr(str,'m') || strchr(str,'M')) ost << "M";
+		else ost << "Y";
+
+		ost << ends;
+		char *agestr=ost.str();
+		if (agestr) {
+			if (strlen(agestr))
+				(*list)+=new AgeStringAttribute(
+					TagFromName(PatientAge),agestr);
+			delete[] agestr;
+		}
+	}
+
+	// PatientWeight
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PatientWeight),Uint32(SGN_HeaderInstance_STUDYHDR->PatientWeightGrams)/1000.0);
+}
+
diff --git a/libsrc/src/dconvert/signa/sgnmmsc.cc b/libsrc/src/dconvert/signa/sgnmmsc.cc
new file mode 100644
index 0000000..77a404c
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnmmsc.cc
@@ -0,0 +1,361 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgnmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sgndc.h"
+#include "elmconst.h"
+
+void 
+SGN_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	{
+		// ImageType
+
+		const char *value1,*value2,*value3;
+
+		switch (SGN_HeaderInstance_SERIESHDR->SeriesType) {
+			case 0:		// Normal
+					value1="ORIGINAL";
+					value2="PRIMARY";
+					value3="OTHER";
+					break;
+			case 1:		// Screensave
+					value1="DERIVED";
+					value2="PRIMARY";
+					value3="OTHER";
+					break;
+			case 2:		// Composite
+					value1="DERIVED";
+					value2="PRIMARY";
+					value3="OTHER";
+					break;
+			default:
+					value1="UNKNOWN";
+					value2="UNKNOWN";
+					value3="UNKNOWN";
+					break;
+		}
+
+		(*list)+=new CodeStringAttribute(TagFromName(ImageType),value1,value2,value3);
+	}
+
+	{
+		// MagneticFieldStrength - Tesla
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(MagneticFieldStrength),
+				Uint32(SGN_HeaderInstance_SERIESHDR->MagneticFieldStrengthGauss)/10000.0);
+
+		// ImagingFrequency MHz (Signa is in Hz)
+
+		(*list)+=new
+			DecimalStringAttribute(TagFromName(ImagingFrequency),
+				Uint32(SGN_HeaderInstance_IMAGEHDR->TransmitFreq)/1000000.0);
+	}
+
+	{
+		// RepetitionTime
+		// EchoTime
+		// InversionTime
+
+		Uint32 tr_us=SGN_HeaderInstance_IMAGEHDR->RepetitionTimeUS;
+		if (tr_us) {
+			(*list)+=new DecimalStringAttribute(TagFromName(RepetitionTime),tr_us/1000.0);
+		}
+
+		Uint32 te_us=SGN_HeaderInstance_IMAGEHDR->EchoTimeUS;
+		if (te_us) {
+			(*list)+=new DecimalStringAttribute(TagFromName(EchoTime),te_us/1000.0);
+		}
+
+		Uint32 ti_us=SGN_HeaderInstance_IMAGEHDR->InversionTimeUS;
+		if (ti_us) {
+			(*list)+=new DecimalStringAttribute(TagFromName(InversionTime),ti_us/1000.0);
+		}
+		
+		double sctime_fd=SGN_HeaderInstance_IMAGEHDR->ScanTimeUS;
+		if (sctime_fd) {
+			(*list)+=new FloatDoubleAttribute(TagFromName(AcquisitionDuration),sctime_fd/1000000.0);
+		}
+		
+		// EchoTrainLength
+
+		unsigned etl=SGN_HeaderInstance_IMAGEHDR->EchoTrainLength;
+		unsigned numecho=SGN_HeaderInstance_IMAGEHDR->NumberOfEchoes;
+		unsigned useetl = etl ? etl : numecho;
+
+		if (useetl) {
+			(*list)+=new IntegerStringAttribute(TagFromName(EchoTrainLength),Uint32(useetl));
+		}
+	}
+
+	{
+		// ScanningSequence
+		// SequenceVariant
+		// ScanOptions
+
+		CodeStringAttribute *ScanningSequence =
+			new CodeStringAttribute(TagFromName(ScanningSequence));
+
+		CodeStringAttribute *SequenceVariant =
+			new CodeStringAttribute(TagFromName(SequenceVariant));
+
+		CodeStringAttribute *ScanOptions =
+			new CodeStringAttribute(TagFromName(ScanOptions));
+
+		switch (SGN_HeaderInstance_SERIESHDR->PulseSequence) {
+			case 0:			// MEMP
+					ScanningSequence->addValue("SE");
+					break;
+			case 1:			// IR
+					ScanningSequence->addValue("IR");
+					break;
+			case 2:			// PS ? Partial saturation
+						// -> not valid DICOM enum :(
+					ScanningSequence->addValue("PS");
+					break;
+			case 3:			// RM
+					ScanningSequence->addValue("RM");
+					break;
+			case 4:			// RMGE
+					ScanningSequence->addValue("RM");
+					break;
+			case 5:			// GRE
+					ScanningSequence->addValue("GR");
+					break;
+			case 6:			// VEMP
+					ScanningSequence->addValue("SE");
+					break;
+			case 7:			// MPGR
+					ScanningSequence->addValue("GR");
+					break;
+			case 8:			// MPGRV
+					ScanningSequence->addValue("GR");
+					break;
+			case 9:			// MPIRS
+					ScanningSequence->addValue("IR");
+					break;
+			case 10:		// MPIRI
+					ScanningSequence->addValue("IR");
+					break;
+			case 11:		// 3D/GRE
+					ScanningSequence->addValue("GR");
+					break;
+			case 12:		// CINE/GRE
+					ScanningSequence->addValue("GR");
+					break;
+			case 13:		// SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 14:		// SSFP
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("TRSS");
+					break;
+			case 15:		// CINE/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 16:		// 3D/SPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					break;
+			case 17:		// FSE
+					ScanningSequence->addValue("SE");
+					SequenceVariant->addValue("SK");
+					break;
+			case 18:		// FVE
+					ScanningSequence->addValue("SE");
+					SequenceVariant->addValue("SK");
+					break;
+			case 19:		// FSPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					SequenceVariant->addValue("SK");
+					break;
+			case 20:		// FGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 21:		// FMPSPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SP");
+					SequenceVariant->addValue("SK");
+					break;
+			case 22:		// FMPGR
+					ScanningSequence->addValue("GR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 23:		// FMPIR
+					ScanningSequence->addValue("IR");
+					SequenceVariant->addValue("SK");
+					break;
+			case 24:		// PROBE.S
+			case 25:		// PROBE.P
+					break;
+			default:	break;
+		}
+
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<0) {	// EG - ECG Gated
+			ScanOptions->addValue("CG");
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<1) {	// RESP - Resp Gated
+			ScanOptions->addValue("RG");
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<2) {	// RC - Resp Compensated
+			ScanOptions->addValue("PER");
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<3) {	// FC - Flow Compensated
+			ScanOptions->addValue("FC");
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<4) {	// CL
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<6) {	// PG - Periph Gated
+			ScanOptions->addValue("PPG");
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<7) {	// NP - No Phase Wrap
+			SequenceVariant->addValue("OSP");
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<8) {	// RF - ?
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<9) {	// RT - Rect FOV
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<10) {	// VB - Var Bandwidth
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<11) {	// ED - Ext Dynamic Rng
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<12) {	// PM - POMP
+		}
+		if (SGN_HeaderInstance_SERIESHDR->GatingType & 1<<15) {	// MP - Multiplanar
+		}
+
+		if ((SGN_HeaderInstance_SERIESHDR->GatingType & 1<<5)	// ST - Sat parameters
+		 || SGN_HeaderInstance_SERIESHDR->Sat					// any sat bits set
+		) {
+			ScanOptions->addValue("SP");		// spatial presaturation
+		}
+
+		switch (SGN_HeaderInstance_SERIESHDR->SuppTech) {
+			case 1:
+				ScanOptions->addValue("FS");	// fat saturation
+				break;
+			case 2:
+				ScanOptions->addValue("WS");	// water saturation
+				break;			// not DICOM def term
+			default:
+				break;
+		}
+
+		if (SGN_HeaderInstance_SERIESHDR->SCIC) {
+			ScanOptions->addValue("IIC");	// intensity correction
+		}					// not DICOM def term
+
+		if (SGN_HeaderInstance_IMAGEHDR->FracEcho & 1<<0) {
+			ScanOptions->addValue("PFF");	// partial fourier freq
+		}
+
+		if (SGN_HeaderInstance_SERIESHDR->GatingType2 & 1<<0	// Inversion Recovery:IR
+		 || SGN_HeaderInstance_SERIESHDR->GatingType2 & 1<<1) {	// Driven Equilibrium:DE
+			SequenceVariant->addValue("MP");	// mag prepared
+		}
+
+		if (!SequenceVariant->getVM())
+			SequenceVariant->addValue("NONE");
+
+		(*list)+=ScanningSequence;
+		(*list)+=SequenceVariant;
+		(*list)+=ScanOptions;
+	}
+
+	{
+		// MRAcquisitionType
+
+		const char *str;
+		switch(SGN_HeaderInstance_SERIESHDR->ImageMode) {
+			case 0:			// 2D single
+			case 1:			// 2D multiple
+				str="2D";
+				break;
+			case 2:			// 3D volume
+				str="3D";
+				break;
+			case 3:			// Cine:Cine
+			case 4:			// Spectroscopy:SPECT
+			default:
+				str="";
+				break;
+		}
+		(*list)+=new CodeStringAttribute(TagFromName(MRAcquisitionType),str);
+	}
+
+	{
+		// InPlanePhaseEncodingDirection
+
+		const char *str;
+
+		if (SGN_HeaderInstance_IMAGEHDR->PFSwapped)	// Swap Phase/Frequency:SPF
+			str="COL";
+		else
+			str="ROW";
+		(*list)+=new CodeStringAttribute(TagFromName(InPlanePhaseEncodingDirection),str);
+	}
+
+	{
+		// Acquisition Matrix
+
+		Uint16 freq_rows=0;
+		Uint16 freq_cols=0;
+		Uint16 phase_rows=0;
+		Uint16 phase_cols=0;
+
+		if (SGN_HeaderInstance_IMAGEHDR->PFSwapped) {
+			freq_rows=SGN_HeaderInstance_SERIESHDR->ScanMatrixX;
+			phase_cols=SGN_HeaderInstance_SERIESHDR->ScanMatrixY;
+		}
+		else {
+			freq_cols=SGN_HeaderInstance_SERIESHDR->ScanMatrixX;
+			phase_rows=SGN_HeaderInstance_SERIESHDR->ScanMatrixY;
+		}
+
+		if (freq_rows || freq_cols || phase_rows || phase_cols) {
+			Attribute *a=new UnsignedShortAttribute(TagFromName(AcquisitionMatrix));
+			Assert(a);
+			a->addValue(freq_rows);
+			a->addValue(freq_cols);
+			a->addValue(phase_rows);
+			a->addValue(phase_cols);
+			(*list)+=a;
+		}
+	}
+
+	{
+		// Number Of Phase Encoding Steps
+
+		(*list)+=new IntegerStringAttribute(TagFromName(NumberOfPhaseEncodingSteps),(Uint32)SGN_HeaderInstance_SERIESHDR->ScanMatrixY);
+	}
+
+	{
+		// AngioFlag
+
+		bool angio = SGN_HeaderInstance_SERIESHDR->VasMode != 0;	// 0=none,1=TOF,2=PC
+
+		bool collapsed = SGN_HeaderInstance_IMAGEHDR->VascCollapse;
+
+		if (angio) {
+			const char *str;
+			if (!collapsed)
+				str="Y";
+			else
+				str="N";
+			(*list)+=new CodeStringAttribute(TagFromName(AngioFlag),str);
+		}
+		// else leave it out
+	}
+
+	if (SGN_HeaderInstance_IMAGEHDR->VariableBandwidth != 0) {
+		// PixelBandwidth
+
+		(*list)+=new DecimalStringAttribute(TagFromName(PixelBandwidth),(Float32)SGN_HeaderInstance_IMAGEHDR->VariableBandwidth*2*1000);
+	}
+	
+}
+
diff --git a/libsrc/src/dconvert/signa/sgnmpln.cc b/libsrc/src/dconvert/signa/sgnmpln.cc
new file mode 100644
index 0000000..5701817
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnmpln.cc
@@ -0,0 +1,118 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sgnmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sgndc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+SGN_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlaneHeadFeet headfeet;
+
+	switch (SGN_HeaderInstance_SERIESHDR->PatientPosition) {
+		case 0:
+				hfff="HF";
+				headfeet=HeadFirst;
+				break;
+		case 1:
+				hfff="FF";
+				headfeet=FeetFirst;
+				break;
+		default:	hfff="UNKNOWN";		// :(
+				headfeet=HeadFirst;
+				break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (SGN_HeaderInstance_SERIESHDR->PatientOrientation) {
+		case 0:
+				ap="S";
+				position=Supine;
+				break;
+		case 1:
+				ap="P";
+				position=Prone;
+				break;
+		case 2:
+				ap="DL";
+				position=LeftLateralDecubitus;
+				break;
+		case 3:
+				ap="DR";
+				position=RightLateralDecubitus;
+				break;
+		default:	ap="UNKNOWN";		// :(
+				position=Supine;
+				break;
+	}
+
+	ImagePlane imageplane(headfeet,position);
+
+	// get common definitions for CT or MR
+
+	double tlhc_R;
+	double tlhc_A;
+	double tlhc_S;
+	double trhc_R;
+	double trhc_A;
+	double trhc_S;
+	double blhc_R;
+	double blhc_A;
+	double blhc_S;
+	{
+		tlhc_R=SGN_HeaderInstance_IMAGEHDR->TLHC_R;
+		tlhc_A=SGN_HeaderInstance_IMAGEHDR->TLHC_A;
+		tlhc_S=SGN_HeaderInstance_IMAGEHDR->TLHC_S;
+		trhc_R=SGN_HeaderInstance_IMAGEHDR->TRHC_R;
+		trhc_A=SGN_HeaderInstance_IMAGEHDR->TRHC_A;
+		trhc_S=SGN_HeaderInstance_IMAGEHDR->TRHC_S;
+		blhc_R=SGN_HeaderInstance_IMAGEHDR->BLHC_R;
+		blhc_A=SGN_HeaderInstance_IMAGEHDR->BLHC_A;
+		blhc_S=SGN_HeaderInstance_IMAGEHDR->BLHC_S;
+	}
+
+	// DICOM plane definitions are:
+	// - Left Pos Superior +ve
+
+	// The Genesis co-ordinates are:
+	// - Right Ant Superior +ve
+	// - Corners offset by center co-ordinates
+	// - already account for offset from isocenter/reference
+
+	// (NB. no effort is made to fix the sign of SliceLocation)
+
+	// Change sign of AP and LR from Signa to DICOM...
+
+	Point3D TLHC(-tlhc_R,-tlhc_A, tlhc_S);
+	Point3D TRHC(-trhc_R,-trhc_A, trhc_S);
+	Point3D BLHC(-blhc_R,-blhc_A, blhc_S);
+
+	imageplane.PatientPlane::setCorners(TLHC,
+					    TRHC-TLHC,	// Row Vector
+					    BLHC-TLHC);	// Col Vector
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+
+
+	// PixelSpacing
+
+	double 	pixsize_X  = SGN_HeaderInstance_IMAGEHDR->PixelSize;
+	double 	pixsize_Y  = SGN_HeaderInstance_IMAGEHDR->PixelSize;
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+					pixsize_X,pixsize_Y);
+
+}
+
diff --git a/libsrc/src/dconvert/signa/sgnptrs.h b/libsrc/src/dconvert/signa/sgnptrs.h
new file mode 100644
index 0000000..4cb95dc
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnptrs.h
@@ -0,0 +1,13 @@
+/* sgnptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+// offsets are in bytes
+
+#define SGN_Offset_STUDYHDR_ptr		(6 * 512)
+#define SGN_Offset_SERIESHDR_ptr	(8 * 512)
+#define SGN_Offset_IMAGEHDR_ptr		(10 * 512)
+#define SGN_Offset_IMAGEDATA_ptr	(28 * 512)
+
+// lengths are in bytes
+
+#define SGN_Offset_STUDYHDR_lng		1024
+#define SGN_Offset_SERIESHDR_lng	1024
+#define SGN_Offset_IMAGEHDR_lng		1024
diff --git a/libsrc/src/dconvert/signa/sgnsrc.h b/libsrc/src/dconvert/signa/sgnsrc.h
new file mode 100644
index 0000000..354177a
--- /dev/null
+++ b/libsrc/src/dconvert/signa/sgnsrc.h
@@ -0,0 +1,61 @@
+/* sgnsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_sgnsrc__
+#define __Header_sgnsrc__
+
+class SGN_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	SGN_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~SGN_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Big endian ...
+				Uint16 pixel;
+				pixel=(bytes[0]<<8)|bytes[1];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_sgnsrc__
diff --git a/libsrc/src/dconvert/signa/signa.h b/libsrc/src/dconvert/signa/signa.h
new file mode 100644
index 0000000..58a33e4
--- /dev/null
+++ b/libsrc/src/dconvert/signa/signa.h
@@ -0,0 +1,48 @@
+/* signa.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_sgn__
+#define __Header_sgn__
+
+// NB. a SGN_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~SGN_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class SGN_Header_BothClass;
+class SGN_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class SGN_Conversion {
+	SGN_Header_BothClass *sgnhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	SGN_PixelDataSource *pixeldatasrc;
+
+	void init(istream &i,ostream &e);
+public:
+	SGN_Conversion(istream &i,ostream &e);
+
+	virtual ~SGN_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0)
+		{
+			(void)out; (void)imagenumber;
+			return true;
+		}
+
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_sgn__ */
+
diff --git a/libsrc/src/dconvert/signa/signa.tpl b/libsrc/src/dconvert/signa/signa.tpl
new file mode 100644
index 0000000..2fc378f
--- /dev/null
+++ b/libsrc/src/dconvert/signa/signa.tpl
@@ -0,0 +1,272 @@
+# Offsets are in 8 bit bytes from 0
+# Lengths are in intype words
+
+block="STUDYHDR"	offset="0"		intype="String"		inlength="14"	name="?"	dicomtype="?"	dicomtag="?"				# Study Header Identifier
+block="STUDYHDR"	offset="14"		intype="String"		inlength="8"	name="?"	dicomtype="?"	dicomtag="?"				# Study Header Revision Number xx.xx.xx
+block="STUDYHDR"	offset="22"		intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of Study Header Blocks
+block="STUDYHDR"	offset="24"		intype="String"		inlength="32"	name="?"	dicomtype="?"	dicomtag="?"				# Study Header Creator (Process Name:PID)
+block="STUDYHDR"	offset="56"		intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Study Header Creator (Task ID)
+block="STUDYHDR"	offset="58"		intype="String"		inlength="5"	name="?"	dicomtype="?"	dicomtag="?"				# Original Raw Data Study Number (null unless different from study number)
+block="STUDYHDR"	offset="64"		intype="String"		inlength="5"	keyword="StudyNumber"	dicomtype="SH"	dicomtag="StudyID"		# Study Number
+block="STUDYHDR"	offset="70"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Raw Data System ID
+block="STUDYHDR"	offset="74"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# System Generation ID
+block="STUDYHDR"	offset="78"		intype="String"		inlength="9"	name="?"	dicomtype="?"	dicomtag="?"				# Date of Study (ascii dd-mmm-yy)
+block="STUDYHDR"	offset="88"		intype="Int16_B"	inlength="1"	keyword="StudyDateDay"	dicomtype="?"	dicomtag="?"			# Date of Study (integer day)
+block="STUDYHDR"	offset="90"		intype="Int16_B"	inlength="1"	keyword="StudyDateMonth"	dicomtype="?"	dicomtag="?"		# Date of Study (integer month)
+block="STUDYHDR"	offset="92"		intype="Int16_B"	inlength="1"	keyword="StudyDateYear"	dicomtype="?"	dicomtag="?"			# Date of Study (integer year-1900)
+block="STUDYHDR"	offset="94"		intype="String"		inlength="8"	name="?"	dicomtype="?"	dicomtag="?"				# Time of Study (ascii hh:mm:ss)
+block="STUDYHDR"	offset="102"	intype="Int16_B"	inlength="1"	keyword="StudyTimeHour"	dicomtype="?"	dicomtag="?"			# Time of Study (integer hr)
+block="STUDYHDR"	offset="104"	intype="Int16_B"	inlength="1"	keyword="StudyTimeMin"	dicomtype="?"	dicomtag="?"			# Time of Study (integer min)
+block="STUDYHDR"	offset="106"	intype="Int16_B"	inlength="1"	keyword="StudyTimeSec"	dicomtype="?"	dicomtag="?"			# Time of Study (integer sec)
+block="STUDYHDR"	offset="108"	intype="String"		inlength="32"	name="?"	dicomtype="PN"	dicomtag="PatientName"			# Patient Name
+block="STUDYHDR"	offset="140"	intype="String"		inlength="12"	name="?"	dicomtype="LO"	dicomtag="PatientID"			# Patient ID
+block="STUDYHDR"	offset="152"	intype="String"		inlength="4"	name="?"	dicomtype="?"	dicomtag="?"				# Patient ID padding for future exp.
+block="STUDYHDR"	offset="156"	intype="String"		inlength="4"	keyword="PatientAge"	dicomtype="?"	dicomtag="?"			# Age of patient - xxx years or xxx[dDwWmMyY]
+block="STUDYHDR"	offset="160"	intype="String"		inlength="1"	name="?"	dicomtype="CS"	dicomtag="PatientSex"			# Sex of patient - M or F
+block="STUDYHDR"	offset="162"	intype="Int32_B"	inlength="1"	keyword="PatientWeightGrams"	dicomtype="?"	dicomtag="?"		# Weight of the patient in grams
+block="STUDYHDR"	offset="166"	intype="String"		inlength="32"	name="?"	dicomtype="PN"	dicomtag="ReferringPhysicianName"	# Referred by
+block="STUDYHDR"	offset="198"	intype="String"		inlength="32"	name="?"	dicomtype="PN"	dicomtag="PerformingPhysicianName"	# Diagnostician
+block="STUDYHDR"	offset="230"	intype="String"		inlength="32"	name="?"	dicomtype="PN"	dicomtag="OperatorsName"			# Operator
+block="STUDYHDR"	offset="262"	intype="String"		inlength="60"	name="?"	dicomtype="LO"	dicomtag="StudyDescription"		# Description
+block="STUDYHDR"	offset="322"	intype="String"		inlength="120"	name="?"	dicomtype="LT"	dicomtag="AdditionalPatientHistory"	# History
+block="STUDYHDR"	offset="442"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation time in seconds.
+block="STUDYHDR"	offset="446"	intype="String"		inlength="32"	name="?"	dicomtype="LO"	dicomtag="InstitutionName"		# Hospital name
+block="STUDYHDR"	offset="478"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=inpatient,1=outpatient,2=emergency,3=referral,4=blank"	# Patient status
+block="STUDYHDR"	offset="480"	intype="String"		inlength="12"	name="?"	dicomtype="?"	dicomtag="?"				# Req. Number from Scan Rx first page
+block="STUDYHDR"	offset="1022"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# checksum
+
+
+block="SERIESHDR"	offset="0"		intype="String"		inlength="14"	name="?"	dicomtype="?"	dicomtag="?"				# Series Header Identifier
+block="SERIESHDR"	offset="14"		intype="String"		inlength="8"	name="?"	dicomtype="?"	dicomtag="?"				# Series Header Revision Number xx.xx.xx
+block="SERIESHDR"	offset="22"		intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of Series Header Blocks
+block="SERIESHDR"	offset="24"		intype="String"		inlength="32"	name="?"	dicomtype="?"	dicomtag="?"				# Series Header Creator (Process Name:PID)
+block="SERIESHDR"	offset="56"		intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Series Header Creator (Task ID)
+block="SERIESHDR"	offset="58"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Original Series Number
+block="SERIESHDR"	offset="62"		intype="String"		inlength="3"	keyword="SeriesNumber"	dicomtype="IS"	dicomtag="SeriesNumber"		# Series Number
+block="SERIESHDR"	offset="66"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Raw Data System ID
+block="SERIESHDR"	offset="70"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# System Generation ID
+block="SERIESHDR"	offset="74"		intype="String"		inlength="9"	name="?"	dicomtype="?"	dicomtag="?"				# Date of Series (ascii dd-mmm-yy)
+block="SERIESHDR"	offset="84"		intype="Int16_B"	inlength="1"	keyword="SeriesDateDay"	dicomtype="?"	dicomtag="?"			# Date of Series (integer day)
+block="SERIESHDR"	offset="86"		intype="Int16_B"	inlength="1"	keyword="SeriesDateMonth"	dicomtype="?"	dicomtag="?"		# Date of Series (integer month)
+block="SERIESHDR"	offset="88"		intype="Int16_B"	inlength="1"	keyword="SeriesDateYear"	dicomtype="?"	dicomtag="?"		# Date of Series (integer year-1900)
+block="SERIESHDR"	offset="90"		intype="String"		inlength="8"	name="?"	dicomtype="?"	dicomtag="?"				# Time of Series (ascii hh:mm:ss)
+block="SERIESHDR"	offset="98"		intype="Int16_B"	inlength="1"	keyword="SeriesTimeHour"	dicomtype="?"	dicomtag="?"		# Time of Series (integer hr)
+block="SERIESHDR"	offset="100"	intype="Int16_B"	inlength="1"	keyword="SeriesTimeMin"	dicomtype="?"	dicomtag="?"			# Time of Series (integer min)
+block="SERIESHDR"	offset="102"	intype="Int16_B"	inlength="1"	keyword="SeriesTimeSec"	dicomtype="?"	dicomtag="?"			# Time of Series (integer sec)
+block="SERIESHDR"	offset="104"	intype="String"		inlength="120"	name="?"	dicomtype="LO"	dicomtag="SeriesDescription"		# Series Description
+block="SERIESHDR"	offset="224"	intype="Int16_B"	inlength="1"	keyword="SeriesType"	dicomtype="?"	dicomtag="?"	enum="0=normal,1=screensave,2=composite"	# Series Type
+block="SERIESHDR"	offset="226"	intype="Int16_B"	inlength="1"	name="CoilType"	dicomtype="?"	dicomtag="?"	enum="0=head,1=body,2=surface"			# Coil Type
+block="SERIESHDR"	offset="228"	intype="String"		inlength="16"	name="CoilName"	dicomtype="?"	dicomtag="?"			# Coil Name (HEAD,BODY,coil name) (Not always present)
+block="SERIESHDR"	offset="244"	intype="String"		inlength="32"	name="?"	dicomtype="LO"	dicomtag="ContrastBolusAgent"		# Contrast Description
+block="SERIESHDR"	offset="276"	intype="Int16_B"	inlength="1"	name="PlaneType"	dicomtype="?"	dicomtag="?"	enum="0=axial,1=sagittal,2=coronal,3=oblique,4=screensave"	# Plane Type
+block="SERIESHDR"	offset="278"	intype="String"		inlength="16"	name="PlaneName"	dicomtype="?"	dicomtag="?"			# Plane Name (AXIAL,SAGITTAL,CORONAL,OBLIQUE,SCREEN SAVE)
+block="SERIESHDR"	offset="294"	intype="Int16_B"	inlength="1"	keyword="ImageMode"	dicomtype="?"	dicomtag="?"	enum="0=2D Single,1=2D Multiple,2=3D Volume,3=Cine,4=Spectro"	# Image Mode
+block="SERIESHDR"	offset="296"	intype="Int16_B"	inlength="1"	keyword="MagneticFieldStrengthGauss"	dicomtype="?"	dicomtag="?"	# Magnetic Field Strength (Gauss)
+block="SERIESHDR"	offset="298"	intype="Int16_B"	inlength="1"	keyword="PulseSequence"	dicomtype="?"	dicomtag="?"	enum="0=MEMP,1=IR,2=PS,3=RM,4=RMGE,5=GRE,6=VEMP,7=MPGR,8=MPGRV,9=MPIRS,10=MPIRI,11=3D/GRE,12=CINE/GRE,13=SPGR,14=SSFP,15=CINE/SPGR,16=3D/SPGR,17=FSE,18=FVE,19=FSPGR,20=FGR,21=FMPSPGR,22=FMPGR,23=FMPIR,24=PROBE.S,25=PROBE.P"	# Pulse Sequence
+block="SERIESHDR"	offset="300"	intype="Int16_B"	inlength="1"	name="?"		dicomtype="?"	dicomtag="?"	enum="0=chopper"	# Pulse sequence subtype
+block="SERIESHDR"	offset="302"	intype="DG_Float_F"	inlength="1"	name="FieldOfView"	dicomtype="DS"	dicomtag="ReconstructionDiameter"	# Field of view mm
+block="SERIESHDR"	offset="306"	intype="DG_Float_F"	inlength="1"	name="CenterRL"	dicomtype="?"	dicomtag="?"			# Center RL R+ (relative to landmark)
+block="SERIESHDR"	offset="310"	intype="DG_Float_F"	inlength="1"	name="CenterAP"	dicomtype="?"	dicomtag="?"			# Center AP A+ (relative to landmark)
+block="SERIESHDR"	offset="314"	intype="DG_Float_F"	inlength="1"	name="CenterSI"	dicomtype="?"	dicomtag="?"			# Center SI S+ (relative to landmark)
+block="SERIESHDR"	offset="318"	intype="Int16_B"	inlength="1"	keyword="PatientOrientation"	dicomtype="?"	dicomtag="?"		# Orientation (0=supine,1=prone,2=lt decubitus,3=rt decubitus)
+block="SERIESHDR"	offset="320"	intype="Int16_B"	inlength="1"	keyword="PatientPosition"	dicomtype="?"	dicomtag="?"	enum="0=Head First,1=Feet First"	# Position
+block="SERIESHDR"	offset="322"	intype="String"		inlength="32"	name="LongitudinalReference"	dicomtype="LO"	dicomtag="PositionReferenceIndicator"	# Longitudinal Anatomical Reference
+block="SERIESHDR"	offset="354"	intype="String"		inlength="32"	name="VerticalReference"	dicomtype="?"	dicomtag="?"		# Vertical Anatomical Reference
+block="SERIESHDR"	offset="386"	intype="DG_Float_F"	inlength="1"	name="VerticalLandmark"	dicomtype="?"	dicomtag="?"		# Vertical Landmark (relative to tabletop) mm
+block="SERIESHDR"	offset="390"	intype="DG_Float_F"	inlength="1"	name="HorizontalLandmark"	dicomtype="?"	dicomtag="?"		# Horizontal Landmark (relative to table center) mm
+block="SERIESHDR"	offset="394"	intype="DG_Float_F"	inlength="1"	name="PhysicalTableLocation"	dicomtype="?"	dicomtag="?"		# Physical Table Location relative to home
+block="SERIESHDR"	offset="398"	intype="Int16_B"	inlength="1"	name="ScanMatrixX"	dicomtype="?"	dicomtag="?"			# Scan Matrix - X
+block="SERIESHDR"	offset="400"	intype="Int16_B"	inlength="1"	name="ScanMatrixY"	dicomtype="?"	dicomtag="?"			# Scan Matrix - Y
+block="SERIESHDR"	offset="402"	intype="Int16_B"	inlength="1"	keyword="ImageMatrix"	dicomtype="?"	dicomtag="?"			# Image Matrix
+block="SERIESHDR"	offset="404"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# No. of Images Allocated
+block="SERIESHDR"	offset="406"	intype="Int16_B"	inlength="1"	keyword="GatingType"	dicomtype="?"	dicomtag="?"	bitmap="0:none,EG;1:none,RESP;2:none,RC;3:none,FC;4:none,CL;5:none,ST;6:none,PG;7:none,NP;8:none,RF;9:none,RT;10:none,VB;11:none,ED;12:none,PM;15:none,MP"	# Gating Type
+block="SERIESHDR"	offset="408"	intype="Int16_B"	inlength="1"	name="PSMode"	dicomtype="?"	dicomtag="?"	enum="0=Product,1=Research,2=Research GE"	# Pulse sequence mode
+block="SERIESHDR"	offset="410"	intype="String"		inlength="12"	name="?"	dicomtype="?"	dicomtag="?"				# PSD name from NAME = aPPL psd name
+block="SERIESHDR"	offset="422"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Landmark counter
+block="SERIESHDR"	offset="426"	intype="String"		inlength="20"	name="?"	dicomtype="LO"	dicomtag="ProtocolName"			# Protocol name for Scan
+block="SERIESHDR"	offset="446"	intype="Int16_B"	inlength="1"	name="SCoilType"	dicomtype="?"	dicomtag="?"	enum="0=receive,1=transmit/receive"	# Surface coil type
+block="SERIESHDR"	offset="448"	intype="Int16_B"	inlength="1"	keyword="SuppTech"		dicomtype="?"	dicomtag="?"	enum="0=none,1=fat:F,2=water:W"	# Suppression technique
+block="SERIESHDR"	offset="450"	intype="Int16_B"	inlength="1"	name="Sat"		dicomtype="?"	dicomtag="?"	bitmap="0:none,superior(S);1:none,inferior(I);2:none,right(R);3:none,left(R);4:none,anterior(A);5:none,posterior(P);6:none,superior(s);7:none,inferior(i);8:none,right(r);9:none,left(l);10:none,anterior(a);11:none,posterior(p)"	#  Bitmap of SAT selections
+block="SERIESHDR"	offset="452"	intype="Int16_B"	inlength="1"	keyword="SCIC"	dicomtype="?"	dicomtag="?"	enum="0=off,1=on"	# Surface Coil Intensity Correction Flag
+block="SERIESHDR"	offset="454"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R saturation pulse location  - mm from landmark
+block="SERIESHDR"	offset="456"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# L saturation pulse location  - mm from landmark
+block="SERIESHDR"	offset="458"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# A saturation pulse location  - mm from landmark
+block="SERIESHDR"	offset="460"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# P saturation pulse location  - mm from landmark
+block="SERIESHDR"	offset="462"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# S saturation pulse location  - mm from landmark
+block="SERIESHDR"	offset="464"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# I saturation pulse location  - mm from landmark
+block="SERIESHDR"	offset="466"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# X saturation pulse thickness - mm
+block="SERIESHDR"	offset="468"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Y saturation pulse thickness - mm
+block="SERIESHDR"	offset="470"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Z saturation pulse thickness - mm
+block="SERIESHDR"	offset="472"	intype="Int16_B"	inlength="1"	keyword="VasMode"	dicomtype="?"	dicomtag="?"	enum="0=none,1=TOF,2=PC"	# Vascular mode
+block="SERIESHDR"	offset="474"	intype="Int16_B"	inlength="1"	name="FlowAxis"	dicomtype="?"	dicomtag="?"	bitmap="0:none,S/I;1:none,R/L;2:none,A/P;3:none,SLICE"	# Phase contrast flow axis
+block="SERIESHDR"	offset="476"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# unused venc ... see image header
+block="SERIESHDR"	offset="478"	intype="Int16_B"	inlength="1"	keyword="GatingType2"	dicomtype="?"	dicomtag="?"	bitmap="0:none,IR Prep;1:none,DE Prep"	# more pulse sequence types
+block="SERIESHDR"	offset="1022"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# checksum
+
+
+block="IMAGEHDR"	offset="0"		intype="String"		inlength="14"	name="?"	dicomtype="?"	dicomtag="?"				# Image Header Identifier
+block="IMAGEHDR"	offset="14"		intype="String"		inlength="8"	name="?"	dicomtype="LO"	dicomtag="SoftwareVersions"		# Image Header Revision Number xx.xx.xx
+block="IMAGEHDR"	offset="22"		intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of Image Header Blocks
+block="IMAGEHDR"	offset="24"		intype="String"		inlength="32"	name="?"	dicomtype="?"	dicomtag="?"				# Image Header Creator (Process Name:PID)
+block="IMAGEHDR"	offset="56"		intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Image Header Creator (Task ID)
+block="IMAGEHDR"	offset="58"		intype="String"		inlength="9"	name="?"	dicomtype="?"	dicomtag="?"				# Date of Image (ascii dd-mmm-yy)
+block="IMAGEHDR"	offset="68"		intype="Int16_B"	inlength="1"	keyword="ImageDateDay"	dicomtype="?"	dicomtag="?"			# Date of Image (integer day)
+block="IMAGEHDR"	offset="70"		intype="Int16_B"	inlength="1"	keyword="ImageDateMonth"	dicomtype="?"	dicomtag="?"		# Date of Image (integer month)
+block="IMAGEHDR"	offset="72"		intype="Int16_B"	inlength="1"	keyword="ImageDateYear"	dicomtype="?"	dicomtag="?"			# Date of Image (integer year-1900)
+block="IMAGEHDR"	offset="74"		intype="String"		inlength="8"	name="?"	dicomtype="?"	dicomtag="?"				# Time of Image (ascii hh:mm:ss)
+block="IMAGEHDR"	offset="82"		intype="Int16_B"	inlength="1"	keyword="ImageTimeHour"	dicomtype="?"	dicomtag="?"			# Time of Image (integer hr)
+block="IMAGEHDR"	offset="84"		intype="Int16_B"	inlength="1"	keyword="ImageTimeMin"	dicomtype="?"	dicomtag="?"			# Time of Image (integer min)
+block="IMAGEHDR"	offset="86"		intype="Int16_B"	inlength="1"	keyword="ImageTimeSec"	dicomtype="?"	dicomtag="?"			# Time of Image (integer sec)
+block="IMAGEHDR"	offset="88"		intype="String"		inlength="3"	keyword="ImageNumber"	dicomtype="IS"	dicomtag="InstanceNumber"		# Image Number
+block="IMAGEHDR"	offset="92"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Series Number of Image
+block="IMAGEHDR"	offset="96"		intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Raw Data System ID
+block="IMAGEHDR"	offset="100"	intype="String"		inlength="3"	name="?"	dicomtype="SH"	dicomtag="StationName"			# System Generation ID
+block="IMAGEHDR"	offset="104"	intype="DG_Float_F"	inlength="1"	name="LocationRMin"	dicomtype="?"	dicomtag="?"			# Start Location X, Right min
+block="IMAGEHDR"	offset="108"	intype="DG_Float_F"	inlength="1"	name="LocationRMax"	dicomtype="?"	dicomtag="?"			# End Location X, Right max
+block="IMAGEHDR"	offset="112"	intype="DG_Float_F"	inlength="1"	name="LocationAMin"	dicomtype="?"	dicomtag="?"			# Start Location Y, Anterior min
+block="IMAGEHDR"	offset="116"	intype="DG_Float_F"	inlength="1"	name="LocationAMax"	dicomtype="?"	dicomtag="?"			# End Location Y, Anterior max
+block="IMAGEHDR"	offset="120"	intype="DG_Float_F"	inlength="1"	name="LocationSMin"	dicomtype="?"	dicomtag="?"			# Start Location Z, Superior min
+block="IMAGEHDR"	offset="124"	intype="DG_Float_F"	inlength="1"	name="LocationSMax"	dicomtype="?"	dicomtag="?"			# End Location Z, Superior max
+block="IMAGEHDR"	offset="146"	intype="DG_Float_F"	inlength="1"	name="SliceLocation"	dicomtype="DS"	dicomtag="SliceLocation"	# Image Location relative to landmark
+block="IMAGEHDR"	offset="150"	intype="DG_Float_F"	inlength="1"	name="TablePosition"	dicomtype="?"	dicomtag="?"			# Table Position
+block="IMAGEHDR"	offset="154"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="SliceThickness"		# Thickness in mm
+block="IMAGEHDR"	offset="158"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="SpacingBetweenSlices"		# Spacing in mm
+block="IMAGEHDR"	offset="162"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="-1=round to nearest slice"	# Round
+block="IMAGEHDR"	offset="164"	intype="DG_Float_F"	inlength="1"	keyword="RepetitionTimeUS"	dicomtype="?"	dicomtag="?"		# Repetition/Recovery Time uS
+block="IMAGEHDR"	offset="168"	intype="DG_Float_F"	inlength="1"	name="ScanTimeUS"	dicomtype="?"	dicomtag="?"			# Scan Time uS
+block="IMAGEHDR"	offset="172"	intype="DG_Float_F"	inlength="1"	keyword="EchoTimeUS"	dicomtype="?"	dicomtag="?"			# Echo Delay uS
+block="IMAGEHDR"	offset="176"	intype="DG_Float_F"	inlength="1"	keyword="InversionTimeUS"	dicomtype="?"	dicomtag="?"		# Inversion Time uS
+block="IMAGEHDR"	offset="180"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Other time 0 - Reserved for future use.
+block="IMAGEHDR"	offset="184"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Other time 1 - Reserved for future use.
+block="IMAGEHDR"	offset="188"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Other time 2 - Reserved for future use.
+block="IMAGEHDR"	offset="192"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Other time 3 - Reserved for future use.
+block="IMAGEHDR"	offset="196"	intype="Int16_B"	inlength="1"	keyword="NumberOfEchoes"	dicomtype="?"	dicomtag="?"		# Number of echos.
+block="IMAGEHDR"	offset="198"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="EchoNumbers"			# Echo number.
+block="IMAGEHDR"	offset="200"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="ImagesInAcquisition"		# Number of slices in scan group.
+block="IMAGEHDR"	offset="202"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of averages (before fractional nex)
+block="IMAGEHDR"	offset="204"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,-1=yes"	# Research mode used
+block="IMAGEHDR"	offset="206"	intype="String"		inlength="32"	name="?"	dicomtype="?"	dicomtag="?"				# Name of PSD file.
+block="IMAGEHDR"	offset="238"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation Date of PSD file dd
+block="IMAGEHDR"	offset="240"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation Date of PSD file mm
+block="IMAGEHDR"	offset="242"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation Date of PSD file yy-1900
+block="IMAGEHDR"	offset="244"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation Date of PSD file hh
+block="IMAGEHDR"	offset="246"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation Date of PSD file mm
+block="IMAGEHDR"	offset="248"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Creation Date of PSD file ss
+block="IMAGEHDR"	offset="250"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,-1=yes"	# Graphically Prescribed (? any non-zero is yes)
+block="IMAGEHDR"	offset="252"	intype="String"		inlength="9"	name="?"	dicomtype="?"	dicomtag="?"				# Series Numbers [3*3] from which prescribed
+block="IMAGEHDR"	offset="262"	intype="String"		inlength="9"	name="?"	dicomtype="?"	dicomtag="?"				# Image Numbers [3*3] from which prescribed
+block="IMAGEHDR"	offset="272"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=box,1=ellipse"	# Image Shape
+block="IMAGEHDR"	offset="274"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="US"	dicomtag="Rows"				# X pixel dimension
+block="IMAGEHDR"	offset="276"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="US"	dicomtag="Columns"			# Y pixel dimension
+block="IMAGEHDR"	offset="278"	intype="DG_Float_F"	inlength="1"	keyword="PixelSize"	dicomtype="?"	dicomtag="?"			# Pixel Size - mm
+block="IMAGEHDR"	offset="282"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no"		# Image Compressed (non-zero=technique)
+block="IMAGEHDR"	offset="284"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Bits per Pixel - not always filled in
+block="IMAGEHDR"	offset="286"	intype="Int16_B"	inlength="1"	keyword="DefaultWindow"	dicomtype="?"	dicomtag="?"	# Default Window
+block="IMAGEHDR"	offset="288"	intype="Int16_B"	inlength="1"	keyword="DefaultLevel"	dicomtype="?"	dicomtag="?"	# Default Level
+block="IMAGEHDR"	offset="290"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of Blocks in File
+block="IMAGEHDR"	offset="292"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="NumberOfAverages"		# Number of excitations (presumably post-fractional NEX)
+block="IMAGEHDR"	offset="296"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Value of peak SAR watts/kg
+block="IMAGEHDR"	offset="300"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="SAR"				# Value of average SAR watts/kg
+block="IMAGEHDR"	offset="304"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# SAR monitored
+block="IMAGEHDR"	offset="306"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# Contiguous slices (? any non-zero is yes)
+block="IMAGEHDR"	offset="308"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="HeartRate"			# Cardiac Heart Rate
+block="IMAGEHDR"	offset="310"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Total Delay Time After Trigger - ms between QRS peak and 1st excitation pulse
+block="IMAGEHDR"	offset="314"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="TriggerWindow"		# Arrhythmia Rejection Ratio - % of avg RR during which trigger is recognized
+block="IMAGEHDR"	offset="316"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Cardiac Rep Time - 1 pulse every beat, 2 pulse very 2nd beat, etc
+block="IMAGEHDR"	offset="318"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="CardiacNumberOfImages"	# Images per Cardiac Cycle (single scan only)
+block="IMAGEHDR"	offset="320"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="IS"	dicomtag="IntervalsAcquired"		# Number of RR's during the Scan
+block="IMAGEHDR"	offset="324"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Transmit attenuator setting .1 dB
+block="IMAGEHDR"	offset="326"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recieve attenuator setting .1dB
+block="IMAGEHDR"	offset="328"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Magnetic Field Strength 10 microgauss
+block="IMAGEHDR"	offset="332"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Image offset - frequency/phase offset [-256...256]
+block="IMAGEHDR"	offset="334"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Inter image/inter location delay - ms between excitation pulses within RR interval
+block="IMAGEHDR"	offset="338"	intype="String"		inlength="12"	name="?"	dicomtype="?"	dicomtag="?"				# PSD name from NAME = aPPL psd name
+block="IMAGEHDR"	offset="350"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="DS"	dicomtag="FlipAngle"			# Flip angle for GRASS
+block="IMAGEHDR"	offset="352"	intype="String"		inlength="4"	name="?"	dicomtype="?"	dicomtag="?"				# Type of correction for surface coils ?????
+block="IMAGEHDR"	offset="356"	intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Series no. of corrected/uncor images ?????
+block="IMAGEHDR"	offset="360"	intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Image no. of corrected/uncor images ?????
+block="IMAGEHDR"	offset="364"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=false,1=true"	# Extremity coil
+block="IMAGEHDR"	offset="386"	intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Series no. of second localizer
+block="IMAGEHDR"	offset="390"	intype="String"		inlength="3"	name="?"	dicomtype="?"	dicomtag="?"				# Image no. of second localizer
+block="IMAGEHDR"	offset="394"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R center coordinate on plane image mm
+block="IMAGEHDR"	offset="398"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# A center coordinate on plane image mm
+block="IMAGEHDR"	offset="402"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# S center coordinate on plane image mm
+block="IMAGEHDR"	offset="406"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R normal coordinate mm
+block="IMAGEHDR"	offset="410"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# A normal coordinate mm
+block="IMAGEHDR"	offset="414"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# S normal coordinate mm
+block="IMAGEHDR"	offset="418"	intype="DG_Float_F"	inlength="1"	keyword="TLHC_R"	dicomtype="?"	dicomtag="?"			# TLHC R coordinate mm
+block="IMAGEHDR"	offset="422"	intype="DG_Float_F"	inlength="1"	keyword="TLHC_A"	dicomtype="?"	dicomtag="?"			# TLHC A coordinate mm
+block="IMAGEHDR"	offset="426"	intype="DG_Float_F"	inlength="1"	keyword="TLHC_S"	dicomtype="?"	dicomtag="?"			# TLHC S coordinate mm
+block="IMAGEHDR"	offset="430"	intype="DG_Float_F"	inlength="1"	keyword="TRHC_R"	dicomtype="?"	dicomtag="?"			# TRHC R coordinate mm
+block="IMAGEHDR"	offset="434"	intype="DG_Float_F"	inlength="1"	keyword="TRHC_A"	dicomtype="?"	dicomtag="?"			# TRHC A coordinate mm
+block="IMAGEHDR"	offset="438"	intype="DG_Float_F"	inlength="1"	keyword="TRHC_S"	dicomtype="?"	dicomtag="?"			# TRHC S coordinate mm
+block="IMAGEHDR"	offset="442"	intype="DG_Float_F"	inlength="1"	keyword="BLHC_R"	dicomtype="?"	dicomtag="?"			# BLHC R coordinate mm
+block="IMAGEHDR"	offset="446"	intype="DG_Float_F"	inlength="1"	keyword="BLHC_A"	dicomtype="?"	dicomtag="?"			# BLHC A coordinate mm
+block="IMAGEHDR"	offset="450"	intype="DG_Float_F"	inlength="1"	keyword="BLHC_S"	dicomtype="?"	dicomtag="?"			# BLHC S coordinate mm
+block="IMAGEHDR"	offset="454"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Image header disclaimer
+block="IMAGEHDR"	offset="456"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Minimum delay after trigger ms
+block="IMAGEHDR"	offset="458"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of cardiac phases to reconstruct [1...32]
+block="IMAGEHDR"	offset="460"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# TE2 (VEMP) us
+block="IMAGEHDR"	offset="464"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# Swap phase/frequency axis - operators choice
+block="IMAGEHDR"	offset="466"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Pause interval ms
+block="IMAGEHDR"	offset="468"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Pause time ms
+block="IMAGEHDR"	offset="472"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Bitmap defining users CVs
+block="IMAGEHDR"	offset="474"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 0
+block="IMAGEHDR"	offset="478"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 1
+block="IMAGEHDR"	offset="482"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 2
+block="IMAGEHDR"	offset="486"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 3
+block="IMAGEHDR"	offset="490"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 4
+block="IMAGEHDR"	offset="494"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 5
+block="IMAGEHDR"	offset="498"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 6
+block="IMAGEHDR"	offset="502"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 7
+block="IMAGEHDR"	offset="506"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 8
+block="IMAGEHDR"	offset="510"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PSD user variable 9
+block="IMAGEHDR"	offset="514"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	bitmap="0;none,Axial;1:none,Sagittal;2:none,Coronal;4:none,Oblique"	# Oblique plane (most like plane)
+block="IMAGEHDR"	offset="516"	intype="Int16_B"	inlength="1"	name="ContrastUsed"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# Contrast used
+block="IMAGEHDR"	offset="518"	intype="String"		inlength="10"	name="?"	dicomtype="?"	dicomtag="?"				# Contrast agent
+block="IMAGEHDR"	offset="528"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Contrast amount
+block="IMAGEHDR"	offset="532"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=pre 3.0,1=post 3.0"	# File format
+block="IMAGEHDR"	offset="534"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=current,1=midpoint,2=water,3=fat,4=peak,5=centroid"	# Auto center frequency
+block="IMAGEHDR"	offset="536"	intype="Int32_B"	inlength="1"	name="TransmitFreq"	dicomtype="?"	dicomtag="?"				# Actual transmit freq used on scan Hz
+block="IMAGEHDR"	offset="540"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Actual receive freq used on scan Hz
+block="IMAGEHDR"	offset="544"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recommended automated transmit freq Hz
+block="IMAGEHDR"	offset="548"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recommended automated receive freq Hz
+block="IMAGEHDR"	offset="552"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recommended automated transmit attenuation .1 dB
+block="IMAGEHDR"	offset="556"	intype="Int32_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Recommended automated receive attenuation .1 dB
+block="IMAGEHDR"	offset="560"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# Histogram present in raw header?
+block="IMAGEHDR"	offset="562"	intype="Int16_B"	inlength="1"	keyword="PFSwapped"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# Swapped phase/frequency - reality (rules or choice)
+block="IMAGEHDR"	offset="564"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R1 for prescan
+block="IMAGEHDR"	offset="566"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R2 for prescan
+block="IMAGEHDR"	offset="568"	intype="Int16_B"	inlength="1"	keyword="VariableBandwidth"	dicomtype="?"	dicomtag="?"				# Variable bandwidth - docs say enum=0=no,1=yes but seems to be kHz
+block="IMAGEHDR"	offset="570"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R1 manual
+block="IMAGEHDR"	offset="572"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# R2 manual
+block="IMAGEHDR"	offset="574"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=none,1=auto failed,2=auto succeeded,3=manual,4=auto failed/manual,5=auto succeeded/manual"	# auto/manual prescan flag
+block="IMAGEHDR"	offset="576"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	bitmap="0:none,CF;1:none,TA;2:none,R1;3:none,R2"	# Changed prescan values
+block="IMAGEHDR"	offset="578"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=Magnitude,1=Phase,2=Real,3=Imaginary"		# Image type
+block="IMAGEHDR"	offset="580"	intype="Int16_B"	inlength="1"	keyword="VascCollapse"	dicomtype="?"	dicomtag="?"	enum="0=Off,1=Col,2=Mag,3=R/L,4=A/P,5=S/I,6=Pjn,7=All,8=OMag,9=OR/L,10=OA/P,11=OS/I,12=OAll,13=OCol"	# Vascular collapse
+block="IMAGEHDR"	offset="582"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# Thickness disclaimer
+block="IMAGEHDR"	offset="584"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# PC venc mm/sec
+block="IMAGEHDR"	offset="586"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# tardis projection angle - degrees
+block="IMAGEHDR"	offset="590"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	enum="0=no,1=yes"	# concatenated sat selected
+block="IMAGEHDR"	offset="592"	intype="Int16_B"	inlength="1"	keyword="FracEcho"	dicomtype="?"	dicomtag="?"	bitmap="0:none,Fractional(Fr);1:none,Effective(Ef)"	# TE Flag
+block="IMAGEHDR"	offset="594"	intype="Int32_B"	inlength="1"	keyword="EchoTrainLength"	dicomtype="?"	dicomtag="?"				# Echo train length
+block="IMAGEHDR"	offset="598"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Slice multiplier to obtain phases for FAST - MP option (multiphase) - number of phases per location
+block="IMAGEHDR"	offset="600"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Cardiac phase number of current image
+block="IMAGEHDR"	offset="602"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# Number of Acquisitions in scan
+block="IMAGEHDR"	offset="604"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"	bitmap=""0:none,noflags;1:none,magweight"	# Vascular imaging flags
+block="IMAGEHDR"	offset="606"	intype="DG_Float_F"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# VENC scaling factor
+block="IMAGEHDR"	offset="1022"	intype="Int16_B"	inlength="1"	name="?"	dicomtype="?"	dicomtag="?"				# checksum
+
+constant="16" 							dicomtype="US"	dicomtag="BitsAllocated"
+constant="12" 							dicomtype="US"	dicomtag="BitsStored"
+constant="11" 							dicomtype="US"	dicomtag="HighBit"
+constant="0" 							dicomtype="US"	dicomtag="PixelRepresentation"	# Unsigned
+constant="1" 							dicomtype="US"	dicomtag="SamplesPerPixel"
+constant="MONOCHROME2" 					dicomtype="CS"	dicomtag="PhotometricInterpretation"
+constant=""								dicomtype="SH"	dicomtag="AccessionNumber"
+constant=""								dicomtype="DA"	dicomtag="PatientBirthDate"
+constant="GE Medical Systems"			dicomtype="LO"	dicomtag="Manufacturer"
+constant="Signa"						dicomtype="LO"	dicomtag="ManufacturerModelName"
+constant="1.2.840.10008.5.1.4.1.1.4"	dicomtype="UI"	dicomtag="SOPClassUID"
+constant="MR"							dicomtype="CS"	dicomtag="Modality"
+
diff --git a/libsrc/src/dconvert/somp/Imakefile b/libsrc/src/dconvert/somp/Imakefile
new file mode 100755
index 0000000..1bb2acf
--- /dev/null
+++ b/libsrc/src/dconvert/somp/Imakefile
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = sompdc.cc sompconv.cc sompmpln.cc \
+		 sompmmsc.cc sompmdt.cc \
+		 sompdmp.cc sompdmpf.cc \
+		 somphdrc.cc somp.cc
+
+OBJS = 		 sompdc.o  sompconv.o  sompmpln.o  \
+		 sompmmsc.o  sompmdt.o  \
+		 sompdmp.o  sompdmpf.o  \
+		 somphdrc.o  somp.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdsomp.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(somp,dconvert)
+
+ProjectConvertTemplate(somphdrp.h,somp,convert,prefix=SOMP_ role=headerpart)
+ProjectConvertTemplate(somphdrw.h,somp,convert,prefix=SOMP_ role=wholeheader)
+ProjectConvertTemplate(somphdrc.h,somp,convert,prefix=SOMP_ role=constructheader)
+ProjectConvertTemplate(sompconv.h,somp,convert,prefix=SOMP_ role=dicom)
+ProjectConvertTemplate(sompdmpf.h,somp,convert,prefix=SOMP_ role=dump)
+
+sompdmpf.o: sompdmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) sompdmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/somp/README b/libsrc/src/dconvert/somp/README
new file mode 100755
index 0000000..4008bb6
--- /dev/null
+++ b/libsrc/src/dconvert/somp/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"somp.h"
+		class SOMP_Conversion {
+			SOMP_Conversion(istream &i,ostream &e);
+			virtual ~SOMP_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"somp.cc"
+
+		SOMP_Conversion::SOMP_Conversion(istream &i,ostream &e);
+		SOMP_Conversion::~SOMP_Conversion();
+
+	"sompcl.h"
+
+		class SOMP_Header_BothClass  : public SOMP_HeaderClass
+		{
+		public:
+			SOMP_Header_BothClass(istream *ist) : SOMP_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"sompconv.cc"
+
+		#include "sompconv.h"
+
+	"sompdc.c"
+
+		bool SOMP_Conversion::convertHeader(AttributeList *list);
+		bool SOMP_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool SOMP_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"sompdc.h"
+
+	"sompdmp.cc"
+
+		bool SOMP_Conversion::dump(ostream &o);
+
+	"sompdmp.h"
+
+	"somphdrc.cc"
+
+		#include "somphdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"somp.tpl"
+
+		The template "describing" the format for header generation
+
+	"sompmdt.cc"
+
+		void SOMP_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"sompmmsc.cc"
+
+		void SOMP_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"sompmpln.cc"
+
+		void SOMP_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"sompptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"sompsrc.h"
+
+		class SOMP_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			SOMP_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~SOMP_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from somp.tpl:
+
+	"somphdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class SOMP_HeaderClass_HDR1 {
+		public:
+			SOMP_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"somphdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class SOMP_HeaderClass
+		{
+		public:
+			SOMP_HeaderClass(istream *ist);
+
+			SOMP_HeaderClass_HDR1 *SOMP_HeaderInstance_HDR1;
+			SOMP_HeaderClass_HDR2 *SOMP_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"somphdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		SOMP_HeaderClass::SOMP_HeaderClass(istream *ist);
+
+	"sompconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void SOMP_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"sompdmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void SOMP_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "somphdrm.h".
+
+	if you have special purpose code, then "somphdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "somphdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/somp/somp.cc b/libsrc/src/dconvert/somp/somp.cc
new file mode 100644
index 0000000..37b762e
--- /dev/null
+++ b/libsrc/src/dconvert/somp/somp.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)somp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "somp.h"
+#include "sompcl.h"
+#include "srcsink.h"
+#include "sompsrc.h"
+
+SOMP_Conversion::SOMP_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	somphdr=0;
+	pixeldatasrc=0;
+}
+
+SOMP_Conversion::~SOMP_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (somphdr) delete somphdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/somp/somp.h b/libsrc/src/dconvert/somp/somp.h
new file mode 100644
index 0000000..5855150
--- /dev/null
+++ b/libsrc/src/dconvert/somp/somp.h
@@ -0,0 +1,46 @@
+/* somp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_somp__
+#define __Header_somp__
+
+// NB. a SOMP_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~SOMP_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class SOMP_Header_BothClass;
+class SOMP_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class SOMP_Conversion {
+	SOMP_Header_BothClass *somphdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	SOMP_PixelDataSource *pixeldatasrc;
+public:
+	SOMP_Conversion(istream &i,ostream &e);
+
+	virtual ~SOMP_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0)
+		{
+			(void)out; (void)imagenumber;
+			return true;
+		}
+
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_somp__ */
+
diff --git a/libsrc/src/dconvert/somp/somp.tpl b/libsrc/src/dconvert/somp/somp.tpl
new file mode 100755
index 0000000..49e80cd
--- /dev/null
+++ b/libsrc/src/dconvert/somp/somp.tpl
@@ -0,0 +1,266 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="BINHDR"  offset="0"    intype="Int16_L"         inlength="1"    name="unknown0"       dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="2"    intype="Int16_L"         inlength="1"    name="unknown2"       dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="4"    intype="Int16_L"         inlength="1"    keyword="blksize"     dicomtype="?"   dicomtag="?"    enum="512=512 bytes"	# Block size
+block="BINHDR"  offset="6"    intype="Int16_L"         inlength="1"    keyword="blkstotal"   dicomtype="?"   dicomtag="?"    # Total blocks in file
+block="BINHDR"  offset="8"    intype="Int16_L"         inlength="1"    name="unknown8"       dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="10"   intype="Int16_L"         inlength="1"    name="unknown10"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="12"   intype="Int16_L"         inlength="1"    name="unknown12"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="14"   intype="Int16_L"         inlength="1"    name="unknown14"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="16"   intype="Int16_L"         inlength="1"    name="unknown16"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="18"   intype="Int16_L"         inlength="1"    name="unknown18"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="20"   intype="Int16_L"         inlength="1"    name="unknown20"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="22"   intype="Int16_L"         inlength="1"    name="unknown22"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="24"   intype="Int16_L"         inlength="1"    name="unknown24"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="26"   intype="Int16_L"         inlength="1"    name="unknown26"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="28"   intype="Int16_L"         inlength="1"    name="unknown28"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="30"   intype="Int16_L"         inlength="1"    name="unknown30"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="32"   intype="Int16_L"         inlength="1"    name="unknown32"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="34"   intype="Int16_L"         inlength="1"    name="unknown34"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="36"   intype="Int16_L"         inlength="1"    name="unknown36"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="38"   intype="Int16_L"         inlength="1"    name="unknown38"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="40"   intype="Int32_L"         inlength="1"    name="unknown40"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="44"   intype="Int16_L"         inlength="1"    name="unknown44"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="46"   intype="Int16_L"         inlength="1"    name="unknown46"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="48"   intype="Int16_L"         inlength="1"    name="unknown48"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="50"   intype="Int16_L"         inlength="1"    name="unknown50"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="52"   intype="Int16_L"         inlength="1"    name="unknown52"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="54"   intype="Int16_L"         inlength="1"    keyword="blkshdr"     dicomtype="?"   dicomtag="?"    enum="8=4096 byte header"	# Blocks in header
+block="BINHDR"  offset="56"   intype="Int16_L"         inlength="1"    name="unknown56"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="58"   intype="Int16_L"         inlength="1"    name="unknown58"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="60"   intype="Int16_L"         inlength="1"    name="unknown60"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="62"   intype="Int16_L"         inlength="1"    name="unknown62"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="64"   intype="Int32_L"         inlength="1"    name="unknown64"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="68"   intype="Int32_L"         inlength="1"    name="unknown68"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="72"   intype="Int32_L"         inlength="1"    name="unknown72"      dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="76"   intype="Int16_L"         inlength="1"    keyword="ptrdata"     dicomtype="?"   dicomtag="?"    enum="9=data after 4096 byte header"	# Block offset (from 1) of image pixel data
+block="BINHDR"  offset="78"   intype="Int16_L"         inlength="1"    keyword="blksdata"    dicomtype="?"   dicomtag="?"    enum="1024=length of uncompressed 512 matrix"	# Blocks in image pixel data
+
+block="BINHDR"  offset="512"  intype="Int32_L"         inlength="1"    name="unknown512"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="516"  intype="String"          inlength="4"    keyword="version"     dicomtype="LO"  dicomtag="SoftwareVersions"    #
+block="BINHDR"  offset="520"  intype="String_Date_DMY" inlength="12"   keyword="studydate"   dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="532"  intype="String_Time"     inlength="12"   keyword="studytime"   dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="544"  intype="String"          inlength="44"   name="unknown544"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="588"  intype="Int32_L"         inlength="1"    name="unknown588"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="592"  intype="Int32_L"         inlength="1"    name="unknown592"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="596"  intype="Int32_L"         inlength="1"    name="unknown596"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="600"  intype="Int32_L"         inlength="1"    name="unknown600"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="604"  intype="Int32_L"         inlength="1"    name="unknown604"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="608"  intype="Int32_L"         inlength="1"    name="unknown608"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="612"  intype="Int32_L"         inlength="1"    name="unknown612"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="616"  intype="Int32_L"         inlength="1"    name="unknown616"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="620"  intype="Int32_L"         inlength="1"    name="unknown620"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="624"  intype="Vax_Float_F"     inlength="1"    name="unknown624"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="628"  intype="Vax_Float_F"     inlength="1"    name="unknown628"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="632"  intype="Vax_Float_F"     inlength="1"    name="unknown632"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="636"  intype="Int32_L"         inlength="1"    name="unknown636"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="640"  intype="Int32_L"         inlength="1"    name="unknown640"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="644"  intype="Int32_L"         inlength="1"    name="unknown644"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="648"  intype="Int32_L"         inlength="1"    name="unknown648"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="652"  intype="Int32_L"         inlength="1"    name="unknown652"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="656"  intype="Int32_L"         inlength="1"    name="unknown656"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="660"  intype="Int32_L"         inlength="1"    name="unknown660"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="664"  intype="String"          inlength="14"   name="model"          dicomtype="LO"  dicomtag="ManufacturerModelName"    #
+block="BINHDR"  offset="678"  intype="Int16_L"         inlength="1"    name="unknown678"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="680"  intype="Int32_L"         inlength="1"    name="unknown680"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="684"  intype="Int32_L"         inlength="1"    name="unknown684"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="688"  intype="Int32_L"         inlength="1"    name="unknown688"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="692"  intype="Int32_L"         inlength="1"    name="unknown692"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="696"  intype="String"          inlength="12"   name="uid1"           dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="708"  intype="String"          inlength="64"   name="uid2"           dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="772"  intype="Int32_L"         inlength="1"    name="unknown772"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="776"  intype="Int32_L"         inlength="1"    name="unknown776"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="780"  intype="String"          inlength="72"   name="unknown780"     dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="852"  intype="String"          inlength="35"   name="unknown852"     dicomtype="?"   dicomtag="?"    #
+
+block="BINHDR"  offset="1024" intype="Int32_L"         inlength="1"    name="unknown1024"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1028" intype="Int32_L"         inlength="1"    name="unknown1028"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1032" intype="Int32_L"         inlength="1"    name="unknown1032"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1036" intype="Int32_L"         inlength="1"    name="unknown1036"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1040" intype="Int32_L"         inlength="1"    name="unknown1040"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1044" intype="Int32_L"         inlength="1"    name="rotation"       dicomtype="?"   dicomtag="?"    enum="360=full,270=quick"	# Gantry rotation (?)
+block="BINHDR"  offset="1048" intype="String"          inlength="20"   keyword="description" dicomtype="LO"  dicomtag="StudyDescription"    #
+
+block="BINHDR"  offset="1072" intype="Int32_L"         inlength="1"    keyword="kv"          dicomtype="DS"  dicomtag="KVP"    #
+block="BINHDR"  offset="1076" intype="Int32_L"         inlength="1"    name="unknown1076"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1080" intype="Int32_L"         inlength="1"    keyword="mas"         dicomtype="IS"  dicomtag="Exposure"    #
+block="BINHDR"  offset="1084" intype="Vax_Float_F"     inlength="1"    keyword="acqtimef"    dicomtype="?"   dicomtag="?"    # TI secs
+block="BINHDR"  offset="1088" intype="Int32_L"         inlength="1"    keyword="slthick"     dicomtype="DS"  dicomtag="SliceThickness"    # mm
+block="BINHDR"  offset="1092" intype="Int32_L"         inlength="1"    name="unknown1092"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1096" intype="Int32_L"         inlength="1"    name="unknown1096"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1100" intype="Int32_L"         inlength="1"    name="unknown1100"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1108" intype="Int32_L"         inlength="1"    name="unknown1108"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1112" intype="Int32_L"         inlength="1"    name="unknown1112"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1116" intype="Int32_L"         inlength="1"    name="unknown1116"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1120" intype="Int32_L"         inlength="1"    name="unknown1120"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1124" intype="Int32_L"         inlength="1"    name="unknown1124"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1128" intype="Int32_L"         inlength="1"    name="unknown1128"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1132" intype="Int32_L"         inlength="1"    name="unknown1132"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1136" intype="Int32_L"         inlength="1"    name="unknown1136"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1140" intype="Vax_Float_F"     inlength="1"    name="unknown1140"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1148" intype="Int32_L"         inlength="1"    name="unknown1148"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1152" intype="Vax_Float_F"     inlength="1"    name="unknown1152"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1156" intype="String"          inlength="4"    keyword="acqtimes"    dicomtype="?"   dicomtag="?"    # TI secs
+block="BINHDR"  offset="1160" intype="Int32_L"         inlength="1"    name="unknown1160"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1164" intype="Int32_L"         inlength="1"    name="unknown1164"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1168" intype="Int32_L"         inlength="1"    name="unknown1168"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1172" intype="Int32_L"         inlength="1"    name="unknown1172"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1176" intype="Int32_L"         inlength="1"    name="unknown1176"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1180" intype="Int32_L"         inlength="1"    name="unknown1180"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1184" intype="Vax_Float_F"     inlength="1"    name="unknown1184"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1188" intype="Int32_L"         inlength="1"    name="unknown1188"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1192" intype="Int32_L"         inlength="1"    name="unknown1192"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1196" intype="Int32_L"         inlength="1"    keyword="ma"          dicomtype="IS"   dicomtag="XRayTubeCurrent"    # mA
+block="BINHDR"  offset="1200" intype="Int32_L"         inlength="1"    name="unknown1200"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1204" intype="Int32_L"         inlength="1"    name="unknown1204"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1208" intype="Int32_L"         inlength="1"    name="unknown1208"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1212" intype="Int32_L"         inlength="1"    name="unknown1212"    dicomtype="?"   dicomtag="?"    #
+
+block="BINHDR"  offset="1280" intype="Int32_L"         inlength="1"    name="unknown1280"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1284" intype="Int32_L"         inlength="1"    name="unknown1284"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1288" intype="Int32_L"         inlength="1"    name="unknown1288"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1292" intype="Int32_L"         inlength="1"    name="unknown1292"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1296" intype="Int32_L"         inlength="1"    name="unknown1296"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1300" intype="Int16_L"         inlength="1"    name="unknown1300"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1302" intype="Int16_L"         inlength="1"    name="unknown1302"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1304" intype="Vax_Float_F"     inlength="1"    name="unknown1304"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1308" intype="Vax_Float_F"     inlength="1"    name="unknown1308"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1312" intype="Vax_Float_F"     inlength="1"    name="unknown1312"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1316" intype="Vax_Float_F"     inlength="1"    name="unknown1316"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1320" intype="Vax_Float_F"     inlength="1"    name="unknown1320"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1324" intype="Vax_Float_F"     inlength="1"    name="unknown1324"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1328" intype="Int32_L"         inlength="1"    keyword="matrix"      dicomtype="?"   dicomtag="?"    # Matrix size (?)
+block="BINHDR"  offset="1332" intype="Vax_Float_F"     inlength="1"    keyword="zoomfactor"  dicomtype="DS"   dicomtag="ZoomFactor"    # Zoom factor (?)
+block="BINHDR"  offset="1336" intype="Vax_Float_F"     inlength="1"    name="unknown1336"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1340" intype="Vax_Float_F"     inlength="1"    name="unknown1340"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1344" intype="Int32_L"         inlength="1"    name="unknown1344"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1348" intype="Int32_L"         inlength="1"    name="unknown1348"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1352" intype="Int32_L"         inlength="1"    name="unknown1352"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1356" intype="Int32_L"         inlength="1"    name="unknown1356"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1360" intype="Int32_L"         inlength="1"    name="unknown1360"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1364" intype="Int32_L"         inlength="1"    name="unknown1364"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1368" intype="Vax_Float_F"     inlength="1"    name="unknown1368"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1372" intype="String"          inlength="4"    name="unknown1372"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1376" intype="Int32_L"         inlength="1"    name="unknown1376"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1380" intype="Int8"            inlength="1"    name="unknown1380"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1381" intype="String"          inlength="3"    name="unknown1381"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1384" intype="Vax_Float_F"     inlength="1"    name="unknown1384"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1388" intype="Int32_L"         inlength="1"    name="unknown1388"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1392" intype="Int32_L"         inlength="1"    name="unknown1392"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1396" intype="Int32_L"         inlength="1"    name="unknown1396"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1400" intype="Int32_L"         inlength="1"    name="unknown1400"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1404" intype="Vax_Float_F"     inlength="1"    name="unknown1404"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1408" intype="Int32_L"         inlength="1"    name="unknown1408"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1412" intype="Int32_L"         inlength="1"    name="unknown1412"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1416" intype="Int32_L"         inlength="1"    name="unknown1416"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1420" intype="Int32_L"         inlength="1"    name="unknown1420"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1424" intype="Int32_L"         inlength="1"    name="unknown1424"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1428" intype="Int32_L"         inlength="1"    name="unknown1428"    dicomtype="?"   dicomtag="?"    #
+
+block="BINHDR"  offset="1540" intype="Int32_L"         inlength="1"    name="unknown1540"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1544" intype="Int32_L"         inlength="1"    keyword="tableposn"   dicomtype="DS"  dicomtag="SliceLocation"    # TP mm
+block="BINHDR"  offset="1548" intype="Int32_L"         inlength="1"    keyword="tableheight" dicomtype="DS"  dicomtag="TableHeight"    # Table height mm ?
+block="BINHDR"  offset="1552" intype="Int32_L"         inlength="1"    name="unknown1552"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1556" intype="Int32_L"         inlength="1"    name="unknown1556"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1560" intype="Int32_L"         inlength="1"    keyword="scannumber"  dicomtype="IS"  dicomtag="InstanceNumber"    # Scan number
+block="BINHDR"  offset="1564" intype="String_Date_DMY" inlength="12"   keyword="scandate"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1576" intype="String_Time"     inlength="12"   keyword="scantime"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1588" intype="String"          inlength="24"   name="unknown1588"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1612" intype="Int32_L"         inlength="1"    name="unknown1612"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1616" intype="Int32_L"         inlength="1"    name="unknown1616"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1620" intype="Int32_L"         inlength="1"    name="unknown1620"    dicomtype="?"   dicomtag="?"    #
+
+block="BINHDR"  offset="1664" intype="String"          inlength="40"   name="unknown1664"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1704" intype="Int32_L"         inlength="1"    name="unknown1704"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1708" intype="Int32_L"         inlength="1"    name="unknown1708"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1718" intype="Int16_L"         inlength="1"    name="unknown1718"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1720" intype="Int16_L"         inlength="1"    name="unknown1720"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1722" intype="Int16_L"         inlength="1"    name="unknown1722"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1724" intype="Int16_L"         inlength="1"    name="unknown1724"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1726" intype="Int16_L"         inlength="1"    name="unknown1726"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1728" intype="Vax_Float_F"     inlength="1"    name="unknown1728"    dicomtype="?"   dicomtag="?"    #
+
+block="BINHDR"  offset="1792" intype="Int16_L"         inlength="1"    name="unknown1792"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1794" intype="Int16_L"         inlength="1"    name="unknown1794"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1796" intype="Int16_L"         inlength="1"    name="unknown1796"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1798" intype="Int16_L"         inlength="1"    name="unknown1798"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1800" intype="Int16_L"         inlength="1"    name="unknown1800"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1802" intype="Int16_L"         inlength="1"    name="unknown1802"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1804" intype="Int32_L"         inlength="1"    name="unknown1804"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1808" intype="Int16_L"         inlength="1"    name="unknown1808"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1810" intype="Int16_L"         inlength="1"    name="unknown1810"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1812" intype="Int16_L"         inlength="1"    name="unknown1812"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1814" intype="Int16_L"         inlength="1"    name="unknown1814"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1816" intype="Int32_L"         inlength="1"    name="unknown1816"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1820" intype="Int32_L"         inlength="1"    name="unknown1820"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1824" intype="Int16_L"         inlength="1"    name="unknown1824"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1826" intype="Int16_L"         inlength="1"    name="unknown1826"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1828" intype="Int16_L"         inlength="1"    name="unknown1828"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1830" intype="Int16_L"         inlength="1"    name="unknown1830"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1832" intype="Int16_L"         inlength="1"    name="unknown1832"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1834" intype="Int16_L"         inlength="1"    name="unknown1834"    dicomtype="?"   dicomtag="?"    #
+block="BINHDR"  offset="1836" intype="Int16_L"         inlength="1"    name="unknown1836"    dicomtype="?"   dicomtag="?"    #
+
+block="TEXTHDR"	offset="4"    intype="String"          inlength="21"   keyword="tproduct"    dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="25"   intype="String"          inlength="5"    keyword="tversion"    dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="30"   intype="String"          inlength="30"   keyword="thospital"   dicomtype="LO"  dicomtag="InstitutionName"    #
+block="TEXTHDR"	offset="60"   intype="String_Time"     inlength="8"    keyword="ttime"       dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="72"   intype="String"          inlength="12"   keyword="tsliceno"    dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="84"   intype="String"          inlength="2"    keyword="ttableposnf" dicomtype="?"   dicomtag="?"    enum="'TP'=Table position mm"	#
+block="TEXTHDR"	offset="86"   intype="String"          inlength="10"   keyword="ttableposn"  dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="96"   intype="String"          inlength="24"   keyword="tpatname"    dicomtype="PN"  dicomtag="PatientName"    #
+block="TEXTHDR"	offset="120"  intype="String"          inlength="13"   keyword="tpatid"	     dicomtype="LO"  dicomtag="PatientID"      #
+block="TEXTHDR"	offset="133"  intype="String_Date_DMY" inlength="12"   keyword="tdate"       dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="145"  intype="String"          inlength="2"    keyword="tacqtimesf"  dicomtype="?"   dicomtag="?"    enum="'TI'=Acquisition time secs"	#
+block="TEXTHDR"	offset="147"  intype="String"          inlength="10"   keyword="tacqtimes"   dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="157"  intype="String"          inlength="3"    keyword="tmasf"       dicomtype="?"   dicomtag="?"    enum="'mAs'=Exposure mAs"    #
+block="TEXTHDR"	offset="160"  intype="String"          inlength="9"    keyword="tmas"        dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="169"  intype="String"          inlength="2"    keyword="tkvf"        dicomtype="?"   dicomtag="?"    enum="'kV'=Tube voltage kV"    #
+block="TEXTHDR"	offset="171"  intype="String"          inlength="10"   keyword="tkv"         dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="181"  intype="String"          inlength="2"    keyword="tslf"        dicomtype="?"   dicomtag="?"    enum="'SL'=Slice thickness mm" #
+block="TEXTHDR"	offset="183"  intype="String"          inlength="10"   keyword="tsl"         dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="193"  intype="String"          inlength="2"    keyword="tgtf"        dicomtype="?"   dicomtag="?"    enum="'GT'=Gantry Tilt degrees"    #
+block="TEXTHDR"	offset="195"  intype="String"          inlength="10"   keyword="tgt"         dicomtype="DS"  dicomtag="GantryDetectorTilt"    #
+block="TEXTHDR"	offset="205"  intype="String"          inlength="2"    keyword="tzof"        dicomtype="?"   dicomtag="?"    enum="'ZO'=Zoom factor"    #
+block="TEXTHDR"	offset="207"  intype="String"          inlength="10"   keyword="tzo"         dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="217"  intype="String"          inlength="2"    keyword="tcef"        dicomtype="?"   dicomtag="?"    enum="'CE'=Zoom center"    #
+block="TEXTHDR"	offset="219"  intype="String"          inlength="12"   keyword="tcex"        dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="231"  intype="String"          inlength="10"   keyword="tcey"        dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="241"  intype="String"          inlength="2"    keyword="tmaf"        dicomtype="?"   dicomtag="?"    enum="'CE'=Tube current mA"    #
+block="TEXTHDR"	offset="243"  intype="String"          inlength="10"   keyword="tma"         dicomtype="?"   dicomtag="?"    #
+block="TEXTHDR"	offset="253"  intype="String"          inlength="10"   keyword="tlabelright" dicomtype="?"   dicomtag="?"	enum="'LEFT'=left,'RIGHT'=Right,'ANTERIOR'=Anterior,'POSTERIOR'=Posterior,'HEAD'=Head,'FEET'=Feet"    #
+block="TEXTHDR"	offset="263"  intype="String"          inlength="10"   keyword="tlabeltop"   dicomtype="?"   dicomtag="?"	enum="'LEFT'=left,'RIGHT'=Right,'ANTERIOR'=Anterior,'POSTERIOR'=Posterior,'HEAD'=Head,'FEET'=Feet"    #
+block="TEXTHDR"	offset="273"  intype="String"          inlength="40"   keyword="tcomment"    dicomtype="LT"   dicomtag="ImageComments"				   #
+
+constant="0" 			dicomtype="US"	dicomtag="PixelPaddingValue"		# 
+constant="16" 			dicomtype="US"	dicomtag="BitsAllocated"		# 
+constant="16" 			dicomtype="US"	dicomtag="BitsStored"			# 
+constant="15" 			dicomtype="US"	dicomtag="HighBit"			# 
+constant="0" 			dicomtype="US"	dicomtag="PixelRepresentation"		# Unsigned
+constant="1" 			dicomtype="US"	dicomtag="SamplesPerPixel"		# 
+constant="MONOCHROME2" 		dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="-1000" 		dicomtype="DS"	dicomtag="RescaleIntercept"		# 
+constant="1" 			dicomtype="DS"	dicomtag="RescaleSlope"			# 
+constant="Hounsfield Units" 	dicomtype="LO"	dicomtag="RescaleType"			# 
+constant="30"			dicomtype="DS"	dicomtag="WindowCenter"			# 
+constant="250"			dicomtype="DS"	dicomtag="WindowWidth"			# 
+constant="Soft tissue"		dicomtype="LO"	dicomtag="WindowCenterWidthExplanation"	# 
+
+constant=""			dicomtype="SH"	dicomtag="AccessionNumber"		# 
+constant="1"			dicomtype="IS"	dicomtag="SeriesInStudy"		# 
+constant="1"			dicomtype="IS"	dicomtag="AcquisitionsInStudy"		# 
+constant=""			dicomtype="SH"	dicomtag="StudyID"			#
+constant="1"			dicomtype="IS"	dicomtag="SeriesNumber"			# 
+
+constant=""			dicomtype="LO"	dicomtag="DeviceSerialNumber"		# 
+constant="SIEMENS"		dicomtype="LO"	dicomtag="Manufacturer"			# 
+constant=""			dicomtype="DS"	dicomtag="PatientWeight"		# 
+constant=""			dicomtype="CS"	dicomtag="PatientSex"			# 
+constant=""			dicomtype="DA"	dicomtag="PatientBirthDate"		# 
+constant=""			dicomtype="AS"	dicomtag="PatientAge"			# 
+
+constant=""			dicomtype="CS"	dicomtag="BodyPartExamined"		# 
+constant=""			dicomtype="SH"	dicomtag="FilterType"			# 
+constant="CT"			dicomtype="CS"	dicomtag="Modality"			# 
diff --git a/libsrc/src/dconvert/somp/sompcl.h b/libsrc/src/dconvert/somp/sompcl.h
new file mode 100644
index 0000000..494d7dd
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompcl.h
@@ -0,0 +1,25 @@
+/* sompcl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "somphdrp.h"
+#include "somphdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class SOMP_Header_BothClass : public SOMP_HeaderClass
+{
+public:
+	SOMP_Header_BothClass(istream *ist) : SOMP_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/somp/sompconv.cc b/libsrc/src/dconvert/somp/sompconv.cc
new file mode 100644
index 0000000..3035811
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "sompdc.h"
+#include "sompptrs.h"
+#include "sompconv.h"
diff --git a/libsrc/src/dconvert/somp/sompdc.cc b/libsrc/src/dconvert/somp/sompdc.cc
new file mode 100644
index 0000000..32e83dd
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompdc.cc
@@ -0,0 +1,90 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompdc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sompdc.h"
+#include "somp.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "sompsrc.h"
+
+bool
+SOMP_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!somphdr) somphdr=new SOMP_Header_BothClass(in);
+	Assert(somphdr);
+
+	somphdr->ToDicom_Template(list);
+	somphdr->ToDicom_ManualMisc(list);
+	somphdr->ToDicom_ManualPlane(list);
+	somphdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in somp.h about the importance of the scope
+// of a SOMP_Conversion object and AttributeList object
+
+bool
+SOMP_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!somphdr) somphdr=new SOMP_Header_BothClass(in);
+	Assert(somphdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	pixeldatasrc=new SOMP_PixelDataSource(
+		*in,
+		SOMP_Offset_PixelData_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+SOMP_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/somp/sompdc.h b/libsrc/src/dconvert/somp/sompdc.h
new file mode 100644
index 0000000..352dfe2
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompdc.h
@@ -0,0 +1,7 @@
+/* sompdc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "sompcl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "sompptrs.h"
diff --git a/libsrc/src/dconvert/somp/sompdmp.cc b/libsrc/src/dconvert/somp/sompdmp.cc
new file mode 100644
index 0000000..78f9944
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompdmp.cc
@@ -0,0 +1,23 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sompdmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "somp.h"
+
+bool
+SOMP_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!somphdr) somphdr=new SOMP_Header_BothClass(in);
+	Assert(somphdr);
+
+	TextOutputStream out(o);
+
+	somphdr->DumpCommon(&out);
+
+	return true;
+}
+
+
diff --git a/libsrc/src/dconvert/somp/sompdmp.h b/libsrc/src/dconvert/somp/sompdmp.h
new file mode 100644
index 0000000..4c384c3
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompdmp.h
@@ -0,0 +1,4 @@
+/* sompdmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "sompcl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/somp/sompdmpf.cc b/libsrc/src/dconvert/somp/sompdmpf.cc
new file mode 100644
index 0000000..3392b92
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompdmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompdmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sompdmp.h"
+#include "sompptrs.h"
+#include "sompdmpf.h"
diff --git a/libsrc/src/dconvert/somp/somphdrc.cc b/libsrc/src/dconvert/somp/somphdrc.cc
new file mode 100644
index 0000000..8aa2c1f
--- /dev/null
+++ b/libsrc/src/dconvert/somp/somphdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)somphdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "sompptrs.h"
+#include "somphdrp.h"
+#include "somphdrw.h"
+#include "somphdrc.h"
+
diff --git a/libsrc/src/dconvert/somp/sompmdt.cc b/libsrc/src/dconvert/somp/sompmdt.cc
new file mode 100644
index 0000000..8f3e832
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompmdt.cc
@@ -0,0 +1,31 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sompdc.h"
+#include "elmconst.h"
+
+void 
+SOMP_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),
+		Date(String_Use(SOMP_HeaderInstance_BINHDR->studydate)));
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),
+		Time(String_Use(SOMP_HeaderInstance_BINHDR->studytime)));
+
+	// ContentDate (formerly Image)
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+		Date(String_Use(SOMP_HeaderInstance_BINHDR->scandate)));
+
+	// ContentTime (formerly Image)
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+		Time(String_Use(SOMP_HeaderInstance_BINHDR->scantime)));
+
+}
+
diff --git a/libsrc/src/dconvert/somp/sompmmsc.cc b/libsrc/src/dconvert/somp/sompmmsc.cc
new file mode 100644
index 0000000..03829d8
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompmmsc.cc
@@ -0,0 +1,217 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sompdc.h"
+#include "elmconst.h"
+
+void 
+SOMP_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Rows,Columns
+
+	(*list)+=new UnsignedShortAttribute(TagFromName(Rows),
+		SOMP_HeaderInstance_BINHDR->matrix);
+	(*list)+=new UnsignedShortAttribute(TagFromName(Columns),
+		SOMP_HeaderInstance_BINHDR->matrix);
+
+	// ExposureTime
+
+	// Loose fractional part ...
+
+	{
+		// Not in line because SC 4.0 has ambiguity :(
+		Int32 i = Int32(SOMP_HeaderInstance_BINHDR->acqtimef);
+		(*list)+=new IntegerStringAttribute(TagFromName(ExposureTime),i);
+	}
+
+#ifdef CRAP
+	// Modality
+
+	switch (SOMP_HeaderInstance_STDHDR->SMODELNO_Mod) {
+		case 1:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"CT");
+			break;
+		case 2:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"MR");
+			break;
+		default:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"SC");
+			break;
+	}
+
+	// ImageType
+
+	char *value1,*value2,*value3;
+
+	value1="ORIGINAL";
+
+	// P is prospective, R is retrospective ...
+
+	value2=strncmp(SOMP_HeaderInstance_IMGHDR2->ITCTYPE,"P",1) == 0
+		? "PRIMARY" : "SECONDARY";
+
+	value3=strncmp(SOMP_HeaderInstance_IMGHDR->IMTYPE,"AX",2) == 0
+		? "AXIAL" : "LOCALIZER";
+
+	(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+		value1,value2,value3);
+
+	// ContrastBolus Module
+
+	if (strncmp(SOMP_HeaderInstance_IMGHDR->IENHANCE,"+C",2) == 0) {
+
+		// ContrastBolusAgent ="Contrast"
+		// ContrastBolusStartTime
+
+		(*list)+=new LongStringAttribute(TagFromName(ContrastBolusAgent),
+			"Contrast");
+
+		(*list)+=new TimeStringAttribute(TagFromName(ContrastBolusStartTime),
+			Time(String_Use(SOMP_HeaderInstance_IMGHDR->ICETIME)));
+	}
+
+	// GeneratorPower
+
+	// Loose fractional part ...
+
+	(*list)+=new IntegerStringAttribute(TagFromName(GeneratorPower),
+		(unsigned short)(atof(SOMP_HeaderInstance_IMGHDR->IGENPOW)));
+
+	{
+		// SoftwareVersion 
+
+		ostrstream ost;
+		ost << "System "    << SOMP_HeaderInstance_STDHDR->SSYSVNO
+		    << "."          << SOMP_HeaderInstance_STDHDR->SSYSRNO
+		    << " Database " << SOMP_HeaderInstance_STDHDR->SDATVNO
+		    << "."          << SOMP_HeaderInstance_STDHDR->SDATRNO
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new LongStringAttribute(TagFromName(SoftwareVersion),str);
+		if (str) delete[] str;
+	}
+	{
+		// StationName 
+
+		ostrstream ost;
+		ost << SOMP_HeaderInstance_STDHDR->SMODELNO_Mod << "."
+		    << SOMP_HeaderInstance_STDHDR->SMODELNO_Mac << "."
+		    << SOMP_HeaderInstance_STDHDR->SMACHINE
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new ShortStringAttribute(TagFromName(StationName),str);
+		if (str) delete[] str;
+	}
+
+	// Do the descriptions ...
+
+	class Description {
+		ostrstream ost;
+		int first;
+		char delim;
+	public:
+		Description(char d=0)	{ first=1; delim=d; }
+
+		void add(const char *desc,unsigned maxlength)
+			{
+				char *buf = new char[maxlength+1];
+				strncpy(buf,desc,maxlength); buf[maxlength]=0;
+				char *lastssomp=strrchr(buf,' ');
+				if (lastssomp && buf[maxlength-1] == ' ')
+					*lastssomp=0;
+				char *start = buf;
+				while (*start && *start == ' ') ++start;
+				if (*start) {
+					if (!first && delim) ost << delim;
+					ost << start;
+				}
+				first=0;
+				if (buf) delete[] buf;
+			}
+
+		char *get(void)		{ ost << ends; return ost.str(); }
+	};
+
+	{
+		// StudyDescription
+
+		Description desc(' ');
+		desc.add(SOMP_HeaderInstance_STDHDR->SDESC1,50);
+		desc.add(SOMP_HeaderInstance_STDHDR->SDESC2,50);
+		desc.add(SOMP_HeaderInstance_STDHDR->SDESC3,50);
+		desc.add(SOMP_HeaderInstance_STDHDR->SDESC4,50);
+		desc.add(SOMP_HeaderInstance_STDHDR->SDESC5,50);
+
+		char *str=desc.get();
+		unsigned length=strlen(str);
+		if (length > 64) {
+			str[64]=0;
+			length=64;
+		}
+
+		(*list)+=new LongStringAttribute(TagFromName(StudyDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// SeriesDescription
+
+		Description desc(' ');
+		desc.add(SOMP_HeaderInstance_IMGHDR2->ISRDESC1,16);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->ISRDESC2,14);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->ISRDESC3,12);
+
+		char *str=desc.get();
+
+		(*list)+=new LongStringAttribute(TagFromName(SeriesDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// ImageComments
+
+		Description desc(' ');
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IIMDESC1,10);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IIMDESC2,8);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IIMDESC3,7);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(ImageComments),str);
+		if (str) delete[] str;
+	}
+	{
+		// AdditionalPatientHistory
+
+		Description desc(' ');
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC1,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC2,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC3,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC4,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC5,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC6,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC7,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC8,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC9,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC10,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC11,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC12,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC13,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC14,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC15,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC16,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC17,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC18,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC19,17);
+		desc.add(SOMP_HeaderInstance_IMGHDR2->IEXDESC20,17);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(AdditionalPatientHistory),str);
+		if (str) delete[] str;
+	}
+#endif
+}
+
diff --git a/libsrc/src/dconvert/somp/sompmpln.cc b/libsrc/src/dconvert/somp/sompmpln.cc
new file mode 100644
index 0000000..6783952
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompmpln.cc
@@ -0,0 +1,372 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sompmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sompdc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+SOMP_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	{
+		const char *labelright=SOMP_HeaderInstance_TEXTHDR->tlabelright;
+		const char *rowdir;
+
+		switch (labelright[0]) {
+			case 'L':
+				rowdir="L"; break;
+			case 'R':
+				rowdir="R"; break;
+			case 'A':
+				rowdir="A"; break;
+			case 'P':
+				rowdir="P"; break;
+			case 'H':
+				rowdir="H"; break;
+			case 'F':
+				rowdir="F"; break;
+			default:
+				rowdir=0; break;
+		}
+
+		const char *labeltop=SOMP_HeaderInstance_TEXTHDR->tlabeltop;
+		const char *coldir;
+
+		switch (labeltop[0]) {
+			case 'L':
+				coldir="R"; break;
+			case 'R':
+				coldir="L"; break;
+			case 'A':
+				coldir="P"; break;
+			case 'P':
+				coldir="A"; break;
+			case 'H':
+				coldir="F"; break;
+			case 'F':
+				coldir="H"; break;
+			default:
+				coldir=0; break;
+		}
+
+		if (coldir && rowdir)
+			(*list)+=new CodeStringAttribute(TagFromName(PatientOrientation),
+				rowdir,coldir);
+	}
+
+#ifdef CRAP
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlanePlane plane;
+
+	// Determine the "machine" plane of the image ...
+
+	// (Doesn't handle scout azimuth yet)
+	// Same for CT and MR (CT seems to set IMTYPE "AX  ")
+	switch (((char *)(SOMP_HeaderInstance_IMGHDR->IPLANE))[0]) {
+		case 'A':	// "AX  "
+			plane=Axial;
+			break;
+		case 'S':	// "SAG "
+			plane=Sagittal;
+			break;
+		case 'C':	// "COR "
+			plane=Coronal;
+			break;
+		default:	// Yuck - just in case :(
+			plane=Axial;
+			break;
+	}
+
+	ImagePlaneHeadFeet orientation;
+
+	switch (((char *)(SOMP_HeaderInstance_IMGHDR->IHFFIRST))[0]) {
+		case 'H':
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+		case 'F':
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+		default:
+			hfff="";		// :(
+			orientation=HeadFirst;
+			break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (((char *)(SOMP_HeaderInstance_IMGHDR->IPATORI))[0]) {
+		case 'P':
+			ap="P";
+			position=Prone;
+			break;
+		case 'S':
+			ap="S";
+			position=Supine;
+			break;
+		case 'L':
+			ap="DL";
+			position=LeftLateralDecubitus;
+			break;
+		case 'R':
+			ap="DR";
+			position=RightLateralDecubitus;
+			break;
+		default:
+			ap="";			// :(
+			position=Supine;
+			break;
+	}
+
+	double scanfov = atof(SOMP_HeaderInstance_IMGHDR->ISFOV)*10;	// cm -> mm
+
+	// Make a model of the image plane ...
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlanet" << endl;
+
+	ImagePlane imageplane(plane,scanfov,orientation,position);
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlane done" << endl;
+//imageplane.put(cerr);
+
+	// While we are in the "display" or "gantry plane ...
+	// (before angulation) 
+
+	// Apply any transformations specified in the
+	// display/gantry plane, such as magnification and
+	// reconstruction target offsets ...
+
+	// Assume that these are machine rather than body relative
+
+	double reconfov	= atof(SOMP_HeaderInstance_IMGHDR2->IRFOV)*10;	// cm -> mm
+	double reconch	= SOMP_HeaderInstance_IMGHDR2->IRCENTX;
+	double reconcv	= SOMP_HeaderInstance_IMGHDR2->IRCENTY;
+
+	double magfact 	= SOMP_HeaderInstance_IMGHDR2->IMAGFACT;
+	double magch	= SOMP_HeaderInstance_IMGHDR2->IMAGCX;
+	double magcv	= SOMP_HeaderInstance_IMGHDR2->IMAGCY;
+
+	Vector3D reconoffset;
+	Vector3D magoffset;
+
+	// Determine which axes are "horizontal" & "vertical" ...
+	// Don't forget sign changes ...
+
+	switch (plane) {
+		case Axial:
+			reconoffset=Vector3D(reconch,-reconcv,0);
+			magoffset  =Vector3D(magch,    -magcv,0);
+			break;
+		case Sagittal:
+			reconoffset=Vector3D(0,-reconch,reconcv);
+			magoffset  =Vector3D(0,  -magch,  magcv);
+			break;
+		case Coronal:
+			reconoffset=Vector3D(reconch,0,reconcv);
+			magoffset  =Vector3D(magch  ,0,  magcv);
+			break;
+	}
+
+//cerr << "ToDicom_ManualPlane::reconoffset is:" << endl;
+//reconoffset.put(cerr);
+//cerr << "ToDicom_ManualPlane::magoffset is:" << endl;
+//magoffset.put(cerr);
+
+//cerr << "ToDicom_ManualPlane::scale:" << endl;
+	imageplane.MachinePlane::scale(magfact*reconfov/scanfov);
+//cerr << "ToDicom_ManualPlane::scale result:" << endl;
+//imageplane.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by reconoffset:" << endl;
+	imageplane.MachinePlane::shift(reconoffset);
+//cerr << "ToDicom_ManualPlane::shift by reconoffset result:" << endl;
+//imageplane.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by magoffset:" << endl;
+	imageplane.MachinePlane::shift(magoffset);
+//cerr << "ToDicom_ManualPlane::shift by magoffset result:" << endl;
+//imageplane.put(cerr);
+
+	// Account for angulation ...
+
+	if (SOMP_isct) {
+//cerr << "ToDicom_ManualPlane::angling:" << endl;
+#ifdef SOMPTILTCTUSINGMACHINECORDS
+		// +ve is top towards table
+		// whereas Z is positive into gantry so change sign
+		imageplane.MachinePlane::angle(
+			LeftRight,-SOMP_HeaderInstance_CTHDR->IGTILT);
+#else // SOMPTILTCTUSINGMACHINECORDS
+		// +ve is always towards front of head
+		imageplane.PatientPlane::angle(
+			LeftRight,atof(SOMP_HeaderInstance_CTHDR->IGTILTB));
+#endif // SOMPTILTCTUSINGMACHINECORDS
+//cerr << "ToDicom_ManualPlane::angling result:" << endl;
+//imageplane.put(cerr);
+	}
+
+	if (SOMP_ismr) {
+		// Not yet tested ... no samples available ...
+
+		// Tilt is specified as none or relative to axis
+		// Axis+/-Angle [xx+/-xx]
+		// NB. in body not machine coordinates **********
+
+		char *str=SOMP_HeaderInstance_MRHDR->IMRTILT;
+		char axis[3]; strncpy(axis,str,2); axis[2]=0;
+		int angle=str[2] ? atoi(str+2) : 0;
+
+		// in Japanese docs, text contradicts drawing so
+		// go with drawing ...
+
+		ImagePlaneAxis planeaxis;
+
+		if (angle) {
+			switch (axis[0]) {
+				case 'A':
+				case 'P':
+					planeaxis=AnteriorPosterior;
+					// Somp CW +ve facing posterior
+					// angle=angle;
+					break;
+				case 'R':
+				case 'L':
+					planeaxis=LeftRight;
+					// Somp CW +ve facing right lat
+					angle=-angle;
+					break;
+				case 'H':
+				case 'F':
+					planeaxis=HeadFeet;
+					// Somp CW +ve facing head
+					// angle=angle;
+					break;
+			}
+		}
+		imageplane.PatientPlane::angle(planeaxis,angle);
+	}
+
+	// Account for physical offsets in the body plane ...
+	// (after angulation)
+
+	// For Somp the only difference between slices seems to be
+	// in the "Slice position by body coords" (ISLPOSxx) fields
+	// These do NOT include recon center offset and gantry tilt
+
+	// NB. The "Image center machine coords" (IIMPOSx) already
+	// account for both the recon center offset and the gantry
+	// tilt. They do NOT however handle the change between
+	// slices in the Z direction (what I would expect to be
+	// in ITBLPOS but is not ... it is zero in every slice :()
+	// so we can't use them.
+
+	double xcenter=SOMP_HeaderInstance_IMGHDR->ISLPOSLR;
+	double ycenter=SOMP_HeaderInstance_IMGHDR->ISLPOSAP;
+	double zcenter=SOMP_HeaderInstance_IMGHDR->ISLPOSHF;
+
+	// Consider sign difference Somp vs. Dicom for Y
+
+//cerr << "ToDicom_ManualPlane::physical offset is" << endl;
+	Vector3D offset(xcenter,-ycenter,zcenter);
+//offset.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by physical offset" << endl;
+	imageplane.PatientPlane::shift(offset);
+//cerr << "ToDicom_ManualPlane::shift by physical offset result:" << endl;
+//imageplane.put(cerr);
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+//cerr << "ToDicom_ManualPlane::addPlaneToList:" << endl;
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+//cerr << "ToDicom_ManualPlane::addPlaneToList done:" << endl;
+
+	// SliceLocation
+
+	// ITBLPOS always seems to be zero, so use IPLANE to
+	// decide which slice position value to use
+
+	// Somp slice position values are in body coordinates.
+	// Neither DICOM PS3 nor ACR/NEMA 2 define sign of
+	// SliceLocation, but seeing as it is an old element
+	// it seems appropriate to use machine coordinates
+
+	// Don't want to use the angled, magnified, targeted
+	// imageplane because it is in the axis of the
+	// image center rather than the axis at isocenter
+	// and is slightly different from the conventional
+	// interpretation of table position if an offset
+	// in the display/gantry plane has been applied.
+
+	// So set up a new imageplane just to convert from
+	// body to machine cordinates, and apply physical
+	// offset without angulation or recon or zoom ...
+
+//cerr << "ToDicom_ManualPlane::Use a new image plane for rest:" << endl;
+
+	ImagePlane locationimageplane(plane,scanfov,orientation,position);
+
+	locationimageplane.PatientPlane::shift(offset);
+
+	Point3D center=locationimageplane.MachinePlane::getCenter();
+
+	double location;
+
+	switch (plane) {
+		case Axial:
+			location=center.getZ();
+			break;
+		case Sagittal:
+			location=center.getX();
+			break;
+		case Coronal:
+			location=center.getY();
+			break;
+	}
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),location);
+
+	// TableHeight
+
+	// DICOM ...+ve is below center
+	// Somp is in machine co-ordinates ... +ve is up
+
+	if (SOMP_isct) (*list)+=new
+		DecimalStringAttribute(TagFromName(TableHeight),
+			double(-double(SOMP_HeaderInstance_CTHDR->ITBLHGT)));
+
+	// PixelSpacing
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		SOMP_HeaderInstance_IMGHDR2->IPIXSIZE,
+		SOMP_HeaderInstance_IMGHDR2->IPIXSIZE);
+
+	// ZoomFactor
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomFactor),
+		SOMP_HeaderInstance_IMGHDR2->IMAGFACT,
+		SOMP_HeaderInstance_IMGHDR2->IMAGFACT);
+
+	// ZoomCenter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomCenter),
+			SOMP_HeaderInstance_IMGHDR2->IMAGCX,
+			SOMP_HeaderInstance_IMGHDR2->IMAGCY);
+
+	// ReconstructionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),
+		atof(SOMP_HeaderInstance_IMGHDR2->IRFOV)*10);
+
+	// DataCollectionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(DataCollectionDiameter),
+		atof(SOMP_HeaderInstance_IMGHDR->ISFOV)*10);
+#endif
+}
+
diff --git a/libsrc/src/dconvert/somp/sompptrs.h b/libsrc/src/dconvert/somp/sompptrs.h
new file mode 100644
index 0000000..63c4d33
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompptrs.h
@@ -0,0 +1,5 @@
+/* sompptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	SOMP_Offset_BINHDR_ptr	0
+#define	SOMP_Offset_TEXTHDR_ptr	3072
+
+#define	SOMP_Offset_PixelData_ptr	4096
diff --git a/libsrc/src/dconvert/somp/sompsrc.h b/libsrc/src/dconvert/somp/sompsrc.h
new file mode 100644
index 0000000..cf82d3a
--- /dev/null
+++ b/libsrc/src/dconvert/somp/sompsrc.h
@@ -0,0 +1,61 @@
+/* sompsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_sompsrc__
+#define __Header_sompsrc__
+
+class SOMP_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	SOMP_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~SOMP_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Little endian ...
+				Uint16 pixel;
+				pixel=(bytes[1]<<8)|bytes[0];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_sompsrc__
diff --git a/libsrc/src/dconvert/support/Imakefile b/libsrc/src/dconvert/support/Imakefile
new file mode 100755
index 0000000..93b9d08
--- /dev/null
+++ b/libsrc/src/dconvert/support/Imakefile
@@ -0,0 +1,11 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = planea.cc plane.cc dateconv.cc
+
+OBJS =           planea.o  plane.o  dateconv.o
+
+LibraryTarget($(PROJECTLIBDIR)/lib$(PROJECTDCONVERTLIBNAME).a,$(OBJS))
+
+DependCCTarget()
diff --git a/libsrc/src/dconvert/support/dateconv.cc b/libsrc/src/dconvert/support/dateconv.cc
new file mode 100644
index 0000000..0b3dd2b
--- /dev/null
+++ b/libsrc/src/dconvert/support/dateconv.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dateconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "convtype.h"
+#include "datetype.h"
+#include "dateconv.h"
+
+
diff --git a/libsrc/src/dconvert/support/plane.cc b/libsrc/src/dconvert/support/plane.cc
new file mode 100644
index 0000000..2f3b6ee
--- /dev/null
+++ b/libsrc/src/dconvert/support/plane.cc
@@ -0,0 +1,253 @@
+static const char *CopyrightIdentifier(void) { return "@(#)plane.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "plane.h"
+
+AbstractImagePlane::AbstractImagePlane(
+	ImagePlanePlane plane,double hfov,double vfov)
+{
+#ifdef DEBUGPLANE
+	cerr << "AbstractImagePlane::AbstractImagePlane() start" << endl;
+#endif
+	Point3D  o(0,0,0); center=o;
+	double dh=hfov/2;
+	double dv=vfov/2;
+	switch (plane) {
+		case Axial:
+		case AxialLP:
+			// Conventional - viewed "bottom up"
+		{
+			Point3D  b(-dh,-dv, 0); tlhc=b;
+			Vector3D r( 1,  0,  0); rowvec=r;
+			Vector3D c( 0,  1,  0); colvec=c;
+			break;
+		}
+		case AxialRP:
+			// Old EMI style - viewed "top down"
+		{
+			Point3D  b( dh,-dv, 0); tlhc=b;
+			Vector3D r(-1,  0,  0);  rowvec=r;
+			Vector3D c( 0,  1,  0);  colvec=c;
+			break;
+		}
+		case Sagittal:
+		case SagittalPF:
+			// Conventional MRI viewed "from left"
+		{
+			Point3D  b( 0,-dh, dv); tlhc=b;
+			Vector3D r( 0,  1,  0);  rowvec=r;
+			Vector3D c( 0,  0, -1);  colvec=c;
+			break;
+		}
+		case SagittalIP:
+			// Conventional CT Lateral Scout
+		{
+			Point3D  b( 0,-dh, dv); tlhc=b;
+			Vector3D r( 0,  0, -1);  rowvec=r;
+			Vector3D c( 0,  1,  0);  colvec=c;
+			break;
+		}
+		case Coronal:
+		case CoronalLI:
+			// Conventional MRI viewed "from front"
+			// Conventional CT AP Scout
+		{
+			Point3D  b(-dh, 0, dv); tlhc=b;
+			Vector3D r( 1,  0,  0); rowvec=r;
+			Vector3D c( 0,  0, -1); colvec=c;
+			break;
+		}
+	}
+#ifdef DEBUGPLANE
+	cerr << "AbstractImagePlane::constructed this:" << endl;
+	put(cerr);
+#endif
+}
+
+#ifdef DEBUGPLANE
+void
+AbstractImagePlane::put(ostream &ostr)
+{
+	ostr << "AbstractImagePlane::put()" << endl;
+	ostr << "\tcenter" << endl;
+	center.put(ostr);
+	ostr << "\ttlhc" << endl;
+	tlhc.put(ostr);
+	ostr << "\trowvec" << endl;
+	rowvec.put(ostr);
+	ostr << "\tcolvec" << endl;
+	colvec.put(ostr);
+}
+#endif
+
+#ifdef DEBUGPLANE
+void
+DerivedImagePlane::put(ostream &ostr)
+{
+	ostr << "DerivedImagePlane::put()" << endl;
+	ostr << "\trotation" << endl;
+	rotation.put(ostr);
+	ostr << "\tunrotation" << endl;
+	unrotation.put(ostr);
+}
+#endif
+
+#ifdef DEBUGPLANE
+void
+PatientPlane::put(ostream &ostr)
+{
+	ostr << "PatientPlane::put()" << endl;
+	DerivedImagePlane::put(ostr);
+}
+#endif
+
+#ifdef DEBUGPLANE
+void
+MachinePlane::put(ostream &ostr)
+{
+	ostr << "MachinePlane::put()" << endl;
+	DerivedImagePlane::put(ostr);
+}
+#endif
+
+#ifdef DEBUGPLANE
+void
+ImagePlane::put(ostream &ostr)
+{
+	ostr << "ImagePlane::put()" << endl;
+	AbstractImagePlane::put(ostr);
+	MachinePlane::put(ostr);
+	PatientPlane::put(ostr);
+}
+#endif
+
+char *
+DerivedImagePlane::getOrientation(Vector3D vector)
+{
+	char *orientation=new char[4];
+	char *optr = orientation;
+	*optr='\0';
+
+	char orientationX = vector.getX() < 0 ? 'R' : 'L';
+	char orientationY = vector.getY() < 0 ? 'A' : 'P';
+	char orientationZ = vector.getZ() < 0 ? 'F' : 'H';
+
+	double absX = fabs(vector.getX());
+	double absY = fabs(vector.getY());
+	double absZ = fabs(vector.getZ());
+
+	int i;
+	for (i=0; i<3; ++i) {
+		if (absX>.0001 && absX>absY && absX>absZ) {
+			*optr++=orientationX;
+			absX=0;
+		}
+		else if (absY>.0001 && absY>absX && absY>absZ) {
+			*optr++=orientationY;
+			absY=0;
+		}
+		else if (absZ>.0001 && absZ>absX && absZ>absY) {
+			*optr++=orientationZ;
+			absZ=0;
+		}
+		else break;
+		*optr='\0';
+	}
+	return orientation;
+}
+
+DerivedImagePlane::DerivedImagePlane(
+	ImagePlaneHeadFeet hfff,ImagePlanePosition posn)
+{
+#ifdef DEBUGPLANE
+	cerr << "DerivedImagePlane::DerivedImagePlane(hfff,posn) start" << endl;
+#endif
+	switch(hfff) {
+		case HeadFirst:
+			break;
+		case FeetFirst:
+		{
+			Rotation3D r(Y,180);
+			rotation*=r;
+			Rotation3D unr(Y,-180);
+			unrotation*=unr;
+			break;
+		}
+	}
+
+	switch(posn) {
+		case Supine:
+			break;
+		case Prone:
+		{
+			Rotation3D r(Z,180);
+			rotation*=r;
+			Rotation3D unr(Z,-180);
+			unrotation*=unr;
+			break;
+		}
+		case LeftLateralDecubitus:
+		{
+			Rotation3D r(Z,90);
+			rotation*=r;
+			Rotation3D unr(Z,-90);
+			unrotation*=unr;
+			break;
+		}
+		case RightLateralDecubitus:
+		{
+			Rotation3D r(Z,-90);
+			rotation*=r;
+			Rotation3D unr(Z,90);
+			unrotation*=unr;
+			break;
+		}
+	}
+#ifdef DEBUGPLANE
+	cerr << "DerivedImagePlane::constructed this:" << endl;
+	put(cerr);
+#endif
+}
+
+void
+DerivedImagePlane::setCorners(Point3D tlhc,Vector3D row,Vector3D col)
+{
+	_set_tlhc(tlhc*unrotation);
+	_set_rowvec((row*unrotation)/row.magnitude());
+	_set_colvec((col*unrotation)/col.magnitude());
+	_set_center((tlhc+row/2+col/2)*unrotation);
+}
+
+void
+DerivedImagePlane::angle(ImagePlaneAxis axis,double angle)
+{
+	Index3D plane;
+	switch(axis) {
+		case LeftRight:		plane=X; break;
+		case AnteriorPosterior:	plane=Y; break;
+		case HeadFeet:		plane=Z; break;
+	}
+	Rotation3D r(plane,angle);
+	Rotation3D br=r*unrotation;
+
+	_rotate_tlhc(br);
+	_rotate_center(br);
+	_rotate_rowvec(br);
+	_rotate_colvec(br);
+}
+
+void
+DerivedImagePlane::shift(Vector3D shift)
+{
+	_shift_center(shift*unrotation);
+	_shift_tlhc(shift*unrotation);
+}
+
+void
+DerivedImagePlane::scale(double factor)
+{
+	Point3D origin(0,0,0);
+	Vector3D shift = origin - _get_center();
+	_shift_tlhc(shift);
+	_scale_tlhc(factor);
+	_shift_tlhc(-shift);
+}
+
diff --git a/libsrc/src/dconvert/support/planea.cc b/libsrc/src/dconvert/support/planea.cc
new file mode 100644
index 0000000..06bfec1
--- /dev/null
+++ b/libsrc/src/dconvert/support/planea.cc
@@ -0,0 +1,50 @@
+static const char *CopyrightIdentifier(void) { return "@(#)planea.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrlist.h"
+#include "elmconst.h"
+#include "planea.h"
+#include "strtype.h"
+
+void
+ImagePlaneLister::addPlaneToList(AttributeList& list)
+{
+	// PatientPosition
+	// ImagePositionPatient
+	// ImageOrientationPatient
+	// ImagePosition
+	// ImageOrientation
+	// PatientOrientation
+
+	Assert(plane);
+
+	list+=new DecimalStringAttribute(TagFromName(ImagePositionPatient),
+		plane->PatientPlane::getTLHC().getX(),
+		plane->PatientPlane::getTLHC().getY(),
+		plane->PatientPlane::getTLHC().getZ());
+
+	list+=new DecimalStringAttribute(TagFromName(ImageOrientationPatient),
+		plane->PatientPlane::getRowVector().getX(),
+		plane->PatientPlane::getRowVector().getY(),
+		plane->PatientPlane::getRowVector().getZ(),
+		plane->PatientPlane::getColVector().getX(),
+		plane->PatientPlane::getColVector().getY(),
+		plane->PatientPlane::getColVector().getZ());
+
+	list+=new DecimalStringAttribute(TagFromName(ImagePosition),
+		plane->MachinePlane::getTLHC().getX(),
+		plane->MachinePlane::getTLHC().getY(),
+		plane->MachinePlane::getTLHC().getZ());
+
+	list+=new DecimalStringAttribute(TagFromName(ImageOrientation),
+		plane->MachinePlane::getRowVector().getX(),
+		plane->MachinePlane::getRowVector().getY(),
+		plane->MachinePlane::getRowVector().getZ(),
+		plane->MachinePlane::getColVector().getX(),
+		plane->MachinePlane::getColVector().getY(),
+		plane->MachinePlane::getColVector().getZ());
+
+	list+=new CodeStringAttribute(TagFromName(PatientOrientation),
+		String_Use(plane->PatientPlane::getRowOrientation()),
+		String_Use(plane->PatientPlane::getColOrientation()));
+}
+
diff --git a/libsrc/src/dconvert/xxxx/Imakefile b/libsrc/src/dconvert/xxxx/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/src/dconvert/xxxx/Imakefile.tmpl b/libsrc/src/dconvert/xxxx/Imakefile.tmpl
new file mode 100755
index 0000000..991b534
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/Imakefile.tmpl
@@ -0,0 +1,30 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCONVERTEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = xxxxdc.cc xxxxconv.cc xxxxmpln.cc \
+		 xxxxmmsc.cc xxxxmdt.cc \
+		 xxxxdmp.cc xxxxdmpf.cc \
+		 xxxxhdrc.cc xxxx.cc
+
+OBJS = 		 xxxxdc.o  xxxxconv.o  xxxxmpln.o  \
+		 xxxxmmsc.o  xxxxmdt.o  \
+		 xxxxdmp.o  xxxxdmpf.o  \
+		 xxxxhdrc.o  xxxx.o
+
+LibraryTarget($(PROJECTLIBDIR)/libdxxxx.a,$(OBJS))
+
+ProjectInstallOnMakeUpdatedLibraryHeader(xxxx,dconvert)
+
+ProjectConvertTemplate(xxxxhdrp.h,xxxx,convert,prefix=XXXX_ role=headerpart)
+ProjectConvertTemplate(xxxxhdrw.h,xxxx,convert,prefix=XXXX_ role=wholeheader)
+ProjectConvertTemplate(xxxxhdrc.h,xxxx,convert,prefix=XXXX_ role=constructheader)
+ProjectConvertTemplate(xxxxconv.h,xxxx,convert,prefix=XXXX_ role=dicom)
+ProjectConvertTemplate(xxxxdmpf.h,xxxx,convert,prefix=XXXX_ role=dump)
+
+xxxxdmpf.o: xxxxdmpf.cc
+	$(CCC) -c $(CPLUSPLUS_UNOPTIMIZEDFLAGS) $(CPLUSPLUS_OPTIONS) \
+		  $(CPLUSPLUS_ALLDEFINES) xxxxdmpf.cc
+
+DependCCTarget()
+
diff --git a/libsrc/src/dconvert/xxxx/README b/libsrc/src/dconvert/xxxx/README
new file mode 100755
index 0000000..80fad0d
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/README
@@ -0,0 +1,159 @@
+The file that describes the public interface:
+
+	"xxxx.h"
+		class XXXX_Conversion {
+			XXXX_Conversion(istream &i,ostream &e);
+			virtual ~XXXX_Conversion();
+			bool dump(ostream &out);
+			bool convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+			bool convertHeader(AttributeList *list);
+			bool convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		};
+
+	NB. The Imakefile is set up to install this file in the main include area
+	whenever on a "make".
+
+Files that are usually left alone (the "glue" between headers, classes, etc.):
+
+	"xxxx.cc"
+
+		XXXX_Conversion::XXXX_Conversion(istream &i,ostream &e);
+		XXXX_Conversion::~XXXX_Conversion();
+
+	"xxxxcl.h"
+
+		class XXXX_Header_BothClass  : public XXXX_HeaderClass
+		{
+		public:
+			XXXX_Header_BothClass(istream *ist) : XXXX_HeaderClass(ist) {}
+			void Dump(TextOutputStream *log);
+			void ToDicom_Template   (AttributeList *list);
+			void ToDicom_ManualMisc (AttributeList *list);
+			void ToDicom_ManualPlane(AttributeList *list);
+			void ToDicom_ManualDates(AttributeList *list);
+		};
+
+	"xxxxconv.cc"
+
+		#include "xxxxconv.h"
+
+	"xxxxdc.c"
+
+		bool XXXX_Conversion::convertHeader(AttributeList *list);
+		bool XXXX_Conversion::convertPixelData(AttributeList *list,TransferSyntax *transfersyntax);
+		bool XXXX_Conversion::convertAll(AttributeList *list,TransferSyntax *transfersyntax);
+
+	"xxxxdc.h"
+
+	"xxxxdmp.cc"
+
+		bool XXXX_Conversion::dump(ostream &o);
+
+	"xxxxdmp.h"
+
+	"xxxxhdrc.cc"
+
+		#include "xxxxhdrc.h"
+
+Files that definitely need to be tailored for each format:
+
+	"xxxx.tpl"
+
+		The template "describing" the format for header generation
+
+	"xxxxmdt.cc"
+
+		void XXXX_Header_BothClass::ToDicom_ManualDates(AttributeList *list);
+
+	"xxxxmmsc.cc"
+
+		void XXXX_Header_BothClass::ToDicom_ManualMisc(AttributeList *list);
+
+	"xxxxmpln.cc"
+
+		void XXXX_Header_BothClass::ToDicom_ManualPlane(AttributeList *list);
+
+	"xxxxptrs.h"
+
+		define offsets, pointers and values, both fixed, and dependent on previous fields
+
+	"xxxxsrc.h"
+
+		class XXXX_PixelDataSource : public SourceBase<Uint16> {
+		public:
+			XXXX_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c) : SourceBase<Uint16>();
+			~XXXX_PixelDataSource();
+			size_t read(void);
+			const Uint16 *getBuffer(void);
+			size_t getBufferCount(void) const;
+			int good(void) const;
+		};
+
+Files that are automatically generated from xxxx.tpl:
+
+	"xxxxhdrp.h"
+
+		generated with role=headerpart
+
+		contains the detailed description of each format header
+		block class, eg.
+
+		class XXXX_HeaderClass_HDR1 {
+		public:
+			XXXX_HeaderClass_HDR1(istream *ist,size_t offset)
+		 		{ ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }
+
+			Uint16_L 	FHENTRIES	; // at 0
+			Uint16_L 	FHCOUNT		; // at 2
+			...
+		};
+
+	"xxxxhdrw.h"
+
+		generated with role=wholeheader
+
+		contains the declaration of the top level class that contains instances
+		classes for each block of the header, eg.
+
+		class XXXX_HeaderClass
+		{
+		public:
+			XXXX_HeaderClass(istream *ist);
+
+			XXXX_HeaderClass_HDR1 *XXXX_HeaderInstance_HDR1;
+			XXXX_HeaderClass_HDR2 *XXXX_HeaderInstance_HDR2;
+			...
+		};
+
+
+	"xxxxhdrc.h"
+
+		generated with role=constructheader
+
+		contains the constructor for the top level class that instantiates
+		classes for each block of the header
+
+		XXXX_HeaderClass::XXXX_HeaderClass(istream *ist);
+
+	"xxxxconv.h"
+
+		generated with role=dicom
+
+		contains the code to generate DICOM attributes
+
+		void XXXX_Header_BothClass::ToDicom_Template(AttributeList *list);
+
+	"xxxxdmpf.h"
+		generated with role=dump
+
+		contains the code to dump a describtion of the file header content
+
+		void XXXX_Header_BothClass::Dump(TextOutputStream *log);
+
+Places to put special handling code:
+
+	if you need an "extra" header file for miscellaneous stuff, use "xxxxhdrm.h".
+
+	if you have special purpose code, then "xxxxhdrc.cc" is a good place to put
+	it, as normally all this file does is instantiate the "xxxxhdrc.h", but it
+	is always going to get loaded in any application using this library.
diff --git a/libsrc/src/dconvert/xxxx/replacexxxxwithinfiles.sh b/libsrc/src/dconvert/xxxx/replacexxxxwithinfiles.sh
new file mode 100755
index 0000000..32fa404
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/replacexxxxwithinfiles.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Usage: find . -name '*.h'   -exec ./replacexxxxwithinfiles.sh '{}' ';'
+# Usage: find . -name '*.cc'  -exec ./replacexxxxwithinfiles.sh '{}' ';'
+# Usage: find . -name '*.tpl' -exec ./replacexxxxwithinfiles.sh '{}' ';'
+# Usage: find . -name 'Imakefile' -exec ./replacexxxxwithinfiles.sh '{}' ';'
+#
+# (using -o in same find fails to exec)
+
+filename="${1}"
+backupfilename="${filename}.bak"
+
+rm -f "${backupfilename}"
+mv "${filename}" "${backupfilename}"
+
+sed -e 's/xxxx/yyyy/g' -e 's/XXXX/YYYY/g' <"${backupfilename}" >"${filename}"
+
+rm "${backupfilename}"
diff --git a/libsrc/src/dconvert/xxxx/xxxx.cc b/libsrc/src/dconvert/xxxx/xxxx.cc
new file mode 100644
index 0000000..85cad23
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxx.cc
@@ -0,0 +1,28 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxx.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "bnstream.h"
+#include "txstream.h"
+#include "xxxx.h"
+#include "xxxxcl.h"
+#include "srcsink.h"
+#include "xxxxsrc.h"
+
+XXXX_Conversion::XXXX_Conversion(istream &i,ostream &e)
+{
+	in=new BinaryInputStream(i,BigEndian);
+	err=new TextOutputStream(e);
+	xxxxhdr=0;
+	pixeldatasrc=0;
+}
+
+XXXX_Conversion::~XXXX_Conversion()
+{
+	Assert(in);
+	if (in) delete in;
+	Assert(err);
+	if (err) delete err;
+
+	if (xxxxhdr) delete xxxxhdr;
+	if (pixeldatasrc) delete pixeldatasrc;
+}
+
diff --git a/libsrc/src/dconvert/xxxx/xxxx.h b/libsrc/src/dconvert/xxxx/xxxx.h
new file mode 100644
index 0000000..14bc0c7
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxx.h
@@ -0,0 +1,46 @@
+/* xxxx.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_xxxx__
+#define __Header_xxxx__
+
+// NB. a XXXX_Conversion object MUST NOT GO OUT OF SCOPE before
+// the AttributeList is finished with, otherwise the pixeldatasrc
+// will be deleted by ~XXXX_Conversion() and the pointer in
+// OtherUnspecifiedLargeAttribute will be invalid 
+
+class XXXX_Header_BothClass;
+class XXXX_PixelDataSource;
+class AttributeList;
+class TransferSyntax;
+
+class XXXX_Conversion {
+	XXXX_Header_BothClass *xxxxhdr;
+	BinaryInputStream *in;
+	TextOutputStream *err;
+	XXXX_PixelDataSource *pixeldatasrc;
+public:
+	XXXX_Conversion(istream &i,ostream &e);
+
+	virtual ~XXXX_Conversion();
+
+	bool dumpCommon(ostream &out);
+
+	bool dumpSelectedImage(ostream &out,unsigned imagenumber=0)
+		{
+			(void)out; (void)imagenumber;
+			return true;
+		}
+
+
+	bool convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+
+	bool convertHeader(AttributeList *list,unsigned imagenumber=0);
+
+	bool convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber=0);
+};
+
+#endif /* __Header_xxxx__ */
+
diff --git a/libsrc/src/dconvert/xxxx/xxxx.tpl b/libsrc/src/dconvert/xxxx/xxxx.tpl
new file mode 100755
index 0000000..cf2979a
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxx.tpl
@@ -0,0 +1,25 @@
+# Offsets are in bytes from 0
+# Lengths are in intype units
+
+block="STDHDR"	offset="0"	intype="String"	inlength="4"	keyword="?"	dicomtype="?"	dicomtag="?"			# comment
+block="STDHDR"	offset="66"	intype="String"	inlength="2"	keyword="?"	dicomtype="?"	dicomtag="?"	enum="'SP'=Supine,'PR'=Prone"	# comment
+
+block="STDHDR"	offset="116"	intype="String_Date_YMD"	inlength="10"	keyword="?"	dicomtype="?"	dicomtag="?"	# yyyy/mm/dd
+block="STDHDR"	offset="126"	intype="String_Time"		inlength="12"	keyword="?"	dicomtype="?"	dicomtag="?"	# hh/mm/ss.xxx
+block="STDHDR"	offset="210"	intype="Time_Milliseconds_B"	inlength="1"	keyword="?"	dicomtype="?"	dicomtag="?"	# 
+
+block="STDHDR"	offset="306"	intype="Uint8"		inlength="1"	keyword="?"	dicomtype="?"	dicomtag="?"	enum="1=X,2=Y"	# 
+block="STDHDR"	offset="380"	intype="Uint16_B"	inlength="1"	keyword="?"	dicomtype="?"	dicomtag="?"	bitmap="0:N,X;1:N,Y"	# 
+block="STDHDR"	offset="382"	intype="Uint32_B"	inlength="1"	keyword="?"	dicomtype="?"	dicomtag="?"		# 
+
+block="IMGHDR"	offset="84"	intype="IEEE_Float32_B"	inlength="1"	keyword="?"	dicomtype="?"	dicomtag="?"		# 
+
+block="IMGHDR"	offset="112"	intype="String"			inlength="4"	keyword="?"	dicomtype="DS"	dicomtag="SliceThickness"	# 
+block="IMGHDR2"	offset="4"	intype="Time_Milliseconds_B"	inlength="1"	keyword="?"	dicomtype="TM"	dicomtag="TimeOfLastCalibration"	# 
+block="IMGHDR2"	offset="96"	intype="Uint16_B"		inlength="1"	keyword="?"	dicomtype="US"	dicomtag="Columns"	# 
+
+constant="0" 		dicomtype="US"	dicomtag="PixelPaddingValue"		# 
+constant="MONOCHROME2" 	dicomtype="CS"	dicomtag="PhotometricInterpretation"	# 
+constant="0" 		dicomtype="DS"	dicomtag="RescaleIntercept"		# 
+constant="" 		dicomtype="PN"	dicomtag="ReferringPhysicianName"	# 
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxcl.h b/libsrc/src/dconvert/xxxx/xxxxcl.h
new file mode 100644
index 0000000..9f56981
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxcl.h
@@ -0,0 +1,25 @@
+/* xxxxcl.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "ptyhdr.h"
+#include "xxxxhdrp.h"
+#include "xxxxhdrw.h"
+
+class TextOutputStream;
+class AttributeList;
+
+class XXXX_Header_BothClass : public XXXX_HeaderClass
+{
+public:
+	XXXX_Header_BothClass(istream *ist) : XXXX_HeaderClass(ist) {}
+
+	void DumpCommon(TextOutputStream *log);
+	void DumpSelectedImage(TextOutputStream *log,unsigned imagenumber=0)
+		{
+			(void)log; (void)imagenumber;
+		}
+
+	void ToDicom_Template   (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualMisc (AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber=0);
+	void ToDicom_ManualDates(AttributeList *list,unsigned imagenumber=0);
+};
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxconv.cc b/libsrc/src/dconvert/xxxx/xxxxconv.cc
new file mode 100644
index 0000000..5e75afb
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxconv.cc
@@ -0,0 +1,5 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxconv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmconst.h"
+#include "xxxxdc.h"
+#include "xxxxptrs.h"
+#include "xxxxconv.h"
diff --git a/libsrc/src/dconvert/xxxx/xxxxdc.cc b/libsrc/src/dconvert/xxxx/xxxxdc.cc
new file mode 100644
index 0000000..9985d5e
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxdc.cc
@@ -0,0 +1,90 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxdc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "xxxxdc.h"
+#include "xxxx.h"
+
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "elmconst.h"
+
+#include "xxxxsrc.h"
+
+bool
+XXXX_Conversion::convertHeader(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(in);
+	if (!xxxxhdr) xxxxhdr=new XXXX_Header_BothClass(in);
+	Assert(xxxxhdr);
+
+	xxxxhdr->ToDicom_Template(list);
+	xxxxhdr->ToDicom_ManualMisc(list);
+	xxxxhdr->ToDicom_ManualPlane(list);
+	xxxxhdr->ToDicom_ManualDates(list);
+
+	return true;
+}
+
+// See comments in xxxx.h about the importance of the scope
+// of a XXXX_Conversion object and AttributeList object
+
+bool
+XXXX_Conversion::convertPixelData(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+	Assert(list);
+	Assert(transfersyntax);
+	Assert(in);
+	if (!xxxxhdr) xxxxhdr=new XXXX_Header_BothClass(in);
+	Assert(xxxxhdr);
+
+	Uint16 bitsAllocated=
+		AttributeValue((*list)[TagFromName(BitsAllocated)],16);
+	Uint16 bitsStored=
+		AttributeValue((*list)[TagFromName(BitsStored)],bitsAllocated);
+	Uint16 highBit=
+		AttributeValue((*list)[TagFromName(HighBit)],bitsStored-1u);
+	Uint16 rows=
+		AttributeValue((*list)[TagFromName(Rows)]);
+	Uint16 cols=
+		AttributeValue((*list)[TagFromName(Columns)]);
+
+	Assert(rows);
+	Assert(cols);
+
+	Assert(pixeldatasrc==0);
+
+	pixeldatasrc=new XXXX_PixelDataSource(
+		*in,
+		XXXX_Offset_PixelData_ptr,
+		rows,
+		cols);
+
+	Assert(pixeldatasrc);
+
+	(*list)+=new OtherUnspecifiedLargeAttribute(
+		TagFromName(PixelData),
+		pixeldatasrc,
+		rows,
+		cols,
+		1, // frame
+		1, // samples per pixel
+		transfersyntax,
+		0,bitsAllocated,bitsStored,highBit);
+
+	return true;
+}
+
+bool
+XXXX_Conversion::convertAll(AttributeList *list,
+			TransferSyntax *transfersyntax,
+			unsigned imagenumber)
+{
+	if (!convertHeader(list,imagenumber)) return false;
+	if (!convertPixelData(list,transfersyntax,imagenumber)) return false;
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxdc.h b/libsrc/src/dconvert/xxxx/xxxxdc.h
new file mode 100644
index 0000000..e059734
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxdc.h
@@ -0,0 +1,7 @@
+/* xxxxdc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "xxxxcl.h"
+
+#include "attrtype.h"
+#include "attrlist.h"
+
+#include "xxxxptrs.h"
diff --git a/libsrc/src/dconvert/xxxx/xxxxdmp.cc b/libsrc/src/dconvert/xxxx/xxxxdmp.cc
new file mode 100644
index 0000000..cd5a459
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxdmp.cc
@@ -0,0 +1,37 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxdmp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "xxxxdmp.h"
+
+#include "bnstream.h"
+#include "transyn.h"
+
+#include "xxxx.h"
+
+bool
+XXXX_Conversion::dumpCommon(ostream &o)
+{
+	Assert(in);
+	if (!xxxxhdr) xxxxhdr=new XXXX_Header_BothClass(in);
+	Assert(xxxxhdr);
+
+	TextOutputStream out(o);
+
+	xxxxhdr->DumpCommon(&out);
+
+	return true;
+}
+
+
+bool
+XXXX_Conversion::dumpSelectedImage(ostream &o,unsigned imagenumber)
+{
+	Assert(in);
+	if (!xxxxhdr) xxxxhdr=new XXXX_Header_BothClass(in);
+	Assert(xxxxhdr);
+
+	TextOutputStream out(o);
+
+	xxxxhdr->DumpSelectedImage(&out,imagenumber);
+
+	return true;
+}
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxdmp.h b/libsrc/src/dconvert/xxxx/xxxxdmp.h
new file mode 100644
index 0000000..03e24a5
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxdmp.h
@@ -0,0 +1,4 @@
+/* xxxxdmp.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#include "xxxxcl.h"
+
+#include "txstream.h"
diff --git a/libsrc/src/dconvert/xxxx/xxxxdmpf.cc b/libsrc/src/dconvert/xxxx/xxxxdmpf.cc
new file mode 100644
index 0000000..808e54b
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxdmpf.cc
@@ -0,0 +1,4 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxdmpf.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "xxxxdmp.h"
+#include "xxxxptrs.h"
+#include "xxxxdmpf.h"
diff --git a/libsrc/src/dconvert/xxxx/xxxxhdrc.cc b/libsrc/src/dconvert/xxxx/xxxxhdrc.cc
new file mode 100644
index 0000000..e3034a9
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxhdrc.cc
@@ -0,0 +1,7 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxhdrc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ptyhdr.h"
+#include "xxxxptrs.h"
+#include "xxxxhdrp.h"
+#include "xxxxhdrw.h"
+#include "xxxxhdrc.h"
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxmdt.cc b/libsrc/src/dconvert/xxxx/xxxxmdt.cc
new file mode 100644
index 0000000..991077c
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxmdt.cc
@@ -0,0 +1,51 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxmdt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "xxxxdc.h"
+#include "elmconst.h"
+
+void 
+XXXX_Header_BothClass::ToDicom_ManualDates(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	{
+		// PatientAge
+
+		// Xxxx is yyy;mm
+		unsigned yyy=atoi(String_Use(XXXX_HeaderInstance_STDHDR->SAGE));
+		unsigned mm =atoi((const char *)(String_Use(XXXX_HeaderInstance_STDHDR->SAGE))+4);
+
+		ostrstream ost;
+		if (yyy)
+			ost << setw(3) << setfill('0')
+			    << yyy << 'Y' << ends;	// blow off months
+		else
+			ost << setw(3) << setfill('0')
+			    << mm  << 'M' << ends;	// a baby presumably
+
+		char *agestr=ost.str();
+		(*list)+=new AgeStringAttribute(TagFromName(PatientAge),agestr);
+		if (agestr) delete[] agestr;
+	}
+
+	// StudyDate
+
+	(*list)+=new DateStringAttribute(TagFromName(StudyDate),
+		Date(String_Use(XXXX_HeaderInstance_STDHDR->SDATE)));
+
+	// StudyTime
+
+	(*list)+=new TimeStringAttribute(TagFromName(StudyTime),
+		Time(String_Use(XXXX_HeaderInstance_STDHDR->STIME)));
+
+	// ContentDate (formerly Image)
+
+	(*list)+=new DateStringAttribute(TagFromName(ContentDate),
+		Date(String_Use(XXXX_HeaderInstance_IMGHDR->IDATE)));
+
+	// ContentTime (formerly Image)
+
+	(*list)+=new TimeStringAttribute(TagFromName(ContentTime),
+		Time(String_Use(XXXX_HeaderInstance_STDHDR->STIME)));
+
+}
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxmmsc.cc b/libsrc/src/dconvert/xxxx/xxxxmmsc.cc
new file mode 100644
index 0000000..23cb415
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxmmsc.cc
@@ -0,0 +1,199 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxmmsc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "xxxxdc.h"
+#include "elmconst.h"
+
+void 
+XXXX_Header_BothClass::ToDicom_ManualMisc(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Modality
+
+	switch (XXXX_HeaderInstance_STDHDR->SMODELNO_Mod) {
+		case 1:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"CT");
+			break;
+		case 2:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"MR");
+			break;
+		default:
+			(*list)+=new CodeStringAttribute(TagFromName(Modality),"SC");
+			break;
+	}
+
+	// ImageType
+
+	char *value1,*value2,*value3;
+
+	value1="ORIGINAL";
+
+	// P is prospective, R is retrospective ...
+
+	value2=strncmp(XXXX_HeaderInstance_IMGHDR2->ITCTYPE,"P",1) == 0
+		? "PRIMARY" : "SECONDARY";
+
+	value3=strncmp(XXXX_HeaderInstance_IMGHDR->IMTYPE,"AX",2) == 0
+		? "AXIAL" : "LOCALIZER";
+
+	(*list)+=new CodeStringAttribute(TagFromName(ImageType),
+		value1,value2,value3);
+
+	// ContrastBolus Module
+
+	if (strncmp(XXXX_HeaderInstance_IMGHDR->IENHANCE,"+C",2) == 0) {
+
+		// ContrastBolusAgent ="Contrast"
+		// ContrastBolusStartTime
+
+		(*list)+=new LongStringAttribute(TagFromName(ContrastBolusAgent),
+			"Contrast");
+
+		(*list)+=new TimeStringAttribute(TagFromName(ContrastBolusStartTime),
+			Time(String_Use(XXXX_HeaderInstance_IMGHDR->ICETIME)));
+	}
+
+	// GeneratorPower
+
+	// Loose fractional part ...
+
+	(*list)+=new IntegerStringAttribute(TagFromName(GeneratorPower),
+		(unsigned short)(atof(XXXX_HeaderInstance_IMGHDR->IGENPOW)));
+
+	{
+		// SoftwareVersion 
+
+		ostrstream ost;
+		ost << "System "    << XXXX_HeaderInstance_STDHDR->SSYSVNO
+		    << "."          << XXXX_HeaderInstance_STDHDR->SSYSRNO
+		    << " Database " << XXXX_HeaderInstance_STDHDR->SDATVNO
+		    << "."          << XXXX_HeaderInstance_STDHDR->SDATRNO
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new LongStringAttribute(TagFromName(SoftwareVersion),str);
+		if (str) delete[] str;
+	}
+	{
+		// StationName 
+
+		ostrstream ost;
+		ost << XXXX_HeaderInstance_STDHDR->SMODELNO_Mod << "."
+		    << XXXX_HeaderInstance_STDHDR->SMODELNO_Mac << "."
+		    << XXXX_HeaderInstance_STDHDR->SMACHINE
+		    << ends;
+
+		char *str=ost.str();
+
+		(*list)+=new ShortStringAttribute(TagFromName(StationName),str);
+		if (str) delete[] str;
+	}
+
+	// Do the descriptions ...
+
+	class Description {
+		ostrstream ost;
+		int first;
+		char delim;
+	public:
+		Description(char d=0)	{ first=1; delim=d; }
+
+		void add(const char *desc,unsigned maxlength)
+			{
+				char *buf = new char[maxlength+1];
+				strncpy(buf,desc,maxlength); buf[maxlength]=0;
+				char *lastsxxxx=strrchr(buf,' ');
+				if (lastsxxxx && buf[maxlength-1] == ' ')
+					*lastsxxxx=0;
+				char *start = buf;
+				while (*start && *start == ' ') ++start;
+				if (*start) {
+					if (!first && delim) ost << delim;
+					ost << start;
+				}
+				first=0;
+				if (buf) delete[] buf;
+			}
+
+		char *get(void)		{ ost << ends; return ost.str(); }
+	};
+
+	{
+		// StudyDescription
+
+		Description desc(' ');
+		desc.add(XXXX_HeaderInstance_STDHDR->SDESC1,50);
+		desc.add(XXXX_HeaderInstance_STDHDR->SDESC2,50);
+		desc.add(XXXX_HeaderInstance_STDHDR->SDESC3,50);
+		desc.add(XXXX_HeaderInstance_STDHDR->SDESC4,50);
+		desc.add(XXXX_HeaderInstance_STDHDR->SDESC5,50);
+
+		char *str=desc.get();
+		unsigned length=strlen(str);
+		if (length > 64) {
+			str[64]=0;
+			length=64;
+		}
+
+		(*list)+=new LongStringAttribute(TagFromName(StudyDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// SeriesDescription
+
+		Description desc(' ');
+		desc.add(XXXX_HeaderInstance_IMGHDR2->ISRDESC1,16);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->ISRDESC2,14);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->ISRDESC3,12);
+
+		char *str=desc.get();
+
+		(*list)+=new LongStringAttribute(TagFromName(SeriesDescription),str);
+		if (str) delete[] str;
+	}
+	{
+		// ImageComments
+
+		Description desc(' ');
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IIMDESC1,10);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IIMDESC2,8);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IIMDESC3,7);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(ImageComments),str);
+		if (str) delete[] str;
+	}
+	{
+		// AdditionalPatientHistory
+
+		Description desc(' ');
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC1,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC2,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC3,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC4,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC5,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC6,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC7,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC8,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC9,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC10,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC11,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC12,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC13,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC14,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC15,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC16,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC17,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC18,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC19,17);
+		desc.add(XXXX_HeaderInstance_IMGHDR2->IEXDESC20,17);
+
+		char *str=desc.get();
+
+		(*list)+=new LongTextAttribute(TagFromName(AdditionalPatientHistory),str);
+		if (str) delete[] str;
+	}
+
+}
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxmpln.cc b/libsrc/src/dconvert/xxxx/xxxxmpln.cc
new file mode 100644
index 0000000..675211f
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxmpln.cc
@@ -0,0 +1,323 @@
+static const char *CopyrightIdentifier(void) { return "@(#)xxxxmpln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "xxxxdc.h"
+#include "elmconst.h"
+#include "planea.h"
+
+void 
+XXXX_Header_BothClass::ToDicom_ManualPlane(AttributeList *list,unsigned imagenumber)
+{
+	Assert(imagenumber==0);
+
+	// Trying to derive Image Plane Module ...
+
+	char *hfff,*ap;
+
+	ImagePlanePlane plane;
+
+	// Determine the "machine" plane of the image ...
+
+	// (Doesn't handle scout azimuth yet)
+	// Same for CT and MR (CT seems to set IMTYPE "AX  ")
+	switch (((char *)(XXXX_HeaderInstance_IMGHDR->IPLANE))[0]) {
+		case 'A':	// "AX  "
+			plane=Axial;
+			break;
+		case 'S':	// "SAG "
+			plane=Sagittal;
+			break;
+		case 'C':	// "COR "
+			plane=Coronal;
+			break;
+		default:	// Yuck - just in case :(
+			plane=Axial;
+			break;
+	}
+
+	ImagePlaneHeadFeet orientation;
+
+	switch (((char *)(XXXX_HeaderInstance_IMGHDR->IHFFIRST))[0]) {
+		case 'H':
+			hfff="HF";
+			orientation=HeadFirst;
+			break;
+		case 'F':
+			hfff="FF";
+			orientation=FeetFirst;
+			break;
+		default:
+			hfff="";		// :(
+			orientation=HeadFirst;
+			break;
+	}
+
+	ImagePlanePosition position;
+
+	switch (((char *)(XXXX_HeaderInstance_IMGHDR->IPATORI))[0]) {
+		case 'P':
+			ap="P";
+			position=Prone;
+			break;
+		case 'S':
+			ap="S";
+			position=Supine;
+			break;
+		case 'L':
+			ap="DL";
+			position=LeftLateralDecubitus;
+			break;
+		case 'R':
+			ap="DR";
+			position=RightLateralDecubitus;
+			break;
+		default:
+			ap="";			// :(
+			position=Supine;
+			break;
+	}
+
+	double scanfov = atof(XXXX_HeaderInstance_IMGHDR->ISFOV)*10;	// cm -> mm
+
+	// Make a model of the image plane ...
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlanet" << endl;
+
+	ImagePlane imageplane(plane,scanfov,orientation,position);
+
+//cerr << "ToDicom_ManualPlane::Creating ImagePlane done" << endl;
+//imageplane.put(cerr);
+
+	// While we are in the "display" or "gantry plane ...
+	// (before angulation) 
+
+	// Apply any transformations specified in the
+	// display/gantry plane, such as magnification and
+	// reconstruction target offsets ...
+
+	// Assume that these are machine rather than body relative
+
+	double reconfov	= atof(XXXX_HeaderInstance_IMGHDR2->IRFOV)*10;	// cm -> mm
+	double reconch	= XXXX_HeaderInstance_IMGHDR2->IRCENTX;
+	double reconcv	= XXXX_HeaderInstance_IMGHDR2->IRCENTY;
+
+	double magfact 	= XXXX_HeaderInstance_IMGHDR2->IMAGFACT;
+	double magch	= XXXX_HeaderInstance_IMGHDR2->IMAGCX;
+	double magcv	= XXXX_HeaderInstance_IMGHDR2->IMAGCY;
+
+	Vector3D reconoffset;
+	Vector3D magoffset;
+
+	// Determine which axes are "horizontal" & "vertical" ...
+	// Don't forget sign changes ...
+
+	switch (plane) {
+		case Axial:
+			reconoffset=Vector3D(reconch,-reconcv,0);
+			magoffset  =Vector3D(magch,    -magcv,0);
+			break;
+		case Sagittal:
+			reconoffset=Vector3D(0,-reconch,reconcv);
+			magoffset  =Vector3D(0,  -magch,  magcv);
+			break;
+		case Coronal:
+			reconoffset=Vector3D(reconch,0,reconcv);
+			magoffset  =Vector3D(magch  ,0,  magcv);
+			break;
+	}
+
+//cerr << "ToDicom_ManualPlane::reconoffset is:" << endl;
+//reconoffset.put(cerr);
+//cerr << "ToDicom_ManualPlane::magoffset is:" << endl;
+//magoffset.put(cerr);
+
+//cerr << "ToDicom_ManualPlane::scale:" << endl;
+	imageplane.MachinePlane::scale(magfact*reconfov/scanfov);
+//cerr << "ToDicom_ManualPlane::scale result:" << endl;
+//imageplane.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by reconoffset:" << endl;
+	imageplane.MachinePlane::shift(reconoffset);
+//cerr << "ToDicom_ManualPlane::shift by reconoffset result:" << endl;
+//imageplane.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by magoffset:" << endl;
+	imageplane.MachinePlane::shift(magoffset);
+//cerr << "ToDicom_ManualPlane::shift by magoffset result:" << endl;
+//imageplane.put(cerr);
+
+	// Account for angulation ...
+
+	if (XXXX_isct) {
+//cerr << "ToDicom_ManualPlane::angling:" << endl;
+#ifdef XXXXTILTCTUSINGMACHINECORDS
+		// +ve is top towards table
+		// whereas Z is positive into gantry so change sign
+		imageplane.MachinePlane::angle(
+			LeftRight,-XXXX_HeaderInstance_CTHDR->IGTILT);
+#else // XXXXTILTCTUSINGMACHINECORDS
+		// +ve is always towards front of head
+		imageplane.PatientPlane::angle(
+			LeftRight,atof(XXXX_HeaderInstance_CTHDR->IGTILTB));
+#endif // XXXXTILTCTUSINGMACHINECORDS
+//cerr << "ToDicom_ManualPlane::angling result:" << endl;
+//imageplane.put(cerr);
+	}
+
+	if (XXXX_ismr) {
+		// Not yet tested ... no samples available ...
+
+		// Tilt is specified as none or relative to axis
+		// Axis+/-Angle [xx+/-xx]
+		// NB. in body not machine coordinates **********
+
+		char *str=XXXX_HeaderInstance_MRHDR->IMRTILT;
+		char axis[3]; strncpy(axis,str,2); axis[2]=0;
+		int angle=str[2] ? atoi(str+2) : 0;
+
+		// in Japanese docs, text contradicts drawing so
+		// go with drawing ...
+
+		ImagePlaneAxis planeaxis;
+
+		if (angle) {
+			switch (axis[0]) {
+				case 'A':
+				case 'P':
+					planeaxis=AnteriorPosterior;
+					// Xxxx CW +ve facing posterior
+					// angle=angle;
+					break;
+				case 'R':
+				case 'L':
+					planeaxis=LeftRight;
+					// Xxxx CW +ve facing right lat
+					angle=-angle;
+					break;
+				case 'H':
+				case 'F':
+					planeaxis=HeadFeet;
+					// Xxxx CW +ve facing head
+					// angle=angle;
+					break;
+			}
+		}
+		imageplane.PatientPlane::angle(planeaxis,angle);
+	}
+
+	// Account for physical offsets in the body plane ...
+	// (after angulation)
+
+	// For Xxxx the only difference between slices seems to be
+	// in the "Slice position by body coords" (ISLPOSxx) fields
+	// These do NOT include recon center offset and gantry tilt
+
+	// NB. The "Image center machine coords" (IIMPOSx) already
+	// account for both the recon center offset and the gantry
+	// tilt. They do NOT however handle the change between
+	// slices in the Z direction (what I would expect to be
+	// in ITBLPOS but is not ... it is zero in every slice :()
+	// so we can't use them.
+
+	double xcenter=XXXX_HeaderInstance_IMGHDR->ISLPOSLR;
+	double ycenter=XXXX_HeaderInstance_IMGHDR->ISLPOSAP;
+	double zcenter=XXXX_HeaderInstance_IMGHDR->ISLPOSHF;
+
+	// Consider sign difference Xxxx vs. Dicom for Y
+
+//cerr << "ToDicom_ManualPlane::physical offset is" << endl;
+	Vector3D offset(xcenter,-ycenter,zcenter);
+//offset.put(cerr);
+//cerr << "ToDicom_ManualPlane::shift by physical offset" << endl;
+	imageplane.PatientPlane::shift(offset);
+//cerr << "ToDicom_ManualPlane::shift by physical offset result:" << endl;
+//imageplane.put(cerr);
+
+	// Now build the DICOM attributes ...
+
+	(*list)+=new CodeStringAttribute(TagFromName(PatientPosition),
+		String_Cat_Use(hfff,ap));
+
+//cerr << "ToDicom_ManualPlane::addPlaneToList:" << endl;
+	ImagePlaneLister ipl(imageplane);
+	ipl.addPlaneToList(*list);
+//cerr << "ToDicom_ManualPlane::addPlaneToList done:" << endl;
+
+	// SliceLocation
+
+	// ITBLPOS always seems to be zero, so use IPLANE to
+	// decide which slice position value to use
+
+	// Xxxx slice position values are in body coordinates.
+	// Neither DICOM PS3 nor ACR/NEMA 2 define sign of
+	// SliceLocation, but seeing as it is an old element
+	// it seems appropriate to use machine coordinates
+
+	// Don't want to use the angled, magnified, targeted
+	// imageplane because it is in the axis of the
+	// image center rather than the axis at isocenter
+	// and is slightly different from the conventional
+	// interpretation of table position if an offset
+	// in the display/gantry plane has been applied.
+
+	// So set up a new imageplane just to convert from
+	// body to machine cordinates, and apply physical
+	// offset without angulation or recon or zoom ...
+
+//cerr << "ToDicom_ManualPlane::Use a new image plane for rest:" << endl;
+
+	ImagePlane locationimageplane(plane,scanfov,orientation,position);
+
+	locationimageplane.PatientPlane::shift(offset);
+
+	Point3D center=locationimageplane.MachinePlane::getCenter();
+
+	double location;
+
+	switch (plane) {
+		case Axial:
+			location=center.getZ();
+			break;
+		case Sagittal:
+			location=center.getX();
+			break;
+		case Coronal:
+			location=center.getY();
+			break;
+	}
+	(*list)+=new DecimalStringAttribute(TagFromName(SliceLocation),location);
+
+	// TableHeight
+
+	// DICOM ...+ve is below center
+	// Xxxx is in machine co-ordinates ... +ve is up
+
+	if (XXXX_isct) (*list)+=new
+		DecimalStringAttribute(TagFromName(TableHeight),
+			double(-double(XXXX_HeaderInstance_CTHDR->ITBLHGT)));
+
+	// PixelSpacing
+
+	(*list)+=new DecimalStringAttribute(TagFromName(PixelSpacing),
+		XXXX_HeaderInstance_IMGHDR2->IPIXSIZE,
+		XXXX_HeaderInstance_IMGHDR2->IPIXSIZE);
+
+	// ZoomFactor
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomFactor),
+		XXXX_HeaderInstance_IMGHDR2->IMAGFACT,
+		XXXX_HeaderInstance_IMGHDR2->IMAGFACT);
+
+	// ZoomCenter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ZoomCenter),
+			XXXX_HeaderInstance_IMGHDR2->IMAGCX,
+			XXXX_HeaderInstance_IMGHDR2->IMAGCY);
+
+	// ReconstructionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(ReconstructionDiameter),
+		atof(XXXX_HeaderInstance_IMGHDR2->IRFOV)*10);
+
+	// DataCollectionDiameter
+
+	(*list)+=new DecimalStringAttribute(TagFromName(DataCollectionDiameter),
+		atof(XXXX_HeaderInstance_IMGHDR->ISFOV)*10);
+}
+
diff --git a/libsrc/src/dconvert/xxxx/xxxxptrs.h b/libsrc/src/dconvert/xxxx/xxxxptrs.h
new file mode 100644
index 0000000..5d00f83
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxptrs.h
@@ -0,0 +1,12 @@
+/* xxxxptrs.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#define	XXXX_Offset_STDHDR_ptr	256
+#define	XXXX_Offset_IMGHDR_ptr	768
+#define	XXXX_Offset_MRHDR_ptr	(XXXX_Offset_IMGHDR_ptr+192)
+#define	XXXX_Offset_CTHDR_ptr	(XXXX_Offset_IMGHDR_ptr+192)
+#define	XXXX_Offset_IMGHDR2_ptr	(XXXX_Offset_IMGHDR_ptr+320)
+
+#define	XXXX_isct	(XXXX_HeaderInstance_IMGHDR->IMODELNO_Mod == 1)
+#define	XXXX_ismr	(XXXX_HeaderInstance_IMGHDR->IMODELNO_Mod == 2)
+
+#define	XXXX_Offset_PixelData_ptr	(XXXX_Offset_IMGHDR_ptr \
+			+xxxxhdr->XXXX_HeaderInstance_IMGHDR->IBLOCK*1024)
diff --git a/libsrc/src/dconvert/xxxx/xxxxsrc.h b/libsrc/src/dconvert/xxxx/xxxxsrc.h
new file mode 100644
index 0000000..7ca5724
--- /dev/null
+++ b/libsrc/src/dconvert/xxxx/xxxxsrc.h
@@ -0,0 +1,61 @@
+/* xxxxsrc.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_xxxxsrc__
+#define __Header_xxxxsrc__
+
+class XXXX_PixelDataSource : public SourceBase<Uint16> {
+	istream *istr;
+	long offset;
+	Uint16 rows;
+	Uint16 columns;
+	Uint16 row;
+	Uint16 col;
+	Uint16 *buffer;
+public:
+	XXXX_PixelDataSource(istream& i,long off,Uint16 r,Uint16 c)
+			: SourceBase<Uint16>()
+		{
+			istr=&i;
+			offset=off;
+			rows=r;
+			Assert(rows);
+			columns=c;
+			Assert(columns);
+			row=0;
+			col=0;
+			buffer=new Uint16[columns];
+			Assert(buffer);
+		}
+
+	~XXXX_PixelDataSource()
+		{
+			if (buffer) delete[] buffer;
+		}
+
+	size_t read(void)
+		{
+			if (row == 0) {
+				Assert(istr);
+				istr->seekg(offset,ios::beg);
+			}
+			col=0;
+			if (!istr->good() || row++ >= rows) return 0;
+			Uint16 *ptr=buffer;
+			while (col < columns) {
+				unsigned char bytes[2];
+				istr->read((char *)bytes,2);
+				if (!istr->good()) return 0;
+				// Little endian ...
+				Uint16 pixel;
+				pixel=(bytes[1]<<8)|bytes[0];
+				*ptr++=pixel; ++col;
+			}
+			return col;
+		}
+
+	const Uint16 *getBuffer(void)		{ return buffer; }
+	size_t getBufferCount(void) const	{ return col; }
+
+	int good(void) const	{ return istr && istr->good() && row < rows; }
+};
+
+#endif // __Header_xxxxsrc__
diff --git a/libsrc/src/dctool/Imakefile b/libsrc/src/dctool/Imakefile
new file mode 100755
index 0000000..d8456dc
--- /dev/null
+++ b/libsrc/src/dctool/Imakefile
@@ -0,0 +1,56 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBDCTOOLEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = charset.cc transyn.cc transynd.cc transync.cc sopclc.cc sopcli.cc \
+		 attr.cc attrtag.cc attrtypd.cc \
+		 attrtyps.cc attrtypt.cc attrtypo.cc attrtypv.cc \
+		 attrlist.cc attrlsln.cc attrothr.cc attrnew.cc attrseq.cc \
+		 attrmxrd.cc attrmxvr.cc attrmxls.cc attrvrfy.cc \
+		 elmdict.cc elmpriv.cc dcstream.cc uidgen.cc \
+		 dcopti.cc dcopto.cc dcoptc.cc \
+		 pixposn.cc \
+		 strval.cc binval.cc tagval.cc condn.cc \
+		 moduleb.cc modulev.cc modulew.cc \
+		 iodcompb.cc iodcompv.cc iodcompw.cc iodcomps.cc \
+		 dicomdir.cc ie.cc
+
+OBJS =           charset.o transyn.o  transynd.o  transync.o  sopclc.o  sopcli.o  \
+		 attr.o  attrtag.o attrtypd.o \
+		 attrtyps.o  attrtypt.o  attrtypo.o  attrtypv.o \
+		 attrlist.o  attrlsln.o  attrothr.o  attrnew.o  attrseq.o \
+		 attrmxrd.o  attrmxvr.o  attrmxls.o  attrvrfy.o \
+		 elmdict.o  elmpriv.o  dcstream.o  uidgen.o \
+		 dcopti.o  dcopto.o  dcoptc.o \
+		 pixposn.o \
+		 strval.o  binval.o  tagval.o  condn.o \
+		 moduleb.o  modulev.o  modulew.o \
+		 iodcompb.o  iodcompv.o  iodcompw.o  iodcomps.o \
+		 dicomdir.o ie.o
+
+
+LibraryTarget($(PROJECTLIBDIR)/lib$(PROJECTDCTOOLLIBNAME).a,$(OBJS))
+
+ProjectToolLibraryHeaderTemplate(transynt,transyn,transyn,role=table outname=transynt)
+ProjectToolLibraryHeaderTemplate(transync,transyn,transyn,role=constant outname=transync)
+
+ProjectToolLibraryHeaderTemplate(sopclc,sopcl,sopcl,role=constant outname=sopclc)
+ProjectToolLibraryHeaderTemplate(sopclt,sopcl,sopcl,role=table outname=sopclt)
+
+ProjectToolLibraryHeaderTemplate(elmtable,elmdict,elmdict,role=table outname=elmtable)
+
+ProjectToolLibraryHeaderTemplate(strvald,strval,strval,role=define outname=strvald)
+ProjectToolLibraryHeaderTemplate(binvald,binval,binval,role=define outname=binvald)
+ProjectToolLibraryHeaderTemplate(tagvald,tagval,tagval,role=define outname=tagvald)
+ProjectToolLibraryHeaderTemplate(condnd,condn,condn,role=define outname=condnd)
+
+ProjectToolLibraryHeaderTemplate(moduleb,module,module,role=build  outname=moduleb)
+ProjectToolLibraryHeaderTemplate(modulev,module,module,role=verify outname=modulev)
+ProjectToolLibraryHeaderTemplate(modulew,module,module,role=write  outname=modulew)
+
+ProjectToolLibraryHeaderTemplate(iodcompb,iodcomp,iodcomp,role=build  outname=iodcompb)
+ProjectToolLibraryHeaderTemplate(iodcompv,iodcomp,iodcomp,role=verify outname=iodcompv)
+ProjectToolLibraryHeaderTemplate(iodcompw,iodcomp,iodcomp,role=write  outname=iodcompw)
+ProjectToolLibraryHeaderTemplate(iodcomps,iodcomp,iodcomp,role=select outname=iodcomps)
+
+DependCCTarget()
diff --git a/libsrc/src/dctool/attr.cc b/libsrc/src/dctool/attr.cc
new file mode 100644
index 0000000..6ee88f5
--- /dev/null
+++ b/libsrc/src/dctool/attr.cc
@@ -0,0 +1,377 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+
+Attribute::Attribute(Tag t)
+{
+	tag=t;
+	byteoffset=0xffffffff;
+	used=false;
+	ie = UnknownIE;
+}
+
+Attribute::~Attribute()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "Attribute::~Attribute" << endl;
+#endif
+}
+
+void
+Attribute::setByteOffset(Uint32 offset)
+{
+//cerr << "Attribute::setByteOffset to " << hex << offset << dec << endl;
+	byteoffset=offset;
+}
+
+Uint32
+Attribute::getByteOffset(void) const
+{
+//cerr << "Attribute::getByteOffset is " << hex << byteoffset << dec << endl;
+//	Assert(byteoffset != 0xffffffff);
+	return byteoffset;
+}
+
+TextOutputStream&
+Attribute::writeBase(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	if (verbose) {
+		stream << "@";
+		writeZeroPaddedHexNumber(stream,byteoffset,8);
+		stream << ": ";
+	}
+	tag.write(stream,dict);
+	stream << "\t VR=<" << getVR() << ">  ";
+	stream << " VL=<";
+	writeZeroPaddedHexNumber(stream,getVL(),4);
+	stream << ">  " << flush;
+	if (showUsedAndIE) {
+		stream << "Used=<" << (isUsed() ? "T" : "F") << "> ";
+		stream << "IE=<" << describeInformationEntity(getInformationEntity()) << "> ";
+	}
+	return stream;
+}
+
+BinaryOutputStream&
+Attribute::writeBase(BinaryOutputStream& stream)
+{
+	Assert(0);
+	// this routine is probably never used, but just in case ...
+	// assume default Implicit VR
+	stream << tag << getVL();
+	return stream;
+}
+
+DicomOutputStream&
+Attribute::writeBase(DicomOutputStream& stream)
+{
+	// NB. Changing transfer syntaxes is caller's responsibility
+	stream << tag;
+	const char *vr = getVR();
+	Assert(stream.getTransferSyntaxInUse());
+	if (stream.getTransferSyntaxInUse()->isExplicitVR()) {
+		Assert(vr);
+		Assert(strlen(vr) == 2);
+//cerr << "VR=" << vr << endl;
+		if (vr[0]=='X') {			// we have a problem ... an internal unspecified pseudo-VR is present ... need to override it
+			if (vr[1]=='S') {		// XS is choice between US or SS
+//cerr << "Overriding XS with US during write" << endl;
+				vr="US";
+			}
+			else if (vr[1]=='O') {		// XO is choice between US or SS or OW
+//cerr << "Overriding XO with OW during write" << endl;
+				vr="OW";
+			}
+		}
+		else if (vr[0]=='O' && vr[1]=='X') {	// we have a problem ... an internal unspecified pseudo-VR is present ... need to override it
+//cerr << "Overriding OX with OW during write" << endl;
+			vr="OW";
+		}
+		stream << vr;
+		if ((vr[0]=='O' && (vr[1]=='B' || vr[1]=='D' || vr[1]=='F' || vr[1]=='L' || vr[1]=='W' || vr[1]=='X'))
+	 	 || (vr[0]=='S' &&  vr[1]=='Q')
+	 	 || (vr[0]=='U' && (vr[1]=='C' || vr[1]=='N' || vr[1]=='R' || vr[1]=='T')))
+		{
+			// Explicit OB,OD,OF,OL,OW,OX,SQ,UC,UN,UR,UT
+			stream << Uint16(0) << getVL();
+		}
+		else {
+			stream << (Uint16)getVL();
+		}
+	}
+	else {	// Implicit VR
+		stream << getVL();
+	}
+	return stream;
+}
+
+BinaryOutputStream&
+Attribute::writeData(BinaryOutputStream& stream)
+{
+	Assert(0);
+	return stream;
+}
+
+TextOutputStream&
+Attribute::writeData(TextOutputStream& stream)
+{
+	Assert(0);
+	return stream;
+}
+
+OtherUnspecifiedLargeAttributeBase *
+Attribute::castToOtherData(void)
+{
+	Assert(0);
+	return 0;
+}
+
+void
+Attribute::setOutputEncoding(
+		TransferSyntax *,
+		unsigned short,
+		unsigned short,
+		unsigned short,
+		unsigned short,
+		Uint32)
+{
+	// ignore, since may be set for PixelData that we are treating as ordinary attribute, e.g., illegal GE Private Thumbnails (000426)
+}
+
+bool
+Attribute::getValue(unsigned,Uint16&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,Uint32&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,Int16&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,Int32&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,Float32&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,Float64&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,Tag&) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(unsigned,char * &) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(const unsigned char * &,Uint32 &) const
+{
+	return false;
+}
+
+bool
+Attribute::getValue(const Uint16 * &,Uint32 &) const
+{
+	return false;
+}
+
+void
+Attribute::setValue(unsigned,Uint16)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,Uint32)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,Int16)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,Int32)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,Float32)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,Float64)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,Tag)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(unsigned,const char *)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(const unsigned char *,Uint32)
+{
+	Assert(0);
+}
+
+void
+Attribute::setValue(const Uint16 *,Uint32)
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Uint16)
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Uint32)
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Int16)	
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Int32)	
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Float32)
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Float64)
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(Tag)
+{
+	Assert(0);
+}
+
+void
+Attribute::addValue(const char *)
+{
+	Assert(0);
+}
+
+
+void
+Attribute::addValues(unsigned number,Uint16 *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,Uint32 *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,Int16 *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,Int32 *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,Float32 *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,Float64 *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,Tag *vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(unsigned number,const char **vptr)
+{
+	while (number--) addValue(*vptr++);
+}
+
+void
+Attribute::addValues(const char *)
+{
+	Assert(0);
+}
+
+int
+Attribute::getLists(AttributeList ***a)
+{
+	Assert(0);
+	*a=0;
+	return 0;
+}
+
+DicomOutputStream&
+DicomOutputStream::operator<<(Attribute& rhs)
+{
+	rhs.write(*this);
+	return *this;
+}
+
diff --git a/libsrc/src/dctool/attrlist.cc b/libsrc/src/dctool/attrlist.cc
new file mode 100644
index 0000000..848be94
--- /dev/null
+++ b/libsrc/src/dctool/attrlist.cc
@@ -0,0 +1,206 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrlist.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "listsort.h"
+
+// In order for the sorted list template to know how to sort one needs
+// to define a type that can order itself, hence this ...
+
+class AttributePointer {
+	Attribute *Pointer;
+public:
+	AttributePointer(void)				{ Pointer=0; }
+	AttributePointer(Attribute *p)			{ Pointer=p; }
+	AttributePointer(const AttributePointer& t)	{ Pointer=t.Pointer; }
+
+	void operator=(Attribute *p)			{ Pointer=p; }
+	void operator=(const AttributePointer& t)	{ Pointer=t.Pointer; }
+
+	Attribute *	operator()(void)		{ return Pointer; }
+	Attribute *	operator->(void)		{ return Pointer; }
+	Attribute &	operator*(void)			{ return *Pointer; }
+
+	operator Attribute*()				{ return Pointer; }
+
+	int operator==(const AttributePointer& t2)
+		{ return Pointer->getTag() == t2.Pointer->getTag(); }
+	int operator<(const AttributePointer& t2)
+		{ return Pointer->getTag() <  t2.Pointer->getTag(); }
+	int operator<=(const AttributePointer& t2)
+		{ return Pointer->getTag() <= t2.Pointer->getTag(); }
+	int operator>(const AttributePointer& t2)
+		{ return Pointer->getTag() >  t2.Pointer->getTag(); }
+	int operator>=(const AttributePointer& t2)
+		{ return Pointer->getTag() >= t2.Pointer->getTag(); }
+};	
+
+// ********************** Implementation methods ************************
+
+class AttributeListImpl : public SortedList<AttributePointer> {
+public:
+	AttributeListImpl(void) : SortedList<AttributePointer>()
+		{
+		}
+
+	virtual ~AttributeListImpl();
+
+	Attribute * operator[](Tag tag);
+	void	operator-=(Tag tag);
+
+	void	operator+=(Attribute *p);
+	void	operator-=(Attribute *p);
+
+	void	operator-=(AttributeList& deletelist);
+	void	operator+=(AttributeList& replacelist);
+
+	void	operator-=(AttributeListImpl& deletelist);
+	void	operator+=(AttributeListImpl& replacelist);
+};
+
+class AttributeListIteratorImpl : public SortedListIterator<AttributePointer> {
+public:
+	AttributeListIteratorImpl(AttributeListImpl& list)
+		: SortedListIterator<AttributePointer> (list)
+		{
+			//cerr << "AttributeListIteratorImpl(list)" << endl;
+			//cerr << "AttributeListIteratorImpl(list) "
+			//     << "list.head=" << hex << (unsigned long)(list.head)
+			//     << "" << endl;
+		}
+};
+
+AttributeListImpl::~AttributeListImpl()
+{
+//#ifdef TRACE_DESTRUCTORS
+//cerr << "AttributeListImpl::~AttributeListImpl" << endl;
+//#endif
+	AttributeListIteratorImpl listi(*this);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		delete a;
+		++listi;
+	}
+}
+
+inline Attribute *
+AttributeListImpl::operator[](Tag tag)
+{
+	Attribute *p = 0;
+	AttributeListIteratorImpl i(*this);
+	while (!i) {
+		if (i()->getTag() == tag) {
+			p=i();
+//cerr << "operator[]: found tag = " << tag << endl;
+			break;
+		}
+		++i;
+	}
+	return p;
+}
+
+inline void
+AttributeListImpl::operator-=(Attribute *p)
+{
+	if (p) {
+//cerr << "operator-=: removing tag = " << p->getTag() << endl;
+		SortedList<AttributePointer>::operator-=(p);
+	}
+}
+
+inline void
+AttributeListImpl::operator+=(Attribute *p)
+{
+	if (p) SortedList<AttributePointer>::operator+=(p);
+}
+
+inline void
+AttributeListImpl::operator-=(Tag tag)
+{
+	Attribute *p;
+	while ((p = operator[](tag)) != 0) operator-=(p);
+}
+
+inline void
+AttributeListImpl::operator-=(AttributeListImpl& deletelist)
+{
+	AttributeListIteratorImpl i(deletelist);
+	while (!i) { operator-=(i()); ++i; }
+}
+
+inline void
+AttributeListImpl::operator+=(AttributeListImpl& replacelist)
+{
+	AttributeListIteratorImpl i(replacelist);
+	while (!i) {
+		Attribute *a=i();
+		operator-=(a->getTag());
+		operator+=(a);
+		replacelist-=a;
+		i.first();
+	}
+}
+
+inline void
+AttributeListImpl::operator-=(AttributeList& deletelist)
+{
+	operator-=(*deletelist.list);
+}
+
+inline void
+AttributeListImpl::operator+=(AttributeList& replacelist)
+{
+	operator+=(*replacelist.list);
+}
+
+// ********************** Interface methods ************************
+
+AttributeList::AttributeList(void)
+{
+	list=new AttributeListImpl();
+	Assert(list);
+	dictionary=0;
+	specificCharacterSetInfo=NULL;		// populated when needed by looking for SpecificCharacterSet attribute value in list, e.g., on calling validateVR() in ManagedAttributeList
+}
+
+AttributeList::~AttributeList()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "AttributeList::~AttributeList" << endl;
+#endif
+	Assert(list);
+	delete list;
+	if (dictionary) delete dictionary;
+	if (specificCharacterSetInfo) delete specificCharacterSetInfo;
+}
+
+Attribute * 	AttributeList::operator[](Tag tag)		{ return list->operator[](tag); }
+void		AttributeList::operator-=(Tag tag)		{ list->operator-=(tag); }
+
+void 		AttributeList::operator-=(Attribute *p)		{ list->operator-=(p); }
+void		AttributeList::operator+=(Attribute *p)		{ list->operator+=(p); }
+
+void 		AttributeList::operator-=(AttributeList& p)	{ list->operator-=(p); }
+void		AttributeList::operator+=(AttributeList& p)	{ list->operator+=(p); }
+
+AttributeListIterator::AttributeListIterator(AttributeList& list)
+{
+	iterator=new AttributeListIteratorImpl(*list.list);
+	Assert(iterator);
+}
+
+AttributeListIterator::~AttributeListIterator()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "AttributeListIterator::~AttributeListIterator" << endl;
+#endif
+	Assert(iterator);
+	delete iterator;
+}
+
+void 		AttributeListIterator::first(void)	{ iterator->first(); }
+int 		AttributeListIterator::ismore(void)	{ return iterator->ismore(); }
+void 		AttributeListIterator::next(void)	{ iterator->next(); }
+Attribute * 	AttributeListIterator::value(void)	{ return iterator->value(); }
+
+
diff --git a/libsrc/src/dctool/attrlsln.cc b/libsrc/src/dctool/attrlsln.cc
new file mode 100644
index 0000000..f5c04b1
--- /dev/null
+++ b/libsrc/src/dctool/attrlsln.cc
@@ -0,0 +1,100 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrlsln.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrlsln.h"
+#include "attrseq.h"
+
+Uint32
+lengthOfFixedPartOfAttribute(
+	const TransferSyntax *ts,const Attribute *a)
+{
+	// returned the length in bytes of the fixed part of an element
+	// ie. that part other than that returned by a->getVL()
+	// obviously this is dictated by the Value Representation which
+	// in turn depends on the Transfer Syntax
+
+	Assert(a);
+	Assert(ts);
+
+	Uint32 length=4;	// length of tag itself
+	// work out length of "value length" field
+	if (ts->isImplicitVR())
+		length+=4;
+	else if (ts->isExplicitVR()) {
+		const char *vru=a->getVR();
+		if (vru) {	// Explicit OB,OW,SQ,UN,UT
+			if (isLongValueLengthInExplicitValueRepresentation(vru))
+				length+=6;
+			else
+				length+=2;
+		}
+		else
+			Assert(0);
+		length+=2;	// add length of explicit VR itself
+	}
+	else
+		Assert(0);
+	return length;
+}
+
+Uint32
+lengthOfFixedPartOfAttribute(
+	const TransferSyntax *metats,const TransferSyntax *datats,const Attribute *a)
+{
+	return lengthOfFixedPartOfAttribute(a->getTag().isMetaheaderGroup() ? metats : datats,a);
+}
+
+Uint32
+lengthOfEntireAttribute(const TransferSyntax *ts,const Attribute *a)
+{
+	// returned the length in bytes of the entire element
+	// obviously this is dictated by the Value Representation which
+	// in turn depends on the Transfer Syntax
+
+        // returns 0xffffffff if undefined length
+
+	Assert(a);
+	Assert(ts);
+
+	Uint32 length=lengthOfFixedPartOfAttribute(ts,a);
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		SequenceAttribute *as=(SequenceAttribute *)a;
+		AttributeList **alists;
+		int count=as->getLists(&alists);
+		while (count--) {
+			Assert(*alists);
+			length+=8;	// Item
+			AttributeListIterator i(**alists);
+			while (!i) {
+				Attribute *a=i();
+				Assert(a);
+                                Uint32 add=lengthOfEntireAttribute(ts,a);
+                                if (add == 0xffffffff) {
+                                        return 0xffffffff;
+                                }
+                                length+=add;
+				++i;
+			}
+			length+=8;	// Item Delimiter
+			++alists;
+		}
+		length+=8;		// Sequence Delimiter
+	}
+        else {
+                Uint32 add=a->getVL();
+                if (add == 0xffffffff) {
+                        length=0xffffffff;      // no support for undefined lengths other than sequences (e.g. encapsulated pixel data)
+                }
+	        else {
+		        length+=add;
+                }
+        }
+        return length;
+}
+
+
+Uint32
+lengthOfEntireAttribute(
+	const TransferSyntax *metats,const TransferSyntax *datats,const Attribute *a)
+{
+	return lengthOfEntireAttribute(a->getTag().isMetaheaderGroup() ? metats : datats,a);
+}
+
diff --git a/libsrc/src/dctool/attrmxls.cc b/libsrc/src/dctool/attrmxls.cc
new file mode 100644
index 0000000..8e71ab6
--- /dev/null
+++ b/libsrc/src/dctool/attrmxls.cc
@@ -0,0 +1,1226 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrmxls.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrlsln.h"
+#include "attrmxls.h"
+#include "attrval.h"
+#include "attrothr.h"
+#include "uidgen.h"
+#include "sopclu.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+#include "bnchar.h"
+
+static bool
+loopOverListsInSequences(Attribute *a,bool (*func)(AttributeList &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i])) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+loopOverListsInSequencesWithFlag(Attribute *a,bool flag,bool (*func)(AttributeList &,bool flag))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],flag)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+loopOverListsInSequencesWithLog(Attribute *a,TextOutputStream &log,
+		bool (*func)(AttributeList &,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+loopOverListsInSequencesWithSpecificCharacterSetInfoAndLog(Attribute *a,SpecificCharacterSetInfo *specificCharacterSetInfo,TextOutputStream &log,
+		bool (*func)(AttributeList &,SpecificCharacterSetInfo *specificCharacterSetInfo,TextOutputStream &))
+{
+	bool succeeded=true;
+	if (strcmp(a->getVR(),"SQ") == 0) {
+		AttributeList **al;
+		int n;
+		if ((n=a->getLists(&al)) > 0) {
+			int i;
+			for (i=0; i<n; ++i) {
+				if (!(*func)(*al[i],specificCharacterSetInfo,log)) succeeded=false;
+			}
+			delete [] al;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+validateVR(AttributeList& list,SpecificCharacterSetInfo *parentSpecificCharacterSetInfo,TextOutputStream &log)
+{
+	SpecificCharacterSetInfo *specificCharacterSetInfo = list.getSpecificCharacterSetInfo();
+	if (!specificCharacterSetInfo) {
+		Attribute *aSpecificCharacterSet = list[TagFromName(SpecificCharacterSet)];
+		if (aSpecificCharacterSet) {
+			specificCharacterSetInfo = new SpecificCharacterSetInfo(aSpecificCharacterSet);		// always use it if present (even if zero length ... overrides parent with default)
+		}
+		else {
+			specificCharacterSetInfo = parentSpecificCharacterSetInfo ? parentSpecificCharacterSetInfo : new SpecificCharacterSetInfo();	// create default if not inherited from parent
+		}
+		list.setSpecificCharacterSetInfo(specificCharacterSetInfo);
+	}
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithSpecificCharacterSetInfoAndLog(a,specificCharacterSetInfo,log,&::validateVR))
+			succeeded=false;
+		if (a->getVL() > 0 && !a->validateVR(log,specificCharacterSetInfo,list.getDictionary()))
+			succeeded=false;
+		++listi;
+	}
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::validateVR(TextOutputStream &log)
+{
+//cerr << "ManagedAttributeList::validateVR" << endl;
+	return ::validateVR(*this,NULL,log);
+}
+
+static bool
+validateRetired(AttributeList& list,TextOutputStream &log)
+{
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithLog(a,log,&::validateRetired))
+			succeeded=false;
+		if (!a->validateRetired(log,list.getDictionary()))
+			succeeded=false;
+		++listi;
+	}
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::validateRetired(TextOutputStream &log)
+{
+//cerr << "ManagedAttributeList::validateRetired" << endl;
+	return ::validateRetired(*this,log);
+}
+
+static bool
+validateUsed(AttributeList& list,TextOutputStream &log)
+{
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		Tag t = a->getTag();
+		if (!t.isPrivateGroup()) {
+			if (!::loopOverListsInSequencesWithLog(a,log,&::validateUsed))
+				succeeded=false;
+		}
+		bool used = a->isUsed();
+		if (!used && t.isRepeatingGroup()) {
+			Attribute *ab = list[t.getRepeatingBase()];
+			if (ab) {
+				used = ab->isUsed();
+			}
+		}
+		if (!used) {
+			if (t.isStandardGroup() && !t.isLengthElementOrLengthToEnd() && t != TagFromName(DataSetTrailingPadding)) {	// NOT isPrivate()
+				ElementDictionary *dictionary = list.getDictionary();
+				if (dictionary) {
+					const char *vrd = dictionary->getValueRepresentation(t);
+					if (!vrd) {
+						log << EMsgDC(AttributeIsNotARecognizedStandardAttribute) << " - ";
+						t.write(log,dictionary);
+						log << endl;
+						succeeded=false;
+					}
+				}
+				log << WMsgDC(AttributeIsNotUsedInIOD) << " - ";
+				t.write(log,dictionary);
+				log << endl;
+				succeeded=false;
+			}
+		}
+		++listi;
+	}
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::validateUsed(TextOutputStream &log)
+{
+//cerr << "ManagedAttributeList::validateUsed" << endl;
+	return ::validateUsed(*this,log);
+}
+
+static bool
+validatePrivate(AttributeList& list,TextOutputStream &log)
+{
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		Tag t = a->getTag();
+		if (!::loopOverListsInSequencesWithLog(a,log,&::validatePrivate))
+			succeeded=false;
+		if ((t.getGroup() % 2) == 1 && !t.isValidPrivateGroup()) {
+			ElementDictionary *dictionary = list.getDictionary();
+			if (dictionary) {
+				log << EMsgDC(AttributeIsNotInALegalPrivateGroup) << " - ";
+				t.write(log,dictionary);
+				log << endl;
+				succeeded=false;
+			}
+		}
+		++listi;
+	}
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::validatePrivate(TextOutputStream &log)
+{
+//cerr << "ManagedAttributeList::validatePrivate" << endl;
+	return ::validatePrivate(*this,log);
+}
+
+static bool
+removeLengths(AttributeList& list)
+{
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		Tag tag=a->getTag();
+		if (tag.isLengthElementOrLengthToEnd()) {
+			list-=(tag);
+			listi.first();
+		}
+		else {
+			if (!::loopOverListsInSequences(a,&::removeLengths))
+				succeeded=false;
+			++listi;
+		}
+	}
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::removeLengths(void)
+{
+//cerr << "ManagedAttributeList::removeLengths" << endl;
+	return ::removeLengths(*this);
+}
+
+bool
+ManagedAttributeList::removeMetaHeader(bool leaveuid)
+{
+//cerr << "ManagedAttributeList::removeMetaHeader" << endl;
+//cerr << "ManagedAttributeList::removeMetaHeader - leaveuid" << (leaveuid ? "T" : "F") << endl;
+	bool succeeded=true;
+	AttributeListIterator listi(*this);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		Tag tag=a->getTag();
+		if (tag.isMetaheaderGroup()
+		 && !(leaveuid && (tag == TagFromName(MediaStorageSOPClassUID)
+			        || tag == TagFromName(MediaStorageSOPInstanceUID) ))
+		) {
+//TextOutputStream terr(cerr);
+//terr << "ManagedAttributeList::removeMetaHeader: removing";
+//a->write(terr,getDictionary());
+//terr << endl;
+			(*this)-=(tag);
+			listi.first();
+		}
+		else {
+			// doesn't recurse through sequences
+			++listi;
+		}
+	}
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::removeInstanceUID(void)
+{
+//cerr << "ManagedAttributeList::removeInstanceUID" << endl;
+
+	// Only top level Instance UID's other than references
+
+	bool succeeded=true;
+	AttributeListIterator listi(*this);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		const char *vr=a->getVR();
+		Assert(vr);
+		Tag tag=a->getTag();
+		if (strcmp(vr,"UI") == 0
+		 && (tag == TagFromName(SOPInstanceUID)
+		  || tag == TagFromName(StudyInstanceUID)
+		  || tag == TagFromName(SeriesInstanceUID)
+		  || tag == TagFromName(FrameOfReferenceUID)
+		  || tag == TagFromName(SynchronizationFrameOfReferenceUID)
+		  || tag == TagFromName(MediaStorageSOPInstanceUID)
+		 )
+		) {
+			(*this)-=(tag);
+			listi.first();
+		}
+		else {
+			// doesn't recurse through sequences
+			++listi;
+		}
+	}
+	return succeeded;
+}
+
+static bool
+removePrivate(AttributeList& list)
+{
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		Tag tag=a->getTag();
+		if (tag.isPrivateGroup()) {
+			list-=(tag);
+			listi.first();
+		}
+		else {
+			if (!::loopOverListsInSequences(a,&::removePrivate))
+				succeeded=false;
+			++listi;
+		}
+	}
+	return succeeded;
+}
+
+void
+ManagedAttributeList::removeCommandGroup(void)
+{
+	AttributeListIterator listi(*this);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		Tag tag=a->getTag();
+		if (tag.getGroup() == 0x0000) {
+			(*this)-=(tag);
+			listi.first();
+		}
+		else {
+			break;
+		}
+		// no need for ++listi, since either broke or restarted
+	}
+}
+
+bool
+ManagedAttributeList::removePrivate(void)
+{
+//cerr << "ManagedAttributeList::removePrivate" << endl;
+	return ::removePrivate(*this);
+}
+
+bool
+ManagedAttributeList::addMetaHeader(TransferSyntax *ts,const char *stamp)
+{
+//cerr << "ManagedAttributeList::addMetaHeader" << endl;
+	Attribute *a;
+
+	operator-=(TagFromName(TransferSyntaxUID));
+	//if (!operator[](TagFromName(TransferSyntaxUID))) {
+//cerr << "ManagedAttributeList::addMetaHeader - TransferSyntaxUID" << endl;
+		Assert(ts);
+		const char *tsuid=ts->getUID();
+		Assert(tsuid);
+		a=new UIStringAttribute(TagFromName(TransferSyntaxUID),tsuid);
+		Assert(a);
+		operator+=(a);
+	//}
+
+	operator-=(TagFromName(FileMetaInformationVersion));
+	//if (!operator[](TagFromName(FileMetaInformationVersion))) {
+//cerr << "ManagedAttributeList::addMetaHeader - FileMetaInformationVersion" << endl;
+		a=new OtherByteSmallNonPixelAttribute(TagFromName(FileMetaInformationVersion));
+		Assert(a);
+		unsigned char values[2];
+		values[0]=0x00;
+		values[1]=0x01;
+		a->setValue(values,2);
+		operator+=(a);
+	//}
+
+	operator-=(TagFromName(MediaStorageSOPClassUID));
+	//if (!operator[](TagFromName(MediaStorageSOPClassUID))) {
+//cerr << "ManagedAttributeList::addMetaHeader - MediaStorageSOPClassUID" << endl;
+		char *classuid=AttributeValue(operator[](TagFromName(SOPClassUID)));
+		if (classuid) {
+			a=new UIStringAttribute(TagFromName(MediaStorageSOPClassUID));
+			Assert(a);
+			a->addValue(String_Use(classuid));	// correct: AttributeValue() returns a copy
+			operator+=(a);
+		}
+		else if (operator[](TagFromName(DirectoryRecordSequence))) {
+			// we are doing a DICOMDIR
+			operator+=(new UIStringAttribute(TagFromName(MediaStorageSOPClassUID),MediaStorageDirectoryStorageSOPClassUID));
+		}
+		else {
+			errorstream << EMsgDC(MissingSOPClassUIDBuildingMetaHeader) << endl;
+			good_flag=false;
+			return false;
+		}
+	//}
+
+	operator-=(TagFromName(MediaStorageSOPInstanceUID));
+	//if (!operator[](TagFromName(MediaStorageSOPInstanceUID))) {
+//cerr << "ManagedAttributeList::addMetaHeader - MediaStorageSOPInstanceUID" << endl;
+		char *instanceuid=AttributeValue(operator[](TagFromName(SOPInstanceUID)));
+		if (instanceuid) {
+			a=new UIStringAttribute(TagFromName(MediaStorageSOPInstanceUID));
+			Assert(a);
+			a->addValue(String_Use(instanceuid));	// correct: AttributeValue() returns a copy
+			operator+=(a);
+		}
+		else if (operator[](TagFromName(DirectoryRecordSequence))) {
+			// we are doing a DICOMDIR, so just make up a new InstanceUID ...
+			operator+=(new UIStringAttribute(TagFromName(MediaStorageSOPClassUID),StrDup(GeneratedDirInstanceUID(stamp))));
+		}
+		else {
+			errorstream << EMsgDC(MissingSOPInstanceUIDBuildingMetaHeader) << endl;
+			good_flag=false;
+			return false;
+		}
+	//}
+
+#ifndef DEFAULTIMPLEMENTATIONCLASSUID
+#define DEFAULTIMPLEMENTATIONCLASSUID "0.0.0.0"
+#endif
+	operator-=(TagFromName(ImplementationClassUID));
+	//if (!operator[](TagFromName(ImplementationClassUID))) {
+//cerr << "ManagedAttributeList::addMetaHeader - ImplementationClassUID" << endl;
+		a=new UIStringAttribute(TagFromName(ImplementationClassUID));
+		Assert(a);
+		a->addValue(DEFAULTIMPLEMENTATIONCLASSUID);
+		operator+=(a);
+	//}
+
+#ifndef DEFAULTIMPLEMENTATIONVERSIONNAME
+#define DEFAULTIMPLEMENTATIONVERSIONNAME "NOTSPECIFIED"
+#endif
+	operator-=(TagFromName(ImplementationVersionName));
+	//if (!operator[](TagFromName(ImplementationVersionName))) {
+//cerr << "ManagedAttributeList::addMetaHeader - ImplementationVersionName" << endl;
+		a=new ShortStringAttribute(TagFromName(ImplementationVersionName));
+		Assert(a);
+		a->addValue(DEFAULTIMPLEMENTATIONVERSIONNAME);
+		operator+=(a);
+	//}
+
+#ifndef DEFAULTSOURCEAPPLICATIONENTITYTITLE
+#define DEFAULTSOURCEAPPLICATIONENTITYTITLE "NOTSPECIFIED"
+#endif
+	operator-=(TagFromName(SourceApplicationEntityTitle));
+	//if (!operator[](TagFromName(SourceApplicationEntityTitle))) {
+//cerr << "ManagedAttributeList::addMetaHeader - SourceApplicationEntityTitle" << endl;
+		a=new ApplicationEntityAttribute(TagFromName(SourceApplicationEntityTitle));
+		Assert(a);
+		a->addValue(DEFAULTSOURCEAPPLICATIONENTITYTITLE);
+		operator+=(a);
+	//}
+
+	return true;
+}
+
+
+static const char *uidstamp;
+static const char *instanceCreationDate;
+static const char *instanceCreationTime;
+static const char *timezoneOffsetFromUTC;
+
+static bool
+addDicom(AttributeList& list,bool disambiguateseriesbydescription)
+{
+//cerr << "addDicom:" << endl;
+//cerr << "addDicom: disambiguateseriesbydescription = " << disambiguateseriesbydescription << endl;
+	bool succeeded=true;
+
+	// Patient and Study attributes will not both be present
+	// in a Normalized IOD, but are always present in a
+	// Composite IOD (even if empty, all these are Type 2 in
+	// all modules), including the Basic Study Descriptor IOD
+
+	// Don't do anything for Normalized IOD's ...
+
+	bool ispatient = list[TagFromName(PatientName)] != 0
+		      || list[TagFromName(PatientID)] != 0
+		      || list[TagFromName(PatientSex)] != 0
+		      || list[TagFromName(PatientBirthDate)] != 0;
+	bool isstudy = list[TagFromName(StudyID)] != 0
+		    || list[TagFromName(StudyDate)] != 0
+		    || list[TagFromName(StudyTime)] != 0;
+
+	if (!(ispatient && isstudy)) return true;
+
+	// Must be a Composite IOD ...
+
+	// AccessionNumber is Type 2 so add zero length if not present
+
+	if (!list[TagFromName(AccessionNumber)]) {
+		list+=new ShortStringAttribute(TagFromName(AccessionNumber));
+	}
+
+	Attribute *astudy    = list[TagFromName(StudyID)];
+	Attribute *apatient  = list[TagFromName(PatientName)];
+	Attribute *amodality = list[TagFromName(Modality)];
+	Attribute *aseries   = list[TagFromName(SeriesNumber)];
+	Attribute *ainstance = list[TagFromName(InstanceNumber)];
+	Attribute *aInConcatenationNumber = list[TagFromName(InConcatenationNumber)];
+
+	char *studystring = AttributeValue(astudy);
+	Uint16 study = studystring ? atoi(studystring) : 0;
+	Uint16 series = AttributeValue(aseries);
+	Uint16 instance = AttributeValue(ainstance);
+	Int32 inConcatenationNumber = aInConcatenationNumber ? Int32(AttributeValue(aInConcatenationNumber)) : -1;
+//cerr << "addDicom: inConcatenationNumber " << dec << inConcatenationNumber << endl;
+	
+	if (disambiguateseriesbydescription) {
+//cerr << "addDicom: disambiguateseriesbydescription - series number was " << dec << series << endl;
+		Attribute *aSeriesDescription    = list[TagFromName(SeriesDescription)];
+		char *seriesDescriptionString = AttributeValue(aSeriesDescription);
+		if (seriesDescriptionString != NULL) {
+			const char *p = seriesDescriptionString;
+			while (*p) {
+				series+=*p++;	// crude hash by adding character values
+			}
+		}
+//cerr << "addDicom: disambiguateseriesbydescription - series number now " << dec << series << endl;
+	}
+
+	// The SOPClassUID and SOPInstanceUID are required
+	// in all Composite IOD's.
+
+	// SOPClassUID
+
+	if (!list[TagFromName(SOPClassUID)]) {
+		const char *modality;
+		const char *uid;
+		if (amodality && (modality=AttributeValue(amodality))) {
+			if (strcmp(modality,"CR") == 0)
+				uid=ComputedRadiographyImageStorageSOPClassUID;
+			else if (strcmp(modality,"CT") == 0)
+				uid=CTImageStorageSOPClassUID;
+			else if (strcmp(modality,"MR") == 0)
+				uid=MRImageStorageSOPClassUID;
+			else // can't be sure ... multiple choices
+				uid=SecondaryCaptureImageStorageSOPClassUID;
+		}
+		else {
+			uid=SecondaryCaptureImageStorageSOPClassUID;
+		}
+		list+=(new UIStringAttribute(TagFromName(SOPClassUID),uid));
+	}
+
+	// SOPInstanceUID
+
+	if (!list[TagFromName(SOPInstanceUID)]) {
+		list+=(new UIStringAttribute(
+			TagFromName(SOPInstanceUID),
+			GeneratedSOPInstanceUID(uidstamp, study,series,instance,inConcatenationNumber)
+		));
+	}
+
+	// StudyInstanceUID
+
+	if (!list[TagFromName(StudyInstanceUID)] && astudy) {
+		list+=(new UIStringAttribute(
+			TagFromName(StudyInstanceUID),
+			GeneratedStudyInstanceUID(uidstamp,study)
+		));
+	}
+
+	// SeriesInstanceUID
+
+	if (!list[TagFromName(SeriesInstanceUID)] && aseries) {
+		list+=(new UIStringAttribute(
+			TagFromName(SeriesInstanceUID),
+			GeneratedSeriesInstanceUID(uidstamp,study,series)
+		));
+	}
+
+	// FrameOfReferenceUID
+
+	if (!list[TagFromName(FrameOfReferenceUID)]
+	  && list[TagFromName(PositionReferenceIndicator)]) {
+		list+=(new UIStringAttribute(
+			TagFromName(FrameOfReferenceUID),
+			GeneratedFrameOfReferenceUID(uidstamp,
+				study,series)
+		));
+	}
+
+	// SynchronizationFrameOfReferenceUID
+
+	if (!list[TagFromName(SynchronizationFrameOfReferenceUID)]
+	  && (list[TagFromName(SynchronizationTrigger)] || list[TagFromName(AcquisitionTimeSynchronized)])) {
+		list+=(new UIStringAttribute(
+			TagFromName(SynchronizationFrameOfReferenceUID),
+			GeneratedSynchronizationFrameOfReferenceUID(uidstamp,
+				study,series)
+		));
+	}
+
+	// InstanceCreatorUID
+
+#ifndef DEFAULTINSTANCECREATORUID
+#define DEFAULTINSTANCECREATORUID "0.0.0.0"
+#endif
+	if (!list[TagFromName(InstanceCreatorUID)]) {
+		list+=(new UIStringAttribute(
+			TagFromName(InstanceCreatorUID),
+			DEFAULTINSTANCECREATORUID
+		));
+	}
+
+	// InstanceCreationDate
+
+	if (!list[TagFromName(InstanceCreationDate)]) {
+		list+=(new DateStringAttribute(
+			TagFromName(InstanceCreationDate),
+			instanceCreationDate ? Date(instanceCreationDate,DateOrderMonthMiddleYearFirst) : Date()
+		));
+	}
+
+	// InstanceCreationTime
+
+	if (!list[TagFromName(InstanceCreationTime)]) {
+		list+=(new TimeStringAttribute(
+			TagFromName(InstanceCreationTime),
+			instanceCreationTime ? Time(instanceCreationTime) : Time()
+		));
+	}
+
+	// TimezoneOffsetFromUTC
+
+	if (!list[TagFromName(TimezoneOffsetFromUTC)]) {
+		list+=(new ShortStringAttribute(
+			TagFromName(TimezoneOffsetFromUTC),
+			timezoneOffsetFromUTC ? timezoneOffsetFromUTC : Date().getTZOffset()
+		));
+	}
+
+	if (studystring) delete[] studystring;
+
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		Assert(a);
+		if (!::loopOverListsInSequencesWithFlag(a,disambiguateseriesbydescription,&::addDicom))
+			succeeded=false;
+		++listi;
+	}
+
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::addDicom(bool disambiguateseriesbydescription)
+{
+//cerr << "ManagedAttributeList::addDicom" << endl;
+//cerr << "ManagedAttributeList::addDicom: disambiguateseriesbydescription = " << disambiguateseriesbydescription << endl;
+	::uidstamp = getUIDStamp();
+	::instanceCreationDate = getInstanceCreationDate();
+//cerr << "ManagedAttributeList::addDicom instanceCreationDate=" << ::instanceCreationDate << endl;
+	::instanceCreationTime = getInstanceCreationTime();
+	::timezoneOffsetFromUTC = getTimezoneOffsetFromUTC();
+	return ::addDicom(*this,disambiguateseriesbydescription);
+}
+
+bool
+ManagedAttributeList::addDisclaimer(void)
+{
+//cerr << "ManagedAttributeList::addDisclaimer" << endl;
+	const char *disclaimer=MMsgDC(DisclaimerMessage);
+	Attribute *aImageComments=(*this)[TagFromName(ImageComments)];
+	if (aImageComments) {
+		char *sImageComments=0;
+		// LT so VM should always be 1
+		if (aImageComments->getVM() == 1
+		 && aImageComments->getValue(0,sImageComments)
+		 && sImageComments
+		 && strstr(sImageComments,disclaimer) == 0) {
+			ostrstream o;
+			o << disclaimer << "\n" << sImageComments << ends;
+			char *s=o.str();
+			if (s) {
+				aImageComments->setValue(0,s);
+				delete[] s;
+			}
+		}
+	}
+	else {
+		(*this)+=new LongTextAttribute(TagFromName(ImageComments),disclaimer);
+	}
+		
+	return true;
+}
+
+bool
+ManagedAttributeList::addLengths(
+	TransferSyntax *metats,TransferSyntax *datats,bool allgroups,bool toend)
+{
+//cerr << "ManagedAttributeList::addLengths" << endl;
+	// Fixup and/or insert group lengths
+
+	// insert a dummy LengthToEnd element in case not present ...
+	// (otherwise the length of group 0008 would be wrong)
+
+	if (toend)
+		operator+=(new UnsignedLongAttribute(TagFromName(LengthToEnd),Uint32(0)));
+
+	// each (nnnn,0000) group length element
+	// contains the length in bytes of the rest of the group
+	// not including the length element itself
+
+	bool metaseen=false;
+	bool dothisgroup=true;
+	Uint16 doinggroup=0;
+	Uint32 length=0;
+	AttributeList lengthlist;
+	AttributeListIterator listi(*this);
+	while (1) {
+		Attribute *a;
+		Tag tag;
+		if (!listi) {
+			a=listi();
+			Assert(a);
+			tag=a->getTag();
+		}
+		if (!!listi || tag.getGroup() > doinggroup) {
+			if (length && dothisgroup && (allgroups || doinggroup == 0x0002)) {
+				lengthlist+=new UnsignedLongAttribute(Tag(doinggroup,0),length);
+			}
+			if (!!listi)
+				break;
+			else {
+				doinggroup=tag.getGroup();
+				dothisgroup=true;
+				length=0;
+			}
+		}
+		else if (tag.getGroup() == doinggroup) {
+                        Uint32 add=lengthOfEntireAttribute(metats,datats,a);
+			if (add == 0xffffffff)
+				dothisgroup=false;
+			else
+				length+=add;
+			++listi;
+		}
+		else
+			++listi;
+
+		if (!allgroups) {
+			if (tag.isMetaheaderGroup())
+				metaseen=true;
+			else
+				if (metaseen) break;
+		}
+	}
+
+	operator+=(lengthlist);
+
+	if (toend) {
+		listi.first();
+		length=0;
+		while (!listi) {
+			Attribute *a = listi();
+			Assert(a);
+			Tag tag = a->getTag();
+			if (tag > TagFromName(LengthToEnd)) {
+                                Uint32 add=lengthOfEntireAttribute(metats,datats,a);
+		                if (add == 0xffffffff)
+			                Assert(0);              // could just break silently and not add, but let's flag the problem
+		                else
+			                length+=add;
+			 }
+                        ++listi;
+		}
+
+		operator-=(TagFromName(LengthToEnd));
+		operator+=(new UnsignedLongAttribute(TagFromName(LengthToEnd),length));
+	}
+
+	return true;
+}
+
+static bool
+getOffsetToAttributeValue(Tag matchtag,AttributeList& list,
+	TransferSyntax *metats,TransferSyntax *datats,bool metaflag,
+	Uint32& length)
+{
+//cerr << "getOffsetToPixelData" << endl;
+
+	length=metaflag ? 132 : 0;
+
+	AttributeListIterator listi(list);
+	while (!listi) {
+//cerr << "getOffsetToPixelData: length = hex " << hex << length << dec << endl;
+		Attribute *a=listi();
+		Assert(a);
+		Tag tag=a->getTag();
+		if (tag == matchtag) {
+			length+=lengthOfFixedPartOfAttribute(metats,datats,a);
+			return true;
+		}
+                Uint32 add=lengthOfEntireAttribute(metats,datats,a);
+		if (add == 0xffffffff)
+			Assert(0);
+		else
+			length+=add;
+		++listi;
+	}
+
+	return false;
+}
+
+bool
+ManagedAttributeList::addTiffTrailer(DicomOutputStream& stream,bool metaflag)
+{
+//cerr << "ManagedAttributeList::addTiffTrailer" << endl;
+
+	TransferSyntax *metats=stream.getTransferSyntaxToWriteMetaHeader();
+	TransferSyntax *datats=stream.getTransferSyntaxToWriteDataSet();
+
+	Attribute *a;
+
+	if ((a=(*this)[TagFromName(Columns)])) {
+		Uint32 ImageWidth = AttributeValue(a);
+//cerr << "ManagedAttributeList::addTiffTrailer - ImageWidth " << dec << ImageWidth << endl;
+		if ((a=(*this)[TagFromName(Rows)])) {
+			Uint32 ImageLength = AttributeValue(a);
+//cerr << "ManagedAttributeList::addTiffTrailer - ImageLength " << dec << ImageLength << endl;
+			if ((a=(*this)[TagFromName(BitsAllocated)])) {
+				Uint16 BitsPerSample = AttributeValue(a);
+//cerr << "ManagedAttributeList::addTiffTrailer - BitsPerSample " << dec << BitsPerSample << endl;
+				Assert(BitsPerSample ==8 || BitsPerSample == 16);
+				if ((a=(*this)[TagFromName(PhotometricInterpretation)])) {
+					Uint16 PhotometricInterpretation;
+					Uint16 SamplesPerPixel;
+					Uint16 PlanarConfiguration=0;	// flag not to send it
+
+					const char *s = AttributeValue(a);
+					if (s && strcmp(s,"MONOCHROME1") == 0) PhotometricInterpretation=0;
+					else if (s && strcmp(s,"MONOCHROME2") == 0) PhotometricInterpretation=1;
+					else if (s && strcmp(s,"RGB") == 0) PhotometricInterpretation=2;
+					else if (s && strcmp(s,"PALETTE COLOR") == 0) PhotometricInterpretation=3;
+					else PhotometricInterpretation=99;
+
+					SamplesPerPixel=(PhotometricInterpretation == 2) ? 3 : 1;
+						
+					if (PhotometricInterpretation == 2) {
+						SamplesPerPixel=3;
+						if ((a=(*this)[TagFromName(PlanarConfiguration)])) {
+							PlanarConfiguration=AttributeValue(a);
+							++PlanarConfiguration;
+						}
+						else PlanarConfiguration=1;	// blech :(
+					}
+					else {
+						SamplesPerPixel=1;
+					}
+
+//cerr << "ManagedAttributeList::addTiffTrailer - PhotometricInterpretation " << dec << PhotometricInterpretation << endl;
+//cerr << "ManagedAttributeList::addTiffTrailer - SamplesPerPixel " << dec << SamplesPerPixel << endl;
+//cerr << "ManagedAttributeList::addTiffTrailer - PlanarConfiguration " << dec << PlanarConfiguration << endl;
+
+					if (PhotometricInterpretation != 99) {
+						if ((a=(*this)[TagFromName(PixelData)])) {
+							Uint32 StripOffset;
+							if (getOffsetToAttributeValue(TagFromName(PixelData),*this,metats,datats,metaflag,StripOffset)) {
+
+//cerr << "ManagedAttributeList::addTiffTrailer - StripOffset hex " << hex << StripOffset << dec << endl;
+
+								Assert(datats);
+								Endian endian=datats->getEndian();
+								unsigned char ifd[2+132+4];
+								unsigned char *ptr=ifd;
+								Uint16 entries = 10 + (PlanarConfiguration ? 1 : 0);
+
+								insert16incr(entries,ptr,endian);	// Entry count 10 or 11 (each 12 bytes)
+
+								insert16incr(0x00fe,ptr,endian);	// NewSubfileType
+								insert16incr(0x0004,ptr,endian);	// - type   LONG
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(0x0000,ptr,endian);	// - value  0
+
+								insert16incr(0x0100,ptr,endian);	// ImageWidth
+								insert16incr(0x0004,ptr,endian);	// - type   LONG
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(ImageWidth,ptr,endian);	// - value
+
+								insert16incr(0x0101,ptr,endian);	// ImageLength
+								insert16incr(0x0004,ptr,endian);	// - type   LONG
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(ImageLength,ptr,endian);	// - value
+
+								insert16incr(0x0102,ptr,endian);	// BitsPerSample
+								insert16incr(0x0003,ptr,endian);	// - type   SHORT
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(BitsPerSample,ptr,endian);	// - value  None
+
+								insert16incr(0x0103,ptr,endian);	// Compression
+								insert16incr(0x0003,ptr,endian);	// - type   SHORT
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(0x0001,ptr,endian);	// - value  None
+
+								insert16incr(0x0106,ptr,endian);	// Photometric Interpretation
+								insert16incr(0x0003,ptr,endian);	// - type   SHORT
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(PhotometricInterpretation,ptr,endian);	// - value
+
+								insert16incr(0x0111,ptr,endian);	// StripOffsets
+								insert16incr(0x0004,ptr,endian);	// - type   LONG
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(StripOffset,ptr,endian);	// - value
+
+								insert16incr(0x0115,ptr,endian);	// SamplesPerPixel
+								insert16incr(0x0003,ptr,endian);	// - type   SHORT
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(SamplesPerPixel,ptr,endian);	// - value
+
+								insert16incr(0x0116,ptr,endian);	// RowsPerStrip
+								insert16incr(0x0004,ptr,endian);	// - type   LONG
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr(ImageLength,ptr,endian);	// - value
+
+								insert16incr(0x0117,ptr,endian);	// StripByteCounts
+								insert16incr(0x0004,ptr,endian);	// - type   LONG
+								insert32incr(0x0001,ptr,endian);	// - length 1
+								insert32incr((Uint32)ImageLength*ImageWidth*((BitsPerSample-1)/8+1)*SamplesPerPixel,ptr,endian);	// - value
+
+								if (PlanarConfiguration) {
+									insert16incr(0x011c,ptr,endian);	// PlanarConfiguration
+									insert16incr(0x0003,ptr,endian);	// - type   SHORT
+									insert32incr(0x0001,ptr,endian);	// - length 1
+									insert32incr(PlanarConfiguration,ptr,endian);	// - value  None
+								}
+
+								insert32incr(0,ptr,endian);		// Offset of next IFD (none)
+
+//cerr << "ptr-ifd = " << dec << ptr-ifd << endl;
+								Assert(ptr-ifd == 2 + 12*entries + 4);
+
+								OtherByteSmallNonPixelAttributeBase *apad=
+									new OtherByteSmallNonPixelAttributeBase(
+										TagFromName(DataSetTrailingPadding));
+								Assert(apad);
+								apad->setValue(ifd,ptr-ifd);
+
+								if ((a=(*this)[TagFromName(DataSetTrailingPadding)])) (*this)-=a;
+								(*this)+=apad;
+
+								Uint32 IFDOffset;
+								if (getOffsetToAttributeValue(TagFromName(DataSetTrailingPadding),
+										*this,metats,datats,metaflag,IFDOffset)) {
+//cerr << "ManagedAttributeList::addTiffTrailer - IFDOffset hex " << hex << IFDOffset << dec << endl;
+									stream.setIFDOffset(IFDOffset);
+									return true;
+								}
+								Assert(0);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return false;
+}
+
+static bool
+setOutputEncoding(AttributeList& list,TransferSyntax *ts,ostream &errorstream)
+{
+//cerr << "::setOutputEncoding" << endl;
+	bool succeeded=true;
+	AttributeListIterator listi(list);
+	while (!listi) {
+		Attribute *a=listi();
+		if (strcmp(a->getVR(),"SQ") == 0) {
+			AttributeList **al;
+			int n;
+			if ((n=a->getLists(&al)) > 0) {
+				int i;
+				for (i=0; i<n; ++i) {
+					if (!setOutputEncoding(*al[i],ts,errorstream))
+						succeeded=false;
+				}
+				delete [] al;
+			}
+		}
+
+		if (a->getTag() == TagFromName(PixelData)) {
+//TextOutputStream terr(cerr);
+//terr << "::setOutputEncoding: setting";
+//a->write(terr,0);
+//terr << endl;
+			Attribute *aba=list[TagFromName(BitsAllocated)];
+			Attribute *abs=list[TagFromName(BitsStored)];
+			Attribute *abh=list[TagFromName(HighBit)];
+
+			Uint16 bitsAllocated=0;
+			Uint16 bitsStored=0;
+			Uint16 highBit=0;
+
+			if (!aba)
+				errorstream << WMsgDC(MissingAttribute) << " - BitsAllocated" << endl;
+			if (!abs)
+				errorstream << WMsgDC(MissingAttribute) << " - BitsStored" << endl;
+			if (!abh)
+				errorstream << WMsgDC(MissingAttribute) << " - HighBit" << endl;
+
+			if (!aba && abs && (bitsStored=AttributeValue(abs)) != 0) {
+				bitsAllocated=((bitsStored-1u)/8u+1u)*8u;
+				highBit=AttributeValue(abh,bitsStored-1u);
+			}
+			else if (aba && (bitsAllocated=AttributeValue(aba)) != 0) {
+				bitsStored=AttributeValue(abs,bitsAllocated);
+				highBit=AttributeValue(abh,bitsStored-1u);
+			}
+			else {
+				errorstream << EMsgDC(InsufficientInformationToSetEncoding) << endl;
+				succeeded=false;
+			}
+
+			// bytesinword == 0 -> determine from ts
+			if (bitsAllocated && bitsStored)
+				a->setOutputEncoding(ts,0,
+					bitsAllocated,bitsStored,highBit,0xffffffff);
+		}
+		++listi;
+	}
+
+	return succeeded;
+}
+
+bool
+ManagedAttributeList::setOutputEncoding(TransferSyntax *ts)
+{
+//cerr << "ManagedAttributeList::setOutputEncoding" << endl;
+	return ::setOutputEncoding(*this,ts,errorstream);
+}
+
+ManagedAttributeList::ManagedAttributeList(void)
+	: ReadableAttributeList()
+{
+	flags=none;
+	uidstamp=0;
+	instanceCreationDate=0;
+	instanceCreationTime=0;
+	timezoneOffsetFromUTC=0;
+	preparedstream=0;
+	dictionary=new ElementDictionary();
+}
+
+ManagedAttributeList::~ManagedAttributeList(void)
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "ManagedAttributeList::~ManagedAttributeList" << endl;
+#endif
+}
+
+bool
+ManagedAttributeList::read(DicomInputStream& stream,
+		TextOutputStream *log,
+		bool verbose,
+		Uint32 length,
+		bool metaheadercheck,
+		bool uselengthtoend,
+		bool ignoretagsoutoforder,
+		bool useUSVRForLUTDataIfNotExplicit,
+		bool useStopAtTag,
+		Tag stopAtTag,
+		bool fixBitsDuringRead)
+{
+	return ReadableAttributeList::read(
+		stream,getDictionary(),
+		log,verbose,length,
+		metaheadercheck,uselengthtoend,ignoretagsoutoforder,useUSVRForLUTDataIfNotExplicit,
+		false/*forceImplicit*/,
+		useStopAtTag,stopAtTag,
+		false/*nestedWithinSequence*/,NULL/*sequenceOwner*/,
+		fixBitsDuringRead);
+}
+
+bool
+ManagedAttributeList::clean(flag_types fset,flag_types freset)
+{
+//cerr << "ManagedAttributeList::clean" << endl;
+	set(fset);
+	reset(freset);
+
+	return
+	    removeLengths()
+	 && removeMetaHeader(flags&metaheader)
+	 && (!(flags&removeinstanceuid) || removeInstanceUID())
+	 && (!(flags&removeprivate) || removePrivate());
+}
+
+bool
+ManagedAttributeList::prepare(DicomOutputStream& stream,
+	flag_types fset,flag_types freset,const char *stamp,
+	const char *creationDate,const char *creationTime,
+	const char *tzOffset)
+{
+//cerr << "ManagedAttributeList::prepare" << endl;
+	set(fset);
+	reset(freset);
+	if (stamp) uidstamp=stamp;
+	if (creationDate) instanceCreationDate=creationDate;
+//cerr << "ManagedAttributeList::prepare instanceCreationDate=" << instanceCreationDate << endl;
+	if (creationTime) instanceCreationTime=creationTime;
+	if (tzOffset) timezoneOffsetFromUTC=tzOffset;
+	preparedstream=&stream;
+
+//cerr << "ManagedAttributeList::prepare flags = 0x" << hex << flags << dec << endl;
+//cerr << "ManagedAttributeList::prepare flags&disambiguateseriesbydescription = 0x" << hex << (flags&disambiguateseriesbydescription) << dec << endl;
+	return 
+	(!(flags&adddicom) || addDicom(flags&disambiguateseriesbydescription ? true : false))
+	 && (!(flags&adddisclaimer) || addDisclaimer())
+	 && setOutputEncoding(stream.getTransferSyntaxToWriteDataSet())
+	 && setValueRepresentation()
+	 && (!(flags&metaheader) || addMetaHeader(stream.getTransferSyntaxToWriteDataSet(),stamp));
+}
+
+bool
+ManagedAttributeList::finalize(DicomOutputStream& stream)
+{
+//cerr << "ManagedAttributeList::finalize" << endl;
+	Assert(preparedstream == &stream);
+
+	// Flags already available from prepare
+
+	return addLengths(stream.getTransferSyntaxToWriteMetaHeader(),
+			  stream.getTransferSyntaxToWriteDataSet(),
+			  flags&addlengths,flags&addlengthtoend)
+	    && (!(flags&addtiff) || addTiffTrailer(stream,flags&metaheader));
+}
+
+DicomOutputStream&
+ManagedAttributeList::write(DicomOutputStream& stream)
+{
+//cerr << "ManagedAttributeList::write" << endl;
+	Assert(preparedstream == &stream);
+
+	AttributeListIterator i(*this);
+	while (!i) {
+//cerr << "ManagedAttributeList::write: looping on next attribute" << endl;
+		Attribute *a=i();
+		Assert(a);
+		if (a->getTag().isMetaheaderGroup()) {
+			if (flags&metaheader) {
+				stream.writingMetaHeader();
+//TextOutputStream terr(cerr);
+//terr << "ManagedAttributeList::write: writing";
+//a->write(terr,getDictionary());
+//terr << endl;
+				stream << *a;
+			}
+		}
+		else {
+			if (flags&dataset) {
+				stream.writingDataSet();
+//TextOutputStream terr(cerr);
+//terr << "ManagedAttributeList::write: writing";
+//a->write(terr,getDictionary());
+//terr << endl;
+				stream << *a;
+			}
+		}
+		++i;
+	}
+//cerr << "ManagedAttributeList::write return" << endl;
+	return stream;
+}
+
+DicomOutputStream& operator<<
+	(DicomOutputStream& stream,ManagedAttributeList& list)
+{
+	return list.write(stream);	// leave flags alone
+}
+
+TextOutputStream&
+ManagedAttributeList::write(TextOutputStream& stream,bool verbose,bool showUsedAndIE)
+{
+//TextOutputStream terr(cerr);
+//terr << "ManagedAttributeList::write" << endl;
+	AttributeListIterator i(*this);
+//terr << "ManagedAttributeList::have iterator" << endl;
+	while (!i) {
+//terr << "ManagedAttributeList::passed test" << endl;
+		Attribute *a=i();
+//terr << "ManagedAttributeList::have attribute" << endl;
+		Assert(a);
+//terr << "ManagedAttributeList::attribute not null" << endl;
+//terr << "ManagedAttributeList::tag = "; a->getTag().write(terr); terr << endl;
+//a->write(terr,getDictionary());
+//terr << endl;
+		a->write(stream,getDictionary(),verbose,showUsedAndIE);
+		stream << endl;
+		++i;
+	}
+	return stream;
+}
+
+TextOutputStream& operator<<
+	(TextOutputStream& stream,ManagedAttributeList& list)
+{
+	return list.write(stream);
+}
+
+
diff --git a/libsrc/src/dctool/attrmxrd copy.cc b/libsrc/src/dctool/attrmxrd copy.cc
new file mode 100755
index 0000000..5bdb85c
--- /dev/null
+++ b/libsrc/src/dctool/attrmxrd copy.cc	
@@ -0,0 +1,1205 @@
+#include "attrtype.h"
+#include "attrnew.h"
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "elmconst.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+
+// This may be defined in attrtype.h previously ...
+
+#ifndef LARGESTOTHERDATATOKEEPINMEMORY
+#define LARGESTOTHERDATATOKEEPINMEMORY 524288
+#endif
+
+// Want a routine to actually read rather than just use seekg(), since otherwise
+// there is no detection of failure to skip a truncated attribute at the end
+// of the dataset
+
+static long
+skipBytes(istream *stream,long nSkip) {
+	bool success=true;
+	const int bufferSize=32768;
+	char buffer[bufferSize];
+	long totalSkipped=0;
+	while (nSkip > 0) {
+		int nToRead = nSkip > bufferSize ? bufferSize : (int)nSkip;
+		stream->read(buffer,nToRead);
+		if (stream->fail()) {
+			break;
+		}
+		int nActuallyRead = (int)(stream->gcount());
+		if (nActuallyRead == 0) {
+			break;
+		}
+		nSkip-=nActuallyRead;
+		totalSkipped+=nActuallyRead;
+	}
+	return totalSkipped;
+}
+
+TextOutputStream& 
+ReadableAttributeList::writebase(const Tag tag,const char *vr,Uint32 vl)
+{
+	Assert(log);
+	tag.write(*log,dictionary);
+	(*log) << "\t VR=<" << (vr ? vr : "") << ">  " << flush;
+	(*log) << " VL=<";
+	writeZeroPaddedHexNumber(*log,vl,4);
+	(*log) << ">  " << flush;
+	return (*log);
+}
+
+const char *
+ReadableAttributeList::getValueRepresentation(Tag tag,char *vrbuf,bool& readAsImplicitRegardless)
+{
+//cerr << "ReadableAttributeList::getValueRepresentation():" << endl;
+	// dictionary Value Representation expected
+
+//cerr << "ReadableAttributeList::getValueRepresentation tag.isPrivateGroup()" << (tag.isPrivateGroup() ? "true" : "false") << endl;
+//cerr << "ReadableAttributeList::getValueRepresentation tag.isPrivateOwner()" << (tag.isPrivateOwner() ? "true" : "false") << endl;
+	
+	const char *vrd=
+		(tag.isPrivateGroup() && tag.isPrivateOwner())
+			? "LO"	// PS3.5-7.8.1
+			: dictionary->getValueRepresentation(tag);
+
+	// explicit Value Representation in input
+
+	//readAsImplicitRegardless=false;
+	const char *vre;
+	//Assert(stream->getTransferSyntaxInUse()->isImplicitVR() != stream->getTransferSyntaxInUse()->isExplicitVR());
+	//if (stream->getTransferSyntaxInUse()->isExplicitVR()) {	// See [bugs.dicom3tools] (000130) as to why this and previous assertion commented out
+	if (!stream->getTransferSyntaxInUse()->isImplicitVR() && !readAsImplicitRegardless) {
+//cerr << "ReadableAttributeList::getValueRepresentation(): stream is explicit VR - reading VR" << endl;
+		stream->read(vrbuf,2);
+		if (stream->fail()) return 0;
+		if (vrbuf[0] < 'A' || vrbuf[1] < 'A') {		// DicomWorks bug ... occasional implicit VR attribute even though explicit transfer syntax
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			errorstream << EMsgDC(TagReadFailed) << " - " << MMsgDC(ImplicitVREncodingWhenExplicitRequired) << endl;
+//cerr << "ReadableAttributeList::getValueRepresentation(): implicit VR encoding even though supposed to be explicit" << endl;
+			good_flag=false;
+			// backup so that we treat the VR bytes as VL, and do not advance byteoffset
+			stream->seekg(-2l,ios::cur);
+			if (stream->fail()) {
+				tag.write(terr,dictionary);
+				errorstream << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+				good_flag=false;
+				return 0;
+			}
+			vrbuf[0]=vrbuf[1]=vrbuf[2]=0;		// ignore whatever was read (vrbuf contents are tested by caller)
+			readAsImplicitRegardless=true;
+			vre=0;					// will trigger return value based on dictionary lookup
+		}
+		else {
+			byteoffset+=2;
+			vrbuf[2]=0;
+			vre=vrbuf;
+		}
+	}
+	else
+		vre=0;
+
+	// if was Explicit VR, vrbuf is now set and can be used as return value
+
+	if (!vrd && vre) {
+		TextOutputStream terr(errorstream.rdbuf());
+		tag.write(terr,dictionary);
+		if (strncmp(vre,"UN",2) == 0) {
+			errorstream << " - " << WMsgDC(NoDictionaryVRUseExplicitUN) << endl;
+		}
+		else {
+			errorstream << " - " << WMsgDC(NoDictionaryVRUseExplicit) << endl;
+		}
+	}
+
+	// choose/match Value Representation to use
+
+	TextOutputStream terr(errorstream.rdbuf());
+	const char *vru;
+	if (vre && vrd) {
+		if (strncmp(vre,vrd,2) == 0) {
+			// Both present and same
+			vru=vre;
+		}
+		else if (strncmp(vre,"UN",2) == 0) {
+			if (strncmp(vrd,"SQ",2) == 0) {
+				vru=vre;	// Explicit overrides dictionary for sequence (since need to treat undefined length sequence content as implicit VR later)
+				tag.write(terr,dictionary);
+				errorstream << " - " << WMsgDC(MismatchDictionaryVR) << "; Explicit <" << vre << "> Dictionary <" << vrd << ">" << endl;
+			}
+			else {
+				// Replace explicit UN with dictionary only if not a sequence
+				vru=vrd;
+				tag.write(terr,dictionary);
+				errorstream << " - " << WMsgDC(OverridingUNWithDictionaryVR) << endl;
+			}
+		}
+		else if ((strncmp(vrd,"OX",2) == 0
+		          && (strncmp(vre,"OB",2) == 0
+		              || strncmp(vre,"OW",2) == 0)
+		         )
+		      || (strncmp(vrd,"XS",2) == 0
+		          && (strncmp(vre,"US",2) == 0
+		              || strncmp(vre,"SS",2) == 0)
+		         )
+		      || (strncmp(vrd,"XO",2) == 0
+		          && (strncmp(vre,"US",2) == 0
+		              || strncmp(vre,"SS",2) == 0
+		              || strncmp(vre,"OW",2) == 0)
+		         )
+		      || (strncmp(vrd,"XL",2) == 0
+		          && (strncmp(vre,"UL",2) == 0
+		              || strncmp(vre,"SL",2) == 0)
+			 )
+		      ) {
+			// Explicit overrides ambiguous in dictionary
+			vru=vre;
+		}
+		else {
+			vru=vre;	// Explicit overrides dictionary
+			tag.write(terr,dictionary);
+			errorstream << " - " << WMsgDC(MismatchDictionaryVR) << "; Explicit <" << vre << "> Dictionary <" << vrd << ">" << endl;
+		}
+	}
+	else if (vrd) {
+		vru=vrd;
+	}
+	else if (vre) {
+		vru=vre;
+	}
+	else {
+		vru="UN";
+	}
+
+	if (tag.isPrivateGroup() && tag.isPrivateOwner()) {
+		if (strncmp(vru,"LO",2) != 0) {
+			vru="LO";
+			tag.write(terr,dictionary);
+			errorstream << " - " << EMsgDC(PrivateCreatorIsNotLOVR) << "; Explicit <" << vre << "> " << MMsgDC(OverridingVR) << " with <LO>" << endl;
+		}
+	}
+	return vru;
+}
+
+bool
+ReadableAttributeList::isOtherFloatVR(const char *vr)
+{
+	return vr && vr[0]=='O' && vr[1]=='F';
+}
+
+bool
+ReadableAttributeList::isOtherByteVR(const char *vr)
+{
+	return vr && vr[0]=='O' && vr[1]=='B';
+}
+
+bool
+ReadableAttributeList::isOtherByteOrWordVR(const char *vr)
+{
+	return vr && vr[0]=='O' && (vr[1]=='B' || vr[1]=='W' || vr[1]=='X');
+}
+
+bool
+ReadableAttributeList::isSequenceVR(const char *vr)
+{
+	return vr && vr[0]=='S' &&  vr[1]=='Q';
+}
+
+bool
+ReadableAttributeList::isUnknownVR(const char *vr)
+{
+	return vr && vr[0]=='U' &&  vr[1]=='N';
+}
+
+bool
+ReadableAttributeList::isUnlimitedTextVR(const char *vr)
+{
+	return vr && vr[0]=='U' &&  vr[1]=='T';
+}
+
+static bool
+isKnownExplicitValueRepresentation(const char *vr) {
+	return vr && (
+		   strcmp(vr,"AE") == 0
+		|| strcmp(vr,"AS") == 0
+		|| strcmp(vr,"AT") == 0
+		|| strcmp(vr,"CS") == 0
+		|| strcmp(vr,"DA") == 0
+		|| strcmp(vr,"DS") == 0
+		|| strcmp(vr,"DT") == 0
+		|| strcmp(vr,"FL") == 0
+		|| strcmp(vr,"FD") == 0
+		|| strcmp(vr,"IS") == 0
+		|| strcmp(vr,"LO") == 0
+		|| strcmp(vr,"LT") == 0
+		|| strcmp(vr,"OB") == 0
+		|| strcmp(vr,"OF") == 0
+		|| strcmp(vr,"OW") == 0
+		|| strcmp(vr,"PN") == 0
+		|| strcmp(vr,"SH") == 0
+		|| strcmp(vr,"SL") == 0
+		|| strcmp(vr,"SQ") == 0
+		|| strcmp(vr,"SS") == 0
+		|| strcmp(vr,"ST") == 0
+		|| strcmp(vr,"TM") == 0
+		|| strcmp(vr,"UI") == 0
+		|| strcmp(vr,"UL") == 0
+		|| strcmp(vr,"UN") == 0
+		|| strcmp(vr,"US") == 0
+		|| strcmp(vr,"UT") == 0
+		);
+}
+
+Uint32
+ReadableAttributeList::getValueLength(const char *vr,bool readAsImplicitRegardless)
+{
+//cerr << "ReadableAttributeList::getValueLength(): vr=" << vr << endl;
+	Uint32 vl;
+	if (stream->getTransferSyntaxInUse()->isImplicitVR() || readAsImplicitRegardless) {
+//cerr << "ReadableAttributeList::getValueLength(): is implicit VR" << endl;
+		(*stream) >> vl;
+		byteoffset+=4;
+	}
+	else {
+//cerr << "ReadableAttributeList::getValueLength(): is explicit VR" << endl;
+		if (isOtherByteOrWordVR(vr) || isSequenceVR(vr) || isOtherFloatVR(vr)) {
+			(void)stream->read16();	// "Reserved"
+			(*stream) >> vl;
+			byteoffset+=6;
+		}
+		else if (isUnlimitedTextVR(vr) || isUnknownVR(vr)) {
+			// should be long form, but check for bad implementations that use short form ...
+			vl=stream->read16();
+			byteoffset+=2;
+			if (vl == 0) {		// if reserved bytes not zero, assume used for short form of length (risky) :(
+				(*stream) >> vl;
+				byteoffset+=4;
+			}
+			else {
+				errorstream << EMsgDC(IncorrectShortVLForUTOrUN) << endl;
+				//good_flag=false;
+			}
+		}
+		else {
+			vl=stream->read16();
+			byteoffset+=2;
+		}
+	}
+//cerr << "ReadableAttributeList::getValueLength(): vl=0x" << hex << vl << dec << endl;
+	return vl;
+}
+
+static void
+dumpOffset(TextOutputStream *log,Uint32 byteoffset,DicomInputStream *stream,Uint32 length)
+{
+	unsigned long position=(unsigned long)stream->tellg();
+	(*log) << "@";
+	writeZeroPaddedHexNumber(*log,position,8);
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+	(*log) << "(";
+	writeZeroPaddedHexNumber(*log,stream->rdbuf()->PubSeekOff(0,ios::cur),8);
+	(*log) << ")";
+#endif
+	(*log) << ",";
+	writeZeroPaddedHexNumber(*log,byteoffset,8);
+	(*log) << " of ";
+	writeZeroPaddedHexNumber(*log,length,8);
+	(*log) << ": ";
+}
+
+void
+ReadableAttributeList::skipEncapsulatedData(void)
+{
+//cerr << "ReadableAttributeList::skipEncapsulatedData: start" << endl;
+	bool showoffset=verbose;
+	// See libsrc/include/pixeldat/unencap.h for details of GE bug
+	while (1) {
+//cerr << "ReadableAttributeList::skipEncapsulatedData: looping" << endl;
+		if (verbose && showoffset) dumpOffset(log,byteoffset,stream,0xffffffff);
+		Tag tag;
+		(*stream) >> tag;	// Assume is Item Tag
+		if (stream->fail()) {
+			errorstream << EMsgDC(TagReadFailed) << endl;
+			good_flag=false;
+			return;
+		}
+		byteoffset+=4;
+		
+		// Always Implicit VR
+		Uint32 vl;
+		(*stream) >> vl;
+		if (stream->fail()) {
+			errorstream << EMsgDC(VLReadFailed) << endl;
+			good_flag=false;
+			return;
+		}
+		byteoffset+=4;
+
+		if (verbose) {
+			writebase(tag,"",vl); (*log) << endl;
+		}
+
+		if (tag == TagFromName(SequenceDelimitationItem)
+		 || tag == Tag(0xfeff,0xdde0)				// GE bug
+		 || tag == Tag(0xe0dd,0xfffe)				// GE bug
+		) {
+			return;
+		}
+
+		// If GE byte order bug is present, need to swap vl bytes ...
+
+		if (tag != TagFromName(Item)) {		// don't actually check for 0xfeff,0x00e0 or 0xe000,0xfffe
+//cerr << "ReadableAttributeList::skipEncapsulatedData: got possible bad byte order VL of 0x" << hex << vl << dec << endl;
+			vl=(((Uint32)vl&0xff000000)>>24)
+			  +(((Uint32)vl&0x00ff0000)>>8)
+			  +(((Uint32)vl&0x0000ff00)<<8)
+			  +(((Uint32)vl&0x000000ff)<<24);
+//cerr << "ReadableAttributeList::skipEncapsulatedData: assuming VL has bad byte order, using 0x" << hex << vl << dec << endl;
+		}
+
+		//stream->seekg(vl,ios::cur); 
+		//if (stream->fail()) {
+		if (skipBytes(stream,vl) != vl || stream->fail()) {
+			errorstream << EMsgDC(SeekFailed)
+				    << " - while skipping encapsulated data"
+				    << endl;
+			good_flag=false;
+			return;
+		}
+		byteoffset+=vl;
+	}
+}
+
+SequenceAttribute *
+ReadableAttributeList::readNewSequenceAttribute(Tag stag,Uint32 length,bool ignoreoutofordertags,bool useUSVRForLUTDataIfNotExplicit,bool undefinedLengthUNTreatedAsSequence,const char *sequenceOwner)
+{
+//cerr << "readNewSequenceAttribute(): start: undefinedLengthUNTreatedAsSequence = " << (undefinedLengthUNTreatedAsSequence ? "T" : "F") << endl;
+//cerr << "readNewSequenceAttribute(): start: length = " << dec << length << endl;
+cerr << "readNewSequenceAttribute(): start: sequenceOwner = \"" << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"" << endl;
+	bool showoffset=verbose;
+	SequenceAttribute *a=new SequenceAttribute(stag);
+//cerr << "readNewSequenceAttribute(): created empty tag - isEmpty()=" << a->isEmpty() << endl;
+//cerr << "readNewSequenceAttribute(): created empty tag - isOne()=" << a->isOne() << endl;
+//cerr << "readNewSequenceAttribute(): created empty tag - isMultiple()=" << a->isMultiple() << endl;
+	Uint32 startbyteoffset=byteoffset;
+//cerr << "readNewSequenceAttribute(): start: startbyteoffset = " << dec << startbyteoffset << endl;
+	bool done=false;
+	while (!done && (byteoffset < startbyteoffset+length || length == 0xffffffff)) {
+//cerr << "readNewSequenceAttribute(): start: byteoffset = " << dec << byteoffset << endl;
+		// Expecting Item or SequenceDelimitationItem
+		if (verbose && showoffset) dumpOffset(log,byteoffset,stream,length);
+		Tag tag;
+		(*stream) >> tag;
+		if (stream->fail()) {
+			errorstream << EMsgDC(TagReadFailed) << endl;
+			good_flag=false;
+			return 0;
+		}
+		byteoffset+=4;
+
+		// Always Implicit VR
+		Uint32 vl;
+		(*stream) >> vl;
+		if (stream->fail()) {
+			errorstream << EMsgDC(VLReadFailed) << endl;
+			good_flag=false;
+			return 0;
+		}
+		byteoffset+=4;
+		Uint32 itemstartbyteoffset=byteoffset;
+
+		if (verbose) {
+			writebase(tag,"",vl); (*log) << endl;
+		}
+		
+		if (tag == TagFromName(SequenceDelimitationItem)
+		 || tag == Tag(0xffe0,0xe0dd)				// GE bug
+		) {
+			if (tag != TagFromName(SequenceDelimitationItem)) {
+//cerr << "Ignoring GE Sequence Delimitation Item encoding bug" << endl;
+				errorstream << WMsgDC(IgnoringGESequenceDelimitationItemEncodingBug) << endl;
+			}
+			if (length != 0xffffffff) {
+				errorstream << WMsgDC(UnexpectedSequenceDelimiterInFixedLengthSequence) << endl;
+				if (byteoffset < startbyteoffset+length) {
+					errorstream << WMsgDC(PrematureEndOfSequence) << endl;
+				}
+			}
+			done=true;	// Force loop exit
+			continue;	// Normal exit path for delimited sequences - don't just break here, in case length was specified - need to detect that error
+		}
+		if (tag == TagFromName(Item)) {
+//cerr << "readNewSequenceAttribute(): Item" << endl;
+			ReadableAttributeList *item=new ReadableAttributeList();
+			Assert(item);
+			ElementDictionary *newdict=new ElementDictionary();
+			Assert(newdict);
+			bool result=item->read(*stream,newdict,log,verbose,vl,false/*metaheadercheck*/,false/*uselengthtoend*/,ignoreoutofordertags,useUSVRForLUTDataIfNotExplicit,undefinedLengthUNTreatedAsSequence/*forceImplicit*/,false/*useStopAtTag*/,Tag(0,0)/*stopAtTag*/,true/*nestedWithinSequence*/,sequenceOwner);
+			const char *e=item->errors();
+			if (e) errorstream << e;	// may be warnings
+			if (!result) {
+				errorstream << EMsgDC(SequenceItemReadFailed) << endl;
+//cerr << "readNewSequenceAttribute(): Item error exit" << endl;
+				good_flag=false;
+				return 0;
+			}
+			byteoffset+=item->getByteOffset();
+			(*a)+=item;
+//cerr << "readNewSequenceAttribute(): added item - isEmpty()=" << a->isEmpty() << endl;
+//cerr << "readNewSequenceAttribute(): added item - isOne()=" << a->isOne() << endl;
+//cerr << "readNewSequenceAttribute(): added item - isMultiple()=" << a->isMultiple() << endl;
+			if (vl != 0xffffffff && byteoffset != itemstartbyteoffset+vl) {
+				TextOutputStream terr(errorstream.rdbuf());
+				stag.write(terr,dictionary);
+				errorstream << " - " << EMsgDC(BadSequenceItemValueLength)
+					<< " - " << MMsgDC(ActualLength) << " " << hex << (byteoffset-itemstartbyteoffset)
+					<< " " << MMsgDC(NotEqualTo) << " " << MMsgDC(SpecifiedLength) << " " << vl << dec
+					<< endl;
+				good_flag=false;
+			}
+//cerr << "readNewSequenceAttribute(): Item done" << endl;
+		}
+		else {
+			TextOutputStream terr(errorstream.rdbuf());
+			stag.write(terr,dictionary);
+			terr << " - " << EMsgDC(BadTagInSequence) << " - got - ";
+			tag.write(terr,dictionary);
+			terr << " - " << MMsgDC(ExpectingItemOrSequenceDelimiter);
+			long bytesToSkip = 0;
+			if (length == 0xffffffff) {
+				terr << " - " << MMsgDC(SkippingBadTagInsideUndefinedLengthSequence) << endl;
+				bytesToSkip = vl;
+			}
+			else {
+				terr << " - " << MMsgDC(SkippingToEndOfEnclosingFixedLengthSequence) << endl;
+				bytesToSkip = length - (byteoffset-startbyteoffset);
+			}
+//cerr << "readNewSequenceAttribute(): bytesToSkip = " << dec << bytesToSkip << endl;
+			if (skipBytes(stream,bytesToSkip) != bytesToSkip || stream->fail()) {
+				errorstream << EMsgDC(SeekFailed)
+					<< " - " << MMsgDC(WhileSkipping)
+					<< endl;
+				good_flag=false;
+				return 0;
+			}
+			byteoffset+=bytesToSkip;
+		}
+	}
+	if (length != 0xffffffff && byteoffset != startbyteoffset+length) {
+		TextOutputStream terr(errorstream.rdbuf());
+		stag.write(terr,dictionary);
+		errorstream << " - " << EMsgDC(BadSequenceValueLength)
+			    << " - " << MMsgDC(ActualLength) << " " << hex << (byteoffset-startbyteoffset)
+			    << " " << MMsgDC(NotEqualTo) << " " << MMsgDC(SpecifiedLength) << " " << length << dec
+			    << endl;
+		good_flag=false;
+	}
+	//if (stream->fail()) good_flag=false;		// this seems to fail on AMD64 Linux with Siemens PDI 2004 DICOMDIR :(
+//cerr << "readNewSequenceAttribute(): done good_flag=" << good_flag << endl;
+	//return good_flag ? a : NULL;
+	return a;
+}
+
+ReadableAttributeList::ReadableAttributeList(void)
+	: ErrorsInClass()
+{
+	stream=0;
+	dictionary=0;
+	log=0;
+	verbose=false;
+	byteoffset=0;
+}
+
+ReadableAttributeList::~ReadableAttributeList()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "ReadableAttributeList::~ReadableAttributeList" << endl;
+#endif
+}
+
+bool
+ReadableAttributeList::read(DicomInputStream& str,ElementDictionary* dict,TextOutputStream* l,bool v,Uint32 length,
+	bool metaheadercheck,bool uselengthtoend,bool ignoreoutofordertags,bool useUSVRForLUTDataIfNotExplicit,bool forceImplicit,bool useStopAtTag,Tag stopAtTag,bool nestedWithinSequence,const char *sequenceOwner)
+{
+//cerr << "ReadableAttributeList::read - start: forceImplicit = " << (forceImplicit ? "T" : "F") << endl;
+//cerr << "ReadableAttributeList::read nestedWithinSequence = " << (nestedWithinSequence ? "T" : "F") << endl;
+cerr << "ReadableAttributeList::read sequenceOwner = \"" << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"" << endl;
+	stream=&str;
+	dictionary=dict;
+	log=l;
+	verbose=v;
+
+	bool showoffset=v;
+
+	bool allUSSeemToBeByteSwapped=false;	// detect a very unusual and peculiar bug in some images
+	Endian forcePixelDataEndian=NoEndian;	// leave it to the transfer syntax, unless peculiar circumstances arise (allUSSeemToBeByteSwapped is true)
+	bool donewithmetaheader=!metaheadercheck;
+	Uint32 startbyteoffset=byteoffset;
+	Uint32 dicomdirposition=0xffffffff;
+	bool oldtagvalid=false;
+	Tag oldtag;
+	bool grouplengthcheck=false;
+	Uint32 groupbyteoffsetafterlength=0;	// not used unless grouplengthcheck, but shuts up warning
+	Uint32 grouplengthexpected=0;		// not used unless grouplengthcheck, but shuts up warning
+	while (stream->peek() != istream::traits_type::eof() && (byteoffset < startbyteoffset+length || length == 0xffffffff)) {
+//cerr << "ReadableAttributeList::read - looping (donewithmetaheader is " << (donewithmetaheader ? "true" : "false") << ")" << endl;
+
+//{
+//TransferSyntax *ts = stream->getTransferSyntaxInUse();
+//cerr << "ReadableAttributeList::read getTransferSyntaxInUse(): uid = " << ts->getUID() << endl;
+//cerr << "ReadableAttributeList::read getTransferSyntaxInUse(): description = " << ts->getDescription() << endl;
+//cerr << "ReadableAttributeList::read getTransferSyntaxInUse(): encapsulated = " << (ts->getEncapsulated() ? "true" : "false") << endl;
+//}
+
+		//unsigned long position=stream->rdbuf()->PubSeekOff(0,ios::cur);
+		unsigned long position=(unsigned long)stream->tellg();
+
+		dicomdirposition=position;	// includes preamble and "DICM"
+
+		if (verbose && showoffset) dumpOffset(log,byteoffset,stream,length);
+		Tag tag;
+		(*stream) >> tag;
+		if (stream->fail()) {
+			errorstream << WMsgDC(TagReadFailed) << endl;
+			//good_flag=false;
+			//return false;
+			if (verbose && showoffset) (*log) << endl;
+			return true;
+		}
+{ TextOutputStream terr(cerr.rdbuf()); terr << "ReadableAttributeList::read(): tag = "; tag.write(terr,dictionary); terr << endl; }
+		// this next would fail if endian changed and first group was 0x0200 !
+
+		if (!donewithmetaheader && !tag.isMetaheaderGroup()) {
+//cerr << "ReadableAttributeList::read(): Changing from metaheader to dataset" << endl;
+			if (stream->getTransferSyntaxToReadDataSet()) {
+//cerr << "ReadableAttributeList::read(): There is a dataset transfer syntax" << endl;
+				stream->readingDataSet();
+				donewithmetaheader=true;
+				// backup and read again in case endian changed ...
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+cerr << endl << "Before endian check backup @";
+writeZeroPaddedHexNumber(cerr,position,8);
+cerr << "(";
+writeZeroPaddedHexNumber(cerr,stream->rdbuf()->PubSeekOff(0,ios::cur));
+cerr << ")"
+     << ": ";
+#endif
+				stream->seekg(-4l,ios::cur);
+				if (stream->fail()) {
+					errorstream << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+					good_flag=false;
+					return false;
+				}
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+cerr << endl << "Before endian check backup @";
+writeZeroPaddedHexNumber(cerr,position,8);
+cerr << "(";
+writeZeroPaddedHexNumber(cerr,stream->rdbuf()->PubSeekOff(0,ios::cur));
+cerr << ")"
+    << ": " << endl;
+#endif
+				(*stream) >> tag;
+				if (stream->fail()) {
+					errorstream << WMsgDC(TagReadFailed) << endl;
+					//good_flag=false;
+					//return false;
+					if (verbose && showoffset) (*log) << endl;
+					return true;
+				}
+			}
+			else {
+				errorstream << EMsgDC(NoTransferSyntaxInMetaHeader) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+		}
+
+		if (oldtagvalid) {
+			if (tag < oldtag) {
+			//if (tag <= oldtag) {
+				errorstream << (ignoreoutofordertags ? WMsgDC(TagsOutOfOrder) : EMsgDC(TagsOutOfOrder)) << endl;
+				//good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				if (!ignoreoutofordertags) return false;
+			}
+			else if (tag == oldtag) {
+				TextOutputStream terr(errorstream.rdbuf());
+				oldtag.write(terr,dictionary);
+				errorstream << EMsgDC(TagsDuplicated) << endl;
+				good_flag=false;
+				// don't return ... can keep reading
+			}
+ 			if (tag.getGroup() != oldtag.getGroup() && grouplengthcheck) {
+				Uint32 actualgrouplength=byteoffset-groupbyteoffsetafterlength;
+				if (grouplengthexpected != actualgrouplength) {
+					errorstream << WMsgDC(BadGroupLength)
+						    << " - " << MMsgDC(Group) << " " << hex << oldtag.getGroup()
+						    << " " << MMsgDC(SpecifiedAs) << " " << hex << grouplengthexpected
+						    << " " << MMsgDC(Actually) << " " << hex << actualgrouplength
+						    << dec << endl;
+				}
+				grouplengthcheck=false;
+			}
+		}
+		oldtag=tag;
+		oldtagvalid=true;
+
+		byteoffset+=4;
+
+		if (useStopAtTag && tag == stopAtTag) {
+//cerr << "read: stopped at " << byteoffset << endl;
+			return true;
+		}
+				
+		if (tag == TagFromName(ItemDelimitationItem)
+		 || tag == Tag(0xffe0,0xe00d)					// GE bug
+		) {
+//cerr << "ReadableAttributeList::read - ItemDelimitationItem" << endl;
+			if (tag != TagFromName(ItemDelimitationItem)) {
+				errorstream << WMsgDC(IgnoringGEItemDelimitationItemEncodingBug) << endl;
+			}
+			// Read and discard value length
+			(void)stream->read32();
+			if (stream->fail()) {
+				errorstream << EMsgDC(VLReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+			byteoffset+=4;
+			if (byteoffset < startbyteoffset+length && length != 0xffffffff) {
+				errorstream << WMsgDC(PrematureEndOfItem) << endl;
+			}
+			length=0;	// Force loop exit
+			continue;	// Normal exit path for delimited items
+		}
+
+		if (tag == TagFromName(Item)) {
+			// this is bad ... there shouldn't be Items here since they should
+			// only be found during readNewSequenceAttribute()
+			// however, try to work around Philips bug ...
+			// Read and discard value length
+			(void)stream->read32();
+			if (stream->fail()) {
+				errorstream << EMsgDC(VLReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+			byteoffset+=4;
+			errorstream << WMsgDC(BadItemInItem) << endl;
+			continue;	// let's just ignore it for now
+		}
+
+		// need to have owner in dictionary BEFORE calling getValueRepresentation()
+		if (tag.isPrivateGroup() && !tag.isPrivateOwner() && !dictionary->hasOwner(tag)) {
+cerr << "ReadableAttributeList::read - tag is private without owner, have sequenceOwner = " << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"" << endl;
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			errorstream << " - " << WMsgDC(PrivateTagWithoutOwner);
+			
+			if (sequenceOwner != NULL) {
+				errorstream << " - use owner of parent sequence \"" << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"";
+				// need to make a simulated private owner that specifies the block used by the current tag
+				dictionary->addOwner(Tag(tag.getGroup(),(tag.getElement()>>8)&0xff),sequenceOwner);
+			}
+			errorstream << endl;
+		}
+
+		char vre[3];
+		bool readAsImplicitRegardless = forceImplicit;
+		const char *vr = NULL;
+		Uint32 vl = 0;
+		bool tryAgain = false;
+		Uint32 vrstartbyteoffset = byteoffset;
+		do {
+			vr=getValueRepresentation(tag,vre,readAsImplicitRegardless);	// readAsImplicitRegardless may be set on return even if forceImplicit was false
+			if (stream->fail()) {
+				errorstream << EMsgDC(VRReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+
+			// Make sure to use the VR for the input, even if overridden by dictionary VR
+			// to select the VL encoding method in the input ...
+
+			vl=getValueLength(stream->getTransferSyntaxInUse()->isExplicitVR() ? vre : vr,readAsImplicitRegardless);
+			if (stream->fail()) {
+				errorstream << EMsgDC(VLReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+//cerr << "Value length = 0x" << hex << vl << endl;
+			if (length != 0xffffffff && vl != 0xffffffff && vl > (byteoffset-startbyteoffset+length)) {
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				terr << " - ";
+//cerr << "Value length exceeds fixed length for reading dataset" << endl;
+				if (!tryAgain && readAsImplicitRegardless && stream->getTransferSyntaxInUse()->isExplicitVR()) {
+//cerr << "Since readAsImplicitRegardless was set, try reading VL again without forcing implicit" << endl;
+					// could be because even though supposed to be implicit VR inside UN sequence, is actually explicit :( (000286)
+					// try again without forcing explicit
+					terr << EMsgDC(IncorrectExplicitVRInsideFixedLengthSequenceEncodedAsUnknownVR) << endl;
+					// backup to start of VR and re-read VR and VL
+					long backup = byteoffset-vrstartbyteoffset;
+//cerr << "backup bytes = " << dec << (-backup) << endl;
+					stream->seekg(-backup,ios::cur);
+					if (stream->fail()) {
+						tag.write(terr,dictionary);
+						terr << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+						good_flag=false;
+						return 0;
+					}
+					byteoffset=vrstartbyteoffset;
+					readAsImplicitRegardless = false;
+					tryAgain = true;
+					continue;
+				}
+				else {
+					// not sure what to do here - skip to end of fixed length dataset, potentially allowing resumption if inside sequence item ? :(
+					// turns out to be better not to skip ... allows later detection of when actual sequence length does not match defined length, though sequence can be successfully read, which sometimes happens
+					terr << EMsgDC(ValueLengthExceedsFixedLengthForReadingDataset) << " - " << MMsgDC(Ignoring) << endl;
+					//Uint32 skiptoend = byteoffset-startbyteoffset+length;
+					////stream->seekg(skiptoend,ios::cur);
+					////if (stream->fail()) {
+					//if (skipBytes(stream,skiptoend) != skiptoend || stream->fail()) {
+					//	tag.write(terr,dictionary);
+					//	terr << EMsgDC(SeekFailed)
+					//		<< endl;
+					//	good_flag=false;
+					//	return false;
+					//}
+					//byteoffset+=skiptoend;
+				}
+			}
+			tryAgain = false;
+		} while (tryAgain);
+		
+		if (ignoreoutofordertags && vl > 0xffff && stream->getTransferSyntaxInUse()->isImplicitVR()) {
+			// there are occasions when buggy files will have some elements encoded with explicit rather than implicit VR
+			// check here to see if first two bytes are actually a VR ... if so, assume the presence of this bug and repair
+			char vrtest[3];
+			vrtest[0] = vl & 0xff;			// implicit is always little endian
+			vrtest[1] = (vl >> 8) & 0xff;
+			vrtest[2] = 0;
+			if (isKnownExplicitValueRepresentation(vrtest)) {
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				terr << " - " << WMsgDC(DataElementEncodedAsExplicitInImplicitVRTransferSyntax) << " - ignoring explicit VR <" << vrtest << "> and trying to recover short VL" << endl;
+				vl = (vl >> 16) &0xffff;
+				// ignore "explicit" VR, since experience suggests that it will be "wrong" when this bug occurs
+			}
+		}
+		
+		if (vl != 0xffffffff & vl%2 != 0) {
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			terr << " - " << EMsgDC(BadValueLengthNotEven) << " - VL is " << hex << vl << " should be " << (vl+1) << dec << endl;
+			good_flag=false;
+		}
+//cerr << "ReadableAttributeList::read VL  = 0x" << hex << vl << dec << endl;
+
+		Attribute *a=0;
+
+		const char *vrd = dictionary->getValueRepresentation(tag);
+		bool treatedUnknownVRAsSequence = isUnknownVR(vr) && (vl == 0xffffffff || (vrd && strncmp(vrd,"SQ",2) == 0));
+		if (isSequenceVR(vr) || treatedUnknownVRAsSequence) {
+			if (verbose) { writebase(tag,vr,vl); (*log) << endl; }
+//cerr << "ReadableAttributeList::read - before readNewSequenceAttribute() good_flag = " << good_flag << endl;
+			const char *useSequenceOwner = dictionary->getOwner(tag);
+cerr << "ReadableAttributeList::read - useSequenceOwner from dictionary->getOwner(tag) = \"" << (useSequenceOwner ? useSequenceOwner : "--NULL--") << "\"" << endl;
+			if (!useSequenceOwner) {
+				useSequenceOwner = sequenceOwner;	// propagate owner of successively nested sequences (really should check group and block, but since this is non-standard anyway ... :( )
+cerr << "ReadableAttributeList::read - useSequenceOwner from parent = \"" << (useSequenceOwner ? useSequenceOwner : "--NULL--") << "\"" << endl;
+			}
+			a=readNewSequenceAttribute(tag,vl,ignoreoutofordertags,useUSVRForLUTDataIfNotExplicit,
+				forceImplicit || treatedUnknownVRAsSequence,		/* once inside UN SQ, always implicit, even if nested */
+				useSequenceOwner									/* in case nested lists are missing owner, propagate owner of the sequence tag itself, if private, or its parent, if missing its own owner */
+				);
+//cerr << "ReadableAttributeList::read - back from readNewSequenceAttribute() with a = " << (a == NULL ? "null" : "valid") << endl;
+//cerr << "ReadableAttributeList::read - back from readNewSequenceAttribute() with stream->fail() = " << stream->fail() << endl;
+//cerr << "ReadableAttributeList::read - back from readNewSequenceAttribute() good_flag = " << good_flag << endl;
+			if (!a) {	// hmm; should check good_flag ? :(
+				errorstream << EMsgDC(SeqAttrReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+			// byteoffset already updated by readNewSequenceAttribute()
+		}
+		else if (tag.isPixelDataElement()) {
+//cerr << "ReadableAttributeList::read PixelData" << endl;
+			if (isOtherByteOrWordVR(vr)) {
+//cerr << "ReadableAttributeList::read OX PixelData" << endl;
+				Uint16 vBitsAllocated=AttributeValue(operator[](TagFromName(BitsAllocated)));
+				Uint16 vBitsStored=AttributeValue(operator[](TagFromName(BitsStored)));
+				Uint16 vHighBit=AttributeValue(operator[](TagFromName(HighBit)));
+				if (!vBitsAllocated && vBitsStored) vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+				if (!vBitsAllocated) vBitsAllocated=16;
+				if (!vBitsStored) vBitsStored=vBitsAllocated;
+				if (!vHighBit) vHighBit=vBitsStored-1u;
+				if (vHighBit > (vBitsStored-1u)) {
+					errorstream << WMsgDC(BadAttributeValue)
+						    << " - High Bit = " << vHighBit
+						    << " " << MMsgDC(Exceeds) << " " << (vBitsStored-1u)
+						    << endl;
+				}
+				if (vHighBit > (vBitsAllocated-1u)) {
+					errorstream << EMsgDC(BadAttributeValue)
+						    << " - High Bit = " << vHighBit
+						    << " " << MMsgDC(Exceeds) << " " << (vBitsAllocated-1u)
+						    << " " << MMsgDC(Using) << " " << (vBitsAllocated-1u)
+						    << endl;
+					vHighBit=vBitsAllocated-1u;
+					operator-=(TagFromName(HighBit));
+					UnsignedShortAttribute *aHighBit=new UnsignedShortAttribute(TagFromName(HighBit),vHighBit);
+					Assert(aHighBit);
+					operator+=(aHighBit);
+				}
+				if (vHighBit < (vBitsStored-1u)) {
+					errorstream << WMsgDC(BadAttributeValue)
+						    << " - Bits Stored = " << vBitsStored
+						    << " " << MMsgDC(Exceeds) << " High Bit " << vHighBit << " + 1"
+						    << " " << MMsgDC(Using) << " " << (vHighBit+1u)
+						    << endl;
+					vBitsStored=vHighBit+1u;
+					operator-=(TagFromName(BitsStored));
+					UnsignedShortAttribute *aBitsStored=new UnsignedShortAttribute(TagFromName(BitsStored),vBitsStored);
+					Assert(aBitsStored);
+					operator+=(aBitsStored);
+				}
+				if (vl == 0xffffffff) {
+//cerr << "ReadableAttributeList::read Pixel Data has undefined length VL" << endl;
+					if (stream->getTransferSyntaxInUse()->isEncapsulated()) {
+						a=new OtherUnspecifiedLargeAttributeEncapsulated(
+							tag,
+							*stream,
+							stream->tellg(),
+							AttributeValue(operator[](TagFromName(Rows))),
+							AttributeValue(operator[](TagFromName(Columns))),
+							AttributeValue(operator[](TagFromName(NumberOfFrames)),1),
+							AttributeValue(operator[](TagFromName(SamplesPerPixel)),1),
+							vBitsAllocated,
+							vBitsStored,
+							vHighBit
+						);
+						// skip the blocked data (we don't know its length)...
+						skipEncapsulatedData();	// increments byteoffset as it skips
+						if (verbose) { a->write(*log,dictionary); (*log) << endl; }
+						//byteoffset+=vl;	// already done in skipEncapsulatedData()
+					}
+					else {
+						errorstream << EMsgDC(UndefinedVLForOX) << endl;
+						good_flag=false;
+						if (verbose && showoffset) (*log) << endl;
+						return false;
+					}
+				}
+				else {
+//cerr << "ReadableAttributeList::read Pixel Data has defined length VL" << endl;
+					if (stream->getTransferSyntaxInUse()->isEncapsulated() && !nestedWithinSequence) {
+						errorstream << EMsgDC(IllegalVLForPixelDataInEncapsulatedTransferSyntaxInTopLevelDataset) << endl;
+						if (verbose && showoffset) (*log) << endl;
+						// do not return false but keep going anyway, and do not negate good_flag, since should be able to read it and no need to fail reading of entire dataset
+					}
+					{
+//cerr << "ReadableAttributeList::read vl=" << hex << vl << dec << endl;
+						Uint16 bytesinword = (Uint16)(vr[1] == 'W' ? 2 : (vr[1] == 'B' ? 1 : 0));
+						if (vBitsAllocated > 8 && isOtherByteVR(vr) && stream->getTransferSyntaxInUse()->isExplicitVR()) {
+								errorstream << EMsgDC(BadValueRepresentation)
+								    << " - Pixel Data - VR = OB, Explicit VR, Bits Allocated = " << vBitsAllocated
+								    << " " << MMsgDC(Exceeds) << " 8"
+								    << endl;
+							bytesinword=2;		// force OW to make it usable
+						}
+						a=new OtherUnspecifiedLargeAttributeCopied(
+							tag,
+							*stream,
+							stream->tellg(),
+							AttributeValue(operator[](TagFromName(Rows))),
+							AttributeValue(operator[](TagFromName(Columns))),
+							AttributeValue(operator[](TagFromName(NumberOfFrames)),1),
+							AttributeValue(operator[](TagFromName(SamplesPerPixel)),1),
+							bytesinword,
+							vBitsAllocated,
+							vBitsStored,
+							vHighBit,
+							vl,
+							forcePixelDataEndian
+						);
+						//stream->seekg(vl,ios::cur);
+						//if (stream->fail()) {
+						if (skipBytes(stream,vl) != vl || stream->fail()) {
+							errorstream << EMsgDC(SeekFailed)
+								    << " - while reading unencapsulated Pixel Data"
+								    << endl;
+							good_flag=false;
+							return false;
+						}
+						if (verbose) { a->write(*log,dictionary); (*log) << endl; }
+						byteoffset+=vl;
+					}
+				}
+			}
+			else {
+//cerr << "ReadableAttributeList::read PixelData not OX" << endl;
+				errorstream << EMsgDC(IllegalVRForPixelData) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+		}
+		else {
+//cerr << "ReadableAttributeList::read non-PixelData" << endl;
+			if (tag == TagFromName(WaveformData)) {
+//cerr << "ReadableAttributeList::read WaveformData" << endl;
+				Uint16 vWaveformBitsAllocated=AttributeValue(operator[](TagFromName(WaveformBitsAllocated)));
+				if (vWaveformBitsAllocated > 8) {
+					if (isOtherByteVR(vr) && stream->getTransferSyntaxInUse()->isExplicitVR()) {
+						errorstream << EMsgDC(BadValueRepresentation)
+							<< " - Waveform Data - VR = OB, Explicit VR, Waveform Bits Allocated = " << vWaveformBitsAllocated
+							<< " " << MMsgDC(Exceeds) << " 8"
+							<< endl;
+						if (stream->getTransferSyntaxInUse()->isLittleEndian()) {
+//cerr << "ReadableAttributeList::forcing WaveformData VR from OB to OW since > 8 bit, explicit VR and little endian" << endl;
+							vr="OW";
+						}
+						// else cannot recover to OW without byte swapping, which is too hard at this point :(
+					}
+					else {
+						if (strcmp(vr,"OX") == 0) {
+//cerr << "ReadableAttributeList::using OW for > 8 bit WaveformData in implicit VR" << endl;
+							vr="OW";
+						}
+					}
+				}
+				else {
+					if (strcmp(vr,"OX") == 0) {
+//cerr << "ReadableAttributeList::using OB for <= 8 bit WaveformData in implicit VR" << endl;
+						vr="OB";
+					}
+				}
+			}
+			
+			if (isOtherByteOrWordVR(vr)) {
+				// PixelData already handled specially
+				if (strcmp(vr,"OX") == 0) {
+					if (tag == TagFromName(OverlayData)) {
+						vr="OW";
+					}
+					else if (tag == TagFromName(CurveData)) {
+						vr="OB";
+					}
+					else {
+						vr="OB";
+					}
+				}
+				if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+					if (strcmp(vr,"OB") == 0)
+						a=new OtherByteSmallNonPixelAttribute(tag);
+					else if (strcmp(vr,"OW") == 0)
+						a=new OtherWordSmallNonPixelAttribute(tag);
+					else { Assert(0); }
+				}
+				else {
+					if (strcmp(vr,"OB") == 0)
+						a=new OtherByteLargeNonPixelAttribute(tag,
+							*stream,
+							stream->tellg());
+					else if (strcmp(vr,"OW") == 0)
+						a=new OtherWordLargeNonPixelAttribute(tag,
+							*stream,
+							stream->tellg());
+					else { Assert(0); }
+					// the skipping and vl setting is done later in read()
+				}
+			}
+			else if (isOtherFloatVR(vr)) {
+				//if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+				//	a=new OtherFloatSmallAttribute(tag);
+				//}
+				//else {
+					a=new OtherFloatLargeAttribute(tag,
+							*stream,
+							stream->tellg());
+					// the skipping and vl setting is done later in read()
+				//}
+			}
+			else if (isUnknownVR(vr)) {
+				if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+					a=new UnknownSmallAttribute(tag);
+				}
+				else {
+					a=new UnknownLargeAttribute(tag,
+							*stream,
+							stream->tellg());
+					// the skipping and vl setting is done later in read()
+				}
+			}
+			else if (tag == TagFromName(LUTData) && strcmp(vr,"XO") == 0 && useUSVRForLUTDataIfNotExplicit) {
+//cerr << "ReadableAttributeList::read(): using US VR for LUT Data" << endl;
+				a=new UnsignedShortAttribute(tag);
+			}
+			else {
+				a=newAttribute(vr,tag);
+				if (!a) {
+					TextOutputStream terr(errorstream.rdbuf());
+					tag.write(terr,dictionary);
+					errorstream << WMsgDC(VRUnsupported) << " - <" << vr[0] << vr[1] << ">" << endl;
+				}
+			}
+
+			if (a) {
+				if (vl%a->getValueSize() != 0) {
+					TextOutputStream terr(errorstream.rdbuf());
+					tag.write(terr,dictionary);
+					terr << " - " << EMsgDC(VLDoesNotMatchVR) << " - value length = " << dec << vl << " dec - expected multiple of " << a->getValueSize() << " - skipping value length bytes to next data element" << endl;
+					good_flag=false;
+					if (verbose && showoffset) (*log) << endl;
+					// do not give up though - just skip it
+					if (skipBytes(stream,vl) != vl || stream->fail()) {
+						errorstream << EMsgDC(SeekFailed)
+							<< " - while skipping value of length " << dec << vl << " dec"
+							<< endl;
+						good_flag=false;
+						return false;
+					}
+				}
+				else {
+					a->read(*stream,vl);
+				}
+				if (stream->fail()) {
+					errorstream << EMsgDC(AttributeReadFailed) << endl;
+					good_flag=false;
+					if (verbose && showoffset) (*log) << endl;
+					return false;
+				}
+				if (verbose) { a->write(*log,dictionary); (*log) << endl; }
+#define FIXUPSWAPPEDUS
+#ifdef FIXUPSWAPPEDUS
+				if (strcmp(a->getVR(),"US") == 0 && a->getVM() == 1) {
+					Uint16 value;
+					if (a->getValue(0,value)) {
+						if (tag == TagFromName(SamplesPerPixel)) {		// check the first US we are likely to encounter
+							if (value > 255) {
+								allUSSeemToBeByteSwapped=true;
+								forcePixelDataEndian=BigEndian;
+								errorstream << EMsgDC(BadEncoding) << " - detected swapped bytes of US and pixel data values - fixing" << endl;
+							}
+						}
+						if (allUSSeemToBeByteSwapped) {
+							value = ((value&0xff)<<8)|(((value&0xff00)>>8)&0xff);
+							a->setValue(0,value);
+							if (verbose) { (*log) << "Fixup swapped US VR: "; a->write(*log,dictionary); (*log) << endl; }
+						}
+					}
+				}
+#endif
+
+				byteoffset+=vl;
+				if (tag == TagFromName(TransferSyntaxUID)) {
+					const char *newTransferSyntaxUID = AttributeValue(a);
+					if (donewithmetaheader) {
+						errorstream << EMsgDC(UnexpectedTransferSyntaxUIDOutsideMetaInformationHeader) << " - ignoring - " << newTransferSyntaxUID << endl;
+					}
+					else {
+//cerr << "ReadableAttributeList::read() encountered TransferSyntaxUID - before changing getTransferSyntaxInUse()->isEncapsulated() " << (stream->getTransferSyntaxInUse()->isEncapsulated() ? "true" : "false") << endl;
+//cerr << "ReadableAttributeList::read() encountered TransferSyntaxUID - setting transfer syntax to read data set to " << newTransferSyntaxUID << endl;
+						stream->setTransferSyntaxToReadDataSet(new TransferSyntax(newTransferSyntaxUID));
+//cerr << "ReadableAttributeList::read() encountered TransferSyntaxUID - after changing getTransferSyntaxInUse()->isEncapsulated() " << (stream->getTransferSyntaxInUse()->isEncapsulated() ? "true" : "false") << endl;
+					}
+				}
+				else if (tag == TagFromName(FileMetaInformationVersion)) {
+					// check this is correct here ... easier than elsewhere
+					// and this is the only place an OB is used like this
+					const unsigned char *value;
+					Uint32 length;
+					if (!a->isOtherByteNonPixel()
+					 || !a->getValue(value,length)
+					 || length != 2
+					 || *value != 0x00
+					 || *(value+1) != 0x01) {
+						errorstream << WMsgDC(BadFileMetaInformationVersion) << endl;
+					}
+				}
+				else if (tag.isLengthElement()) {
+					// Retired except for metaheader, but if you've got it check it
+					grouplengthexpected=Uint32(AttributeValue(a));
+					groupbyteoffsetafterlength=byteoffset;
+					grouplengthcheck=true;
+				}
+				else if (tag == TagFromName(LengthToEnd)
+					&& vl != 0 && length == 0xffffffff) {
+					// Retired, but if you've got it use it
+					if (uselengthtoend) length=byteoffset-startbyteoffset+Uint32(AttributeValue(a));
+				}
+				else if (tag.isPrivateGroup()) {
+					if (tag.isPrivateOwner()) {
+//cerr << "ReadableAttributeList::read adding owner" << endl;
+						if (tag.getElement() < 0x0010) {
+							TextOutputStream terr(errorstream.rdbuf());
+							tag.write(terr,dictionary);
+							errorstream << " - " << EMsgDC(BadPrivateOwner) << " - element must be greater than or equal to 0x0010" << endl;
+						}
+						char *s=AttributeValue(a);
+						if (s && *s) 
+							dictionary->addOwner(tag,s);
+						else {
+							TextOutputStream terr(errorstream.rdbuf());
+							tag.write(terr,dictionary);
+							errorstream << " - " << WMsgDC(BadPrivateOwner) << " - empty value" << endl;
+						}
+						if (s) delete[] s;
+					}
+					// PrivateTagWithoutOwner is handled earlier when establishing dictionary VR and need to possibly inherit parent sequence owner if owner missing within item dataset
+					//else {
+					//	if (!dictionary->hasOwner(tag)) {
+					//		TextOutputStream terr(errorstream.rdbuf());
+					//		tag.write(terr,dictionary);
+					//		errorstream << " - " << WMsgDC(PrivateTagWithoutOwner) << endl;
+					//	}
+					//}
+				}
+			}
+			else {
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				errorstream << WMsgDC(UnrecognizedOrUnsupportedTag) << endl;
+				if (verbose && showoffset) (*log) << endl;
+				//stream->seekg(vl,ios::cur);
+				//if (stream->fail()) {
+				if (skipBytes(stream,vl) != vl || stream->fail()) {
+					errorstream << EMsgDC(SeekFailed)
+						<< " - while skipping remainder of "
+						<< MMsgDC(UnrecognizedOrUnsupportedTag)
+						<< endl;
+					good_flag=false;
+					return false;
+				}
+				byteoffset+=vl;
+			}
+		}
+
+		if (a) {
+			a->setByteOffset(dicomdirposition);
+			operator+=(a);
+		}
+
+		// Need private owner & metaheader stuff here
+	}
+//cerr << "ReadableAttributeList::read - falling out at end byteoffset = " << hex << byteoffset << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end startbyteoffset = " << hex << startbyteoffset << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end length = " << hex << length << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end startbyteoffset+length = " << hex << (length == 0xffffffff ? 0xffffffff : (startbyteoffset+length)) << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end stream->fail() = " << stream->fail() << endl;
+	TransferSyntax *dts=stream->getTransferSyntaxToReadDataSet();
+	return ((dts && dts->isExplicitVR()) || setValueRepresentation())
+	    /*&& !stream->fail()*/;		// seems to fail inappropriately on AMD 64 Linux with Siemens PDI 2004 demo DICOMDIR :(
+}
+
diff --git a/libsrc/src/dctool/attrmxrd.cc b/libsrc/src/dctool/attrmxrd.cc
new file mode 100644
index 0000000..a319a50
--- /dev/null
+++ b/libsrc/src/dctool/attrmxrd.cc
@@ -0,0 +1,1217 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrmxrd.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrnew.h"
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "elmconst.h"
+#include "attrothr.h"
+#include "attrval.h"
+#include "mesgtext.h"
+
+// This may be defined in attrtype.h previously ...
+
+#ifndef LARGESTOTHERDATATOKEEPINMEMORY
+#define LARGESTOTHERDATATOKEEPINMEMORY 524288
+#endif
+
+// Want a routine to actually read rather than just use seekg(), since otherwise
+// there is no detection of failure to skip a truncated attribute at the end
+// of the dataset
+
+// Need to use Unit32 (NOT long) argument and return value, since may be larger than 2GB (e.g., for large uncompressed pixel data), and VL may be up to (2^32)-2 (000440)
+
+static Uint32
+skipBytes(istream *stream,Uint32 nSkip) {
+	bool success=true;
+	const int bufferSize=32768;
+	char buffer[bufferSize];
+	Uint32 totalSkipped=0;
+	while (nSkip > 0) {
+		int nToRead = nSkip > bufferSize ? bufferSize : (int)nSkip;
+		stream->read(buffer,nToRead);
+		if (stream->fail()) {
+			break;
+		}
+		int nActuallyRead = (int)(stream->gcount());
+		if (nActuallyRead == 0) {
+			break;
+		}
+		nSkip-=nActuallyRead;
+		totalSkipped+=nActuallyRead;
+	}
+	return totalSkipped;
+}
+
+TextOutputStream& 
+ReadableAttributeList::writebase(const Tag tag,const char *vr,Uint32 vl)
+{
+	Assert(log);
+	tag.write(*log,dictionary);
+	(*log) << "\t VR=<" << (vr ? vr : "") << ">  " << flush;
+	(*log) << " VL=<";
+	writeZeroPaddedHexNumber(*log,vl,4);
+	(*log) << ">  " << flush;
+	return (*log);
+}
+
+const char *
+ReadableAttributeList::getValueRepresentation(Tag tag,char *vrbuf,bool& readAsImplicitRegardless)
+{
+//cerr << "ReadableAttributeList::getValueRepresentation():" << endl;
+	// dictionary Value Representation expected
+
+//cerr << "ReadableAttributeList::getValueRepresentation tag.isPrivateGroup()" << (tag.isPrivateGroup() ? "true" : "false") << endl;
+//cerr << "ReadableAttributeList::getValueRepresentation tag.isPrivateOwner()" << (tag.isPrivateOwner() ? "true" : "false") << endl;
+	
+	const char *vrd=
+		(tag.isPrivateGroup() && tag.isPrivateOwner())
+			? "LO"	// PS3.5-7.8.1
+			: dictionary->getValueRepresentation(tag);
+
+	// explicit Value Representation in input
+
+	//readAsImplicitRegardless=false;
+	const char *vre;
+	//Assert(stream->getTransferSyntaxInUse()->isImplicitVR() != stream->getTransferSyntaxInUse()->isExplicitVR());
+	//if (stream->getTransferSyntaxInUse()->isExplicitVR()) {	// See [bugs.dicom3tools] (000130) as to why this and previous assertion commented out
+	if (!stream->getTransferSyntaxInUse()->isImplicitVR() && !readAsImplicitRegardless) {
+//cerr << "ReadableAttributeList::getValueRepresentation(): stream is explicit VR - reading VR" << endl;
+		stream->read(vrbuf,2);
+		if (stream->fail()) return 0;
+		if (vrbuf[0] == '-' && vrbuf[1] == '-') {	// illegal proprietary equivalent of UN VR used by Australian Central Data Networks (CDN) PACS
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			errorstream << EMsgDC(IllegalCDNHyphenVR) << endl;
+			byteoffset+=2;
+			vrbuf[0]=vrbuf[1]=vrbuf[2]=0;		// ignore whatever was read (vrbuf contents are tested by caller)
+			vre=0;								// will trigger return value based on dictionary lookup
+		}
+		else if (vrbuf[0] == 0 && vrbuf[1] == 0) {	// illegal two bytes of zero VR encountered in Sante de-identifier output (followed by two byte length)
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			errorstream << EMsgDC(IllegalZeroBytesWhenExplicitVRExpected) << endl;
+			byteoffset+=2;
+			vrbuf[0]=vrbuf[1]=vrbuf[2]=0;		// ignore whatever was read (vrbuf contents are tested by caller)
+			vre=0;								// will trigger return value based on dictionary lookup
+			// subsequent call to getValueLength() will guess that short form length is in use because no padding zero bytes
+		}
+		else if (vrbuf[0] < 'A' || vrbuf[1] < 'A') {		// DicomWorks bug ... occasional implicit VR attribute even though explicit transfer syntax
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			errorstream << EMsgDC(TagReadFailed) << " - " << MMsgDC(ImplicitVREncodingWhenExplicitRequired) << endl;
+//cerr << "ReadableAttributeList::getValueRepresentation(): implicit VR encoding even though supposed to be explicit" << endl;
+			good_flag=false;
+			// backup so that we treat the VR bytes as VL, and do not advance byteoffset
+			stream->seekg(-2l,ios::cur);
+			if (stream->fail()) {
+				tag.write(terr,dictionary);
+				errorstream << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+				good_flag=false;
+				return 0;
+			}
+			vrbuf[0]=vrbuf[1]=vrbuf[2]=0;		// ignore whatever was read (vrbuf contents are tested by caller)
+			readAsImplicitRegardless=true;
+			vre=0;					// will trigger return value based on dictionary lookup
+		}
+		else {
+			byteoffset+=2;
+			vrbuf[2]=0;
+			vre=vrbuf;
+		}
+	}
+	else
+		vre=0;
+
+	// if was Explicit VR, vrbuf is now set and can be used as return value
+
+	if (!vrd && vre) {
+		TextOutputStream terr(errorstream.rdbuf());
+		tag.write(terr,dictionary);
+		if (strncmp(vre,"UN",2) == 0) {
+			errorstream << " - " << WMsgDC(NoDictionaryVRUseExplicitUN) << endl;
+		}
+		else {
+			errorstream << " - " << WMsgDC(NoDictionaryVRUseExplicit) << endl;
+		}
+	}
+
+	// choose/match Value Representation to use
+
+	TextOutputStream terr(errorstream.rdbuf());
+	const char *vru;
+	if (vre && vrd) {
+		if (strncmp(vre,vrd,2) == 0) {
+			// Both present and same
+			vru=vre;
+		}
+		else if (strncmp(vre,"UN",2) == 0) {
+			if (strncmp(vrd,"SQ",2) == 0) {
+				vru=vre;	// Explicit overrides dictionary for sequence (since need to treat undefined length sequence content as implicit VR later)
+				//tag.write(terr,dictionary);
+				//errorstream << " - " << WMsgDC(MismatchDictionaryVR) << "; Explicit <" << vre << "> Dictionary <" << vrd << ">" << endl;
+			}
+			else {
+				// Replace explicit UN with dictionary only if not a sequence
+				vru=vrd;
+				//tag.write(terr,dictionary);
+				//errorstream << " - " << WMsgDC(OverridingUNWithDictionaryVR) << endl;
+			}
+		}
+		else if ((strncmp(vrd,"OX",2) == 0
+		          && (strncmp(vre,"OB",2) == 0
+		              || strncmp(vre,"OW",2) == 0)
+		         )
+		      || (strncmp(vrd,"XS",2) == 0
+		          && (strncmp(vre,"US",2) == 0
+		              || strncmp(vre,"SS",2) == 0)
+		         )
+		      || (strncmp(vrd,"XO",2) == 0
+		          && (strncmp(vre,"US",2) == 0
+		              || strncmp(vre,"SS",2) == 0
+		              || strncmp(vre,"OW",2) == 0)
+		         )
+		      || (strncmp(vrd,"XL",2) == 0
+		          && (strncmp(vre,"UL",2) == 0
+		              || strncmp(vre,"SL",2) == 0)
+			 )
+		      ) {
+			// Explicit overrides ambiguous in dictionary
+			vru=vre;
+		}
+		else {
+			vru=vre;	// Explicit overrides dictionary
+			tag.write(terr,dictionary);
+			errorstream << " - " << WMsgDC(MismatchDictionaryVR) << "; Explicit <" << vre << "> Dictionary <" << vrd << ">" << endl;
+		}
+	}
+	else if (vrd) {
+		vru=vrd;
+	}
+	else if (vre) {
+		vru=vre;
+	}
+	else {
+		vru="UN";
+	}
+
+	if (tag.isPrivateGroup() && tag.isPrivateOwner()) {
+		if (strncmp(vru,"LO",2) != 0) {
+			vru="LO";
+			tag.write(terr,dictionary);
+			errorstream << " - " << EMsgDC(PrivateCreatorIsNotLOVR) << "; Explicit <" << vre << "> " << MMsgDC(OverridingVR) << " with <LO>" << endl;
+		}
+	}
+	return vru;
+}
+
+
+
+
+Uint32
+ReadableAttributeList::getValueLength(const char *vr,bool readAsImplicitRegardless)
+{
+//cerr << "ReadableAttributeList::getValueLength(): vr=" << vr << endl;
+//cerr << "ReadableAttributeList::getValueLength(): readAsImplicitRegardless=" << readAsImplicitRegardless << endl;
+
+	Uint32 vl;
+	if (stream->getTransferSyntaxInUse()->isImplicitVR() || readAsImplicitRegardless) {
+//cerr << "ReadableAttributeList::getValueLength(): is implicit VR" << endl;
+		(*stream) >> vl;
+		byteoffset+=4;
+	}
+	else {
+//cerr << "ReadableAttributeList::getValueLength(): is explicit VR" << endl;
+		if (isUniversalResourceVR(vr) || isUnlimitedCharactersVR (vr) || isUnlimitedTextVR(vr) || isUnknownVR(vr)) {
+			// should be long form, but check for bad implementations that use short form ...
+			vl=stream->read16();
+			byteoffset+=2;
+			if (vl == 0) {		// if reserved bytes not zero, assume used for short form of length (risky) :(
+				(*stream) >> vl;
+				byteoffset+=4;
+			}
+			else {
+				errorstream << EMsgDC(IncorrectShortVLForUROrUCOrUTOrUN) << endl;
+				//good_flag=false;
+			}
+		}
+		else if (isLongValueLengthInExplicitValueRepresentation(vr)) {		// some of these already handled above
+			(void)stream->read16();	// "Reserved"
+			(*stream) >> vl;
+			byteoffset+=6;
+		}
+		else {
+			vl=stream->read16();
+			byteoffset+=2;
+		}
+	}
+//cerr << "ReadableAttributeList::getValueLength(): vl=0x" << hex << vl << dec << endl;
+	return vl;
+}
+
+static void
+dumpOffset(TextOutputStream *log,Uint32 byteoffset,DicomInputStream *stream,Uint32 length)
+{
+	unsigned long position=(unsigned long)stream->tellg();
+	(*log) << "@";
+	writeZeroPaddedHexNumber(*log,position,8);
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+	(*log) << "(";
+	writeZeroPaddedHexNumber(*log,stream->rdbuf()->PubSeekOff(0,ios::cur),8);
+	(*log) << ")";
+#endif
+	(*log) << ",";
+	writeZeroPaddedHexNumber(*log,byteoffset,8);
+	(*log) << " of ";
+	writeZeroPaddedHexNumber(*log,length,8);
+	(*log) << ": ";
+}
+
+void
+ReadableAttributeList::skipEncapsulatedData(void)
+{
+//cerr << "ReadableAttributeList::skipEncapsulatedData: start" << endl;
+	bool showoffset=verbose;
+	// See libsrc/include/pixeldat/unencap.h for details of GE bug
+	while (1) {
+//cerr << "ReadableAttributeList::skipEncapsulatedData: looping" << endl;
+		if (verbose && showoffset) dumpOffset(log,byteoffset,stream,0xffffffff);
+		Tag tag;
+		(*stream) >> tag;	// Assume is Item Tag
+		if (stream->fail()) {
+			errorstream << EMsgDC(TagReadFailed) << endl;
+			good_flag=false;
+			return;
+		}
+		byteoffset+=4;
+		
+		// Always Implicit VR
+		Uint32 vl;
+		(*stream) >> vl;
+		if (stream->fail()) {
+			errorstream << EMsgDC(VLReadFailed) << endl;
+			good_flag=false;
+			return;
+		}
+		byteoffset+=4;
+
+		if (verbose) {
+			writebase(tag,"",vl); (*log) << endl;
+		}
+
+		if (tag == TagFromName(SequenceDelimitationItem)
+		 || tag == Tag(0xfeff,0xdde0)				// GE bug
+		 || tag == Tag(0xe0dd,0xfffe)				// GE bug
+		) {
+			return;
+		}
+
+		// If GE byte order bug is present, need to swap vl bytes ...
+
+		if (tag != TagFromName(Item)) {		// don't actually check for 0xfeff,0x00e0 or 0xe000,0xfffe
+//cerr << "ReadableAttributeList::skipEncapsulatedData: got possible bad byte order VL of 0x" << hex << vl << dec << endl;
+			vl=(((Uint32)vl&0xff000000)>>24)
+			  +(((Uint32)vl&0x00ff0000)>>8)
+			  +(((Uint32)vl&0x0000ff00)<<8)
+			  +(((Uint32)vl&0x000000ff)<<24);
+//cerr << "ReadableAttributeList::skipEncapsulatedData: assuming VL has bad byte order, using 0x" << hex << vl << dec << endl;
+		}
+
+		//stream->seekg(vl,ios::cur); 
+		//if (stream->fail()) {
+		if (skipBytes(stream,vl) != vl || stream->fail()) {
+			errorstream << EMsgDC(SeekFailed)
+				    << " - while skipping encapsulated data"
+				    << endl;
+			good_flag=false;
+			return;
+		}
+		byteoffset+=vl;
+	}
+}
+
+SequenceAttribute *
+ReadableAttributeList::readNewSequenceAttribute(Tag stag,Uint32 length,bool ignoreoutofordertags,bool useUSVRForLUTDataIfNotExplicit,bool undefinedLengthUNTreatedAsSequence,const char *sequenceOwner,bool fixBitsDuringRead)
+{
+//cerr << "readNewSequenceAttribute(): start: undefinedLengthUNTreatedAsSequence = " << (undefinedLengthUNTreatedAsSequence ? "T" : "F") << endl;
+//cerr << "readNewSequenceAttribute(): start: length = " << dec << length << endl;
+//cerr << "readNewSequenceAttribute(): start: sequenceOwner = \"" << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"" << endl;
+	bool showoffset=verbose;
+	SequenceAttribute *a=new SequenceAttribute(stag);
+//cerr << "readNewSequenceAttribute(): created empty tag - isEmpty()=" << a->isEmpty() << endl;
+//cerr << "readNewSequenceAttribute(): created empty tag - isOne()=" << a->isOne() << endl;
+//cerr << "readNewSequenceAttribute(): created empty tag - isMultiple()=" << a->isMultiple() << endl;
+	Uint32 startbyteoffset=byteoffset;
+//cerr << "readNewSequenceAttribute(): start: startbyteoffset = " << dec << startbyteoffset << endl;
+	bool done=false;
+	while (!done && (byteoffset < startbyteoffset+length || length == 0xffffffff)) {
+//cerr << "readNewSequenceAttribute(): start: byteoffset = " << dec << byteoffset << endl;
+		// Expecting Item or SequenceDelimitationItem
+		if (verbose && showoffset) dumpOffset(log,byteoffset,stream,length);
+		Tag tag;
+		(*stream) >> tag;
+		if (stream->fail()) {
+			errorstream << EMsgDC(TagReadFailed) << endl;
+			good_flag=false;
+			return 0;
+		}
+		byteoffset+=4;
+
+		// Always Implicit VR
+		Uint32 vl;
+		(*stream) >> vl;
+		if (stream->fail()) {
+			errorstream << EMsgDC(VLReadFailed) << endl;
+			good_flag=false;
+			return 0;
+		}
+		byteoffset+=4;
+		Uint32 itemstartbyteoffset=byteoffset;
+
+		if (verbose) {
+			writebase(tag,"",vl); (*log) << endl;
+		}
+		
+		if (tag == TagFromName(SequenceDelimitationItem)
+		 || tag == Tag(0xffe0,0xe0dd)				// GE bug
+		) {
+			if (tag != TagFromName(SequenceDelimitationItem)) {
+//cerr << "Ignoring GE Sequence Delimitation Item encoding bug" << endl;
+				errorstream << WMsgDC(IgnoringGESequenceDelimitationItemEncodingBug) << endl;
+			}
+			if (length != 0xffffffff) {
+				errorstream << WMsgDC(UnexpectedSequenceDelimiterInFixedLengthSequence) << endl;
+				if (byteoffset < startbyteoffset+length) {
+					errorstream << WMsgDC(PrematureEndOfSequence) << endl;
+				}
+			}
+			done=true;	// Force loop exit
+			continue;	// Normal exit path for delimited sequences - don't just break here, in case length was specified - need to detect that error
+		}
+		if (tag == TagFromName(Item)) {
+//cerr << "readNewSequenceAttribute(): Item" << endl;
+			ReadableAttributeList *item=new ReadableAttributeList();
+			Assert(item);
+			ElementDictionary *newdict=new ElementDictionary();
+			Assert(newdict);
+			bool result=item->read(*stream,newdict,log,verbose,vl,false/*metaheadercheck*/,false/*uselengthtoend*/,ignoreoutofordertags,useUSVRForLUTDataIfNotExplicit,undefinedLengthUNTreatedAsSequence/*forceImplicit*/,false/*useStopAtTag*/,Tag(0,0)/*stopAtTag*/,true/*nestedWithinSequence*/,sequenceOwner,fixBitsDuringRead);
+			const char *e=item->errors();
+			if (e) errorstream << e;	// may be warnings
+			if (!result) {
+				errorstream << EMsgDC(SequenceItemReadFailed) << endl;
+//cerr << "readNewSequenceAttribute(): Item error exit" << endl;
+				good_flag=false;
+				return 0;
+			}
+			byteoffset+=item->getByteOffset();
+			(*a)+=item;
+//cerr << "readNewSequenceAttribute(): added item - isEmpty()=" << a->isEmpty() << endl;
+//cerr << "readNewSequenceAttribute(): added item - isOne()=" << a->isOne() << endl;
+//cerr << "readNewSequenceAttribute(): added item - isMultiple()=" << a->isMultiple() << endl;
+			if (vl != 0xffffffff && byteoffset != itemstartbyteoffset+vl) {
+				TextOutputStream terr(errorstream.rdbuf());
+				stag.write(terr,dictionary);
+				errorstream << " - " << EMsgDC(BadSequenceItemValueLength)
+					<< " - " << MMsgDC(ActualLength) << " " << hex << (byteoffset-itemstartbyteoffset)
+					<< " " << MMsgDC(NotEqualTo) << " " << MMsgDC(SpecifiedLength) << " " << vl << dec
+					<< endl;
+				good_flag=false;
+			}
+//cerr << "readNewSequenceAttribute(): Item done" << endl;
+		}
+		else {
+			TextOutputStream terr(errorstream.rdbuf());
+			stag.write(terr,dictionary);
+			terr << " - " << EMsgDC(BadTagInSequence) << " - got - ";
+			tag.write(terr,dictionary);
+			terr << " - " << MMsgDC(ExpectingItemOrSequenceDelimiter);
+			long bytesToSkip = 0;
+			if (length == 0xffffffff) {
+				terr << " - " << MMsgDC(SkippingBadTagInsideUndefinedLengthSequence) << endl;
+				bytesToSkip = vl;
+			}
+			else {
+				terr << " - " << MMsgDC(SkippingToEndOfEnclosingFixedLengthSequence) << endl;
+				bytesToSkip = length - (byteoffset-startbyteoffset);
+			}
+//cerr << "readNewSequenceAttribute(): bytesToSkip = " << dec << bytesToSkip << endl;
+			if (skipBytes(stream,bytesToSkip) != bytesToSkip || stream->fail()) {
+				errorstream << EMsgDC(SeekFailed)
+					<< " - " << MMsgDC(WhileSkipping)
+					<< endl;
+				good_flag=false;
+				return 0;
+			}
+			byteoffset+=bytesToSkip;
+		}
+	}
+	if (length != 0xffffffff && byteoffset != startbyteoffset+length) {
+		TextOutputStream terr(errorstream.rdbuf());
+		stag.write(terr,dictionary);
+		errorstream << " - " << EMsgDC(BadSequenceValueLength)
+			    << " - " << MMsgDC(ActualLength) << " " << hex << (byteoffset-startbyteoffset)
+			    << " " << MMsgDC(NotEqualTo) << " " << MMsgDC(SpecifiedLength) << " " << length << dec
+			    << endl;
+		good_flag=false;
+	}
+	//if (stream->fail()) good_flag=false;		// this seems to fail on AMD64 Linux with Siemens PDI 2004 DICOMDIR :(
+//cerr << "readNewSequenceAttribute(): done good_flag=" << good_flag << endl;
+	//return good_flag ? a : NULL;
+	return a;
+}
+
+ReadableAttributeList::ReadableAttributeList(void)
+	: ErrorsInClass()
+{
+	stream=0;
+	dictionary=0;
+	log=0;
+	verbose=false;
+	byteoffset=0;
+}
+
+ReadableAttributeList::~ReadableAttributeList()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "ReadableAttributeList::~ReadableAttributeList" << endl;
+#endif
+}
+
+bool
+ReadableAttributeList::read(DicomInputStream& str,ElementDictionary* dict,TextOutputStream* l,bool v,Uint32 length,
+	bool metaheadercheck,bool uselengthtoend,bool ignoreoutofordertags,bool useUSVRForLUTDataIfNotExplicit,bool forceImplicit,bool useStopAtTag,Tag stopAtTag,bool nestedWithinSequence,const char *sequenceOwner,bool fixBitsDuringRead)
+{
+//cerr << "ReadableAttributeList::read - start: forceImplicit = " << (forceImplicit ? "T" : "F") << endl;
+//cerr << "ReadableAttributeList::read nestedWithinSequence = " << (nestedWithinSequence ? "T" : "F") << endl;
+//cerr << "ReadableAttributeList::read sequenceOwner = \"" << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"" << endl;
+//cerr << "ReadableAttributeList::read - fixBitsDuringRead = " << (fixBitsDuringRead ? "T" : "F") << endl;
+	stream=&str;
+	dictionary=dict;
+	log=l;
+	verbose=v;
+
+	bool showoffset=v;
+
+	bool treatPixelDataAsOtherNonPixelAttribute=false;	// to handle an illegal GE form in which inside a private GE Private Image Thumbnail Sequence is compressed PixelData even though uncompressed transfer syntax (000426)
+	bool allUSSeemToBeByteSwapped=false;				// detect a very unusual and peculiar bug in some images
+	Endian forcePixelDataEndian=NoEndian;				// leave it to the transfer syntax, unless peculiar circumstances arise (allUSSeemToBeByteSwapped is true)
+	bool donewithmetaheader=!metaheadercheck;
+	Uint32 startbyteoffset=byteoffset;
+	Uint32 dicomdirposition=0xffffffff;
+	bool oldtagvalid=false;
+	Tag oldtag;
+	bool grouplengthcheck=false;
+	Uint32 groupbyteoffsetafterlength=0;	// not used unless grouplengthcheck, but shuts up warning
+	Uint32 grouplengthexpected=0;		// not used unless grouplengthcheck, but shuts up warning
+	while (stream->peek() != istream::traits_type::eof() && (byteoffset < startbyteoffset+length || length == 0xffffffff)) {
+//cerr << "ReadableAttributeList::read - looping (donewithmetaheader is " << (donewithmetaheader ? "true" : "false") << ")" << endl;
+
+//{
+//TransferSyntax *ts = stream->getTransferSyntaxInUse();
+//cerr << "ReadableAttributeList::read getTransferSyntaxInUse(): uid = " << ts->getUID() << endl;
+//cerr << "ReadableAttributeList::read getTransferSyntaxInUse(): description = " << ts->getDescription() << endl;
+//cerr << "ReadableAttributeList::read getTransferSyntaxInUse(): encapsulated = " << (ts->getEncapsulated() ? "true" : "false") << endl;
+//}
+
+		//unsigned long position=stream->rdbuf()->PubSeekOff(0,ios::cur);
+		unsigned long position=(unsigned long)stream->tellg();
+
+		dicomdirposition=position;	// includes preamble and "DICM"
+
+		if (verbose && showoffset) dumpOffset(log,byteoffset,stream,length);
+		Tag tag;
+		(*stream) >> tag;
+		if (stream->fail()) {
+			errorstream << WMsgDC(TagReadFailed) << endl;
+			//good_flag=false;
+			//return false;
+			if (verbose && showoffset) (*log) << endl;
+			return true;
+		}
+//{ TextOutputStream terr(cerr.rdbuf()); terr << "ReadableAttributeList::read(): tag = "; tag.write(terr,dictionary); terr << endl; }
+		// this next would fail if endian changed and first group was 0x0200 !
+
+		if (!donewithmetaheader && !tag.isMetaheaderGroup()) {
+//cerr << "ReadableAttributeList::read(): Changing from metaheader to dataset" << endl;
+			{
+				// backup and read again in case endian changed ...
+//cerr << "ReadableAttributeList::read(): There is a dataset transfer syntax" << endl;
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+cerr << endl << "Before endian check backup @";
+writeZeroPaddedHexNumber(cerr,position,8);
+cerr << "(";
+writeZeroPaddedHexNumber(cerr,stream->rdbuf()->PubSeekOff(0,ios::cur));
+cerr << ")"
+     << ": ";
+#endif
+				stream->seekg(-4l,ios::cur);
+				if (stream->fail()) {
+					errorstream << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+					good_flag=false;
+					return false;
+				}
+#ifdef CHECKFORSGINATIVECCSEEKBUG
+cerr << endl << "Before endian check backup @";
+writeZeroPaddedHexNumber(cerr,position,8);
+cerr << "(";
+writeZeroPaddedHexNumber(cerr,stream->rdbuf()->PubSeekOff(0,ios::cur));
+cerr << ")"
+    << ": " << endl;
+#endif
+				if (!stream->getTransferSyntaxToReadDataSet()) {
+					errorstream << EMsgDC(NoTransferSyntaxInMetaHeader) << endl;
+					good_flag=false;
+					if (verbose && showoffset) (*log) << endl;
+					bool setswapped32big;
+					stream->guessTransferSyntaxToReadDataSet(setswapped32big);		// always guesses something
+				}
+				stream->readingDataSet();
+				donewithmetaheader=true;
+				(*stream) >> tag;
+				if (stream->fail()) {
+					errorstream << WMsgDC(TagReadFailed) << endl;
+					//good_flag=false;
+					//return false;
+					if (verbose && showoffset) (*log) << endl;
+					return true;
+				}
+			}
+		}
+
+		if (oldtagvalid) {
+			if (tag < oldtag) {
+			//if (tag <= oldtag) {
+				errorstream << (ignoreoutofordertags ? WMsgDC(TagsOutOfOrder) : EMsgDC(TagsOutOfOrder)) << endl;
+				//good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				if (!ignoreoutofordertags) return false;
+			}
+			else if (tag == oldtag) {
+				TextOutputStream terr(errorstream.rdbuf());
+				oldtag.write(terr,dictionary);
+				errorstream << EMsgDC(TagsDuplicated) << endl;
+				good_flag=false;
+				// don't return ... can keep reading
+			}
+ 			if (tag.getGroup() != oldtag.getGroup() && grouplengthcheck) {
+				Uint32 actualgrouplength=byteoffset-groupbyteoffsetafterlength;
+				if (grouplengthexpected != actualgrouplength) {
+					errorstream << WMsgDC(BadGroupLength)
+						    << " - " << MMsgDC(Group) << " " << hex << oldtag.getGroup()
+						    << " " << MMsgDC(SpecifiedAs) << " " << hex << grouplengthexpected
+						    << " " << MMsgDC(Actually) << " " << hex << actualgrouplength
+						    << dec << endl;
+				}
+				grouplengthcheck=false;
+			}
+		}
+		oldtag=tag;
+		oldtagvalid=true;
+
+		byteoffset+=4;
+
+		if (useStopAtTag && tag == stopAtTag) {
+//cerr << "read: stopped at " << byteoffset << endl;
+			return true;
+		}
+				
+		if (tag == TagFromName(ItemDelimitationItem)
+		 || tag == Tag(0xffe0,0xe00d)					// GE bug
+		) {
+//cerr << "ReadableAttributeList::read - ItemDelimitationItem" << endl;
+			if (tag != TagFromName(ItemDelimitationItem)) {
+				errorstream << WMsgDC(IgnoringGEItemDelimitationItemEncodingBug) << endl;
+			}
+			// Read and discard value length
+			(void)stream->read32();
+			if (stream->fail()) {
+				errorstream << EMsgDC(VLReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+			byteoffset+=4;
+			if (byteoffset < startbyteoffset+length && length != 0xffffffff) {
+				errorstream << WMsgDC(PrematureEndOfItem) << endl;
+			}
+			length=0;	// Force loop exit
+			continue;	// Normal exit path for delimited items
+		}
+
+		if (tag == TagFromName(Item)) {
+			// this is bad ... there shouldn't be Items here since they should
+			// only be found during readNewSequenceAttribute()
+			// however, try to work around Philips bug ...
+			// Read and discard value length
+			(void)stream->read32();
+			if (stream->fail()) {
+				errorstream << EMsgDC(VLReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+			byteoffset+=4;
+			errorstream << WMsgDC(BadItemInItem) << endl;
+			continue;	// let's just ignore it for now
+		}
+
+		// need to have owner in dictionary BEFORE calling getValueRepresentation()
+		if (tag.isPrivateGroup() && !tag.isLengthElement() && !tag.isPrivateOwner() && !dictionary->hasOwner(tag)) {
+//cerr << "ReadableAttributeList::read - tag is private without owner, have sequenceOwner = " << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"" << endl;
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			errorstream << " - " << WMsgDC(PrivateTagWithoutOwner);
+			
+			if (sequenceOwner != NULL) {
+				errorstream << " - use owner of parent sequence \"" << (sequenceOwner ? sequenceOwner : "--NULL--") << "\"";
+				// need to make a simulated private owner that specifies the block used by the current tag
+				dictionary->addOwner(Tag(tag.getGroup(),(tag.getElement()>>8)&0xff),sequenceOwner);
+			}
+			errorstream << endl;
+		}
+		
+		char vre[3];
+		bool readAsImplicitRegardless = forceImplicit;
+		const char *vr = NULL;
+		Uint32 vl = 0;
+		bool tryAgain = false;
+		Uint32 vrstartbyteoffset = byteoffset;
+		do {
+			vr=getValueRepresentation(tag,vre,readAsImplicitRegardless);	// readAsImplicitRegardless may be set on return even if forceImplicit was false
+			if (stream->fail()) {
+				errorstream << EMsgDC(VRReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+
+			// Make sure to use the VR for the input, even if overridden by dictionary VR
+			// to select the VL encoding method in the input ...
+
+			vl=getValueLength(stream->getTransferSyntaxInUse()->isExplicitVR() ? vre : vr,readAsImplicitRegardless);
+			if (stream->fail()) {
+				errorstream << EMsgDC(VLReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+//cerr << "Value length = 0x" << hex << vl << endl;
+			if (length != 0xffffffff && vl != 0xffffffff && vl > (byteoffset-startbyteoffset+length)) {
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				terr << " - ";
+//cerr << "Value length exceeds fixed length for reading dataset" << endl;
+				if (!tryAgain && readAsImplicitRegardless && stream->getTransferSyntaxInUse()->isExplicitVR()) {
+//cerr << "Since readAsImplicitRegardless was set, try reading VL again without forcing implicit" << endl;
+					// could be because even though supposed to be implicit VR inside UN sequence, is actually explicit :( (000286)
+					// try again without forcing explicit
+					terr << EMsgDC(IncorrectExplicitVRInsideFixedLengthSequenceEncodedAsUnknownVR) << endl;
+					// backup to start of VR and re-read VR and VL
+					long backup = byteoffset-vrstartbyteoffset;
+//cerr << "backup bytes = " << dec << (-backup) << endl;
+					stream->seekg(-backup,ios::cur);
+					if (stream->fail()) {
+						tag.write(terr,dictionary);
+						terr << EMsgDC(TagReadFailed) << " - " << EMsgDC(SeekFailed) << endl;
+						good_flag=false;
+						return 0;
+					}
+					byteoffset=vrstartbyteoffset;
+					readAsImplicitRegardless = false;
+					tryAgain = true;
+					continue;
+				}
+				else {
+					// not sure what to do here - skip to end of fixed length dataset, potentially allowing resumption if inside sequence item ? :(
+					// turns out to be better not to skip ... allows later detection of when actual sequence length does not match defined length, though sequence can be successfully read, which sometimes happens
+					terr << EMsgDC(ValueLengthExceedsFixedLengthForReadingDataset) << " - " << MMsgDC(Ignoring) << endl;
+					//Uint32 skiptoend = byteoffset-startbyteoffset+length;
+					////stream->seekg(skiptoend,ios::cur);
+					////if (stream->fail()) {
+					//if (skipBytes(stream,skiptoend) != skiptoend || stream->fail()) {
+					//	tag.write(terr,dictionary);
+					//	terr << EMsgDC(SeekFailed)
+					//		<< endl;
+					//	good_flag=false;
+					//	return false;
+					//}
+					//byteoffset+=skiptoend;
+				}
+			}
+			tryAgain = false;
+		} while (tryAgain);
+		
+		if (ignoreoutofordertags && vl > 0xffff && stream->getTransferSyntaxInUse()->isImplicitVR()) {
+			// there are occasions when buggy files will have some elements encoded with explicit rather than implicit VR
+			// check here to see if first two bytes are actually a VR ... if so, assume the presence of this bug and repair
+			char vrtest[3];
+			vrtest[0] = vl & 0xff;			// implicit is always little endian
+			vrtest[1] = (vl >> 8) & 0xff;
+			vrtest[2] = 0;
+			if (isKnownExplicitValueRepresentation(vrtest)) {
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				terr << " - " << WMsgDC(DataElementEncodedAsExplicitInImplicitVRTransferSyntax) << " - ignoring explicit VR <" << vrtest << "> and trying to recover short VL" << endl;
+				vl = (vl >> 16) &0xffff;
+				// ignore "explicit" VR, since experience suggests that it will be "wrong" when this bug occurs
+			}
+		}
+		
+		if (vl != 0xffffffff & vl%2 != 0) {
+			TextOutputStream terr(errorstream.rdbuf());
+			tag.write(terr,dictionary);
+			terr << " - " << EMsgDC(BadValueLengthNotEven) << " - VL is " << hex << vl << " should be " << (vl+1) << dec << endl;
+			good_flag=false;
+		}
+//cerr << "ReadableAttributeList::read VL  = 0x" << hex << vl << dec << endl;
+
+		Attribute *a=0;
+
+		const char *vrd = dictionary->getValueRepresentation(tag);
+		bool treatedUnknownVRAsSequence = isUnknownVR(vr) && (vl == 0xffffffff || (vrd && strncmp(vrd,"SQ",2) == 0));
+		if (isSequenceVR(vr) || treatedUnknownVRAsSequence) {
+			if (verbose) { writebase(tag,vr,vl); (*log) << endl; }
+//cerr << "ReadableAttributeList::read - before readNewSequenceAttribute() good_flag = " << good_flag << endl;
+			const char *useSequenceOwner = dictionary->getOwner(tag);
+//cerr << "ReadableAttributeList::read - useSequenceOwner from dictionary->getOwner(tag) = \"" << (useSequenceOwner ? useSequenceOwner : "--NULL--") << "\"" << endl;
+			if (!useSequenceOwner) {
+				useSequenceOwner = sequenceOwner;	// propagate owner of successively nested sequences (really should check group and block, but since this is non-standard anyway ... :( )
+//cerr << "ReadableAttributeList::read - useSequenceOwner from parent = \"" << (useSequenceOwner ? useSequenceOwner : "--NULL--") << "\"" << endl;
+			}
+			a=readNewSequenceAttribute(tag,vl,ignoreoutofordertags,useUSVRForLUTDataIfNotExplicit,
+				forceImplicit || treatedUnknownVRAsSequence,		/* once inside UN SQ, always implicit, even if nested */
+				useSequenceOwner,									/* in case nested lists are missing owner, propagate owner of the sequence tag itself, if private, or its parent, if missing its own owner */
+				fixBitsDuringRead
+				);
+//cerr << "ReadableAttributeList::read - back from readNewSequenceAttribute() with a = " << (a == NULL ? "null" : "valid") << endl;
+//cerr << "ReadableAttributeList::read - back from readNewSequenceAttribute() with stream->fail() = " << stream->fail() << endl;
+//cerr << "ReadableAttributeList::read - back from readNewSequenceAttribute() good_flag = " << good_flag << endl;
+			if (!a) {	// hmm; should check good_flag ? :(
+				errorstream << EMsgDC(SeqAttrReadFailed) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+			// byteoffset already updated by readNewSequenceAttribute()
+		}
+		else if (tag.isPixelDataElement() && !treatPixelDataAsOtherNonPixelAttribute) {		// treatPixelDataAsOtherNonPixelAttribute is to handle (000426)
+//cerr << "ReadableAttributeList::read PixelData" << endl;
+			if (isOtherByteOrWordOrUnspecifiedVR(vr)) {
+//cerr << "ReadableAttributeList::read OX PixelData" << endl;
+				Uint16 vBitsAllocated=AttributeValue(operator[](TagFromName(BitsAllocated)));
+				Uint16 vBitsStored=AttributeValue(operator[](TagFromName(BitsStored)));
+				Uint16 vHighBit=AttributeValue(operator[](TagFromName(HighBit)));
+				if (!vBitsAllocated && vBitsStored) vBitsAllocated=((vBitsStored-1u)/8u+1u)*8u;
+				if (!vBitsAllocated) vBitsAllocated=16;
+				if (!vBitsStored) vBitsStored=vBitsAllocated;
+				if (!vHighBit) vHighBit=vBitsStored-1u;
+				if (vHighBit > (vBitsStored-1u)) {
+					errorstream << WMsgDC(BadAttributeValue)
+						    << " - High Bit = " << vHighBit
+						    << " " << MMsgDC(Exceeds) << " " << (vBitsStored-1u)
+						    << endl;
+				}
+				if (vHighBit > (vBitsAllocated-1u)) {
+					errorstream << EMsgDC(BadAttributeValue)
+						    << " - High Bit = " << vHighBit
+						    << " " << MMsgDC(Exceeds) << " " << (vBitsAllocated-1u);
+					if (fixBitsDuringRead) {
+						errorstream << " " << MMsgDC(Using) << " " << (vBitsAllocated-1u);
+					}
+					errorstream << endl;
+					if (fixBitsDuringRead) {
+						vHighBit=vBitsAllocated-1u;
+						operator-=(TagFromName(HighBit));
+						UnsignedShortAttribute *aHighBit=new UnsignedShortAttribute(TagFromName(HighBit),vHighBit);
+						Assert(aHighBit);
+						operator+=(aHighBit);
+					}
+				}
+				if (vHighBit < (vBitsStored-1u)) {
+					errorstream << EMsgDC(BadAttributeValue)
+						    << " - Bits Stored = " << vBitsStored
+						    << " " << MMsgDC(Exceeds) << " High Bit " << vHighBit << " + 1";
+					if (fixBitsDuringRead) {
+						errorstream << " " << MMsgDC(Using) << " " << (vHighBit+1u);
+					}
+					errorstream << endl;
+					if (fixBitsDuringRead) {
+						vBitsStored=vHighBit+1u;
+						operator-=(TagFromName(BitsStored));
+						UnsignedShortAttribute *aBitsStored=new UnsignedShortAttribute(TagFromName(BitsStored),vBitsStored);
+						Assert(aBitsStored);
+						operator+=(aBitsStored);
+					}
+				}
+				if (vl == 0xffffffff) {
+//cerr << "ReadableAttributeList::read Pixel Data has undefined length VL" << endl;
+					if (stream->getTransferSyntaxInUse()->isEncapsulated()) {
+						a=new OtherUnspecifiedLargeAttributeEncapsulated(
+							tag,
+							*stream,
+							stream->tellg(),
+							AttributeValue(operator[](TagFromName(Rows))),
+							AttributeValue(operator[](TagFromName(Columns))),
+							AttributeValue(operator[](TagFromName(NumberOfFrames)),1),
+							AttributeValue(operator[](TagFromName(SamplesPerPixel)),1),
+							vBitsAllocated,
+							vBitsStored,
+							vHighBit
+						);
+						// skip the blocked data (we don't know its length)...
+						skipEncapsulatedData();	// increments byteoffset as it skips
+						if (verbose) { a->write(*log,dictionary); (*log) << endl; }
+						//byteoffset+=vl;	// already done in skipEncapsulatedData()
+					}
+					else {
+						errorstream << EMsgDC(UndefinedVLForOX) << endl;
+						good_flag=false;
+						if (verbose && showoffset) (*log) << endl;
+						return false;
+					}
+				}
+				else {
+//cerr << "ReadableAttributeList::read Pixel Data has defined length VL" << endl;
+					if (stream->getTransferSyntaxInUse()->isEncapsulated() && !nestedWithinSequence) {
+						errorstream << EMsgDC(IllegalVLForPixelDataInEncapsulatedTransferSyntaxInTopLevelDataset) << endl;
+						if (verbose && showoffset) (*log) << endl;
+						// do not return false but keep going anyway, and do not negate good_flag, since should be able to read it and no need to fail reading of entire dataset
+					}
+					{
+//cerr << "ReadableAttributeList::read vl=" << hex << vl << dec << endl;
+						Uint16 bytesinword = (Uint16)(vr[1] == 'W' ? 2 : (vr[1] == 'B' ? 1 : 0));
+						if (vBitsAllocated > 8 && isOtherByteVR(vr) && stream->getTransferSyntaxInUse()->isExplicitVR()) {
+								errorstream << EMsgDC(BadValueRepresentation)
+								    << " - Pixel Data - VR = OB, Explicit VR, Bits Allocated = " << vBitsAllocated
+								    << " " << MMsgDC(Exceeds) << " 8"
+								    << endl;
+							bytesinword=2;		// force OW to make it usable
+						}
+						a=new OtherUnspecifiedLargeAttributeCopied(
+							tag,
+							*stream,
+							stream->tellg(),
+							AttributeValue(operator[](TagFromName(Rows))),
+							AttributeValue(operator[](TagFromName(Columns))),
+							AttributeValue(operator[](TagFromName(NumberOfFrames)),1),
+							AttributeValue(operator[](TagFromName(SamplesPerPixel)),1),
+							bytesinword,
+							vBitsAllocated,
+							vBitsStored,
+							vHighBit,
+							vl,
+							forcePixelDataEndian
+						);
+						//stream->seekg(vl,ios::cur);
+						//if (stream->fail()) {
+						if (skipBytes(stream,vl) != vl || stream->fail()) {
+							errorstream << EMsgDC(SeekFailed)
+								    << " - while reading unencapsulated Pixel Data"
+								    << endl;
+							good_flag=false;
+							return false;
+						}
+						if (verbose) { a->write(*log,dictionary); (*log) << endl; }
+						byteoffset+=vl;
+					}
+				}
+			}
+			else {
+//cerr << "ReadableAttributeList::read PixelData not OX" << endl;
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				terr << EMsgDC(IllegalVRForPixelData) << endl;
+				good_flag=false;
+				if (verbose && showoffset) (*log) << endl;
+				return false;
+			}
+		}
+		else {
+//cerr << "ReadableAttributeList::read non-PixelData" << endl;
+			if (tag == TagFromName(WaveformData)) {
+//cerr << "ReadableAttributeList::read WaveformData" << endl;
+				Uint16 vWaveformBitsAllocated=AttributeValue(operator[](TagFromName(WaveformBitsAllocated)));
+				if (vWaveformBitsAllocated > 8) {
+					if (isOtherByteVR(vr) && stream->getTransferSyntaxInUse()->isExplicitVR()) {
+						errorstream << EMsgDC(BadValueRepresentation)
+							<< " - Waveform Data - VR = OB, Explicit VR, Waveform Bits Allocated = " << vWaveformBitsAllocated
+							<< " " << MMsgDC(Exceeds) << " 8"
+							<< endl;
+						if (stream->getTransferSyntaxInUse()->isLittleEndian()) {
+//cerr << "ReadableAttributeList::forcing WaveformData VR from OB to OW since > 8 bit, explicit VR and little endian" << endl;
+							vr="OW";
+						}
+						// else cannot recover to OW without byte swapping, which is too hard at this point :(
+					}
+					else {
+						if (strcmp(vr,"OX") == 0) {
+//cerr << "ReadableAttributeList::using OW for > 8 bit WaveformData in implicit VR" << endl;
+							vr="OW";
+						}
+					}
+				}
+				else {
+					if (strcmp(vr,"OX") == 0) {
+//cerr << "ReadableAttributeList::using OB for <= 8 bit WaveformData in implicit VR" << endl;
+						vr="OB";
+					}
+				}
+			}
+			
+			if (isOtherByteOrWordOrUnspecifiedVR(vr)) {
+				// PixelData already handled specially
+				if (strcmp(vr,"OX") == 0) {
+					if (tag == TagFromName(OverlayData)) {
+						vr="OW";
+					}
+					else if (tag == TagFromName(CurveData)) {
+						vr="OB";
+					}
+					else {
+						vr="OB";
+					}
+				}
+				if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+					if (strcmp(vr,"OB") == 0)
+						a=new OtherByteSmallNonPixelAttribute(tag);
+					else if (strcmp(vr,"OW") == 0)
+						a=new OtherWordSmallNonPixelAttribute(tag);
+					else { Assert(0); }
+				}
+				else {
+					if (strcmp(vr,"OB") == 0)
+						a=new OtherByteLargeNonPixelAttribute(tag,
+							*stream,
+							stream->tellg());
+					else if (strcmp(vr,"OW") == 0)
+						a=new OtherWordLargeNonPixelAttribute(tag,
+							*stream,
+							stream->tellg());
+					else { Assert(0); }
+					// the skipping and vl setting is done later in read()
+				}
+			}
+			else if (isOtherLongVR(vr)) {
+				//if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+				//	a=new OtherLongSmallAttribute(tag);
+				//}
+				//else {
+					a=new OtherLongLargeAttribute(tag,
+							*stream,
+							stream->tellg());
+					// the skipping and vl setting is done later in read()
+				//}
+			}
+			else if (isOtherFloatVR(vr)) {
+				//if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+				//	a=new OtherFloatSmallAttribute(tag);
+				//}
+				//else {
+					a=new OtherFloatLargeAttribute(tag,
+							*stream,
+							stream->tellg());
+					// the skipping and vl setting is done later in read()
+				//}
+			}
+			else if (isOtherDoubleVR(vr)) {
+				//if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+				//	a=new OtherDoubleSmallAttribute(tag);
+				//}
+				//else {
+					a=new OtherDoubleLargeAttribute(tag,
+							*stream,
+							stream->tellg());
+					// the skipping and vl setting is done later in read()
+				//}
+			}
+			else if (isUnknownVR(vr)) {
+				if (vl <= LARGESTOTHERDATATOKEEPINMEMORY) {
+					a=new UnknownSmallAttribute(tag);
+				}
+				else {
+					a=new UnknownLargeAttribute(tag,
+							*stream,
+							stream->tellg());
+					// the skipping and vl setting is done later in read()
+				}
+			}
+			else if (tag == TagFromName(LUTData) && strcmp(vr,"XO") == 0 && useUSVRForLUTDataIfNotExplicit) {
+//cerr << "ReadableAttributeList::read(): using US VR for LUT Data" << endl;
+				a=new UnsignedShortAttribute(tag);
+			}
+			else {
+				a=newAttribute(vr,tag);
+				if (!a) {
+					TextOutputStream terr(errorstream.rdbuf());
+					tag.write(terr,dictionary);
+					errorstream << WMsgDC(VRUnsupported) << " - <" << vr[0] << vr[1] << ">" << endl;
+				}
+			}
+
+			if (a) {
+				if (vl%a->getValueSize() != 0) {
+					TextOutputStream terr(errorstream.rdbuf());
+					tag.write(terr,dictionary);
+					terr << " - " << EMsgDC(VLDoesNotMatchVR) << " - value length = " << dec << vl << " dec - expected multiple of " << a->getValueSize() << " - skipping value length bytes to next data element" << endl;
+					good_flag=false;
+					if (verbose && showoffset) (*log) << endl;
+					// do not give up though - just skip it
+					if (skipBytes(stream,vl) != vl || stream->fail()) {
+						errorstream << EMsgDC(SeekFailed)
+							<< " - while skipping value of length " << dec << vl << " dec"
+							<< endl;
+						good_flag=false;
+						return false;
+					}
+				}
+				else {
+					a->read(*stream,vl);
+					if (!isLongValueLengthInExplicitValueRepresentation(vr) && a->getValueSize()*a->getVM() >= 65536) {
+						TextOutputStream terr(errorstream.rdbuf());
+						tag.write(terr,dictionary);
+						terr << " - " << WMsgDC(VLExceedsExplicitVRMaximium) << " - value length = " << dec << vl << endl;
+					}
+				}
+				if (stream->fail()) {
+					errorstream << EMsgDC(AttributeReadFailed) << endl;
+					good_flag=false;
+					if (verbose && showoffset) (*log) << endl;
+					return false;
+				}
+				if (verbose) { a->write(*log,dictionary); (*log) << endl; }
+#define FIXUPSWAPPEDUS
+#ifdef FIXUPSWAPPEDUS
+				if (strcmp(a->getVR(),"US") == 0 && a->getVM() == 1) {
+					Uint16 value;
+					if (a->getValue(0,value)) {
+						if (tag == TagFromName(SamplesPerPixel)) {		// check the first US we are likely to encounter
+							if (value > 255) {
+								allUSSeemToBeByteSwapped=true;
+								forcePixelDataEndian=BigEndian;
+								errorstream << EMsgDC(BadEncoding) << " - detected swapped bytes of US and pixel data values - fixing" << endl;
+							}
+						}
+						if (allUSSeemToBeByteSwapped) {
+							value = ((value&0xff)<<8)|(((value&0xff00)>>8)&0xff);
+							a->setValue(0,value);
+							if (verbose) { (*log) << "Fixup swapped US VR: "; a->write(*log,dictionary); (*log) << endl; }
+						}
+					}
+				}
+#endif
+
+				byteoffset+=vl;
+				if (tag == TagFromName(TransferSyntaxUID)) {
+					const char *newTransferSyntaxUID = AttributeValue(a);
+					if (donewithmetaheader) {
+						errorstream << EMsgDC(UnexpectedTransferSyntaxUIDOutsideMetaInformationHeader) << " - ignoring - " << newTransferSyntaxUID << endl;
+					}
+					else if (newTransferSyntaxUID && strlen(newTransferSyntaxUID) > 0) {
+//cerr << "ReadableAttributeList::read() encountered TransferSyntaxUID - before changing getTransferSyntaxInUse()->isEncapsulated() " << (stream->getTransferSyntaxInUse()->isEncapsulated() ? "true" : "false") << endl;
+//cerr << "ReadableAttributeList::read() encountered TransferSyntaxUID - setting transfer syntax to read data set to " << newTransferSyntaxUID << endl;
+						stream->setTransferSyntaxToReadDataSet(new TransferSyntax(newTransferSyntaxUID));
+//cerr << "ReadableAttributeList::read() encountered TransferSyntaxUID - after changing getTransferSyntaxInUse()->isEncapsulated() " << (stream->getTransferSyntaxInUse()->isEncapsulated() ? "true" : "false") << endl;
+					}
+					else {
+						errorstream << EMsgDC(EmptyTransferSyntaxUIDInMetaInformationHeader) << endl;
+						stream->setTransferSyntaxToReadDataSet(NULL);
+					}
+				}
+				else if (tag == TagFromName(FileMetaInformationVersion)) {
+					// check this is correct here ... easier than elsewhere
+					// and this is the only place an OB is used like this
+					const unsigned char *value;
+					Uint32 length;
+					if (!a->isOtherByteNonPixel()
+					 || !a->getValue(value,length)
+					 || length != 2
+					 || *value != 0x00
+					 || *(value+1) != 0x01) {
+						errorstream << WMsgDC(BadFileMetaInformationVersion) << endl;
+					}
+				}
+				else if (tag.isLengthElement()) {
+					// Retired except for metaheader, but if you've got it check it
+					grouplengthexpected=Uint32(AttributeValue(a));
+					groupbyteoffsetafterlength=byteoffset;
+					grouplengthcheck=true;
+				}
+				else if (tag == TagFromName(LengthToEnd)
+					&& vl != 0 && length == 0xffffffff) {
+					// Retired, but if you've got it use it
+					if (uselengthtoend) length=byteoffset-startbyteoffset+Uint32(AttributeValue(a));
+				}
+				else if (tag.isPrivateGroup()) {
+					if (tag.isPrivateOwner()) {
+//cerr << "ReadableAttributeList::read adding owner" << endl;
+						if (tag.getElement() < 0x0010) {
+							TextOutputStream terr(errorstream.rdbuf());
+							tag.write(terr,dictionary);
+							errorstream << " - " << EMsgDC(BadPrivateOwner) << " - element must be greater than or equal to 0x0010" << endl;
+						}
+						char *s=AttributeValue(a);
+						if (s && *s) 
+							dictionary->addOwner(tag,s);
+						else {
+							TextOutputStream terr(errorstream.rdbuf());
+							tag.write(terr,dictionary);
+							errorstream << " - " << WMsgDC(BadPrivateOwner) << " - empty value" << endl;
+						}
+						if (s) delete[] s;
+					}
+					// PrivateTagWithoutOwner is handled earlier when establishing dictionary VR and need to possibly inherit parent sequence owner if owner missing within item dataset
+					//else {
+					//	if (!dictionary->hasOwner(tag)) {
+					//		TextOutputStream terr(errorstream.rdbuf());
+					//		tag.write(terr,dictionary);
+					//		errorstream << " - " << WMsgDC(PrivateTagWithoutOwner) << endl;
+					//	}
+					//}
+					else if (tag.isPrivateTag()) {
+						const char *useOwner = dictionary->getOwner(tag);
+						// handle an illegal GE form in which inside a private GE Private Image Thumbnail Sequence is compressed PixelData even though uncompressed transfer syntax (000426)
+						if (tag.getGroup() == 0x7fd1 && (tag.getElement() & 0x00ff) == 0x0010 && useOwner != NULL && strcmp(useOwner,"GEIIS ")) {	// (0x7fd1,0x1010) Compression Type; note the space in the owner check
+							// Need to actually check the value, since when this is used, there is one inside the GE Private Image Thumbnail Sequence with a non-zero value
+							// and one in the top level dataset with a zero value, which shoudl not affect how top level Pixel Data is handled ...
+							Uint32 geGompressionType =AttributeValue(a);
+							treatPixelDataAsOtherNonPixelAttribute = geGompressionType != 0;
+//cerr << "ReadableAttributeList::read - tag is private GE Compression Type, value " << geGompressionType << "; will " << (treatPixelDataAsOtherNonPixelAttribute ? "" : "not ") << "treat PixelData as ordinary tag" << endl;
+						}
+					}
+				}
+			}
+			else {
+				TextOutputStream terr(errorstream.rdbuf());
+				tag.write(terr,dictionary);
+				errorstream << WMsgDC(UnrecognizedOrUnsupportedTag) << endl;
+				if (verbose && showoffset) (*log) << endl;
+				//stream->seekg(vl,ios::cur);
+				//if (stream->fail()) {
+				if (skipBytes(stream,vl) != vl || stream->fail()) {
+					errorstream << EMsgDC(SeekFailed)
+						<< " - while skipping remainder of "
+						<< MMsgDC(UnrecognizedOrUnsupportedTag)
+						<< endl;
+					good_flag=false;
+					return false;
+				}
+				byteoffset+=vl;
+			}
+		}
+
+		if (a) {
+			a->setByteOffset(dicomdirposition);
+			operator+=(a);
+		}
+
+		// Need private owner & metaheader stuff here
+	}
+//cerr << "ReadableAttributeList::read - falling out at end byteoffset = " << hex << byteoffset << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end startbyteoffset = " << hex << startbyteoffset << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end length = " << hex << length << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end startbyteoffset+length = " << hex << (length == 0xffffffff ? 0xffffffff : (startbyteoffset+length)) << dec << endl;
+//cerr << "ReadableAttributeList::read - falling out at end stream->fail() = " << stream->fail() << endl;
+	TransferSyntax *dts=stream->getTransferSyntaxToReadDataSet();
+	return ((dts && dts->isExplicitVR()) || setValueRepresentation())
+	    /*&& !stream->fail()*/;		// seems to fail inappropriately on AMD 64 Linux with Siemens PDI 2004 demo DICOMDIR :(
+}
+
diff --git a/libsrc/src/dctool/attrmxvr.cc b/libsrc/src/dctool/attrmxvr.cc
new file mode 100644
index 0000000..329ca96
--- /dev/null
+++ b/libsrc/src/dctool/attrmxvr.cc
@@ -0,0 +1,171 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrmxvr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrmxls.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+
+// Handle any special cases required to determine Value Representation
+
+// May need to consult:
+//	- other attributes specifying representation
+//	- transfer syntax
+
+// If PixelRepresentation = 0 (unsigned) or 1 (signed), can determine:
+//
+// XS	SmallestImagePixelValue
+// XS	LargestImagePixelValue
+// XS	SmallestValidPixelValue
+// XS	LargestValidPixelValue
+// XS	SmallestPixelValueInSeries
+// XS	LargestPixelValueInSeries
+// XS	SmallestImagePixelValueInPlane
+// XS	LargestImagePixelValueInPlane
+// XS	PixelPaddingValue
+
+// XS	RedPaletteColorLookupTableDescriptor
+// XS	GreenPaletteColorLookupTableDescriptor
+// XS	BluePaletteColorLookupTableDescriptor
+// XO	RedPaletteColorLookupTableData
+// XO	GreenPaletteColorLookupTableData
+// XO	BluePaletteColorLookupTableData
+
+// LUTDescriptor and LUTData are not here anymore... they are now specified
+// as US in the dictionary, even though they might be US or SS ... they occur
+// within a sequence and hence access to PixelRepresentation is tough.
+// XS	LUTDescriptor
+// XS	LUTData
+// It is not clear how the LUT Descriptor VR should be specified
+// The VM is 3 ... NumberOfEntries\FirstStoredPixelMapped\BitsPerEntry
+// Presumably the VR of the second is dictated by PixelRepresentation,
+// and therefore the others will therefore have to be the same.
+
+// The following are retired as of PS 3.0 but no reason we shouldn't
+// be able to handle them ...
+
+// XS	GrayLookupTableDescriptor
+// XS	GrayLookupTableData
+
+// More recent additions ...
+
+// XS	RealWorldValueLastValueMapped
+// XS	RealWorldValueFirstValueMapped
+// XS	HistogramFirstBinValue
+// XS	HistogramLastBinValue
+
+// Another oldie ...
+
+// XS	PerimeterValue
+
+// ? should we not change if OW for XO to avoid VM problems ?
+
+bool
+ReadableAttributeList::replaceWithPixelRepresentation(const Tag &t,const char *name,bool havepixrep,bool usesigned)
+{
+	bool success=true;
+	Attribute *a=operator[](t);
+	if (a) {
+		if (havepixrep) {
+			Attribute *newa;
+			if (usesigned)
+				newa=new SignedShortAttribute(t);
+			else
+				newa=new UnsignedShortAttribute(t);
+			Assert(newa);
+			unsigned vm=a->getVM();
+			unsigned i;
+			for (i=0; i < vm; ++i) {
+				Uint16 v;
+				if (!a->getValue(i,v)) Assert(0);
+				newa->addValue(v);
+			}
+			operator-=(a);
+			operator+=(newa);
+		}
+		else {
+			const char *vr=a->getVR();
+			if (vr && vr[0] == 'X') {
+				errorstream << EMsgDC(MissingPixelRepresentation) << " - " << name << endl;
+				good_flag=0;
+				success=false;
+			}
+		}
+	}
+	return success;
+}
+
+#define ReplaceWithPixelRepresentation(n) \
+	replaceWithPixelRepresentation(TagFromName(n),#n,aPixelRepresentation!=0,vPixelRepresentation==1)
+
+bool
+ReadableAttributeList::setValueRepresentation(void)
+{
+	bool success=true;
+
+	Attribute *aPixelRepresentation = operator[](TagFromName(PixelRepresentation));
+	Uint16 vPixelRepresentation;
+
+	if (aPixelRepresentation) {
+		vPixelRepresentation=AttributeValue(aPixelRepresentation);
+		if (vPixelRepresentation != 0 && vPixelRepresentation != 1) {
+			errorstream << EMsgDC(BadValuePixelRepresentation) << endl;
+			good_flag=0;
+			success=false;
+			vPixelRepresentation=0;
+		}
+	}
+
+	success=success && ReplaceWithPixelRepresentation(PerimeterValue);
+	success=success && ReplaceWithPixelRepresentation(SmallestImagePixelValue);
+	success=success && ReplaceWithPixelRepresentation(LargestImagePixelValue);
+	success=success && ReplaceWithPixelRepresentation(SmallestValidPixelValue);
+	success=success && ReplaceWithPixelRepresentation(LargestValidPixelValue);
+	success=success && ReplaceWithPixelRepresentation(SmallestPixelValueInSeries);
+	success=success && ReplaceWithPixelRepresentation(LargestPixelValueInSeries);
+	success=success && ReplaceWithPixelRepresentation(SmallestImagePixelValueInPlane);
+	success=success && ReplaceWithPixelRepresentation(LargestImagePixelValueInPlane);
+	success=success && ReplaceWithPixelRepresentation(PixelPaddingValue);
+	success=success && ReplaceWithPixelRepresentation(RedPaletteColorLookupTableDescriptor);
+	success=success && ReplaceWithPixelRepresentation(GreenPaletteColorLookupTableDescriptor);
+	success=success && ReplaceWithPixelRepresentation(BluePaletteColorLookupTableDescriptor);
+	//success=success && ReplaceWithPixelRepresentation(RedPaletteColorLookupTableData);
+	//success=success && ReplaceWithPixelRepresentation(GreenPaletteColorLookupTableData);
+	//success=success && ReplaceWithPixelRepresentation(BluePaletteColorLookupTableData);
+	//success=success && ReplaceWithPixelRepresentation(LUTDescriptor);
+	//success=success && ReplaceWithPixelRepresentation(LUTData);
+	success=success && ReplaceWithPixelRepresentation(GrayLookupTableDescriptor);
+	//success=success && ReplaceWithPixelRepresentation(GrayLookupTableData);
+	success=success && ReplaceWithPixelRepresentation(RealWorldValueLastValueMapped);
+	success=success && ReplaceWithPixelRepresentation(RealWorldValueFirstValueMapped);
+	success=success && ReplaceWithPixelRepresentation(HistogramFirstBinValue);
+	success=success && ReplaceWithPixelRepresentation(HistogramLastBinValue);
+
+	return success;
+}
+
+// Handle elsewhere or not at all yet :( ...
+
+// If AudioSampleFormat = 0 (16 bit signed LSB 1st interleaved per channel)
+// If AudioSampleFormat = 1 (8 bit signed LSB 1st interleaved per channel)
+//
+// OX	AudioSampleData
+
+// If DateValueRepresentation is nn then CurveData is:
+//	0 - US
+//	1 - SS
+//	2 - FL
+//	3 - FD
+//	4 - SL
+//
+//	Unless implict VR in which case it is OB little endian !
+//
+// OX	CurveData
+
+// These depend only on the transfer syntax:
+//	- Implicit VR Little Endian -> OW
+//	- Explicit VR Little Endian -> OW
+//	- Explicit VR Big Endian -> OW
+//	- Encapsulated Pixel Data -> OB
+
+// OX	PixelData
+
diff --git a/libsrc/src/dctool/attrnew.cc b/libsrc/src/dctool/attrnew.cc
new file mode 100644
index 0000000..658d76f
--- /dev/null
+++ b/libsrc/src/dctool/attrnew.cc
@@ -0,0 +1,168 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrnew.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+#include "attrnew.h"
+#include "attrseq.h"
+
+Attribute *
+newAttribute(const char* vr,Tag tag)
+{
+	Attribute *a = 0;
+
+	if (vr && vr[0]) {
+		switch (vr[0]) {
+		case 'A':
+			switch (vr[1]) {
+			case 'E':
+				a=new ApplicationEntityAttribute(tag);
+				break;
+			case 'S':
+				a=new AgeStringAttribute(tag);
+				break;
+			case 'T':
+				a=new AttributeTagAttribute(tag);
+				break;
+			}
+			break;
+		case 'C':
+			switch (vr[1]) {
+			case 'S':
+				a=new CodeStringAttribute(tag);
+				break;
+			}
+			break;
+		case 'D':
+			switch (vr[1]) {
+			case 'A':
+				a=new DateStringAttribute(tag);
+				break;
+			case 'S':
+				a=new DecimalStringAttribute(tag);
+				break;
+			case 'T':
+				a=new DateTimeStringAttribute(tag);
+				break;
+			}
+			break;
+		case 'F':
+			switch (vr[1]) {
+			case 'L':
+				a=new FloatSingleAttribute(tag);
+				break;
+			case 'D':
+				a=new FloatDoubleAttribute(tag);
+				break;
+			default:
+				break;
+			}
+			break;
+		case 'I':
+			switch (vr[1]) {
+			case 'S':
+				a=new IntegerStringAttribute(tag);
+				break;
+			}
+			break;
+		case 'L':
+			switch (vr[1]) {
+			case 'O':
+				a=new LongStringAttribute(tag);
+				break;
+			case 'T':
+				a=new LongTextAttribute(tag);
+				break;
+			}
+			break;
+		case 'O':
+			switch (vr[1]) {
+			case 'B':
+				a=new OtherByteSmallNonPixelAttribute(tag);
+				break;
+			//case 'F':
+			//	a=new OtherFloatSmallAttribute(tag);
+			//	break;
+			case 'W':
+				a=new OtherWordSmallNonPixelAttribute(tag);
+				break;
+			case 'X':
+				// This is probably not cool :( ...
+				a=new OtherWordSmallNonPixelAttribute(tag);
+				break;
+			}
+			break;
+		case 'P':
+			switch (vr[1]) {
+			case 'N':
+				a=new PersonNameAttribute(tag);
+				break;
+			}
+			break;
+		case 'S':
+			switch (vr[1]) {
+			case 'H':
+				a=new ShortStringAttribute(tag);
+				break;
+			case 'L':
+				a=new SignedLongAttribute(tag);
+				break;
+			case 'Q':
+				a=new SequenceAttribute(tag);
+				break;
+			case 'S':
+				a=new SignedShortAttribute(tag);
+				break;
+			case 'T':
+				a=new ShortTextAttribute(tag);
+				break;
+			}
+			break;
+		case 'T':
+			switch (vr[1]) {
+			case 'M':
+				a=new TimeStringAttribute(tag);
+				break;
+			}
+			break;
+		case 'U':
+			switch (vr[1]) {
+			case 'C':
+				a=new UnlimitedCharactersAttribute(tag);
+				break;
+			case 'I':
+				a=new UIStringAttribute(tag);
+				break;
+			case 'L':
+				a=new UnsignedLongAttribute(tag);
+				break;
+			case 'N':
+				a=new UnknownSmallAttribute(tag);
+				break;
+			case 'R':
+				a=new UniversalResourceAttribute(tag);
+				break;
+			case 'S':
+				a=new UnsignedShortAttribute(tag);
+				break;
+			case 'T':
+				a=new UnlimitedTextAttribute(tag);
+				break;
+			}
+			break;
+		case 'X':
+			switch (vr[1]) {
+			case 'L':
+				a=new UnspecifiedLongAttribute(tag);
+				break;
+			case 'O':
+				a=new OtherWordSmallNonPixelAttribute(tag);
+				break;
+			case 'S':
+				a=new UnspecifiedShortAttribute(tag);
+				break;
+			}
+			break;
+		}
+	}
+
+	return a;
+}
+
diff --git a/libsrc/src/dctool/attrothr.cc b/libsrc/src/dctool/attrothr.cc
new file mode 100644
index 0000000..3bde0b5
--- /dev/null
+++ b/libsrc/src/dctool/attrothr.cc
@@ -0,0 +1,576 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrothr.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrothr.h"
+#include "convtype.h"
+#include "tobyte.h"
+#include "frombyte.h"
+#include "topack.h"
+#include "frompack.h"
+#include "fromshft.h"
+#include "toshft.h"
+#include "cnvbit.h"
+#include "unencap.h"
+
+void
+OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules(
+	Uint16 bitsallocated,
+	TransferSyntax *transfersyntax,
+	Uint16& bytesinword,
+	Endian& encodedendian,
+	Uint32& length,
+	Endian forceEndian)
+{
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start" << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start rows=" << dec << rows << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start columns=" << dec << columns << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start frames=" << dec << frames << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start samples=" << dec << samplesperpixel << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start transfersyntax ptr=" << hex << transfersyntax << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start bytesinword=" << dec << bytesinword << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start encodedendian=" << dec << encodedendian << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start length=" << hex << length << dec << endl;
+
+	Assert(transfersyntax);
+	Endian wordendian = forceEndian == NoEndian ? transfersyntax->getPixelEndian() : forceEndian;
+
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules start wordendian=" << dec << wordendian << endl;
+
+	Assert(bytesinword<=2);
+
+	if (bytesinword == 0)
+		bytesinword =
+			(transfersyntax->isNotEncapsulated()
+			&& (transfersyntax->isImplicitVR() || bitsallocated>8))
+				? 2 : 1;
+
+	Assert(bitsallocated <= bytesinword*8u);
+
+	encodedendian = bytesinword == 2 ? wordendian : ByteEndian;
+
+	if (length == 0xffffffff && transfersyntax->isNotEncapsulated()) {
+		// the following is a problem on < 32 bit long machines, since need largest intermediate value may be bitsallocated * 2^32
+		// but factoring out the ((bitsallocated-1u)/16u+1u)*2u is not really good enough since bitsallocated may not be a multiple of 8 or 16 :(
+		if (bitsallocated % 8 == 0) {
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules Using bitsallocated is modulo 8 method" << endl;
+			 Uint16 bytesPerBitsAllocated = (bitsallocated-1u)/8u+1u;
+			 length=Uint32(rows)*columns*frames*samplesperpixel*bytesPerBitsAllocated;
+			 if (length % 2 == 1) ++length;
+		}
+		else {
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules Using bitsallocated not modulo 8 method" << endl;
+			Assert( ((unsigned long)(rows)*columns*frames*samplesperpixel) <= ((unsigned long)(rows)*columns*frames*samplesperpixel*bitsallocated) );
+			length=(((unsigned long)(rows)*columns*frames*samplesperpixel*bitsallocated-1u)/16u+1u)*2u;	// note cast to ensure (hope) that result is not truncated - 32 bits are NOT enough
+		}
+	}
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules ************" << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules end bytesinword=" << dec << bytesinword << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules end encodedendian=" << dec << encodedendian << endl;
+//cerr << "OtherUnspecifiedLargeAttributeBase::Proposal14EncodingRules end length=" << hex << length << dec << endl;
+}
+
+Uint32
+OtherUnspecifiedLargeAttributeBase::getDestinationBytesPerFrame(void) {
+	Assert(dsttransfersyntax->isNotEncapsulated());
+	Assert( ((Uint64)(rows)*columns*frames*samplesperpixel) < ((Uint64)(rows)*columns*frames*samplesperpixel*dstbitsallocated) );
+	return (Uint32)(((Uint64)(rows)*columns*samplesperpixel*dstbitsallocated-1u)/8u+1u);
+}
+
+DicomOutputStream&
+OtherUnspecifiedLargeAttributeBase::writeData(DicomOutputStream& stream)
+{
+	Assert(dsttransfersyntax == 0
+		|| (stream.getTransferSyntaxToWriteDataSet() != 0
+		   && *(stream.getTransferSyntaxToWriteDataSet())
+			== *dsttransfersyntax));
+
+	writeData((BinaryOutputStream&)stream);
+
+	return stream;
+}
+
+OtherUnspecifiedLargeAttributeBase::OtherUnspecifiedLargeAttributeBase(Tag t,Uint16 r,Uint16 c,Uint16 f,Uint16 sperp)
+		: Attribute(t)
+{
+	srcpixeldata=0;
+
+	rows=r;
+	columns=c;
+	frames=f;
+	samplesperpixel=sperp;
+	//Assert(rows);					// have encountered objects with zero length Pixel Data that are standard extended and not described by Rows, etc. :(
+	//Assert(columns);
+	//Assert(frames);
+	//Assert(samplesperpixel);
+
+	dsttransfersyntax=0;
+	dstbytesinword=0;
+	dstbitsallocated=0;
+	dstbitsstored=0;
+	dsthighbit=0;
+	dstlength=0xffffffff;
+	dstendian=NoEndian;
+
+	srcbitsallocated=0;
+	srcbitsstored=0;
+	srchighbit=0;
+
+	srcpixeldata=0;
+	srcrawdata=0;
+
+	pixelDataPointTransformFilter=0;
+	
+	suppressScalingOnBitDepthConversion = false;		// the default behavior when copying is to move the pixels up if ddstbitsstored > srcbitsstored, i.e., to scale, which may not always be desirable
+}
+
+OtherUnspecifiedLargeAttributeBase::~OtherUnspecifiedLargeAttributeBase()
+{
+	// NB. destruction of srcpixeldata is handled by derived classes prn.
+}
+
+BinaryOutputStream&
+OtherUnspecifiedLargeAttributeBase::writeData(BinaryOutputStream& stream)
+{
+	Assert(dstbitsallocated);
+	Assert(dstendian != NoEndian);
+
+// Comment out this in case PixelEndian != stream.getEndian() ...
+//	Assert(dstendian == stream.getEndian() || (dstendian == ByteEndian && dstbitsallocated == 8));
+
+	if (!activateSource()) Assert(0);
+	Assert(srcpixeldata);
+
+	class SourceBase<Uint16> *srcpixeldatatouse;
+
+	if (pixelDataPointTransformFilter) {
+		if (pixelDataPointTransformFilter->isOffsetIndependent()) {
+			srcpixeldatatouse=new ConvertSourceToSinkWithFilterIndependentOfOffset<Uint16,Uint16>(*srcpixeldata,
+						(PointFilterIndependentOfOffset<Uint16,Uint16> *)pixelDataPointTransformFilter);
+		}
+		else {
+			srcpixeldatatouse=new ConvertSourceToSinkWithFilterDependentOnOffset<Uint16,Uint16>(*srcpixeldata,
+						(PointFilterDependentOnOffset<Uint16,Uint16> *)pixelDataPointTransformFilter);
+		}
+		Assert(srcpixeldatatouse);
+	}
+	else {
+		srcpixeldatatouse=srcpixeldata;
+	}
+
+	ConvertBitUint16 *cnvbit;
+	ShiftUint16 *toshift;
+	if (!suppressScalingOnBitDepthConversion && srcbitsstored != dstbitsstored) {
+//cerr << "OtherUnspecifiedLargeAttributeBase::writeData scaling on bit depth conversion from srcbitsstored=" << srcbitsstored << " to dstbitsstored=" << dstbitsstored << endl;
+		cnvbit = new ConvertBitUint16(*srcpixeldatatouse,srcbitsstored,dstbitsstored);
+		toshift = new ShiftUint16(*cnvbit,dstbitsallocated,dstbitsstored,dsthighbit);
+	}
+	else {
+//cerr << "OtherUnspecifiedLargeAttributeBase::writeData NOT scaling on bit depth conversion - supressed or the same bit depth; from srcbitsstored=" << srcbitsstored << " to dstbitsstored=" << dstbitsstored << endl;
+		cnvbit = NULL;
+		toshift = new ShiftUint16(*srcpixeldatatouse,dstbitsallocated,dstbitsstored,dsthighbit);
+	}
+	if (dstbytesinword == 1) {
+//cerr << "OtherUnspecifiedLargeAttributeBase::writeData dstbytesinword == 1" << endl;
+		Assert(dstbitsallocated == 8);	// No PackByte() yet !
+		ConvertUint16ToByte   tobyte   (*toshift,dstendian);
+		Sink<unsigned char>   output   (stream,tobyte);
+		output.write(dstlength);
+	}
+	else {
+//cerr << "OtherUnspecifiedLargeAttributeBase::writeData dstbytesinword != 1" << endl;
+		PackUint16            topack   (*toshift,dstbitsallocated);
+		ConvertUint16ToByte   tobyte   (topack,dstendian);
+		Sink<unsigned char>   output   (stream,tobyte);
+		output.write(dstlength);
+	}
+
+	if (pixelDataPointTransformFilter) {
+		Assert(srcpixeldatatouse);
+		delete srcpixeldatatouse;
+	}
+
+	if (toshift) {
+		delete toshift;
+	}
+
+	if (cnvbit) {
+		delete cnvbit;
+	}
+
+	return stream;
+}
+
+ostream&
+OtherUnspecifiedLargeAttributeBase::writeRaw(ostream& stream)
+{
+	if (!activateSource()) Assert(0);
+	Assert(srcrawdata);
+
+	Sink<unsigned char>output(stream,*srcrawdata);
+	output.write(0xffffffff);
+
+	return stream;
+}
+
+ostream&
+OtherUnspecifiedLargeAttributeBase::writeRaw(ostream& stream,Uint32 byteOffset,Uint32 byteCount)
+{
+	if (!activateSource()) Assert(0);
+	Assert(srcrawdata);
+
+	Sink<unsigned char>output(stream,*srcrawdata);
+	output.write(byteOffset,byteCount);
+
+	return stream;
+}
+
+TextOutputStream&
+OtherUnspecifiedLargeAttributeBase::write(TextOutputStream& stream,
+			ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	return stream;
+}
+
+BinaryOutputStream&
+OtherUnspecifiedLargeAttributeBase::write(BinaryOutputStream& stream)
+{
+	// not in use
+	Assert(0);
+	return stream;
+}
+
+DicomOutputStream&
+OtherUnspecifiedLargeAttributeBase::write(DicomOutputStream& stream)
+{
+	Attribute::writeBase(stream);
+	writeData(stream);
+	return stream;
+}
+
+BinaryInputStream&
+OtherUnspecifiedLargeAttributeBase::read(BinaryInputStream& stream,Uint32 length)
+{
+	// read is handled elsewhere ... see attrmxrd.h
+	(void)length;
+	Assert(0);
+	return stream;
+}
+
+void
+OtherUnspecifiedLargeAttributeBase::setOutputEncoding(
+		TransferSyntax *transfersyntax,
+		Uint16 bytesinword,
+		Uint16 bitsallocated,
+		Uint16 bitsstored,
+		Uint16 highbit,
+		Uint32 length)
+{
+	Assert(transfersyntax);
+
+	dsttransfersyntax=transfersyntax;
+	dstbytesinword=bytesinword;
+	dstbitsallocated=bitsallocated;
+	dstbitsstored=bitsstored;
+	dsthighbit=highbit;
+	dstlength=length;
+
+	Assert(dstbitsstored <= dstbitsallocated);
+	Assert(dsthighbit < dstbitsstored);
+
+	Proposal14EncodingRules(
+		dstbitsallocated,
+		transfersyntax,
+		dstbytesinword,
+		dstendian,
+		dstlength,
+		NoEndian);
+}
+
+OtherUnspecifiedLargeAttribute::OtherUnspecifiedLargeAttribute(Tag t,
+		SourceBase<Uint16> *src,
+		Uint16 r,Uint16 c,Uint16 f,Uint16 sperp)
+	: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+{
+	Assert(0);	// otherwise how to set srcbitsallocated, etc. ?
+	(void)src;
+	//Assert(src!=0);
+	//srcpixeldata=src;
+}
+
+OtherUnspecifiedLargeAttribute::OtherUnspecifiedLargeAttribute(Tag t,
+		SourceBase<Uint16> *src,
+		Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+		TransferSyntax *transfersyntax,
+		Uint16 bytesinword,
+		Uint16 bitsallocated,
+		Uint16 bitsstored,
+		Uint16 highbit,
+		Uint32 length)
+	: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+{
+	Assert(src!=0);
+	srcpixeldata=src;
+
+	srcbitsallocated=bitsallocated;
+	srcbitsstored=bitsstored;
+	srchighbit=highbit;
+
+	Assert(transfersyntax);
+	setOutputEncoding(
+		transfersyntax,
+		bytesinword,bitsallocated,
+		bitsstored,highbit,length);
+}
+
+OtherUnspecifiedLargeAttribute::~OtherUnspecifiedLargeAttribute()
+{
+	// NB. destruction does NOT delete srcpixeldata
+}
+
+bool
+OtherUnspecifiedLargeAttribute::activateSource(void)
+{
+	return true;
+}
+
+bool
+OtherUnspecifiedLargeAttribute::activateSourceWithoutUnpacking(void)
+{
+	Assert(0);
+	return true;
+}
+
+OtherUnspecifiedLargeAttributeCopied::OtherUnspecifiedLargeAttributeCopied(Tag t,Uint16 r,Uint16 c,Uint16 f,Uint16 sperp)
+	: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+{
+	srcstream=0;
+	srcpos=OurStreamPos(-1);
+	srclength=0;
+	srcbytesinword=0;
+	srcbitsallocated=0;
+	srcbitsstored=0;
+	srchighbit=0;
+	srcendian=NoEndian;
+
+	srcinput     = 0;
+	srcfrombyte  = 0;
+	srcfrompack  = 0;
+	srcfromshift = 0;
+}
+
+OtherUnspecifiedLargeAttributeCopied::OtherUnspecifiedLargeAttributeCopied(Tag t,
+		DicomInputStream &stream,OurStreamPos pos,
+		Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+		Uint16 bytesinword,
+		Uint16 bitsallocated,
+		Uint16 bitsstored,
+		Uint16 highbit,
+		Uint32 length,
+		Endian forceEndian)
+	: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+{
+//cerr << "OtherUnspecifiedLargeAttributeCopied::OtherUnspecifiedLargeAttributeCopied length=" << hex << length << dec << endl;
+	srcstream=&stream;
+	srcpos=pos;
+	srcbytesinword=bytesinword;
+	srcbitsallocated=bitsallocated;
+	srcbitsstored=bitsstored;
+	srchighbit=highbit;
+	srclength=length;
+
+	srcinput    = 0;
+	srcfrombyte = 0;
+	srcfrompack = 0;
+	srcfromshift = 0;
+
+	Assert(srcstream);
+	Assert(srcbitsallocated);
+
+//cerr << "OtherUnspecifiedLargeAttributeCopied::OtherUnspecifiedLargeAttributeCopied srclength=" << hex << srclength << dec << endl;
+	Proposal14EncodingRules(
+		srcbitsallocated,
+		srcstream->getTransferSyntaxToReadDataSet(),
+		srcbytesinword,
+		srcendian,
+		srclength,
+		forceEndian);
+
+	// Default is to write same as read
+	// until otherwise set by setOutputEncoding()
+
+	dsttransfersyntax=
+		srcstream->getTransferSyntaxToReadDataSet();
+	dstendian=srcendian;
+	dstbytesinword=srcbytesinword;
+	dstbitsallocated=srcbitsallocated;
+	dstbitsstored=srcbitsstored;
+	dsthighbit=srchighbit;
+	dstlength=srclength;
+}
+
+OtherUnspecifiedLargeAttributeCopied::~OtherUnspecifiedLargeAttributeCopied()
+{
+	if (srcinput) delete srcinput;
+	if (srcfrombyte) delete srcfrombyte;
+	if (srcfrompack) delete srcfrompack;
+	if (srcfromshift) delete srcfromshift;
+	// Not srcpixeldata because it was a copy of srcfrombyte/srcfrompack/srcfromshift
+	// Not srcrawdata because it was a copy of srcinput
+}
+
+bool
+OtherUnspecifiedLargeAttributeCopied::activateSource(void)
+{
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		if (srcinput) delete srcinput;
+		Assert(srclength != 0xffffffff);
+		// want the buffer size a multiple of various things to
+		// prevent them traversing buffer boundaries ...
+		srcinput=new Source<unsigned char>(*srcstream,
+			(size_t)columns*srcbitsallocated*samplesperpixel,srclength);
+		Assert(srcinput);
+		srcrawdata=srcinput;
+
+		if (srcfrombyte) delete srcfrombyte;
+		srcfrombyte = new ConvertByteToUint16(*srcinput,srcendian);
+		Assert(srcfrombyte);
+
+		if (srcbytesinword == 1) {
+//cerr << "OtherUnspecifiedLargeAttributeCopied::activateSource srcbytesinword == 1" << endl;
+			Assert(srcbitsallocated == 8);	// No UnpackByte() yet !
+			Assert(!srcfrompack);
+			srcpixeldata=srcfrombyte;
+		}
+		else {
+//cerr << "OtherUnspecifiedLargeAttributeCopied::activateSource srcbytesinword != 1" << endl;
+			if (srcfrompack) delete srcfrompack;
+			srcfrompack = new UnpackUint16(*srcfrombyte,srcbitsallocated);
+			Assert(srcfrompack);
+			if (srcfromshift) delete srcfromshift;
+			srcfromshift = new UnshiftUint16(*srcfrompack,srcbitsallocated,srcbitsstored,srchighbit);
+			Assert(srcfromshift);
+			srcpixeldata=srcfromshift;
+		}
+
+		return true;
+	}
+	else
+		return false;
+}
+
+bool
+OtherUnspecifiedLargeAttributeCopied::activateSourceWithoutUnpacking(void)
+{
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		if (srcinput) delete srcinput;
+		Assert(srclength != 0xffffffff);
+		// want the buffer size a multiple of various things to
+		// prevent them traversing buffer boundaries ...
+		srcinput=new Source<unsigned char>(*srcstream,
+			(size_t)columns*srcbitsallocated*samplesperpixel,srclength);
+		Assert(srcinput);
+		srcrawdata=srcinput;
+
+		if (srcfrombyte) delete srcfrombyte;
+		srcfrombyte = new ConvertByteToUint16(*srcinput,srcendian);
+		Assert(srcfrombyte);
+
+		if (srcbytesinword == 1) {
+//cerr << "OtherUnspecifiedLargeAttributeCopied::activateSource srcbytesinword == 1" << endl;
+			Assert(srcbitsallocated == 8);	// No UnpackByte() yet !
+			Assert(!srcfrompack);
+			srcpixeldata=srcfrombyte;
+		}
+		else {
+//cerr << "OtherUnspecifiedLargeAttributeCopied::activateSource srcbytesinword != 1" << endl;
+			if (srcfrompack) delete srcfrompack;
+			srcfrompack = new UnpackUint16(*srcfrombyte,srcbitsallocated);
+			Assert(srcfrompack);
+			if (srcfromshift) delete srcfromshift;
+			srcfromshift = NULL;
+			srcpixeldata=srcfrompack;
+		}
+
+		return true;
+	}
+	else
+		return false;
+}
+
+OtherUnspecifiedLargeAttributeEncapsulated::OtherUnspecifiedLargeAttributeEncapsulated(Tag t,
+		DicomInputStream &stream,OurStreamPos pos,
+		Uint16 r,Uint16 c,Uint16 f,Uint16 sperp,
+		Uint16 bitsallocated,
+		Uint16 bitsstored,
+		Uint16 highbit)
+	: OtherUnspecifiedLargeAttributeBase(t,r,c,f,sperp)
+{
+//cerr << "OtherUnspecifiedLargeAttributeEncapsulated::OtherUnspecifiedLargeAttributeEncapsulated" << endl;
+	srcstream=&stream;
+	srcpos=pos;
+	srcbitsallocated=bitsallocated;
+	srcbitsstored=bitsstored;
+	srchighbit=highbit;
+
+	Assert(srcstream);
+	Assert(srcbitsallocated);
+
+	// Proposal14EncodingRules don't apply to encapsulated data
+
+	// Default is to write same as read
+	// until otherwise set by setOutputEncoding()
+
+	dsttransfersyntax=
+		srcstream->getTransferSyntaxToReadDataSet();
+	dstendian=ByteEndian;
+	dstbytesinword=1;
+	dstbitsallocated=srcbitsallocated;
+	dstbitsstored=srcbitsstored;
+	dsthighbit=srchighbit;
+	// note cast to Uint32 to ensure that result is not truncated
+	if (srcbitsallocated % 8 == 0) {
+		dstlength= Uint32(r)*c*f*sperp*(srcbitsallocated/8);
+	}
+	else {
+		// account for packed data, as in old ACR-NEMA objects, instead of assuming whole number of bytes
+		// but this may overflow 32 bits if too long :(
+		dstlength= ((Uint32(r)*c*f*sperp*srcbitsallocated-1)/8+1);
+	}
+	if (dstlength%2 == 1) {
+		++dstlength;	// odd lengths are always padded by one byte to even
+	}
+}
+
+OtherUnspecifiedLargeAttributeEncapsulated::~OtherUnspecifiedLargeAttributeEncapsulated()
+{
+	if (srcrawdata) delete srcrawdata;
+	// srcpixeldata is not yet in use
+}
+
+bool
+OtherUnspecifiedLargeAttributeEncapsulated::activateSource(void)
+{
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		if (srcrawdata) delete srcrawdata;
+		srcrawdata = new UnencapsulatePixelData(*srcstream);
+		Assert(srcrawdata);
+		srcpixeldata=0;		// decompression NYI
+		return true;
+	}
+	else
+		return false;
+}
+
+bool
+OtherUnspecifiedLargeAttributeEncapsulated::activateSourceWithoutUnpacking(void)
+{
+	Assert(0);
+	return true;
+}
+
diff --git a/libsrc/src/dctool/attrseq.cc b/libsrc/src/dctool/attrseq.cc
new file mode 100644
index 0000000..e439f85
--- /dev/null
+++ b/libsrc/src/dctool/attrseq.cc
@@ -0,0 +1,155 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrseq.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "attrmxls.h"
+#include "attrseq.h"
+#include "elmconst.h"
+#include "elmtype.h"
+#include "mesgtext.h"
+
+// The various items and delimiters have no VR and always have
+// implicit VR style value length fields
+
+SequenceAttribute::~SequenceAttribute()
+{
+	FifoListIterator<AttributeList *> itemsi(listoflists);
+	while (!itemsi) {
+		AttributeListIterator listi(*itemsi());
+		while (!listi) {
+			Attribute *a=listi();
+			Assert(a);
+			delete a;
+			++listi;
+		}
+		++itemsi;
+	}
+}
+
+DicomOutputStream&
+SequenceAttribute::write(DicomOutputStream& stream)
+{
+	// The various items and delimiters have no VR and always have
+	// implicit VR style value length fields
+
+	Attribute::writeBase(stream);
+	FifoListIterator<AttributeList *> itemsi(listoflists);
+	while (!itemsi) {
+		stream << TagFromName(Item)
+		       << Uint32(0xffffffff);	// undefined VL
+		AttributeListIterator listi(*itemsi());
+		while (!listi) {
+			stream << *listi();
+			++listi;
+		}
+		stream << TagFromName(ItemDelimitationItem) << Uint32(0);
+		++itemsi;
+	}
+	stream << TagFromName(SequenceDelimitationItem) << Uint32(0);
+	return stream;
+}
+
+TextOutputStream&
+SequenceAttribute::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "\n";
+	FifoListIterator<AttributeList *> itemsi(listoflists);
+	while (!itemsi) {
+		ElementDictionary *itemdict=((ReadableAttributeList *)itemsi())->getDictionary();
+		AttributeListIterator listi(*itemsi());
+		stream << "  ----:\n";
+		while (!listi) {
+			stream << "    > ";
+			//Assert(itemdict);
+			listi()->write(stream,itemdict ? itemdict : dict,verbose);
+			stream << "\n";
+			++listi;
+		}
+		++itemsi;
+	}
+	return stream;
+}
+
+int
+SequenceAttribute::getLists(AttributeList ***a)
+{
+	// returns number of AttributeList pointers
+	// creates an array of these pointers in a
+	// it is the callers responsibility to destroy
+	// the array (but NOT the objects pointed to) later
+
+	FifoListIterator<AttributeList *> itemsi(listoflists);
+
+	int n=0;
+	while (!itemsi) {
+		++n;
+		++itemsi;
+	}
+	if (n) {
+		*a=new AttributeList * [n];
+		int i;
+		for (i=0,itemsi.first(); i<n && !itemsi; ++i,++itemsi) {
+			(*a)[i]=itemsi();
+		}
+	}
+	else
+		*a=0;
+
+	return n;
+}
+
+Uint32
+SequenceAttribute::getNumberOfItems (void) const
+{
+	Uint32 nItems=0;
+	SimpleListEntry<AttributeList *> *ptr = listoflists.head;
+	while (ptr) {
+		++nItems;
+		ptr=ptr->next;
+	}
+	return nItems;
+}
+
+
+bool
+SequenceAttribute::verifyVM(const char *module,const char *element,
+	TextOutputStream& log,
+	ElementDictionary *dict,
+	Uint16 multiplicityMin,Uint16 multiplicityMax,const char *specifiedSource) const
+{
+	// Sequences always have a VM of 1, by definition
+	// Here we are checking the number of items, not the VM per se.
+	Assert(dict);
+	Tag tag=getTag();
+	Uint32 nItems = getNumberOfItems();
+//log << "SequenceAttribute::verifyVM(): nItems = " << nItems << endl;
+	Uint16 errmin,errmax;
+	int err=0;
+	const char *source;
+	if (multiplicityMin != 0 && multiplicityMax != 0) {	// else don't check
+		if (nItems < multiplicityMin || nItems >multiplicityMax) {
+			err=1;
+			errmin=multiplicityMin;
+			errmax=multiplicityMax;
+			source= specifiedSource ? specifiedSource : MMsgDC(ModuleDefinition);
+		}
+	}
+	if (err) {
+		log << EMsgDC(BadSequenceNumberOfItems)
+		    <<  " " << dec << nItems << " (" << errmin;
+		if (errmin != errmax)
+			if (errmax == VMUNLIMITED)
+				log << "-n";
+			else
+				log << "-" << errmax;
+		log << " " << MMsgDC(RequiredBy) << " " << source << ")";
+		if (element) log << " " << MMsgDC(Element) << "=<" << element << ">";
+		if (module)  log << " " << MMsgDC(Module)  << "=<" << module  << ">";
+		log << endl;
+		return false;
+	}
+	else {
+		return true;
+	}
+}
+
diff --git a/libsrc/src/dctool/attrtag.cc b/libsrc/src/dctool/attrtag.cc
new file mode 100644
index 0000000..e617448
--- /dev/null
+++ b/libsrc/src/dctool/attrtag.cc
@@ -0,0 +1,139 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrtag.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtag.h"
+#include "elmdict.h"
+
+Tag
+Tag::getRepeatingBase(void) const
+{
+	Uint16 g=group;
+	Uint16 e=element;
+
+	Uint16 gMASKEDff00=g&0xff00;
+	Uint16 eMASKEDff00=e&0xff00;
+	Uint16 eMASKEDff0f=e&0xff0f;
+
+	// Transformations must match those in dictionary ... see elmdict.awk,elmdict.tpl,attrtag.cc
+
+	// Note that some are from element 0xxx00 and others from 0xxx10
+
+	if      (g == 0x0020) {
+		if      (eMASKEDff00 == 0x3100) e=0x3100;			// 0x31xx - PS 300 - Source Image IDs
+	}
+	else if (g == 0x0028) {
+		if      (eMASKEDff0f == 0x0400 && e != 0x0400) e=0x0410;	// 0x04x0 - PS 2 - RowsForNthOrderCoefficients
+		else if (eMASKEDff0f == 0x0401 && e != 0x0401) e=0x0411;	// 0x04x1 - PS 2 - ColumnsForNthOrderCoefficients
+		else if (eMASKEDff0f == 0x0402 && e != 0x0402) e=0x0412;	// 0x04x2 - PS 2 - CoefficientCoding
+		else if (eMASKEDff0f == 0x0403 && e != 0x0403) e=0x0413;	// 0x04x3 - PS 2 - CoefficientCodingPointers
+
+		else if (eMASKEDff0f == 0x0800) e=0x0800;			// 0x08x0 - PS 2 - CodeLabel
+		else if (eMASKEDff0f == 0x0802) e=0x0802;			// 0x08x2 - PS 2 - NumberOfTables
+		else if (eMASKEDff0f == 0x0803) e=0x0803;			// 0x08x3 - PS 2 - CodeTableLocation
+		else if (eMASKEDff0f == 0x0804) e=0x0804;			// 0x08x4 - PS 2 - BitsForCodeWord
+		else if (eMASKEDff0f == 0x0808) e=0x0808;			// 0x08x8 - PS 2 - ImageDataLocation
+	}
+	else if (g == 0x1000) {
+		if      (eMASKEDff0f == 0x0000 && e != 0x0000) e=0x0010;	// 0x00x0 - PS 2 - Escape Triplet
+		else if (eMASKEDff0f == 0x0001 && e != 0x0001) e=0x0011;	// 0x00x1 - PS 2 - Run Length Triplet
+		else if (eMASKEDff0f == 0x0002 && e != 0x0002) e=0x0012;	// 0x00x2 - PS 2 - Huffman Table Size
+		else if (eMASKEDff0f == 0x0003 && e != 0x0003) e=0x0013;	// 0x00x3 - PS 2 - Huffman Table Triplet
+		else if (eMASKEDff0f == 0x0004 && e != 0x0004) e=0x0014;	// 0x00x4 - PS 2 - Shift Table Size
+		else if (eMASKEDff0f == 0x0005 && e != 0x0005) e=0x0015;	// 0x00x5 - PS 2 - Shift Table Triplet
+	}
+	else if (g == 0x1010) {
+		if (e >= 0x0004 && e <= 0xfffe) e=0x0004;			// PS 2 - Zonal Map
+	}
+	else if (gMASKEDff00 == 0x5000) g=(g%2) ? 0x5001: 0x5000;		// 0x50xx - PS 3 - Curve stuff
+	else if (gMASKEDff00 == 0x6000) g=(g%2) ? 0x6001: 0x6000;		// 0x60xx - PS 3 and earlier - Overlay stuff
+	else if (gMASKEDff00 == 0x7000) g=(g%2) ? 0x7001: 0x7000;		// 0x70xx - Private DLX TextAnnotation etc.
+	else if (gMASKEDff00 == 0x7f00 && g != 0x7fe0) g=0x7f00;		// 0x7Fxx - PS 2 - VariablePixelData
+
+	return Tag(g,e);
+}
+
+
+TextOutputStream&
+Tag::write(TextOutputStream& stream,ElementDictionary *dict) const
+{
+	stream << "(";
+	writeZeroPaddedHexNumber(stream,group,4);
+	stream << ",";
+	writeZeroPaddedHexNumber(stream,element,4);
+	stream << ") " << flush;
+
+	const char *vr=0;
+	const char *desc=0;
+
+	if (isPrivateGroup() && isPrivateOwner()) {
+		vr="LO";		// PS3.5-7.8.1
+		desc="PrivateCreator";
+	}
+	else if (dict) {
+		vr=dict->getValueRepresentation(*this);
+		desc=dict->getDescription(*this);
+	}
+
+	stream << (vr ? vr : "") << " ";
+	stream << (desc ? desc : "?") << " " << flush;
+
+	return stream;
+}
+
+BinaryOutputStream&
+Tag::write(BinaryOutputStream& stream) const
+{
+	stream << group << element;
+	return stream;
+}
+
+DicomOutputStream&
+Tag::write(DicomOutputStream& stream) const
+{
+	// NB. Changing transfer syntaxes is caller's responsibility
+	write((BinaryOutputStream&)stream);
+	return stream;
+}
+
+BinaryInputStream&
+Tag::read(BinaryInputStream& stream)
+{
+	stream >> group;
+	stream >> element;
+	return stream;
+}
+
+DicomInputStream&
+Tag::read(DicomInputStream& stream)
+{
+	// NB. Changing transfer syntaxes is caller's responsibility
+	read((BinaryInputStream&)stream);
+	return stream;
+}
+
+BinaryInputStream&
+BinaryInputStream::operator>>(Tag& rhs)
+{
+	rhs.read(*this);
+	return *this;
+}
+
+DicomInputStream&
+DicomInputStream::operator>>(Tag& rhs)
+{
+	rhs.read(*this);
+	return *this;
+}
+
+BinaryOutputStream&
+BinaryOutputStream::operator<<(Tag rhs)
+{
+	rhs.write(*this);
+	return *this;
+}
+
+DicomOutputStream&
+DicomOutputStream::operator<<(Tag rhs)
+{
+	rhs.write(*this);
+	return *this;
+}
+
diff --git a/libsrc/src/dctool/attrtypd.cc b/libsrc/src/dctool/attrtypd.cc
new file mode 100644
index 0000000..01cef72
--- /dev/null
+++ b/libsrc/src/dctool/attrtypd.cc
@@ -0,0 +1,92 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrtypd.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrtype.h"
+
+DateStringAttribute::DateStringAttribute(Tag t,Date const & date)
+		: NonNumericStringAttribute(t)
+{
+			ostrstream ost;
+			ost << dec << setfill('0');
+			if (date.isgood()) {
+				ost << setw(4) << date.getYYYY()
+				    << setw(2) << date.getMM()
+				    << setw(2) << date.getDD();
+			}
+			ost << ends;
+			char *s = ost.str();
+			addValue(s);
+			if (s) delete[] s;
+}
+
+DateStringAttribute::DateStringAttribute(Tag t,DateTime const & datetime)
+		: NonNumericStringAttribute(t)
+		{
+			ostrstream ost;
+			ost << dec << setfill('0');
+			if (datetime.isgood()) {
+				ost << setw(4) << datetime.getYYYY()
+				    << setw(2) << datetime.getMM()
+				    << setw(2) << datetime.getDD();
+			}
+			ost << ends;
+			char *s = ost.str();
+			addValue(s);
+			if (s) delete[] s;
+		}
+
+DateTimeStringAttribute::DateTimeStringAttribute(Tag t,Date const & date,Time const & time)
+		: NonNumericStringAttribute(t)
+		{
+			ostrstream ost;
+			ost << dec << setfill('0');
+			if (date.isgood()) {
+				ost << setw(4) << date.getYYYY()
+				    << setw(2) << date.getMM()
+				    << setw(2) << date.getDD();
+				if (time.isgood()) {
+					ost << setw(2) << time.getHour()
+					    << setw(2) << time.getMinute()
+					    << setw(2) << time.getSecond();
+					if (time.getMilliSecond())
+						ost << '.' << setw(3) << time.getMilliSecond();
+				}
+			}
+			ost << ends;
+			char *s = ost.str();
+			addValue(s);
+			if (s) delete[] s;
+		}
+TimeStringAttribute::TimeStringAttribute(Tag t,Time const & time)
+		: NonNumericStringAttribute(t)
+		{
+			ostrstream ost;
+			ost << dec << setfill('0');
+			if (time.isgood()) {
+				ost << setw(2) << time.getHour()
+				    << setw(2) << time.getMinute()
+				    << setw(2) << time.getSecond();
+				if (time.getMilliSecond())
+					ost << '.' << setw(3) << time.getMilliSecond();
+			}
+			ost << ends;
+			char *s = ost.str();
+			addValue(s);
+			if (s) delete[] s;
+		}
+
+TimeStringAttribute::TimeStringAttribute(Tag t,DateTime const & datetime)
+		: NonNumericStringAttribute(t)
+		{
+			ostrstream ost;
+			ost << dec << setfill('0');
+			if (datetime.isgood()) {
+				ost << setw(2) << datetime.getHour()
+				    << setw(2) << datetime.getMinute()
+				    << setw(2) << datetime.getSecond();
+				if (datetime.getMilliSecond())
+					ost << '.' << setw(3) << datetime.getMilliSecond();
+			}
+			ost << ends;
+			char *s = ost.str();
+			addValue(s);
+			if (s) delete[] s;
+		}
diff --git a/libsrc/src/dctool/attrtypo.cc b/libsrc/src/dctool/attrtypo.cc
new file mode 100644
index 0000000..a89040c
--- /dev/null
+++ b/libsrc/src/dctool/attrtypo.cc
@@ -0,0 +1,791 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrtypo.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrtypo.h"
+#include "attrtag.h"
+#include "elmdict.h"
+#include "srcsink.h"
+#include "convtype.h"
+#include "tobyte.h"
+#include "frombyte.h"
+
+OtherNonPixelAttribute::OtherNonPixelAttribute(Tag t) : Attribute(t)
+{
+	lengthinbytes=0;
+}
+
+OtherNonPixelAttribute:: ~OtherNonPixelAttribute(void)
+{
+}
+
+OtherByteSmallNonPixelAttributeBase::OtherByteSmallNonPixelAttributeBase(Tag t)
+	 : OtherNonPixelAttribute(t)
+{
+	data=0;
+}
+
+OtherByteSmallNonPixelAttributeBase:: ~OtherByteSmallNonPixelAttributeBase(void)
+{
+	if (data) delete[] data;
+}
+
+BinaryOutputStream&
+OtherByteSmallNonPixelAttributeBase::writeValues(BinaryOutputStream& stream)
+{
+	if (lengthinbytes) {
+		Assert(data);
+		stream.write((char *)data,size_t(lengthinbytes));
+	}
+	return stream;
+}
+
+TextOutputStream&
+OtherByteSmallNonPixelAttributeBase::writeData(TextOutputStream& stream)
+{
+	Uint32 i = lengthinbytes;
+	unsigned char *ptr = data;
+	while (i > 0) {
+		writeZeroPaddedHexNumber(stream,unsigned(*ptr++),2);
+		--i;
+		if (i > 0) {
+			stream << ",";
+			if (i%16 == 0) stream << "\n\t";
+		}
+	}
+	return stream;
+}
+
+TextOutputStream&
+OtherByteSmallNonPixelAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	Tag t = getTag();
+	if (dict->isRenderAsString(t)) {
+		stream << "<";
+		stream << data;
+		if (strlen((const char *)data)%2) stream << ' ';		// pad for consistency with string attribute writes
+		stream << "> ";
+	}
+	else {
+		stream << "[";
+		writeData(stream);
+		stream << "] ";
+	}
+	return stream;
+}
+
+BinaryInputStream&
+OtherByteSmallNonPixelAttributeBase::read(BinaryInputStream& stream,Uint32 length)
+{
+	Assert(lengthinbytes == 0);
+	Assert(data == 0);
+	Assert(length%2 == 0);	// DICOM likes even things
+	data=new unsigned char[length];
+	Assert(data);
+	if (length) stream.read((char *)data,size_t(length));
+	lengthinbytes=length;
+	return stream;
+}
+
+bool
+OtherByteSmallNonPixelAttributeBase::getValue(const unsigned char * & rvalue,Uint32 &rlength) const
+{
+	rlength=lengthinbytes;
+	rvalue=data;
+	return true;	// ? should this be false if zero length ? :(
+}
+
+void
+OtherByteSmallNonPixelAttributeBase::setValue(const unsigned char *values,Uint32 length)
+{
+	Assert(lengthinbytes == 0);
+	Assert(data == 0);
+	Assert(length%2 == 0);	// DICOM likes even things
+	data=new unsigned char[length];
+	Assert(data);
+	memcpy(data,values,size_t(length));
+	lengthinbytes=length;
+}
+
+OtherWordSmallNonPixelAttributeBase::OtherWordSmallNonPixelAttributeBase(Tag t)
+	 : OtherNonPixelAttribute(t)
+{
+	data=0;
+}
+
+OtherWordSmallNonPixelAttributeBase:: ~OtherWordSmallNonPixelAttributeBase(void)
+{
+	if (data) delete[] data;
+}
+
+BinaryOutputStream&
+OtherWordSmallNonPixelAttributeBase::writeValues(BinaryOutputStream& stream)
+{
+	if (lengthinbytes) {
+		Assert(data);
+		Assert(lengthinbytes%2 == 0);
+		Uint32 lengthinwords=lengthinbytes/2;
+		Uint16 *ptr=data;
+		while (lengthinwords--) stream << *ptr++;
+	}
+	return stream;
+}
+
+TextOutputStream&
+OtherWordSmallNonPixelAttributeBase::writeData(TextOutputStream& stream)
+{
+	Assert(lengthinbytes%2 == 0);
+	Uint32 i = lengthinbytes/2;
+	Uint16 *ptr = data;
+	while (i > 0) {
+		writeZeroPaddedHexNumber(stream,*ptr++,4);
+		--i;
+		if (i > 0) {
+			stream << ",";
+			if (i%8 == 0) stream << "\n\t";
+		}
+	}
+	return stream;
+}
+
+TextOutputStream&
+OtherWordSmallNonPixelAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+OtherWordSmallNonPixelAttributeBase::read(BinaryInputStream& stream,Uint32 length)
+{
+	Assert(lengthinbytes == 0);
+	Assert(data == 0);
+	Assert(length%2 == 0);	// DICOM likes even things
+	Uint32 lengthinwords=length/2;
+	if (lengthinwords) {
+		data=new Uint16[lengthinwords];
+		Assert(data);
+		Uint32 i=lengthinwords;
+		Uint16 *ptr=data;
+		while (i--) stream >> *ptr++;
+		lengthinbytes=length;
+	}
+	return stream;
+}
+
+bool
+OtherWordSmallNonPixelAttributeBase::getValue(const Uint16 * & rvalue,Uint32 &rlengthinwords) const
+{
+	Assert(lengthinbytes%2 == 0);
+	rlengthinwords=lengthinbytes/2;
+	rvalue=data;
+	return true;	// ? should this be false if zero length ? :(
+}
+
+void
+OtherWordSmallNonPixelAttributeBase::setValue(const Uint16 *values,Uint32 lengthinwords)
+{
+	Assert(lengthinbytes == 0);
+	Assert(data == 0);
+	if (lengthinwords) {
+		data=new Uint16[lengthinwords];
+		Assert(data);
+		Uint32 i=lengthinwords;
+		Uint16 *ptr=data;
+		while (i--) *ptr++=*values++;
+		lengthinbytes=lengthinwords*2;
+	}
+}
+
+OtherByteLargeNonPixelAttributeBase::OtherByteLargeNonPixelAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos,OurStreamPos length)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	srcpos=pos;
+	srclength=length;
+	hasSrclength=true;
+	lengthinbytes=length;
+	if (lengthinbytes%2 != 0) {
+		++lengthinbytes;
+	}
+	
+	Assert(srcstream);
+}
+
+OtherByteLargeNonPixelAttributeBase::OtherByteLargeNonPixelAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	srcpos=pos;
+	hasSrclength=false;
+
+	Assert(srcstream);
+}
+
+OtherByteLargeNonPixelAttributeBase::~OtherByteLargeNonPixelAttributeBase()
+{
+}
+
+BinaryOutputStream&
+OtherByteLargeNonPixelAttributeBase::writeValues(BinaryOutputStream& dststream)
+{
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	Uint32 lengthToCopy = hasSrclength ? Uint32(srclength) : lengthinbytes;
+	if (srcstream->good()) {
+		Source<unsigned char> srcinput    (*srcstream,1024,lengthToCopy);
+		Sink<unsigned char>   output      (dststream,srcinput);
+		output.write(lengthToCopy);
+	}
+	Uint32 pad = lengthinbytes - lengthToCopy;
+	while (pad-- > 0) {
+//cerr << "OtherByteLargeNonPixelAttributeBase::writeValues: writing pad byte" << endl;
+		dststream.put(0);
+	}
+	return dststream;
+}
+
+TextOutputStream&
+OtherByteLargeNonPixelAttributeBase::writeData(TextOutputStream& stream)
+{
+	stream << "...";
+	return stream;
+}
+
+TextOutputStream&
+OtherByteLargeNonPixelAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+OtherByteLargeNonPixelAttributeBase::read(BinaryInputStream& stream,Uint32 vl)
+{
+	Assert(&stream == srcstream);
+	stream.seekg(vl,ios::cur);
+	lengthinbytes=vl;
+	return stream;
+}
+
+bool
+OtherByteLargeNonPixelAttributeBase::getValue(const unsigned char * &,Uint32 &) const
+{
+	Assert(0);
+	return false;
+}
+
+void
+OtherByteLargeNonPixelAttributeBase::setValue(const unsigned char *,Uint32 )
+{
+	Assert(0);
+}
+
+
+OtherWordLargeNonPixelAttributeBase::OtherWordLargeNonPixelAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	Assert(srcstream);
+	srcpos=pos;
+	srcendian=srcstream->getEndian();
+	Assert(srcendian != NoEndian);
+	Assert(srcendian != ByteEndian);
+}
+
+OtherWordLargeNonPixelAttributeBase::~OtherWordLargeNonPixelAttributeBase()
+{
+}
+
+BinaryOutputStream&
+OtherWordLargeNonPixelAttributeBase::writeValues(BinaryOutputStream& dststream)
+{
+	// use current dststream endian, not getTransferSyntaxToReadDataSet()->getEndian()
+	Endian dstendian=dststream.getEndian();
+	Assert(dstendian != NoEndian);
+	Assert(dstendian != ByteEndian);
+
+	Assert(getVL()%2 == 0);
+
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		Source<unsigned char> srcinput    (*srcstream,1024,getVL());
+		ConvertByteToUint16   srcfrombyte (srcinput,srcendian);
+		ConvertUint16ToByte   tobyte      (srcfrombyte,dstendian);
+		Sink<unsigned char>   output      (dststream,tobyte);
+		output.write(getVL());
+	}
+	return dststream;
+}
+
+TextOutputStream&
+OtherWordLargeNonPixelAttributeBase::writeData(TextOutputStream& stream)
+{
+	stream << "...";
+	return stream;
+}
+
+TextOutputStream&
+OtherWordLargeNonPixelAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+OtherWordLargeNonPixelAttributeBase::read(BinaryInputStream& stream,Uint32 vl)
+{
+	Assert(&stream == srcstream);
+	stream.seekg(vl,ios::cur);
+	lengthinbytes=vl;
+	return stream;
+}
+
+bool
+OtherWordLargeNonPixelAttributeBase::getValue(const Uint16 * &,Uint32 &) const
+{
+	Assert(0);
+	return false;
+}
+
+void
+OtherWordLargeNonPixelAttributeBase::setValue(const Uint16 *,Uint32 )
+{
+	Assert(0);
+}
+
+/* ********************* OL VR Attributes ********************* */
+
+OtherLongLargeAttributeBase::OtherLongLargeAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	Assert(srcstream);
+	srcpos=pos;
+	srcendian=srcstream->getEndian();
+	Assert(srcendian != NoEndian);
+	Assert(srcendian != ByteEndian);
+}
+
+OtherLongLargeAttributeBase::~OtherLongLargeAttributeBase()
+{
+}
+
+BinaryOutputStream&
+OtherLongLargeAttributeBase::writeValues(BinaryOutputStream& dststream)
+{
+	// use current dststream endian, not getTransferSyntaxToReadDataSet()->getEndian()
+	Endian dstendian=dststream.getEndian();
+	Assert(dstendian != NoEndian);
+	Assert(dstendian != ByteEndian);
+
+	Assert(getVL()%4 == 0);
+
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		// we don't have a ConvertByteToUint32, analogous to the ConvertByteToUint16 used for OW, so do it like we do for OF and OD ...
+		Source<unsigned char> srcinput (*srcstream,1024,getVL());
+		if (dstendian != srcendian) {
+			ConvertSourceToSinkSwapping<unsigned char,unsigned char,4> swab(srcinput);
+			Sink<unsigned char> output(dststream,swab);
+			output.write(getVL());
+		}
+		else {
+			Sink<unsigned char> output(dststream,srcinput);
+			output.write(getVL());
+		}
+	}
+	return dststream;
+}
+
+TextOutputStream&
+OtherLongLargeAttributeBase::writeData(TextOutputStream& stream)
+{
+	stream << "...";
+	return stream;
+}
+
+TextOutputStream&
+OtherLongLargeAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+OtherLongLargeAttributeBase::read(BinaryInputStream& stream,Uint32 vl)
+{
+	Assert(&stream == srcstream);
+	stream.seekg(vl,ios::cur);
+	lengthinbytes=vl;
+	return stream;
+}
+
+bool
+OtherLongLargeAttributeBase::getValue(const Uint16 * &,Uint32 &) const
+{
+	Assert(0);
+	return false;
+}
+
+void
+OtherLongLargeAttributeBase::setValue(const Uint16 *,Uint32 )
+{
+	Assert(0);
+}
+
+/* ********************* OF VR Attributes ********************* */
+
+OtherFloatLargeAttributeBase::OtherFloatLargeAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	Assert(srcstream);
+	srcpos=pos;
+	srcendian=srcstream->getEndian();
+	Assert(srcendian != NoEndian);
+	Assert(srcendian != ByteEndian);
+}
+
+OtherFloatLargeAttributeBase::~OtherFloatLargeAttributeBase()
+{
+}
+
+BinaryOutputStream&
+OtherFloatLargeAttributeBase::writeValues(BinaryOutputStream& dststream)
+{
+	// use current dststream endian, not getTransferSyntaxToReadDataSet()->getEndian()
+	Endian dstendian=dststream.getEndian();
+	Assert(dstendian != NoEndian);
+	Assert(dstendian != ByteEndian);
+
+	Assert(getVL()%4 == 0);
+
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		Source<unsigned char> srcinput (*srcstream,1024,getVL());
+		if (dstendian != srcendian) {
+			ConvertSourceToSinkSwapping<unsigned char,unsigned char,4> swab(srcinput);
+			Sink<unsigned char> output(dststream,swab);
+			output.write(getVL());
+		}
+		else {
+			Sink<unsigned char> output(dststream,srcinput);
+			output.write(getVL());
+		}
+	}
+	return dststream;
+}
+
+TextOutputStream&
+OtherFloatLargeAttributeBase::writeData(TextOutputStream& stream)
+{
+	stream << "...";
+	return stream;
+}
+
+TextOutputStream&
+OtherFloatLargeAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+OtherFloatLargeAttributeBase::read(BinaryInputStream& stream,Uint32 vl)
+{
+	Assert(&stream == srcstream);
+	stream.seekg(vl,ios::cur);
+	lengthinbytes=vl;
+	return stream;
+}
+
+bool
+OtherFloatLargeAttributeBase::getValue(const unsigned char * &,Uint32 &) const
+{
+	Assert(0);
+	return false;
+}
+
+void
+OtherFloatLargeAttributeBase::setValue(const unsigned char *,Uint32 )
+{
+	Assert(0);
+}
+
+
+/* ********************* OD VR Attributes ********************* */
+
+OtherDoubleLargeAttributeBase::OtherDoubleLargeAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	Assert(srcstream);
+	srcpos=pos;
+	srcendian=srcstream->getEndian();
+	Assert(srcendian != NoEndian);
+	Assert(srcendian != ByteEndian);
+}
+
+OtherDoubleLargeAttributeBase::~OtherDoubleLargeAttributeBase()
+{
+}
+
+BinaryOutputStream&
+OtherDoubleLargeAttributeBase::writeValues(BinaryOutputStream& dststream)
+{
+	// use current dststream endian, not getTransferSyntaxToReadDataSet()->getEndian()
+	Endian dstendian=dststream.getEndian();
+	Assert(dstendian != NoEndian);
+	Assert(dstendian != ByteEndian);
+
+	Assert(getVL()%8 == 0);
+	
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		Source<unsigned char> srcinput (*srcstream,1024,getVL());
+		if (dstendian != srcendian) {
+			ConvertSourceToSinkSwapping<unsigned char,unsigned char,8> swab(srcinput);
+			Sink<unsigned char> output(dststream,swab);
+			output.write(getVL());
+		}
+		else {
+			Sink<unsigned char> output(dststream,srcinput);
+			output.write(getVL());
+		}
+	}
+	return dststream;
+}
+
+TextOutputStream&
+OtherDoubleLargeAttributeBase::writeData(TextOutputStream& stream)
+{
+	stream << "...";
+	return stream;
+}
+
+TextOutputStream&
+OtherDoubleLargeAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+OtherDoubleLargeAttributeBase::read(BinaryInputStream& stream,Uint32 vl)
+{
+	Assert(&stream == srcstream);
+	stream.seekg(vl,ios::cur);
+	lengthinbytes=vl;
+	return stream;
+}
+
+bool
+OtherDoubleLargeAttributeBase::getValue(const unsigned char * &,Uint32 &) const
+{
+	Assert(0);
+	return false;
+}
+
+void
+OtherDoubleLargeAttributeBase::setValue(const unsigned char *,Uint32 )
+{
+	Assert(0);
+}
+
+/* ********************* Unknown VR Attributes ********************* */
+
+UnknownSmallAttributeBase::UnknownSmallAttributeBase(Tag t)
+	 : OtherNonPixelAttribute(t)
+{
+	data=0;
+}
+
+UnknownSmallAttributeBase:: ~UnknownSmallAttributeBase(void)
+{
+	if (data) delete[] data;
+}
+
+BinaryOutputStream&
+UnknownSmallAttributeBase::writeValues(BinaryOutputStream& stream)
+{
+	if (lengthinbytes) {
+		Assert(data);
+		stream.write((char *)data,size_t(lengthinbytes));
+	}
+	return stream;
+}
+
+TextOutputStream&
+UnknownSmallAttributeBase::writeData(TextOutputStream& stream)
+{
+	Uint32 i = lengthinbytes;
+	unsigned char *ptr = data;
+	while (i > 0) {
+		writeZeroPaddedHexNumber(stream,unsigned(*ptr++),2);
+		--i;
+		if (i > 0) {
+			stream << ",";
+			if (i%16 == 0) stream << "\n\t";
+		}
+	}
+	return stream;
+}
+
+TextOutputStream&
+UnknownSmallAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+UnknownSmallAttributeBase::read(BinaryInputStream& stream,Uint32 length)
+{
+	Assert(lengthinbytes == 0);
+	Assert(data == 0);
+	//Assert(length%2 == 0);	// DICOM likes even things
+	data=new unsigned char[length];
+	Assert(data);
+	if (length) stream.read((char *)data,size_t(length));
+	lengthinbytes=length;
+	return stream;
+}
+
+bool
+UnknownSmallAttributeBase::getValue(const unsigned char * & rvalue,Uint32 &rlength) const
+{
+	rlength=lengthinbytes;
+	rvalue=data;
+	return true;	// ? should this be false if zero length ? :(
+}
+
+void
+UnknownSmallAttributeBase::setValue(const unsigned char *values,Uint32 length)
+{
+	Assert(lengthinbytes == 0);
+	Assert(data == 0);
+	Assert(length%2 == 0);	// DICOM likes even things
+	data=new unsigned char[length];
+	Assert(data);
+	memcpy(data,values,size_t(length));
+	lengthinbytes=length;
+}
+
+void
+UnknownSmallAttributeBase::addValues(const char *values)
+{
+	if (values) {
+		int length=strlen(values);
+		if (length) {
+			Uint32 padcount = (lengthinbytes+length)%2;	// DICOM likes even things
+			Uint32 newlength = lengthinbytes+length+padcount;
+			unsigned char *newdata = new unsigned char[newlength];
+			Assert(newdata);
+			if (lengthinbytes) {
+				memcpy(newdata,data,size_t(lengthinbytes));
+			}
+			memcpy(newdata+lengthinbytes,values,size_t(length));
+			if (padcount) newdata[newlength-1]=0;
+			data=newdata;
+			lengthinbytes=lengthinbytes+length+padcount;
+		}
+	}
+}
+
+UnknownLargeAttributeBase::UnknownLargeAttributeBase(Tag t,
+		BinaryInputStream &stream,OurStreamPos pos)
+	 : OtherNonPixelAttribute(t)
+{
+	srcstream=&stream;
+	srcpos=pos;
+
+	Assert(srcstream);
+}
+
+UnknownLargeAttributeBase::~UnknownLargeAttributeBase()
+{
+}
+
+BinaryOutputStream&
+UnknownLargeAttributeBase::writeValues(BinaryOutputStream& dststream)
+{
+	srcstream->clear();
+	srcstream->seekg(srcpos);
+	if (srcstream->good()) {
+		Source<unsigned char> srcinput    (*srcstream,1024,getVL());
+		Sink<unsigned char>   output      (dststream,srcinput);
+		output.write(getVL());
+	}
+	return dststream;
+}
+
+TextOutputStream&
+UnknownLargeAttributeBase::writeData(TextOutputStream& stream)
+{
+	stream << "...";
+	return stream;
+}
+
+TextOutputStream&
+UnknownLargeAttributeBase::write(TextOutputStream& stream,ElementDictionary *dict,bool verbose,bool showUsedAndIE)
+{
+	Attribute::writeBase(stream,dict,verbose,showUsedAndIE);
+	stream << "[";
+	writeData(stream);
+	stream << "] ";
+	return stream;
+}
+
+BinaryInputStream&
+UnknownLargeAttributeBase::read(BinaryInputStream& stream,Uint32 vl)
+{
+	Assert(&stream == srcstream);
+	stream.seekg(vl,ios::cur);
+	lengthinbytes=vl;
+	return stream;
+}
+
+bool
+UnknownLargeAttributeBase::getValue(const unsigned char * &,Uint32 &) const
+{
+	Assert(0);
+	return false;
+}
+
+void
+UnknownLargeAttributeBase::setValue(const unsigned char *,Uint32 )
+{
+	Assert(0);
+}
+
diff --git a/libsrc/src/dctool/attrtyps.cc b/libsrc/src/dctool/attrtyps.cc
new file mode 100644
index 0000000..4671c9a
--- /dev/null
+++ b/libsrc/src/dctool/attrtyps.cc
@@ -0,0 +1,490 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrtyps.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isspace()
+#else
+#include <ctype.h>	// for isspace()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attr.h"
+#include "listval.h"
+#include "attrtyps.h"
+
+TextOutputStream&
+StringAttribute::writePaddedValues(TextOutputStream& stream,char pad)
+{
+//cerr << "StringAttribute::writePaddedValues" << endl;
+	Uint32 length = 0;
+#ifndef CRAP
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		const char *string=i();
+		Uint32 l = strlen(string);
+		length+=l;
+		if (l) stream << string;
+		++i;
+		if (!i) {
+			stream << "\\";
+			++length;
+		}
+	}
+#else
+	// use as test of getValue()
+	if (getVM()) {
+		int i=0;
+		while (1) {
+			char *string;
+			//bool success=values.getValue(i,string);
+			bool success=getValue(i,string);
+			Assert(success);
+			Assert(string);
+			Uint32 l = strlen(string);
+			length+=l;
+			if (l) stream << string;
+			if (string) delete[] string;
+			++i;
+			if (i<getVM()) {
+				stream << "\\";
+				++length;
+			}
+			else
+				break;
+		}
+	}
+#endif
+	if (length%2 && pad) stream << pad;
+	return stream;
+}
+
+BinaryOutputStream&
+StringAttribute::writePaddedValues(BinaryOutputStream& stream,char pad)
+{
+	ValueListIterator<char *> i(values);
+	Uint32 length = 0;
+	while (!i) {
+		const char *string=i();
+		Uint32 l = strlen(string);
+		length+=l;
+		if (l) stream << string;
+		++i;
+		if (!i) {
+			stream << "\\";
+			++length;
+		}
+	}
+	if (length%2) stream << pad;
+	return stream;
+}
+
+// ********** these methods call addValue() or setValue() ************
+
+BinaryInputStream&
+StringAttribute::read(BinaryInputStream& stream,Uint32 length)
+{
+	Assert(length<0xffffffff);
+	if (length) {
+		char *buffer=new char[length+1];
+		stream.read(buffer,(int)length);
+		buffer[length]=0;
+		bool foundNonNullByte = false;
+		const char *p = buffer + length - 1;
+		while (p >= buffer) {
+			if (*p-- == 0) {
+				if (foundNonNullByte) {
+					embeddedNullByte = true;	// used in attrtypv.cc
+				}
+				else {
+					trailingNullByte = true;	// used in attrtypv.cc
+				}
+			}
+			else {
+				foundNonNullByte = true;
+			}
+		}
+		if (isspace(buffer[length-1])) {
+			trailingSpace = true;
+		}
+		if (stream.good()) addValues(buffer);
+		if (buffer) delete[] buffer;
+	}
+	return stream;
+}
+
+Uint32
+StringAttribute::getVL(void) const
+{
+	ValueListIterator<char *> i(values);
+	Uint32 length = 0;
+	while (!i) {
+		const char *string=i();
+		length+=strlen(string);
+		++i;
+		if (!i) {
+			++length;	// delimiters
+		}
+	}
+	if (length%2) ++length;		// pad to even length
+	return length;
+}
+
+
+bool
+StringAttribute::isEmptyOrHasAnyEmptyValue(void) const
+{
+	if (getVM() == 0) {
+		return true;
+	}
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		const char *string=i();
+		Uint32 thisValueLength=strlen(string);
+		const char *ptr=string;
+		while (thisValueLength > 0 && *ptr++ == ' ') --thisValueLength;
+		if (thisValueLength == 0) {
+			return true;
+		}
+		++i;
+	}
+	return false;
+}
+
+bool
+StringAttribute::isEmptyOrHasAllEmptyValues(void) const
+{
+	if (getVM() == 0) {
+		return true;
+	}
+	bool allEmpty = true;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		const char *string=i();
+		Uint32 thisValueLength=strlen(string);
+		const char *ptr=string;
+		while (thisValueLength > 0 && *ptr++ == ' ') --thisValueLength;
+		if (thisValueLength > 0) {
+			allEmpty = false;
+			break;
+		}
+		++i;
+	}
+	return allEmpty;
+}
+
+bool
+StringAttribute::getValue(unsigned index,Uint16& vp) const
+{
+	char * value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Uint16)atof(value);	// use atof not atol to handle exponential notation
+	return success;
+}
+
+bool
+StringAttribute::getValue(unsigned index,Uint32& vp) const
+{
+	char * value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Uint32)atof(value);	// use atof not atol to handle exponential notation
+	return success;
+}
+
+bool
+StringAttribute::getValue(unsigned index,Int16& vp) const
+{
+	char * value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Int16)atof(value);	// use atof not atol to handle exponential notation
+	return success;
+}
+
+bool
+StringAttribute::getValue(unsigned index,Int32& vp) const
+{
+	char * value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Int32)atof(value);	// use atof not atol to handle exponential notation
+	return success;
+}
+
+bool
+StringAttribute::getValue(unsigned index,Float32& vp) const
+{
+	char * value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Float32)atof(value);
+	return success;
+}
+
+bool
+StringAttribute::getValue(unsigned index,Float64& vp) const
+{
+	char * value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Float64)atof(value);
+	return success;
+}
+
+bool
+StringAttribute::getValue(unsigned index,char * & rvalue) const
+{
+	char *value;
+	bool success=values.getValue(index,value);
+	if (success) {
+//cerr << "StringAttribute::getValue(): got value =<" << value << ">" << endl;
+		rvalue=StrDup(value);
+//cerr << "StringAttribute::getValue(): dup value =<" << rvalue << ">" << endl;
+	}
+	return success;
+}
+
+void
+StringAttribute::setValue(unsigned index,Uint16 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	setValue(index,str);
+}
+
+void
+StringAttribute::setValue(unsigned index,Uint32 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	setValue(index,str);
+}
+
+void
+StringAttribute::setValue(unsigned index,Int16 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	setValue(index,str);
+}
+
+void
+StringAttribute::setValue(unsigned index,Int32 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	setValue(index,str);
+}
+
+void
+StringAttribute::setValue(unsigned index,Float32 value)
+{
+	ostrstream ost;
+	ost	<< resetiosflags(ios::scientific|ios::fixed|ios::uppercase)
+		<< setiosflags(ios::showpoint)
+		<< setprecision(6)
+		<< value << ends;
+	char *str = ost.str();
+	setValue(index,str);
+}
+
+void
+StringAttribute::setValue(unsigned index,Float64 value)
+{
+	ostrstream ost;
+	ost	<< resetiosflags(ios::scientific|ios::fixed|ios::uppercase)
+		<< setiosflags(ios::showpoint)
+		<< setprecision(6)
+		<< setprecision(6)
+		<< value << ends;
+	char *str = ost.str();
+	setValue(index,str);
+}
+
+void
+StringAttribute::addValue(Uint16 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	addValue(str);
+}
+
+void
+StringAttribute::addValue(Uint32 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	addValue(str);
+}
+
+void
+StringAttribute::addValue(Int16 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	addValue(str);
+}
+
+void
+StringAttribute::addValue(Int32 value)
+{
+	ostrstream ost;
+	ost << dec << value << ends;
+	char *str = ost.str();
+	addValue(str);
+}
+
+void
+StringAttribute::addValue(Float32 value)
+{
+	ostrstream ost;
+	ost	<< resetiosflags(ios::scientific|ios::fixed|ios::uppercase)
+		<< setiosflags(ios::showpoint)
+		<< setprecision(6)
+		<< setprecision(6)
+		<< value << ends;
+	char *str = ost.str();
+	addValue(str);
+}
+
+void
+StringAttribute::addValue(Float64 value)
+{
+	ostrstream ost;
+	ost	<< resetiosflags(ios::scientific|ios::fixed|ios::uppercase)
+		<< setiosflags(ios::showpoint)
+		<< setprecision(6)
+		<< setprecision(6)
+		<< value << ends;
+	char *str = ost.str();
+	addValue(str);
+}
+
+void
+StringAttribute::addValues(const char *vptr)
+{
+	Assert(vptr);
+	char *str=StrDup(vptr);
+	char *p=str;
+	while (p) {
+		char *delim=strchr(p,'\\');
+		if (delim) *delim='\0';
+		addValue(StrDup(p));
+		p=delim ? delim+1 : 0;
+	}
+	if (str) delete[] str;
+}
+
+// ********** these methods actually do the insertion ************
+
+// NB. pay attention to spaces in both addValue() and setValue()
+
+// all other methods should use addValue() or setValue() and hence
+// can forget about handling spaces
+
+static const char*
+removeLeadingSpaces(const char *from)
+{
+	if (from) while (*from && isspace(*from)) ++from;
+	return from;
+}
+
+static const char*
+removeTrailingSpaces(char *from)
+{
+	if (from) {
+		unsigned length=strlen(from);
+		const char *last=&from[length-1];
+		while (length && isspace(*last--)) --length;
+		from[length]=0;
+	}
+	return from;
+}
+
+void
+StringAttribute::setValue(unsigned index,const char *value)
+{
+	char *str=StrDup(removeLeadingSpaces(value));
+	removeTrailingSpaces(str);
+	values.setValue(index,str);
+}
+
+void
+StringAttribute::addValue(const char *value)
+{
+	Assert(value);
+	char *str=StrDup(removeLeadingSpaces(value));
+	removeTrailingSpaces(str);
+	values.addValue(str);
+}
+
+// leading (but not trailing) spaces are significant in text
+
+void
+TextAttribute::setValue(unsigned index,const char *value)
+{
+	Assert(value);
+	char *str=StrDup(value);
+	removeTrailingSpaces(str);
+	values.setValue(index,str);
+}
+
+void
+TextAttribute::addValue(const char *value)
+{
+	Assert(value);
+	char *str=StrDup(value);
+	removeTrailingSpaces(str);
+	values.addValue(str);
+}
+
+// Long Text doesn't use backslash delimiter which is a valid character
+// and may never have a VM of more than 1
+
+void
+LongTextAttributeBase::setValue(unsigned index,const char *value)
+{
+	Assert(value);
+	Assert(index == 0);
+	TextAttribute::setValue(index,value);
+}
+
+void
+LongTextAttributeBase::addValue(const char *value)
+{
+	Assert(value);
+	Assert(getVM() == 0);
+	TextAttribute::addValue(value);
+}
+
+void
+LongTextAttributeBase::addValues(const char *vptr)
+{
+	Assert(vptr);
+	addValue(vptr);
+}
+
+// CodeStringFileComponent needs to separate components of path
+// into separate values
+
+void
+CodeStringFileComponentAttributeBase::addValues(const char *vptr)
+{
+	Assert(vptr);
+	char *str=StrDup(vptr);
+	char *p=str;
+	while (p) {
+		char *delim=strchr(p,'\\');		// DOS
+		if (!delim) delim=strchr(p,'/');	// Unix
+		if (!delim) delim=strchr(p,':');	// Mac
+		if (delim) *delim='\0';
+		addValue(StrDup(p));
+		p=delim ? delim+1 : 0;
+	}
+	if (str) delete[] str;
+
+}
+
diff --git a/libsrc/src/dctool/attrtypt.cc b/libsrc/src/dctool/attrtypt.cc
new file mode 100644
index 0000000..7944d63
--- /dev/null
+++ b/libsrc/src/dctool/attrtypt.cc
@@ -0,0 +1,119 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrtypt.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "listval.h"
+#include "attrtypt.h"
+
+BinaryOutputStream&
+TagAttribute::writeValues(BinaryOutputStream& stream)
+{
+	ValueListIterator<Tag> i(values);
+	while (!i) {
+		stream << i();
+		 ++i;
+	}
+	return stream;
+}
+
+TextOutputStream&
+TagAttribute::writeData(TextOutputStream& stream)
+{
+	ValueListIterator<Tag> i(values);
+	while (!i) {
+		stream << "(";
+		writeZeroPaddedHexNumber(stream,i().getGroup(),4);
+		stream << ",";
+		writeZeroPaddedHexNumber(stream,i().getElement(),4);
+		stream << ")";
+		++i;
+		if (!i) stream << ",";
+	}
+	return stream;
+}
+
+BinaryInputStream&
+TagAttribute::read(BinaryInputStream& stream,Uint32 length)
+{
+	Assert(length%4 == 0);
+	while (length && stream.good()) {
+		Uint16 g;
+		Uint16 e;
+		stream >> g;
+		stream >> e;
+		addValue(Tag(g,e));
+		length-=4;
+	}
+	return stream;
+}
+
+bool
+TagAttribute::getValue(unsigned index,Uint32& vp) const
+{
+	Tag value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Uint32)
+		   (((Uint32)value.getGroup()<<16)
+		    |(Uint32)value.getElement());
+	return success;
+}
+
+bool
+TagAttribute::getValue(unsigned index,Int32& vp) const
+{
+	Tag value;
+	bool success=values.getValue(index,value);
+	if (success) vp=(Int32)
+		   (((Uint32)value.getGroup()<<16)
+		    |(Uint32)value.getElement());
+	return success;
+}
+
+bool
+TagAttribute::getValue(unsigned index,Tag& value) const
+{
+	return values.getValue(index,value);
+}
+
+void
+TagAttribute::setValue(unsigned index,Uint32 value)
+{
+	Tag tag((Uint16)((value>>16)&0xffff),
+		(Uint16)(value&0xffff));
+	values.setValue(index,tag);
+}
+
+void
+TagAttribute::setValue(unsigned index,Int32 value)
+{
+	Tag tag((Uint16)((value>>16)&0xffff),
+		(Uint16)(value&0xffff));
+	values.setValue(index,tag);
+}
+
+void
+TagAttribute::setValue(unsigned index,Tag value)
+{
+	values.setValue(index,value);
+}
+
+void
+TagAttribute::addValue(Uint32 value)
+{
+	Tag tag((Uint16)((value>>16)&0xffff),
+		(Uint16)(value&0xffff));
+	values.addValue(tag);
+}
+
+void
+TagAttribute::addValue(Int32 value)
+{
+	Tag tag((Uint16)((value>>16)&0xffff),
+		(Uint16)(value&0xffff));
+	values.addValue(tag);
+}
+
+void
+TagAttribute::addValue(Tag value)
+{
+	values.addValue(value);
+}
+
diff --git a/libsrc/src/dctool/attrtypv.cc b/libsrc/src/dctool/attrtypv.cc
new file mode 100644
index 0000000..e95e6d1
--- /dev/null
+++ b/libsrc/src/dctool/attrtypv.cc
@@ -0,0 +1,1100 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrtypv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>
+#else
+#include <ctype.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attr.h"
+#include "attrtype.h"
+#include "mesgtext.h"
+#include "elmdict.h"
+
+static bool inline iscntrlok(char c) {	// Per PS 3.5 6.1.3
+	return (c == 0x1b /*ESC*/ || c == 0x0a /*LF*/ || c == 0x0c /*FF*/ || c == 0x0d /*CR*/);
+}
+
+static bool inline isescape(char c) {	// Per PS 3.5 6.1.3
+	return (c == 0x1b /*ESC*/);
+}
+
+static void
+writeWarningVRValue(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,int valuenumber,const char *value)
+{
+	log << WMsgDC(ValueDubiousForThisVR) << " - ";
+	tag.write(log,dict);
+	log << " " << (vr ? vr : 0)
+	    << " [" << dec << valuenumber << "]"
+	    << " = <" << (value ? value : "") << "> - ";
+}
+
+static void
+writeErrorBadVR(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr)
+{
+	log << EMsgDC(ValueInvalidForThisVR) << " - ";
+	tag.write(log,dict);
+	log << " " << (vr ? vr : 0)
+	    << " - ";
+}
+
+static void
+writeErrorBadVRValue(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,int valuenumber,const char *value)
+{
+	log << EMsgDC(ValueInvalidForThisVR) << " - ";
+	tag.write(log,dict);
+	log << " " << (vr ? vr : 0)
+	    << " [" << dec << valuenumber << "]"
+	    << " = <" << (value ? value : "") << "> - ";
+}
+
+static void
+writeErrorBadTrailingChar(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,char c)
+{
+	writeErrorBadVR(log,dict,tag,vr);
+	log << MMsgDC(TrailingCharacterInvalidForThisVR)
+	    << " = '";
+	if (isprint(c)) log << c;
+	log << "' (" << hex << (unsigned(c)&0xff) << dec << ")"
+	    << endl;
+}
+
+static void
+writeErrorBadVRCharNL(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,char c)
+{
+	writeErrorBadVR(log,dict,tag,vr);
+	log << MMsgDC(CharacterInvalidForThisVR)
+	    << " = '";
+	if (isprint(c)) log << c;
+	log << "' (" << hex << (unsigned(c)&0xff) << dec << ")"
+	    << endl;
+}
+
+static void
+writeErrorBadVRCharNL(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,int valuenumber,const char *value,
+	char c)
+{
+	writeErrorBadVRValue(log,dict,tag,vr,valuenumber,value);
+	log << MMsgDC(CharacterInvalidForThisVR)
+	    << " = '";
+	if (isprint(c)) log << c;
+	log << "' (" << hex << (unsigned(c)&0xff) << dec << ")"
+	    << endl;
+}
+
+static void
+writeErrorBadCharacterRepertoireCharNL(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,int valuenumber,const char *value,
+	char c)
+{
+	writeErrorBadVRValue(log,dict,tag,vr,valuenumber,value);
+	log << MMsgDC(CharacterInvalidForCharacterRepertoire)
+	    << " = '";
+	if (isprint(c)) log << c;
+	log << "' (" << hex << (unsigned(c)&0xff) << dec << ")"
+	    << endl;
+}
+
+static void
+writeErrorBadVRLengthNL(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,int valuenumber,const char *value,
+	unsigned length,const char *expected)
+{
+	writeErrorBadVRValue(log,dict,tag,vr,valuenumber,value);
+	log << MMsgDC(LengthInvalidForThisVR)
+	    << " = " << dec << length
+	    << ", " << MMsgDC(Expected) << " " << (expected ? expected : "")
+	    << endl;
+}
+
+static void
+writeErrorBadVRRange(TextOutputStream& log,ElementDictionary *dict,Tag tag,const char *vr,int valuenumber,const char *value,
+	const char *expected)
+{
+	writeErrorBadVRValue(log,dict,tag,vr,valuenumber,value);
+	log << MMsgDC(RangeInvalidForThisVR)
+	    << ", " << MMsgDC(Expected) << " " << (expected ? expected : "")
+	    << endl;
+}
+
+bool
+Attribute::validateRetired(TextOutputStream& log,ElementDictionary *dict) const
+{
+	Tag t = getTag();
+	bool retired = dict && dict->isRetired(t);
+	if (retired) {
+		log << WMsgDC(RetiredAttribute) << " - ";
+		tag.write(log,dict);
+		log << endl;
+	}
+	return !retired;
+}
+
+bool
+ApplicationEntityAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 16) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 16");
+			ok=false;
+		}
+		const char *p=s;
+		while (*p) {
+			if (iscntrl(*p) || (isspace(*p) && *p != ' ')) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+AgeStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) != 4) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"== 4");
+			ok=false;
+		}
+		else {
+			int j;
+			for (j=0; j<3; ++j) {
+				if (!isdigit(s[j])) {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,s[j]);
+					ok=false;
+				}
+			}
+			if (s[3] != 'D' && s[3] != 'W' && s[3] != 'M' && s[3] != 'Y') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,s[3]);
+				ok=false;
+			}
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingSpace && getVM()%2 == 1) {	// set during StringAttribute::read(); need to check VM, since if odd number of delimiters need some sort of padding, even if standard doesn't specify it :(
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),' ');
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+CodeStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 16) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 16");
+			ok=false;
+		}
+		const char *p=s;
+		while (*p) {
+			// should check for invalid embedded spaces :(
+			if (!isupper(*p) && !isdigit(*p) && *p != ' ' && *p != '_') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+CodeStringFileComponentAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 8) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 8");
+			ok=false;
+		}
+		const char *p=s;
+		while (*p) {
+			if (!isupper(*p) && !isdigit(*p) && *p != '_') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+
+	// should check for VM <= 8 here :(
+
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+DateStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		int l=strlen(s);
+		if (l == 8 || l == 10) {
+			const char *p=s;
+			if (*p != '1' &&  *p != '2') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (*p == '.' && l == 10) ++p;
+			if (*p != '0' &&  *p != '1') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (*p == '.' && l == 10) ++p;
+			if (*p != '0' &&  *p != '1' &&  *p != '2' &&  *p != '3') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+		}
+		else {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,l,"== 8 or 10");
+			ok=false;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingSpace && getVM()%2 == 1) {	// set during StringAttribute::read(); need to check VM, since if odd number of delimiters need some sort of padding, even if standard doesn't specify it :(
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),' ');
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+DateTimeStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		int l=strlen(s);
+		if (l >= 2 && l <= 26) {
+			const char *p=s;
+			if (*p != '1' &&  *p != '2') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (*p) {	// Not just CC
+				if (!isdigit(*p)) {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+					ok=false;
+				}
+				++p;
+				if (!isdigit(*p)) {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+					ok=false;
+				}
+				++p;
+				if (*p) {	// Not just CCYY
+					if (*p != '0' &&  *p != '1') {
+						writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+						ok=false;
+					}
+					++p;
+					if (!isdigit(*p)) {
+						writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+						ok=false;
+					}
+					++p;
+					if (*p) {	// Not just CCYYMM
+						if (*p != '0' &&  *p != '1' &&  *p != '2' &&  *p != '3') {
+							writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+							ok=false;
+						}
+						++p;
+						if (!isdigit(*p)) {
+							writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+							ok=false;
+						}
+						++p;
+						if (*p) {	// Not just CCYYMMDD
+							if (*p != '0' &&  *p != '1' &&  *p != '2') {
+								writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+								ok=false;
+							}
+							++p;
+							if (!isdigit(*p)) {
+								writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+								ok=false;
+							}
+							++p;
+							if (*p) {	// Not just CCYYMMDDHH
+								if (*p != '0' &&  *p != '1' &&  *p != '2' &&  *p != '3' &&  *p != '4' &&  *p != '5') {
+									writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+									ok=false;
+								}
+								++p;
+								if (!isdigit(*p)) {
+									writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+									ok=false;
+								}
+								++p;
+								if (*p) {	// Not just CCYYMMDDHHMM
+									if (*p != '0' &&  *p != '1' &&  *p != '2' &&  *p != '3' &&  *p != '4' &&  *p != '5') {
+										writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+										ok=false;
+									}
+									++p;
+									if (!isdigit(*p)) {
+										writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+										ok=false;
+									}
+									++p;
+									if (*p) {	// Not just CCYYMMDDHHMMSS
+										if (*p == '.') {	// .FFFFFF
+											while (*++p && isdigit(*p));
+										}
+										if (*p == '+' || *p == '-') {	// + or - ZZZZ
+											while (*++p) {
+												if (!isdigit(*p)) {
+													writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+													ok=false;
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+				while (*p) {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+					ok=false;
+					++p;
+				}
+			}
+		}
+		else {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,l,">= 2 && <= 26");
+			ok=false;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+DecimalStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 16) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 16");
+			ok=false;
+		}
+		const char *p=s;
+		if (*p == '+' ||  *p == '-') ++p;
+		if (isdigit(*p)) while (isdigit(*++p));
+		if (*p == '.') while (isdigit(*++p));
+		if (*p == 'e' || *p == 'E') {
+			++p;
+			if (*p == '+' ||  *p == '-') ++p;
+			if (isdigit(*p)) while (isdigit(*++p));
+		}
+		if (*p){
+			writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+			ok=false;
+		}
+
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+IntegerStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 12) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 12");
+			ok=false;
+		}
+		const char *p=s;
+		if (*p == '+' ||  *p == '-') ++p;
+		if (isdigit(*p)) while (isdigit(*++p));
+		if (*p){
+			writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+			ok=false;
+		}
+
+		// check in range of -(2^31-1) <= n <= (2^31-1)
+		//                   -2147483647        2147483647
+
+		double value = 0.0; 	// :)
+		p=s;
+		while (*p) {
+			if (isdigit(*p)) value=value*10+(toascii(*p)-toascii('0'));
+			++p;
+		}
+
+		// don't need to worry about sign because abs() max is same for both
+
+		if (value > 2147483647) {
+			writeErrorBadVRRange(log,dict,getTag(),getVR(),vn,s,"-(2^31-1) <= n <= (2^31-1)");
+			ok=false;
+		}
+
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+LongStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 64) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 64");
+			ok=false;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		const char *p=s;
+		while (*p) {
+			if ((iscntrl(*p) && !isescape(*p)) || *p == '\\') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+LongTextAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 10240) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 10240");
+			ok=false;
+		}
+		const char *p=s;
+		while (*p) {
+			if (iscntrl(*p) && !iscntrlok(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+PersonNameAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 64) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 64");
+			ok=false;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		int caretsTotal=0;
+		int caretsInGroup=0;
+		int equals=0;
+		const char *p=s;
+		while (*p) {
+			if ((iscntrl(*p) && !isescape(*p)) || *p == '\\' || (isspace(*p) && *p != ' ')) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			else if (*p == '^') {
+				++caretsTotal;
+				++caretsInGroup;
+//log << "Found ^ - incrementing - now equals = " << equals << ", caretsInGroup = " <<  caretsInGroup<< ", caretsTotal = " << caretsTotal << endl;
+			}
+			else if (*p == '=') {
+				if (caretsInGroup > 4) {
+					writeErrorBadVRValue(log,dict,getTag(),getVR(),vn,s);
+					log << MMsgDC(TooManyComponentDelimitersInPersonName) << endl;
+					ok=false;
+				}
+				caretsInGroup=0;
+				++equals;
+//log << "Found = - incrementing - now equals = " << equals << ", caretsInGroup = " <<  caretsInGroup<< ", caretsTotal = " << caretsTotal << endl;
+			}
+			++p;
+		}
+		if (caretsTotal == 0) {
+			writeWarningVRValue(log,dict,getTag(),getVR(),vn,s);
+			log << MMsgDC(RetiredPersonNameForm) << endl;
+		}
+		else if (caretsInGroup > 4) {
+			writeErrorBadVRValue(log,dict,getTag(),getVR(),vn,s);
+			log << MMsgDC(TooManyComponentDelimitersInPersonName) << endl;
+			ok=false;
+		}
+		if (equals > 2) {
+			log << MMsgDC(TooManyComponentGroupDelimitersInPersonName) << endl;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+ShortStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 16) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 16");
+			ok=false;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		const char *p=s;
+		while (*p) {
+			if ((iscntrl(*p) && !isescape(*p)) || *p == '\\') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+ShortTextAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (strlen(s) > 1024) {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 1024");
+			ok=false;
+		}
+		const char *p=s;
+		while (*p) {
+			if (iscntrl(*p) && !iscntrlok(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+TimeStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		int l=strlen(s);
+		if (l >= 2 && l <= 16) {
+			const char *p=s;
+			if (*p != '0' &&  *p != '1' &&  *p != '2') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (!isdigit(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+			if (*p) {	// Not just HH
+				if (*p == ':') ++p;
+				if (*p != '0' &&  *p != '1' &&  *p != '2' &&  *p != '3' &&  *p != '4' &&  *p != '5') {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+					ok=false;
+				}
+				++p;
+				if (!isdigit(*p)) {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+					ok=false;
+				}
+				++p;
+				if (*p) {	// Not just HHMM
+					if (*p == ':') ++p;
+					if (*p != '0' &&  *p != '1' &&  *p != '2' &&  *p != '3' &&  *p != '4' &&  *p != '5') {
+						writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+						ok=false;
+					}
+					++p;
+					if (!isdigit(*p)) {
+						writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+						ok=false;
+					}
+					++p;
+					if (*p == '.') {	// .FFFFFF
+						while (*++p) {
+							if (!isdigit(*p)) {
+								writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+								ok=false;
+							}
+						}
+					}
+					while (*p) {
+						writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+						ok=false;
+						++p;
+					}
+				}
+			}
+		}
+		else {
+			writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,l,">= 2 && <= 16");
+			ok=false;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+UIStringAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		int length = strlen(s);
+		if (length > 0) {
+			if (length > 64) {
+				writeErrorBadVRLengthNL(log,dict,getTag(),getVR(),vn,s,strlen(s),"<= 64");
+				ok=false;
+			}
+			const char *p=s;
+			int componentlength=0;
+			int countleadingzeroes=0;
+			bool foundnonzerodigitsincomponent=false;
+			bool nothingbutzeroesinallcomponents=true;
+			while (*p) {
+				if (!isdigit(*p) && *p != '.') {
+					writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+					ok=false;
+				}
+
+				if (*p == '0') {
+					if (!foundnonzerodigitsincomponent) ++countleadingzeroes;
+				}
+				else {
+					if (isdigit(*p)) {
+						foundnonzerodigitsincomponent=true;
+					}
+					if (*p != '.') {
+						nothingbutzeroesinallcomponents=false;
+					}
+				}
+
+				componentlength = (*p == '.') ? 0 : (componentlength+1);
+
+				++p;
+
+				if (!*p || *p == '.') {
+					if (componentlength == 0) {
+						writeErrorBadVRValue(log,dict,getTag(),getVR(),vn,s);
+						log << MMsgDC(EmptyComponent)
+						    << endl;
+						ok=false;
+					}
+					else if ((foundnonzerodigitsincomponent && countleadingzeroes > 0) || (!foundnonzerodigitsincomponent && countleadingzeroes > 1)) {
+						writeErrorBadVRValue(log,dict,getTag(),getVR(),vn,s);
+						log << MMsgDC(LeadingZeroes)
+						    << endl;
+						ok=false;
+					}
+					countleadingzeroes=0; foundnonzerodigitsincomponent=false;
+				}
+			}
+			if (nothingbutzeroesinallcomponents) {
+				writeErrorBadVRValue(log,dict,getTag(),getVR(),vn,s);
+				log << MMsgDC(NothingButZeroComponents)
+				    << endl;
+				ok=false;
+			}
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	// null is OK as trailing character, but trailing space is not
+	if (trailingSpace) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),' ');
+		ok=false;
+	}
+	return ok;
+}
+
+
+bool
+UniversalResourceAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		const char *p=s;
+		while (*p) {
+			// pct-encoded = "%" HEXDIG HEXDIG
+			// reserved    = gen-delims / sub-delims
+			// gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+			// sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
+			// unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
+			if (!isalnum(*p)
+			 && *p != ':' && *p != '/' && *p != '?' && *p != '#' && *p != '[' && *p != ']' && *p != '@'
+			 && *p != '!' && *p != '$' && *p != '&' && *p != '\'' && *p != '(' && *p != ')' && *p != '*' && *p != '+' && *p != ',' && *p != ';' && *p != '='
+			 && *p != '-' && *p != '.' && *p != '_' && *p != '~' && *p != '%') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+bool
+UnlimitedCharactersAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		const char *p=s;
+		while (*p) {
+			if ((iscntrl(*p) && !isescape(*p)) || *p == '\\') {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
+
+bool
+UnlimitedTextAttribute::validateVR(TextOutputStream& log,SpecificCharacterSetInfo *specificCharacterSetInfo,ElementDictionary *dict) const
+{
+	bool ok=true;
+	int vn=0;
+	ValueListIterator<char *> i(values);
+	while (!i) {
+		char *s=i();
+		const char *p=s;
+		while (*p) {
+			if (iscntrl(*p) && !iscntrlok(*p)) {
+				writeErrorBadVRCharNL(log,dict,getTag(),getVR(),vn,s,*p);
+				ok=false;
+			}
+			++p;
+		}
+		if (specificCharacterSetInfo) {
+			int badCharacterPosition;
+			if (!specificCharacterSetInfo->isValidString(s,badCharacterPosition)) {
+				Assert(badCharacterPosition >= 0);
+				writeErrorBadCharacterRepertoireCharNL(log,dict,getTag(),getVR(),vn,s,*(s+badCharacterPosition));
+				ok=false;
+			}
+		}
+		++vn; ++i;
+		//if (s) delete[] s;
+	}
+	if (embeddedNullByte) {		// set during StringAttribute::read()
+		writeErrorBadVRCharNL(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	if (trailingNullByte) {		// set during StringAttribute::read()
+		writeErrorBadTrailingChar(log,dict,getTag(),getVR(),0);
+		ok=false;
+	}
+	return ok;
+}
+
diff --git a/libsrc/src/dctool/attrvrfy.cc b/libsrc/src/dctool/attrvrfy.cc
new file mode 100644
index 0000000..3d11b2f
--- /dev/null
+++ b/libsrc/src/dctool/attrvrfy.cc
@@ -0,0 +1,464 @@
+static const char *CopyrightIdentifier(void) { return "@(#)attrvrfy.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "mesgtext.h"
+#include "elmdict.h"
+#include "elmtype.h"
+
+bool
+Attribute::verifyDefinedTerms(char *(*method)(char *value),
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	int which) const
+{
+	Assert(dict);
+	bool success=true;
+	if (isString()) {
+		unsigned vm=getVM();
+		unsigned start = (which == -1) ? 0 : which;
+		unsigned end = (which == -1) ? vm : (which+1);
+		unsigned i;
+		for (i=start; i < end; ++i) {
+			char *value;
+			if (getValue(i,value)) {
+				char *desc;
+				if (value && (desc=(*method)(value))) {
+					if (verbose) {
+						log << MMsgDC(RecognizedDefinedTerm)
+						    << " <" << value << "> " << MMsgDC(Is) << " <" << desc
+						    << "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+						    << " " << MMsgDC(OfAttribute) << " <"
+						    << (dict ? dict->getDescription(getTag()) : "")
+							<< ">" << endl;
+					}
+					delete desc;
+				}
+				else {
+					log << WMsgDC(UnrecognizedDefinedTerm)
+					    << " <" << (value ? value : "")
+					    << "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+					    << " " << MMsgDC(OfAttribute) << " <"
+					    << (dict ? dict->getDescription(getTag()) : "")
+						<< ">" << endl;
+					// does NOT cause failure (cf. EnumValues)
+				}
+				delete value;
+			}
+			else {
+//cerr << "Attribute::verifyDefinedTerms: couldn't get value=" << dec << i << endl;
+				// couldn't get a value - not a failure (eg. may be type 2 or 3)
+			}
+		}
+	}
+	else {
+		log << EMsgDC(TriedToVerifyDefinedTermsForNonStringAttribute) << " "
+		    << MMsgDC(ForAttribute) << " <"
+		    << (dict ? dict->getDescription(getTag()) : "")
+		    << ">" << endl;
+		success=false;
+	}
+//cerr << "Attribute::verifyDefinedTerms: return " << (success ? "T" : "F") << endl;
+	return success;
+}
+
+bool
+Attribute::verifyEnumValues(char *(*method)(char *value),
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	int which) const
+{
+//cerr << "Attribute::verifyEnumValues: which=" << dec << which << endl;
+	Assert(dict);
+	bool success=true;
+	if (isString()) {
+		unsigned vm=getVM();
+//cerr << "Attribute::verifyEnumValues: vm=" << dec << vm << endl;
+		unsigned start = (which == -1) ? 0 : which;
+		unsigned end = (which == -1) ? vm : (which+1);
+//cerr << "Attribute::verifyEnumValues: start=" << dec << start << endl;
+//cerr << "Attribute::verifyEnumValues: end=" << dec << end << endl;
+		unsigned i;
+		for (i=start; i < end; ++i) {
+//cerr << "Attribute::verifyEnumValues: doing=" << dec << i << endl;
+			char *value;
+			if (getValue(i,value)) {
+				char *desc;
+//if (value) cerr << "Attribute::verifyEnumValues: value=" << value << endl;
+				if (value && (desc=(*method)(value))) {
+					if (verbose) {
+						log << MMsgDC(RecognizedEnumeratedValue)
+						    << " <" << value << "> " << MMsgDC(Is) << " <" << desc
+							<< "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+						    << " " << MMsgDC(OfAttribute) << " <"
+						    << ">" << (dict ? dict->getDescription(getTag()) : "")
+							<< endl;
+					}
+					delete desc;
+				}
+				else {
+					log << EMsgDC(UnrecognizedEnumeratedValue)
+					    << " <" << (value ? value : "")
+					    << "> " << MMsgDC(ForValue) << " " << dec << (i+1)
+					    << " " << MMsgDC(OfAttribute) << " <"
+					    << (dict ? dict->getDescription(getTag()) : "")
+						<< ">" << endl;
+					success=false;
+				}
+				delete value;
+			}
+			else {
+//cerr << "Attribute::verifyEnumValues: couldn't get value=" << dec << i << endl;
+				// couldn't get a value - not a failure (eg. may be type 2 or 3)
+			}
+		}
+	}
+	else {
+		log << EMsgDC(TriedToVerifyEnumeratedValueForNonStringAttribute) << " "
+		    << MMsgDC(ForAttribute) << " <"
+		    << (dict ? dict->getDescription(getTag()) : "")
+		    << ">" << endl;
+		success=false;
+	}
+//cerr << "Attribute::verifyEnumValues: return " << (success ? "T" : "F") << endl;
+	return success;
+}
+
+bool
+Attribute::verifyEnumValues(char *(*method)(Uint16 value),
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	int which) const
+{
+//cerr << "Attribute::verifyEnumValues: which=" << dec << which << endl;
+	Assert(dict);
+	bool success=true;
+	if (isNumeric()) {
+		unsigned vm=getVM();
+//cerr << "Attribute::verifyEnumValues: vm=" << dec << vm << endl;
+		unsigned start = (which == -1) ? 0 : which;
+		unsigned end = (which == -1) ? vm : (which+1);
+//cerr << "Attribute::verifyEnumValues: start=" << dec << start << endl;
+//cerr << "Attribute::verifyEnumValues: end=" << dec << end << endl;
+		unsigned i;
+		for (i=start; i < end; ++i) {
+//cerr << "Attribute::verifyEnumValues: doing=" << dec << i << endl;
+			Uint16 value;
+			if (getValue(i,value)) {
+//cerr << "Attribute::verifyEnumValues: value=" << hex << value << dec << endl;
+				char *desc=(*method)(value);
+				if (desc) {
+					if (verbose) {
+						log << MMsgDC(RecognizedEnumeratedValue)
+						    << " <" << hex << value << dec << "> " << MMsgDC(Is) << " <" << desc
+						    << "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+							<< " " << MMsgDC(OfAttribute) << " <"
+						    << (dict ? dict->getDescription(getTag()) : "")
+							<< ">" << endl;
+					}
+					delete desc;
+				}
+				else {
+					log << EMsgDC(UnrecognizedEnumeratedValue)
+					    << " <" << hex << value << dec
+					    << "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+					    << " " << MMsgDC(OfAttribute) << " <"
+					    << (dict ? dict->getDescription(getTag()) : "")
+						<< ">" << endl;
+					success=false;
+				}
+			}
+			else {
+//cerr << "Attribute::verifyEnumValues: couldn't get value=" << dec << i << endl;
+				// couldn't get a value - not a failure (eg. may be type 2 or 3)
+			}
+		}
+	}
+	else {
+		log << EMsgDC(TriedToVerifyEnumeratedValueForNonNumericAttribute) << " "
+		    << MMsgDC(ForAttribute) << " <"
+		    << (dict ? dict->getDescription(getTag()) : "")
+		    << ">" << endl;
+		success=false;
+	}
+//cerr << "Attribute::verifyEnumValues: return " << (success ? "T" : "F") << endl;
+	return success;
+}
+
+bool
+Attribute::verifyBitMap(char *(*method)(Uint16 value),
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	int which) const
+{
+	Assert(dict);
+	bool success=true;
+	if (isNumeric()) {
+		unsigned vm=getVM();
+		unsigned start = (which == -1) ? 0 : which;
+		unsigned end = (which == -1) ? vm : (which+1);
+		unsigned i;
+		for (i=start; i < end; ++i) {
+			Uint16 value;
+			if (getValue(i,value)) {
+				char *desc=(*method)(value);
+				if (desc) {
+					if (verbose) {
+						log << MMsgDC(RecognizedBitMap)
+						    << " <" << hex << value << dec << "> " << MMsgDC(Is) << " <" << desc
+							<< "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+						    << " " << MMsgDC(OfAttribute) << " <"
+						    << (dict ? dict->getDescription(getTag()) : "")
+						    << ">" << endl;
+					}
+					delete desc;
+				}
+				else {
+					log << EMsgDC(UnrecognizedBitMap)
+					    << " <" << hex << value << dec
+						<< "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+					    << " " << MMsgDC(OfAttribute) << " <"
+					    << (dict ? dict->getDescription(getTag()) : "")
+					    << ">" << endl;
+					success=false;
+				}
+			}
+			else {
+//cerr << "Attribute::verifyBitMap: couldn't get value=" << dec << i << endl;
+				// couldn't get a value - not a failure (eg. may be type 2 or 3)
+			}
+		}
+	}
+	else {
+		log << EMsgDC(TriedToVerifyBitMapForNonNumericAttribute) << " "
+		    << MMsgDC(ForAttribute) << " <"
+		    << (dict ? dict->getDescription(getTag()) : "")
+		    << ">" << endl;
+		success=false;
+	}
+//cerr << "Attribute::verifyBitMap: return " << (success ? "T" : "F") << endl;
+	return success;
+
+}
+
+bool
+Attribute::verifyEnumValues(char *(*method)(Uint16 group,Uint16 element),
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	int which) const
+{
+//cerr << "Attribute::verifyEnumValues: which=" << dec << which << endl;
+	Assert(dict);
+	bool success=true;
+	if (isTag()) {
+		unsigned vm=getVM();
+//cerr << "Attribute::verifyEnumValues: vm=" << dec << vm << endl;
+		unsigned start = (which == -1) ? 0 : which;
+		unsigned end = (which == -1) ? vm : (which+1);
+//cerr << "Attribute::verifyEnumValues: start=" << dec << start << endl;
+//cerr << "Attribute::verifyEnumValues: end=" << dec << end << endl;
+		unsigned i;
+		for (i=start; i < end; ++i) {
+//cerr << "Attribute::verifyEnumValues: doing=" << dec << i << endl;
+			Tag value;
+			if (getValue(i,value)) {
+				Uint16 group=value.getGroup();
+				Uint16 element=value.getElement();
+//cerr << "Attribute::verifyEnumValues: value=(" << hex << group << "," << element << ")" << dec << endl;
+				char *desc=(*method)(group,element);
+				if (desc) {
+					if (verbose) {
+						log << MMsgDC(RecognizedEnumeratedValue)
+						    << " (" << hex << group << "," << element << ") " << dec << MMsgDC(Is) << " <" << desc
+							<< "> " << MMsgDC(ForValue) << " "  << dec << (i+1)
+						    << " " << MMsgDC(OfAttribute) << " <"
+						    << (dict ? dict->getDescription(getTag()) : "")
+						    << ">" << endl;
+					}
+					delete desc;
+				}
+				else {
+					log << EMsgDC(UnrecognizedEnumeratedValue)
+					    << " (" << hex << group << "," << element << ") " << dec
+						<< MMsgDC(ForValue) << " "  << dec << (i+1)
+					    << " " << MMsgDC(OfAttribute) << " <"
+					    << (dict ? dict->getDescription(getTag()) : "")
+					    << ">" << endl;
+					success=false;
+				}
+			}
+			else {
+//cerr << "Attribute::verifyEnumValues: couldn't get value=" << dec << i << endl;
+				// couldn't get a value - not a failure (eg. may be type 2 or 3)
+			}
+		}
+	}
+	else {
+		log << EMsgDC(TriedToVerifyEnumeratedValueForNonTagAttribute) << " "
+		    << MMsgDC(ForAttribute) << " <"
+		    << (dict ? dict->getDescription(getTag()) : "")
+		    << ">" << endl;
+		success=false;
+	}
+//cerr << "Attribute::verifyEnumValues: return " << (success ? "T" : "F") << endl;
+	return success;
+}
+
+bool
+Attribute::verifyNotZero(
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	int which,
+	bool warningNotError) const
+{
+//cerr << "Attribute::verifyNotZero: which=" << dec << which << endl;
+	Assert(dict);
+	bool success=true;
+	if (isNumeric()) {
+		unsigned vm=getVM();
+//cerr << "Attribute::verifyNotZero: vm=" << dec << vm << endl;
+		unsigned start = (which == -1) ? 0 : which;
+		unsigned end = (which == -1) ? vm : (which+1);
+//cerr << "Attribute::verifyNotZero: start=" << dec << start << endl;
+//cerr << "Attribute::verifyNotZero: end=" << dec << end << endl;
+		unsigned i;
+		for (i=start; i < end; ++i) {
+//cerr << "Attribute::verifyNotZero: doing=" << dec << i << endl;
+			Float64 value;
+			if (getValue(i,value)) {
+//cerr << "Attribute::verifyNotZero: value=" << dec << value << endl;
+				if (value == 0) {
+					log << (warningNotError ? WMsgDC(ZeroValue) : EMsgDC(ZeroValue))
+						<< " " << MMsgDC(ForValue) << " "  << dec << (i+1)
+					    << " " << MMsgDC(OfAttribute) << " <"
+					    << (dict ? dict->getDescription(getTag()) : "")
+					    << ">" << endl;
+					success=false;
+				}
+			}
+			else {
+//cerr << "Attribute::verifyNotZero: couldn't get value=" << dec << i << endl;
+				// couldn't get a value - not a failure (eg. may be type 2 or 3)
+			}
+		}
+	}
+	else {
+		log << EMsgDC(TriedToVerifyNotZeroForNonNumericAttribute) << " "
+		    << MMsgDC(ForAttribute) << " <"
+		    << (dict ? dict->getDescription(getTag()) : "")
+		    << ">" << endl;
+		success=false;
+	}
+//cerr << "Attribute::verifyNotZero: return " << ((warningNotError || success) ? "T" : "F") << endl;
+	return warningNotError || success;
+}
+
+bool
+Attribute::verifyVR(const char *module,const char *element,
+	TextOutputStream& log,
+	ElementDictionary *dict) const
+{
+	Assert(dict);
+	Tag tag=getTag();
+	
+	if (tag.isPrivateTag()) {
+		// Since we do not have the owner context at this point, we cannot look it up in the p[rivate dictionary
+		// so just skip the test ... will only impact IODs that use private attributes, e.g., private IODs
+		return true;
+	}
+	const char *vrd=dict->getValueRepresentation(tag);
+	const char *vre=getVR();
+
+	if (!vrd) {
+		log << EMsgDC(NoSuchElementInDictionary) << " ";
+		if (element) log << MMsgDC(Element) << "=<" << element << ">";
+		if (module)  log << MMsgDC(Module)  << "=<" << module  << ">";
+		log << endl;
+		return false;
+	}
+	else {
+		if (strncmp(vre,vrd,2) != 0
+		    && !( strncmp(vrd,"OX",2) == 0
+		          && (strncmp(vre,"OB",2) == 0
+		              || strncmp(vre,"OW",2) == 0)
+		        )
+		    && !( strncmp(vrd,"XS",2) == 0
+		          && (strncmp(vre,"US",2) == 0
+		              || strncmp(vre,"SS",2) == 0)
+		        )
+		    && !( strncmp(vrd,"XO",2) == 0
+		          && (strncmp(vre,"US",2) == 0
+		              || strncmp(vre,"SS",2) == 0
+		              || strncmp(vre,"OW",2) == 0)
+		        )
+		    && !( strncmp(vrd,"XL",2) == 0
+		          && (strncmp(vre,"UL",2) == 0
+		              || strncmp(vre,"SL",2) == 0)
+		        )
+		    ) {
+			log << EMsgDC(BadValueRepresentation)
+			    << " " << vre << " (" << vrd
+			    << " " << MMsgDC(Required) << ")";
+			if (element) log << " " << MMsgDC(Element) << "=<" << element << ">";
+			if (module)  log << " " << MMsgDC(Module)  << "=<" << module  << ">";
+			log << endl;
+			return false;
+		}
+		else {
+			return true;
+		}
+	}
+}
+
+bool
+Attribute::verifyVM(const char *module,const char *element,
+	TextOutputStream& log,
+	ElementDictionary *dict,
+	Uint16 multiplicityMin,Uint16 multiplicityMax,const char *specifiedSource) const
+{
+	Assert(dict);
+	Tag tag=getTag();
+	Uint16 vm=getVM();
+//log << "Attribute::verifyVM(): getVM() = " << vm << endl;
+	Uint16 dictmin=dict->getValueMultiplicityMinimum(tag);
+	Uint16 dictmax=dict->getValueMultiplicityMaximum(tag);
+	Uint16 errmin,errmax;
+	int err=0;
+	const char *source;
+	Assert(VMNONE == 0);
+//log << "Attribute::verifyVM(): multiplicityMin = " << multiplicityMin << " multiplicityMax = " << multiplicityMax << endl;
+	if (multiplicityMin == 0 && multiplicityMax == 0) {	// ie. don't override dictionary
+		if (vm < dictmin || vm >dictmax) {
+			err=1;
+			errmin=dictmin;
+			errmax=dictmax;
+			source=MMsgDC(Dictionary);
+		}
+	}
+	else {
+//log << "Attribute::verifyVM(): checking using multiplicityMin and multiplicityMax" << endl;
+		if (vm < multiplicityMin || vm >multiplicityMax) {
+//log << "Attribute::verifyVM(): error" << endl;
+			err=1;
+			errmin=multiplicityMin;
+			errmax=multiplicityMax;
+			source= specifiedSource ? specifiedSource : MMsgDC(ModuleDefinition);
+		}
+	}
+	if (err) {
+		log << EMsgDC(BadAttributeValueMultiplicity)
+		    <<  " " << dec << vm << " (" << errmin;
+		if (errmin != errmax)
+			if (errmax == VMUNLIMITED)
+				log << "-n";
+			else
+				log << "-" << errmax;
+		log << " " << MMsgDC(RequiredBy) << " " << source << ")";
+		if (element) log << " " << MMsgDC(Element) << "=<" << element << ">";
+		if (module)  log << " " << MMsgDC(Module)  << "=<" << module  << ">";
+		log << endl;
+		return false;
+	}
+	else {
+		return true;
+	}
+}
+
diff --git a/libsrc/src/dctool/binval.cc b/libsrc/src/dctool/binval.cc
new file mode 100644
index 0000000..b09d500
--- /dev/null
+++ b/libsrc/src/dctool/binval.cc
@@ -0,0 +1,14 @@
+static const char *CopyrightIdentifier(void) { return "@(#)binval.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iomanip>
+#else
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "binvalc.h"
+#include "binvald.h"
diff --git a/libsrc/src/dctool/charset.cc b/libsrc/src/dctool/charset.cc
new file mode 100644
index 0000000..3aa64bf
--- /dev/null
+++ b/libsrc/src/dctool/charset.cc
@@ -0,0 +1,135 @@
+static const char *CopyrightIdentifier(void) { return "@(#)charset.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include <string.h>
+
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>	// for debugging
+#include <iomanip>	// for debugging
+#else
+#include <iostream.h>	// for debugging
+#include <iomanip.h>	// for debugging
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;	// for debugging
+#endif
+
+#include "charset.h"
+#include "attr.h"
+
+SpecificCharacterSetInfo::SpecificCharacterSetInfo(void) {
+	setSpecificCharacterSet();
+}
+
+SpecificCharacterSetInfo::SpecificCharacterSetInfo(int nCharSetValues,char** charSetValues) {
+	setSpecificCharacterSet(nCharSetValues,charSetValues);
+}
+
+SpecificCharacterSetInfo::SpecificCharacterSetInfo(Attribute *aSpecificCharacterSet) {
+	if (!aSpecificCharacterSet || aSpecificCharacterSet->getVL() == 0) {
+		setSpecificCharacterSet();
+	}
+	else {
+		int nCharSetValues =  aSpecificCharacterSet->getVM();
+		Assert(nCharSetValues > 0);
+		char **charSetValues = new char *[nCharSetValues];
+		for (int i=0; i<nCharSetValues; ++i) {
+			aSpecificCharacterSet->getValue(i,charSetValues[i]);
+		}
+		setSpecificCharacterSet(nCharSetValues,charSetValues);
+	}
+}
+
+SpecificCharacterSetInfo::~SpecificCharacterSetInfo() {
+}
+
+void
+SpecificCharacterSetInfo::setSpecificCharacterSet(void) {
+	flag7BitSingleByte = true;		// default character repertoire
+	flag8BitSingleByte = false;
+	flagISO2022 = false;
+	flagUTF8 = false;
+}
+
+void
+SpecificCharacterSetInfo::setSpecificCharacterSet(int nCharSetValues,char** charSetValues) {
+	flag7BitSingleByte = true;
+	flag8BitSingleByte = false;
+	flagISO2022 = false;
+	flagUTF8 = false;
+	if (nCharSetValues > 0 && charSetValues) {
+		if (nCharSetValues == 1) {
+			const char *value = charSetValues[0];
+			if (value) {
+				if (strcmp(value,"ISO_IR 100") == 0
+				 || strcmp(value,"ISO_IR 101") == 0
+				 || strcmp(value,"ISO_IR 109") == 0
+				 || strcmp(value,"ISO_IR 110") == 0
+				 || strcmp(value,"ISO_IR 144") == 0
+				 || strcmp(value,"ISO_IR 127") == 0
+				 || strcmp(value,"ISO_IR 126") == 0
+				 || strcmp(value,"ISO_IR 138") == 0
+				 || strcmp(value,"ISO_IR 148") == 0
+				 || strcmp(value,"ISO_IR 166") == 0
+				) {
+//cerr << "SpecificCharacterSetInfo::setSpecificCharacterSet(): found single byte ISO" << endl;
+					flag7BitSingleByte = false;
+					flag8BitSingleByte = true;
+				}
+				else if (strcmp(value,"ISO_IR 192") == 0 || strcmp(value,"GB18030") == 0
+				) {
+//cerr << "SpecificCharacterSetInfo::setSpecificCharacterSet(): found ISO_IR 192" << endl;
+					flag7BitSingleByte = false;
+					flagUTF8 = true;
+				}
+			}
+		}
+		else {
+			flag7BitSingleByte = false;
+			flagISO2022 = true;
+		}
+	}
+//cerr << "SpecificCharacterSetInfo::setSpecificCharacterSet(): flag7BitSingleByte = " << flag7BitSingleByte << endl;
+//cerr << "SpecificCharacterSetInfo::setSpecificCharacterSet(): flag8BitSingleByte = " << flag8BitSingleByte << endl;
+//cerr << "SpecificCharacterSetInfo::setSpecificCharacterSet(): flagISO2022 = " << flagISO2022 << endl;
+//cerr << "SpecificCharacterSetInfo::setSpecificCharacterSet(): flagUTF8 = " << flagUTF8 << endl;
+}
+
+bool
+SpecificCharacterSetInfo::isValidString(const char *s,int& badCharacterPosition) const {
+//cerr << "SpecificCharacterSetInfo::isValidString(): checking string = <" << s << ">" << endl;
+	bool success = true;
+	const char *p=s;
+	while (*p) {
+		unsigned char c = unsigned(*p)&0xff;
+		if (flag7BitSingleByte) {
+			if ((c&0x80) != 0) {
+//cerr << "SpecificCharacterSetInfo::isValidString(): flag7BitSingleByte - character has high bit set '" << c << "' (" << hex << c << dec << ")" << endl;
+				success = false;
+				break;
+			}
+		}
+		else if (flag8BitSingleByte || flagISO2022) {
+			// CL	bytes from 00/00 to 01/15
+			// GL	bytes from 02/00 to 07/15
+			// CR	bytes from 08/00 to 09/15 ... never used
+			// GR	bytes from 10/00 to 15/15
+			if (c >= 0x80 && c <= 0x9F) {
+//cerr << "SpecificCharacterSetInfo::isValidString(): flag8BitSingleByte || flagISO2022 - illegal CR control character '" << c << "' (" << hex << c << dec << ")" << endl;
+				success = false;
+				break;
+			}
+		}
+		// else if UTF8 assume anything is OK
+		++p;
+	}
+	if (success) {
+		badCharacterPosition = -1;
+	}
+	else {
+		badCharacterPosition = p-s;
+	}
+//cerr << "SpecificCharacterSetInfo::isValidString(): returning " << success << endl;
+	return success;
+}
+
+
diff --git a/libsrc/src/dctool/condn.cc b/libsrc/src/dctool/condn.cc
new file mode 100644
index 0000000..cec29db
--- /dev/null
+++ b/libsrc/src/dctool/condn.cc
@@ -0,0 +1,401 @@
+static const char *CopyrightIdentifier(void) { return "@(#)condn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrseq.h"
+#include "attrlist.h"
+#include "elmconst.h"
+#include "sopclu.h"
+
+#include "condnc.h"
+
+static bool ElementPresent(AttributeList *list,Tag tag)
+{
+	Assert(list);
+	return (*list)[tag] != 0;
+}
+
+static bool ElementPresentMasked(AttributeList *list,Tag tag,Uint16 mask)
+{
+	Uint16 g = tag.getGroup() & mask;
+	Uint16 e = tag.getElement();
+	Assert(list);
+	AttributeListIterator li(*list);
+	while (!li) {
+		Tag t = li()->getTag();
+		if (!t.isPrivateGroup() && (t.getGroup() & mask) == g && t.getElement() == e) return true;
+		li++;
+	}
+	return false;
+}
+
+static bool ElementPresentAbove(AttributeList *parentlist,Tag tag)
+{
+//cerr << "ElementPresentAbove: returns " << (((*parentlist)[tag] != 0) ? "true" : "false") << endl;
+	return (*parentlist)[tag] != 0;
+}
+
+static bool ElementPresentWithin(AttributeList *list,Tag tag,Tag sequencetag)
+{
+//cerr << "ElementPresentWithin:" << endl;
+	bool present=false;
+	Assert(list);
+	Attribute *a=(*list)[sequencetag];
+	if (a && a->isSequence()) {
+//cerr << "ElementPresentWithin: found sequence" << endl;
+		SequenceAttribute *aseq=(SequenceAttribute *)a;
+		Assert(aseq);
+		AttributeList **array;
+		int n;
+		if ((n=aseq->getLists(&array)) > 0) {
+//cerr << "ElementPresentWithin: found items" << endl;
+			int i; for (i=0; i<n; ++i) {
+//cerr << "ElementPresentWithin: item " << dec << i << endl;
+				AttributeList *list=array[i];
+				if ((*list)[tag]) {
+//cerr << "ElementPresentWithin: tag present" << endl;
+					present=true;
+					break;
+				}
+			}
+		}
+	}
+
+	return present;
+}
+
+static bool ElementPresentInPath(AttributeList *list,Tag tag)
+{
+//cerr << "ElementPresentInPath:" << endl;
+//cerr << "ElementPresentInPath: tag " << hex << tag.getGroup() << "," << tag.getElement() << dec << endl;
+	if ((*list)[tag]) {
+//cerr << "ElementPresentInPath: tag present" << endl;
+		return true;
+	}
+	else {
+		AttributeListIterator listi(*list);
+		while (!listi) {
+			Attribute *a=listi();
+			if (a->isSequence()) {
+				SequenceAttribute *aseq=(SequenceAttribute *)a;
+				Assert(aseq);
+				AttributeList **array;
+				int n;
+				if ((n=aseq->getLists(&array)) > 0) {
+//cerr << "ElementPresentInPath: found " << n << " items" << endl;
+					int i;
+					for (i=0; i<n; ++i) {
+//cerr << "ElementPresentInPath: item " << dec << i << endl;
+						AttributeList *list=array[i];
+						if (ElementPresentInPath(list,tag)) {	// recurses if necessary
+//cerr << "ElementPresentInPath: back from ElementPresentInPath having found tag" << endl;
+							delete [] array;
+							return true;	
+						}
+					}
+				}
+				delete [] array;
+			}
+			++listi;
+		}
+	}
+//cerr << "ElementPresentInPath: did not find tag" << endl;
+	return false;
+}
+
+// Recursively descends from root into items of a top level sequence ... can be very slow :(
+// This doesn't work when called within a macro, which doesn't really have access
+// to the rootlist at all :(
+static bool ElementPresentInPathFromRoot(AttributeList *list,Tag tag,Tag sequencetag)
+{
+//cerr << "ElementPresentInPathFromRoot:" << endl;
+//cerr << "ElementPresentInPathFromRoot: sequencetag " << hex << sequencetag.getGroup() << "," << sequencetag.getElement() << dec << endl;
+//cerr << "ElementPresentInPathFromRoot: tag " << hex << tag.getGroup() << "," << tag.getElement() << dec << endl;
+//if (sequencetag.getElement() == 0x9222) {
+//TextOutputStream terr(cerr);
+//AttributeListIterator i(*list);
+//	while (!i) {
+//		Attribute *a=i();
+//		Assert(a);
+//		a->write(terr,NULL);
+//		terr << endl;
+//		++i;
+//	}
+//}
+	Assert(list);
+	Attribute *a=(*list)[sequencetag];
+	if (a && a->isSequence()) {
+//cerr << "ElementPresentInPathFromRoot: found sequence" << endl;
+		SequenceAttribute *aseq=(SequenceAttribute *)a;
+		Assert(aseq);
+		AttributeList **array;
+		int n;
+		if ((n=aseq->getLists(&array)) > 0) {
+//cerr << "ElementPresentInPathFromRoot: found " << n << " items" << endl;
+			int i; for (i=0; i<n; ++i) {
+//cerr << "ElementPresentInPathFromRoot: item " << dec << i << endl;
+				AttributeList *list=array[i];
+				if (ElementPresentInPath(list,tag)) {	// recurses if necessary
+//cerr << "ElementPresentInPathFromRoot: back from ElementPresentInPath having found tag" << endl;
+					delete [] array;
+					return true;	
+				}
+			}
+		}
+		delete [] array;
+	}
+//cerr << "ElementPresentInPathFromRoot: did not find tag" << endl;
+	return false;
+}
+
+static bool GroupPresent(AttributeList *list,Tag tag)
+{
+	Uint16 g = tag.getGroup();
+	Assert(list);
+	AttributeListIterator li(*list);
+	while (!li) {
+		Tag t = li()->getTag();
+		if (t.getGroup() == g) return true;
+		li++;
+	}
+	return false;
+}
+
+static bool GroupPresentMasked(AttributeList *list,Tag tag,Uint16 mask)
+{
+	Uint16 g = tag.getGroup() & mask;
+	Assert(list);
+	AttributeListIterator li(*list);
+	while (!li) {
+		Tag t = li()->getTag();
+		if ((t.getGroup() & mask) == g) return true;
+		li++;
+	}
+	return false;
+}
+
+static bool ValuePresent(AttributeList *list,Tag tag,int valueselector)
+{
+//cerr << "ValuePresent: want valueselector=" << dec << valueselector << endl;
+	int present=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a) {
+		int vm = int(a->getVM());
+//cerr << "ValuePresent: vm =" << dec << vm << endl;
+		if (valueselector >= 0) {			// 0 is 1st value
+			if(vm > valueselector) {
+				present=true;
+			}
+		}
+		else {								// -1 is wildcard
+			present = vm > 0;		// any value will do
+		}
+	}
+	return present;
+}
+
+
+static bool StringValueMatch(AttributeList *list,Tag tag,int valueselector,const char *string)
+{
+//cerr << "StringValueMatch: want valueselector=" << dec << valueselector << endl;
+//cerr << "StringValueMatch: want value <" << string << ">" << endl;
+//cerr << "StringValueMatch: want tag <" << hex << tag << dec << ">" << endl;
+//cerr << "StringValueMatch: want string <" << string << ">" << endl;
+//cerr << "StringValueMatch: looking in list " << hex << list << dec << endl;
+	int match=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a) {
+//cerr << "StringValueMatch: got attribute" << a << endl;
+		if (a->isString()) {
+//cerr << "StringValueMatch: testing string attribute" << a << endl;
+			unsigned start;
+			unsigned end;
+			if (valueselector >= 0) {	// 0 is 1st value
+				if(int(a->getVM()) >= valueselector) {
+					start=valueselector;
+					end=valueselector+1;
+				}
+				else
+					start=end=0;
+			}
+			else {				// -1 is wildcard
+				start=0;
+				end=a->getVM();
+			}
+			while (start<end && !match) {
+				char *value;
+				if (a->getValue(start,value) && value) {
+//cerr << "StringValueMatch: testing value number=" << dec << start << endl;
+//cerr << "StringValueMatch: testing value <" << value << ">" << endl;
+					if (strcmp(value,string) == 0)  {
+//cerr << "StringValueMatch: matched at value# " << dec << start << endl;
+						match=true;
+					}
+					delete[] value;	// correct: getValue() returns a copy
+				}
+				++start;
+			}
+		}
+	}
+	return match;
+}
+
+static bool TagValueMatch(AttributeList *list,Tag tag,int valueselector,Tag tagtomatch)
+{
+//cerr << "TagValueMatch: want valueselector=" << dec << valueselector << endl;
+	int match=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a && a->isTag()) {
+		unsigned start;
+		unsigned end;
+		if (valueselector >= 0) {	// 0 is 1st value
+			if(int(a->getVM()) >= valueselector) {
+				start=valueselector;
+				end=valueselector+1;
+			}
+			else
+				start=end=0;
+		}
+		else {				// -1 is wildcard
+			start=0;
+			end=a->getVM();
+		}
+		while (start<end && !match) {
+			Tag value;
+			if (a->getValue(start,value) && value == tagtomatch) {
+//cerr << "TagValueMatch: matched at value# " << dec << start << endl;
+				match=true;
+			}
+			++start;
+		}
+	}
+	return match;
+}
+
+enum BinaryValueMatchOperator {
+	Equals,
+	NotEquals,
+	LessThan,
+	LessThanOrEquals,
+	GreaterThan,
+	GreaterThanOrEquals
+};
+
+static bool BinaryValueMatch(AttributeList *list,Tag tag,int valueselector,BinaryValueMatchOperator matchoperator,Int32 valuetomatch)
+{
+//cerr << "BinaryValueMatch: want valueselector=" << dec << valueselector << endl;
+	int match=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a && a->isNumeric()) {
+		unsigned start;
+		unsigned end;
+		if (valueselector >= 0) {	// 0 is 1st value
+			if(int(a->getVM()) >= valueselector) {
+				start=valueselector;
+				end=valueselector+1;
+			}
+			else
+				start=end=0;
+		}
+		else {				// -1 is wildcard
+			start=0;
+			end=a->getVM();
+		}
+		while (start<end && !match) {
+			Int32 value;
+			if (a->getValue(start,value)) {
+//cerr << "BinaryValueMatch: checking value# " << dec << start << endl;
+				if ((matchoperator == Equals && value == valuetomatch)
+				 || (matchoperator == NotEquals && value != valuetomatch)
+				 || (matchoperator == LessThan && value < valuetomatch)
+				 || (matchoperator == LessThanOrEquals && value <= valuetomatch)
+				 || (matchoperator == GreaterThan && value > valuetomatch)
+				 || (matchoperator == GreaterThanOrEquals && value >= valuetomatch)
+				) {
+//cerr << "BinaryValueMatch: matched at value# " << dec << start << endl;
+					match=true;
+				}
+			}
+			++start;
+		}
+	}
+	return match;
+}
+
+static bool SequenceHasItems(AttributeList *list,Tag tag)
+{
+	bool present=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a && a->isSequence()) {
+		SequenceAttribute *aseq=(SequenceAttribute *)a;
+		Assert(aseq);
+		if (!aseq->isEmpty()) {
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool SequenceHasOneItem(AttributeList *list,Tag tag)
+{
+	bool present=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a && a->isSequence()) {
+		SequenceAttribute *aseq=(SequenceAttribute *)a;
+		Assert(aseq);
+		if (aseq->isOne()) {
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool SequenceHasMultipleItems(AttributeList *list,Tag tag)
+{
+	bool present=false;
+	Assert(list);
+	Attribute *a=(*list)[tag];
+	if (a && a->isSequence()) {
+		SequenceAttribute *aseq=(SequenceAttribute *)a;
+		Assert(aseq);
+		if (aseq->isMultiple()) {
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool ElementStringValueMatchWithin(AttributeList *list,Tag tag,Tag sequencetag,int valueselector,const char *string)
+{
+//cerr << "ElementStringValueMatchWithin:" << endl;
+	bool presentAndMatch=false;
+	Assert(list);
+	Attribute *a=(*list)[sequencetag];
+	if (a && a->isSequence()) {
+//cerr << "ElementStringValueMatchWithin: found sequence" << endl;
+		SequenceAttribute *aseq=(SequenceAttribute *)a;
+		Assert(aseq);
+		AttributeList **array;
+		int n;
+		if ((n=aseq->getLists(&array)) > 0) {
+//cerr << "ElementStringValueMatchWithin: found items" << endl;
+			int i; for (i=0; i<n; ++i) {
+//cerr << "ElementStringValueMatchWithin: item " << dec << i << endl;
+				AttributeList *list=array[i];
+				if ((*list)[tag]) {
+//cerr << "ElementStringValueMatchWithin: tag present" << endl;
+					presentAndMatch = StringValueMatch(list,tag,valueselector,string);
+//cerr << "ElementStringValueMatchWithin: presentAndMatch = " << presentAndMatch << endl;
+					break;
+				}
+			}
+		}
+	}
+	return presentAndMatch;
+}
+
+#include "condnd.h"
diff --git a/libsrc/src/dctool/dcoptc.cc b/libsrc/src/dctool/dcoptc.cc
new file mode 100644
index 0000000..afb426c
--- /dev/null
+++ b/libsrc/src/dctool/dcoptc.cc
@@ -0,0 +1,118 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcoptc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attrmxls.h"
+#include "mesgtext.h"
+#include "dcopt.h"
+
+bool
+usualManagedAttributeListWrite(
+	ManagedAttributeList& list,
+	DicomOutputStream& dout,
+	DicomOutputOptions& dicom_output_options,
+	TextOutputStream& log,
+	bool verbose)
+{
+	ManagedAttributeList::flag_types flags=ManagedAttributeList::flag_types(
+		 (dicom_output_options.usemetaheader     ? ManagedAttributeList::metaheader:0)
+		|(dicom_output_options.writedataset      ? ManagedAttributeList::dataset:0)
+		|(dicom_output_options.addlengths        ? ManagedAttributeList::addlengths:0)
+		|(dicom_output_options.addlengthtoend    ? ManagedAttributeList::addlengthtoend:0)
+		|(dicom_output_options.removeprivate     ? ManagedAttributeList::removeprivate:0)
+		|(dicom_output_options.removeinstanceuid ? ManagedAttributeList::removeinstanceuid:0)
+		|(dicom_output_options.adddicom          ? ManagedAttributeList::adddicom:0)
+		|(dicom_output_options.addtiff           ? ManagedAttributeList::addtiff:0)
+		|(dicom_output_options.adddisclaimer     ? ManagedAttributeList::adddisclaimer:0)
+		|(dicom_output_options.disambiguateseriesbydescription ? ManagedAttributeList::disambiguateseriesbydescription:0)
+	);
+
+	if (verbose) {
+		log << "******** As read ... ********" << endl;
+		log << list;
+	}
+
+	if (!list.clean(flags)) {
+		cerr << list.errors() << flush;
+		cerr << EMsgDC(DatasetWriteFailed) << endl;
+		return false;
+	}
+
+	if (dicom_output_options.deletelist) {
+		list-=*(dicom_output_options.deletelist);
+		if (verbose) {
+			log << "******** After delete ... ********" << endl;
+			log << list;
+		}
+	}
+
+	if (dicom_output_options.replacebeforelist) {
+		list+=*(dicom_output_options.replacebeforelist);
+		if (verbose) {
+			log << "******** After replace before... ********" << endl;
+			log << list;
+		}
+	}
+
+	if (!list.prepare(dout,flags,ManagedAttributeList::none,dicom_output_options.stamp,
+			dicom_output_options.instancecreationdate,
+			dicom_output_options.instancecreationtime,
+			dicom_output_options.timezoneoffsetfromutc)) {
+		cerr << list.errors() << flush;
+		cerr << EMsgDC(DatasetWriteFailed) << endl;
+		return false;
+	}
+
+	if (dicom_output_options.replaceafterlist) {
+		list+=*(dicom_output_options.replaceafterlist);
+		if (verbose) {
+			log << "******** After replace after ... ********" << endl;
+			log << list;
+		}
+	}
+
+	if (!list.finalize(dout)) {
+		cerr << list.errors() << flush;
+		cerr << EMsgDC(DatasetWriteFailed) << endl;
+		return false;
+	}
+
+	if (!list.write(dout) || !list.good()) {
+		cerr << list.errors() << flush;
+		cerr << EMsgDC(DatasetWriteFailed) << endl;
+		return false;
+	}
+
+	const char *errors=list.errors();
+	if (errors) log << errors << flush;
+
+	if (verbose) {
+		log << "******** As written ... ********" << endl;
+		log << list;
+	}
+	return true;
+}
+
+bool
+getAttributeTagFromStringHexForm(
+	const char *arg,
+	Tag &tag)
+{
+	bool success=false;
+	if (arg && arg[0] == '(') {			// handle "(0xgggg,0xeeee)"
+		// based on ancreate.cc approach
+		istrstream istr(arg+1);
+		Uint16 group;
+		istr >> resetiosflags(ios::basefield) >> group;
+		if (istr.good()) {
+			char c;
+			istr >> c;
+			if (istr.good() && c == ',') {
+				Uint16 element;
+				istr >> resetiosflags(ios::basefield) >> element;
+				if (istr.good()) {
+					tag=Tag(group,element);
+					success=true;
+				}
+			}
+		}
+	}
+	return success;
+}
diff --git a/libsrc/src/dctool/dcopti.cc b/libsrc/src/dctool/dcopti.cc
new file mode 100644
index 0000000..e6d34b3
--- /dev/null
+++ b/libsrc/src/dctool/dcopti.cc
@@ -0,0 +1,307 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcopti.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "dcopt.h"
+#include "transynu.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static const char *options_input_file[] = {
+	"if",
+	"input-file",
+	0
+};
+
+static const char *options_input_nolengthtoend[] = {
+	"input-nolengthtoend",
+	0
+};
+
+static const char *options_input_nometaheader[] = {
+	"input-nometa",
+	0
+};
+
+static const char *options_input_ignoreoutofordertags[] = {
+	"ignoreoutofordertags",
+	0
+};
+
+static const char *options_input_useUSVRForLUTDataIfNotExplicit[] = {
+	"usvrlutdata",
+	0
+};
+
+static const char *options_input_transfersyntax[] = {
+	"input-transfersyntax",
+	"input-ts",
+	0
+};
+
+static const char *options_input_defaulttransfersyntax[] = {
+	"input-default",
+	0
+};
+
+static const char *options_input_byteorder[] = {
+	"input-byteorder",
+	"input-endian",
+	0
+};
+
+static const char *options_input_vr[] = {
+	"input-vr",
+	0
+};
+
+DicomInputOptions::DicomInputOptions(GetNamedOptions &options)
+		: ErrorsInClass()
+{
+	filename=0;
+	options.get(options_input_file,filename);
+
+	usemetaheader=!(options.get(options_input_nometaheader));
+
+	uselengthtoend=!(options.get(options_input_nolengthtoend));
+
+	ignoreoutofordertags=options.get(options_input_ignoreoutofordertags);
+	
+	useUSVRForLUTDataIfNotExplicit=options.get(options_input_useUSVRForLUTDataIfNotExplicit);
+
+	transfersyntaxuid=0;
+	options.get(options_input_transfersyntax,transfersyntaxuid);
+
+	if (options.get(options_input_defaulttransfersyntax)) {
+		if (transfersyntaxuid) {
+			errorstream << EMsgDC(AlreadyHaveTransferSyntax)
+				    << endl;
+			good_flag=false;
+		}
+		else
+			transfersyntaxuid=DefaultTransferSyntaxUID;
+	}
+
+	const char *byteorder=0;
+	if (options.get(options_input_byteorder,byteorder)) {
+		if (strcmp(byteorder,"big") != 0
+		 && strcmp(byteorder,"little") != 0) {
+			errorstream << EMsgDC(BadByteOrder) << endl;
+			good_flag=false;
+		}
+	}
+	if (byteorder && transfersyntaxuid) {
+		errorstream << EMsgDC(AlreadyHaveTransferSyntax) << endl;
+		good_flag=false;
+	}
+
+	const char *vr=0;
+	if (options.get(options_input_vr,vr)) {
+		if (strcmp(vr,"explicit") != 0
+		 && strcmp(vr,"implicit") != 0) {
+			errorstream << EMsgDC(BadByteOrder) << endl;
+			good_flag=false;
+			vr=0;
+		}
+	}
+	if (vr && transfersyntaxuid) {
+		errorstream << EMsgDC(AlreadyHaveTransferSyntax) << endl;
+		good_flag=false;
+		vr=0;
+	}
+
+	if ((byteorder && !vr) || (vr && !byteorder)) {
+		errorstream << EMsgDC(NeedBothVRAndByteOrder) << endl;
+		good_flag=false;
+	}
+
+	if (!transfersyntaxuid && byteorder && vr) {
+		if (strcmp(byteorder,"little") == 0) {
+			if (strcmp(vr,"explicit") == 0)
+				transfersyntaxuid=
+					ExplicitVRLittleEndianTransferSyntaxUID;
+			else
+				transfersyntaxuid=
+					ImplicitVRLittleEndianTransferSyntaxUID;
+		}
+		else {
+			if (strcmp(vr,"explicit") == 0)
+				transfersyntaxuid=
+					ExplicitVRBigEndianTransferSyntaxUID;
+			else {
+				errorstream << EMsgDC(BadImplicitBig) << endl;
+				good_flag=false;
+			}
+		}
+	}
+}
+
+char *
+DicomInputOptions::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_input_nolengthtoend,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_input_nometaheader,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_input_ignoreoutofordertags,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_input_useUSVRForLUTDataIfNotExplicit,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_input_transfersyntax,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(UID) << "]";
+
+	ostr << " [";
+	for (ptr=options_input_defaulttransfersyntax,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_input_byteorder,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " big|little]";
+
+	ostr << " [";
+	for (ptr=options_input_vr,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " implicit|explicit]";
+
+	ostr << " [";
+	for (ptr=options_input_file,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(InputFile) << "]";
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+void
+DicomInputOptions::done(void)
+{
+}
+
+// NB. What is the significance of fstr being deleted after
+// assignment to another stream ? Should the DicomInputOpenerFromOptions
+// object be required to remain in scope as long as the
+// assigned to stream is still in use ??
+
+DicomInputOpenerFromOptions::DicomInputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename,
+		istream &cstr)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+	filenameUsed=filename;
+
+	if (filename) {
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		streambuf *sbuf  = cstr.rdbuf();
+		str=new istream(sbuf);
+		// default ANSI cin/cout is unbuffered, slow, so ...
+//		char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//		if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+		// this buffer will never be delete[]'d but doesn't
+		// matter ... how often would we be reusing cin/cout ?
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileReadOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+DicomInputOpenerFromOptions::DicomInputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+	filenameUsed=filename;
+
+	if (filename) {
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		str=0;
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileReadOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+DicomInputOpenerFromOptions::~DicomInputOpenerFromOptions()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "DicomInputOpenerFromOptions::~DicomInputOpenerFromOptions" << endl;
+#endif
+	if (str) delete str;
+}
+
+DicomInputOpenerFromOptions::operator istream *(void)
+{
+	return str;
+}
+
diff --git a/libsrc/src/dctool/dcopto.cc b/libsrc/src/dctool/dcopto.cc
new file mode 100644
index 0000000..28c4eae
--- /dev/null
+++ b/libsrc/src/dctool/dcopto.cc
@@ -0,0 +1,565 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcopto.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "attr.h"
+#include "attrlist.h"
+#include "attrnew.h"
+#include "elmdict.h"
+#include "transynu.h"
+#include "dcopt.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static const char *options_output_file[] = {
+	"output-file",
+	"of",
+	0
+};
+
+static const char *options_output_nometaheader[] = {
+	"output-nometa",
+	"nometa",
+	"n",
+	0
+};
+
+static const char *options_output_justmeta[] = {
+	"output-justmeta",
+	"justmeta",
+	0
+};
+
+static const char *options_output_implicitmetaheader[] = {
+	"output-implicitmeta",
+	"implicitmeta",
+	0
+};
+
+static const char *options_output_transfersyntax[] = {
+	"output-transfersyntax",
+	"output-ts",
+	"ts",
+	0
+};
+
+static const char *options_output_defaulttransfersyntax[] = {
+	"output-default",
+	"default",
+	0
+};
+
+static const char *options_output_byteorder[] = {
+	"output-byteorder",
+	"output-endian",
+	"byteorder",
+	"endian",
+	0
+};
+
+static const char *options_output_vr[] = {
+	"output-vr",
+	"vr",
+	0
+};
+
+static const char *options_output_stamp[] = {
+	"stamp",
+	"s",
+	0
+};
+
+static const char *options_output_instancecreationdate[] = {
+	"instancecreationdate",
+	0
+};
+
+static const char *options_output_instancecreationtime[] = {
+	"instancecreationtime",
+	0
+};
+
+static const char *options_output_timezoneoffsetfromutc[] = {
+	"timezoneoffsetfromutc",
+	0
+};
+
+static const char *options_output_addlengths[] = {
+	"addlengths",
+	0
+};
+
+static const char *options_output_addlengthtoend[] = {
+	"addlengthtoend",
+	0
+};
+
+static const char *options_output_addtiff[] = {
+	"tiff",
+	"tif",
+	0
+};
+
+static const char *options_output_removeprivate[] = {
+	"removeprivate",
+	0
+};
+
+static const char *options_output_removeinstanceuid[] = {
+	"removeinstanceuid",
+	0
+};
+
+static const char *options_output_noadddicom[] = {
+	"noadddicom",
+	0
+};
+
+static const char *options_output_noadddisclaimer[] = {
+"nodisclaimer",
+0
+};
+
+static const char *options_output_disambiguateseriesbydescription[] = {
+"disambiguateseriesbydescription",
+0
+};
+
+static const char *options_output_replace_after[] = {
+	"replace-after",
+	"ra",
+	0
+};
+
+static const char *options_output_replace_before[] = {
+	"replace",
+	"replace-before",
+	"r",
+	"rb",
+	0
+};
+
+static const char *options_output_delete[] = {
+	"delete",
+	"d",
+	0
+};
+
+DicomOutputOptions::DicomOutputOptions(GetNamedOptions &options)
+		: ErrorsInClass()
+{
+	filename=0;
+	options.get(options_output_file,filename);
+
+	usemetaheader=!(options.get(options_output_nometaheader));
+
+	writedataset=true;
+	if (options.get(options_output_justmeta)) {
+		usemetaheader=true;
+		writedataset=false;
+	}
+
+	useimplicitmetaheader=(options.get(options_output_implicitmetaheader));
+
+	if (!usemetaheader && useimplicitmetaheader) {
+		good_flag=false;
+	}
+
+	transfersyntaxuid=0;
+	options.get(options_output_transfersyntax,transfersyntaxuid);
+
+	if (options.get(options_output_defaulttransfersyntax)) {
+		if (transfersyntaxuid) {
+			errorstream << EMsgDC(AlreadyHaveTransferSyntax)
+				    << endl;
+			good_flag=false;
+		}
+		else
+			transfersyntaxuid=DefaultTransferSyntaxUID;
+	}
+
+	const char *byteorder=0;
+	if (options.get(options_output_byteorder,byteorder)) {
+		if (strcmp(byteorder,"big") != 0
+		 && strcmp(byteorder,"little") != 0) {
+			errorstream << EMsgDC(BadByteOrder) << endl;
+			good_flag=false;
+		}
+	}
+	if (byteorder && transfersyntaxuid) {
+		errorstream << EMsgDC(AlreadyHaveTransferSyntax) << endl;
+		good_flag=false;
+	}
+
+	const char *vr=0;
+	if (options.get(options_output_vr,vr)) {
+		if (strcmp(vr,"explicit") != 0
+		 && strcmp(vr,"implicit") != 0) {
+			errorstream << EMsgDC(BadByteOrder) << endl;
+			good_flag=false;
+			vr=0;
+		}
+	}
+	if (vr && transfersyntaxuid) {
+		errorstream << EMsgDC(AlreadyHaveTransferSyntax) << endl;
+		good_flag=false;
+		vr=0;
+	}
+
+	if ((byteorder && !vr) || (vr && !byteorder)) {
+		errorstream << EMsgDC(NeedBothVRAndByteOrder) << endl;
+		good_flag=false;
+	}
+
+	if (!transfersyntaxuid && byteorder && vr) {
+		if (strcmp(byteorder,"little") == 0) {
+			if (strcmp(vr,"explicit") == 0)
+				transfersyntaxuid=
+					ExplicitVRLittleEndianTransferSyntaxUID;
+			else
+				transfersyntaxuid=
+					ImplicitVRLittleEndianTransferSyntaxUID;
+		}
+		else {
+			if (strcmp(vr,"explicit") == 0)
+				transfersyntaxuid=
+					ExplicitVRBigEndianTransferSyntaxUID;
+			else {
+				errorstream << EMsgDC(BadImplicitBig) << endl;
+				good_flag=false;
+			}
+		}
+	}
+
+	if (!transfersyntaxuid && !byteorder && !vr) {
+		transfersyntaxuid=ExplicitVRLittleEndianTransferSyntaxUID;
+	}
+
+	stamp=0;
+	options.get(options_output_stamp,stamp);
+	instancecreationdate=0;
+	options.get(options_output_instancecreationdate,instancecreationdate);
+	instancecreationtime=0;
+	options.get(options_output_instancecreationtime,instancecreationtime);
+	timezoneoffsetfromutc=0;
+	options.get(options_output_timezoneoffsetfromutc,timezoneoffsetfromutc);
+
+	addlengths=options.get(options_output_addlengths);
+	addlengthtoend=options.get(options_output_addlengthtoend);
+	addtiff=options.get(options_output_addtiff);
+	removeprivate=options.get(options_output_removeprivate);
+	removeinstanceuid=options.get(options_output_removeinstanceuid);
+	adddicom=!(options.get(options_output_noadddicom));
+	adddisclaimer=!(options.get(options_output_noadddisclaimer));
+	disambiguateseriesbydescription=options.get(options_output_disambiguateseriesbydescription);
+//cerr << "DicomOutputOptions::DicomOutputOptions: disambiguateseriesbydescription = " << disambiguateseriesbydescription << endl;
+	
+	replacebeforelist=0;
+	replaceafterlist=0;
+	deletelist=0;
+
+	ElementDictionary dictionary;
+
+	const char *args[2];
+	int n;
+	while ((n=options.get(options_output_replace_before,args,2)) != -1) {
+		if (n == 2) {
+			Tag tag;
+			if (getAttributeTagFromStringHexForm(args[0],tag)
+			 || dictionary.getTag(args[0],tag)) {
+				const char *vr=dictionary.getValueRepresentation(tag);
+				if(!vr) vr="UN";
+				Attribute *a=newAttribute(vr,tag);
+				Assert(a);
+				a->addValues(args[1]);
+				if (!replacebeforelist) {
+					replacebeforelist=new AttributeList;
+					Assert(replacebeforelist);
+				}
+				(*replacebeforelist)+=a;
+			}
+			else {
+				errorstream << "-" << options_output_replace_before[0] << ": "
+					    << EMsgDC(UnrecognizedElement)
+					    << " - \"" << args[0] << "\""
+					    << endl;
+				good_flag=false;
+			}
+		}
+		else {
+			errorstream << "-" << options_output_replace_before[0] << ": "
+				    << EMsgDC(WantedElementAndDelimitedValues)
+				    << " - \"" << args[0] << "\""
+				    << endl;
+			good_flag=false;
+		}
+	}
+
+	while ((n=options.get(options_output_replace_after,args,2)) != -1) {
+		if (n == 2) {
+			Tag tag;
+			if (getAttributeTagFromStringHexForm(args[0],tag)
+			 || dictionary.getTag(args[0],tag)) {
+				const char *vr=dictionary.getValueRepresentation(tag);
+				if(!vr) vr="UN";
+				Attribute *a=newAttribute(vr,tag);
+				Assert(a);
+				a->addValues(args[1]);
+				if (!replaceafterlist) {
+					replaceafterlist=new AttributeList;
+					Assert(replaceafterlist);
+				}
+				(*replaceafterlist)+=a;
+			}
+			else {
+				errorstream << "-" << options_output_replace_after[0] << ": "
+					    << EMsgDC(UnrecognizedElement)
+					    << " - \"" << args[0] << "\""
+					    << endl;
+				good_flag=false;
+			}
+		}
+		else {
+			errorstream << "-" << options_output_replace_after[0] << ": "
+				    << EMsgDC(WantedElementAndDelimitedValues)
+				    << " - \"" << args[0] << "\""
+				    << endl;
+			good_flag=false;
+		}
+	}
+
+	const char *arg;
+	while (options.get(options_output_delete,arg)) {
+		Assert(arg);
+		Tag tag;
+		if (getAttributeTagFromStringHexForm(arg,tag)
+		 || dictionary.getTag(arg,tag)) {
+			const char *vr=dictionary.getValueRepresentation(tag);
+			if(!vr) vr="UN";
+			Attribute *a=newAttribute(vr,tag);
+			Assert(a);
+			if (!deletelist) {
+				deletelist=new AttributeList;
+				Assert(deletelist);
+			}
+			(*deletelist)+=a;
+		}
+		else {
+			errorstream << "-" << options_output_delete[0] << ": "
+				    << EMsgDC(UnrecognizedElement)
+				    << " - \"" << arg << "\""
+				    << endl;
+			good_flag=false;
+		}
+	}
+}
+
+DicomOutputOptions::~DicomOutputOptions()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "DicomOutputOptions::~DicomOutputOptions" << endl;
+#endif
+	if (replaceafterlist) delete replaceafterlist;
+	if (replacebeforelist) delete replacebeforelist;
+	if (deletelist)  delete deletelist;
+}
+
+char *
+DicomOutputOptions::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_output_nometaheader,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_justmeta,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_implicitmetaheader,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_transfersyntax,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(UID) << "]";
+
+	ostr << " [";
+	for (ptr=options_output_defaulttransfersyntax,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_byteorder,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " big|little]";
+
+	ostr << " [";
+	for (ptr=options_output_vr,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " implicit|explicit]";
+
+	ostr << " [";
+	for (ptr=options_output_stamp,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " uidstamp]";
+
+	ostr << " [";
+	for (ptr=options_output_instancecreationdate,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " date]";
+
+	ostr << " [";
+	for (ptr=options_output_instancecreationtime,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " time]";
+
+	ostr << " [";
+	for (ptr=options_output_timezoneoffsetfromutc,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " offset]";
+
+	ostr << " [";
+	for (ptr=options_output_addlengths,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_addlengthtoend,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_addtiff,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_removeprivate,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_removeinstanceuid,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_noadddicom,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_noadddisclaimer,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+	
+	ostr << " [";
+	for (ptr=options_output_disambiguateseriesbydescription,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << "]";
+
+	ostr << " [";
+	for (ptr=options_output_replace_before,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " keyword delimitedvalues]";
+
+	ostr << " [";
+	for (ptr=options_output_replace_after,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " keyword delimitedvalues]";
+
+	ostr << " [";
+	for (ptr=options_output_delete,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " keyword]";
+
+	ostr << " [";
+	for (ptr=options_output_file,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(OutputFile) << "]";
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+void
+DicomOutputOptions::done(void)
+{
+}
+
+DicomOutputOpenerFromOptions::DicomOutputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename,
+		ostream &cstr)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+	filenameUsed=filename;
+
+	if (filename) {
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+		ofstream *fstr=new ofstream(filename,
+			ios::out|ios::trunc|ios::binary);
+#else
+		ofstream *fstr=new ofstream(filename,ios::out|ios::trunc);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		streambuf *sbuf  = cstr.rdbuf();
+		str=new ostream(sbuf);
+		// default ANSI cin/cout is unbuffered, slow, so ...
+//		char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//		if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+		// this buffer will never be delete[]'d but doesn't
+		// matter ... how often would we be reusing cin/cout ?
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileWriteOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+DicomOutputOpenerFromOptions::~DicomOutputOpenerFromOptions()
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "DicomOutputOpenerFromOptions::~DicomOutputOpenerFromOptions" << endl;
+#endif
+	if (str) delete str;
+}
+
+DicomOutputOpenerFromOptions::operator ostream *(void)
+{
+	return str;
+}
+
diff --git a/libsrc/src/dctool/dcstream.cc b/libsrc/src/dctool/dcstream.cc
new file mode 100644
index 0000000..8e82222
--- /dev/null
+++ b/libsrc/src/dctool/dcstream.cc
@@ -0,0 +1,297 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dcstream.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>	// for isupper()
+#else
+#include <ctype.h>	// for isupper()
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "dcstream.h"
+
+static bool
+checkSwapped32BigEndian(char *buffer)
+{
+	// DICOM PS3.5 says big-endian is msb first, lsb last
+	// However have encountered files where a 32 bit value is sent
+	// as big-endian lsb 16 bits, then big-endian msb 16 bits :(
+	// These were from a Philips CT
+
+	Uint32 goodvalue;
+	Uint32 badvalue;
+
+	goodvalue =  (Uint32)buffer[0];
+	goodvalue <<= 8;
+	goodvalue |= (Uint32)buffer[1];
+	goodvalue <<= 8;
+	goodvalue |= (Uint32)buffer[2];
+	goodvalue <<= 8;
+	goodvalue |= (Uint32)buffer[3];
+
+	badvalue  =  (Uint32)buffer[2];
+	badvalue  <<= 8;
+	badvalue  |= (Uint32)buffer[3];
+	badvalue  <<= 8;
+	badvalue  |= (Uint32)buffer[0];
+	badvalue  <<= 8;
+	badvalue  |= (Uint32)buffer[1];
+
+	// assume that the lower value is the correct one
+	// (the check is applied to the first entry which
+	// should be a group length (IdentifyingGroup) that
+	// is VERY unlikely to be long enough to break this
+
+	return badvalue < goodvalue;
+}
+
+void
+DicomInputStream::initializeTransferSyntax(const char *uid,bool meta)
+{
+	TransferSyntaxToReadMetaHeader = 0;
+	TransferSyntaxToReadDataSet = 0;
+
+	// First make use of command line parameters that override guesswork ...
+
+	if (uid) {
+//cerr << "DicomInputStream::initializeTransferSyntax() initial uid=" << uid << endl;
+		TransferSyntax *ts = new TransferSyntax(uid);
+		if (meta) {
+			TransferSyntaxToReadMetaHeader = ts;	// specified UID is transfer syntax to read metaheader
+		}
+		else {
+			TransferSyntaxToReadDataSet = ts;	// specified UID is transfer syntax to read dataset (there is no metaheader)
+		}
+	}
+	// else transfer syntax has to be determined by either guesswork or metaheader ...
+
+	char b[8];
+	bool setswapped32big = false;
+
+	if (meta) {
+//cerr << "DicomInputStream::initializeTransferSyntax() testing for metaheader after 128 byte preamble" << endl;
+		// test for metaheader prefix after 128 byte preamble
+		seekg(128,ios::beg);
+		if (good() && read(b,4) && strncmp(b,"DICM",4) == 0) {
+//cerr << "DicomInputStream::initializeTransferSyntax() found metaheader after 128 byte preamble" << endl;
+			if (!TransferSyntaxToReadMetaHeader) TransferSyntaxToReadMetaHeader = 	// guess only if not specified on command line
+				read(b,6) && isupper(b[4]) && isupper(b[5])
+				? new TransferSyntax(ExplicitVRLittleEndianTransferSyntaxUID)	// standard
+				: new TransferSyntax(ImplicitVRLittleEndianTransferSyntaxUID);	// old draft (e.g. used internally on GE IOS platform)
+
+			// leaves positioned at start of metaheader
+			seekg(128+4,ios::beg);
+		}
+		else {
+//cerr << "DicomInputStream::initializeTransferSyntax() did not find metaheader after 128 byte preamble" << endl;
+			clear(); seekg(0,ios::beg);		// reset stream since metaheader was sought but not found
+			TransferSyntaxToReadDataSet=TransferSyntaxToReadMetaHeader;
+			TransferSyntaxToReadMetaHeader=0;
+		}
+	}
+//cerr << "DicomInputStream::initializeTransferSyntax() after metaheader checks, good()=" << good() << endl;
+//cerr << "DicomInputStream::initializeTransferSyntax() after metaheader checks, TransferSyntaxToReadMetaHeader=" << (TransferSyntaxToReadMetaHeader ? TransferSyntaxToReadMetaHeader->getUID() : "") << endl;
+//cerr << "DicomInputStream::initializeTransferSyntax() after metaheader checks, TransferSyntaxToReadDataSet=" << (TransferSyntaxToReadDataSet ? TransferSyntaxToReadDataSet->getUID() : "") << endl;
+	
+	if (!TransferSyntaxToReadDataSet && !TransferSyntaxToReadMetaHeader){	// was not specified on the command line and there is no metaheader
+//cerr << "DicomInputStream::initializeTransferSyntax() no metaheader found and no transfer syntax prespecified, guessing" << endl;
+		clear();
+		seekg(0,ios::beg);
+
+		guessTransferSyntaxToReadDataSet(setswapped32big);
+
+		// leaves positioned at start of dataset
+		clear();
+		seekg(0,ios::beg);
+	}
+
+	TransferSyntaxInUse = TransferSyntaxToReadMetaHeader ? TransferSyntaxToReadMetaHeader : TransferSyntaxToReadDataSet;
+	Assert(TransferSyntaxInUse);
+	setEndian(TransferSyntaxInUse->getEndian());
+	if (setswapped32big) setSwapped32Big();	// This is not reflected in the TS
+//cerr << "DicomInputStream::initializeTransferSyntax() at end, good()=" << good() << endl;
+//cerr << "DicomInputStream::initializeTransferSyntax() at end, TransferSyntaxToReadMetaHeader=" << (TransferSyntaxToReadMetaHeader ? TransferSyntaxToReadMetaHeader->getUID() : "") << endl;
+//cerr << "DicomInputStream::initializeTransferSyntax() at end, TransferSyntaxToReadDataSet=" << (TransferSyntaxToReadDataSet ? TransferSyntaxToReadDataSet->getUID() : "") << endl;
+//cerr << "DicomInputStream::initializeTransferSyntax() at end, TransferSyntaxInUse=" << (TransferSyntaxInUse ? TransferSyntaxInUse->getUID() : "") << endl;
+}
+
+void
+DicomInputStream::guessTransferSyntaxToReadDataSet(bool& setswapped32big) {
+	bool bigendian = false;
+	bool explicitvr	= false;
+	setswapped32big = false;
+	char b[8];
+	if (good() && read(b,8)) {
+		// examine probable group number ... assume <= 0x00ff
+		if (b[0] < b[1]) bigendian=true;
+		else if (b[0] == 0 && b[1] == 0) {
+			// blech ... group number is zero
+			// no point in looking at element number
+			// as it will probably be zero too (group length)
+			// try the 32 bit value length of implicit vr
+			if (b[4] < b[7]) bigendian=true;
+		}
+		// else littleendian
+		if (isupper(b[4]) && isupper(b[5])) explicitvr=true;
+		else if (bigendian) setswapped32big=checkSwapped32BigEndian(b+4);
+
+		seekg(-8l,ios::cur);
+	}
+	// else unrecognized ... assume default
+
+	if (bigendian)
+		if (explicitvr)
+			TransferSyntaxToReadDataSet = new TransferSyntax(ExplicitVRBigEndianTransferSyntaxUID);
+		else
+			TransferSyntaxToReadDataSet = new TransferSyntax(ImplicitVR,BigEndian);
+	else
+		if (explicitvr)
+			TransferSyntaxToReadDataSet = new TransferSyntax(ExplicitVRLittleEndianTransferSyntaxUID);
+		else
+			TransferSyntaxToReadDataSet = new TransferSyntax(ImplicitVRLittleEndianTransferSyntaxUID);
+}
+
+DicomInputStream::DicomInputStream(streambuf *buf,const char *uid,bool meta)
+	: BinaryInputStream(buf)
+{
+	initializeTransferSyntax(uid,meta);
+}
+
+DicomInputStream::DicomInputStream(istream& istr,const char *uid,bool meta)
+	: BinaryInputStream(istr)
+{
+	initializeTransferSyntax(uid,meta);
+}
+
+DicomInputStream::~DicomInputStream(void)
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "DicomInputStream::~DicomInputStream" << endl;
+#endif
+	if (TransferSyntaxToReadDataSet)
+		delete TransferSyntaxToReadDataSet;
+	if (TransferSyntaxToReadMetaHeader)
+		delete TransferSyntaxToReadMetaHeader;
+}
+
+void
+DicomInputStream::setTransferSyntaxToReadDataSet(TransferSyntax *ts)
+{
+//cerr << "DicomInputStream::setTransferSyntaxToReadDataSet(): was " << (TransferSyntaxToReadDataSet ? TransferSyntaxToReadDataSet->getUID() : "") << endl;
+	if (TransferSyntaxToReadDataSet)
+		delete TransferSyntaxToReadDataSet;
+	TransferSyntaxToReadDataSet=ts;
+//cerr << "DicomInputStream::setTransferSyntaxToReadDataSet(): now " << (TransferSyntaxToReadDataSet ? TransferSyntaxToReadDataSet->getUID() : "") << endl;
+}
+
+void
+DicomInputStream::readingDataSet(void)
+{
+//cerr << "DicomInputStream::readingDataSet()" << endl;
+	Assert(TransferSyntaxToReadDataSet);
+	TransferSyntaxInUse=TransferSyntaxToReadDataSet;
+	setEndian(TransferSyntaxInUse->getEndian());
+	//Assert(TransferSyntaxInUse->isImplicitVR() != TransferSyntaxInUse->isExplicitVR());
+}
+
+void
+DicomInputStream::readingMetaHeader(void)
+{
+//cerr << "DicomInputStream::readingMetaHeader()" << endl;
+	Assert(TransferSyntaxToReadMetaHeader);
+	TransferSyntaxInUse=TransferSyntaxToReadMetaHeader;
+	setEndian(TransferSyntaxInUse->getEndian());
+	//Assert(TransferSyntaxInUse->isImplicitVR() != TransferSyntaxInUse->isExplicitVR());
+}
+
+void
+DicomOutputStream::initializeTransferSyntax(const char *uid,bool meta,bool implicitmeta,bool addtiff)
+{
+	if (!uid) uid=DefaultTransferSyntaxUID;
+	TransferSyntaxToWriteDataSet = new TransferSyntax(uid);
+	preambledone=false;
+	tiffinpreamble=false;
+	if (meta) {
+		if (addtiff) tiffinpreamble=true;
+		TransferSyntaxToWriteMetaHeader =
+		    (implicitmeta ? new TransferSyntax(ImplicitVRLittleEndianTransferSyntaxUID)
+				  : new TransferSyntax(MetaInformationTransferSyntaxUID));
+		//writingMetaHeader();	// Musn't be done now else preamble written before TIFF IFD offset is known
+	}
+	else {
+		TransferSyntaxToWriteMetaHeader = 0;
+		//writingDataSet();
+	}
+}
+
+void
+DicomOutputStream::writeMetaHeaderPreamble(void)
+{
+	char zeroes[128];
+	memset(zeroes,0,128);
+	if (tiffinpreamble) {
+		Assert(TransferSyntaxToWriteDataSet);
+		setEndian(TransferSyntaxToWriteDataSet->getEndian());
+		write(isBigEndian() ? "MM":"II",2);	// Motorola or Intel byte order flag
+		write16(0x002A);			// TIFF Version number
+		Assert(offsetofIFD);
+		write32(offsetofIFD);
+		write(zeroes,120);
+		Assert(TransferSyntaxToWriteMetaHeader);
+		setEndian(TransferSyntaxToWriteMetaHeader->getEndian());
+	}
+	else {
+		write(zeroes,128);
+	}
+	write("DICM",4);
+	preambledone=true;
+}
+
+DicomOutputStream::DicomOutputStream(streambuf *buf,
+		  const char *uid,
+		  bool meta,bool implicitmeta,
+		  bool addtiff)
+	: BinaryOutputStream(buf)
+{
+	initializeTransferSyntax(uid,meta,implicitmeta,addtiff);
+}
+
+DicomOutputStream::DicomOutputStream(ostream& ostr,
+		  const char *uid,
+		  bool meta,bool implicitmeta,
+		  bool addtiff)
+	: BinaryOutputStream(ostr)
+{
+	initializeTransferSyntax(uid,meta,implicitmeta,addtiff);
+}
+
+DicomOutputStream::~DicomOutputStream(void)
+{
+#ifdef TRACE_DESTRUCTORS
+cerr << "DicomOutputStream::~DicomOutputStream" << endl;
+#endif
+	if (TransferSyntaxToWriteDataSet)
+		delete TransferSyntaxToWriteDataSet;
+	if (TransferSyntaxToWriteMetaHeader)
+		delete TransferSyntaxToWriteMetaHeader;
+}
+
+void
+DicomOutputStream::writingDataSet(void)
+{
+//cerr << "DicomOutputStream::writingDataSet" << endl;
+	TransferSyntaxInUse=TransferSyntaxToWriteDataSet;
+	Assert(TransferSyntaxInUse);
+	setEndian(TransferSyntaxInUse->getEndian());
+}
+
+void DicomOutputStream::writingMetaHeader(void)
+{
+//cerr << "DicomOutputStream::writingMetaHeader" << endl;
+	TransferSyntaxInUse=TransferSyntaxToWriteMetaHeader;
+	Assert(TransferSyntaxInUse);
+	setEndian(TransferSyntaxInUse->getEndian());
+	if (!preambledone) writeMetaHeaderPreamble();
+}
+
diff --git a/libsrc/src/dctool/dicomdir.cc b/libsrc/src/dctool/dicomdir.cc
new file mode 100644
index 0000000..45fa73e
--- /dev/null
+++ b/libsrc/src/dctool/dicomdir.cc
@@ -0,0 +1,297 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dicomdir.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrmxls.h"
+#include "attrval.h"
+#include "hash.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+
+class Entry {
+	Uint32 inputoffset;
+	AttributeList * dicomdirrecord;
+public:
+	Entry(void)				{}
+	Entry(Uint32 o,AttributeList * i)	{ inputoffset=o; dicomdirrecord=i; }
+	Entry(Entry *e)				{ inputoffset=e->inputoffset; dicomdirrecord=e->dicomdirrecord; }
+
+	Uint32	getInputOffset(void) const		{ return inputoffset; }
+	AttributeList *	getDicomdirRecord(void) const	{ return dicomdirrecord; }
+
+	bool operator==(Entry e)		{ return inputoffset == e.getInputOffset(); }
+};
+
+
+class EntryList : public SimpleList<Entry>
+{
+public:
+	~EntryList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class EntryListIterator : public SimpleListIterator<Entry>
+{
+public:
+	EntryListIterator(void)
+		: SimpleListIterator<Entry>() {}
+	EntryListIterator(EntryList& list)
+		: SimpleListIterator<Entry>(list) {}
+};
+
+class IndexDicomdirRecordsByInputOffset : public OpenHashTable <Entry,
+			Uint32,
+			EntryList,
+			EntryListIterator>
+{
+public:
+	IndexDicomdirRecordsByInputOffset(unsigned long size)
+		: OpenHashTable<Entry,
+			Uint32,
+			EntryList,
+			EntryListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long hash(const Uint32 &inputoffset,unsigned long size)
+		{
+			return inputoffset%size; 
+		}
+
+	Uint32 key(const Entry &e)		{ return e.getInputOffset(); }
+};
+
+#define DICOMDIRRECORDSINDEXSIZE	131
+
+static void
+indent(TextOutputStream &log,unsigned depth)
+{
+	while (depth--) log << "\t";
+}
+
+static bool
+traverseDepthFirst(IndexDicomdirRecordsByInputOffset *index,Uint32 offset,
+	TextOutputStream &log,bool verbose,bool veryverbose,bool showrecordinfo,bool showabstract,bool showpaths,bool showdescription,unsigned depth)
+{
+	while (offset) {
+		Entry *entry=(*index)[offset];
+		if (entry == 0) {
+			log << EMsgDC(DirectoryOffsetInvalid)
+			    << " - " << hex << offset << dec
+			    << endl;
+			return false;
+		}
+		AttributeList *list=entry->getDicomdirRecord();
+		Assert(list);
+
+		char *type = AttributeValue((*list)[TagFromName(DirectoryRecordType)]);
+		
+		if (showabstract) {
+			indent(log,depth);
+			
+			if (showrecordinfo) log << hex << offset << dec << ": ";
+
+			log << (type ? type : "-none-");
+			
+			if (strcmp(type,"PATIENT") == 0) {
+				char *name = AttributeValue((*list)[TagFromName(PatientName)]);
+				char *id = AttributeValue((*list)[TagFromName(PatientID)]);
+				log << " " << (name ? name : "") << " " << (id ? id : "");
+			}
+			else if (strcmp(type,"STUDY") == 0) {
+				char *date = AttributeValue((*list)[TagFromName(StudyDate)]);
+				char *time = AttributeValue((*list)[TagFromName(StudyTime)]);
+				char *id = AttributeValue((*list)[TagFromName(StudyID)]);
+				char *num = AttributeValue((*list)[TagFromName(AccessionNumber)]);
+				char *desc = showdescription ? AttributeValue((*list)[TagFromName(StudyDescription)]) : (char *)NULL;
+				log << " " << (id ? id : "") << " " << (num ? num : "")
+				    << " " << (date ? date : "") << " " << (time ? time : "")
+				    << " " << (desc ? desc : "");
+			}
+			else if (strcmp(type,"SERIES") == 0) {
+				char *mod = AttributeValue((*list)[TagFromName(Modality)]);
+				char *num = AttributeValue((*list)[TagFromName(SeriesNumber)]);
+				char *desc = showdescription ? AttributeValue((*list)[TagFromName(SeriesDescription)]) : (char *)NULL;
+				log << " " << (num ? num : "") << " " << (mod ? mod : "")
+				    << " " << (desc ? desc : "");
+			}
+			else if (strcmp(type,"IMAGE") == 0) {
+				char *num = AttributeValue((*list)[TagFromName(InstanceNumber)]);
+				log << " " << (num ? num : "");
+			}
+			else if (strcmp(type,"STUDY COMPONENT") == 0) {
+				char *mod = AttributeValue((*list)[TagFromName(Modality)]);
+				char *desc = AttributeValue((*list)[TagFromName(StudyDescription)]);
+				// should also do ProcedureCodeSequence
+				log << " " << (mod ? mod : "") << " " << (desc ? desc : "");
+			}
+			else if (strcmp(type,"MRDR") == 0) {
+				char *num = AttributeValue((*list)[TagFromName(NumberOfReferences)]);
+				log << " (" << (num ? num : "") << ")";
+			}
+
+			log << endl;
+		}
+		
+		Attribute *aFilename = (*list)[TagFromName(ReferencedFileID)];
+		if (aFilename) {
+			if (showabstract) {
+				indent(log,depth);
+				log << " -> ";
+				aFilename->writeData(log);
+				log << endl;
+			}
+			if (showpaths) {
+				int vm = aFilename->getVM();
+				const char *prefix="";
+				for (int i=0; i<vm; ++i) {
+					log << prefix;
+					char *string;
+					if (aFilename->getValue(i,string) && string != NULL) {
+						if (strlen(string) > 0) {
+							log << string;
+						}
+						delete[] string;
+					}
+					prefix="/";
+				}
+				if (vm > 0) {
+					log << endl;
+				}
+			}
+		}
+
+		if (verbose) {
+			AttributeListIterator i(*list);
+			while (!i) {
+				Attribute *a=i();
+				Assert(a);
+				indent(log,depth);
+				a->write(log,list->getDictionary(),veryverbose);
+				log << endl;
+				++i;
+			}
+		}
+
+		Uint32 mrdroffset = AttributeValue((*list)[TagFromName(MRDRDirectoryRecordOffset)],double(0));
+		if (mrdroffset && !traverseDepthFirst(index,mrdroffset,log,verbose,veryverbose,showrecordinfo,showabstract,showpaths,showdescription,depth+1)) return false;
+
+		Uint32 lower = AttributeValue((*list)[TagFromName(OffsetOfReferencedLowerLevelDirectoryEntity)],double(0));
+		if (lower && !traverseDepthFirst(index,lower,log,verbose,veryverbose,showrecordinfo,showabstract,showpaths,showdescription,depth+1)) return false;
+
+		offset=AttributeValue((*list)[TagFromName(OffsetOfTheNextDirectoryRecord)],double(0));
+	}
+	return true;
+}
+
+bool
+parseDicomdir(ManagedAttributeList &list,TextOutputStream &log,bool verbose,bool veryverbose,bool showrecordinfo,bool showabstract,bool showpaths,bool showdescription)
+{
+	IndexDicomdirRecordsByInputOffset *DicomdirRecordsIndex;
+
+	DicomdirRecordsIndex = new
+		IndexDicomdirRecordsByInputOffset(DICOMDIRRECORDSINDEXSIZE);
+
+	Assert(DicomdirRecordsIndex);
+
+	// NB. The byteoffset from 0 (including the preamble and DICM) is
+	// recorded with the start of each attribute. The offset for the
+	// first attribute of each DICOMDIR record is actually 8 bytes larger
+	// than the value contained in the "pointers" contained within the
+	// records, because the pointer is directed at the 8 byte long Item
+	// element that preceeds each item in the directory record sequence,
+	// and is not recorded in our internal structure. The input offset
+	// values entered in this table are the "corrected" values, ie. those
+	// that match the directory record pointer values, ie. 8 bytes less
+	// than the byteoffset value stored in the attribute internal structure.
+
+	Uint32 vRootDirectoryFirstRecord = 0;
+	Attribute *aRootDirectoryFirstRecord=list[TagFromName(OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity)];
+	if (!aRootDirectoryFirstRecord)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"RootDirectoryFirstRecord\""
+		    << endl;
+	else
+		vRootDirectoryFirstRecord=AttributeValue(aRootDirectoryFirstRecord);
+
+	if (veryverbose | showrecordinfo)
+		log << "RootDirectoryFirstRecord = " << hex << vRootDirectoryFirstRecord << dec << endl;
+
+	Uint32 vRootDirectoryLastRecord = 0;
+	Attribute *aRootDirectoryLastRecord=list[TagFromName(OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity)];
+	if (!aRootDirectoryLastRecord)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"RootDirectoryLastRecord\""
+		    << endl;
+	else
+		vRootDirectoryLastRecord=AttributeValue(aRootDirectoryLastRecord);
+
+	if (veryverbose | showrecordinfo)
+		log << "RootDirectoryLastRecord = " << hex << vRootDirectoryLastRecord << dec << endl;
+
+	// The directory record sequence is returned as
+	// an array of pointers to attribute lists
+
+	int nDirectoryRecordSequence = 0;
+	AttributeList ** vDirectoryRecordSequence = 0;
+	Attribute *aDirectoryRecordSequence=list[TagFromName(DirectoryRecordSequence)];
+	if (!aDirectoryRecordSequence)
+		log << WMsgDC(MissingAttribute)
+		    << " - \"DirectoryRecordSequence\""
+		    << endl;
+	else
+		nDirectoryRecordSequence=aDirectoryRecordSequence->getLists(&vDirectoryRecordSequence);
+
+	Assert(nDirectoryRecordSequence==0 || vDirectoryRecordSequence);
+
+	if (veryverbose | showrecordinfo)
+		log << "Number of records = " << dec << nDirectoryRecordSequence << endl;
+
+	int i;
+	AttributeList **iptr;
+
+	for (i=0,iptr=vDirectoryRecordSequence; i<nDirectoryRecordSequence; ++i,++iptr) {
+		AttributeList *ptr = *iptr;
+		Assert(ptr);
+#ifdef CRAP
+		// The DirectoryRecordSequence attribute is ALWAYS the 1st in the item,
+		// so find it and use its byteoffset - 8 as the input offset of this record ...
+
+		Attribute *aNextDirectoryRecordOffset=(*ptr)[TagFromName(NextDirectoryRecordOffset)];
+#else
+		// The proceeding is NOT true ... what if there is a group length ? (eg. ECR 97 Philips)
+		// so take 1st element in item ...
+
+		AttributeListIterator i(*ptr);
+		// i.first() is redundant
+		Attribute *aNextDirectoryRecordOffset=i.value();
+#endif
+		if (!aNextDirectoryRecordOffset)
+			log << WMsgDC(MissingAttribute)
+			    << " - \"NextDirectoryRecordOffset\""
+			    << endl;
+		else {
+			Uint32 inputoffset=aNextDirectoryRecordOffset->getByteOffset()-8;
+			*DicomdirRecordsIndex+=Entry(inputoffset,ptr);
+			if (veryverbose) {
+				log << "Offset = " << hex << inputoffset << dec << endl;
+				AttributeListIterator i(*ptr);
+				while (!i) {
+					Attribute *a=i();
+					Assert(a);
+					log << "\t";
+					a->write(log,ptr->getDictionary(),true);
+					log << endl;
+					++i;
+				}
+			}
+		}
+	}
+
+	if (veryverbose) log << endl;
+
+	// Each directory record has a "next" entry at the same level
+	// and a "lower-level" entry ... do a depth-first traversal
+	// descending recursively ...
+
+	return traverseDepthFirst(DicomdirRecordsIndex,vRootDirectoryFirstRecord,log,verbose,veryverbose,showrecordinfo,showabstract,showpaths,showdescription,0);
+}
+
diff --git a/libsrc/src/dctool/elmdict.cc b/libsrc/src/dctool/elmdict.cc
new file mode 100644
index 0000000..fb45cb7
--- /dev/null
+++ b/libsrc/src/dctool/elmdict.cc
@@ -0,0 +1,231 @@
+static const char *CopyrightIdentifier(void) { return "@(#)elmdict.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmtype.h"
+#include "elmdict.h"
+#include "elmentry.h"
+#include "elmtable.h"
+#include "elmpriv.h"	// declare before elmhash.h to avoid old SunPro C++ bug
+#include "elmhash.h"
+
+static int ElementDictionaryReferenceCount;	// will be zero at start
+
+static ElementDictionaryTableEntry 	*Table;
+static IndexByString 			*StringIndex;
+static IndexByTag   			*TagIndex;
+static IndexByTagAndOwnerAndBlock   	*TagAndOwnerAndBlockIndex;
+
+static class ElementDictionaryTableEntry GenericGroupLengthElementDictionaryTableEntry = { 0x0000,0x0000,0x0000,"UL",1,1,"","GroupLength","Group Length",true };
+
+ElementDictionary::ElementDictionary(void)
+{
+	if (ElementDictionaryReferenceCount++ == 0) {
+		Table=ElementDictionaryTable;
+		StringIndex = new
+			IndexByString(DATADICTIONARYINDEXSIZE);
+		TagIndex = new
+			IndexByTag(DATADICTIONARYINDEXSIZE);
+		TagAndOwnerAndBlockIndex = new
+			IndexByTagAndOwnerAndBlock(DATADICTIONARYINDEXSIZE);
+		ElementDictionaryTableEntry *ptr=Table;
+		unsigned long index=0;
+		while (ptr->Keyword) {
+			Tag tag(ptr->Group,ptr->Element);
+			if (tag.isPrivateGroup()) {
+			// if (ptr->Owner == 0) {	// same same
+				TagAndOwnerAndBlock tob(tag,ptr->Owner,ptr->PrivateBlock);
+				IndexEntryTagAndOwnerAndBlock ietob(tob,index);
+				(*TagAndOwnerAndBlockIndex)+=ietob;
+				// PrivateBlock will be zero (wildcard) except when
+				// non-standard owner disambiguation needed
+			}
+			else {
+				(*StringIndex)+=IndexEntryString(
+					ptr->Keyword,index);
+				(*TagIndex)+=IndexEntryTag(tag,index);
+			}
+			++ptr;
+			++index;
+		}
+	}
+	CurrentOwners=new PrivateOwners;
+}
+
+ElementDictionary::~ElementDictionary()
+{
+	Assert(ElementDictionaryReferenceCount>0);
+	Assert(StringIndex);
+	Assert(TagIndex);
+	Assert(TagAndOwnerAndBlockIndex);
+	Assert(CurrentOwners);
+
+	if (--ElementDictionaryReferenceCount == 0) {
+		if (StringIndex) delete StringIndex;
+		if (TagIndex) delete TagIndex;
+		if (TagAndOwnerAndBlockIndex) delete TagAndOwnerAndBlockIndex;
+	}
+	if (CurrentOwners) delete CurrentOwners;
+}
+
+const ElementDictionaryTableEntry *
+ElementDictionary::operator[] (Tag tag) const
+{
+	ElementDictionaryTableEntry *e = 0;
+
+	// Repeating group/element mechanism is NOT applied to private groups
+	// except Papyrus 3.0 60xx annotations
+
+	// Use isPrivateGroup() from attrtag.h to find
+	// exclusions to odd group rule such as Variable Pixel Data
+
+	if (tag.isPrivateGroup()) {
+		if (CurrentOwners) {
+			const char *owner=(*CurrentOwners)[tag];
+			if (owner) {
+				// Try first with block in case owner is ambiguous
+				// (this is counter to the standard but happens)
+				IndexEntryTagAndOwnerAndBlock *ei=
+				    (*TagAndOwnerAndBlockIndex)[TagAndOwnerAndBlock(
+					Tag(tag.getGroup(),tag.getElement()&0xff),
+					owner,
+					(tag.getElement()&0xff00)>>8u)];
+				// If failed then use block of 0x0000 which is not a valid
+				// block and hence is used as a "wildcard" ... this is
+				// the "standard" way to do it and is the most common path 
+				if (!ei) {
+//cerr << "Tag group=" << hex << tag.getGroup() << dec << endl;
+//cerr << "Tag element=" << hex << tag.getElement() << dec << endl;
+//cerr << "Owner=<" << owner << ">" << endl;
+					Tag testtag=tag.getRepeatingBase();
+//cerr << "Test tag group=" << hex << testtag.getGroup() << dec << endl;
+//cerr << "Test tag element=" << hex << testtag.getElement() << dec << endl;
+					if (testtag.getGroup() == 0x6001 && strcmp(owner,"PAPYRUS 3.0") == 0) {
+//cerr << "matched criteria" << endl;
+//cerr << "Index tag group=" << hex << Tag(testtag.getGroup(),testtag.getElement()&0xff).getGroup() << dec << endl;
+//cerr << "Index tag element=" << hex << Tag(testtag.getGroup(),testtag.getElement()&0xff).getElement() << dec << endl;
+						ei=(*TagAndOwnerAndBlockIndex)[TagAndOwnerAndBlock(
+							Tag(testtag.getGroup(),testtag.getElement()&0xff),
+							owner,
+							0)];
+					}
+					else {
+						ei=(*TagAndOwnerAndBlockIndex)[TagAndOwnerAndBlock(
+							Tag(tag.getGroup(),tag.getElement()&0xff),
+							owner,
+							0)];
+					}
+				}
+				if (ei) e=Table+ei->getIndex();
+			}
+		}
+	}
+	else {
+		Tag testtag=tag.getRepeatingBase();
+		IndexEntryTag *ei = (*TagIndex)[testtag];
+		if(ei) e=Table+ei->getIndex();
+	}
+
+	// Don't assume all elements == 0 are GroupLength
+	// because in some private dictionaries they are not (!)
+	// but we would have found them by now, so this is ok...
+
+	if (!e && tag.getElement() == 0) {
+		e = &GenericGroupLengthElementDictionaryTableEntry;
+	}
+
+	return e;
+}
+
+const ElementDictionaryTableEntry *
+ElementDictionary::operator[] (const char *keyword) const
+{
+	IndexEntryString *e=(*StringIndex)[keyword];
+	return e ? Table+e->getIndex() : 0;
+}
+
+const char *
+ElementDictionary::getValueRepresentation(Tag t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e ? e->ValueRepresentation : 0;
+}
+
+const Uint16
+ElementDictionary::getValueMultiplicityMinimum(Tag t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e ? e->ValueMultiplicityMinimum : VMNONE;
+}
+
+const Uint16
+ElementDictionary::getValueMultiplicityMaximum(Tag t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e ? e->ValueMultiplicityMaximum : VMNONE;
+}
+
+const char *
+ElementDictionary::getDescription(Tag t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e ? e->Description : 0;
+//	return e ? e->Keyword : 0;
+}
+
+const char *
+ElementDictionary::getKeyword(Tag t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e ? e->Keyword : 0;
+}
+
+bool
+ElementDictionary::getTag(const char *keyword,Tag& tr) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[keyword];
+	if (e) {
+		tr=Tag(e->Group,e->Element);
+		return true;
+	}
+	else
+		return false;
+}
+
+bool
+ElementDictionary::isRetired(Tag& t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e && e->Retired;
+}
+
+bool
+ElementDictionary::isRenderAsString(Tag& t) const
+{
+	const ElementDictionaryTableEntry *e = (*this)[t];
+	return e && e->RenderAsString;
+}
+
+void
+ElementDictionary::addOwner(Tag t,const char *owner)
+{
+	Assert(CurrentOwners);
+	Assert(owner);
+	Assert (*owner); 
+	// NB. we don't use the block in the owner list so use wildcard of 0
+	(*CurrentOwners)+=TagAndOwnerAndBlock(t,owner,0);
+}
+
+bool
+ElementDictionary::hasOwner(Tag& t) const
+{
+	return t.isPrivateGroup() && CurrentOwners && (*CurrentOwners)[t];
+}
+
+const char *
+ElementDictionary::getOwner(Tag& t) const
+{
+	const char* owner = NULL;
+	if (t.isPrivateGroup() && CurrentOwners) {
+		owner = (*CurrentOwners)[t];
+	}
+	return owner;
+}
+
diff --git a/libsrc/src/dctool/elmentry.h b/libsrc/src/dctool/elmentry.h
new file mode 100644
index 0000000..94afae1
--- /dev/null
+++ b/libsrc/src/dctool/elmentry.h
@@ -0,0 +1,20 @@
+/* elmentry.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_elmentry__
+#define __Header_elmentry__
+
+class ElementDictionaryTableEntry {
+public:
+	Uint16		Group;
+	Uint16		Element;
+	Uint16		PrivateBlock;	// 0x0010-0x00ff valid, 0x0000=inactive
+	const char *	ValueRepresentation;
+	Uint16		ValueMultiplicityMinimum;
+	Uint16		ValueMultiplicityMaximum;
+	const char *	Owner;
+	const char *	Keyword;
+	const char *	Description;
+	bool	Retired;
+	bool	RenderAsString;
+};
+
+#endif /* __Header_elmentry__ */
diff --git a/libsrc/src/dctool/elmhash.h b/libsrc/src/dctool/elmhash.h
new file mode 100644
index 0000000..7941e42
--- /dev/null
+++ b/libsrc/src/dctool/elmhash.h
@@ -0,0 +1,229 @@
+/* elmhash.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_ElmHash__
+#define __Header_ElmHash__
+
+#include "hash.h"
+#include "elmtype.h"
+
+// ********************* stuff for IndexByString *********************
+
+class IndexEntryString {
+	HashKeyString key;
+	unsigned long index;
+public:
+	IndexEntryString(void)		{}
+	IndexEntryString(const char *s,unsigned long i)
+					{ key=HashKeyString(s); index=i; }
+	IndexEntryString(IndexEntryString *e)
+					{ key=e->key; index=e->index; }
+
+	HashKeyString	getKey(void) const	{ return key; }
+	unsigned long	getIndex(void) const	{ return index; }
+
+	bool operator==(IndexEntryString e)
+					{ return key == e.getKey(); }
+};
+
+class IndexEntryStringList : public SimpleList<IndexEntryString>
+{
+public:
+	~IndexEntryStringList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class IndexEntryStringListIterator : public SimpleListIterator<IndexEntryString>
+{
+public:
+	IndexEntryStringListIterator(void)
+		: SimpleListIterator<IndexEntryString>() {}
+	IndexEntryStringListIterator(IndexEntryStringList& list)
+		: SimpleListIterator<IndexEntryString>(list) {}
+};
+
+class IndexByString : public OpenHashTable <IndexEntryString,
+					HashKeyString,
+					IndexEntryStringList,
+					IndexEntryStringListIterator>
+{
+public:
+	IndexByString(unsigned long size)
+		: OpenHashTable<IndexEntryString,
+				HashKeyString,
+				IndexEntryStringList,
+				IndexEntryStringListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long	hash(const HashKeyString &key,unsigned long size)
+		{
+			const unsigned nchars = 10;
+			const unsigned shift  = 4;
+
+			unsigned n=nchars;
+			unsigned long value=0;
+			const char *s=key.getString();
+			while (n-- && *s) {
+				value=(value<<shift)|*s++;
+			}
+			return value%size; 
+		}
+
+	HashKeyString key(const IndexEntryString &e)	{ return e.getKey(); }
+};
+
+// ********************* stuff for IndexByTag *********************
+
+class HashKeyTag {			// Use as class K
+	Tag tag;
+public:
+	HashKeyTag(void)		{ }
+	HashKeyTag(Tag t)		{ tag=t; }
+
+	Tag getTag(void) const		{ return tag; }
+
+	bool operator==(HashKeyTag k)	{ return tag == k.getTag(); }
+};
+
+class IndexEntryTag {
+	HashKeyTag key;
+	unsigned long index;
+public:
+	IndexEntryTag(void)		{}
+	IndexEntryTag(Tag t,unsigned long i)
+					{ key=HashKeyTag(t); index=i; }
+	IndexEntryTag(IndexEntryTag *e)	{ key=e->key; index=e->index; }
+
+	HashKeyTag	getKey(void) const	{ return key; }
+	unsigned long	getIndex(void) const	{ return index; }
+
+	bool operator==(IndexEntryTag e)
+					{ return key == e.getKey(); }
+};
+
+class IndexEntryTagList : public SimpleList<IndexEntryTag>
+{
+public:
+	~IndexEntryTagList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class IndexEntryTagListIterator : public SimpleListIterator<IndexEntryTag>
+{
+public:
+	IndexEntryTagListIterator(void)
+		: SimpleListIterator<IndexEntryTag>() {}
+	IndexEntryTagListIterator(IndexEntryTagList& list)
+		: SimpleListIterator<IndexEntryTag>(list) {}
+};
+
+class IndexByTag : public OpenHashTable <IndexEntryTag,
+					HashKeyTag,
+					IndexEntryTagList,
+					IndexEntryTagListIterator>
+{
+public:
+	IndexByTag(unsigned long size)
+		: OpenHashTable<IndexEntryTag,
+				HashKeyTag,
+				IndexEntryTagList,
+				IndexEntryTagListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long	hash(const HashKeyTag &key,unsigned long size)
+		{
+			const unsigned shift  = 4;
+
+			unsigned short group   = key.getTag().getGroup();
+			unsigned short element = key.getTag().getElement();
+
+			unsigned long value = (group<<shift)|element;
+			return value%size; 
+		}
+
+	HashKeyTag key(const IndexEntryTag &e)	{ return e.getKey(); }
+};
+
+// ********************* stuff for IndexByTagAndOwnerAndBlock *********************
+
+class IndexEntryTagAndOwnerAndBlock {
+	TagAndOwnerAndBlock key;
+	unsigned long index;
+public:
+	IndexEntryTagAndOwnerAndBlock(void)		{}
+	IndexEntryTagAndOwnerAndBlock(TagAndOwnerAndBlock to,unsigned long i)
+			{ key=to; index=i; }
+	IndexEntryTagAndOwnerAndBlock(IndexEntryTagAndOwnerAndBlock *e)
+			{ key=e->getKey(); index=e->getIndex(); }
+
+	TagAndOwnerAndBlock	getKey(void) const	{ return key; }
+	unsigned long		getIndex(void) const	{ return index; }
+
+	bool operator==(IndexEntryTagAndOwnerAndBlock& e) const
+					{ return key == e.getKey(); }
+};
+
+class IndexEntryTagAndOwnerAndBlockList : public SimpleList<IndexEntryTagAndOwnerAndBlock>
+{
+public:
+	~IndexEntryTagAndOwnerAndBlockList() {}	// only because buggy g++ 2.7.0 freaks
+};
+
+class IndexEntryTagAndOwnerAndBlockListIterator : public SimpleListIterator<IndexEntryTagAndOwnerAndBlock>
+{
+public:
+	IndexEntryTagAndOwnerAndBlockListIterator(void)
+		: SimpleListIterator<IndexEntryTagAndOwnerAndBlock>() {}
+	IndexEntryTagAndOwnerAndBlockListIterator(IndexEntryTagAndOwnerAndBlockList& list)
+		: SimpleListIterator<IndexEntryTagAndOwnerAndBlock>(list) {}
+};
+
+class IndexByTagAndOwnerAndBlock : public OpenHashTable <IndexEntryTagAndOwnerAndBlock,
+					TagAndOwnerAndBlock,
+					IndexEntryTagAndOwnerAndBlockList,
+					IndexEntryTagAndOwnerAndBlockListIterator>
+{
+public:
+	IndexByTagAndOwnerAndBlock(unsigned long size)
+		: OpenHashTable<IndexEntryTagAndOwnerAndBlock,
+				TagAndOwnerAndBlock,
+				IndexEntryTagAndOwnerAndBlockList,
+				IndexEntryTagAndOwnerAndBlockListIterator>(size)
+		{}
+
+	// supply virtual functions for OpenHashTable ...
+
+	unsigned long	hash(const TagAndOwnerAndBlock &key,unsigned long size)
+		{
+			const unsigned shiftt  = 4;
+
+			unsigned short group   = key.getTag().getGroup();
+			unsigned short element = key.getTag().getElement();
+
+			unsigned long valuet = (group<<shiftt)|element;
+
+			const unsigned nchars = 10;
+			const unsigned shifts  = 4;
+
+			unsigned n=nchars;
+			unsigned long values=0;
+			const char *s=key.getOwner();
+
+			if (s) {
+				while (n-- && *s) {
+					values=(values<<shifts)|*s++;
+				}
+			}
+			return (valuet+values+key.getBlock())%size; 
+		}
+
+	TagAndOwnerAndBlock key(const IndexEntryTagAndOwnerAndBlock &e)
+		{
+			// Split these up because behaved wierdly with SC 4.0 (zeroed out Tag) :(
+			TagAndOwnerAndBlock k=e.getKey();
+			return k;
+		}
+};
+
+#endif /* __Header_ElmHash__ */
+
diff --git a/libsrc/src/dctool/elmpriv.cc b/libsrc/src/dctool/elmpriv.cc
new file mode 100644
index 0000000..186a1d9
--- /dev/null
+++ b/libsrc/src/dctool/elmpriv.cc
@@ -0,0 +1,31 @@
+static const char *CopyrightIdentifier(void) { return "@(#)elmpriv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "elmtype.h"
+#include "elmpriv.h"
+
+const char *
+PrivateOwners::operator[](Tag tag)
+{
+	SimpleListIterator<TagAndOwnerAndBlock *> i(*this);
+	while (!i) {
+		// ignore the block
+		if (tag.getGroup() == i()->getTag().getGroup()
+		&& (tag.getElement()&0xff00)
+			== i()->getTag().getElement()
+				) return i()->getOwner();
+		++i;
+	}
+	return 0;
+}
+
+void
+PrivateOwners::operator+=(const TagAndOwnerAndBlock &to)
+{
+	// elements      0x0010-0x00ff
+	// define blocks 0x1000-0xff00
+
+	const char *owner = to.getOwner();
+	Assert(owner);
+	SimpleList<TagAndOwnerAndBlock *>::operator+=(new TagAndOwnerAndBlock(
+		Tag(to.getTag().getGroup(),to.getTag().getElement()<<8),
+		owner,0)); // ignore the block field
+}
diff --git a/libsrc/src/dctool/elmpriv.h b/libsrc/src/dctool/elmpriv.h
new file mode 100644
index 0000000..f880d95
--- /dev/null
+++ b/libsrc/src/dctool/elmpriv.h
@@ -0,0 +1,17 @@
+/* elmpriv.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_elmpriv__
+#define __Header_elmpriv__
+
+#include "listsimp.h"
+
+class PrivateOwners : public SimpleList<TagAndOwnerAndBlock *> {
+public:
+	PrivateOwners(void) : SimpleList<TagAndOwnerAndBlock *>() {}
+	~PrivateOwners() {}
+
+	const char *	operator[](Tag tag);
+
+	void	operator+=(const TagAndOwnerAndBlock& to);
+};
+
+#endif /* __Header_elmpriv__ */
diff --git a/libsrc/src/dctool/elmtype.h b/libsrc/src/dctool/elmtype.h
new file mode 100644
index 0000000..ac6b8d1
--- /dev/null
+++ b/libsrc/src/dctool/elmtype.h
@@ -0,0 +1,65 @@
+/* elmtype.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_elmtype__
+#define __Header_elmtype__
+
+#include "attrtag.h"
+
+const Uint16 VMUNLIMITED = (Uint16)-1;
+const Uint16 VMNONE = 0;
+
+#define DATADICTIONARYINDEXSIZE	791
+
+class TagAndOwnerAndBlock {
+	Tag tag;
+	char *owner;
+	Uint16 block;
+	TagAndOwnerAndBlock& constructor(Tag t,const char *o,Uint16 b)
+		{
+			tag=t;
+			Assert(o);
+			owner=new char[strlen(o)+1];
+			strcpy(owner,o);
+			block=b;
+			return *this;
+		}
+public:
+	TagAndOwnerAndBlock(void)			{}
+	TagAndOwnerAndBlock(Tag t,const char *o,Uint16 b)
+		{
+			constructor(t,o,b);
+		}
+	TagAndOwnerAndBlock(const TagAndOwnerAndBlock &to)
+		{
+			constructor(to.getTag(),to.getOwner(),to.getBlock());
+		}
+	TagAndOwnerAndBlock& operator=(const TagAndOwnerAndBlock &to)
+		{
+			return constructor(to.getTag(),to.getOwner(),to.getBlock());
+		}
+	~TagAndOwnerAndBlock()
+		{
+			Assert(owner);
+			delete[] owner;
+		}
+
+	Tag		getTag(void)   const	{ return tag; }
+	const char *	getOwner(void) const	{ return owner; }
+	Uint16		getBlock(void) const	{ return block; }
+
+	bool operator==(const TagAndOwnerAndBlock& to) const
+		{
+//if (tag == to.getTag() && owner && to.getOwner() && block == to.getBlock()) {
+//	cerr	<< "TagAndOwnerAndBlock: operator==(): comparing <"
+//		<< (owner ? owner : "-null-") << "> with <"
+//		<< (to.getOwner() ? to.getOwner() : "-null-") << "> returns "
+//		<< (strcmp(owner,to.getOwner()) ? "not equal" : "equal")
+//		<< endl;
+//}
+			return tag == to.getTag()
+			    && owner && to.getOwner()
+			    && strcmp(owner,to.getOwner()) == 0
+			    && block == to.getBlock();
+		}
+};
+
+#endif /* __Header_elmtype__ */
diff --git a/libsrc/src/dctool/ie.cc b/libsrc/src/dctool/ie.cc
new file mode 100644
index 0000000..9d1328b
--- /dev/null
+++ b/libsrc/src/dctool/ie.cc
@@ -0,0 +1,61 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ie.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "ie.h"
+
+InformationEntity
+getInformationEntityFromDescription(const char *d) {
+	InformationEntity ie = UnknownIE;
+	if (d) {
+		if      (strcmp(d,"Directory") == 0)				ie = DirectoryIE;
+		else if (strcmp(d,"Document") == 0)					ie = DocumentIE;
+		else if (strcmp(d,"EncapsulatedDocument") == 0)		ie = EncapsulatedDocumentIE;
+		else if (strcmp(d,"Equipment") == 0)				ie = EquipmentIE;
+		else if (strcmp(d,"File") == 0)						ie = FileIE;
+		else if (strcmp(d,"FrameOfReference") == 0)			ie = FrameOfReferenceIE;
+		else if (strcmp(d,"HangingProtocol") == 0)			ie = HangingProtocolIE;
+		else if (strcmp(d,"Image") == 0)					ie = ImageIE;
+		else if (strcmp(d,"MRSpectroscopy") == 0)			ie = MRSpectroscopyIE;
+		else if (strcmp(d,"Patient") == 0)					ie = PatientIE;
+		else if (strcmp(d,"Plan") == 0)						ie = PlanIE;
+		else if (strcmp(d,"Presentation") == 0)				ie = PresentationIE;
+		else if (strcmp(d,"RawData") == 0)					ie = RawDataIE;
+		else if (strcmp(d,"RealWorldValueMapping") == 0)	ie = RealWorldValueMappingIE;
+		else if (strcmp(d,"Series") == 0)					ie = SeriesIE;
+		else if (strcmp(d,"SpatialFiducials") == 0)			ie = SpatialFiducialsIE;
+		else if (strcmp(d,"SpatialRegistration") == 0)		ie = SpatialRegistrationIE;
+		else if (strcmp(d,"StructureSet") == 0)				ie = StructureSetIE;
+		else if (strcmp(d,"Study") == 0)					ie = StudyIE;
+		else if (strcmp(d,"TreatmentRecord") == 0)			ie = TreatmentRecordIE;
+		else if (strcmp(d,"Waveform") == 0)					ie = WaveformIE;
+	}
+	return ie;
+}
+
+const char *
+describeInformationEntity(InformationEntity ie) {
+	const char *d = "Unknown";
+	if      (ie == DirectoryIE)				d = "Directory";
+	else if (ie == DocumentIE)				d = "Document";
+	else if (ie == EncapsulatedDocumentIE)	d = "EncapsulatedDocument";
+	else if (ie == EquipmentIE)				d = "Equipment";
+	else if (ie == FileIE)					d = "File";
+	else if (ie == FrameOfReferenceIE)		d = "FrameOfReference";
+	else if (ie == HangingProtocolIE)		d = "HangingProtocol";
+	else if (ie == ImageIE)					d = "Image";
+	else if (ie == MRSpectroscopyIE)		d = "MRSpectroscopy";
+	else if (ie == PatientIE)				d = "Patient";
+	else if (ie == PlanIE)					d = "Plan";
+	else if (ie == PresentationIE)			d = "Presentation";
+	else if (ie == RawDataIE)				d = "RawData";
+	else if (ie == RealWorldValueMappingIE)	d = "RealWorldValueMapping";
+	else if (ie == SeriesIE)				d = "Series";
+	else if (ie == SpatialFiducialsIE)		d = "SpatialFiducials";
+	else if (ie == SpatialRegistrationIE)	d = "SpatialRegistration";
+	else if (ie == StructureSetIE)			d = "StructureSet";
+	else if (ie == StudyIE)					d = "Study";
+	else if (ie == TreatmentRecordIE)		d = "TreatmentRecord";
+	else if (ie == WaveformIE)				d = "Waveform";
+	return d;
+}
+
+
diff --git a/libsrc/src/dctool/iodcompb.cc b/libsrc/src/dctool/iodcompb.cc
new file mode 100644
index 0000000..8da6b47
--- /dev/null
+++ b/libsrc/src/dctool/iodcompb.cc
@@ -0,0 +1,14 @@
+static const char *CopyrightIdentifier(void) { return "@(#)iodcompb.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+
+#include "module.h"
+#include "modulec.h"
+
+#include "condnc.h"
+
+#include "iodcomp.h"
+#include "iodcompc.h"
+
+#include "iodcompb.h"
+
diff --git a/libsrc/src/dctool/iodcomps.cc b/libsrc/src/dctool/iodcomps.cc
new file mode 100644
index 0000000..00f29ba
--- /dev/null
+++ b/libsrc/src/dctool/iodcomps.cc
@@ -0,0 +1,14 @@
+static const char *CopyrightIdentifier(void) { return "@(#)iodcomps.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+
+#include "module.h"
+#include "modulec.h"
+
+#include "condnc.h"
+
+#include "iodcomp.h"
+#include "iodcompc.h"
+
+#include "iodcomps.h"
+
diff --git a/libsrc/src/dctool/iodcompv.cc b/libsrc/src/dctool/iodcompv.cc
new file mode 100644
index 0000000..4f6ae48
--- /dev/null
+++ b/libsrc/src/dctool/iodcompv.cc
@@ -0,0 +1,17 @@
+static const char *CopyrightIdentifier(void) { return "@(#)iodcompv.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "elmdict.h"
+#include "binvalc.h"
+#include "strvalc.h"
+#include "condnc.h"
+#include "mesgtext.h"
+
+#include "module.h"
+#include "modulec.h"
+
+#include "iodcomp.h"
+#include "iodcompc.h"
+
+#include "iodcompv.h"
+
diff --git a/libsrc/src/dctool/iodcompw.cc b/libsrc/src/dctool/iodcompw.cc
new file mode 100644
index 0000000..cee9c3d
--- /dev/null
+++ b/libsrc/src/dctool/iodcompw.cc
@@ -0,0 +1,12 @@
+static const char *CopyrightIdentifier(void) { return "@(#)iodcompw.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+
+#include "module.h"
+#include "modulec.h"
+
+#include "iodcomp.h"
+#include "iodcompc.h"
+
+#include "iodcompw.h"
+
diff --git a/libsrc/src/dctool/moduleb.cc b/libsrc/src/dctool/moduleb.cc
new file mode 100644
index 0000000..a8a85cd
--- /dev/null
+++ b/libsrc/src/dctool/moduleb.cc
@@ -0,0 +1,10 @@
+static const char *CopyrightIdentifier(void) { return "@(#)moduleb.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "elmconst.h"
+
+#include "module.h"
+#include "modulec.h"
+
+#include "moduleb.h"
+
diff --git a/libsrc/src/dctool/modulev.cc b/libsrc/src/dctool/modulev.cc
new file mode 100644
index 0000000..9c0837f
--- /dev/null
+++ b/libsrc/src/dctool/modulev.cc
@@ -0,0 +1,372 @@
+static const char *CopyrightIdentifier(void) { return "@(#)modulev.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "attrval.h"
+#include "elmdict.h"
+#include "elmconst.h"
+#include "elmtype.h"
+#include "binvalc.h"
+#include "strvalc.h"
+#include "tagvalc.h"
+#include "condnc.h"
+#include "mesgtext.h"
+
+#include "module.h"
+
+#include "modulec.h"
+
+static void
+LogElementAndModule(const char *module,const char *element,
+		TextOutputStream& log)
+{
+	if (element) log << " " << MMsgDC(Element) << "=<" << element << ">";
+	if (module)  log << " " << MMsgDC(Module)  << "=<" << module  << ">";
+}
+
+static void
+ViolationMessage(const char *error,const char *elementtype,
+		const char *module,const char *element,
+		TextOutputStream& log,bool verbose)
+{
+	(void)verbose;
+	log << EMsgDC(Null) << error << " " << elementtype;
+	LogElementAndModule(module,element,log);
+	log << endl;
+}
+
+static void
+WarningMessage(const char *error,const char *elementtype,
+		const char *module,const char *element,
+		TextOutputStream& log,bool verbose)
+{
+	(void)verbose;
+	log << WMsgDC(Null) << error << " " << elementtype;
+	LogElementAndModule(module,element,log);
+	log << endl;
+}
+
+static void
+ValidMessage(const char *elementtype,
+		const char *module,const char *element,
+		TextOutputStream& log,bool verbose)
+{
+	if (verbose) {
+		log << MMsgDC(ValidElement) << " - " << elementtype;
+		LogElementAndModule(module,element,log);
+		log << endl;
+	}
+}
+
+static bool
+verifyRequired(Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+	// Normalized Required Data Element
+
+	const char *reason=0;
+	if (attr) {
+		if (attr->getVL() == 0) {
+			reason=MMsgDC(EmptyAttribute);
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+				}
+			}
+		}
+	}
+	else {
+		reason=MMsgDC(MissingAttribute);
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(NormalizedRequired),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(NormalizedRequired),module,element,log,verbose);
+
+	return !reason;
+}
+
+static bool
+verifyType1 (Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+	// Type 1 - Required Data Element
+
+	const char *reason=0;
+	if (attr) {
+		if (attr->isEmptyOrHasAllEmptyValues()) {
+			reason=MMsgDC(EmptyAttribute);
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+				}
+			}
+		}
+	}
+	else {
+		reason=MMsgDC(MissingAttribute);
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(Type1),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(Type1),module,element,log,verbose);
+
+	return !reason;
+}
+
+static bool
+verifyType1C(Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	bool (*condition)(AttributeList *,AttributeList *,AttributeList *),
+	bool mbpo,
+	AttributeList *list,
+	AttributeList *parentlist,
+	AttributeList *rootlist,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+//cerr << "verifyType1C(): " << element << endl;
+	// Type 1C - Conditional Data Element
+
+	Assert(list);
+
+	const char *reason=0;
+	if (attr) {
+//cerr << "verifyType1C(): " << element << " is present" << endl;
+		bool conditionNotSatisfied = false;
+		if (condition && !(*condition)(list,parentlist,rootlist)) {
+			conditionNotSatisfied=true;
+			if (!mbpo) {
+				ViolationMessage(MMsgDC(AttributePresentWhenConditionUnsatisfiedWithoutMayBePresentOtherwise),
+					MMsgDC(Type1C),module,element,log,verbose);
+			}
+		}
+//cerr << "verifyType1C(): " << element << " conditionNotSatisfied = " << conditionNotSatisfied << endl;
+//cerr << "verifyType1C(): " << element << " VL = " << attr->getVL() << endl;
+//cerr << "verifyType1C(): " << element << " VM = " << attr->getVM() << endl;
+//cerr << "verifyType1C(): " << element << " isEmpty() = " << attr->isEmpty() << endl;
+//cerr << "verifyType1C(): " << element << " isEmptyOrHasAllEmptyValues() = " << attr->isEmptyOrHasAllEmptyValues() << endl;
+		if (attr->isEmptyOrHasAllEmptyValues()) {
+			reason= conditionNotSatisfied ? MMsgDC(EmptyAttributeWhenConditionUnsatisfied) : MMsgDC(EmptyAttribute);
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+					attr=0;
+				}
+			}
+		}
+	}
+	else {
+		if (condition && (*condition)(list,parentlist,rootlist))
+			reason=MMsgDC(MissingAttribute);
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(Type1C),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(Type1C),module,element,log,verbose);
+
+	return !reason;
+}
+
+static bool
+verifyType2 (Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+	// Type 2 - Required Data Element (May be Empty)
+
+	const char *reason=0;
+	if (attr) {
+		if (attr->getVL() == 0) {
+			// may be empty
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+				}
+			}
+		}
+	}
+	else {
+		reason=MMsgDC(MissingAttribute);
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(Type2),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(Type2),module,element,log,verbose);
+
+	return !reason;
+}
+
+static bool
+verifyType2C(Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	bool (*condition)(AttributeList *,AttributeList *,AttributeList *),
+	bool mbpo,
+	AttributeList *list,
+	AttributeList *parentlist,
+	AttributeList *rootlist,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+	// Type 2C - Conditional Data Element (May be Empty)
+
+	Assert(list);
+
+	const char *reason=0;
+	if (attr) {
+		if (condition && !(*condition)(list,parentlist,rootlist)) {
+			if (!mbpo) {
+				ViolationMessage(MMsgDC(AttributePresentWhenConditionUnsatisfiedWithoutMayBePresentOtherwise),
+					MMsgDC(Type2C),module,element,log,verbose);
+			}
+		}
+		if (attr->getVL() == 0) {
+			// may be empty
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+				}
+			}
+		}
+	}
+	else {
+		if (condition && (*condition)(list,parentlist,rootlist))
+			reason=MMsgDC(MissingAttribute);
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(Type2C),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(Type2C),module,element,log,verbose);
+
+	return !reason;
+}
+
+static bool
+verifyType3 (Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+	// Type 3 - Optional Data Element
+
+	const char *reason=0;
+	if (attr) {
+		if (attr->getVL() == 0) {
+			// may be empty
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+				}
+			}
+		}
+	}
+	else {
+		// May be absent
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(Type3),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(Type3),module,element,log,verbose);
+
+	return !reason;
+}
+
+static bool
+verifyType3C(Attribute *attr,
+	const char *module,const char *element,
+	bool verbose,TextOutputStream& log,
+	ElementDictionary *dict,
+	bool (*condition)(AttributeList *,AttributeList *,AttributeList *),
+	// mbpo never applies
+	AttributeList *list,
+	AttributeList *parentlist,
+	AttributeList *rootlist,
+	Uint16 multiplicityMin,Uint16 multiplicityMax)
+{
+	// Type 3C - Optional Data Element that can only be present when condition is true
+
+	Assert(list);
+
+	const char *reason=0;
+	if (attr) {
+		if (condition && !(*condition)(list,parentlist,rootlist)) {
+			WarningMessage(MMsgDC(Unexpected),
+				MMsgDC(Type3C),module,element,log,verbose);
+		}
+		if (attr->getVL() == 0) {
+			// may be empty
+		}
+		else {
+			if (!attr->verifyVR(module,element,log,dict)) {
+				reason=MMsgDC(BadValueRepresentation);
+			}
+			else {
+				if (!attr->verifyVM(module,element,log,dict,multiplicityMin,multiplicityMax)) {
+					reason=MMsgDC(BadAttributeValueMultiplicity);
+					attr=0;
+				}
+			}
+		}
+	}
+	else {
+		// May be absent
+	}
+
+	if (reason)
+		ViolationMessage(reason,MMsgDC(Type3C),module,element,log,verbose);
+	else if (attr)
+		ValidMessage(MMsgDC(Type3C),module,element,log,verbose);
+
+	return !reason;
+}
+
+#include "modulev.h"
+
+
+
diff --git a/libsrc/src/dctool/modulew.cc b/libsrc/src/dctool/modulew.cc
new file mode 100644
index 0000000..c8ca6d5
--- /dev/null
+++ b/libsrc/src/dctool/modulew.cc
@@ -0,0 +1,9 @@
+static const char *CopyrightIdentifier(void) { return "@(#)modulew.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "elmconst.h"
+#include "module.h"
+#include "modulec.h"
+
+#include "modulew.h"
+
diff --git a/libsrc/src/dctool/pixposn.cc b/libsrc/src/dctool/pixposn.cc
new file mode 100644
index 0000000..0a7ba30
--- /dev/null
+++ b/libsrc/src/dctool/pixposn.cc
@@ -0,0 +1,139 @@
+static const char *CopyrightIdentifier(void) { return "@(#)pixposn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "attr.h"
+#include "attrlist.h"
+#include "elmdict.h"
+#include "attrval.h"
+#include "elmconst.h"
+#include "mesgtext.h"
+
+#include "pixposn.h"
+
+PositionOfPixel::PositionOfPixel(AttributeList &list,TextOutputStream &log,bool verbose)
+{
+	// if ! verbose and no relevant attributes at all, then doesn't complain
+
+	logp=&log;
+
+	havePixelSpacing=false;
+	aPixelSpacing = list[TagFromName(PixelSpacing)];
+	if (aPixelSpacing) {
+		switch(aPixelSpacing->getVM()) {
+		case 1:
+			(*logp) << WMsgDC(OnlyOnePixelSpacingValue)
+		 	    << endl;
+			aPixelSpacing->getValue(0,vPixelSpacingRow);
+			vPixelSpacingCol=vPixelSpacingRow;
+//(*logp) << "vPixelSpacing both=" << vPixelSpacingCol << endl;
+			havePixelSpacing=true;
+			break;
+		case 2:
+			aPixelSpacing->getValue(0,vPixelSpacingRow);
+			aPixelSpacing->getValue(1,vPixelSpacingCol);
+//(*logp) << "vPixelSpacingRow=" << vPixelSpacingRow << endl;
+//(*logp) << "vPixelSpacingCol=" << vPixelSpacingCol << endl;
+			havePixelSpacing=true;
+			break;
+		default:
+			(*logp) << EMsgDC(BadAttributeValueMultiplicity)
+			    << " - \"PixelSpacing\""
+			    << endl;
+			break;
+		}
+	}
+
+	haveImagePositionPatient=false;
+	aImagePositionPatient = list[TagFromName(ImagePositionPatient)];
+	if (aImagePositionPatient) {
+		if (aImagePositionPatient->getVM() == 3) {
+			aImagePositionPatient->getValue(0,vImagePositionPatientX);
+			aImagePositionPatient->getValue(1,vImagePositionPatientY);
+			aImagePositionPatient->getValue(2,vImagePositionPatientZ);
+			haveImagePositionPatient=true;
+//(*logp) << "vImagePositionPatientX=" << vImagePositionPatientX << endl;
+//(*logp) << "vImagePositionPatientY=" << vImagePositionPatientY << endl;
+//(*logp) << "vImagePositionPatientZ=" << vImagePositionPatientZ << endl;
+		}
+		else {
+			(*logp) << EMsgDC(BadAttributeValueMultiplicity)
+			    << " - \"ImagePositionPatient\""
+			    << endl;
+		}
+	}
+
+	haveImageOrientationPatient=false;
+	aImageOrientationPatient = list[TagFromName(ImageOrientationPatient)];
+	if (aImageOrientationPatient) {
+		if (aImageOrientationPatient->getVM() == 6) {
+			aImageOrientationPatient->getValue(0,vImageOrientationPatientRowX);
+			aImageOrientationPatient->getValue(1,vImageOrientationPatientRowY);
+			aImageOrientationPatient->getValue(2,vImageOrientationPatientRowZ);
+			aImageOrientationPatient->getValue(3,vImageOrientationPatientColX);
+			aImageOrientationPatient->getValue(4,vImageOrientationPatientColY);
+			aImageOrientationPatient->getValue(5,vImageOrientationPatientColZ);
+//(*logp) << "vImageOrientationPatientRowX=" << vImageOrientationPatientRowX << endl;
+//(*logp) << "vImageOrientationPatientRowY=" << vImageOrientationPatientRowY << endl;
+//(*logp) << "vImageOrientationPatientRowZ=" << vImageOrientationPatientRowZ << endl;
+//(*logp) << "vImageOrientationPatientColX=" << vImageOrientationPatientColX << endl;
+//(*logp) << "vImageOrientationPatientColY=" << vImageOrientationPatientColY << endl;
+//(*logp) << "vImageOrientationPatientColZ=" << vImageOrientationPatientColZ << endl;
+			haveImageOrientationPatient=true;
+		}
+		else {
+			(*logp) << EMsgDC(BadAttributeValueMultiplicity)
+			    << " - \"ImageOrientationPatient\""
+			    << endl;
+		}
+	}
+
+	if (!(haveImageOrientationPatient && haveImagePositionPatient && havePixelSpacing)) {
+		// Report limited subset of missing attributes ...
+		if (verbose || aImagePositionPatient || aImageOrientationPatient) {
+			(*logp) << EMsgDC(InsufficientInformationToCalculatePosition) << endl;
+			if (!aPixelSpacing)
+				(*logp) << EMsgDC(MissingAttribute) << " - \"PixelSpacing\"" << endl;
+			if (!aImagePositionPatient)
+				(*logp) << EMsgDC(MissingAttribute) << " - \"ImagePositionPatient\"" << endl;
+			if (!aImageOrientationPatient)
+				(*logp) << EMsgDC(MissingAttribute) << " - \"ImageOrientationPatient\"" << endl;
+		}
+	}
+}
+
+bool
+PositionOfPixel::good()
+{
+	return haveImageOrientationPatient && haveImagePositionPatient && havePixelSpacing;
+}
+
+bool
+PositionOfPixel::getPosition(Uint16 row,Uint16 col,Float64 &x,Float64 &y,Float64 &z)
+{
+	if (haveImageOrientationPatient && haveImagePositionPatient && havePixelSpacing) {
+		// row/col are pixels from TLHC along rows/cols respectively
+		// PixelSpacing Row/Col is space BETWEEN rows/cols respectively
+		// ImageOrientationPatient Row/Col are unit vectors ALONG rows/cols respectively
+		// - hence row pixels of size PixelSpacingRow along ImageOrientationPatientCol
+
+		// Add 0.5 because assume position is that of center of pixel
+
+		x=vImagePositionPatientX
+		 +vImageOrientationPatientColX*(row+0.5)*vPixelSpacingRow
+		 +vImageOrientationPatientRowX*(col+0.5)*vPixelSpacingCol;
+		y=vImagePositionPatientY
+		 +vImageOrientationPatientColY*(row+0.5)*vPixelSpacingRow
+		 +vImageOrientationPatientRowY*(col+0.5)*vPixelSpacingCol;
+		z=vImagePositionPatientZ
+		 +vImageOrientationPatientColZ*(row+0.5)*vPixelSpacingRow
+		 +vImageOrientationPatientRowZ*(col+0.5)*vPixelSpacingCol;
+
+		return true;	
+	}
+	else {
+		// make return values ridiculous in case anyone uses them
+		x=-99999999.99999;
+		y=-99999999.99999;
+		z=-99999999.99999;
+		return false;
+	}
+}
+
diff --git a/libsrc/src/dctool/sopclc.cc b/libsrc/src/dctool/sopclc.cc
new file mode 100644
index 0000000..952e825
--- /dev/null
+++ b/libsrc/src/dctool/sopclc.cc
@@ -0,0 +1,3 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sopclc.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "sopclc.h"
+
diff --git a/libsrc/src/dctool/sopcle.h b/libsrc/src/dctool/sopcle.h
new file mode 100644
index 0000000..df87336
--- /dev/null
+++ b/libsrc/src/dctool/sopcle.h
@@ -0,0 +1,13 @@
+/* sopcle.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_sopcle__
+#define __Header_sopcle__
+
+class SOPClassTableEntry {
+public:
+	const char *	Name;
+	const char *	Description;
+	const char *	UID;
+	const char *	DirectoryRecordType;
+};
+
+#endif /* __Header_sopcle__ */
diff --git a/libsrc/src/dctool/sopcli.cc b/libsrc/src/dctool/sopcli.cc
new file mode 100644
index 0000000..2cb432a
--- /dev/null
+++ b/libsrc/src/dctool/sopcli.cc
@@ -0,0 +1,20 @@
+static const char *CopyrightIdentifier(void) { return "@(#)sopcli.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+
+#include "sopcle.h"
+#include "sopclt.h"
+#include "sopcli.h"
+
+const char *getDirectoryRecordTypeFromUID(const char *uid) {
+	Assert(uid);
+	SOPClassTableEntry *ptr = SOPClassTable;
+	while (ptr && ptr->UID) {
+		if (strcmp(ptr->UID,uid) == 0) {
+			return ptr->DirectoryRecordType;
+		}
+		++ptr;
+	}
+	return 0;
+}
+
+
diff --git a/libsrc/src/dctool/strval.cc b/libsrc/src/dctool/strval.cc
new file mode 100644
index 0000000..7f9395f
--- /dev/null
+++ b/libsrc/src/dctool/strval.cc
@@ -0,0 +1,31 @@
+static const char *CopyrightIdentifier(void) { return "@(#)strval.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include <string.h>
+
+#include "basetype.h"		// for strstream
+#include "strvalc.h"
+
+struct StringValueEntry {
+	const char *value;
+	const char *description;
+};
+
+static char *
+StringValueDescription(const struct StringValueEntry *table,const char * value)
+{
+	ostrstream ost;
+	const struct StringValueEntry *p;
+	for (p=table; p->value; ++p) {
+		if (strcmp(p->value,value) == 0) {
+			if (p->description && strlen(p->description) > 0) {
+				ost << p->description << '\0';
+			}
+			else {
+				ost << p->value << '\0';
+			}
+			return ost.str();
+		}
+	}
+	return 0;
+}
+
+#include "strvald.h"
diff --git a/libsrc/src/dctool/tagval.cc b/libsrc/src/dctool/tagval.cc
new file mode 100644
index 0000000..8e209d6
--- /dev/null
+++ b/libsrc/src/dctool/tagval.cc
@@ -0,0 +1,14 @@
+static const char *CopyrightIdentifier(void) { return "@(#)tagval.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iomanip>
+#else
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "tagvalc.h"
+#include "tagvald.h"
diff --git a/libsrc/src/dctool/transyn.cc b/libsrc/src/dctool/transyn.cc
new file mode 100644
index 0000000..076e771
--- /dev/null
+++ b/libsrc/src/dctool/transyn.cc
@@ -0,0 +1,70 @@
+static const char *CopyrightIdentifier(void) { return "@(#)transyn.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "transyn.h"
+#include "transynd.h"
+
+static TransferSyntaxDictionary tsd;
+
+TransferSyntax::TransferSyntax(const char *uid)
+{
+	Assert(uid);
+	const TransferSyntaxDictionaryEntry *e = tsd[uid];
+	if (e) {
+		UID=e->UID;
+		Description=e->Description;
+		endian=e->endian;
+		VRtype=e->VRtype;
+		encapsulated=e->encapsulated;
+		pixelendian=e->pixelendian;
+	}
+	else {
+		// Unrecognized transfer syntax, so assume EVRLE encapsulated, since that is what most new standard ones are
+		// Could attempt to "guess" using same logic as in dcstream.cc, but late at this point
+		UID=uid;
+		Description="Unrecognized transfer syntax";
+		endian=LittleEndian;
+		VRtype=ExplicitVR;
+		encapsulated=false;
+		pixelendian=LittleEndian;
+	}
+}
+
+TransferSyntax::TransferSyntax(VRType vr,Endian e,bool encap)
+{
+	VRtype=vr;
+	endian=e;
+	pixelendian=e;
+	encapsulated=encap;
+	Description=0;
+	UID=0;
+}
+
+bool
+TransferSyntax::operator==(const TransferSyntax& t2) const
+{
+//cerr << "TransferSyntax::operator==(const TransferSyntax& t2):" << endl;
+	if ((!getEncapsulated() && !t2.getEncapsulated())
+	  || !getUID() || !t2.getUID()) {
+//cerr << "TransferSyntax::operator== comparing components:" << endl;
+		return getEndian() == t2.getEndian()
+		    && getVR() == t2.getVR()
+		    && getPixelEndian() == t2.getPixelEndian()
+		    && !getEncapsulated()
+		    && !t2.getEncapsulated();
+	}
+	else {
+//cerr << "TransferSyntax::operator== comparing UID strings:" << endl;
+//cerr << "TransferSyntax::operator== string1 <" << getUID() << ">" << endl;
+//cerr << "TransferSyntax::operator== string2 <" << t2.getUID() << ">" << endl;
+		return strcmp(getUID(),t2.getUID()) == 0;
+	}
+}
diff --git a/libsrc/src/dctool/transync.cc b/libsrc/src/dctool/transync.cc
new file mode 100644
index 0000000..b192a54
--- /dev/null
+++ b/libsrc/src/dctool/transync.cc
@@ -0,0 +1,3 @@
+static const char *CopyrightIdentifier(void) { return "@(#)transync.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "transync.h"
+
diff --git a/libsrc/src/dctool/transynd.cc b/libsrc/src/dctool/transynd.cc
new file mode 100644
index 0000000..df77ec4
--- /dev/null
+++ b/libsrc/src/dctool/transynd.cc
@@ -0,0 +1,40 @@
+static const char *CopyrightIdentifier(void) { return "@(#)transynd.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "misctype.h"
+
+#include "transynd.h"
+#include "transynt.h"
+
+const TransferSyntaxDictionaryEntry *
+TransferSyntaxDictionary::operator[](const char *uid)
+{
+	TransferSyntaxDictionaryEntry *p = TransferSyntaxDictionaryTable;
+	while (p->UID) {
+		if (strcmp(p->UID,uid) == 0) return p;
+		++p;
+	}
+	return 0;
+}
+
+void
+TransferSyntaxDictionary::first(void)
+{
+	ptr=TransferSyntaxDictionaryTable;
+}
+
+int
+TransferSyntaxDictionary::ismore(void)
+{
+	return ptr->UID != 0;
+}
+
+void
+TransferSyntaxDictionary::next(void)
+{
+	++ptr;
+}
+
+const TransferSyntaxDictionaryEntry *
+TransferSyntaxDictionary::value(void)
+{
+	return ptr->UID ? ptr : 0;
+}
diff --git a/libsrc/src/dctool/transynd.h b/libsrc/src/dctool/transynd.h
new file mode 100644
index 0000000..db9e96f
--- /dev/null
+++ b/libsrc/src/dctool/transynd.h
@@ -0,0 +1,27 @@
+/* transynd.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_transynd__
+#define __Header_transynd__
+
+#include "transyne.h"
+
+class TransferSyntaxDictionary {
+	TransferSyntaxDictionaryEntry *ptr;
+public:
+	TransferSyntaxDictionary(void)	{ first(); }
+
+	const TransferSyntaxDictionaryEntry *operator[](const char *uid);
+
+	void first(void);
+	int ismore(void);
+	void next(void);
+	const TransferSyntaxDictionaryEntry *value(void);
+
+	int operator!()		{ return ismore(); }
+	void operator++()	{ next(); }		// prefix  ++i
+	void operator++(int)	{ next(); }		// postfix i++
+	const TransferSyntaxDictionaryEntry *
+		operator()()
+				{ return value(); }
+};
+
+#endif /* __Header_transynd__ */
diff --git a/libsrc/src/dctool/transyne.h b/libsrc/src/dctool/transyne.h
new file mode 100644
index 0000000..085d1b6
--- /dev/null
+++ b/libsrc/src/dctool/transyne.h
@@ -0,0 +1,14 @@
+/* transyne.h Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved. */
+#ifndef __Header_transyne__
+#define __Header_transyne__
+
+struct TransferSyntaxDictionaryEntry {
+	const char *	UID;
+	const char *	Description;
+	Endian 		endian;
+	VRType 		VRtype;
+	bool 		encapsulated;
+	Endian 		pixelendian;
+};
+
+#endif /* __Header_transyne__ */
diff --git a/libsrc/src/dctool/uidgen.cc b/libsrc/src/dctool/uidgen.cc
new file mode 100644
index 0000000..2f69700
--- /dev/null
+++ b/libsrc/src/dctool/uidgen.cc
@@ -0,0 +1,127 @@
+static const char *CopyrightIdentifier(void) { return "@(#)uidgen.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iomanip>
+#else
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "uidgen.h"
+
+#ifndef DEFAULTUIDROOT
+#define	DEFAULTUIDROOT		"0.0.0.0"
+#endif /* DEFAULTUIDROOT */
+
+#define	UIDGEN_INSTANCE_SOP		".1"
+#define	UIDGEN_INSTANCE_STUDY		".2"
+#define	UIDGEN_INSTANCE_SERIES		".3"
+#define	UIDGEN_FRAMEOFREFERENCE		".4"
+#define	UIDGEN_INSTANCE_DIR		".5"
+#define	UIDGEN_DIMENSIONORGANIZATION	".6"
+#define	UIDGEN_CONCATENATION		".7"
+#define	UIDGEN_SYNCFRAMEOFREFERENCE	".8"
+#define	UIDGEN_RAWDATA			".9"
+#define UIDGEN_IRRADIATIONEVENT	".10"
+
+void
+GeneratedUID::setSOPInstance()
+{
+	ost << UIDGEN_INSTANCE_SOP;
+}
+
+void
+GeneratedUID::setStudyInstance()
+{
+	ost << UIDGEN_INSTANCE_STUDY;
+}
+
+void
+GeneratedUID::setSeriesInstance()
+{
+	ost << UIDGEN_INSTANCE_SERIES;
+}
+
+void
+GeneratedUID::setFrameOfReference()
+{
+	ost << UIDGEN_FRAMEOFREFERENCE;
+}
+
+void
+GeneratedUID::setSynchronizationFrameOfReference()
+{
+	ost << UIDGEN_SYNCFRAMEOFREFERENCE;
+}
+
+void
+GeneratedUID::setDirInstance()
+{
+	ost << UIDGEN_INSTANCE_DIR;
+}
+
+void
+GeneratedUID::setDimensionOrganization()
+{
+	ost << UIDGEN_DIMENSIONORGANIZATION;
+}
+
+void
+GeneratedUID::setConcatenation()
+{
+	ost << UIDGEN_CONCATENATION;
+}
+
+void
+GeneratedUID::setIrradiationEvent()
+{
+	ost << UIDGEN_IRRADIATIONEVENT;
+}
+
+void
+GeneratedUID::setRawData()
+{
+	ost << UIDGEN_RAWDATA;
+}
+
+void GeneratedUID::setUnsigned(unsigned u)
+{
+	ost << "." << (u & 0xffff);		// masked, otherwise gives different results on 64 bit platforms when value is large
+}
+
+GeneratedUID::GeneratedUID(void)
+{
+	ost << DEFAULTUIDROOT;
+	stamp=0;
+	string=0;
+}
+
+GeneratedUID::GeneratedUID(const char *s)
+{
+	ost << DEFAULTUIDROOT;
+	stamp=s;
+	string=0;
+}
+
+GeneratedUID::~GeneratedUID()
+{
+	if (string) delete[] string;
+}
+
+GeneratedUID::operator char *(void)
+{
+	Assert(!string);
+
+	ost << ".";
+	if (stamp)
+		ost << stamp;
+	else
+		ost << (unsigned long)time(0) << "." << (unsigned long)getpid () << "." << (unsigned long)gethostid();
+	ost << ends;
+
+	return string=ost.str();
+}
+
diff --git a/libsrc/src/dculsp/dculsp.cc b/libsrc/src/dculsp/dculsp.cc
new file mode 100644
index 0000000..7a17fd3
--- /dev/null
+++ b/libsrc/src/dculsp/dculsp.cc
@@ -0,0 +1,119 @@
+static const char *CopyrightIdentifier(void) { return "@(#)dculsp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "dculsp.h"
+
+DICOMUpperLayerServiceRequestor::DICOMUpperLayerServiceRequestor(void);
+{
+	state=1;
+}
+
+virtual
+DICOMUpperLayerServiceRequestor::~DICOMUpperLayerServiceRequestor()
+{
+}
+
+void
+DICOMUpperLayerServiceRequestor::T_Connect_Confirm(void)
+{
+	Assert(state==4);
+
+	// used saved stuff from A_Associate_Request to build PDU
+
+	// this is only for TCP ... what would OSI do about PDU's ??
+
+	build the PDU
+
+	T_Data_Request(PDU);
+}
+
+void
+DICOMUpperLayerServiceRequestor::A_Associate_Request(
+	const char *acn,
+	const char *callingae,
+	const char *calledae,
+	UserInformationItem &uitem,
+	PresentationAddress &callingpa,
+	PresentationAddress &calledpa,
+	PresentationContextDefinitionList &pcdl)
+{
+	Assert(state==1);
+
+	// save stuff for T_Connect_Confirm callback to establish association
+
+	applicationcontextname=acn;
+	callingapplicationentitytitle=callingae;
+	calledapplicationentitytitle=calledae;
+	userinformationitem=&uitem;
+	callingpresentationaddress=&callingpa;
+	calledpresentationaddress=&calledpa;
+	presentationcontextdefinitionlist=&pcdl;
+
+	Assert(applicationcontextname && *applicationcontextname);
+	Assert(callingapplicationentitytitle && *callingapplicationentitytitle);
+	Assert(calledapplicationentitytitle && *calledapplicationentitytitle);
+
+	T_Connect_Request(callingpresentationaddress,calledpresentationaddress);
+}
+
+	virtual void A_Associate_Confirm	(const char *applicationcontextname,		// provider  to requestor
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 Uint16 result,
+						 Uint16 resultsource,
+						 Uint16 diagnostic,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlistresult
+						) = 0;
+
+	        void A_Release_Request		(Uint16 reason);				// requestor to provider
+
+	virtual void A_Release_Confirm	(Uint16 reason,Uint16 result) = 0;		// provider  to requestor
+
+	        void A_Abort_Request		(void);						// requestor to provider
+ 
+	virtual void A_P_Abort_Indication	(Uint16 reason) = 0;				// provider  to both
+
+	        void P_Data_Request		(PresentationDataValueList &data);		// requestor to provider
+ };
+
+class DICOMUpperLayerServiceAcceptor {
+public:
+	DICOMUpperLayerServiceAcceptor(void);
+
+virtual
+DICOMUpperLayerServiceAcceptor::~DICOMUpperLayerServiceRequestor()
+{
+	if (connection) delete connection;
+}
+
+	virtual void A_Associate_Indication	(const char *applicationcontextname,		// provider  to acceptor
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlist
+						) = 0;
+
+	        void A_Associate_Response	(const char *applicationcontextname,		// acceptor  to provider
+						 const char *callingapplicationentitytitle,
+						 const char *calledapplicationentitytitle,
+						 UserInformationItem &userinformationitem,
+						 Uint16 result,
+						 Uint16 diagnostic,
+						 PresentationAddress &callingpresentationaddress,
+						 PresentationAddress &calledpresentationaddress,
+						 PresentationContextDefinitionList &presentationcontextdefinitionlistresult
+						);
+
+	virtual void A_Release_Indication	(Uint16 reason) = 0;				// provider  to acceptor 
+	        void A_Release_Response		(Uint16 reason,Uint16 result);			// acceptor  to provider
+
+	virtual void A_Abort_Indication		(Uint16 source) = 0;				// provider  to acceptor
+ 
+	virtual void A_P_Abort_Indication	(Uint16 reason) = 0;				// provider  to both
+
+	virtual void P_Data_Indication		(PresentationDataValueList &data) = 0;		// provider  to acceptor
+ };
+
diff --git a/libsrc/src/generic/Imakefile b/libsrc/src/generic/Imakefile
new file mode 100755
index 0000000..18ef757
--- /dev/null
+++ b/libsrc/src/generic/Imakefile
@@ -0,0 +1,16 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBGENERICEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = getoptns.cc datetype.cc \
+                 bnopti.cc bnopto.cc ioopti.cc ioopto.cc \
+		 txstream.cc version.cc platform.cc
+
+OBJS =           getoptns.o  datetype.o  \
+                 bnopti.o  bnopto.o  ioopti.o  ioopto.o \
+		 txstream.o version.o platform.o
+
+
+LibraryTarget($(PROJECTLIBDIR)/lib$(PROJECTGENERICLIBNAME).a,$(OBJS))
+
+DependCCTarget()
diff --git a/libsrc/src/generic/bnopti.cc b/libsrc/src/generic/bnopti.cc
new file mode 100644
index 0000000..c244798
--- /dev/null
+++ b/libsrc/src/generic/bnopti.cc
@@ -0,0 +1,161 @@
+static const char *CopyrightIdentifier(void) { return "@(#)bnopti.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "endtype.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static const char *options_input_file[] = {
+	"if",
+	"input-file",
+	0
+};
+
+static const char *options_input_byteorder[] = {
+	"input-byteorder",
+	"input-endian",
+	0
+};
+
+BinaryInputOptions::BinaryInputOptions(GetNamedOptions &options)
+		: ErrorsInClass()
+{
+	filename=0;
+	options.get(options_input_file,filename);
+}
+
+BinaryInputOptionsWithByteOrder::BinaryInputOptionsWithByteOrder(
+		GetNamedOptions &options)
+	: BinaryInputOptions(options)
+{
+	byteorder=NoEndian;
+	const char *byteorderstring=0;
+	if (options.get(options_input_byteorder,byteorderstring)) {
+		if (strcmp(byteorderstring,"big") == 0)
+			byteorder=BigEndian;
+		else if (strcmp(byteorderstring,"little") == 0)
+			byteorder=LittleEndian;
+		else {
+			errorstream << EMsgDC(BadByteOrder) << endl;
+			good_flag=false;
+		}
+	}
+}
+
+char *
+BinaryInputOptions::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_input_file,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(InputFile) << "]";
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+char *
+BinaryInputOptionsWithByteOrder::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_input_byteorder,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " big|little]";
+
+	char *baseoptions = BinaryInputOptions::usage();
+
+	if (baseoptions) {
+		ostr << baseoptions;
+		delete[] baseoptions;
+	}
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+void
+BinaryInputOptions::done(void)
+{
+}
+
+// NB. What is the significance of fstr being deleted after
+// assignment to another stream ? Should the BinaryInputOpenerFromOptions
+// object be required to remain in scope as long as the
+// assigned to stream is still in use ??
+
+BinaryInputOpenerFromOptions::BinaryInputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename,
+		istream &cstr)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+
+	if (filename) {
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ifstream *fstr=new ifstream(filename,ios::in|ios::binary);
+#else
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		streambuf *sbuf  = cstr.rdbuf();
+		str=new istream(sbuf);
+		// default ANSI cin/cout is unbuffered, slow, so ...
+//		char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//		if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+		// this buffer will never be delete[]'d but doesn't
+		// matter ... how often would we be reusing cin/cout ?
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileReadOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+BinaryInputOpenerFromOptions::~BinaryInputOpenerFromOptions()
+{
+	if (str) delete str;
+}
+
+BinaryInputOpenerFromOptions::operator istream *(void)
+{
+	return str;
+}
+
diff --git a/libsrc/src/generic/bnopto.cc b/libsrc/src/generic/bnopto.cc
new file mode 100644
index 0000000..0aa76f0
--- /dev/null
+++ b/libsrc/src/generic/bnopto.cc
@@ -0,0 +1,159 @@
+static const char *CopyrightIdentifier(void) { return "@(#)bnopto.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "endtype.h"
+#include "bnopt.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static const char *options_output_file[] = {
+	"of",
+	"output-file",
+	0
+};
+
+static const char *options_output_byteorder[] = {
+	"byteorder",
+	"endian",
+	"output-byteorder",
+	"output-endian",
+	0
+};
+
+BinaryOutputOptions::BinaryOutputOptions(GetNamedOptions &options)
+		: ErrorsInClass()
+{
+	filename=0;
+	options.get(options_output_file,filename);
+}
+
+BinaryOutputOptionsWithByteOrder::BinaryOutputOptionsWithByteOrder(
+		GetNamedOptions &options)
+	: BinaryOutputOptions(options)
+{
+	byteorder=NoEndian;
+	const char *byteorderstring=0;
+	if (options.get(options_output_byteorder,byteorderstring)) {
+		if (strcmp(byteorderstring,"big") == 0)
+			byteorder=BigEndian;
+		else if (strcmp(byteorderstring,"little") == 0)
+			byteorder=LittleEndian;
+		else {
+			errorstream << EMsgDC(BadByteOrder) << endl;
+			good_flag=false;
+		}
+	}
+}
+
+char *
+BinaryOutputOptions::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_output_file,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(OutputFile) << "]";
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+char *
+BinaryOutputOptionsWithByteOrder::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_output_byteorder,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " big|little]";
+
+	char *baseoptions = BinaryOutputOptions::usage();
+
+	if (baseoptions) {
+		ostr << baseoptions;
+		delete[] baseoptions;
+	}
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+void
+BinaryOutputOptions::done(void)
+{
+}
+
+BinaryOutputOpenerFromOptions::BinaryOutputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename,
+		ostream &cstr)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+
+	if (filename) {
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+		ofstream *fstr=new ofstream(filename,
+			ios::out|ios::trunc|ios::binary);
+#else
+		ofstream *fstr=new ofstream(filename,ios::out|ios::trunc);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		streambuf *sbuf  = cstr.rdbuf();
+		str=new ostream(sbuf);
+		// default ANSI cin/cout is unbuffered, slow, so ...
+//		char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//		if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+		// this buffer will never be delete[]'d but doesn't
+		// matter ... how often would we be reusing cin/cout ?
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileWriteOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+BinaryOutputOpenerFromOptions::~BinaryOutputOpenerFromOptions()
+{
+	if (str) delete str;
+}
+
+BinaryOutputOpenerFromOptions::operator ostream *(void)
+{
+	return str;
+}
+
diff --git a/libsrc/src/generic/datetype.cc b/libsrc/src/generic/datetype.cc
new file mode 100644
index 0000000..f600c0a
--- /dev/null
+++ b/libsrc/src/generic/datetype.cc
@@ -0,0 +1,576 @@
+static const char *CopyrightIdentifier(void) { return "@(#)datetype.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <cctype>
+//#include <iostream>	// For debugging only
+#else
+#include <ctype.h>
+//#include <iostream.h>	// For debugging only
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "datetype.h"
+
+static bool
+isAllNumeric(const char *src,size_t length)
+{
+	while (length>0 && isdigit(*src))
+		{ --length; ++src; }
+	return (length == 0);
+}
+
+static bool
+isDateDelimeter(char c) { return c == '-' || c == '/' || c == '.'; }
+
+static bool
+isTimeDelimeter(char c) { return c == ':' || c == '.'; }
+
+static void
+skipDateDelimeter(const char *&src,size_t &length)
+{
+	if (length>0 && isDateDelimeter(*src))
+		{ --length; ++src; }
+}
+
+static void
+skipTimeDelimeter(const char *&src,size_t &length)
+{
+	if (length>0 && isTimeDelimeter(*src))
+		{ --length; ++src; }
+}
+
+static void
+skipSpaces(const char *&src,size_t &length)
+{
+	while (length>0 && isspace(*src))
+		{ --length; ++src; }
+}
+
+static bool
+extractDecimalLong(const char *&src,size_t &length,long &n)
+{
+	n=0;
+	if (length>0 && isdigit(*src)) {
+		do {
+			--length; n=n*10+(*src++-'0');
+		} while (length>0 && isdigit(*src));
+		return true;
+	}
+	else return false;
+}
+
+static bool
+extractDecimalShort(const char *&src,size_t &length,short &n)
+{
+	n=0;
+	if (length>0 && isdigit(*src)) {
+		do {
+			--length; n=n*10+(*src++-'0');
+		} while (length>0 && isdigit(*src));
+		return true;
+	}
+	else return false;
+}
+
+static bool
+extractDecimalShortFixedLength(const char *&src,size_t &length,size_t count,short &n)
+{
+	n=0;
+	if (count>0 && length>0 && isdigit(*src)) {
+		do {
+			--count; --length; n=n*10+(*src++-'0');
+		} while (count>0 && length>0 && isdigit(*src));
+		return count == 0;
+	}
+	else return false;
+}
+
+
+void
+Date::makeTimezoneOffset(long tm_gmtoff) {
+	int gmtoff=tm_gmtoff/60;	// convert from secs to minutes;
+	if (gmtoff < 0) {
+		tzo[0]='-';
+		gmtoff=-gmtoff;
+	}
+	else {
+		tzo[0]='-';
+	}
+	int gmtoff_mins=gmtoff%60;
+	int gmtoff_hrs=gmtoff/60;
+	static char decimal_digits[] = { '0','1','2','3','4','5','6','7','8','9' };
+	Assert(gmtoff_hrs <= 24);
+	tzo[1]=decimal_digits[gmtoff_hrs/10];
+	tzo[2]=decimal_digits[gmtoff_hrs%10];
+	Assert(gmtoff_mins <= 60);
+	tzo[3]=decimal_digits[gmtoff_mins/10];
+	tzo[4]=decimal_digits[gmtoff_mins%10];
+	tzo[5]=0;
+}
+
+char *
+Date::makeMMMFromMM(short m) const
+{
+	char *str=new char[4];
+	switch (m) {
+		case 1:	 strncpy(str,"Jan",3); break;
+		case 2:	 strncpy(str,"Feb",3); break;
+		case 3:	 strncpy(str,"Mar",3); break;
+		case 4:	 strncpy(str,"Apr",3); break;
+		case 5:	 strncpy(str,"May",3); break;
+		case 6:	 strncpy(str,"Jun",3); break;
+		case 7:	 strncpy(str,"Jul",3); break;
+		case 8:	 strncpy(str,"Aug",3); break;
+		case 9:	 strncpy(str,"Sep",3); break;
+		case 10: strncpy(str,"Oct",3); break;
+		case 11: strncpy(str,"Nov",3); break;
+		case 12: strncpy(str,"Dec",3); break;
+		default: strncpy(str,"bad",3); break;
+	}
+	str[3]=0;
+	return str;
+}
+
+bool
+Date::extractMMFromMMM(const char *&src,size_t &length,short &m) const
+{
+	bool ok=true;
+	m=0;
+	char mmm0=toupper(src[0]);
+	char mmm1=tolower(src[1]);
+	char mmm2=tolower(src[2]);
+	switch (mmm0) {
+		case 'A':
+			switch (mmm1) {
+				case 'p':	m=4; break;
+				case 'u':	m=8; break;
+			}
+			break;
+		case 'D':
+			m=12; break;
+		case 'F':
+			m=2; break;
+		case 'J':
+			switch (mmm1) {
+				case 'a':	m=1; break;
+				case 'u':
+					switch (mmm2) {
+						case 'l':
+							m=7;
+							break;
+						case 'n':
+							m=6;
+							break;
+					}
+					break;
+			}
+			break;
+		case 'M':
+			switch (mmm2) {
+				case 'r':	m=3; break;
+				case 'y':	m=5; break;
+			}
+			break;
+		case 'N':
+			m=11; break;
+		case 'O':
+			m=10; break;
+		case 'S':
+			m=9; break;
+		default:
+			m=0; ok=false; break;
+	}
+	length-=3;
+	src+=3;
+	return ok;
+}
+
+bool
+Date::getDatePossibilityFromString(
+	const char *&src,size_t &length,
+	short &value,int &value_ismmm) const
+{
+	if (length) {
+		if (isdigit(*src)) {
+			value_ismmm=0;
+			return extractDecimalShort(src,length,value);
+		}
+		else {
+			value_ismmm=1;
+			return extractMMFromMMM(src,length,value);
+		}
+	}
+	else return false;
+}
+
+bool
+Date::getDatePossibilitiesFromString(
+	const char *src,size_t length,
+	short &v1,int &v1_ismmm,
+	short &v2,int &v2_ismmm,
+	short &v3,int &v3_ismmm) const
+{
+//cerr << "getDatePossibilitiesFromString: string=" << (src ? src : "-zero length-") << endl;
+
+	skipSpaces(src,length);
+	if (!getDatePossibilityFromString(src,length,v1,v1_ismmm)) return false;
+//cerr << "getDatePossibilitiesFromString: v1=" << v1 << endl;
+	skipSpaces(src,length);
+	skipDateDelimeter(src,length);
+	skipSpaces(src,length);
+	if (!getDatePossibilityFromString(src,length,v2,v2_ismmm)) return false;
+//cerr << "getDatePossibilitiesFromString: v2=" << v2 << endl;
+	skipSpaces(src,length);
+	skipDateDelimeter(src,length);
+	skipSpaces(src,length);
+	if (!getDatePossibilityFromString(src,length,v3,v3_ismmm)) return false;
+//cerr << "getDatePossibilitiesFromString: v3=" << v3 << endl;
+	skipSpaces(src,length);
+
+//cerr << "getDatePossibilitiesFromString: v1=" << v1 << " v2=" << v2 << " v3=" << v3 << endl;
+
+	return	length == 0
+		&& v1 && v2 && v3
+		&& (v1_ismmm+v2_ismmm+v3_ismmm) <= 1;
+}
+
+bool
+Date::validateDateValues(short d,short m,short &y)
+{
+//cerr << "validateDateValues: y=" << y << " m=" << m << " d=" << d << endl;
+	// Y2K OK but this will fail before 1910 or after 2010 ...
+	if (y && y < 100) y+=(y < 10 ? 2000 : 1900);
+	return y && m && m <= 12 && d && d <= 31;
+}
+
+void
+Date::assignIndex(int& assignto,int not1,int not2) const
+{
+	int i=0;
+	while(i<3) {
+		if (i != not1 && i != not2) {
+			assignto=i; break;
+		}
+		++i;
+	}
+}
+
+bool
+Date::getDDMMYYFromString(const char *src,size_t length,DateOrder order)
+{
+	bool success=true;
+
+	if (isAllNumeric(src,length)) {
+		// if all numeric depend totally on requested order ...
+
+//cerr << "Date::getDDMMYYFromString isAllNumeric" << endl;
+		if (length == 8) {
+//cerr << "Date::getDDMMYYFromString length == 8" << endl;
+			if (order == DateOrderMonthMiddleYearFirst) {		// yyyymmdd
+//cerr << "Date::getDDMMYYFromString yyyymmdd" << endl;
+				success = extractDecimalShortFixedLength(src,length,4,yyyy)
+				       && extractDecimalShortFixedLength(src,length,2,mm)
+				       && extractDecimalShortFixedLength(src,length,2,dd);
+			}
+			else {
+				success=false;
+			}
+		}
+		else if (length == 6) {
+			if (order == DateOrderMonthMiddleYearFirst) {		// yymmdd
+				success = extractDecimalShortFixedLength(src,length,2,yyyy)
+				       && extractDecimalShortFixedLength(src,length,2,mm)
+				       && extractDecimalShortFixedLength(src,length,2,dd);
+			}
+			else {
+				success=false;
+			}
+		}
+		else {
+			success=false;
+		}
+	}
+	else {
+		// delimiters or spaces or non-numeric month ... get really creative ...
+
+		short v[3];
+		int v_ismmm[3];
+		if (!getDatePossibilitiesFromString(
+			src,length,
+			v[0],v_ismmm[0],
+			v[1],v_ismmm[1],
+			v[2],v_ismmm[2])) return false;
+
+		int dayindex	=-1;
+		int monthindex	=-1;
+		int yearindex	=-1;
+
+		unsigned i;
+
+		// Determine actual string order if possible ...
+
+		i=0;
+		while (i<3) {
+			if (v_ismmm[i]) {
+				monthindex=i;
+				break;
+			}
+			++i;
+		}
+		i=0;
+		while(i<3) {
+			if (i != monthindex && v[i] > 31) {
+				yearindex=i;
+				break;
+			}
+			++i;
+		}
+		i=0;
+		while(i<3) {
+			if (yearindex != -1 && i != yearindex && i != monthindex && v[i] > 12) {
+				dayindex=i;
+				break;
+			}
+			++i;
+		}
+
+		// Actual string order may override requested order ...
+
+		if (order == DateOrderMonthMiddleYearLast) {		// ddmmyy
+			if (yearindex != 0 && dayindex < 0)
+				assignIndex(dayindex,yearindex,monthindex);
+			if (monthindex < 0)
+				assignIndex(monthindex,dayindex,yearindex);
+			if (yearindex < 0)
+				assignIndex(yearindex,dayindex,monthindex);
+			if (dayindex < 0)	// just in case yymmdd
+				assignIndex(dayindex,yearindex,monthindex);
+		}
+		else if (order == DateOrderDayMiddleYearLast) {		// mmddyy
+			if (yearindex != 0 && monthindex < 0)
+				assignIndex(monthindex,yearindex,dayindex);
+			if (dayindex < 0)
+				assignIndex(dayindex,monthindex,yearindex);
+			if (yearindex < 0)
+				assignIndex(yearindex,dayindex,monthindex);
+			if (monthindex < 0)	// just in case yyddmm
+				assignIndex(monthindex,yearindex,dayindex);
+		}
+//		else if (order == DateOrderDayMiddleYearFirst) {	// yyddmm
+//			if (monthindex != 0 && yearindex < 0)
+//				assignIndex(yearindex,monthindex,dayindex);
+//			if (dayindex < 0)
+//				assignIndex(dayindex,monthindex,yearindex);
+//			if (monthindex < 0)
+//				assignIndex(monthindex,dayindex,yearindex);
+//			if (yearindex < 0)	// just in case mmddyy
+//				assignIndex(yearindex,monthindex,dayindex);
+//		}
+		else if (order == DateOrderMonthMiddleYearFirst) {	// yymmdd
+			if (monthindex != 0 && yearindex < 0)
+				assignIndex(yearindex,monthindex,dayindex);
+			if (monthindex < 0)
+			assignIndex(monthindex,dayindex,yearindex);
+			if (dayindex < 0)
+				assignIndex(dayindex,monthindex,yearindex);
+			if (yearindex < 0)	// just in case ddmmyy
+				assignIndex(yearindex,monthindex,dayindex);
+		}
+
+		// all will be assigned by now
+
+		dd=v[dayindex];
+		mm=v[monthindex];
+		yyyy=v[yearindex];
+	}
+
+	return success && validateDateValues(dd,mm,yyyy);
+}
+
+Date::Date(short y,short m,short d)
+{
+	dd=d;
+	yyyy=y;
+	mm=m;
+	mmm=makeMMMFromMM(m);
+	goodflag=validateDateValues(dd,mm,yyyy);	// Adds century prn
+	tzo[0]=0;
+}
+
+Date::Date(short y,const char *mmm,short d)
+{
+	dd=d;
+	yyyy=y;
+	size_t length=strlen(mmm);
+	goodflag=extractMMFromMMM(mmm,length,mm) && validateDateValues(dd,mm,yyyy);	// Adds century prn
+	tzo[0]=0;
+}
+
+Date::Date(const char *str,enum DateOrder order)
+{
+	size_t length=strlen(str);
+	goodflag=getDDMMYYFromString(str,length,order);	// Already does validateDateValues()
+	mmm=makeMMMFromMM(mm);
+	tzo[0]=0;
+}
+
+Date::Date(Date const & date)
+{
+	dd=date.getDD();
+	yyyy=date.getYYYY();
+	mm=date.getMM();
+	mmm=new char[4];
+	strncpy(mmm,date.getMMM(),3);
+	mmm[3]=0;
+	goodflag=validateDateValues(dd,mm,yyyy);
+	strncpy(tzo,date.tzo,5);
+}
+
+Date::Date(void)
+{
+	time_t t = time(NULL);
+	struct tm *lt = localtime(&t);
+	Assert(lt);
+	dd=lt->tm_mday;
+	yyyy=lt->tm_year+1900;
+	mm=lt->tm_mon+1;
+	mmm=new char[4];
+	strncpy(mmm,getMMM(),3);
+	mmm[3]=0;
+	goodflag=validateDateValues(dd,mm,yyyy);
+#ifdef USEGLIBCTIMEZONE
+#if USEGLIBCTIMEZONE == 1
+        makeTimezoneOffset(lt->tm_gmtoff);	// a glibc'ism that works on Linux and Mac but not Solaris
+#else
+#if USEGLIBCTIMEZONE == -1
+	makeTimezoneOffset(lt->tm_isdst == 0 ? timezone : altzone);	// external variables for Solaris (at least prior to Solaris 10)
+#else
+#if USEGLIBCTIMEZONE == -2
+	makeTimezoneOffset(_timezone);	// Cygwin
+#else
+	makeTimezoneOffset(timezone);		// an external variable set whenever localtime() is called
+#endif
+#endif
+#endif
+#else
+	makeTimezoneOffset(timezone);		// an external variable set whenever localtime() is called
+#endif
+}
+
+Date&
+Date::operator=(const Date & date)
+{
+	dd=date.getDD();
+	yyyy=date.getYYYY();
+	mm=date.getMM();
+	mmm=new char[4];
+	strncpy(mmm,date.getMMM(),3);
+	mmm[3]=0;
+	goodflag=validateDateValues(dd,mm,yyyy);
+	return *this;
+}
+
+Date::~Date(void)
+{
+	if (mmm) delete[] mmm;
+}
+
+
+bool
+Time::validateTimeValues(short h,short m,short s,short ms) const
+{
+	return h >= 0 && h<= 23 && m >= 0 && m <= 60 && s >= 0 && s <= 60;
+}
+
+bool
+Time::getHHMMSSFromString(const char *src,size_t length)
+{
+//cerr << "Time::getHHMMSSFromString: <" << src << ">" << endl;
+	hour=0;
+	min=0;
+	sec=0;
+	millisec=0;
+	skipSpaces(src,length);
+	if (!extractDecimalShortFixedLength(src,length,2,hour)) return false;	// must have at least the hour
+//cerr << "Time::getHHMMSSFromString: extracted hour " << hour << endl;
+	skipSpaces(src,length);
+	skipTimeDelimeter(src,length);
+	skipSpaces(src,length);
+	if (!extractDecimalShortFixedLength(src,length,2,min)) return length == 0 && validateTimeValues(hour,min,sec,millisec);
+//cerr << "Time::getHHMMSSFromString: extracted min " << min << endl;
+	skipSpaces(src,length);
+	skipTimeDelimeter(src,length);
+	skipSpaces(src,length);
+	if (!extractDecimalShortFixedLength(src,length,2,sec)) return length == 0 && validateTimeValues(hour,min,sec,millisec);
+//cerr << "Time::getHHMMSSFromString: extracted sec " << sec << endl;
+	if (*src == '.') { --length; ++src; }	// skip fraction of second delimiter
+	if (length && *src) {
+		size_t fraclength=length;
+		long lmillisec;			// because possibility of truncation if precise fraction
+		if (!extractDecimalLong(src,length,lmillisec)) return length == 0 && validateTimeValues(hour,min,sec,millisec);
+		fraclength-=length;
+		if (fraclength > 3) {
+			fraclength-=3;
+			while (fraclength-- && lmillisec) lmillisec/=10;
+		}
+		else if (fraclength < 3) {
+			while (fraclength++ < 3 && lmillisec) lmillisec*=10;
+		}
+		Assert(lmillisec < 32768);
+		millisec=(short)lmillisec;
+//cerr << "Time::getHHMMSSFromString: extracted millisec " << millisec << endl;
+	}
+	return length == 0 && validateTimeValues(hour,min,sec,millisec);
+}
+
+Time::Time(short h,short m,short s,short ms)
+{
+	hour=h;
+	min=m;
+	sec=s;
+	millisec=ms;
+	goodflag=validateTimeValues(hour,min,sec,millisec);
+}
+
+Time::Time(const char *str)
+{
+	size_t length=strlen(str);
+	goodflag=getHHMMSSFromString(str,length); // already does validateTimeValues()
+}
+
+Time::Time(Time const & time)
+{
+	hour=time.getHour();
+	min=time.getMinute();
+	sec=time.getSecond();
+	millisec=time.getMilliSecond();
+	goodflag=validateTimeValues(hour,min,sec,millisec);
+}
+
+Time::Time(Uint32 totalms)
+{
+	millisec=Uint16(totalms%1000u);
+	totalms/=1000u;
+	sec=Uint16(totalms%60u);
+	totalms/=60u;
+	min=Uint16(totalms%60u);
+	totalms/=60u;
+	hour=Uint16(totalms%60u);
+	goodflag=validateTimeValues(hour,min,sec,millisec);
+}
+
+Time::Time(void)
+{
+	time_t t = time(NULL);
+	struct tm *lt = localtime(&t);
+	Assert(lt);
+	millisec=Uint16(0);
+	sec=Uint16(lt->tm_sec);
+	min=Uint16(lt->tm_min);
+	hour=Uint16(lt->tm_hour);
+	goodflag=validateTimeValues(hour,min,sec,millisec);
+}
+
diff --git a/libsrc/src/generic/getoptns.cc b/libsrc/src/generic/getoptns.cc
new file mode 100644
index 0000000..1760b21
--- /dev/null
+++ b/libsrc/src/generic/getoptns.cc
@@ -0,0 +1,484 @@
+static const char *CopyrightIdentifier(void) { return "@(#)getoptns.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>	// for cerr for version message
+#include <iomanip>
+#include <cctype>
+//#include <string>
+#else
+#include <iostream.h>	// for cerr for version message
+#include <iomanip.h>
+#include <ctype.h>
+//#include <string.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "getoptns.h"
+#include "mesgtext.h"
+#include "version.h"
+#include "platform.h"
+
+// many of the get and extract methods should be a template
+// but can't figure out how to have template functions declared within
+// a class
+
+bool
+GetNamedOptions::match(const char *arg,const char *index)
+{
+	return (arg && arg[0] == '-' && index
+		&& ((arg[1] == 0 && index[0] == 0)	// "-"
+		     || strcmp(arg+1,index) == 0));
+}
+
+bool
+GetNamedOptions::extract(const char *index,const char * src,long long &dst)
+{
+	while (*src == ' ') ++src;
+	istrstream istr(src);
+	istr >> resetiosflags(ios::basefield) // force adaptive
+	     >> dst;
+//	if (istr.good())
+		return true;
+//	else {
+//		errorstream << "-" << index
+//			    << ": " << EMsgDC(ArgumentNotInteger) << endl;
+//		good_flag=false;
+//		return false;
+//	}
+}
+
+#define GENERATE_EXTRACT_INDEX_INTEGER(T)				\
+bool									\
+GetNamedOptions::extract(const char *index,const char * src,T &dst)	\
+{									\
+	long long l;								\
+	if (extract(index,src,l)) {					\
+		dst=(T)l;						\
+		return true;						\
+	}								\
+	else								\
+		return false;						\
+}
+
+GENERATE_EXTRACT_INDEX_INTEGER(unsigned long)
+GENERATE_EXTRACT_INDEX_INTEGER(unsigned int)
+GENERATE_EXTRACT_INDEX_INTEGER(int)
+GENERATE_EXTRACT_INDEX_INTEGER(long)
+
+bool
+GetNamedOptions::extract(const char *index,const char * src,double &dst)
+{
+//cerr << "GetNamedOptions::extract(const char *index,const char * src,double &dst):" << endl;
+	while (*src == ' ') ++src;
+	istrstream istr(src);
+	istr >> dst;
+	if (istr.good()
+	 // fudge because fails if no trailing f or d :(
+		 || ((isdigit(*src) || *src == '-' || *src == '+') && isdigit(src[strlen(src)-1]))
+	)
+		return true;
+	else {
+		errorstream << "-" << index
+			    << ": " << EMsgDC(ArgumentNotFloat) << endl;
+		good_flag=false;
+		return false;
+	}
+}
+
+bool
+GetNamedOptions::extract(const char *index,const char * src,float &dst)
+{
+//cerr << "GetNamedOptions::extract(const char *index,const char * src,float &dst):" << endl;
+	double d;
+	if (extract(index,src,d)) {
+		dst=(float)d;
+		return true;
+	}
+	else
+		return false;
+}
+
+bool
+GetNamedOptions::extract(const char *index,const char * src,const char * &dst)
+{
+	(void)good_flag; (void)errorstream;
+	(void)index; dst=src; return true;
+}
+
+int
+GetNamedOptions::findUnusedOption(void)
+{
+//cerr << "GetNamedOptions::findUnusedOption(void):" << endl;
+	int i;
+	for (i=0; i<argc_start; ++i) {
+		if (!argv_used[i]
+		 && argv_start[i]
+		 && argv_start[i][0] == '-') {
+//cerr << "GetNamedOptions::findUnusedOption(void): argv_start[i] = " << argv_start[i] << endl;
+			return i;
+		}
+	}
+	return -1;
+}
+
+int
+GetNamedOptions::findUnusedOption(const char *index)
+{
+//cerr << "GetNamedOptions::findUnusedOption(const char *index):" << endl;
+	if (!index) return -1;
+	int i;
+	for (i=0; i<argc_start; ++i) {
+		if (!argv_used[i] && match(argv_start[i],index)) {
+//cerr << "GetNamedOptions::findUnusedOption(const char *index): argv_start[i] = " << argv_start[i] << endl;
+			return i;
+		}
+	}
+	return -1;
+}
+
+int
+GetNamedOptions::findUnusedOption(const char *const *indexes,int& which)
+{
+//cerr << "GetNamedOptions::findUnusedOption(const char *const *indexes,int& which):" << endl;
+	which=-1;
+	int found=-1;
+	int iw=0;
+	int count=0;
+	while (*indexes) {
+		int i=findUnusedOption(*indexes);
+		if (i != -1) {
+			found=i;
+			which=iw;
+			++count;
+			if (count > 1) {
+				errorstream << "-" << *indexes
+					    << ": "
+					    << EMsgDC(OptionRepeated)
+					    << endl;
+			}
+		}
+		++indexes;
+		++iw;
+	}
+	return found;
+}
+
+int
+GetNamedOptions::findUnusedValue(int n)
+{
+	int i;
+	for (i=0; i<argc_start; ++i) {
+		if (!argv_used[i]) {
+			if (n == 0) return i;
+			--n;
+		}
+	}
+	return -1;
+}
+
+void
+GetNamedOptions::firstValue(void)
+{
+}
+
+int
+GetNamedOptions::areMoreValues(void)
+{
+	int i=0;
+	while (findUnusedValue(i) != -1) ++i;
+	return i;
+}
+
+void
+GetNamedOptions::bumpValue(void)
+{
+	int i=findUnusedValue(0);
+	if (i != -1) argv_used[i]=true;
+}
+
+const char *
+GetNamedOptions::value(int n)
+{
+	int i=findUnusedValue(n);
+	return (i == -1) ? 0 : argv_start[i];
+}
+
+GetNamedOptions::GetNamedOptions(int argc,const char *const *argv)
+	: ErrorsInClass()
+{
+	command_string=argv[0];
+	argv_start=argv+1;
+	argc_left=argc_start=argc-1;
+	argv_used=argc_start ? new bool[argc_start] : 0;
+	if (argc_start && !argv_used)
+		good_flag=false;
+	else {
+		int i;
+		for (i=0; i<argc_start; ++i) argv_used[i]=false;
+	}
+	
+	if (get("version")) {
+		cerr << "dicom3tools " << MMsgDC(Version) << ": " << dicom3tools_version_string << endl;
+		cerr << "dicom3tools " << MMsgDC(Platform) << ": " << dicom3tools_platform_string << endl;
+#ifdef __GNUC__
+		cerr << "dicom3tools " << MMsgDC(Preprocessor) << ": gcc cpp " << __GNUC__ << "." <<  __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << endl;
+		cerr << "dicom3tools " << MMsgDC(Compiler) << ": gcc g++ " << __VERSION__ << endl;
+#endif
+		cerr << "dicom3tools " << MMsgDC(UIDRoot) << ": " << DEFAULTUIDROOT << endl;
+		// if there are other arguments, keep going (i.e., allow the invoker to do something), otherwise exit (i.e., so as to allow getting version and do nothing else)
+		if (argc_start <= 1) {
+			exit(0);
+		}
+	}
+}
+
+GetNamedOptions::~GetNamedOptions()
+{
+	if (argv_used) delete[] argv_used;
+}
+
+bool
+GetNamedOptions::get(const char *index)
+{
+	int i=findUnusedOption(index);
+	if (i != -1) {
+		argv_used[i]=true;
+		return true;
+	}
+	else
+		return false;
+}
+
+bool
+GetNamedOptions::operator[](const char *index)
+{
+	return get(index);
+}
+
+bool
+GetNamedOptions::get(const char *const *indexes)
+{
+	int which;
+	int i=findUnusedOption(indexes,which);
+	if (i != -1) {
+		argv_used[i]=true;
+		return true;
+	}
+	else
+		return false;
+}
+
+bool
+GetNamedOptions::operator[](const char *const *indexes)
+{
+	return get(indexes);
+}
+
+bool
+GetNamedOptions::get(const char *index,const char * &value)
+{
+	int i=findUnusedOption(index);
+	if (i == -1) return false;
+	argv_used[i]=true;
+//cerr << "GetNamedOptions::get(const char *index,const char * &value): argv_start[i+1] = " << argv_start[i+1] << endl;
+	if (i+1 >= argc_start
+	 || argv_used[i+1]
+	 || argv_start[i+1] == 0
+	 || argv_start[i+1][0] == 0
+//	 || argv_start[i+1][0] == '-'
+	) {
+		errorstream << "-" << index
+			    << ": " << EMsgDC(ArgumentMissing) << endl;
+		good_flag=false;
+		return false;
+	}
+	argv_used[i+1]=true;
+	value=argv_start[i+1];
+//cerr << "GetNamedOptions::get(const char *index,const char * &value): value = " << value << endl;
+	return true;
+}
+
+#define GENERATE_GET_ONE_ARGUMENT(T)					\
+bool									\
+GetNamedOptions::get(const char *index,T &value)			\
+{									\
+	const char *s;							\
+	bool rv;							\
+	if (!get(index,s))						\
+		rv=false;						\
+	else								\
+		rv=extract(index,s,value);				\
+	return rv;							\
+}
+
+GENERATE_GET_ONE_ARGUMENT(int)
+GENERATE_GET_ONE_ARGUMENT(unsigned int)
+GENERATE_GET_ONE_ARGUMENT(unsigned long)
+GENERATE_GET_ONE_ARGUMENT(long)
+GENERATE_GET_ONE_ARGUMENT(long long)
+GENERATE_GET_ONE_ARGUMENT(float)
+GENERATE_GET_ONE_ARGUMENT(double)
+
+bool
+GetNamedOptions::get(const char *const *indexes,const char * &value,int& which)
+{
+	int found=findUnusedOption(indexes,which);
+	if (found == -1) return false;
+	argv_used[found]=true;
+//cerr << "GetNamedOptions::get(const char *const *indexes,const char * &value,int& which): argv_start[found+1] = " << argv_start[found+1] << endl;
+	if (found+1 >= argc_start
+	 || argv_used[found+1]
+	 || argv_start[found+1] == 0
+	 || argv_start[found+1][0] == 0
+//	 || argv_start[found+1][0] == '-'
+	) {
+		errorstream << "-" << indexes[which]
+			    << ": " << EMsgDC(ArgumentMissing) << endl;
+		good_flag=false;
+		return false;
+	}
+	argv_used[found+1]=true;
+	value=argv_start[found+1];
+//cerr << "GetNamedOptions::get(const char *const *indexes,const char * &value,int& which): value = " << value << endl;
+	return true;
+}
+
+#define GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(T)		\
+bool									\
+GetNamedOptions::get(const char *const *indexes,T &value)		\
+{									\
+	const char *s;							\
+	bool rv;							\
+	int which;							\
+	if (!get(indexes,s,which))					\
+		rv=false;						\
+	else								\
+		rv=extract(indexes[which],s,value);			\
+	return rv;							\
+}
+
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(int)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(unsigned int)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(unsigned long)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(long)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(long long)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(float)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(double)
+GENERATE_GET_ONE_ARGUMENT_FROM_MULTIPLE_OPTIONS(const char *)
+
+#define GENERATE_GET_MULTIPLE_ARGUMENTS(T)				\
+int 									\
+GetNamedOptions::get(const char *index,T *ptr,int num)			\
+{									\
+	int i=findUnusedOption(index);					\
+	int n=-1;							\
+	if (i != -1) {							\
+		argv_used[i]=true;					\
+		++i;							\
+		for (n=0;  n < num && i+n < argc_start			\
+				&& !argv_used[i+n]			\
+				&& argv_start[i+n]			\
+				&& argv_start[i+n][0]			\
+				&& argv_start[i+n][0] != '-'		\
+			  ; ++n) {					\
+			argv_used[i+n]=true;				\
+			(void)extract(					\
+				index,argv_start[i+n],ptr[n]);		\
+		}							\
+	}								\
+	return n;							\
+}
+
+GENERATE_GET_MULTIPLE_ARGUMENTS(unsigned int)
+GENERATE_GET_MULTIPLE_ARGUMENTS(int)
+GENERATE_GET_MULTIPLE_ARGUMENTS(unsigned long)
+GENERATE_GET_MULTIPLE_ARGUMENTS(long)
+GENERATE_GET_MULTIPLE_ARGUMENTS(long long)
+GENERATE_GET_MULTIPLE_ARGUMENTS(float)
+GENERATE_GET_MULTIPLE_ARGUMENTS(double)
+GENERATE_GET_MULTIPLE_ARGUMENTS(const char *)
+
+#define GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(T)		\
+int 									\
+GetNamedOptions::get(const char *const *indexes,T *ptr,int num)		\
+{									\
+	int which;							\
+	int i=findUnusedOption(indexes,which);				\
+	int n=-1;							\
+	if (i != -1) {							\
+		argv_used[i]=true;					\
+		++i;							\
+		for (n=0;  n < num && i+n < argc_start			\
+				&& !argv_used[i+n]			\
+				&& argv_start[i+n]			\
+				&& argv_start[i+n][0]			\
+				&& argv_start[i+n][0] != '-'		\
+			  ; ++n) {					\
+			argv_used[i+n]=true;				\
+			(void)extract(					\
+				indexes[which],				\
+				argv_start[i+n],ptr[n]);		\
+		}							\
+	}								\
+	return n;							\
+}
+
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(unsigned int)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(int)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(unsigned long)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(long)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(long long)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(float)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(double)
+GENERATE_GET_MULTIPLE_ARGUMENT_FROM_MULTIPLE_OPTIONS(const char *)
+
+int
+GetNamedOptions::operator!()
+{
+	return areMoreValues();
+}
+
+void
+GetNamedOptions::operator++()
+{
+	bumpValue();
+}
+
+void
+GetNamedOptions::operator++(int)
+{
+	bumpValue();
+}
+
+const char *
+GetNamedOptions::operator()()
+{
+	return value(0);
+}
+
+const char *
+GetNamedOptions::operator[](int num)
+{
+	return value(num);
+}
+
+void
+GetNamedOptions::done(void)
+{
+	int i;
+	while ((i=findUnusedOption()) != -1) {
+		good_flag=false;
+		errorstream << argv_start[i] << ": unrecognized option" << endl;
+		argv_used[i]=true;
+	}
+}
+
+const char *
+GetNamedOptions::command(void) const
+{
+	return command_string;
+}
+
diff --git a/libsrc/src/generic/ioopti.cc b/libsrc/src/generic/ioopti.cc
new file mode 100644
index 0000000..03a1fc9
--- /dev/null
+++ b/libsrc/src/generic/ioopti.cc
@@ -0,0 +1,115 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ioopti.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static const char *options_input_file[] = {
+	"if",
+	"input-file",
+	0
+};
+
+InputOptions::InputOptions(GetNamedOptions &options)
+		: ErrorsInClass()
+{
+	filename=0;
+	options.get(options_input_file,filename);
+}
+
+char *
+InputOptions::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_input_file,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(InputFile) << "]";
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+void
+InputOptions::done(void)
+{
+}
+
+// NB. What is the significance of fstr being deleted after
+// assignment to another stream ? Should the InputOpenerFromOptions
+// object be required to remain in scope as long as the
+// assigned to stream is still in use ??
+
+InputOpenerFromOptions::InputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename,
+		istream &cstr,
+		bool raw)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+
+	if (filename) {
+#ifdef USEBINARYFLAGFORINPUTOPENMODE
+		ios::open_mode mode = raw ? (ios::in|ios::binary) : ios::in;
+		ifstream *fstr=new ifstream(filename,mode);
+#else
+		(void)raw;
+		ifstream *fstr=new ifstream(filename);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		streambuf *sbuf  = cstr.rdbuf();
+		str=new istream(sbuf);
+		// default ANSI cin/cout is unbuffered, slow, so ...
+//		char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//		if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+		// this buffer will never be delete[]'d but doesn't
+		// matter ... how often would we be reusing cin/cout ?
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileReadOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+InputOpenerFromOptions::~InputOpenerFromOptions()
+{
+	if (str) delete str;
+}
+
+InputOpenerFromOptions::operator streambuf *(void)
+{
+	Assert(str);
+	return str->rdbuf();
+}
+
diff --git a/libsrc/src/generic/ioopto.cc b/libsrc/src/generic/ioopto.cc
new file mode 100644
index 0000000..76002b7
--- /dev/null
+++ b/libsrc/src/generic/ioopto.cc
@@ -0,0 +1,112 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ioopto.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <fstream>
+#else
+#include <fstream.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "ioopt.h"
+#include "mesgtext.h"
+
+#ifndef REPLACESTANDARDIOBUFSIZE
+#define REPLACESTANDARDIOBUFSIZE 16384
+#endif
+
+static const char *options_output_file[] = {
+	"of",
+	"output-file",
+	0
+};
+
+OutputOptions::OutputOptions(GetNamedOptions &options)
+		: ErrorsInClass()
+{
+	filename=0;
+	options.get(options_output_file,filename);
+}
+
+char *
+OutputOptions::usage(void)
+{
+	ostrstream ostr;
+	const char **ptr;
+	const char *lead;
+
+	ostr << " [";
+	for (ptr=options_output_file,lead=""; *ptr; ++ptr,lead="|")
+		ostr << lead << "-" << *ptr;
+	ostr << " " << MMsgDC(OutputFile) << "]";
+
+	ostr << ends;
+
+	// string deletion becomes callers responsibility ...
+	return ostr.str();
+}
+
+void
+OutputOptions::done(void)
+{
+}
+
+OutputOpenerFromOptions::OutputOpenerFromOptions(
+		GetNamedOptions &options,
+		const char *filename,
+		ostream &cstr,
+		bool raw)
+	: ErrorsInClass()
+{
+	if (!filename && !options) {
+		filename=options();
+		++options;
+	}
+
+	if (filename) {
+#ifdef USEBINARYFLAGFOROUTPUTOPENMODE
+		ios::open_mode mode = raw
+			? (ios::out|ios::trunc|ios::binary)
+			: (ios::out|ios::trunc);
+		ofstream *fstr=new ofstream(filename,mode);
+#else
+		(void)raw;
+		ofstream *fstr=new ofstream(filename,ios::out|ios::trunc);
+#endif
+		if (!fstr || !*fstr || !fstr->rdbuf()->is_open()) {
+			str=0;
+		}
+		else
+			str=fstr;
+	}
+	else {
+		streambuf *sbuf  = cstr.rdbuf();
+		str=new ostream(sbuf);
+		// default ANSI cin/cout is unbuffered, slow, so ...
+//		char *buf=new char[REPLACESTANDARDIOBUFSIZE];
+//		if (buf) sbuf->setbuf(buf,REPLACESTANDARDIOBUFSIZE);
+		// this buffer will never be delete[]'d but doesn't
+		// matter ... how often would we be reusing cin/cout ?
+	}
+
+	if (!str || !*str) {
+		errorstream << AMsgDC(FileWriteOpenFailed);
+		if (filename) errorstream <<" - \"" << filename << "\"";
+		errorstream << endl;
+		good_flag=false;
+	}
+}
+
+OutputOpenerFromOptions::~OutputOpenerFromOptions()
+{
+	if (str) delete str;
+}
+
+OutputOpenerFromOptions::operator streambuf *(void)
+{
+	Assert(str);
+	return str->rdbuf();
+}
+
diff --git a/libsrc/src/generic/ntstream.cc b/libsrc/src/generic/ntstream.cc
new file mode 100644
index 0000000..7f95db9
--- /dev/null
+++ b/libsrc/src/generic/ntstream.cc
@@ -0,0 +1,328 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ntstream.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "ntstream.h"
+
+#include <unistd.h>
+#include <stdlib.h>	// for atoi()
+#include <string.h>	// for memxxx()
+#include <sys/types.h>
+
+#include <sys/socket.h>	// NB. g++ on sun doesn't have prototypes
+
+#ifdef NEEDMISSINGPROTOTYPES
+extern "C" {
+int accept(int, struct sockaddr *, int *);
+int bind(int, struct sockaddr *, int);
+int connect(int, const struct sockaddr *, int);
+int listen(int, int);
+int socket(int, int, int);
+}
+#endif /* NEEDMISSINGPROTOTYPES */
+
+#include <netinet/in.h>	// for htons()
+
+#include <arpa/inet.h>	// for inet_addr()
+			// NB. g++ on sun doesn't have prototypes
+
+#ifdef NEEDMISSINGPROTOTYPES
+extern "C" {
+unsigned long    inet_addr(const char*);
+}
+#endif /* NEEDMISSINGPROTOTYPES */
+
+#include <netdb.h>	// NB. g++ on sun doesn't have prototypes
+
+#ifdef NEEDMISSINGPROTOTYPES
+extern "C" {
+struct hostent *gethostbyname(const char *);
+struct servent *getservbyname(char *, char *);
+struct protoent *getprotobyname(char *);
+}
+#endif /* NEEDMISSINGPROTOTYPES */
+
+#ifndef	INADDR_NONE
+#define	INADDR_NONE	0xffffffff
+#endif /* INADDR_NONE */
+
+// ********************* netbuf member functions ******************
+
+netbuf::netbuf()
+{
+	open_flag=0;
+}
+
+netbuf::~netbuf()
+{
+	(void)close();
+}
+
+netbuf*
+netbuf::open(const char *h,const char *s,const char *p,int md)
+{
+	struct sockaddr_in 	address;
+	struct servent *	service;
+	struct hostent *	host;
+	struct protoent *	protocol;
+
+	memset((char *)&address,0,sizeof(address));
+	address.sin_family = AF_INET;
+
+	if ((service=::getservbyname((char *)s,(char *)p)) == 0) {
+		if ((address.sin_port=htons((unsigned short)atoi(s))) == 0) {
+			return 0;
+		}
+	}
+	else {
+		address.sin_port=htons(ntohs((unsigned short)service->s_port));
+	}
+
+	if ((host=::gethostbyname(h)) == 0) {
+  		if ((address.sin_addr.s_addr=inet_addr(h)) == INADDR_NONE) {
+			return 0;
+		}
+	}
+	else {
+		memcpy((char *)&address.sin_addr,host->h_addr,host->h_length);
+	}
+
+	if ((protocol=::getprotobyname((char *)p)) == 0) return 0;
+
+	int type = strcmp(p,"udp") ? SOCK_STREAM : SOCK_DGRAM;
+
+	if ((socket=::socket(PF_INET,type,protocol->p_proto)) < 0) return 0;
+
+	if (::connect(socket,(struct sockaddr *)&address,sizeof(address)) < 0) return 0;
+
+	open_flag=1;
+	//mode=md;
+	(void)md;
+	mode=ios::in|ios::out;
+
+	//cerr << "netbuf::open: success\n" << flush;
+
+	return this;
+}
+
+netbuf*
+netbuf::close(void)
+{
+	int err=0;
+	if (open_flag) {
+		err+=(mode&ios::out && overflow(EOF) == EOF);
+		err+=(::close(socket) == -1);
+		open_flag=0;
+	}
+	return err ? 0 : this;
+}
+
+// The default supplied by libg++ for this won't work, so do it ourselves ...
+
+int
+netbuf::xsputn(const char *p,int n)
+{
+	//cerr << "netbuf::xsputn: start with p=<" << p << ">\n" << flush;
+	if (sync() == EOF) return EOF;
+	return ::write(socket,p,n);
+}
+
+int
+netbuf::overflow(int c)
+{
+	//cerr << "netbuf::overflow: start with c=" << c << "\n" << flush;
+
+	if (!(mode&ios::out)			// can't write
+	 || allocate() == EOF			// no holding area
+	 || (gptr() && gptr() < egptr())	// are get chars left
+	) return EOF;
+
+	//cerr << "netbuf::overflow: ok\n" << flush;
+
+	setg(0,0,0);
+	if (!pptr()) setp(base(),base());
+
+	int unconsummed = pptr()-pbase();
+
+	if (c != EOF) {		// consume argument
+		*pptr()=c;	// space is always there
+		++unconsummed;
+	}
+
+	//cerr << "netbuf::overflow: unconsummed=" << unconsummed << "\n" << flush;
+
+	if (unconsummed == 0) return 0;	// nothing to do, but not error
+
+	if (::write(socket,pbase(),unconsummed) == unconsummed) {
+		setp(base(),ebuf()-1);	// space for c next time
+
+		//cerr << "netbuf::overflow: success\n" << flush;
+
+		return 1;		// not EOF
+	}
+	else {
+		setp(0,0);
+
+		//cerr << "netbuf::overflow: fail\n" << flush;
+
+		return EOF;	// error
+	}
+}
+
+int
+netbuf::underflow(void)
+{
+	//cerr << "netbuf::underflow: start\n" << flush;
+
+	if (!(mode&ios::in)		// can't read
+	 || allocate() == EOF		// no holding area
+	) return EOF;
+
+	//cerr << "netbuf::underflow: ok\n" << flush;
+
+	if (gptr() && gptr() < egptr())	// still chars in get area
+		return *gptr();
+
+	//cerr << "netbuf::underflow: need to produce more\n" << flush;
+
+	if (pptr() && pptr() < pbase()
+	 && overflow(EOF) == EOF)	// can't put remaining chars
+		return EOF;
+
+	setp(0,0);
+
+	//cerr << "netbuf::underflow: put remaining ok\n" << flush;
+
+	int putbacklng = (blen() > 1) ? 1 : 0;
+
+	int nread=::read(socket,base()+putbacklng,blen()-putbacklng);
+
+	//cerr << "netbuf::underflow: read=" << nread << "\n" << flush;
+
+	if (nread > 0) {
+		setg(base(),base()+putbacklng,base()+putbacklng+nread);
+		return *gptr();
+	}
+	else {
+		setg(0,0,0);
+		return EOF;	// error
+	}
+}
+
+int
+netbuf::sync(void)
+{
+	//cerr << "netbuf::sync: start\n" << flush;
+
+	if (gptr() && gptr() < egptr())	// still chars in get area
+		return EOF;		// can't return them to producer
+
+	if (pptr() && pptr() < pbase()
+	 && overflow(EOF) == EOF)	// can't put remaining chars
+		return EOF;
+
+	//cerr << "netbuf::sync: success\n" << flush;
+
+	return 0;			// all chars flushed
+}
+
+// ********************* netstreambase member functions ******************
+
+netstreambase::netstreambase()
+{
+}
+
+netstreambase::netstreambase(const char *host,const char *service,const char *protocol,int mode)
+{
+	init(&buf);			// supply ios with the streambuf
+	open(host,service,protocol,mode);
+}
+
+netstreambase::~netstreambase()
+{
+	close();
+}
+
+void
+netstreambase::open(const char *host,const char *service,const char *protocol,int mode)
+{
+	(void)buf.open(host,service,protocol,mode);
+}
+
+void
+netstreambase::close(void)
+{
+	(void)buf.close();
+}
+
+void
+netstreambase::setbuf(char *p,int l)
+{
+	(void)buf.setbuf(p,l);
+}
+
+// ********************* inetstream member functions ******************
+
+inetstream::inetstream()
+{
+}
+
+inetstream::inetstream(const char *host,const char *service,const char *protocol,int mode)
+	: netstreambase(host,service,protocol,mode)
+{
+}
+
+inetstream::~inetstream()
+{
+}
+
+// ********************* onetstream member functions ******************
+
+onetstream::onetstream()
+{
+}
+
+onetstream::onetstream(const char *host,const char *service,const char *protocol,int mode)
+	: netstreambase(host,service,protocol,mode)
+{
+}
+
+onetstream::~onetstream()
+{
+}
+
+#ifdef TEST_ntstream
+
+int
+main(int argc,char **argv)
+{
+	(void)argc; (void)argv;
+
+	inetstream in("localhost","echo","tcp");
+
+	//char inbuffer[1024];
+	//in.rdbuf()->setbuf(inbuffer,1024);
+
+	ostream out(in.rdbuf());
+
+	in.tie(&out);
+
+	char buffer[80];
+	while (cin.getline(buffer,80,'\n')) {
+		out.write(buffer,strlen(buffer));
+		out << "\n";
+		if (!out.good()) {
+			cerr << "Write failed\n" << flush;
+		}
+		//out << flush;
+		//if (!out.good()) {
+		//	cerr << "Flush failed\n" << flush;
+		//}
+
+		in.getline(buffer,80,'\n');
+		if (!in.good()) {
+			cerr << "Read failed\n" << flush;
+		}
+		cout.write(buffer,in.gcount());
+		cout << "\n";
+	}
+}
+
+#endif /* TEST_ntstream */
diff --git a/libsrc/src/generic/platform.cc b/libsrc/src/generic/platform.cc
new file mode 100644
index 0000000..0b11f25
--- /dev/null
+++ b/libsrc/src/generic/platform.cc
@@ -0,0 +1,7 @@
+// Automatically generated - EDITS WILL BE LOST
+
+// Generated by support/setplatform
+
+#include "platform.h"
+
+const char* dicom3tools_platform_string = "Darwin graytoo.local 14.5.0 Darwin Kernel Version 14.5.0: Tue Sep  1 21:23:09 PDT 2015; root:xnu-2782.50.1~1/RELEASE_X86_64 x86_64";
diff --git a/libsrc/src/generic/txstream.cc b/libsrc/src/generic/txstream.cc
new file mode 100644
index 0000000..6bf4595
--- /dev/null
+++ b/libsrc/src/generic/txstream.cc
@@ -0,0 +1,31 @@
+static const char *CopyrightIdentifier(void) { return "@(#)txstream.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#include "basetype.h"
+#include "txstream.h"
+
+ostream&
+writeZeroPaddedNumber(ostream& o,Uint32 value,ios::fmtflags basetouse,int size) {
+	Assert(size > 0 && size < 9);	// sanity check just in case
+	if (value == 0) {
+		// For some reason the C++ standard says zero
+		// must be written as 0 not 0x0 when ios::showbase
+		// is set, so override this stupidity that has now
+		// been faithfully implemented by g++ as of 3.2.x
+		o << (basetouse == ios::hex ? "0x" : "00");
+		while (size--) o << "0";
+	}
+	else {
+		o << resetiosflags(ios::adjustfield|ios::basefield)
+		  << setiosflags(ios::showbase|ios::internal|basetouse)
+		  << setfill('0') << setw(2+size)
+		  << value
+		  << dec << setfill(' ')
+		  << resetiosflags(ios::adjustfield|ios::basefield);
+	}
+	return o;
+}
+
+ostream&
+writeZeroPaddedHexNumber(ostream& o,Uint32 value,int size) {
+	return writeZeroPaddedNumber(o,value,ios::hex,size);
+}
+
diff --git a/libsrc/src/generic/version.cc b/libsrc/src/generic/version.cc
new file mode 100644
index 0000000..6c69743
--- /dev/null
+++ b/libsrc/src/generic/version.cc
@@ -0,0 +1,7 @@
+// Automatically generated - EDITS WILL BE LOST
+
+// Generated by support/setversion
+
+#include "version.h"
+
+const char* dicom3tools_version_string = "1.00.snapshot.20151213160232";
diff --git a/libsrc/src/locale/Imakefile b/libsrc/src/locale/Imakefile
new file mode 100755
index 0000000..4a94a94
--- /dev/null
+++ b/libsrc/src/locale/Imakefile
@@ -0,0 +1,19 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBLOCALEEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = mesgtext.cc
+OBJS =           mesgtext.o
+
+LibraryTarget($(PROJECTLIBDIR)/lib$(PROJECTLOCALELIBNAME).a,$(OBJS))
+
+mesgttbl.h:	mesgtext.tpl mesgtext.awk
+	$(AWK) -f mesgtext.awk language=English < mesgtext.tpl >mesgttbl.h
+
+depend::	mesgttbl.h
+
+clean::
+	$(RM) mesgttbl.h
+
+DependCCTarget()
+
diff --git a/libsrc/src/locale/mesgtext.awk b/libsrc/src/locale/mesgtext.awk
new file mode 100644
index 0000000..6cf2a64
--- /dev/null
+++ b/libsrc/src/locale/mesgtext.awk
@@ -0,0 +1,38 @@
+#  mesgtext.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create mesgtext ix/description table in correct language 
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by mesgtext.awk with options " language
+	print ""
+
+	if (language == "") language="English"
+
+	print "struct EMSGDC_Table_Entry EMSGDC_Table[] = {"
+
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*Index/ {
+
+	ix=""
+	if (match($0,"Index=\"[^\"]*\""))
+		ix=substr($0,RSTART+length("Index=\""),
+			RLENGTH-length("Index=\"")-1);
+
+	desc=ix
+	if (match($0,language"=\"[^\"]*\""))
+		desc=substr($0,RSTART+length(language"=\""),
+			RLENGTH-length(language"=\"")-1);
+
+	print "\t\"" ix "\",\t\"" desc "\","
+
+	}
+
+END {
+	print "\t0,\t0"
+	print "};"
+	}
+
diff --git a/libsrc/src/locale/mesgtext.cc b/libsrc/src/locale/mesgtext.cc
new file mode 100644
index 0000000..a0092a0
--- /dev/null
+++ b/libsrc/src/locale/mesgtext.cc
@@ -0,0 +1,76 @@
+static const char *CopyrightIdentifier(void) { return "@(#)mesgtext.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iomanip>
+#else
+#include <iomanip.h>
+//#include <string.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "mesgtext.h"
+
+struct EMSGDC_Table_Entry {
+	const char *index;
+	const char *description;
+};
+
+#include "mesgttbl.h"
+
+static void
+dummy(void)
+{
+	(void)&EMSGDC_Instance;		// shuts up unused warning
+}
+
+static const char *
+findDescription(const char *index)
+{
+	Assert(index);
+	// Efficiency is not an issue here, so linear search is fine
+	EMSGDC_Table_Entry *ptr;
+	for (ptr=EMSGDC_Table; ptr && ptr->index && strcmp(ptr->index,index) != 0; ++ptr);
+	//Assert(ptr && ptr->index && ptr->description);
+	if (!ptr || !ptr->index || !ptr->description) {
+		return index;
+	}
+	else
+		return ptr->description;
+}
+
+char *
+EMSGDC_Class::error(const char *index)
+{
+	ostrstream stream;
+	stream << findDescription("Error") << " - ";
+	if (index && strlen(index)) stream << findDescription(index) << ends;
+	return stream.str();
+}
+
+char *
+EMSGDC_Class::warning(const char *index)
+{
+	ostrstream stream;
+	stream << findDescription("Warning") << " - ";
+	if (index && strlen(index)) stream << findDescription(index) << ends;
+	return stream.str();
+}
+
+char *
+EMSGDC_Class::abort(const char *index)
+{
+	ostrstream stream;
+	stream << findDescription("Abort") << " - ";
+	if (index && strlen(index)) stream << findDescription(index) << ends;
+	return stream.str();
+}
+
+const char *
+EMSGDC_Class::message(const char *index)
+{
+	return index && strlen(index) ? findDescription(index) : "";
+}
+
diff --git a/libsrc/src/locale/mesgtext.tpl b/libsrc/src/locale/mesgtext.tpl
new file mode 100755
index 0000000..86b011b
--- /dev/null
+++ b/libsrc/src/locale/mesgtext.tpl
@@ -0,0 +1,316 @@
+Index="Abort"					English="Abort"
+Index="ActualLength"				English="actual length"
+Index="Actually"				English="actually"
+Index="And"					English="and"
+Index="AlreadyHaveTransferSyntax"		English="Transfer syntax, byte order or value representation already specified"
+Index="ArgumentMissing"				English="Argument missing"
+Index="ArgumentNotFloat"			English="Argument is not a floating point value"
+Index="ArgumentNotInteger"			English="Argument is not an integer value"
+Index="AttributeHasDifferentValueMultiplicityInOneInstanceComparedToTheOther"	English="Attribute has different value multiplicity"
+Index="AttributeIsNotInALegalPrivateGroup"				English="Attribute with an odd group number is not in a legal private group"
+Index="AttributeIsNotARecognizedStandardAttribute"		English="Attribute with an even group number is not a recognized standard attribute"
+Index="AttributeIsNotUsedInIOD"			English="Attribute is not present in standard DICOM IOD"
+Index="AttributePresentInOneInstanceButNotTheOther"	English="Attribute present in one instance but not the other"
+Index="AttributePresentWhenConditionUnsatisfiedWithoutMayBePresentOtherwise"			English="Attribute present when condition unsatisfied (which may not be present otherwise)"
+Index="AttributeReadFailed"			English="Attribute read failed"
+Index="BadAttributeValue"			English="Bad attribute value"
+Index="BadAttributeValueMultiplicity"		English="Bad attribute Value Multiplicity"
+Index="BadByteOrder"				English="Invalid byte order - must be 'big' or 'little'"
+Index="BadDateValue"				English="Bad date value"
+Index="BadEncoding"				English="Invalid encoding"
+Index="BadFileMetaInformationVersion"		English="Bad File Meta Information Version Attribute - wrong VR, length or not 0x00,0x01"
+Index="BadGroup"				English="Bad group"
+Index="BadGroupLength"				English="Bad group length"
+Index="BadImplicitBig"				English="Implicit value representation big-endian transfer syntax is invalid"
+Index="BadItemInItem"				English="Item tag was found prematurely within another Item"
+Index="BadPatches"				English="Some patches are bad, so won't do any"
+Index="BadPrivateOwner"				English="Bad private owner value"
+Index="BadTagInSequence"			English="Bad tag in sequence"
+Index="BadTimeValue"				English="Bad time value"
+Index="BadVRAndByteOrder"			English="Incorrect combination of value representation and byte order"
+Index="BadSequenceValueLength"			English="Bad Explicit Value Length for Sequence"
+Index="BadSequenceItemValueLength"		English="Bad Explicit Value Length for Sequence Item"
+Index="BadSequenceNumberOfItems"		English="Bad Sequence number of Items"
+Index="BadValueLength"				English="Bad Value Length - not a multiple of value size"
+Index="BadValueLengthNotEven"			English="Bad Value Length - not a multiple of 2"
+Index="BadValuePixelRepresentation"		English="Pixel Representation has bad value - not 0 (unsigned) or 1 (signed)"
+Index="BadValueRepresentation"			English="Invalid Value Representation"
+Index="Bytes"					English="bytes"
+Index="CharacterInvalidForThisVR"		English="Character invalid for this VR"
+Index="CharacterInvalidForCharacterRepertoire"		English="Character invalid for character repertoire (default or as defined in Specific Character Set)"
+Index="CodeMeaningForMeasurementUnitsBeginsOrEndsWithQuotationCharacters"	English="Code Meaning in Measurement Units Code Sequence begins or ends with quotation characters"
+Index="CodeValueContainsInvalidCharactersForCodingScheme"	English="Code Value contains invalid characters for coding scheme"
+Index="CodingSchemeDesignatorInUnitsCodeSequenceIsNotUCUM"	English="Coding Scheme Designator in a Units Code Sequence is not UCUM"
+Index="ColorCellAllocationFailedNone"		English="Can't allocate any color cells"
+Index="ColorCellAllocationFailedTooFew"		English="Can't allocate enough color cells"
+Index="ColorCellValueReplacementFailed"		English="Can't replace color cell value"
+Index="ColorMapCreationFailed"			English="Can't create color map"
+Index="CompositeInformationObject"		English="Composite Information Object"
+Index="Compiler"		English="Compiler"
+Index="ConflictingDirectionsInPatientOrientationCannotBePresentInSameValue"		English="Conflicting directions in Patient Orientation cannot be present in same value"
+Index="CoordinatesContentItemMissingOrIncorrectRequiredChildContentItem"	English="Coordinates Content Item has missing or incorrect required child Content Item"
+Index="CouldBe"					English="Could be"
+Index="DataElementEncodedAsExplicitInImplicitVRTransferSyntax"	English="Data element encoded as explicit in implicit VR transfer syntax"
+Index="DataSetContainsAttributesNotUsedInIOD"	English="Dicom dataset contains attributes not present in standard DICOM IOD - this is a Standard Extended SOP Class"
+Index="DataSetContainsInvalidValuesForVR"	English="Dicom dataset contains invalid data values for Value Representations"
+Index="DataSetContainsRetiredAttributes"	English="Dicom dataset contains retired attributes"
+Index="DatasetListFailed"			English="Dicom dataset list failed"
+Index="DatasetReadFailed"			English="Dicom dataset read failed"
+Index="DatasetWriteFailed"			English="Dicom dataset write failed"
+Index="Dictionary"				English="Dictionary"
+Index="DifferentInformationEntitiesForAttributeInOneInstanceComparedToTheOther"		English="Different information entities for attribute"
+Index="DifferentPatientIDForSeriesInstanceUID"			English="Different PatientID for same SeriesInstanceUID"
+Index="DifferentPatientIDForSOPInstanceUID"				English="Different PatientID for same SOPInstanceUID"
+Index="DifferentPatientIDForStudyInstanceUID"			English="Different PatientID for same StudyInstanceUID"
+Index="DifferentSeriesInstanceUIDForSOPInstanceUID"		English="Different SeriesInstanceUID for same SOPInstanceUID"
+Index="DifferentStudyInstanceUIDForSeriesInstanceUID"	English="Different StudyInstanceUID for same SeriesInstanceUID"
+Index="DifferentStudyInstanceUIDForSOPInstanceUID"		English="Different StudyInstanceUID for same SOPInstanceUID"
+Index="DifferentValueRepresentationInOneInstanceComparedToTheOther"			English="Different value representation"
+Index="Diffing"				English="Diffing"
+Index="DimensionIndexValueForInStackPositionNumberDoesNotEqualValueOfInStackPositionNumber"			English="DimensionIndexValue for InStackPositionNumber does not equal value of InStackPositionNumber"
+Index="DimensionIndexValueForTemporalPositionIndexDoesNotEqualValueOfTemporalPositionIndex"			English="DimensionIndexValue for TemporalPositionIndex does not equal value of InStackPositionNumber"
+Index="DirectoryOffsetInvalid"			English="Directory record offset invalid - doesn't point to a directory record"
+Index="DisclaimerMessage"			English="THE OUTPUT OF THIS SOFTWARE IS FOR INVESTIGATIONAL USE ONLY - NOT TESTED OR APPROVED FOR CLINICAL APPLICATION"
+Index="DisplayedAreaSelectionSequenceInternallyInconsistent"			English="DisplayedAreaSelectionSequence is internally inconsistent"
+Index="DisplayOpenFailed"			English="Can't open display"
+Index="Duplicated"				English="Duplicated"
+Index="DuplicateSOPInstanceUID"	English="Duplicate SOPInstanceUID"
+Index="Element"					English="Element"
+Index="EmptyAttribute"				English="Empty attribute (no value)"
+Index="EmptyAttributeWhenConditionUnsatisfied"	English="Attribute present but empty (no value) even though condition not satisfied"
+Index="EmptyComponent"				English="Empty component"
+Index="EmptyTransferSyntaxUIDInMetaInformationHeader"	English="Empty or missing Transfer Syntax UID in Meta Information Header"
+Index="EncapsulatedDataIncorrectVR"		English="Encapsulated Data element has incorrect value representation"
+Index="EncapsulatedDataSkipped"			English="Encapsulated data with unimplemented transfer syntax skipped"
+Index="EqualTo"				English="equal to"
+Index="Error"					English="Error"
+Index="EstimatedRadiographicMagnificationFactorDoesNotMatchRatioOfDistanceSourceToDetectorAndDistanceSourceToPatient"					English="EstimatedRadiographicMagnificationFactor does not match ratio of DistanceSourceToDetector and DistanceSourceToPatient"
+Index="Exceeds"					English="exceeds"
+Index="Expected"				English="expected"
+Index="ExpectingItemOrSequenceDelimiter"	English="Expecting Item or Sequence Delimiter"
+Index="FileReadOpenFailed"			English="File open for read failed"
+Index="FileWriteOpenFailed"			English="File open for write failed"
+Index="FixingBadDecimalSeparator"			English="Fixing bad decimal separator"
+Index="ForAttribute"				English="for attribute"
+Index="ForValue"				English="for value"
+Index="FrameIncrementPointerValueNotPresentInDataset"				English="Frame Increment Pointer value is not present in dataset"
+Index="FunctionalGroupSequenceAlreadyUsedInSharedFunctionalGroupsSequence"				English="Functional Group Sequence already used in Shared Functional Groups Sequence"
+Index="Got"					English="got"
+Index="Group"					English="Group"
+Index="IE"					English="IE"
+Index="IgnoringGEItemDelimitationItemEncodingBug"					English="Ignoring GE Item Delimitation Item encoding bug"
+Index="IgnoringGESequenceDelimitationItemEncodingBug"					English="Ignoring GE Sequence Delimitation Item encoding bug"
+Index="ImplicitVREncodingWhenExplicitRequired"					English="Implicit VR encoding even though supposed to be explicit"
+Index="IllegalCharacterInPatientOrientation"					English="Illegal character in Patient Orientation"
+Index="IllegalNegativeValue"				English="Illegal negative value"
+Index="IllegalRootForUID"					English="Illegal root for UID"
+Index="IllegalVLForPixelDataInEncapsulatedTransferSyntaxInTopLevelDataset"	English="Specification of fixed value length for PixelData element in top level Dataset is illegal in encapsulated transfer syntax"
+Index="IllegalCDNHyphenVR"			English="Value Representation is non-standard pair of hyphens from Central Data Networks defect - treating as UN"
+Index="IllegalVRForPixelData"			English="Value Representation for Pixel Data is not Other Byte or Other Word"
+Index="IllegalZeroBytesWhenExplicitVRExpected"		English="Illegal zero bytes where explicit Value Representation expected - treating as UN"
+Index="IncorrectExplicitVRInsideFixedLengthSequenceEncodedAsUnknownVR"			English="Incorrect Explicit VR inside fixed length sequence encoded as UN VR - Implicit VR required"
+Index="IncorrectShortVLForUROrUCOrUTOrUN"		English="Incorrect Short Value Length Form for UR, UC, UT or UN Value Representation"
+Index="InformationObject"			English="Information Object"
+Index="InsufficientInformationToCalculatePosition"	English="Insufficient information to calculate position"
+Index="InsufficientInformationToSetEncoding"	English="Insufficient information to establish image pixel data encoding"
+Index="InputFile"				English="inputfile"
+Index="Is"					English="is"
+Index="LeadingZeroes"				English="Leading zeroes in embedded numeric component(s)"
+Index="LengthInvalidForThisVR"			English="Length invalid for this VR"
+Index="LowestValueInVectorIsNotOne"					English="Lowest value in vector is not one"
+Index="LUTDataBad"				English="Lookup Table Data bad"
+Index="LUTDataMultiplyDefined"			English="Lookup Table Data multiply defined"
+Index="LUTDataNotNumeric"			English="Lookup Table Data has non-numeric value representation"
+Index="LUTDataWithoutDescriptor"		English="Lookup Table Data without Descriptor"
+Index="LUTDataWrongLength"			English="Lookup Table Data has wrong length"
+Index="LUTDescriptorBad"			English="Lookup Table Descriptor is bad"
+Index="LUTDescriptorNotNumeric"			English="Lookup Table Descriptor has non-numeric value representation"
+Index="LUTDescriptorWrongVM"			English="Lookup Table Descriptor has wrong value multiplicity"
+Index="Macro"					English="Macro"
+Index="MediaStorageSOPInstanceUIDDifferentFromSOPInstanceUID"	English="Media Storage SOP Instance UID different from SOP Instance UID"
+Index="MediaStorageSOPClassUIDDifferentFromSOPClassUID"	English="Media Storage SOP Class UID different from SOP Class UID"
+Index="MediaStorageSOPInstanceUIDButMissingSOPInstanceUIDAndNotADirectory"	English="Media Storage SOP Instance UID but missing SOP Instance UID and not a directory"
+Index="MediaStorageSOPClassUIDNotMediaStorageDirectoryStorageSOPClassUID"	English="Media Storage SOP Class UID not Media Storage Directory Storage SOP Class UID"
+Index="MediaStorageSOPClassUIDButMissingSOPClassUIDAndNotADirectory"	English="Media Storage SOP Class UID but missing SOP Class UID and not a directory"
+Index="MetaHeaderGroupLengthHasWrongVL"		English="Meta Information Header Group Length Has Wrong VL"
+Index="MetaHeaderGroupLengthNotUL"		English="Meta Information Header Group Length Not UL"
+Index="MetaHeaderGroupLengthValueReadFailed"	English="Meta Information Header Group Length Value Read Failed"
+Index="MetaHeaderIsImplicitVR"			English="Meta Information Header Is Implicit VR"
+Index="MetaHeaderMissingGroupLength"		English="Meta Information Header Missing Group Length"
+Index="MetaHeaderReadFailed"			English="Meta Information Header Read Failed"
+Index="MismatchDictionaryVR"			English="Explicit value representation doesn't match data dictionary"
+Index="MissingAttribute"			English="Missing attribute"
+Index="MissingAttributeValueNeededForDirectory"	English="Missing attribute or value that would be needed to build DICOMDIR"
+Index="MissingAttributeInReferencedImage"	English="Missing attribute in referenced image"
+Index="MissingDimensionIndexValueForInStackPositionNumber"			English="Missing DimensionIndexValue for InStackPositionNumber"
+Index="MissingDimensionIndexValueForTemporalPositionIndex"			English="Missing DimensionIndexValue for TemporalPositionIndex"
+Index="MissingInStackPositionNumberUsedAsDimensionIndex"			English="Missing InStackPositionNumber used as Dimension Index"
+Index="MissingLUTs"				English="Missing Lookup Tables"
+Index="MissingMandatoryAttributes"		English="Missing mandatory attributes"
+Index="MissingMetaheader"			English="Missing meta-information header"
+Index="MissingModuleInOneInstanceComparedToTheOther"			English="Missing Module"
+Index="MissingPixelRepresentation"		English="Missing Pixel Representation, can't set VR for element"
+Index="MissingSOPClassUIDBuildingMetaHeader"	English="Missing SOPClassUID in data set - can't make MediaStorageSOPClassUID for metainformation header"
+Index="MissingSOPInstanceUIDBuildingMetaHeader"	English="Missing SOPInstanceUID in data set - can't make MediaStorageSOPInstanceUID for metainformation header"
+Index="MissingTemporalPositionIndexUsedAsDimensionIndex"			English="Missing TemporalPositionIndex used as Dimension Index"
+Index="MissingValueInOneInstanceComparedToTheOtherOKIfType2"	English="Attribute is empty (zero length) in one instance - OK only If Type 2 attribute in that IOD"
+Index="Module"					English="Module"
+Index="ModuleDefinition"			English="Module definition"
+Index="NeedBothVRAndByteOrder"			English="Must specify both byte order and value representation"
+Index="NeedBothWindowLevelWidth"		English="Must specify both window level and width"
+Index="Needed"					English="needed"
+Index="NeedOption"				English="Need option"
+Index="NoDictionaryVRUseExplicit"				English="Unrecognized tag - assuming explicit value representation OK"
+Index="NoDictionaryVRUseExplicitUN"				English="Unrecognized tag - explicit value representation is UN"
+Index="NotCheckingLUTDataMaximum"		English="Not checking LUT Data maximum value"
+Index="NotDICOMMessage"				English="Not a valid DICOM message"
+Index="NotEqualTo"				English="not equal to"
+Index="NothingButZeroComponents"		English="Nothing but zero components"
+Index="NonMonochromeSignedPixelRepresentation"	English="Signed PixelRepresentation for other than monochrome Photometric Interpretation"
+Index="NoNeedForWindowLevelWidth"		English="No need to specify window level or width for this Photometric Interpretation"
+Index="NoReplaceOrDelete"			English="Replace or delete not permitted in this application"
+Index="NormalizedInformationObject"				English="Normalized Information Object"
+Index="NormalizedRequired"			English="Normalized Required"
+Index="NoSuchElementInDictionary"		English="No such element in dictionary"
+Index="NotBothSignedOrUnsigned"			English="Can't use both signed and unsigned"
+Index="NotFound"				English="Not found"
+Index="NothingToDisplay"			English="Nothing to display"
+Index="NotListedInCurrentRequestedProcedureOrPertinentOtherEvidenceSequence"	English="Referenced SOP Instance is not listed in CurrentRequestedProcedureEvidenceSequence or PertinentOtherEvidenceSequence"
+Index="NoTransferSyntaxInMetaHeader"		English="Metaheader present but doesn't contain Transfer Syntax UID"
+Index="Null"					English=""
+Index="NumberOfDimensionIndexValuesDoesNotMatchNumberOfDimensions"	English="Number of values of DimensionIndexValues does not match number of items in DimensionIndexSequence"
+Index="NumberOfPerFrameFunctionalGroupsSequenceItemsDoesNotMatchNumberOfFrames"	English="Number of items in Per-frame Functional Groups Sequence does not match Number of Frames"
+Index="NumberOfValuesInVectorDoesNotMatchNumberOfFrames"					English="Number of values in vector does not match Number of Frames"
+Index="NumericAttributeHasDifferentValueInOneInstanceComparedToTheOther"	English="Numeric attribute has different value"
+Index="NumericStringAttributeHasDifferentValueInOneInstanceComparedToTheOther"		English="Numeric string attribute has different value"
+Index="NumericStringAttributeHasEqualValueButDifferentEncodingInOneInstanceComparedToTheOther"		English="Numeric string attribute has equal value but different encoding"
+Index="OfAttribute"				English="of attribute"
+Index="OnlyOnePixelSpacingValue"		English="Only one PixelSpacing value"
+Index="Optional"				English="Optional"
+Index="OptionRepeated"				English="Same option or variant present more than once - latest value used"
+Index="OptionRequired"				English="Option is required"
+Index="OptionsIncompatible"			English="Options incompatible"
+Index="OptionIncomplete"			English="Option incomplete"
+Index="OptionUnsupported"			English="Option unsupported"
+Index="Or"					English="or"
+Index="OrientationVectorsAreNotOrthogonal"	English="Orientation vectors are not orthogonal"
+Index="OrientationVectorIsNotUnitVector"	English="Orientation vector is not unit vector"
+Index="OutputFile"				English="outputfile"
+Index="OverridingVR"		English="Overriding VR"
+Index="OverridingUNWithDictionaryVR"		English="Overriding UN With Dictionary VR"
+Index="PatchStringTooLong"			English="Patch string longer than specified patch length"
+Index="PatchesNotInOrder"			English="Patches are not in order"
+Index="PatchesOverlap"				English="Patches overlap"
+Index="PatchesSameOffset"			English="Patches at same offset"
+Index="PatientOrientationRowAndColumnDirectionsCannotBeIdentical"			English="Patient Orientation row and column directions cannot be identical"
+Index="PixelAspectRatioNotPermittedWhenOneToOne"			English="Pixel Aspect Ratio may not be present when it has a ratio of 1:1"
+Index="PixelDataTargetNotAvailable"		English="Nowhere to put PixelData"
+Index="PixelDataReadFailed"			English="PixelData read failed"
+Index="PixelDataIncorrectVL"			English="PixelData has incorrect value length"
+Index="PixelDataIncorrectVR"			English="PixelData has incorrect value representation"
+Index="PixelRepresentationIncorrect"		English="Pixel Representation incorrect"
+Index="PixelRepresentationUnnecessary"		English="Pixel Representation unnecessary"
+Index="PixelSpacingDoesNotMatchImagerPixelSpacingButPixelSpacingCalibrationTypeNotPresent"		English="PixelSpacing does not match ImagerPixelSpacing but PixelSpacingCalibrationType not present"
+Index="PixelSpacingDoesNotMatchNominalScannedPixelSpacingButPixelSpacingCalibrationTypeNotPresent"		English="PixelSpacing does not match NominalScannedPixelSpacing but PixelSpacingCalibrationType not present"
+Index="Platform"			English="Platform"
+Index="PrematureEndOfItem"			English="Sequence Item with explicit length was prematurely delimited - assuming item finished"
+Index="PrematureEndOfMetaHeader"		English="Incomplete meta-information header"
+Index="PrematureEndOfSequence"			English="Sequence with explicit length was prematurely delimited - assuming sequence finished"
+Index="Preprocessor"			English="Preprocessor"
+Index="PrivateCreatorIsNotLOVR"			English="Private creator is not LO VR"
+Index="PrivateTagWithoutOwner"			English="Private tag without owner"
+Index="RangeInvalidForThisVR"			English="Range invalid for this VR"
+Index="ReadFailed"				English="Read failed"
+Index="RecognizedBitMap"			English="Recognized bitmap"
+Index="RecognizedDefinedTerm"			English="Recognized defined term"
+Index="RecognizedEnumeratedValue"		English="Recognized enumerated value"
+Index="ReferencedFileIDHasEmptyComponents"	English="Referenced File ID is empty or has empty components"
+Index="Replacing"				English="Replacing"
+Index="Required"				English="Required"
+Index="RequiredBy"				English="Required by"
+Index="Retired"			English="Retired"
+Index="RetiredAttribute"			English="Retired attribute"
+Index="RetiredPersonNameForm"			English="Retired Person Name form"
+Index="ScaledNumericValuesForSameConceptAreInconsistent"			English="Scaled numeric values for same concept are inconsistent"
+Index="SeekFailed"				English="Seek failed"
+Index="SeqAttrReadFailed"			English="Sequence attribute read failed"
+Index="SequenceHasDifferentNumberOfItemsInOneInstanceComparedToTheOther"			English="Sequence has different number of items"
+Index="SequenceHasDifferentValueRepresentationInOneInstanceComparedToTheOther"			English="Sequence has different value representation"
+Index="SequenceItemReadFailed"			English="Sequence Item dataset read failed - giving up"
+Index="SharedMemoryAllocationFailed"		English="Can't allocate shared memory"
+Index="SharedMemoryAttachFailed"		English="Can't attach shared memory"
+Index="ShouldBe"				English="Should be"
+Index="Signed"					English="Signed"
+Index="SkippingBadTagInsideUndefinedLengthSequence"		English="Skipping bad tag inside undefined length sequence"
+Index="SkippingToEndOfEnclosingFixedLengthSequence"		English="Skipping to end of enclosing fixed length sequence"
+Index="SOPClassInCurrentRequestedProcedureOrPertinentOtherEvidenceSequenceDoesNotMatchReference"	English="SOP Class in CurrentRequestedProcedureEvidenceSequence or PertinentOtherEvidenceSequence does not match reference"
+Index="SpecifiedAs"				English="specified as"
+Index="SpecifiedLength"				English="specified length"
+Index="SpecifiedNumberOfVectorValuesDoesNotMatchActualValuesInVector"		English="Specified number of vector values does not match actual values in vector"
+Index="StringAttributeHasDifferentValueInOneInstanceComparedToTheOther"		English="String attribute has different value"
+Index="TagReadFailed"				English="Tag read failed"
+Index="TagsDuplicated"				English="Tags out of order - same element occurs twice"
+Index="TagsOutOfOrder"				English="Tags out of order - trailing garbage, wrong transfer syntax, or not valid DICOM"
+Index="TooManyComponentDelimitersInPersonName"		English="Too many delimiters (^) in PersonName"
+Index="TooManyComponentGroupDelimitersInPersonName"		English="Too many component group delimiters (=) in PersonName"
+Index="TrailingCharacterInvalidForThisVR"		English="Trailing character invalid for this VR"
+Index="TriedToVerifyBitMapForNonNumericAttribute"		English="Non-numeric attribute while verifying bitmap"
+Index="TriedToVerifyDefinedTermsForNonStringAttribute"		English="Non-string attribute while verifying string defined terms"
+Index="TriedToVerifyEnumeratedValueForNonNumericAttribute"	English="Non-numeric attribute while verifying numeric enumerated value"
+Index="TriedToVerifyEnumeratedValueForNonStringAttribute"	English="Non-string attribute while verifying string enumerated value"
+Index="TriedToVerifyEnumeratedValueForNonTagAttribute"		English="Non-tag attribute while verifying tag enumerated value"
+Index="TriedToVerifyNotZeroForNonNumericAttribute"	English="Non-numeric attribute while verifying not zero value"
+Index="Type1"					English="Type 1 Required"
+Index="Type1C"					English="Type 1C Conditional"
+Index="Type2"					English="Type 2 Required"
+Index="Type2C"					English="Type 2C Conditional"
+Index="Type3"					English="Type 3 Optional"
+Index="UCUMCodingSchemeDesignatorIsUsedInSequenceOtherThanUnitsCodeSequence"	English="UCUM Coding Scheme Designator is used in sequence other than a Units Code Sequence"
+Index="UID"					English="uniqueidentifier"
+Index="UIDRoot"					English="UID Root"
+Index="UndefinedVLForOX"			English="Undefined value length of other byte/word element is illegal in non-encapsulated transfer syntax"
+Index="UndesirableAttribute"			English="Undesirable attribute"
+Index="UnexpectedNullInString"			English="Unexpected null in string"
+Index="Unexpected"				English="Unexpected"
+Index="UnexpectedVL"				English="Unexpected value length"
+Index="UnexpectedTransferSyntaxUIDOutsideMetaInformationHeader"				English="Unexpected TransferSyntaxUID outside meta information header"
+Index="Unnecessary"				English="Unnecessary"
+Index="UnrecognizedBitMap"			English="Unrecognized bitmap"
+Index="UnrecognizedDefinedTerm"			English="Unrecognized defined term"
+Index="UnrecognizedEnumeratedValue"		English="Unrecognized enumerated value"
+Index="UnrecognizedElement"			English="Unrecognized element name"
+Index="UnrecognizedFormat"			English="Unrecognized format"
+Index="UnrecognizedTag"				English="Unrecognized tag - skipping"
+Index="UnrecognizedOrUnsupportedTag"				English="Unrecognized or unsupported tag - skipping"
+Index="UnrecognizedSOPClass"	English="Unrecognized SOP Class"
+Index="UnrecognizedVR"				English="Unrecognized value representation"
+Index="Unsigned"				English="Unsigned"
+Index="Unsupported"				English="Unsupported"
+Index="Usage"					English="Usage"
+Index="Using"					English="using"
+Index="ValidElement"				English="Valid Element"
+Index="Value"					English="Value"
+Index="ValueDubiousForThisVR"			English="Value dubious for this VR"
+Index="ValueInvalidForThisVR"			English="Value invalid for this VR"
+Index="ValueLengthExceedsFixedLengthForReadingDataset"			English="Value Length exceeds fixed length for reading dataset"
+Index="ValuePresentInOneInstanceButNotTheOther"	English="Value present in one instance but not the other"
+Index="Verifying"				English="Verifying"
+Index="Version"				English="Version"
+Index="VLDoesNotMatchVR"				English="Value length does not match value representation"
+Index="VLExceedsExplicitVRMaximium"				English="Value length exceeds the largest encodable in 16 bit length field of explicit value representation (0xffff or 65535 dec)"
+Index="VLReadFailed"				English="Value length read failed"
+Index="VMNot0Or1"				English="Value Multiplicity not 0 or 1"
+Index="VRReadFailed"				English="Value representation read failed"
+Index="VRUnsupported"				English="Value representation unsupported by this implementation"
+Index="WantedElementAndDelimitedValues"		English="Expected element name and argument containing backslash delimited list of values"
+Index="Warning"					English="Warning"
+Index="WaveformSequenceInternallyInconsistent"	English="WaveformSequence is internally inconsistent"
+Index="WhileSkipping"				English="While skipping"
+Index="WriteFailed"				English="Write failed"
+Index="WrongNumberOfArguments"			English="Wrong number of arguments"
+Index="XImageCreationFailed"			English="Can't create X image"
+Index="XImageDataAllocationFailed"		English="Can't allocate data for X image"
+Index="XSharedMemorySegmentCreationFailed"	English="Can't create X shared memory segment"
+Index="XSharedMemoryExtensionUnsupported"	English="X shared memory extension not supported"
+Index="XSharedMemoryPixmapsUnsupported"		English="X shared memory extension pixmaps not supported"
+Index="ZeroValue"			English="Value is zero"
diff --git a/libsrc/src/ourdisp/Imakefile b/libsrc/src/ourdisp/Imakefile
new file mode 100755
index 0000000..df72b67
--- /dev/null
+++ b/libsrc/src/ourdisp/Imakefile
@@ -0,0 +1,16 @@
+MANSUFFIX = 3
+
+CPLUSPLUS_EXTRA_INCLUDES  = $(PROJECTLIBOURDISPEXTRAINCLUDES)
+
+CPLUSPLUS_SRCS = ourdisp.cc
+
+OBJS =           ourdisp.o
+
+LibraryTarget($(PROJECTLIBDIR)/lib$(PROJECTOURDISPLIBNAME).a,$(OBJS))
+
+depend::	wlcursor.cbm wlmask.cbm
+
+clean::
+	rm -f wlcursor.cbm wlmask.cbm
+
+DependCCTarget()
diff --git a/libsrc/src/ourdisp/ourdisp.cc b/libsrc/src/ourdisp/ourdisp.cc
new file mode 100644
index 0000000..72ffa1f
--- /dev/null
+++ b/libsrc/src/ourdisp/ourdisp.cc
@@ -0,0 +1,901 @@
+static const char *CopyrightIdentifier(void) { return "@(#)ourdisp.cc Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved."; }
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <iostream>
+#include <iomanip>
+#else
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+#include "basetype.h"
+#include "errclass.h"
+#include "ourdisp.h"
+#include "mesgtext.h"
+
+OurDisplay::OurDisplay(void)
+{
+	name = NULL;
+	if ((display=XOpenDisplay(name)) == NULL) {
+		errorstream << EMsgDC(DisplayOpenFailed) << endl;
+		good_flag=false;
+	}
+	else {
+		screen     = DefaultScreen(display);
+		rootwindow = RootWindow(display,screen);
+		visual     = DefaultVisual(display,screen);
+		depth      = DefaultDepth(display,screen);
+		bitmappad  = XBitmapPad(display);
+	}
+}
+
+OurDisplay::~OurDisplay()
+{
+	XCloseDisplay(display);
+}
+
+XEvent OurDisplay::nextEvent(void)
+{
+	XEvent report;
+	XNextEvent(display,&report);
+	return report;
+}
+
+OurColorMap::OurColorMap(OurDisplay *d)
+{
+	display=d;
+	Assert(display);
+
+	cells=0;
+	length=0;
+	colormap=(Colormap)None;
+}
+
+OurColorMap::~OurColorMap(void)
+{
+	if (colormap != (Colormap) None)
+		XFreeColormap(
+			display->getDisplay(),
+			colormap
+		);
+	if (cells) delete[] cells;
+}
+
+bool
+OurColorMap::setColorCellsWanted(unsigned nwanted,unsigned nminimum)
+{
+//cerr << "OurColorMap::setColorCellsWanted nwanted=" << dec << nwanted << endl;
+//cerr << "OurColorMap::setColorCellsWanted nminimum=" << dec << nminimum << endl;
+	Assert(!cells);
+	cells = new unsigned long [nwanted];
+	Assert(cells);
+
+	// will always tried to get nwanted, but
+	// will use default if can get nminimum
+	// else will try creating private map
+
+	// using the default is much preferrable because
+	// of reduced flashing
+
+	// not using XCopyColormapAndFree() from default
+	// to private because assuming application has
+	// not yet allocated any colors
+
+	bool trieddefault=false;
+	bool triedcreate=false;
+	bool triedwithoutbw=false;
+
+	XColor whitecolor;
+	whitecolor.red=0xffff;
+	whitecolor.green=0xffff;
+	whitecolor.blue=0xffff;
+	XColor blackcolor;
+	blackcolor.red=0;
+	blackcolor.green=0;
+	blackcolor.blue=0;
+
+	unsigned n=0;
+	while (n < nminimum) {
+//cerr << "OurColorMap::setColorCellsWanted loop start"
+//     << " n=" << dec << n
+//     << " nminimum=" << dec << nminimum
+//     << endl;
+		if (!trieddefault) {
+//cerr << "OurColorMap::setColorCellsWanted try DefaultColormap" << endl;
+			colormap = DefaultColormap(
+				display->getDisplay(),
+				display->getScreen()
+			);
+			trieddefault=true;
+		}
+		else if (!triedcreate) {
+//cerr << "OurColorMap::setColorCellsWanted try XCreateColormap" << endl;
+			colormap = XCreateColormap(
+				display->getDisplay(),
+				display->getRootwindow(),
+				display->getVisual(),
+				AllocNone
+			);
+			triedcreate=true;
+
+			// make sure white & black are present in correct order,
+			// otherwise writes in the reserved area won't work
+			// (these will already be present in the default map
+
+			if (!XAllocColor(display->getDisplay(),
+				colormap,&whitecolor)
+			 || !XAllocColor(display->getDisplay(),
+				colormap,&blackcolor)
+			) Assert(0);
+		}
+		else if (!triedwithoutbw) {
+//cerr << "OurColorMap::setColorCellsWanted try XCreateColormap no bw" << endl;
+			colormap = XCreateColormap(
+				display->getDisplay(),
+				display->getRootwindow(),
+				display->getVisual(),
+				AllocNone
+			);
+			triedwithoutbw=true;
+			// Hope for the best re. black and white :(
+		}
+		else {
+//cerr << "OurColorMap::setColorCellsWanted tries failed" << endl;
+			break;
+		}
+		if (colormap == (Colormap) None) {
+			errorstream << EMsgDC(ColorMapCreationFailed) << endl;
+			continue;
+		}
+
+		n=nwanted;	// always optimistic
+		while (n && !XAllocColorCells(
+			display->getDisplay(),
+			colormap,
+			False,			// contiguous planes
+			(unsigned long *) 0,	// plane masks
+			0,			// # of planes
+			cells,
+			n)
+		) --n;
+//cerr << "OurColorMap::setColorCellsWanted loop done"
+//     << " n=" << dec << n
+//     << " nminimum=" << dec << nminimum
+//     << endl;
+	}
+
+//cerr << "OurColorMap::setColorCellsWanted got=" << dec << n << endl;
+
+	length=n;
+
+	if (!n) {
+		errorstream << EMsgDC(ColorCellAllocationFailedNone) << endl;
+		good_flag=false;
+	}
+	else if (n < nminimum) {
+		errorstream << EMsgDC(ColorCellAllocationFailedTooFew)
+			    << " - " << n << " " << MMsgDC(Needed) << " "
+			    << nminimum << "/" << nwanted << endl;
+		good_flag=false;
+	}
+	return good_flag;
+}
+
+bool
+OurColorMap::getColorCellsAvailable(unsigned &n,unsigned long *&table)
+{
+//cerr << "OurColorMap::getColorCellsAvailable length=" << dec << length << endl;
+	if (length && cells) {
+		n=length;
+		table=cells;
+	}
+	else {
+		n=0;
+		table=0;
+		good_flag=false;
+	}
+	return good_flag;
+}
+
+bool
+OurColorMap::setColorCellValues(unsigned n,
+	unsigned short *red,
+	unsigned short *green,
+	unsigned short *blue)
+{
+//cerr << "OurColorMap::setColorCellValues n=" << dec << n << endl;
+	Assert(n == length);
+	XColor c;
+	c.flags=DoRed | DoGreen | DoBlue;
+	unsigned i;
+	for (i=0; i<length; ++i) {
+		c.pixel	= cells[i];
+		c.red	= red[i];
+		c.green	= green[i];
+		c.blue	= blue[i];
+//cerr << "i=" << dec << i
+//     << " pixel=" << dec << c.pixel
+//     << " red=" << hex << c.red
+//     << " green=" << hex << c.green
+//     << " blue=" << hex << c.blue
+//     << dec << endl;
+		XStoreColor(
+			display->getDisplay(),
+			colormap,
+			&c);
+	}
+	return true;
+}
+
+OurWindow::OurWindow(OurDisplay *d,
+	unsigned w,unsigned h,
+	unsigned headerh,unsigned footerh)
+{
+	ourdisplay=d;
+
+	x=0;
+	y=0;
+	width=w;
+	border=4;
+
+	headerheight=headerh;
+	footerheight=footerh;
+
+	imageheight=h;
+	totalheight=imageheight+headerheight+footerheight;
+
+	foreground=WhitePixel(getDisplay(),getScreen());
+	background=BlackPixel(getDisplay(),getScreen());
+
+	window = XCreateSimpleWindow(
+		getDisplay(),
+		getRootwindow(),
+		x,y,width,totalheight,
+		border,
+		foreground,
+		background
+	);
+
+	reservedareagc = XCreateGC(getDisplay(),window,0,NULL);
+	XSetForeground(getDisplay(),reservedareagc,foreground);
+	XSetBackground(getDisplay(),reservedareagc,background);
+	reservedareafont=XQueryFont(getDisplay(),XGContextFromGC(reservedareagc));
+	Assert(reservedareafont);
+
+	clearHeader();
+	clearFooter();
+}
+
+OurWindow::~OurWindow(void)
+{
+	XDestroyWindow(
+		getDisplay(),
+		window
+	);
+}
+
+void
+OurWindow::start(void)
+{
+	XSelectInput(getDisplay(),window,
+		ExposureMask
+		|ButtonPressMask|ButtonReleaseMask
+		|Button1MotionMask
+		|PointerMotionMask
+		|KeyPressMask);
+	XMapWindow(getDisplay(),window);
+}
+
+void
+OurWindow::clear(void)
+{
+	XClearWindow(getDisplay(),window);
+}
+
+void
+OurWindow::alarm(void)
+{
+	XBell(getDisplay(),100);
+	XFlush(getDisplay());
+}
+
+void
+OurWindow::setColormap(OurColorMap *ourcolormap)
+{
+	XSetWindowColormap(
+		getDisplay(),
+		getWindow(),
+		ourcolormap->getColormap()
+	);
+
+	// these may have changed ... it may be worth searching
+	// the new colormap to find the best choices ...
+	// (the default choices here will probably not work if
+	// the default colormap has been replaced :( )
+
+	foreground=WhitePixel(getDisplay(),getScreen());
+	background=BlackPixel(getDisplay(),getScreen());
+
+	XSetForeground(getDisplay(),reservedareagc,foreground);
+	XSetBackground(getDisplay(),reservedareagc,background);
+}
+
+void
+OurWindow::writeTextSomewhere(int baseline,
+	const char *left,const char *center,const char *right)
+{
+//cerr << "write at =" << baseline << endl;
+
+	int length;
+	if (left && (length=strlen(left))) {
+		XDrawImageString(getDisplay(),window,reservedareagc,
+			width/20,baseline,left,length);
+	}
+	if (center && (length=strlen(center))) {
+		int textwidth=XTextWidth(reservedareafont,center,length);
+		int offset=textwidth < width ? (width-textwidth)/2 : 0;
+		XDrawImageString(getDisplay(),window,reservedareagc,
+			offset,baseline,center,length);
+	}
+	if (right && (length=strlen(right))) {
+		int textwidth=XTextWidth(reservedareafont,right,length);
+		int offset=textwidth < width-width/20 ? width-width/20-textwidth : 0;
+		XDrawImageString(getDisplay(),window,reservedareagc,
+			offset,baseline,right,length);
+	}
+	XFlush(getDisplay());
+}
+
+void
+OurWindow::writeHeaderText(
+	const char *left,const char *center,const char *right)
+{
+//cerr << "fid=" << reservedareafont->fid << endl;
+//cerr << "ascent=" << reservedareafont->ascent << endl;
+//cerr << "descent=" << reservedareafont->descent << endl;
+
+	int baseline=(headerheight
+			+reservedareafont->ascent
+			+reservedareafont->descent)/2+1;
+
+	//int baseline=headerheight-reservedareafont->descent+1;
+
+	writeTextSomewhere(baseline,left,center,right);
+}
+
+void
+OurWindow::writeFooterText(
+	const char *left,const char *center,const char *right)
+{
+//cerr << "fid=" << reservedareafont->fid << endl;
+//cerr << "ascent=" << reservedareafont->ascent << endl;
+//cerr << "descent=" << reservedareafont->descent << endl;
+
+	int baseline=headerheight+imageheight
+	            +(footerheight
+			+reservedareafont->ascent
+			+reservedareafont->descent)/2
+		    +1;
+
+	//int baseline=totalheight-reservedareafont->descent+1;
+
+	writeTextSomewhere(baseline,left,center,right);
+}
+
+void
+OurWindow::clearHeader(void)
+{
+	if (headerheight) {
+		XClearArea(getDisplay(),window,
+			0,0,
+			width,headerheight,
+			False // No exposure event generated
+		);
+		XFlush(getDisplay());
+	}
+}
+
+void
+OurWindow::clearFooter(void)
+{
+	if (footerheight) {
+		XClearArea(getDisplay(),window,
+			0,imageheight+headerheight,
+			width,footerheight,
+			False // No exposure event generated
+		);
+		XFlush(getDisplay());
+	}
+}
+
+void
+OurWindow::reportPosition(
+	int x,int y,
+	unsigned short &row,unsigned short &col) const
+{
+	int r=y-headerheight;
+	if (r < 0) r=0;
+	else if (r>=imageheight) r=imageheight-1;
+
+	row=(unsigned short)r;
+	col=(unsigned short)x;
+}
+
+#include "wlcursor.cbm"
+#include "wlmask.cbm"
+
+void
+OurWindow::useCursorLevelWidth(void)
+{
+	static bool initialized;
+	static Cursor cursor;
+
+	if (!initialized) {
+		initialized=true;
+//cerr << "OurWindow::useCursorLevelWidth:: creating" << endl;
+		Pixmap bitmap=XCreateBitmapFromData(getDisplay(),window,
+			(const char *)wlcursor_xbm_bits,
+			wlcursor_xbm_width,
+			wlcursor_xbm_height);
+		Pixmap maskbitmap=XCreateBitmapFromData(getDisplay(),window,
+			(const char *)wlmask_xbm_bits,
+			wlmask_xbm_width,
+			wlmask_xbm_width);
+
+		// color really doesn't matter ...
+
+		XColor foregroundcolor;
+		XColor backgroundcolor;
+		foregroundcolor.pixel=WhitePixel(getDisplay(),getScreen());
+		backgroundcolor.pixel=BlackPixel(getDisplay(),getScreen());
+		XQueryColor(getDisplay(),
+			DefaultColormap(getDisplay(),getScreen()),
+			&foregroundcolor);
+		XQueryColor(getDisplay(),
+			DefaultColormap(getDisplay(),getScreen()),
+			&backgroundcolor);
+
+		cursor=XCreatePixmapCursor(getDisplay(),
+			bitmap,
+			maskbitmap,
+			&foregroundcolor,
+			&backgroundcolor,
+			wlcursor_xbm_width/2-1,
+			wlcursor_xbm_height/2-1);
+		XFreePixmap(getDisplay(),bitmap);
+		XFreePixmap(getDisplay(),maskbitmap);
+	}
+	XDefineCursor(getDisplay(),window,cursor);
+	XFlush(getDisplay());
+}
+
+void
+OurWindow::useCursorCrossHair(void)
+{
+	static bool initialized;
+	static Cursor cursor;
+
+	if (!initialized) {
+		initialized=true;
+//cerr << "OurWindow::useCursorCrossHair:: creating" << endl;
+		cursor=XCreateFontCursor(getDisplay(),34);
+	}
+	XDefineCursor(getDisplay(),window,cursor);
+	XFlush(getDisplay());
+}
+
+void
+OurWindow::useCursorWatch(void)
+{
+	static bool initialized;
+	static Cursor cursor;
+
+	if (!initialized) {
+		initialized=true;
+//cerr << "OurWindow::useCursorCrossHair:: creating" << endl;
+		cursor=XCreateFontCursor(getDisplay(),150);
+	}
+	XDefineCursor(getDisplay(),window,cursor);
+	XFlush(getDisplay());
+}
+
+void
+OurWindow::redraw(void)
+{
+	_XEvent event;
+	event.type=Expose;
+	event.xexpose.count = 0;
+
+	// should probably set a bunch of other stuff, but works for our app 
+
+	XSendEvent(getDisplay(),window,
+		False,	// propagate - the X not C++ false
+		ExposureMask,&event
+	);							
+}
+
+OurWindowImage::OurWindowImage(OurWindow *w)
+{
+	good_flag=true;
+	window=w;
+	ximage=0;
+
+#if USEXMITSHMEXTENSION == 1
+
+	bool shm_flag=true;
+	xshminfo=0;
+
+	int vmajor;
+	int vminor;
+	Bool vpixmap;
+	if (XShmQueryVersion(window->getDisplay(),&vmajor,&vminor,&vpixmap) != True) {	// the X style True !
+		errorstream << WMsgDC(XSharedMemoryExtensionUnsupported) << endl;
+		shm_flag=false;
+	}
+	else if (vpixmap != True) {	// the X style True !
+		errorstream << WMsgDC(XSharedMemoryPixmapsUnsupported) << endl;
+		shm_flag=false;
+	}
+	else {
+		xshminfo=(XShmSegmentInfo *) new char[sizeof(XShmSegmentInfo)];
+		if (xshminfo) {
+			ximage = XShmCreateImage(window->getDisplay(),
+					window->getVisual(),
+					window->getDepth(),
+					ZPixmap,
+					(char *) 0,	// image data
+					xshminfo,
+					window->getImageWidth(),
+					window->getImageHeight()
+			);
+			if (ximage) {
+				Assert(xshminfo);
+				xshminfo->shmid=shmget(IPC_PRIVATE,ximage->bytes_per_line*ximage->height,IPC_CREAT|0777);
+				if (xshminfo->shmid < 0) {
+					errorstream << WMsgDC(SharedMemoryAllocationFailed) << " - "
+					    << (ximage->bytes_per_line*ximage->height)
+					    << " " << MMsgDC(Bytes) << endl;
+					shm_flag=false;
+					XDestroyImage(ximage);
+					ximage=0;
+					delete[] xshminfo;	// otherwise destructor or fall back get messed up
+					xshminfo=0;
+//cerr << "OurWindowImage::OurWindowImage: SharedMemoryAllocationFailed exit" << endl;
+				}
+				else {
+					Assert(xshminfo);
+					xshminfo->shmaddr=(char *)shmat(xshminfo->shmid,0,0);
+					if (xshminfo->shmaddr == (char *)-1) {
+						errorstream << WMsgDC(SharedMemoryAttachFailed) << endl;
+						shm_flag=false;
+						shmctl(xshminfo->shmid,IPC_RMID,0);
+						XDestroyImage(ximage);
+						ximage=0;
+						delete[] xshminfo;	// otherwise destructor or fall back get messed up
+						xshminfo=0;
+					}
+					else {
+						Assert(ximage);
+						ximage->data=xshminfo->shmaddr;
+						Assert(xshminfo);
+						xshminfo->readOnly=False;	// the X style False !
+						XShmAttach(window->getDisplay(),xshminfo);
+//cerr << "OurWindowImage::OurWindowImage: shared memory successfully allocated and attached" << endl;
+						// Good to go ...
+					}
+				}
+			}
+			else {
+				errorstream << WMsgDC(XImageCreationFailed) << endl;
+				shm_flag=false;
+				delete[] xshminfo;	// otherwise destructor or fall back get messed up
+				xshminfo=0;
+			}
+		}
+		else {
+			errorstream << WMsgDC(XSharedMemorySegmentCreationFailed) << endl;
+			shm_flag=false;
+		}
+	}
+
+	if (!shm_flag) {	// do it without shared memory ...
+//cerr << "OurWindowImage::OurWindowImage: fall through to do it without shared memory" << endl;
+		Assert(!xshminfo);
+		Assert(!ximage);
+#endif
+//cerr << "OurWindowImage::OurWindowImage: creating non-shared X Image" << endl;
+		ximage = XCreateImage(window->getDisplay(),
+				window->getVisual(),
+				window->getDepth(),
+				ZPixmap,
+				0,		// offset
+				(char *) 0,	// image data
+				window->getImageWidth(),
+				window->getImageHeight(),
+				window->getBitmapPad(),
+				0		// bytes per line
+		);
+		if (ximage) {
+			ximage->data = new char [ximage->bytes_per_line*ximage->height];
+			if (!ximage->data) {
+				errorstream << EMsgDC(XImageDataAllocationFailed) << " - "
+					    << (ximage->bytes_per_line*ximage->height)
+					    << " " << MMsgDC(Bytes) << endl;
+				good_flag=false;
+				XDestroyImage(ximage);
+				ximage=0;
+			}
+		}
+		else {
+			errorstream << EMsgDC(XImageCreationFailed) << endl;
+			good_flag=false;
+		}
+#if USEXMITSHMEXTENSION == 1
+	}
+#endif
+//cerr << "OurWindowImage::OurWindowImage: creating GC" << endl;
+	if (good_flag && ximage) {
+#ifdef USEDEFAULTGCFORIMAGE
+		imagegc = DefaultGC(
+				window->getDisplay(),
+				window->getScreen()
+		);
+#else
+		imagegc = XCreateGC(window->getDisplay(),window->getWindow(),0,NULL);
+		XSetForeground(window->getDisplay(),imagegc,WhitePixel(window->getDisplay(),window->getScreen()));
+		XSetBackground(window->getDisplay(),imagegc,BlackPixel(window->getDisplay(),window->getScreen()));
+#endif
+	}
+//cerr << "OurWindowImage::OurWindowImage: at end, shm_flag=" << (shm_flag ? "T":"F") << endl;
+//cerr << "OurWindowImage::OurWindowImage: end" << endl;
+}
+
+OurWindowImage::~OurWindowImage()
+{
+//cerr << "OurWindowImage::~OurWindowImage: start" << endl;
+#if USEXMITSHMEXTENSION == 1
+	if (xshminfo) {
+//cerr << "OurWindowImage::~OurWindowImage: destroying xshminfo" << endl;
+		XShmDetach(window->getDisplay(),xshminfo);
+		ximage->data=0;
+		shmdt(xshminfo->shmaddr);
+		shmctl(xshminfo->shmid,IPC_RMID,0);
+		delete[] xshminfo;
+	}
+#endif
+	if (ximage) {
+//cerr << "OurWindowImage::~OurWindowImage: destroying ximage" << endl;
+		if (ximage->data) delete[] ximage->data;
+		XDestroyImage(ximage);
+		ximage=0;
+	}
+//cerr << "OurWindowImage::~OurWindowImage: end" << endl;
+}
+
+void
+OurWindowImage::put(void)
+{
+//cerr << "OurWindowImage::put: start" << endl;
+	Assert(ximage);
+	Assert(ximage->data);
+#if USEXMITSHMEXTENSION == 1
+//cerr << "OurWindowImage::put: shm_flag=" << (shm_flag ? "T":"F") << endl;
+	//if (shm_flag) {
+	if (xshminfo) {
+//cerr << "OurWindowImage::put: XShmPutImage" << endl;
+		XShmPutImage(
+			window->getDisplay(),
+			window->getWindow(),
+			imagegc,ximage,
+			0,0,
+			window->getImageStartX(),window->getImageStartY(),
+			window->getImageWidth(),window->getImageHeight(),
+			False	// send event
+		);
+	}
+	else {
+#endif
+//cerr << "OurWindowImage::put: XPutImage" << endl;
+		XPutImage(
+			window->getDisplay(),
+			window->getWindow(),
+			imagegc,ximage,
+			0,0,
+			window->getImageStartX(),window->getImageStartY(),
+			window->getImageWidth(),window->getImageHeight()
+		);
+#if USEXMITSHMEXTENSION == 1
+	}
+#endif
+}
+
+char *
+OurWindowImage::get8BitDataAddress(void)
+{
+	return ximage->depth == 8
+		? ximage->data
+		: 0;
+}
+
+bool
+OurWindowImage::write8BitDataToStream(ostream &o)
+{
+	Assert(getDepth() == 8);
+
+	char *pixels=get8BitDataAddress();
+	Assert(pixels);
+
+	unsigned row=0;
+	char *p = pixels;
+	while (row++ < getHeight() && o) {
+		o.write(p,getWidth());
+		p+=getBytesPerRow();
+	}
+	return o ? true : false;
+}
+
+bool
+OurWindowImage::write8BitDataToPGMStream(ostream &o)
+{
+	o << "P5\n";
+	o << getWidth() << " " << getHeight() << " 255\n";	// check this doesn't translate to \n on non-unix :(
+
+	return write8BitDataToStream(o);
+}
+
+void
+OurWindowImage::putPoint(unsigned x,unsigned y)
+{
+//cerr << "OurWindowImage::putPoint: start" << endl;
+
+	Assert(x < window->getImageWidth());
+	Assert(y < window->getImageHeight());
+
+//if (window->getImageStartY()+y < window->getImageHeight()) {
+//	cerr << "OurWindowImage::putPoint:" << dec 
+//	     << " window->getImageStartY()=" << window->getImageStartY()
+//	     << " y=" << y
+//	     << " window->getImageHeight()=" << window->getImageHeight()
+//	     << endl;
+//}
+
+	XDrawPoint(
+		window->getDisplay(),
+		window->getWindow(),
+		imagegc,
+		window->getImageStartX()+x,
+		window->getImageStartY()+y
+	);
+}
+
+OurWindowLevelWidthUpdator::OurWindowLevelWidthUpdator(
+	OurWindow &w,Uint16 bits,bool issigned,
+	double rescaleintercept,double rescaleslope)
+{
+	window=&w;
+	maplevelmin=0;
+	maplevelmax=(1<<bits)-1;
+	mapwidthmin=0;
+	mapwidthmax=(1<<bits)-1;
+	maplevel=maplevelmax/2;
+	mapwidth=mapwidthmax/4;
+//cerr << "width min" << mapwidthmin  << " level min " << maplevelmin << endl;
+//cerr << "width max" << mapwidthmax  << " level max " << maplevelmax << endl;
+//cerr << "width " << mapwidth  << " level " << maplevel << endl;
+	signxor=issigned ? 1l<<(bits-1) : 0;
+	Assert(rescaleintercept<=LONG_MAX);
+	Assert(rescaleintercept>=LONG_MIN);
+	intercept=long(rescaleintercept);
+	Assert(rescaleslope<=LONG_MAX/1024);
+	Assert(rescaleslope>=LONG_MIN/1024);
+	slopeby1024=long(rescaleslope*1024);
+}
+
+OurWindowLevelWidthUpdator::~OurWindowLevelWidthUpdator()
+{}
+
+void
+OurWindowLevelWidthUpdator::set(Uint16 level,Uint16 width)
+{
+	maplevel=level;
+	mapwidth=width;
+	Assert(mapwidth>=mapwidthmin);
+	Assert(mapwidth<=mapwidthmax);
+	Assert(maplevel>=maplevelmin);
+	Assert(maplevel<=maplevelmax);
+}
+
+void
+OurWindowLevelWidthUpdator::get(Uint16 &level,Uint16 &width)
+{
+	Assert(maplevel<=Uint16_MAX);
+	Assert(mapwidth<=Uint16_MAX);
+	level=Uint16(maplevel);
+	width=Uint16(mapwidth);
+}
+
+Uint16
+OurWindowLevelWidthUpdator::getStoredLevelFromDisplayedLevel(long l)
+{
+	return Uint16((l-intercept)*1024/slopeby1024+signxor);
+}
+
+Uint16
+OurWindowLevelWidthUpdator::getStoredWidthFromDisplayedWidth(long w)
+{
+	return Uint16(w*1024/slopeby1024);
+}
+
+long
+OurWindowLevelWidthUpdator::getDisplayedLevelFromStoredLevel(long l)
+{
+	return (l-signxor)*slopeby1024/1024+intercept;
+}
+
+long
+OurWindowLevelWidthUpdator::getDisplayedWidthFromStoredWidth(long w)
+{
+	return w*slopeby1024/1024;
+}
+
+void
+OurWindowLevelWidthUpdator::put(void)
+{
+	ostrstream levelostr;
+	levelostr << "level " << setw(6) << getDisplayedLevelFromStoredLevel(maplevel) << ends;
+	char *levelstr = levelostr.str();
+
+	ostrstream widthostr;
+	widthostr << "width " << setw(6) << getDisplayedWidthFromStoredWidth(mapwidth) << ends;
+	char *widthstr = widthostr.str();
+
+	window->clearFooter();
+	window->writeFooterText(levelstr,0,widthstr);
+
+	if (levelstr) delete[] levelstr;
+	if (widthstr) delete[] widthstr;
+}
+
+void
+OurWindowLevelWidthUpdator::press(long x,long y)
+{
+	lastx=x;
+	lasty=y;
+}
+
+void
+OurWindowLevelWidthUpdator::release(long x,long y)
+{
+	// Don't update ... it is irritating to have
+	// the values change slightly on button release
+	(void)x; (void)y;
+}
+
+void
+OurWindowLevelWidthUpdator::move(long deltax,long deltay,long multiplier)
+{
+	update(lastx+deltax,lasty+deltay,multiplier);
+}
+
+void
+OurWindowLevelWidthUpdator::update(long x,long y,long multiplier)
+{
+//cerr << "position " << x << "," << y << endl;
+	long deltax=(x-lastx)*multiplier;	// +ve to right
+	long deltay=(lasty-y)*multiplier;	// +ve upwards
+//cerr << "delta " << deltax << "," << deltay << endl;
+	lastx=x;
+	lasty=y;
+	mapwidth+=deltax;
+	if (mapwidth<mapwidthmin) mapwidth=mapwidthmin;
+	if (mapwidth>mapwidthmax) mapwidth=mapwidthmax;
+	maplevel+=deltay;
+	if (maplevel<maplevelmin) maplevel=maplevelmin;
+	if (maplevel>maplevelmax) maplevel=maplevelmax;
+//cerr << "width " << mapwidth  << " level " << maplevel << endl;
+	put();
+}
+
diff --git a/libsrc/src/ourdisp/wlcursor.xbm b/libsrc/src/ourdisp/wlcursor.xbm
new file mode 100755
index 0000000..5868353
--- /dev/null
+++ b/libsrc/src/ourdisp/wlcursor.xbm
@@ -0,0 +1,6 @@
+#define wlcursor.xbm_width 16
+#define wlcursor.xbm_height 16
+static char wlcursor.xbm_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x0a, 0x28, 0x0a, 0x24, 0x0a, 0x2a, 0x0a, 0x2d,
+   0xfb, 0x6e, 0x00, 0x00, 0xbb, 0x6f, 0x5a, 0x28, 0x2a, 0x28, 0x12, 0x28,
+   0x0a, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/libsrc/src/ourdisp/wlmask.xbm b/libsrc/src/ourdisp/wlmask.xbm
new file mode 100755
index 0000000..8081468
--- /dev/null
+++ b/libsrc/src/ourdisp/wlmask.xbm
@@ -0,0 +1,6 @@
+#define wlmask.xbm_width 16
+#define wlmask.xbm_height 16
+static char wlmask.xbm_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0x0e, 0x3c, 0x0e, 0x3e, 0x0e, 0x3f,
+   0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x7e, 0x38, 0x3e, 0x38, 0x1e, 0x38,
+   0x0e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/libsrc/standard/Imakefile b/libsrc/standard/Imakefile
new file mode 100755
index 0000000..960c064
--- /dev/null
+++ b/libsrc/standard/Imakefile
@@ -0,0 +1,248 @@
+#define IHaveSubdirs
+
+PIXELMEDTARGETDIR = ../../../pixelmed/imgbook/com/pixelmed/dicom
+
+SUBDIRS = elmdict module iodcomp strval
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+
+all::	 elmdict.tpl module.tpl iodcomp.tpl strval.tpl elmdict.xml
+
+depend::	 elmdict.tpl module.tpl iodcomp.tpl strval.tpl
+
+clean::
+	$(RM) elmdict.tpl module.tpl iodcomp.tpl strval.tpl elmdict.xml DicomDictionary.java.work DicomDictionary.java TagFromName.java
+        
+iodandmodulerelationshipsbytag.dat:	$(PROJECTLIBSUPPORTDIR)/extractiodandmodulerelationshipsbytag.awk iodandmodulerelationshipsbytag.head iodcomp.tpl module.tpl
+	cat iodandmodulerelationshipsbytag.head >iodandmodulerelationshipsbytag.dat
+	cat iodcomp.tpl module.tpl | $(AWK) -f $(PROJECTLIBSUPPORTDIR)/extractiodandmodulerelationshipsbytag.awk | sort -u | xargs -L 1 $(PROJECTLIBSUPPORTDIR)/inserttagumberbeforekeyword.sh elmdict/dicom3.tpl >>iodandmodulerelationshipsbytag.dat
+
+iodandmodulerelationshipsbytag_simple.dat:	iodandmodulerelationshipsbytag.dat
+	head -1 <iodandmodulerelationshipsbytag.dat | awk -F, '{print $$1 "," $$2 "," $$3 "," $$4}' >iodandmodulerelationshipsbytag_simple.dat
+	sed -e '1d' <iodandmodulerelationshipsbytag.dat | awk -F, '{print $$1 "," $$2 "," $$3 "," $$4 "," $$5}' | sort -u -t , +2 >>iodandmodulerelationshipsbytag_simple.dat
+
+install.java:	TagFromName.java DicomDictionary.java
+	$(CP) TagFromName.java $(PIXELMEDTARGETDIR)
+	$(CP) DicomDictionary.java $(PIXELMEDTARGETDIR)
+	
+TagFromName.java:	$(PROJECTLIBSUPPORTDIR)/elmtojava_TagFromName.awk \
+		elmdict/dicom3.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		Imakefile
+	RemoveTargetProgram(TagFromName.java)
+	cat \
+		elmdict/dicom3.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		| $(SORT) -b -n +0 -1 +4 -5 \
+		| sed -e 's/xx/00/g' -e 's/\([0-9][0-9]\)x\([0-9]\)/\10\2/g' \
+		| $(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_TagFromName.awk >TagFromName.java
+
+DicomDictionary.java.work:	\
+		elmdict/dicom3.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		Imakefile
+	RemoveTargetProgram(DicomDictionary.java.work)
+	cat \
+		elmdict/dicom3.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		| $(SORT) -b -n +0 -1 +4 -5 \
+		| egrep -v -i '[0-9][0-9]x[0-9]' \
+		| grep -v 'VR="NONE"' \
+		>DicomDictionary.java.work
+
+DicomDictionary.java:	DicomDictionary.java.work \
+		$(PROJECTLIBSUPPORTDIR)/DicomDictionary_header.txt \
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateTagList.awk \
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateVRByTag.awk \
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateIEByTag.awk \
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateTagByName.awk \
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateNameByTag.awk \
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateFullNameByTag.awk \
+		$(PROJECTLIBSUPPORTDIR)/DicomDictionary_trailer.txt \
+		iodcomp.tpl module.tpl Imakefile
+	RemoveTargetProgram(DicomDictionary.java)
+	cat $(PROJECTLIBSUPPORTDIR)/DicomDictionary_header.txt >DicomDictionary.java
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateTagList.awk <DicomDictionary.java.work >>DicomDictionary.java
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateVRByTag.awk <DicomDictionary.java.work >>DicomDictionary.java
+	cat iodcomp.tpl module.tpl | $(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateIEByTag.awk role=java >>DicomDictionary.java
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateTagByName.awk <DicomDictionary.java.work >>DicomDictionary.java
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateNameByTag.awk <DicomDictionary.java.work >>DicomDictionary.java
+	$(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateFullNameByTag.awk <DicomDictionary.java.work >>DicomDictionary.java
+	cat $(PROJECTLIBSUPPORTDIR)/DicomDictionary_trailer.txt >>DicomDictionary.java
+
+InformationEntity.csv:	\
+		$(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateIEByTag.awk \
+		$(PROJECTLIBSUPPORTDIR)/inserttagumberbeforekeyword.sh \
+		iodcomp.tpl module.tpl Imakefile
+	echo "Tag,Keyword,InformationEntity" >InformationEntity.csv
+	cat iodcomp.tpl module.tpl \
+		| $(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtojava_DicomDictionary_CreateIEByTag.awk role=csv \
+		| xargs -L 1 $(PROJECTLIBSUPPORTDIR)/inserttagumberbeforekeyword.sh elmdict/dicom3.tpl \
+		| sort \
+		>>InformationEntity.csv
+
+elmdict.xml: \
+		elmdict/dicom3.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		$(PROJECTLIBSUPPORTDIR)/elmtoxml.awk
+	RemoveTargetProgram(elmdict.xml)
+	cat \
+		elmdict/dicom3.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		| $(SORT) -b -n +0 -1 +4 -5 \
+		| $(AWK) -f $(PROJECTLIBSUPPORTDIR)/elmtoxml.awk >elmdict.xml
+
+elmdict.tpl:	\
+		elmdict/dicom3.tpl	\
+		elmdict/philips.tpl	\
+		elmdict/siemens.tpl	\
+		elmdict/gems.tpl	\
+		elmdict/papyrus.tpl	\
+		elmdict/toshiba.tpl	\
+		elmdict/hitachi.tpl \
+		elmdict/isg.tpl		\
+		elmdict/elscint.tpl	\
+		elmdict/acuson.tpl	\
+		elmdict/camtron.tpl	\
+		elmdict/agfa.tpl	\
+		elmdict/picker.tpl	\
+		elmdict/spi.tpl	\
+		elmdict/other.tpl \
+		elmdict/dicos.tpl \
+		elmdict/diconde.tpl \
+		elmdict/dicondep.tpl
+	cat \
+		elmdict/dicom3.tpl	\
+		elmdict/philips.tpl	\
+		elmdict/siemens.tpl	\
+		elmdict/gems.tpl	\
+		elmdict/papyrus.tpl	\
+		elmdict/toshiba.tpl	\
+		elmdict/hitachi.tpl \
+		elmdict/isg.tpl		\
+		elmdict/elscint.tpl	\
+		elmdict/acuson.tpl	\
+		elmdict/camtron.tpl	\
+		elmdict/agfa.tpl	\
+		elmdict/picker.tpl	\
+		elmdict/spi.tpl	\
+		elmdict/other.tpl	\
+		elmdict/dicos.tpl	\
+		elmdict/diconde.tpl	\
+		elmdict/dicondep.tpl	\
+	| $(SORT) -b -n +0 -1 +4 -5 >elmdict.tpl
+
+elmdict_standard.tpl:	\
+		elmdict/dicom3.tpl
+	cat \
+		elmdict/dicom3.tpl	\
+	| $(SORT) -b -n +0 -1 +4 -5 >elmdict_standard.tpl
+
+module.tpl:	\
+		module/base.tpl		\
+		module/file.tpl		\
+		module/pet.tpl		\
+		module/rt.tpl		\
+		module/acqctx.tpl	\
+		module/specimen.tpl	\
+		module/dx.tpl		\
+		module/vl.tpl		\
+		module/waveform.tpl	\
+		module/sr.tpl		\
+		module/softcopy.tpl	\
+		module/mr.tpl		\
+		module/ct.tpl		\
+		module/xaxrf.tpl	\
+		module/us.tpl
+	cat \
+		module/base.tpl		\
+		module/file.tpl		\
+		module/pet.tpl		\
+		module/rt.tpl		\
+		module/acqctx.tpl	\
+		module/specimen.tpl	\
+		module/dx.tpl		\
+		module/vl.tpl		\
+		module/waveform.tpl	\
+		module/sr.tpl		\
+		module/softcopy.tpl	\
+		module/mr.tpl		\
+		module/ct.tpl		\
+		module/xaxrf.tpl	\
+		module/us.tpl		\
+	>module.tpl
+
+iodcomp.tpl:	\
+		iodcomp/base.tpl	\
+		iodcomp/file.tpl	\
+		iodcomp/xaxrf.tpl	\
+		iodcomp/pet.tpl		\
+		iodcomp/rt.tpl		\
+		iodcomp/dx.tpl		\
+		iodcomp/vl.tpl		\
+		iodcomp/waveform.tpl	\
+		iodcomp/sr.tpl		\
+		iodcomp/softcopy.tpl	\
+		iodcomp/mr.tpl		\
+		iodcomp/ct.tpl	\
+		iodcomp/us.tpl
+	cat \
+		iodcomp/base.tpl	\
+		iodcomp/file.tpl	\
+		iodcomp/xaxrf.tpl	\
+		iodcomp/pet.tpl		\
+		iodcomp/rt.tpl		\
+		iodcomp/dx.tpl		\
+		iodcomp/vl.tpl		\
+		iodcomp/waveform.tpl	\
+		iodcomp/sr.tpl		\
+		iodcomp/softcopy.tpl	\
+		iodcomp/mr.tpl		\
+		iodcomp/ct.tpl		\
+		iodcomp/us.tpl		\
+	>iodcomp.tpl
+
+strval.tpl:	\
+		strval/base.tpl		\
+		strval/charset.tpl	\
+		strval/file.tpl		\
+		strval/xaxrf.tpl	\
+		strval/us.tpl		\
+		strval/nm.tpl		\
+		strval/pet.tpl		\
+		strval/rt.tpl		\
+		strval/dx.tpl		\
+		strval/sdmdx.tpl	\
+		strval/vl.tpl		\
+		strval/waveform.tpl	\
+		strval/sr.tpl		\
+		strval/softcopy.tpl	\
+		strval/mr.tpl		\
+		strval/ct.tpl
+	cat \
+		strval/base.tpl		\
+		strval/charset.tpl	\
+		strval/file.tpl		\
+		strval/xaxrf.tpl	\
+		strval/us.tpl		\
+		strval/nm.tpl		\
+		strval/pet.tpl		\
+		strval/rt.tpl		\
+		strval/dx.tpl		\
+		strval/sdmdx.tpl	\
+		strval/vl.tpl		\
+		strval/waveform.tpl	\
+		strval/sr.tpl		\
+		strval/softcopy.tpl	\
+		strval/mr.tpl		\
+		strval/ct.tpl		\
+	>strval.tpl
+
+
diff --git a/libsrc/standard/NOTES b/libsrc/standard/NOTES
new file mode 100755
index 0000000..91b58a1
--- /dev/null
+++ b/libsrc/standard/NOTES
@@ -0,0 +1,120 @@
+20110529
+
+dcmtk format again
+
+^[(]([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]),"([^"]+)",([0-9A-Fa-f][0-9A-Fa-f])[)][\s]+([A-Z][A-Z])[\s]+([^\s]+)[\s]+([0-9n-]+)[\s]+.*$
+(\1,00\3) VERS="HOL"  VR="\4"   VM="\6"	Owner="\2"		Keyword="\5"			Name="\5"
+
+20110521
+
+# sort
+
+s/\([(][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f],[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][)]\)[ 	]*\(VERS="[^"]*"\)[ 	]*\(VR="[^"]*"\)[ 	]*\(VM="[^"]*"\)[ 	]*\(Owner="[^"]*"\)[ 	]*\(Keyword="[^"]*"\)[ 	]*\(Name="[^"]*"\)/\1	\2	\3	\4	\5	\6	\7/
+sed -f ../../support/canonicalizespacinginelmdict.sed | sort -t '       ' -k 5,5 -k 1,1
+
+([(][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f],[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][)])[\s]+(VERS="[^"]*")[\s]+(VR="[^"]+")[\s]+(VM="[^"]+")[\s]+(Owner="[^"]+")[\s]+(Keyword="[^"]+")[\s]+(Name="[^"]+")
+\1	\2	\3	\4	\5	\6	\7
+
+# dcmtk to template
+[(]([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]),"(.*)",([0-9A-Fa-f][0-9A-Fa-f])[)][\s]+([A-Z][A-Z])[\s]+([^\s]+)[\s]+([0-9n-]+)
+(\1,00\3) VERS="DTK" VR="\4"   VM="\6"	Owner="\2"		Keyword="\5"					Name="\5"
+
+# use name as keyword
+Keyword="[?]"[\s]+Name="([^"]*)"
+Keyword="\1"	Name="\1"
+
+# replace spaces in keywords
+Keyword="([^ "]*) ([^"]*)"
+Keyword="\1\2"
+
+# Patterns for dcdump output to template:
+[(]0x([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]),0x[0-9A-Fa-f][0-9A-Fa-f]([0-9A-Fa-f][0-9A-Fa-f])[)][\s]+[?][\s]+VR=<([A-Z][A-Z])>[\s]+VL=.*$
+(\1,00\2) VERS="SSPI" VR="\3"   VM="1"	Owner="SIEMENS MR SDI 02"				Keyword="?"				Name="?"
+
+# Patterns for Siemens conformance statement layout to template:
+
+Keyword="([^"^ ]*) ([A-Z][^"]*)"
+Keyword="\1\2"
+
+[(]([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]),([A-Z ]*),([0-9A-F][0-9A-F])[)] ([A-Za-z0-9 ]+) ([A-Z][A-Z]) ([0-9n-]+)
+(\1,00\3) VERS="SSPI" VR="\5"   VM="\6"	Owner="\2"		Keyword="\4"					Name="\4"
+
+
+
+
+
+
+19961111	Why is 0028,0036 LUTData only US not "US or SS" in elmdict.tpl ?
+
+From Elscint Passport Conformance Statement v2.04 23Jun95:
+
+
+	0601,0030 Owner="ELSCINT1"	Keyword="SurviewDirection"
+
+		Def terms: IN,OUT 
+
+	0601,0031 Owner="ELSCINT1"	Keyword="SurviewLength"
+
+		Units: mm
+
+	0601,0050 Owner="ELSCINT1"	Keyword="ImageViewType" 
+
+		Def terms:
+
+			S,PS,ES	surview (localized)
+			OB	oblique reformatting
+			CM	combined image
+			TL	time lapse CT
+			MF	multiformat
+			3D,3C	3D images
+			ST	stereotaxis
+			DT	dental
+			MR	MR images
+
+From DuPont Lynx Conformance Statement 16Aug95:
+
+	0019,0010 Owner="1.2.840.113681"	Keyword="CRImageParamsCommon"
+
+	0019,0011 Owner="1.2.840.113681"	Keyword="CRImageIPParamsSingle"
+
+	0019,0012 Owner="1.2.840.113681"	Keyword="CRImageIPParamsLeft"
+
+	0019,0013 Owner="1.2.840.113681"	Keyword="CRImageIPParamsRight"
+
+From Philips EasyGuide Neuro Conformance Statement:
+
+	0009,0004 Owner="SPI-P Release 1"	 Keyword="ImageDataConsistence"
+
+From GE Advantx DLX Conformance Statement:
+
+	0011,xx01 Owner="?"	Keyword="PatientDOB" (in free form)
+
+	0015,xx01 Owner="?"	Keyword="Stenos_calibr_ratio" (Calibration ratio for Stenosis Quantification expressed for a 1024 matrix)
+	0015,xx02 Owner="?"	Keyword="Stenos_magnification" (Calibration ratio for Length measurement)
+	0015,xx03 Owner="?"	Keyword="Cardiac_calibr_ratio" (Calibration ratio for VG quanitifcation)
+
+	0019,xx01 Owner="?"	Keyword="Angle_value_1" (of L arm in degrees)
+	0019,xx02 Owner="?"	Keyword="Angle_value_2" (of P arm in degrees)
+	0019,xx03 Owner="?"	Keyword="Angle_value_3" (of C arm in degrees)
+	0019,xx04 Owner="?"	Keyword="Angle_label_1" (L)
+	0019,xx05 Owner="?"	Keyword="Angle_label_2" (CAU,CRA)
+	0019,xx06 Owner="?"	Keyword="Angle_label_3" (LAO,RAO)
+	0019,xx07 Owner="?"	Keyword="Adx_procedure_name" (free text)
+	0019,xx08 Owner="?"	Keyword="Adx_exam_name" (free text)
+	0019,xx09 Owner="?"	Keyword="Adx_patient_size" (LOW MEDIUM ADULT)
+	0019,xx0A Owner="?"	Keyword="Adx_Record_View" (1=frontal;2=lateral;3=biplane)
+	0019,xx10 Owner="?"	Keyword="Adx_injector delay" (in 1/10th secs)
+	0019,xx11 Owner="?"	Keyword="Adx_auto_inject" (1 if yes, 0 if no)
+	0019,xx14 Owner="?"	Keyword="Adx_acq_mode" (0,1 vascular;2..7 cardiac;8..13 dsa stepping;14..19,26 bolus chasing;20..25 HSS acquisition)
+	0019,xx15 Owner="?"	Keyword="Adx_camera_rotation_enable" (0..3 disabled; 4..7 enabled)
+	0019,xx16 Owner="?"	Keyword="Adx_reverse_sweep" (0,4 none;1,5 vertical; 2,6 horiz ; 3,7 both)
+	0019,xx17 Owner="?"	Keyword="Cur_spatial_filter_strength" (in free form)
+	0019,xx18 Owner="?"	Keyword="Zoom_factor" (1,2 or 4) 
+	0019,xx19 Owner="?"	Keyword="X_zoom" (X center)
+	0019,xx1A Owner="?"	Keyword="Y_zoom" (Y center)
+	0019,xx1B Owner="?"	Keyword="Adx_focus" (focus on frontal plane)
+	0019,xx1C Owner="?"	Keyword="Adx_dose" (0,1,2,3 for dose A,B,C,D)
+	0019,xx1D Owner="?"	Keyword="Side_mark" (0-6)
+	0019,xx1E Owner="?"	Keyword="Percentage_landsape" (Presentage of mask applied)
+	0019,xx1F Owner="?"	Keyword="Adx_exposure_duration" (ms)
+
diff --git a/libsrc/standard/binval.tpl b/libsrc/standard/binval.tpl
new file mode 100755
index 0000000..49a2bbd
--- /dev/null
+++ b/libsrc/standard/binval.tpl
@@ -0,0 +1,455 @@
+BinaryValues="Zero" {
+	0x0000
+}
+
+BinaryValues="One" {
+	0x0001
+}
+
+BinaryValues="Three" {
+	0x0003
+}
+
+BinaryValues="FFFF" {
+	0xffff = Inconsistencies may be present
+}
+
+BinaryValues="PregnancyStatus" {
+	0x0001 = Not Pregnant,
+	0x0002 = Possibly Pregnant,
+	0x0003 = Definitely Pregnant,
+	0x0004 = Unknown
+}
+
+BinaryValues="RegionSpatialFormat" {
+	0x0000 = None,
+	0x0001 = 2D (Tissue or Flow),
+	0x0002 = M-Mode (Tissue or Flow),
+	0x0003 = Spectral (Tissue or Flow),
+	0x0004 = Wave Form,
+	0x0005 = Graphics
+}
+
+BinaryValues="RegionDataType" {
+	0x0000 = None,
+	0x0001 = Tissue,
+	0x0002 = Color Flow,
+	0x0003 = PW Spectral Doppler,
+	0x0004 = CW Spectral Doppler,
+	0x0005 = Doppler Mean Trace,
+	0x0006 = Doppler Mode Trace,
+	0x0007 = Doppler Max Trace,
+	0x0008 = Volume Trace,
+	0x0009 = d(volume)/dt Trace,
+	0x000a = ECG Trace,
+	0x000b = Pulse Trace,
+	0x000c = Phonocardiogram Trace,
+	0x000d = Gray Bar,
+	0x000e = Color Bar,
+	0x000f = Integrated Backscatter,
+	0x0010 = Area Trace,
+	0x0011 = d(area)/dt,
+	0x0012 = Other Physiological Amplitude vs. Time Input
+}
+
+BinaryBitMap="RegionFlags" {
+	0 = Priority       : High,Low;
+	1 = Scaling Protection : Not Protected,Protected;
+	2 = Doppler Scale Type : Velocity,Frequency;
+	3 = Scrolling Region : Not Scrolling,Scrolling;
+	4 = Sweeping Region : Not Sweeping,Sweeping;
+}
+
+BinaryValues="PixelComponentOrganization" {
+	0x0000 = Bit Aligned Positions,
+	0x0001 = Ranges,
+	0x0002 = Table Look Up
+	0x0003 = Code Sequence Look Up
+}
+
+BinaryValues="PixelComponentPhysicalUnits" {
+	0x0000 = None,
+	0x0001 = Percent,
+	0x0002 = dB,
+	0x0003 = cm,
+	0x0004 = seconds,
+	0x0005 = hertz(seconds-1),
+	0x0006 = dB/seconds,
+	0x0007 = cm/sec,
+	0x0008 = cm2,
+	0x0009 = cm2/sec,
+	0x000a = cm3,
+	0x000b = cm3/sec,
+	0x000c = degrees
+}
+
+BinaryValues="PixelComponentDataType" {
+	0x0000 = None,
+	0x0001 = Tissue,
+	0x0002 = Spectral Doppler,
+	0x0003 = Color Flow Velocity,
+	0x0004 = Color Flow Variance,
+	0x0005 = Color Flow Intensity,
+	0x0006 = Gray Bar,
+	0x0007 = Color Bar,
+	0x0008 = Integrated Backscatter,
+	0x0009 = Computed Border,
+	0x000A = Tissue Classification
+}
+
+BinaryValues="PixelRepresentation" {
+	0x0000 = unsigned,
+	0x0001 = signed
+}
+
+BinaryValues="PixelRepresentationUnsigned" {
+	0x0000 = unsigned
+}
+
+BinaryValues="PlanarConfiguration" {
+	0x0000 = sequential planes,
+	0x0001 = contiguous planes
+}
+
+BinaryValues="USPlanarConfiguration" {
+	0x0000 = sequential planes,
+	0x0001 = contiguous planes
+}
+
+BinaryValues="SamplesPerPixelIsOne" {
+	0x0001
+}
+
+BinaryValues="SamplesPerPixelIsThree" {
+	0x0003
+}
+
+BinaryValues="SamplesPerPixelIsOneOrThree" {
+	0x0001,
+	0x0003
+}
+
+BinaryValues="SamplesPerPixelUsedIsTwo" {
+	0x0002
+}
+
+BinaryValues="PlanarConfigurationIsColorByPlane" {
+	0x0001
+}
+
+BinaryValues="PlanarConfigurationIsColorByPixel" {
+	0x0000
+}
+
+BinaryValues="PlanarConfigurationIsColorByPlaneOrPixel" {
+	0x0000,
+	0x0001
+}
+
+BinaryValues="BitsAre32" {
+	32
+}
+
+BinaryValues="BitsAre64" {
+	64
+}
+
+BinaryValues="BitsAre16" {
+	0x0010
+}
+
+BinaryValues="BitsAre15" {
+	0x000f
+}
+
+BinaryValues="BitsAre8" {
+	0x0008
+}
+
+BinaryValues="BitsAre7" {
+	0x0007,
+}
+
+BinaryValues="BitsAre12Or16" {
+	0x000c,
+	0x0010
+}
+
+BinaryValues="BitsAre11Or15" {
+	0x000b,
+	0x000f
+}
+
+BinaryValues="BitsAre8Or16" {
+	0x0008,
+	0x0010
+}
+
+BinaryValues="BitsAre16Or32" {
+	0x0010,
+	0x0020
+}
+
+BinaryValues="BitsAre7Or15" {
+	0x0007,
+	0x000f
+}
+
+BinaryValues="BitsAre15Or31" {
+	0x000f,
+	0x001f
+}
+
+BinaryValues="BitsAre8Or10Or12Or16" {
+	0x0008,
+	0x000a,
+	0x000c,
+	0x0010
+}
+
+BinaryValues="BitsAre7Or9Or11Or15" {
+	0x0007,
+	0x0009,
+	0x000b,
+	0x000f
+}
+
+BinaryValues="BitsAre8Or12To16" {
+	0x0008,
+	0x000c,
+	0x000d,
+	0x000e,
+	0x000f,
+	0x0010
+}
+
+BinaryValues="BitsAre7Or11To15" {
+	0x0007,
+	0x000a,
+	0x000b,
+	0x000c,
+	0x000d,
+	0x000e,
+	0x000f
+}
+
+BinaryValues="BitsAre8Or12Or16" {
+	0x0008,
+	0x000c,
+	0x0010
+}
+
+BinaryValues="BitsAre7Or11Or15" {
+	0x0007,
+	0x000b,
+	0x000f
+}
+
+BinaryValues="BitsAre6To16" {
+	0x0006,
+	0x0007,
+	0x0008,
+	0x0009,
+	0x000a,
+	0x000b,
+	0x000c,
+	0x000d,
+	0x000e,
+	0x000f,
+	0x0010
+}
+
+BinaryValues="BitsAre5To15" {
+	0x0005,
+	0x0006,
+	0x0007,
+	0x0008,
+	0x0009,
+	0x000a,
+	0x000b,
+	0x000c,
+	0x000d,
+	0x000e,
+	0x000f
+}
+
+BinaryValues="BitsAre8To15" {
+	0x0008,
+	0x0009,
+	0x000A,
+	0x000B,
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F
+}
+
+BinaryValues="BitsAre7To15" {
+	0x0007,
+	0x0008,
+	0x0009,
+	0x000A,
+	0x000B,
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F
+}
+
+BinaryValues="BitsAre8To16" {
+	0x0008,
+	0x0009,
+	0x000A,
+	0x000B,
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F,
+	0x0010
+}
+
+BinaryValues="BitsAre9To16" {
+	0x0009,
+	0x000A,
+	0x000B,
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F,
+	0x0010
+}
+
+BinaryValues="BitsAre10To16" {
+	0x000A,
+	0x000B,
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F,
+	0x0010
+}
+
+BinaryValues="BitsAre12To16" {
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F,
+	0x0010
+}
+
+BinaryValues="BitsAre11To15" {
+	0x000B,
+	0x000C,
+	0x000D,
+	0x000E,
+	0x000F
+}
+
+BinaryValues="BitsAre1Or8" {
+	0x0001,
+	0x0008
+}
+
+BinaryValues="BitsAre0Or7" {
+	0x0001,
+	0x0007
+}
+
+BinaryValues="CurveDataValueRepresentation" {
+	0x0000 = Unsigned Short(US),
+	0x0001 = Signed Short(SS),
+	0x0002 = Floating Point Single(FL),
+	0x0003 = Floating Point Double(FD),
+	0x0004 = Signed Long(SL)
+}
+
+BinaryValues="CurveDataDescriptor" {
+	0x0000 = Interval Spacing,
+	0x0001 = Values
+}
+
+BinaryValues="AudioType" {
+	0x0000 = None,
+	0x0001 = Doppler Audio,
+	0x0002 = Voice Audio,
+	0x0003 = Phono Audio
+}
+
+BinaryValues="AudioSampleFormat" {
+	0x0000 = 16 Bit Signed LSB First Interleaved Per Channel,
+	0x0001 = 8 bit Signed Interleaved Per Channel
+}
+
+BinaryValues="NumberOfChannels" {
+	0x0000 = Mono,
+	0x0001 = Stereo
+}
+
+BinaryValues="UltrasoundColorDataPresent" {
+	0x0000 = Ultrasound color data not present in image,
+	0x0001 = Ultrasound color data is present in image
+}
+
+BinaryValues="PreferredPlaybackSequencing" {
+	0x0000 = Looping,
+	0x0001 = Sweeping
+}
+
+BinaryValues="PreferredPlaybackSequencingForHangingProtocol" {
+	0x0000 = Looping,
+	0x0001 = Sweeping
+	0x0002 = Stop
+}
+
+BinaryValues="PreferredPlaybackSequencingForStructuredDisplay" {
+	0x0000 = Looping,
+	0x0001 = Sweeping
+	0x0002 = Stop
+}
+
+BinaryValues="FileSetConsistencyFlag" {
+	0x0000 = No known inconsistencies,
+	0xffff = Inconsistencies may be present
+}
+
+BinaryValues="RecordInUseFlag" {
+	0x0000 = Record is inactive,
+	0xffff = Record is in use
+}
+
+BinaryValues="PixelIntensityRelationshipSign" {
+	0x0001 = Lower pixel values correspond to lower X-Ray intensity,
+	0xffff = Higher pixel values correspond to lower X-Ray intensity
+}
+
+BinaryValues="AllPossibleOverlayGroups" {
+	0x6000,
+	0x6002,
+	0x6004,
+	0x6006,
+	0x6008,
+	0x600a,
+	0x600c,
+	0x600e,
+	0x6010,
+	0x6012,
+	0x6014,
+	0x6016,
+	0x6018,
+	0x601a,
+	0x601c,
+	0x601e
+}
+
+BinaryValues="Two" {
+	2
+}
+
+BinaryValues="ImageRotationValues" {
+	0,
+	90,
+	180,
+	270
+}
+
+
diff --git a/libsrc/standard/condn.tpl b/libsrc/standard/condn.tpl
new file mode 100755
index 0000000..f845e44
--- /dev/null
+++ b/libsrc/standard/condn.tpl
@@ -0,0 +1,6581 @@
+# Conditions to detect Composite IOD presence ...
+#
+
+Condition="ParametricMapInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ParametricMapStorageSOPClassUID"
+ConditionEnd
+
+Condition="VLWholeSlideMicroscopyImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VLWholeSlideMicroscopyImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedUltrasoundVolumeInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedUSVolumeStorageSOPClassUID"
+ConditionEnd
+
+Condition="BasicStructuredDisplayInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="BasicStructuredDisplayStorageSOPClassUID"
+ConditionEnd
+
+Condition="IVOCTImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="IVOCTImageStorageForProcessingSOPClassUID"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="IVOCTImageStorageForPresentationSOPClassUID"
+ConditionEnd
+
+Condition="BreastTomosynthesisInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="BreastTomosynthesisImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="NotBreastTomosynthesisInstance"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="BreastTomosynthesisImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="ColorPaletteInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ColorPaletteStorageSOPClassUID"
+ConditionEnd
+
+Condition="NotColorPaletteInstance"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="ColorPaletteStorageSOPClassUID"
+ConditionEnd
+
+Condition="SegmentationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SegmentationStorageSOPClassUID"
+ConditionEnd
+
+Condition="SurfaceSegmentationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SurfaceSegmentationStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedXAImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedXAImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedXRFImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedXRFImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="RealWorldValueMappingInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RealWorldValueMappingStorageSOPClassUID"
+ConditionEnd
+
+Condition="EncapsulatedPDFInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EncapsulatedPDFStorageSOPClassUID"
+ConditionEnd
+
+Condition="EncapsulatedCDAInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EncapsulatedCDAStorageSOPClassUID"
+ConditionEnd
+
+Condition="OphthalmicPhotography8BitImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="OphthalmicPhotography8BitImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="OphthalmicPhotography16BitImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="OphthalmicPhotography16BitImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="StereometricRelationshipInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="StereometricRelationshipStorageSOPClassUID"
+ConditionEnd
+
+Condition="OphthalmicTomographyImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="OphthalmicTomographyImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="HangingProtocolInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="HangingProtocolStorageSOPClassUID"
+ConditionEnd
+
+Condition="SpatialFiducialsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SpatialFiducialsStorageSOPClassUID"
+ConditionEnd
+
+Condition="SpatialRegistrationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SpatialRegistrationStorageSOPClassUID"
+ConditionEnd
+
+Condition="DeformableSpatialRegistrationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DeformableSpatialRegistrationStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedCTImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedCTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="LegacyConvertedEnhancedCTImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="LegacyConvertedEnhancedCTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="NotLegacyConvertedCT"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="LegacyConvertedEnhancedCTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="PrivatePixelMedLegacyConvertedEnhancedCTImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="PrivatePixelMedLegacyConvertedEnhancedCTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="RawDataInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RawDataStorageSOPClassUID"
+ConditionEnd
+
+Condition="MRSpectroscopyInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MRSpectroscopyStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedMRImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedMRImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedMRColorImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedMRColorImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="LegacyConvertedEnhancedMRImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="LegacyConvertedEnhancedMRImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="NotLegacyConvertedMR"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="LegacyConvertedEnhancedMRImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="PrivatePixelMedLegacyConvertedEnhancedMRImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="PrivatePixelMedLegacyConvertedEnhancedMRImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="KeyObjectSelectionDocumentStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="KeyObjectSelectionDocumentStorageSOPClassUID"
+ConditionEnd
+
+Condition="MammographyCADSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MammographyCADSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="ChestCADSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ChestCADSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="BasicTextSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="BasicTextSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="ComprehensiveSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ComprehensiveSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="Comprehensive3DSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="Comprehensive3DSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="ProcedureLogStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ProcedureLogStorageSOPClassUID"
+ConditionEnd
+
+Condition="XRayRadiationDoseSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="XRayRadiationDoseSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="RadiopharmaceuticalRadiationDoseSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RadiopharmaceuticalRadiationDoseSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="SpectaclePrescriptionReportInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SpectaclePrescriptionReportStorageSOPClassUID"
+ConditionEnd
+
+Condition="AcquisitionContextSRStorageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="AcquisitionContextSRStorageSOPClassUID"
+ConditionEnd
+
+Condition="GrayscaleSoftcopyPresentationStateInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="GrayscaleSoftcopyPresentationStateStorageSOPClassUID"
+ConditionEnd
+
+Condition="ColorSoftcopyPresentationStateInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ColorSoftcopyPresentationStateStorageSOPClassUID"
+ConditionEnd
+
+Condition="PseudoColorSoftcopyPresentationStateInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="PseudoColorSoftcopyPresentationStateStorageSOPClassUID"
+ConditionEnd
+
+Condition="BlendingSoftcopyPresentationStateInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="BlendingSoftcopyPresentationStateStorageSOPClassUID"
+ConditionEnd
+
+Condition="IsForProcessingSOPClass"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalXRayImageStorageForProcessingSOPClassUID"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalMammographyXRayImageStorageForProcessingSOPClassUID"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalIntraoralXRayImageStorageForProcessingSOPClassUID"
+ConditionEnd
+
+Condition="IsForPresentationSOPClass"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalXRayImageStorageForPresentationSOPClassUID"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalMammographyXRayImageStorageForPresentationSOPClassUID"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalIntraoralXRayImageStorageForPresentationSOPClassUID"
+ConditionEnd
+
+Condition="DXImageForProcessingInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalXRayImageStorageForProcessingSOPClassUID"
+ConditionEnd
+
+Condition="DXImageForPresentationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalXRayImageStorageForPresentationSOPClassUID"
+ConditionEnd
+
+Condition="MammographyImageForProcessingInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalMammographyXRayImageStorageForProcessingSOPClassUID"
+ConditionEnd
+
+Condition="MammographyImageForPresentationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalMammographyXRayImageStorageForPresentationSOPClassUID"
+ConditionEnd
+
+Condition="IntraoralImageForProcessingInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalIntraoralXRayImageStorageForProcessingSOPClassUID"
+ConditionEnd
+
+Condition="IntraoralImageForPresentationInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="DigitalIntraoralXRayImageStorageForPresentationSOPClassUID"
+ConditionEnd
+
+Condition="MediaStorageDirectoryInstance"
+	Element="MediaStorageSOPClassUID"	StringConstantFromRootAttribute="MediaStorageDirectoryStorageSOPClassUID"
+ConditionEnd
+
+Condition="PETImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="PETImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="EnhancedPETImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="EnhancedPETImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="LegacyConvertedEnhancedPETImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="LegacyConvertedEnhancedPETImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="NotLegacyConvertedPET"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="LegacyConvertedEnhancedPETImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="PrivatePixelMedLegacyConvertedEnhancedPETImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="PrivatePixelMedLegacyConvertedEnhancedPETImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="StandalonePETCurveInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="StandalonePETCurveStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTDoseInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTDoseStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTStructureSetInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTStructureSetStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTPlanInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTPlanStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTIonPlanInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTIonPlanStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTBeamsTreatmentRecordInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTBeamsTreatmentRecordStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTIonBeamsTreatmentRecordInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTIonBeamsTreatmentRecordStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTBrachyTreatmentRecordInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTBrachyTreatmentRecordStorageSOPClassUID"
+ConditionEnd
+
+Condition="RTTreatmentSummaryRecordInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="RTTreatmentSummaryRecordStorageSOPClassUID"
+ConditionEnd
+
+Condition="VisibleLightEndoscopicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VisibleLightEndoscopicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="VideoEndoscopicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VideoEndoscopicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="VisibleLightMicroscopicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VisibleLightMicroscopicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="VideoMicroscopicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VideoMicroscopicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="VisibleLightSlideCoordinatesMicroscopicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VisibleLightSlideCoordinatesMicroscopicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="VisibleLightPhotographicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VisibleLightPhotographicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="VideoPhotographicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VideoPhotographicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="BasicVoiceInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="BasicVoiceStorageSOPClassUID"
+ConditionEnd
+
+Condition="TwelveLeadECGInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="TwelveLeadECGStorageSOPClassUID"
+ConditionEnd
+
+Condition="GeneralECGInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="GeneralECGStorageSOPClassUID"
+ConditionEnd
+
+Condition="AmbulatoryECGInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="AmbulatoryECGStorageSOPClassUID"
+ConditionEnd
+
+Condition="HemodynamicWaveformInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="HemodynamicWaveformStorageSOPClassUID"
+ConditionEnd
+
+Condition="CardiacElectrophysiologyWaveformInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="CardiacElectrophysiologyWaveformStorageSOPClassUID"
+ConditionEnd
+
+Condition="CRImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="ComputedRadiographyImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="CTImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="CTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="MRImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MRImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="NMImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="NuclearMedicineImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="USImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="UltrasoundImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="USMultiFrameImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="UltrasoundMultiframeImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="SCImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SecondaryCaptureImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="MultiframeSingleBitSCImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MultiframeSingleBitSecondaryCaptureImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="MultiframeGrayscaleByteSCImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MultiframeGrayscaleByteSecondaryCaptureImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="MultiframeGrayscaleWordSCImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MultiframeGrayscaleWordSecondaryCaptureImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="MultiframeTrueColorSCImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="MultiframeTrueColorSecondaryCaptureImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="XAImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="XRayAngiographicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="XABiplaneImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="XRayAngiographicBiplaneImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="XRFImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="XRayRadioFluoroscopicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="XRay3DAngiographicImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="XRay3DAngiographicImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="XRay3DCraniofacialImageInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="XRay3DCraniofacialImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="StandaloneOverlayInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="StandaloneOverlayStorageSOPClassUID"
+ConditionEnd
+
+Condition="StandaloneCurveInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="StandaloneCurveStorageSOPClassUID"
+ConditionEnd
+
+Condition="StandaloneModalityLUTInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="StandaloneModalityLUTStorageSOPClassUID"
+ConditionEnd
+
+Condition="StandaloneVOILUTInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="StandaloneVOILUTStorageSOPClassUID"
+ConditionEnd
+
+Condition="LensometryMeasurementsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="LensometryMeasurementsStorageSOPClassUID"
+ConditionEnd
+
+Condition="AutorefractionMeasurementsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="AutorefractionMeasurementsStorageSOPClassUID"
+ConditionEnd
+
+Condition="KeratometryMeasurementsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="KeratometryMeasurementsStorageSOPClassUID"
+ConditionEnd
+
+Condition="SubjectiveRefractionMeasurementsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="SubjectiveRefractionMeasurementsStorageSOPClassUID"
+ConditionEnd
+
+Condition="VisualAcuityMeasurementsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="VisualAcuityMeasurementsStorageSOPClassUID"
+ConditionEnd
+
+Condition="OphthalmicAxialMeasurementsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="OphthalmicAxialMeasurementsStorageSOPClassUID"
+ConditionEnd
+
+Condition="IntraocularLensCalculationsInstance"
+	Element="SOPClassUID"		StringConstantFromRootAttribute="IntraocularLensCalculationsStorageSOPClassUID"
+ConditionEnd
+
+Condition="BreastProjectionXRayImageInstance"
+	Element="SOPClassUID"						StringConstantFromRootAttribute="BreastProjectionXRayImageStorageForPresentationSOPClassUID"
+	Element="SOPClassUID"		Operator="Or"	StringConstantFromRootAttribute="BreastProjectionXRayImageStorageForProcessingSOPClassUID"
+ConditionEnd
+
+# Conditions for inclusion of Modules with Usage "C" in Composite IODs  ...
+
+# General principle is that if any type 1 or 2 required attributes are
+# present then the module is needed
+
+# Really need to seperate concepts of when is "module required" from "module present" :(
+
+Condition="NeedModuleCommonInstanceReference"
+	Element="ReferencedSeriesSequence"								ElementPresent=""
+	Element="StudiesContainingOtherReferencedInstancesSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleAcquisitionContext"
+	Element="AcquisitionContextSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleContrastBolus"
+	Element="ContrastBolusAgent"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleCine"
+	Element="FrameTime"			ElementPresent=""
+	Element="FrameTimeVector"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleMultiFrame"
+	Element="NumberOfFrames"		ElementPresent=""
+	Element="FrameIncrementPointer"	ElementPresent=""
+ConditionEnd
+
+Condition="NumberOfFramesGreaterThanOne"
+	Element="NumberOfFrames"		ElementPresent=""
+	Element="NumberOfFrames"		Operator="And" BinaryValue="> 1"
+ConditionEnd
+
+Condition="NumberOfFramesIsAbsentOrOne"
+	Element="NumberOfFrames"		Modifier="Not" ElementPresent=""
+	Element="NumberOfFrames"		Operator="Or" BinaryValue="== 1"
+ConditionEnd
+
+Condition="NeedModuleNMMultiGatedAcquisitionImageRetired"
+	Element="FrameTime"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleNMSPECTAcquisitionImageRetired"
+	Element="AngularStep"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleUSFrameOfReference"
+	Element="RegionLocationMinX0"		ElementPresent=""
+	Element="RegionLocationMinY0"		ElementPresent=""
+	Element="RegionLocationMaxX1"		ElementPresent=""
+	Element="RegionLocationMaxY1"		ElementPresent=""
+	Element="PhysicalUnitsXDirection"	ElementPresent=""
+	Element="PhysicalUnitsYDirection"	ElementPresent=""
+	Element="PhysicalDeltaX"		ElementPresent=""
+	Element="PhysicalDeltaY"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleOverlayPlane"
+	Element="OverlayRows"			ElementPresent="0xff00"
+	Element="OverlayColumns"		ElementPresent="0xff00"
+	Element="OverlayType"			ElementPresent="0xff00"
+	Element="OverlaySubtype"		ElementPresent="0xff00"
+	Element="OverlayOrigin"			ElementPresent="0xff00"
+	Element="OverlayBitsAllocated"		ElementPresent="0xff00"
+	Element="OverlayBitPosition"		ElementPresent="0xff00"
+	Element="OverlayData"			ElementPresent="0xff00"
+	Element="ROIArea"			ElementPresent="0xff00"
+	Element="ROIMean"			ElementPresent="0xff00"
+	Element="ROIStandardDeviation"		ElementPresent="0xff00"
+	Element="OverlayDescriptorGray"		ElementPresent="0xff00"
+	Element="OverlayDescriptorRed"		ElementPresent="0xff00"
+	Element="OverlayDescriptorGreen"	ElementPresent="0xff00"
+	Element="OverlayDescriptorBlue"		ElementPresent="0xff00"
+	Element="OverlayGray"			ElementPresent="0xff00"
+	Element="OverlayRed"			ElementPresent="0xff00"
+	Element="OverlayGreen"			ElementPresent="0xff00"
+	Element="OverlayBlue"			ElementPresent="0xff00"
+	Element="OverlayDescription"		ElementPresent="0xff00"
+	Element="OverlayLabel"			ElementPresent="0xff00"
+ConditionEnd
+
+Condition="NeedModuleApproval"
+	Element="ApprovalStatus"		ElementPresent=""
+	Element="ReviewDate"			ElementPresent=""
+	Element="ReviewTime"			ElementPresent=""
+	Element="ReviewerName"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleModalityLUT"
+	Element="RescaleIntercept"		ElementPresent=""
+	Element="RescaleSlope"			ElementPresent=""
+	Element="RescaleType"			ElementPresent=""
+	Element="ModalityLUTSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleVOILUT"
+	Element="WindowCenter"			ElementPresent=""
+	Element="WindowWidth"			ElementPresent=""
+	Element="WindowCenterWidthExplanation"	ElementPresent=""
+	Element="VOILUTSequence"		ElementPresent=""
+	Element="VOILUTFunction"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleFrameOfReference"
+	Element="FrameOfReferenceUID"		ElementPresent=""
+	Element="PositionReferenceIndicator"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleFrameOfReferenceInVLI"
+	# should really check Image Acquisition Context for true condition
+	Element="FrameOfReferenceUID"		ElementPresent=""
+	Element="PositionReferenceIndicator"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleImagePlane"
+	Element="PixelSpacing"			ElementPresent=""
+	Element="ImageOrientationPatient"	ElementPresent=""
+	Element="ImagePositionPatient"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleMultiFrameOverlay"
+	Element="NumberOfFramesInOverlay"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleUSRegionCalibration"
+	Element="SequenceOfUltrasoundRegions"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleGeneralEquipment"
+	Element="Manufacturer"					ElementPresent=""
+	Element="InstitutionName"				ElementPresent=""
+	Element="InstitutionAddress"			ElementPresent=""
+	Element="StationName"					ElementPresent=""
+	Element="InstitutionalDepartmentName"	ElementPresent=""
+	Element="ManufacturerModelName"			ElementPresent=""
+	Element="DeviceSerialNumber"			ElementPresent=""
+	Element="SoftwareVersions"				ElementPresent=""
+	Element="GantryID"						ElementPresent=""
+	Element="SpatialResolution"				ElementPresent=""
+	Element="DateOfLastCalibration"			ElementPresent=""
+	Element="TimeOfLastCalibration"			ElementPresent=""
+	Element="PixelPaddingValue"				ElementPresent=""
+ConditionEnd
+
+Condition="EnhancedGeneralEquipmentIsPresent"
+	Element="Manufacturer"								   ElementPresent=""
+	Element="ManufacturerModelName"			Operator="And" ElementPresent=""
+	Element="DeviceSerialNumber"			Operator="And" ElementPresent=""
+	Element="SoftwareVersions"				Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleNMTomoAcquisition"
+	Element="ImageType"			ValueSelector="2"	StringValue="TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="GATED TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="RECON TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="RECON GATED TOMO"
+ConditionEnd
+
+Condition="NeedModuleNMMultiGatedAcquisition"
+	Element="ImageType"			ValueSelector="2"	StringValue="TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="GATED TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="RECON TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="RECON GATED TOMO"
+ConditionEnd
+
+Condition="NeedModuleNMPhase"
+	Element="ImageType"			ValueSelector="2"	StringValue="DYNAMIC"
+ConditionEnd
+
+Condition="NeedModuleNMReconstruction"
+	Element="ImageType"			ValueSelector="2"	StringValue="RECON TOMO"
+	Element="ImageType"			ValueSelector="2"	StringValue="RECON GATED TOMO"
+ConditionEnd
+
+Condition="NeedModuleSpecimen"
+	Element="ContainerIdentifier"						ElementPresent=""
+	Element="IssuerOfTheContainerIdentifierSequence"	ElementPresent=""
+	Element="AlternateContainerIdentifierSequence"		ElementPresent=""
+	Element="ContainerTypeCodeSequence"					ElementPresent=""
+	Element="ContainerDescription"						ElementPresent=""
+	Element="ContainerComponentSequence"				ElementPresent=""
+	Element="SpecimenDescriptionSequence"				ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleDXDetector"
+	Element="DetectorType"							ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXAXRFMultiFramePresentation"
+	Element="PreferredPlaybackSequencing"					ElementPresent=""
+	Element="FrameDisplaySequence"							ElementPresent=""
+	Element="RecommendedViewingMode"						ElementPresent=""
+	Element="DisplayFilterPercentage"						ElementPresent=""
+ConditionEnd
+
+Condition="RecommendedViewingModeIsSUB"
+	Element="RecommendedViewingMode"						StringValue="SUB"
+ConditionEnd
+
+Condition="CodingSchemeVersionRequired"
+	Element="CodingSchemeDesignator"							StringValue="BI"
+	Element="CodingSchemeDesignator"			Operator="Or"	StringValue="SCPECG"
+	Element="CodingSchemeDesignator"			Operator="Or"	StringValue="BARI"
+	Element="CodingSchemeDesignator"			Operator="Or"	StringValue="NCDR"
+ConditionEnd
+
+Condition="SpecimenIsSlide"
+# too difficult to check real world condition ? ... best guess is ...
+	Element="Modality"			StringValue="SM"
+ConditionEnd
+
+Condition="ModalityIsSM"
+	Element="Modality"			StringValue="SM"
+ConditionEnd
+
+Condition="SpecimenNeedsDescription"
+# too difficult to check real world condition ?
+ConditionEnd
+
+Condition="NeedMeasurementUnitsCodeSequence"
+	Element="ValueType"			Operator="Or"	StringValue="NUM"
+	Element="NumericValue"			ElementPresent=""
+ConditionEnd
+
+Condition="MeasurementUnitsCodeSequencePresentAndNumericValueAbsent"
+	Element="MeasurementUnitsCodeSequence"	ElementPresent=""
+	Element="NumericValue"					Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AcquisitionContextItemIsNumeric"
+	Element="ValueType"						StringValue="NUMERIC"
+	Element="NumericValue"					Operator="Or"	ElementPresent=""
+	Element="FloatingPointValue"			Operator="Or"	ElementPresent=""
+	Element="RationalNumeratorValue"		Operator="Or"	ElementPresent=""
+	Element="RationalDenominatorValue"		Operator="Or"	ElementPresent=""
+	Element="MeasurementUnitsCodeSequence"	Operator="Or"	ElementPresent=""
+	(
+		Element="Time"										Modifier="Not" ElementPresent=""
+		Element="PersonName"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="TextValue"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="ConceptCodeSequence"		Operator="And"	Modifier="Not" ElementPresent=""
+		Element="Date"						Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="AcquisitionContextItemIsNotNumeric"
+	Element="ValueType"						Modifier="Not" StringValue="NUMERIC"
+	Element="NumericValue"					Operator="Or"	Modifier="Not" ElementPresent=""
+	Element="Time"							Operator="Or"	ElementPresent=""
+	Element="PersonName"					Operator="Or"	ElementPresent=""
+	Element="TextValue"						Operator="Or"	ElementPresent=""
+	Element="ConceptCodeSequence"			Operator="Or"	ElementPresent=""
+	Element="Date"							Operator="Or"	ElementPresent=""
+ConditionEnd
+
+Condition="AcquisitionContextItemIsDate"
+	Element="ValueType"						StringValue="DATE"
+	(
+		Element="Time"										Modifier="Not" ElementPresent=""
+		Element="PersonName"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="TextValue"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="ConceptCodeSequence"		Operator="And"	Modifier="Not" ElementPresent=""
+		Element="NumericValue"				Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="AcquisitionContextItemIsTime"
+	Element="ValueType"						StringValue="TIME"
+	(
+		Element="Date"										Modifier="Not" ElementPresent=""
+		Element="PersonName"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="TextValue"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="ConceptCodeSequence"		Operator="And"	Modifier="Not" ElementPresent=""
+		Element="NumericValue"				Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="AcquisitionContextItemIsPersonName"
+	Element="ValueType"						StringValue="PNAME"
+	(
+		Element="Date"										Modifier="Not" ElementPresent=""
+		Element="Time"						Operator="And"	Modifier="Not" ElementPresent=""
+		Element="TextValue"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="ConceptCodeSequence"		Operator="And"	Modifier="Not" ElementPresent=""
+		Element="NumericValue"				Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="AcquisitionContextItemIsTextValue"
+	Element="ValueType"			Operator="Or"	StringValue="TEXT"
+	(
+		Element="Date"										Modifier="Not" ElementPresent=""
+		Element="Time"						Operator="And"	Modifier="Not" ElementPresent=""
+		Element="PersonName"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="ConceptCodeSequence"		Operator="And"	Modifier="Not" ElementPresent=""
+		Element="NumericValue"				Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="AcquisitionContextItemIsConceptCodeSequence"
+	Element="ValueType"						StringValue="CODE"
+	(
+		Element="Date"										Modifier="Not" ElementPresent=""
+		Element="Time"						Operator="And"	Modifier="Not" ElementPresent=""
+		Element="PersonName"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="TextValue"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="NumericValue"				Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="ConceptNameCodeSequenceNotPresent"
+	Element="ConceptNameCodeSequence"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="UnformattedTextValueNotPresent"
+	Element="UnformattedTextValue"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ContextIdentifierIsPresent"
+	Element="ContextIdentifier"		ElementPresent=""
+ConditionEnd
+
+Condition="ExtendedCodingScheme"
+	Element="ContextGroupExtensionFlag"	StringValue="Y"
+ConditionEnd
+
+# Conditions for inclusion of type 1C and 2C Elements in Modules  ...
+
+Condition="SamplesPerPixelGreaterThanOne"
+	Element="SamplesPerPixel"		BinaryValue="> 1"
+ConditionEnd
+
+Condition="PhotometricInterpretationNeedsPalette"
+	Element="PhotometricInterpretation"					StringValue="PALETTE COLOR"
+ConditionEnd
+
+Condition="ImagePixelMacroNeedsPaletteDescriptor"
+	Element="PhotometricInterpretation"					StringValue="PALETTE COLOR"
+	Element="PixelPresentation"			Operator="Or"	StringValue="COLOR"
+	Element="PixelPresentation"			Operator="Or"	StringValue="MIXED"
+ConditionEnd
+
+# US and US MF are the only image IODs that include the Palette Color Module
+# Also need to check that segmented data is actually present, since no "mbpo" when this condition is used in Image Pixel Macro
+Condition="ImagePixelMacroNeedsPaletteDescriptorAndNotSegmentedLegallyPresentInPaletteColorModule"
+	(
+		Element="PhotometricInterpretation"					StringValue="PALETTE COLOR"
+		Element="PixelPresentation"			Operator="Or"	StringValue="COLOR"
+		Element="PixelPresentation"			Operator="Or"	StringValue="MIXED"
+	) Operator="Or"
+	(
+		Element="SegmentedRedPaletteColorLookupTableData"				   ElementPresent=""
+		Element="SegmentedGreenPaletteColorLookupTableData"	Operator="And" ElementPresent=""
+		Element="SegmentedBluePaletteColorLookupTableData"	Operator="And" ElementPresent=""
+		(
+			Element="SOPClassUID"					StringValue="1.2.840.10008.5.1.4.1.1.6.1"
+			Element="SOPClassUID"	Operator="Or"	StringValue="1.2.840.10008.5.1.4.1.1.3.1"
+		)  Operator="And"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="NeedsNonSegmentedLookupTableData"
+	(
+		Element="SegmentedRedPaletteColorLookupTableData"				   Modifier="Not" ElementPresent=""
+		Element="SegmentedGreenPaletteColorLookupTableData"	Operator="And" Modifier="Not" ElementPresent=""
+		Element="SegmentedBluePaletteColorLookupTableData"	Operator="And" Modifier="Not" ElementPresent=""
+	) Operator="Or"
+	Element="SOPClassUID"								Operator="Or" StringValue="1.2.840.10008.5.1.4.1.1.11.3"
+	Element="SOPClassUID"								Operator="Or" StringValue="1.2.840.10008.5.1.4.1.1.11.4"
+	Element="SOPClassUID"								Operator="Or" StringValue="1.2.840.10008.5.1.4.39.1"
+ConditionEnd
+
+Condition="NeedsSegmentedLookupTableData"
+	Element="RedPaletteColorLookupTableData"					   Modifier="Not" ElementPresent=""
+	Element="GreenPaletteColorLookupTableData"		Operator="And" Modifier="Not" ElementPresent=""
+	Element="BluePaletteColorLookupTableData"		Operator="And" Modifier="Not" ElementPresent=""
+	Element="SOPClassUID"							Operator="And" Modifier="Not" StringValue="1.2.840.10008.5.1.4.1.1.11.3"
+	Element="SOPClassUID"							Operator="And" Modifier="Not" StringValue="1.2.840.10008.5.1.4.1.1.11.4"
+	Element="SOPClassUID"							Operator="And" Modifier="Not" StringValue="1.2.840.10008.5.1.4.39.1"
+ConditionEnd
+
+Condition="PhotometricInterpretationIsPaletteColor"
+	Element="PhotometricInterpretation"	StringValue="PALETTE COLOR"
+ConditionEnd
+
+Condition="PhotometricInterpretationIsMonochrome2"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME2"
+ConditionEnd
+
+Condition="PhotometricInterpretationIsMonochrome1"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME1"
+ConditionEnd
+
+Condition="PhotometricInterpretationIsMonochrome"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME1"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME2"
+ConditionEnd
+
+Condition="PhotometricInterpretationNeedsOneSample"
+	Element="PhotometricInterpretation"	StringValue="PALETTE COLOR"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME1"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME2"
+ConditionEnd
+
+# use from root since check may be from inside functional group macro
+# check present first, since not true for presentation states (as opposed to images)
+Condition="PhotometricInterpretationIsGrayscaleOrAbsent"
+	Element="PhotometricInterpretation"	Modifier="Not"	ElementPresent=""
+	Element="PhotometricInterpretation"	Operator="Or"	StringValueFromRootAttribute="MONOCHROME1"
+	Element="PhotometricInterpretation"	Operator="Or"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="PhotometricInterpretationIsColor"
+	Element="PhotometricInterpretation"					Modifier="Not"	StringValueFromRootAttribute="MONOCHROME1"
+	Element="PhotometricInterpretation"	Operator="And"	Modifier="Not"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="PhotometricInterpretationNeedsThreeSamples"
+	Element="PhotometricInterpretation"	StringValue="RGB"
+	Element="PhotometricInterpretation"	StringValue="YBR_FULL"
+	Element="PhotometricInterpretation"	StringValue="YBR_FULL_422"
+	Element="PhotometricInterpretation"	StringValue="YBR_PARTIAL_422"
+	Element="PhotometricInterpretation"	StringValue="YBR_PARTIAL_420"
+	Element="PhotometricInterpretation"	StringValue="YBR_RCT"
+	Element="PhotometricInterpretation"	StringValue="YBR_ICT"
+ConditionEnd
+
+Condition="SOPClassIsCTOrMR"
+	Element="SOPClassUID"			StringConstantFromRootAttribute="EnhancedMRImageStorageSOPClassUID"
+	Element="SOPClassUID"			StringConstantFromRootAttribute="EnhancedMRColorImageStorageSOPClassUID"
+	Element="SOPClassUID"			StringConstantFromRootAttribute="MRSpectroscopyStorageSOPClassUID"
+	Element="SOPClassUID"			StringConstantFromRootAttribute="MRImageStorageSOPClassUID"
+	Element="SOPClassUID"			StringConstantFromRootAttribute="EnhancedCTImageStorageSOPClassUID"
+	Element="SOPClassUID"			StringConstantFromRootAttribute="CTImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="ModalityIsCTOrMR"
+	Element="Modality"			StringValue="MR"
+	Element="Modality"			StringValue="CT"
+ConditionEnd
+
+Condition="PatientOrientationRequired"
+	# General Image Module: "Required if image does not require Image Orientation (Patient) (0020,0037) and Image Position (Patient) (0020,0032)."
+	Element="SOPClassUID"			               Modifier="Not" StringConstantFromRootAttribute="EnhancedMRImageStorageSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="MRSpectroscopyStorageSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="MRImageStorageSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="CTImageStorageSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="EnhancedCTImageStorageSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="NuclearMedicineImageStorageSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="NuclearMedicineImageStorageRetiredSOPClassUID"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="PETImageStorageSOPClassUID"
+	# not required for RT dose, since either needed for grid (image) or not an image hence not applicable
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringConstantFromRootAttribute="RTDoseStorageSOPClassUID"
+	(
+		Element="SOPClassUID"				StringConstantFromRootAttribute="SegmentationStorageSOPClassUID"
+		(
+			Element="PlaneOrientationSequence"					ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+			Element="PlaneOrientationSequence"	Operator="Or"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		) Operator="And"
+	) Operator="And" Modifier="Not"
+ConditionEnd
+
+Condition="DXPatientOrientationRequired"
+	Element="ViewCodeSequence"						Modifier="Not" ElementPresent=""
+	(
+		Element="CodingSchemeDesignator"	ElementPresentWithin="ViewCodeSequence"	StringValue="SRT"
+		(
+			Element="CodeValue"									ElementPresentWithin="ViewCodeSequence"					StringValue="G-8300"	# tissue specimen
+			Element="CodeValue"					Operator="Or"	ElementPresentWithin="ViewCodeSequence"					StringValue="G-8310"	# tissue specimen from breast
+		) Operator="And"
+	) Operator="Or" Modifier="Not"
+ConditionEnd
+
+Condition="MRIsNotEchoPlanarNotSegmentedKSpace"
+	Element="ScanningSequence"						Modifier="Not" ValueSelector="*"	StringValue="EP"
+	Element="SequenceVariant"		Operator="Or"	Modifier="Not" ValueSelector="*"	StringValue="SK"
+ConditionEnd
+
+Condition="MRIsInversionRecovery"
+	Element="ScanningSequence"		ValueSelector="*"	StringValue="IR"
+ConditionEnd
+
+Condition="MRIsCardiacOrPulseGated"
+	Element="ScanOptions"							ValueSelector="*"	StringValue="CG"
+	Element="ScanOptions"			Operator="Or"	ValueSelector="*"	StringValue="PPG"
+ConditionEnd
+
+Condition="NMIsWholeBody"
+	Element="NuclearMedicineSeriesType"	StringValue="WHOLE BODY"
+ConditionEnd
+
+Condition="CurveDataDescriptorPresent"
+	Element="CurveDataDescriptor"		ElementPresent="0xff00"
+ConditionEnd
+
+Condition="ModalityLUTSequenceNotPresent"
+	Element="ModalityLUTSequence"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="RescaleInterceptPresent"
+	Element="RescaleIntercept"		ElementPresent=""
+ConditionEnd
+
+Condition="RescaleInterceptNotPresent"
+	Element="RescaleIntercept"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="RescaleTypeIsPresentAndNotHU"
+	Element="RescaleType"			ElementPresent=""
+	Element="RescaleType"			Operator="And" Modifier="Not" StringValue="HU"
+ConditionEnd
+
+Condition="RescaleTypeIsPresentAndNotHUAndImageIsOriginalNotLocalizer"
+	Element="RescaleType"			ElementPresent=""
+	Element="RescaleType"			Operator="And" Modifier="Not" StringValue="HU"
+	Element="ImageType"				Operator="And" ValueSelector="0" StringValue="ORIGINAL"
+	Element="ImageType"				Operator="And" Modifier="Not" ValueSelector="2" StringValue="LOCALIZER"
+ConditionEnd
+
+Condition="RescaleTypeIsPresentAndIsHUAndImageIsOriginalLocalizer"
+	Element="RescaleType"			ElementPresent=""
+	Element="RescaleType"			Operator="And" StringValue="HU"
+	Element="ImageType"				Operator="And" ValueSelector="0" StringValue="ORIGINAL"
+	Element="ImageType"				Operator="And" ValueSelector="2" StringValue="LOCALIZER"
+ConditionEnd
+
+Condition="WindowCenterPresent"
+	Element="WindowCenter"			ElementPresent=""
+ConditionEnd
+
+Condition="WindowCenterNotPresent"
+	Element="WindowCenter"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="MonochromeAndWindowCenterNotPresent"
+	Element="WindowCenter"								Modifier="Not" ElementPresent=""
+	Element="SamplesPerPixel"							Operator="And"	BinaryValueFromRootAttribute="== 1"
+	Element="RedPaletteColorLookupTableDescriptor"		Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="VOILUTSequenceNotPresent"
+	Element="VOILUTSequence"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="MonochromeAndVOILUTSequenceNotPresent"
+	Element="VOILUTSequence"							Modifier="Not" ElementPresent=""
+	Element="SamplesPerPixel"							Operator="And"	BinaryValueFromRootAttribute="== 1"
+	Element="RedPaletteColorLookupTableDescriptor"		Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NumberOfFramesPresent"
+	Element="NumberOfFrames"	ElementPresent=""
+ConditionEnd
+
+# Conditions for NM object ...
+
+Condition="ImageTypeValue3WholeBodyOrStatic"
+	Element="ImageType"		ValueSelector="2"	StringValue="WHOLE BODY"
+	Element="ImageType"		ValueSelector="2"	StringValue="STATIC"
+ConditionEnd
+
+Condition="ImageTypeValue3WholeBody"
+	Element="ImageType"		ValueSelector="2"	StringValue="WHOLE BODY"
+ConditionEnd
+
+Condition="ImageTypeValue3Gated"
+	Element="ImageType"		ValueSelector="2"	StringValue="GATED"
+ConditionEnd
+
+Condition="ImageTypeValue3Dynamic"
+	Element="ImageType"		ValueSelector="2"	StringValue="DYNAMIC"
+ConditionEnd
+
+Condition="ImageTypeValue3Tomo"
+	Element="ImageType"		ValueSelector="2"	StringValue="TOMO"
+ConditionEnd
+
+Condition="ImageTypeValue3GatedTomo"
+	Element="ImageType"		ValueSelector="2"	StringValue="GATED TOMO"
+ConditionEnd
+
+Condition="ImageTypeValue3ReconTomo"
+	Element="ImageType"		ValueSelector="2"	StringValue="RECON TOMO"
+ConditionEnd
+
+Condition="ImageTypeValue3ReconGatedTomo"
+	Element="ImageType"		ValueSelector="2"	StringValue="RECON GATED TOMO"
+ConditionEnd
+
+Condition="ImageTypeValue3TomoFamily"
+	Element="ImageType"		ValueSelector="2"	StringValue="TOMO"
+	Element="ImageType"		ValueSelector="2"	StringValue="GATED TOMO"
+	Element="ImageType"		ValueSelector="2"	StringValue="RECON TOMO"
+	Element="ImageType"		ValueSelector="2"	StringValue="RECON GATED TOMO"
+ConditionEnd
+
+Condition="ImageTypeValue4TransmissionAndNotTomo"
+	# ie. all except the TOMO values ... check if there are more :(
+	Element="ImageType"		ValueSelector="2"	StringValue="STATIC"
+	Element="ImageType"		ValueSelector="2"	StringValue="WHOLE BODY"
+	Element="ImageType"		ValueSelector="3"	Operator="And" StringValue="TRANSMISSION"
+ConditionEnd
+
+Condition="ImageTypeValue4Transmission"
+	Element="ImageType"		ValueSelector="3"	StringValue="TRANSMISSION"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsEnergyWindowVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0010"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsDetectorVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0020"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsPhaseVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0030"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsRotationVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0050"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsRRIntervalVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0060"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsTimeSlotVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0070"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsSliceVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0080"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsAngularViewVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0090"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsTimeSliceVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0054,0x0100"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsInstanceNumber"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0020,0x0013"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsImageTime"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0008,0x0033"
+ConditionEnd
+
+Condition="TriggerVectorIsPresent"
+	Element="TriggerVector"					ElementPresent=""
+ConditionEnd
+
+# for existing cine module ...
+
+Condition="FrameIncrementPointerContainsFrameTime"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0018,0x1063"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsFrameTimeVector"
+	Element="FrameIncrementPointer"	ValueSelector="*"	TagValue="0x0018,0x1065"
+ConditionEnd
+
+# Conditions for new XA and XRF objects ...
+
+Condition="ImageTypeValue3BiplaneAOrB"
+	Element="ImageType"		ValueSelector="2"	StringValue="BIPLANE A"
+	Element="ImageType"		ValueSelector="2"	StringValue="BIPLANE B"
+ConditionEnd
+
+Condition="OneOverlayForBothPlanesOfBiplane"
+	Element="OverlayPlanes"		BinaryValue="== 1"
+	Element="ImageType"		Operator="And" ValueSelector="2" StringValue="BIPLANE"
+ConditionEnd
+
+Condition="PositionerMotionDynamic"
+	Element="PositionerMotion"	StringValue="DYNAMIC"
+ConditionEnd
+
+Condition="TableMotionDynamic"
+	Element="TableMotion"		StringValue="DYNAMIC"
+ConditionEnd
+
+Condition="ExposureNotPresent"
+	Element="Exposure"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="XRayTubeCurrentAndExposureTimeNotPresent"
+	Element="XRayTubeCurrent"	Modifier="Not" ElementPresent=""
+	Element="ExposureTime"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="DeviceDiameterIsPresent"
+	Element="DeviceDiameter"	ElementPresent=""
+ConditionEnd
+
+Condition="ShutterShapeIsAbsent"
+	Element="ShutterShape"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ShutterShapeIsPresent"
+	Element="ShutterShape"		ElementPresent=""
+ConditionEnd
+
+Condition="ShutterShapeIsRectangular"
+	Element="ShutterShape"		ValueSelector="*"	StringValue="RECTANGULAR"
+ConditionEnd
+
+Condition="ShutterShapeIsCircular"
+	Element="ShutterShape"		ValueSelector="*"	StringValue="CIRCULAR"
+ConditionEnd
+
+Condition="ShutterShapeIsPolygonal"
+	Element="ShutterShape"		ValueSelector="*"	StringValue="POLYGONAL"
+ConditionEnd
+
+Condition="CollimatorShapeIsRectangular"
+	Element="CollimatorShape"	ValueSelector="*"	StringValue="RECTANGULAR"
+ConditionEnd
+
+Condition="CollimatorShapeIsCircular"
+	Element="CollimatorShape"	ValueSelector="*"	StringValue="CIRCULAR"
+ConditionEnd
+
+Condition="CollimatorShapeIsPolygonal"
+	Element="CollimatorShape"	ValueSelector="*"	StringValue="POLYGONAL"
+ConditionEnd
+
+Condition="MaskOperationIsTID"
+	Element="MaskOperation"		StringValue="TID"
+ConditionEnd
+
+Condition="MaskOperationIsAvgSub"
+	Element="MaskOperation"		StringValue="AVG_SUB"
+ConditionEnd
+
+Condition="NeedModuleFramePointers"
+	Element="RepresentativeFrameNumber"	ElementPresent=""
+	Element="FrameNumbersOfInterest"	ElementPresent=""
+	Element="FrameOfInterestDescription"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleMask"
+	Element="MaskSubtractionSequence"	ElementPresent=""
+	Element="RecommendedViewingMode"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleDisplayShutter"
+	Element="ShutterShape"				ElementPresent=""
+	Element="ShutterShape"				Operator="And"	Modifier="Not"	StringValue="BITMAP"
+	Element="ShutterLeftVerticalEdge"	ElementPresent=""
+	Element="ShutterRightVerticalEdge"	ElementPresent=""
+	Element="ShutterUpperHorizontalEdge"	ElementPresent=""
+	Element="ShutterLowerHorizontalEdge"	ElementPresent=""
+	Element="CenterOfCircularShutter"	ElementPresent=""
+	Element="RadiusOfCircularShutter"	ElementPresent=""
+	Element="VerticesOfThePolygonalShutter"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleDevice"
+	Element="DeviceSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleIntervention"
+	Element="InterventionSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRayCollimator"
+	Element="CollimatorShape"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRayTable"
+	Element="TableMotion"			ElementPresent=""
+	Element="TableAngle"			ElementPresent=""
+ConditionEnd
+
+Condition="XRayNeedModuleModalityLUT"
+	Element="PixelIntensityRelationship"	StringValue="LOG"
+	# Optional if Pixel Intensity Relationship is DISP
+ConditionEnd
+
+Condition="NeedModuleBiplaneOverlay"
+	Element="OverlayPlanes"			ElementPresent=""
+	Element="OverlayPlaneOrigin"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRayTomographyAcquisitionBasedOnScanOptions"
+	Element="ScanOptions"		StringValue="TOMO"
+ConditionEnd
+
+Condition="NeedToCheckModuleXRayTomographyAcquisition"
+	Element="TomoLayerHeight"			ElementPresent=""
+ConditionEnd
+
+# Meta Information Header stuff ...
+
+Condition="NeedModuleFileMetaInformation"
+	Element="FileMetaInformationVersion"	GroupPresent=""
+ConditionEnd
+
+Condition="PrivateInformationCreatorUIDPresent"
+	Element="PrivateInformationCreatorUID"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedPixelComponentOrganization"
+# condition is real world, but assume on presence of dependent atributes ...
+	Element="PixelComponentMask"		ElementPresent=""
+	Element="PixelComponentRangeStart"	ElementPresent=""
+	Element="PixelComponentRangeStop"	ElementPresent=""
+	Element="PixelComponentPhysicalUnits"	ElementPresent=""
+	Element="PixelComponentDataType"	ElementPresent=""
+	Element="NumberOfTableBreakPoints"	ElementPresent=""
+	Element="TableOfXBreakPoints"		ElementPresent=""
+	Element="TableOfYBreakPoints"		ElementPresent=""
+	Element="NumberOfTableEntries"		ElementPresent=""
+	Element="TableOfPixelValues"		ElementPresent=""
+	Element="TableOfParameterValues"	ElementPresent=""
+ConditionEnd
+
+Condition="PixelComponentOrganizationPresent"
+	Element="PixelComponentOrganization"	ElementPresent=""
+ConditionEnd
+
+Condition="PixelComponentOrganizationIs0Or1"
+	Element="PixelComponentOrganization"	BinaryValue="== 0"
+	Element="PixelComponentOrganization"	BinaryValue="== 1"
+ConditionEnd
+
+Condition="PixelComponentOrganizationIs0"
+	Element="PixelComponentOrganization"	BinaryValue="== 0"
+ConditionEnd
+
+Condition="PixelComponentOrganizationIs1"
+	Element="PixelComponentOrganization"	BinaryValue="== 1"
+ConditionEnd
+
+Condition="PixelComponentOrganizationIs2"
+	Element="PixelComponentOrganization"	BinaryValue="== 2"
+ConditionEnd
+
+Condition="PixelComponentOrganizationIs3"
+	Element="PixelComponentOrganization"	BinaryValue="== 3"
+ConditionEnd
+
+Condition="PixelComponentOrganizationIs2Or3"
+	Element="PixelComponentOrganization"	BinaryValue="== 2"
+	Element="PixelComponentOrganization"	BinaryValue="== 3"
+ConditionEnd
+
+Condition="US8BitSamples"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME2"
+	Element="PhotometricInterpretation"	StringValue="RGB"
+	Element="PhotometricInterpretation"	StringValue="YBR_FULL"
+	Element="PhotometricInterpretation"	StringValue="YBR_FULL_422"
+	Element="PhotometricInterpretation"	StringValue="YBR_PARTIAL_422"
+ConditionEnd
+
+Condition="US8Or16BitSamples"
+	Element="PhotometricInterpretation"	StringValue="PALETTE COLOR"
+ConditionEnd
+
+Condition="USNeedsColorByPlaneOrPixel"
+	Element="PhotometricInterpretation"	StringValue="RGB"
+ConditionEnd
+
+Condition="USNeedsColorByPlane"
+	Element="PhotometricInterpretation"	StringValue="YBR_FULL"
+ConditionEnd
+
+Condition="USNeedsColorByPixel"
+	Element="PhotometricInterpretation"	StringValue="YBR_FULL_422"
+	Element="PhotometricInterpretation"	StringValue="YBR_PARTIAL_422"
+ConditionEnd
+
+Condition="DirectorySOPInstance"
+	Element="DirectoryRecordType"		StringValue="IMAGE"
+	Element="DirectoryRecordType"		StringValue="OVERLAY"
+	Element="DirectoryRecordType"		StringValue="MODALITY LUT"
+	Element="DirectoryRecordType"		StringValue="VOI LUT"
+	Element="DirectoryRecordType"		StringValue="CURVE"
+	Element="DirectoryRecordType"		StringValue="VISIT"
+	Element="DirectoryRecordType"		StringValue="RESULTS"
+	Element="DirectoryRecordType"		StringValue="INTERPRETATION"
+	Element="DirectoryRecordType"		StringValue="STUDY COMPONENT"
+	Element="DirectoryRecordType"		StringValue="FILM SESSION"
+	Element="DirectoryRecordType"		StringValue="FILM BOX"
+	Element="DirectoryRecordType"		StringValue="IMAGE BOX"
+	Element="DirectoryRecordType"		StringValue="STORED PRINT"
+	Element="DirectoryRecordType"		StringValue="RT DOSE"
+	Element="DirectoryRecordType"		StringValue="RT STRUCTURE SET"
+	Element="DirectoryRecordType"		StringValue="RT PLAN"
+	Element="DirectoryRecordType"		StringValue="RT TREAT RECORD"
+	Element="DirectoryRecordType"		StringValue="PRESENTATION"
+	Element="DirectoryRecordType"		StringValue="WAVEFORM"
+	Element="DirectoryRecordType"		StringValue="SR DOCUMENT"
+	Element="DirectoryRecordType"		StringValue="KEY OBJECT DOC"
+	Element="DirectoryRecordType"		StringValue="SPECTROSCOPY"
+	Element="DirectoryRecordType"		StringValue="RAW DATA"
+	Element="DirectoryRecordType"		StringValue="REGISTRATION"
+	Element="DirectoryRecordType"		StringValue="FIDUCIAL"
+	Element="DirectoryRecordType"		StringValue="ENCAP DOC"
+	Element="DirectoryRecordType"		StringValue="HL7 STRUC DOC"
+	Element="DirectoryRecordType"		StringValue="HANGING PROTOCOL"
+	Element="DirectoryRecordType"		StringValue="VALUE MAP"
+	Element="DirectoryRecordType"		StringValue="STEREOMETRIC"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsPatient"
+	Element="DirectoryRecordType"		StringValue="PATIENT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsStudy"
+	Element="DirectoryRecordType"		StringValue="STUDY"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsSeries"
+	Element="DirectoryRecordType"		StringValue="SERIES"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsImage"
+	Element="DirectoryRecordType"		StringValue="IMAGE"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsOverlay"
+	Element="DirectoryRecordType"		StringValue="OVERLAY"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsModalityLUT"
+	Element="DirectoryRecordType"		StringValue="MODALITY LUT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsVOILUT"
+	Element="DirectoryRecordType"		StringValue="VOI LUT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsCurve"
+	Element="DirectoryRecordType"		StringValue="CURVE"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsTopic"
+	Element="DirectoryRecordType"		StringValue="TOPIC"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsVisit"
+	Element="DirectoryRecordType"		StringValue="VISIT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsResults"
+	Element="DirectoryRecordType"		StringValue="RESULTS"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsInterpretation"
+	Element="DirectoryRecordType"		StringValue="INTERPRETATION"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsStudyComponent"
+	Element="DirectoryRecordType"		StringValue="STUDY COMPONENT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsPrintQueue"
+	Element="DirectoryRecordType"		StringValue="PRINT QUEUE"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsFilmSession"
+	Element="DirectoryRecordType"		StringValue="FILM SESSION"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsFilmBox"
+	Element="DirectoryRecordType"		StringValue="FILM BOX"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsImageBox"
+	Element="DirectoryRecordType"		StringValue="IMAGE BOX"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsStoredPrint"
+	Element="DirectoryRecordType"		StringValue="STORED PRINT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRTDose"
+	Element="DirectoryRecordType"		StringValue="RT DOSE"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRTStructureSet"
+	Element="DirectoryRecordType"		StringValue="RT STRUCTURE SET"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRTPlan"
+	Element="DirectoryRecordType"		StringValue="RT PLAN"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRTTreatmentRecord"
+	Element="DirectoryRecordType"		StringValue="RT TREAT RECORD"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsPresentation"
+	Element="DirectoryRecordType"		StringValue="PRESENTATION"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsWaveform"
+	Element="DirectoryRecordType"		StringValue="WAVEFORM"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsSRDocument"
+	Element="DirectoryRecordType"		StringValue="SR DOCUMENT"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsKeyObjectDocument"
+	Element="DirectoryRecordType"		StringValue="KEY OBJECT DOC"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsSpectroscopy"
+	Element="DirectoryRecordType"		StringValue="SPECTROSCOPY"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRawData"
+	Element="DirectoryRecordType"		StringValue="RAW DATA"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRegistration"
+	Element="DirectoryRecordType"		StringValue="REGISTRATION"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsFiducial"
+	Element="DirectoryRecordType"		StringValue="FIDUCIAL"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsEncapsulatedDocument"
+	Element="DirectoryRecordType"		StringValue="ENCAP DOC"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsHL7StructuredDocument"
+	Element="DirectoryRecordType"		StringValue="HL7 STRUC DOC"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsHangingProtocol"
+	Element="DirectoryRecordType"		StringValue="HANGING PROTOCOL"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsRealWorldValueMapping"
+	Element="DirectoryRecordType"		StringValue="VALUE MAP"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsStereometricRelationship"
+	Element="DirectoryRecordType"		StringValue="STEREOMETRIC"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsSurface"
+	Element="DirectoryRecordType"		StringValue="SURFACE"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsPrivate"
+	Element="DirectoryRecordType"		StringValue="PRIVATE"
+ConditionEnd
+
+Condition="DirectoryRecordTypeIsMRDR"
+	Element="DirectoryRecordType"		StringValue="MRDR"
+ConditionEnd
+
+Condition="ReferencedSOPInstanceUIDInFileIsNotPresent"
+	Element="ReferencedSOPInstanceUIDInFile"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+# for RT
+
+Condition="NeedModuleRTPrescription"
+	Element="PrescriptionDescription"	ElementPresent=""
+	Element="DoseReferenceSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleRTToleranceTables"
+	Element="ToleranceTableSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleRTIonToleranceTables"
+	Element="IonToleranceTableSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleRTPatientSetup"
+	Element="PatientSetupSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleRTFractionScheme"
+	Element="FractionGroupSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedRTBeams"
+	Element="FractionGroupSequence"		ElementPresent=""
+	Element="NumberOfBeams"			Operator="And" ElementPresent=""
+	Element="NumberOfBeams"			Operator="And" BinaryValue="> 0"
+# Below is for presence of module, above is its requirement to be present ...
+	Element="BeamSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedRTIonBeams"
+	Element="FractionGroupSequence"		ElementPresent=""
+	Element="NumberOfBeams"			Operator="And" ElementPresent=""
+	Element="NumberOfBeams"			Operator="And" BinaryValue="> 0"
+# Below is for presence of module, above is its requirement to be present ...
+	Element="IonBeamSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedRTBrachyApplicationSetups"
+	Element="FractionGroupSequence"			ElementPresent=""
+	Element="NumberOfBrachyApplicationSetups"	Operator="And" ElementPresent=""
+	Element="NumberOfBrachyApplicationSetups"	Operator="And" BinaryValue="> 0"
+# Below is for presence of module, above is its requirement to be present ...
+	Element="BrachyTreatmentTechnique"		ElementPresent=""
+	Element="BrachyTreatmentType"			ElementPresent=""
+	Element="TreatmentMachineSequence"		ElementPresent=""
+	Element="ApplicationSetupSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="DoseDataGridbased"
+	Element="InstanceNumber"		ElementPresent=""
+	Element="PixelSpacing"			ElementPresent=""
+	Element="ImageOrientationPatient"	ElementPresent=""
+	Element="ImagePositionPatient"		ElementPresent=""
+	Element="SliceThickness"		ElementPresent=""
+	Element="SamplesPerPixel"		ElementPresent=""
+	Element="PhotometricInterpretation"	ElementPresent=""
+	Element="Rows"				ElementPresent=""
+	Element="Columns"			ElementPresent=""
+	Element="BitsAllocated"			ElementPresent=""
+	Element="BitsStored"			ElementPresent=""
+	Element="HighBit"			ElementPresent=""
+	Element="PixelRepresentation"		ElementPresent=""
+	Element="PixelData"			ElementPresent=""
+ConditionEnd
+
+Condition="DoseDataGridbasedAndNeedModuleMultiFrame"
+	(
+		Element="InstanceNumber"		ElementPresent=""
+		Element="PixelSpacing"			ElementPresent=""
+		Element="ImageOrientationPatient"	ElementPresent=""
+		Element="ImagePositionPatient"		ElementPresent=""
+		Element="SliceThickness"		ElementPresent=""
+		Element="SamplesPerPixel"		ElementPresent=""
+		Element="PhotometricInterpretation"	ElementPresent=""
+		Element="Rows"				ElementPresent=""
+		Element="Columns"			ElementPresent=""
+		Element="BitsAllocated"			ElementPresent=""
+		Element="BitsStored"			ElementPresent=""
+		Element="HighBit"			ElementPresent=""
+		Element="PixelRepresentation"		ElementPresent=""
+		Element="PixelData"			ElementPresent=""
+	)
+	(
+		Element="NumberOfFrames"		ElementPresent=""
+		Element="NumberOfFrames"		Operator="And" BinaryValue="> 1"
+	) Operator="And"
+ConditionEnd
+
+Condition="DoseDataPointsOrCurves"
+	Element="StructureSetLabel"		ElementPresent=""
+	Element="ROIContourSequence"		ElementPresent=""
+	Element="RTDoseROISequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleRTDVH"
+	Element="ReferencedStructureSetSequence"	ElementPresent=""
+	Element="DVHNormalizationPoint"			ElementPresent=""
+	Element="DVHNormalizationDoseValue"		ElementPresent=""
+	Element="DVHSequence"				ElementPresent=""
+ConditionEnd
+
+Condition="ImageTypeValue3SimulatorOrPortal"
+	Element="ImageType"		ValueSelector="2"	StringValue="SIMULATOR"
+	Element="ImageType"		ValueSelector="2"	StringValue="PORTAL"
+ConditionEnd
+
+Condition="ImageTypeValue3SimulatorOrPortalOrRadiograph"
+	Element="ImageType"		ValueSelector="2"	StringValue="SIMULATOR"
+	Element="ImageType"		ValueSelector="2"	StringValue="PORTAL"
+	Element="ImageType"		ValueSelector="2"	StringValue="RADIOGRAPH"
+ConditionEnd
+
+Condition="ImageTypeValue3SimulatorOrRadiograph"
+	Element="ImageType"		ValueSelector="2"	StringValue="SIMULATOR"
+	Element="ImageType"		ValueSelector="2"	StringValue="RADIOGRAPH"
+ConditionEnd
+
+Condition="ImageTypeValue3Portal"
+	Element="ImageType"		ValueSelector="2"	StringValue="PORTAL"
+ConditionEnd
+
+Condition="ImageTypeValue3Fluence"
+	Element="ImageType"		ValueSelector="2"	StringValue="FLUENCE"
+ConditionEnd
+
+Condition="RTImagePlaneIsNonNormal"
+	Element="RTImagePlane"		StringValue="NON_NORMAL"
+ConditionEnd
+
+Condition="NeedExposureSequenceReferencedFrameNumber"
+# not strictly correct ... doesn't check for more than one item in ExposureSequence
+	Element="NumberOfFrames"		ElementPresent=""
+	Element="NumberOfFrames"		Operator="And" BinaryValue="> 1"
+ConditionEnd
+
+Condition="RTBeamLimitingDeviceTypeMLCXOrMLCY"
+	Element="RTBeamLimitingDeviceType"	StringValue="MLCX"
+	Element="RTBeamLimitingDeviceType"	StringValue="MLCY"
+ConditionEnd
+
+Condition="NumberOfBlocksNotZero"
+	Element="NumberOfBlocks"		ElementPresent=""
+	Element="NumberOfBlocks"		Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfRangeShiftersNotZero"
+	Element="NumberOfRangeShifters"		ElementPresent=""
+	Element="NumberOfRangeShifters"		Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfLateralSpreadingDevicesNotZero"
+	Element="NumberOfLateralSpreadingDevices"		ElementPresent=""
+	Element="NumberOfLateralSpreadingDevices"		Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfRangeModulatorsNotZero"
+	Element="NumberOfRangeModulators"		ElementPresent=""
+	Element="NumberOfRangeModulators"		Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfBeamsNotZero"
+	Element="NumberOfBeams"			ElementPresent=""
+	Element="NumberOfBeams"			Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfBrachyApplicationSetupsNotZero"
+	Element="NumberOfBrachyApplicationSetups"	ElementPresent=""
+	Element="NumberOfBrachyApplicationSetups"	Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfWedgesNotZero"
+	Element="NumberOfWedges"			ElementPresent=""
+	Element="NumberOfWedges"			Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NumberOfCompensatorsNotZero"
+	Element="NumberOfCompensators"			ElementPresent=""
+	Element="NumberOfCompensators"			Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="NeedSourceToCompensatorDistance"
+	Element="MaterialID"				ElementPresent=""
+	Element="MaterialID"				Operator="And" ValuePresent=""
+	Element="CompensatorMountingPosition"		Operator="And" ElementPresent=""
+	Element="CompensatorMountingPosition"		Operator="And" StringValue="DOUBLE_SIDED"
+ConditionEnd
+
+Condition="NeedIsocenterToCompensatorDistance"
+	Element="MaterialID"				ElementPresent=""
+	Element="MaterialID"				Operator="And" ValuePresent=""
+	Element="CompensatorMountingPosition"		Operator="And" ElementPresent=""
+	Element="CompensatorMountingPosition"		Operator="And" StringValue="DOUBLE_SIDED"
+ConditionEnd
+
+Condition="NumberOfBoliNotZero"
+	Element="NumberOfBoli"			ElementPresent=""
+	Element="NumberOfBoli"			Operator="And" BinaryValue="> 0"
+ConditionEnd
+
+Condition="PixelDataPresent"
+	Element="PixelData"			ElementPresent=""
+ConditionEnd
+
+Condition="FloatPixelDataPresent"
+	Element="FloatPixelData"		ElementPresent=""
+ConditionEnd
+
+Condition="DoubleFloatPixelDataPresent"
+	Element="DoubleFloatPixelData"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedReferencedRTPlanSequence"
+	Element="DoseSummationType"		StringValueFromRootAttribute="PLAN"
+	Element="DoseSummationType"		StringValueFromRootAttribute="MULTI_PLAN"
+	Element="DoseSummationType"		StringValueFromRootAttribute="FRACTION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BEAM"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BRACHY"
+	Element="DoseSummationType"		StringValueFromRootAttribute="FRACTION_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BEAM_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BRACHY_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="CONTROL_POINT"
+ConditionEnd
+
+Condition="NeedReferencedFractionGroupSequence"
+	Element="DoseSummationType"		StringValueFromRootAttribute="FRACTION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BEAM"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BRACHY"
+	Element="DoseSummationType"		StringValueFromRootAttribute="FRACTION_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BEAM_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BRACHY_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="CONTROL_POINT"
+ConditionEnd
+
+Condition="NeedReferencedBeamSequence"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BEAM"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BEAM_SESSION"
+	Element="DoseSummationType"		StringValueFromRootAttribute="CONTROL_POINT"
+ConditionEnd
+
+Condition="DoseSummationTypeControlPoint"
+	Element="DoseSummationType"		StringValueFromRootAttribute="CONTROL_POINT"
+ConditionEnd
+
+Condition="NeedReferencedBrachyApplicationSetupSequence"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BRACHY"
+	Element="DoseSummationType"		StringValueFromRootAttribute="BRACHY_SESSION"
+ConditionEnd
+
+Condition="NeedGridFrameOffsetVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x3004,0x000C"
+ConditionEnd
+
+Condition="RTPlanGeometryIsPatient"
+	Element="RTPlanGeometry"		StringValue="PATIENT"
+ConditionEnd
+
+Condition="PlanIntentIsVerification"
+	Element="PlanIntent"		StringValueFromRootAttribute="VERIFICATION"
+ConditionEnd
+
+Condition="DoseReferenceStructureTypePointOrVolume"
+	Element="DoseReferenceStructureType"	StringValue="POINT"
+	Element="DoseReferenceStructureType"	StringValue="VOLUME"
+ConditionEnd
+
+Condition="DoseReferenceStructureTypeCoordinates"
+	Element="DoseReferenceStructureType"	StringValue="COORDINATES"
+ConditionEnd
+
+Condition="PatientAdditionalPositionNotPresent"
+	Element="PatientAdditionalPosition"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="PatientPositionNotPresent"
+	Element="PatientPosition"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="BrachyTreatmentTypePDR"
+	Element="BrachyTreatmentType"		StringValue="PDR"
+ConditionEnd
+
+Condition="SourceApplicatorNumberPresent"
+	Element="SourceApplicatorNumber"	ElementPresent=""
+ConditionEnd
+
+Condition="SourceMovementTypeStepwise"
+	Element="SourceMovementType"		StringValue="STEPWISE"
+ConditionEnd
+
+Condition="TransferTubeNumberNotNull"
+	Element="TransferTubeNumber"		ElementPresent=""
+	Element="TransferTubeNumber"		Operator="And" ValuePresent=""
+ConditionEnd
+
+Condition="ApprovalStatusApprovedOrRejected"
+	Element="ApprovalStatus"		StringValue="APPROVED"
+	Element="ApprovalStatus"		StringValue="REJECTED"
+ConditionEnd
+
+Condition="NeedReferencedFrameNumberInContourImageSequence"
+# too difficult to check real world condition
+ConditionEnd
+
+# RT Treatment Record
+
+Condition="NeedModuleRTTreatmentSummaryRecord"
+	Element="CurrentTreatmentStatus"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleCalculatedDoseReferenceRecord"
+	Element="CalculatedDoseReferenceSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleMeasuredDoseReferenceRecord"
+	Element="MeasuredDoseReferenceSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="MeasuredDoseReferenceNumberNotPresent"
+	Element="MeasuredDoseReferenceNumber"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ReferencedMeasuredDoseReferenceNumberNotPresent"
+	Element="ReferencedMeasuredDoseReferenceNumber"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ReferencedDoseReferenceNumberNotPresent"
+	Element="ReferencedDoseReferenceNumber"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ReferencedCalculatedDoseReferenceNumberNotPresent"
+	Element="ReferencedCalculatedDoseReferenceNumber"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="CalculatedDoseReferenceNumberNotPresent"
+	Element="CalculatedDoseReferenceNumber"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NominalBeamEnergyIsPresent"
+	Element="NominalBeamEnergy"				ElementPresent=""
+ConditionEnd
+
+Condition="BrachyTreatmentTypeIsPDR"
+	Element="BrachyTreatmentType"				StringValue="PDR"
+ConditionEnd
+
+Condition="TransferTubeNumberIsNotEmpty"
+	Element="TransferTubeNumber"				ValuePresent=""
+ConditionEnd
+
+Condition="SourceIsNotGammaEmitter"
+	Element="ReferenceAirKermaRate"				BinaryValue="== 0"
+ConditionEnd
+
+# PET
+
+Condition="NeedModulePETMultigatedAcquisition"
+	Element="SeriesType"				ValueSelector="0"	StringValue="GATED"
+ConditionEnd
+
+Condition="PETSeriesType2Reprojection"
+	Element="SeriesType"				ValueSelector="1"	StringValue="REPROJECTION"
+ConditionEnd
+
+Condition="PETSeriesType1Gated"
+	Element="SeriesType"				ValueSelector="0"	StringValue="GATED"
+ConditionEnd
+
+Condition="PETSeriesType1Dynamic"
+	Element="SeriesType"				ValueSelector="0"	StringValue="DYNAMIC"
+ConditionEnd
+
+Condition="PETSeriesType1GatedAndBeatRejection"
+	Element="SeriesType"				ValueSelector="0"	StringValue="DYNAMIC"
+	Element="BeatRejectionFlag"			Operator="And" ElementPresent=""
+	Element="BeatRejectionFlag"			Operator="And" StringValue="Y"
+ConditionEnd
+
+Condition="DecayCorrectionNotNone"
+	Element="DecayCorrection"			ElementPresent=""
+	Element="DecayCorrection"			Operator="And" Modifier="Not" StringValue="NONE"
+ConditionEnd
+
+Condition="TypeOfDataIsBloodSample"
+	Element="TypeOfData"				ElementPresent=""
+	Element="TypeOfData"				Operator="And" StringValue="BLDSMPL"
+ConditionEnd
+
+Condition="AxisUnitsIncludesCounts"
+	Element="TypeOfData"				StringValue="CNTS"
+	Element="TypeOfData"				StringValue="CPS"
+ConditionEnd
+
+# DX Letter Ballot stuff ...
+
+#
+# note that ExposureInmAs, XRayTubeCurrentInmA and ExposureTimeInms are not in the Module, but used here to trigger checker for their (unwanted) presence
+#
+Condition="NeedModuleXRayAcquisitionDose"
+	Element="KVP"						ElementPresent=""
+	
+	Element="XRayTubeCurrent"			ElementPresent=""
+	Element="XRayTubeCurrentInuA"		ElementPresent=""
+	Element="XRayTubeCurrentInmA"		ElementPresent=""
+	
+	Element="ExposureTime"				ElementPresent=""
+	Element="ExposureTimeInuS"			ElementPresent=""
+	Element="ExposureTimeInms"			ElementPresent=""
+	
+	Element="Exposure"					ElementPresent=""
+	Element="ExposureInuAs"				ElementPresent=""
+	Element="ExposureInmAs"				ElementPresent=""
+	
+	Element="DistanceSourceToDetector"	ElementPresent=""
+	Element="DistanceSourceToPatient"	ElementPresent=""
+	Element="ImageAndFluoroscopyAreaDoseProduct"		ElementPresent=""
+	Element="BodyPartThickness"		ElementPresent=""
+	Element="EntranceDose"			ElementPresent=""
+	Element="ExposedArea"			ElementPresent=""
+	Element="DistanceSourceToEntrance"	ElementPresent=""
+	Element="CommentsOnRadiationDose"	ElementPresent=""
+	Element="XRayOutput"			ElementPresent=""
+	Element="HalfValueLayer"		ElementPresent=""
+	Element="OrganDose"			ElementPresent=""
+	Element="OrganExposed"			ElementPresent=""
+	Element="AnodeTargetMaterial"		ElementPresent=""
+	Element="FilterMaterial"		ElementPresent=""
+	Element="FilterThicknessMaximum"	ElementPresent=""
+	Element="FilterThicknessMinimum"	ElementPresent=""
+	Element="RectificationType"		ElementPresent=""
+ConditionEnd
+
+#
+# note that ExposureInmAs, XRayTubeCurrentInmA and ExposureTimeInms are not in the Module, but used here to trigger checker for their (unwanted) presence
+#
+Condition="NeedModuleXRayGeneration"
+	Element="KVP"						ElementPresent=""
+	
+	Element="XRayTubeCurrent"			ElementPresent=""
+	Element="XRayTubeCurrentInuA"		ElementPresent=""
+	Element="XRayTubeCurrentInmA"		ElementPresent=""
+	
+	Element="ExposureTime"				ElementPresent=""
+	Element="ExposureTimeInuS"			ElementPresent=""
+	Element="ExposureTimeInms"			ElementPresent=""
+	
+	Element="Exposure"					ElementPresent=""
+	Element="ExposureInuAs"				ElementPresent=""
+	Element="ExposureInmAs"				ElementPresent=""
+	
+	Element="ExposureControlMode"				ElementPresent=""
+	Element="ExposureControlModeDescription"	ElementPresent=""
+	Element="ExposureStatus"					ElementPresent=""
+	Element="PhototimerSetting"					ElementPresent=""
+	Element="FocalSpots"						ElementPresent=""
+	Element="AnodeTargetMaterial"				ElementPresent=""
+	Element="RectificationType"					ElementPresent=""
+ConditionEnd
+
+Condition="XRayTubeCurrentInmAIsPresentAndOthersAreNot"
+	Element="XRayTubeCurrentInmA"				ElementPresent=""
+	Element="XRayTubeCurrent"					Operator="And" Modifier="Not" ValuePresent=""
+	Element="XRayTubeCurrentInuA"				Operator="And" Modifier="Not" ValuePresent=""
+ConditionEnd
+
+Condition="ExposureTimeInmsIsPresentAndOthersAreNot"
+	Element="ExposureTimeInms"					ElementPresent=""
+	Element="ExposureTime"						Operator="And" Modifier="Not" ValuePresent=""
+	Element="ExposureTimeInuS"					Operator="And" Modifier="Not" ValuePresent=""
+ConditionEnd
+
+Condition="ExposureInmAsIsPresentAndOthersAreNot"
+	Element="ExposureInmAs"						ElementPresent=""
+	Element="Exposure"							Operator="And" Modifier="Not" ValuePresent=""
+	Element="ExposureInuAs"						Operator="And" Modifier="Not" ValuePresent=""
+ConditionEnd
+
+Condition="NeedModuleXRayFiltration"
+	Element="FilterType"			ElementPresent=""
+	Element="FilterMaterial"		ElementPresent=""
+	Element="FilterThicknessMaximum"	ElementPresent=""
+	Element="FilterThicknessMinimum"	ElementPresent=""
+ConditionEnd
+
+# strategy here is any mandatory element and any optional that isn't used elsewhere in the IOD ...
+Condition="NeedModuleDXPositioning"
+	Element="ProjectionEponymousNameCodeSequence"		ElementPresent=""
+	Element="PatientPosition"		ElementPresent=""
+	Element="ViewPosition"		ElementPresent=""
+	Element="ViewCodeSequence"		ElementPresent=""
+	Element="ViewModifierCodeSequence"		ElementPresent=""
+	Element="PatientOrientationCodeSequence"		ElementPresent=""
+	Element="EstimatedRadiographicMagnificationFactor"	ElementPresent=""
+	Element="PositionerType"				ElementPresent=""
+	Element="DetectorPrimaryAngle"				ElementPresent=""
+	Element="DetectorSecondaryAngle""			ElementPresent=""
+	Element="ColumnAngulation"				ElementPresent=""
+	Element="TableAngle"					ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRayGrid"
+	Element="Grid"				ElementPresent=""
+	Element="GridAbsorbingMaterial"		ElementPresent=""
+	Element="GridSpacingMaterial"		ElementPresent=""
+	Element="GridThickness"			ElementPresent=""
+	Element="GridPitch"			ElementPresent=""
+	Element="GridAspectRatio"		ElementPresent=""
+	Element="GridPeriod"			ElementPresent=""
+	Element="GridFocalDistance"		ElementPresent=""
+ConditionEnd
+
+Condition="DXNeedModuleVOILUT"
+	Element="PresentationIntentType"	StringValue="FOR PRESENTATION"
+ConditionEnd
+
+Condition="NeedModuleImageHistogram"
+	Element="HistogramSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="ImageLateralityNotSent"
+	Element="ImageLaterality"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+	# real world - Performed Procedure Step SOP Class supported, so just check if sequence present anyway
+	Element="ReferencedPerformedProcedureStepSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="CodingSchemeDesignatorisSNM3"
+	Element="CodingSchemeDesignator"	StringValue="SNM3"
+ConditionEnd
+
+Condition="ForPresentationAndWindowCenterNotPresent"
+	Element="PresentationIntentType"	StringValue="FOR PRESENTATION"
+	Element="WindowCenter"			Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ForPresentationAndVOILUTSequenceNotPresent"
+	Element="PresentationIntentType"	StringValue="FOR PRESENTATION"
+	Element="VOILUTSequence"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FieldOfViewRotationOrFieldOfViewHorizontalFlipPresent"
+	Element="FieldOfViewRotation"		ElementPresent=""
+	Element="FieldOfViewHorizontalFlip"	ElementPresent=""
+ConditionEnd
+
+Condition="FieldOfViewRotationPresent"
+	Element="FieldOfViewRotation"		ElementPresent=""
+ConditionEnd
+
+Condition="FieldOfViewHorizontalFlipPresent"
+	Element="FieldOfViewHorizontalFlip"	ElementPresent=""
+ConditionEnd
+
+Condition="NoPrimaryAnatomicStructureSequence"
+	Element="PrimaryAnatomicStructureSequence"	Modifier="Not" ElementPresentAbove=""
+ConditionEnd
+
+Condition="NoAnatomicRegionModifierSequence"
+	Element="AnatomicRegionModifierSequence"	Modifier="Not" ElementPresentWithin="AnatomicRegionSequence"
+ConditionEnd
+
+# for softcopy presentation state ...
+
+Condition="NeedModuleSoftcopyVOILUT"
+	Element="SoftcopyVOILUTSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="RequireTextObjectSequence"
+	Element="TextObjectSequence"		ElementPresent=""
+	Element="GraphicObjectSequence"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="RequireGraphicObjectSequence"
+	Element="GraphicObjectSequence"		ElementPresent=""
+	Element="TextObjectSequence"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="BoundingBoxTopLeftHandCornerPresent"
+	Element="BoundingBoxTopLeftHandCorner"		ElementPresent=""
+ConditionEnd
+
+Condition="BoundingBoxTopLeftHandCornerOrBottomRightHandCornerPresent"
+	Element="BoundingBoxTopLeftHandCorner"		ElementPresent=""
+	Element="BoundingBoxBottomRightHandCorner"		ElementPresent=""
+ConditionEnd
+
+Condition="BoundingBoxTopLeftHandCornerOrBottomRightHandCornerNotPresent"
+	Element="BoundingBoxTopLeftHandCorner"		Modifier="Not" ElementPresent=""
+	Element="BoundingBoxBottomRightHandCorner"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnchorPointNeeded"
+	Element="BoundingBoxTopLeftHandCorner"		Modifier="Not" ElementPresent=""
+	Element="BoundingBoxBottomRightHandCorner"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnchorPointPresent"
+	Element="AnchorPoint"			ElementPresent=""
+ConditionEnd
+
+Condition="AnchorPointNotPresent"
+	Element="AnchorPoint"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="BoundingBoxNeeded"
+	Element="BoundingBoxTopLeftHandCorner"		ElementPresent=""
+	Element="BoundingBoxBottomRightHandCorner"		ElementPresent=""
+	Element="AnchorPoint"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="PresentationLUTShapeNotPresent"
+	Element="PresentationLUTShape"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="PresentationLUTSequenceNotPresent"
+	Element="PresentationLUTSequence"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="DisplayOrBitmapDisplayShutterModulePresent"
+	Element="ShutterShape"					ElementPresent=""
+	Element="ShutterLeftVerticalEdge"		ElementPresent=""
+	Element="ShutterRightVerticalEdge"		ElementPresent=""
+	Element="ShutterUpperHorizontalEdge"	ElementPresent=""
+	Element="ShutterLowerHorizontalEdge"	ElementPresent=""
+	Element="CenterOfCircularShutter"		ElementPresent=""
+	Element="RadiusOfCircularShutter"		ElementPresent=""
+	Element="VerticesOfThePolygonalShutter"	ElementPresent=""
+	Element="ShutterPresentationValue"		ElementPresent=""
+	Element="ShutterOverlayGroup"			ElementPresent=""
+ConditionEnd
+
+# would like to detect ShutterOverlayGroup as well, but cannot do boolean expression :(
+Condition="DisplayOrBitmapDisplayShutterModulePresentAndNotGrayscaleSoftcopyPresentationState"
+	Element="SOPClassUID"					Modifier="Not" StringConstantFromRootAttribute="GrayscaleSoftcopyPresentationStateStorageSOPClassUID"
+	Element="ShutterShape"					Operator="And"	ElementPresent=""
+ConditionEnd
+
+Condition="MaskModulePresent"
+	Element="MaskSubtractionSequence"	ElementPresent=""
+	Element="RecommendedViewingMode"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleBitmapDisplayShutter"
+	Element="ShutterShape"			StringValue="BITMAP"
+ConditionEnd
+
+Condition="NeedModuleOverlayActivation"
+	Element="OverlayActivationLayer"	ElementPresent=""
+	Element="CurveActivationLayer"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleGraphicAnnotation"
+	Element="GraphicAnnotationSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleSpatialTransformation"
+	Element="ImageRotation"			ElementPresent=""
+	Element="ImageHorizontalFlip"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleGraphicLayer"
+	Element="GraphicLayerSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="ImageTypeValue3StereoLOrR"
+	Element="ImageType"		ValueSelector="2"	StringValue="STEREO L"
+	Element="ImageType"		ValueSelector="2"	StringValue="STEREO R"
+ConditionEnd
+
+Condition="RequirePresentationPixelSpacing"
+	Element="PresentationSizeMode"		StringValue="TRUE SIZE"
+	Element="PresentationPixelAspectRatio"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="RequirePresentationPixelAspectRatio"
+	Element="PresentationPixelSpacing"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="RequirePresentationPixelMagnificationRatio"
+	Element="PresentationSizeMode"		StringValue="MAGNIFY"
+ConditionEnd
+
+# for structured reporting ...
+
+Condition="VerificationFlagIsVerified"
+	Element="VerificationFlag"		StringValue="VERIFIED"
+ConditionEnd
+
+Condition="VerificationFlagIsVerifiedAndCompletionFlagIsNotComplete"
+	Element="CompletionFlag"		Modifier="Not" StringValue="COMPLETE"
+	Element="VerificationFlag"		Operator="And" StringValue="VERIFIED"
+ConditionEnd
+
+Condition="TemplateExtensionFlagIsY"
+	Element="TemplateExtensionFlag"		StringValue="Y"
+ConditionEnd
+
+Condition="ValueTypeIsText"
+	Element="ValueType"			StringValue="TEXT"
+ConditionEnd
+
+Condition="ValueTypeIsNum"
+	Element="ValueType"			StringValue="NUM"
+ConditionEnd
+
+Condition="ValueTypeIsNumeric"
+	Element="ValueType"			StringValue="NUMERIC"
+ConditionEnd
+
+Condition="ValueTypeIsCode"
+	Element="ValueType"			StringValue="CODE"
+ConditionEnd
+
+Condition="ValueTypeIsDateTime"
+	Element="ValueType"			StringValue="DATETIME"
+ConditionEnd
+
+Condition="ValueTypeIsDate"
+	Element="ValueType"			StringValue="DATE"
+ConditionEnd
+
+Condition="ValueTypeIsTime"
+	Element="ValueType"			StringValue="TIME"
+ConditionEnd
+
+Condition="ValueTypeIsPersonName"
+	Element="ValueType"			StringValue="PNAME"
+ConditionEnd
+
+Condition="ValueTypeIsUID"
+	Element="ValueType"			StringValue="UIDREF"
+ConditionEnd
+
+Condition="NeedConceptName"
+	Element="ValueType"			StringValue="TEXT"
+	Element="ValueType"			StringValue="NUM"
+	Element="ValueType"			StringValue="CODE"
+	Element="ValueType"			StringValue="DATETIME"
+	Element="ValueType"			StringValue="DATE"
+	Element="ValueType"			StringValue="TIME"
+	Element="ValueType"			StringValue="PNAME"
+	Element="ValueType"			StringValue="UIDREF"
+#	Element="ValueType"			StringValue="CONTAINER"		# not quite right ... "and a heading is present, or this is the Root Content Item"
+#	Element="ValueType"			StringValue="COMPOSITE"		# not quite right ... "and the Purpose of Reference is conveyed in the Concept Name" 
+#	Element="ValueType"			StringValue="IMAGE"			# not quite right ... "and the Purpose of Reference is conveyed in the Concept Name"
+#	Element="ValueType"			StringValue="WAVEFORM"		# not quite right ... "and the Purpose of Reference is conveyed in the Concept Name"
+#	Element="ValueType"			StringValue="SCOORD"		# not quite right ... "and the Purpose of Reference is conveyed in the Concept Name"
+#	Element="ValueType"			StringValue="TCOORD"		# not quite right ... "and the Purpose of Reference is conveyed in the Concept Name"
+ConditionEnd
+
+Condition="ValueTypeIsTextOrNumericOrCodeOrDateTimeOrDateOrTimeOrPersonNameOrUIDOrContainer"
+	Element="ValueType"			StringValue="TEXT"
+	Element="ValueType"			StringValue="NUM"
+	Element="ValueType"			StringValue="CODE"
+	Element="ValueType"			StringValue="DATETIME"
+	Element="ValueType"			StringValue="DATE"
+	Element="ValueType"			StringValue="TIME"
+	Element="ValueType"			StringValue="PNAME"
+	Element="ValueType"			StringValue="UIDREF"
+	Element="ValueType"			StringValue="CONTAINER"
+ConditionEnd
+
+Condition="ValueTypeIsImage"
+	Element="ValueType"			StringValue="IMAGE"
+ConditionEnd
+
+Condition="ValueTypeIsWaveform"
+	Element="ValueType"			StringValue="WAVEFORM"
+ConditionEnd
+
+Condition="ValueTypeIsComposite"
+	Element="ValueType"			StringValue="COMPOSITE"
+ConditionEnd
+
+Condition="ValueTypeIsCompositeOrImage"
+	Element="ValueType"			StringValue="COMPOSITE"
+	Element="ValueType"			StringValue="IMAGE"
+ConditionEnd
+
+Condition="ValueTypeIsCompositeOrImageOrWaveform"
+	Element="ValueType"			StringValue="COMPOSITE"
+	Element="ValueType"			StringValue="IMAGE"
+	Element="ValueType"			StringValue="WAVEFORM"
+ConditionEnd
+
+Condition="ValueTypeIsSpatialCoordinates"
+	Element="ValueType"			StringValue="SCOORD"
+ConditionEnd
+
+Condition="ValueTypeIsSpatialCoordinates3D"
+	Element="ValueType"			StringValue="SCOORD3D"
+ConditionEnd
+
+Condition="ValueTypeIsTemporalCoordinates"
+	Element="ValueType"			StringValue="TCOORD"
+ConditionEnd
+
+Condition="NoReferencedDateTimeOrReferencedTimeOffsets"
+	Element="ReferencedDateTime"						Modifier="Not" ElementPresent=""
+	Element="ReferencedTimeOffsets"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NoReferencedDateTimeOrReferencedSamplePositions"
+	Element="ReferencedSamplePositions"					Modifier="Not" ElementPresent=""
+	Element="ReferencedDateTime"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NoReferencedTimeOffsetsOrReferencedSamplePositions"
+	Element="ReferencedSamplePositions"					Modifier="Not" ElementPresent=""
+	Element="ReferencedTimeOffsets"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ValueTypeIsContainer"
+	Element="ValueType"			StringValue="CONTAINER"
+ConditionEnd
+
+Condition="RelationshipByReference"
+	Element="ValueType"				Modifier="Not" ElementPresent=""
+	Element="ReferencedContentItemIdentifier"	Operator="And" ElementPresent=""
+	Element="RelationshipType"			Operator="And" Modifier="Not" StringValue="CONTAINS"
+ConditionEnd
+
+Condition="RelationshipByValue"
+	Element="ValueType"				ElementPresent=""
+	Element="ReferencedContentItemIdentifier"	Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+# Waveform
+
+Condition="NeedModuleWaveformAnnotation"
+	Element="WaveformAnnotationSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="ReallyNeedModuleSynchronization"
+	Element="WaveformOriginality"			StringValue="ORIGINAL"
+	Element="SynchronizationFrameOfReferenceUID"	ElementPresent=""
+	Element="SynchronizationTrigger"		ElementPresent=""
+	Element="TriggerSourceOrType"			ElementPresent=""
+	Element="SynchronizationChannel"		ElementPresent=""
+	Element="AcquisitionTimeSynchronized"		ElementPresent=""
+	Element="TimeSource"				ElementPresent=""
+	Element="TimeDistributionProtocol"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleSynchronizationForIVUS"
+	Element="Modality"								StringValue="IVUS"
+	Element="SynchronizationFrameOfReferenceUID"	ElementPresent=""
+	Element="SynchronizationTrigger"				ElementPresent=""
+	Element="TriggerSourceOrType"					ElementPresent=""
+	Element="SynchronizationChannel"				ElementPresent=""
+	Element="AcquisitionTimeSynchronized"			ElementPresent=""
+	Element="TimeSource"							ElementPresent=""
+	Element="TimeDistributionProtocol"				ElementPresent=""
+ConditionEnd
+
+Condition="NeedToCheckModuleSynchronization"
+	Element="SynchronizationFrameOfReferenceUID"	ElementPresent=""
+	Element="SynchronizationTrigger"		ElementPresent=""
+	Element="TriggerSourceOrType"			ElementPresent=""
+	Element="SynchronizationChannel"		ElementPresent=""
+	Element="AcquisitionTimeSynchronized"		ElementPresent=""
+	Element="TimeSource"				ElementPresent=""
+	Element="TimeDistributionProtocol"		ElementPresent=""
+ConditionEnd
+
+Condition="AcquisitionTimeSynchronizedIsY"
+	Element="AcquisitionTimeSynchronized"		StringValue="Y"
+ConditionEnd
+
+Condition="ChannelSensitivityIsPresent"
+	Element="ChannelSensitivity"			ElementPresent=""
+ConditionEnd
+
+Condition="ChannelSampleSkewNotPresent"
+	Element="ChannelSampleSkew"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ChannelTimeSkewNotPresent"
+	Element="ChannelTimeSkew"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnnotationNeedsReferencedSamplePositions"
+	Element="TemporalRangeType"		ElementPresent=""
+	Element="ReferencedTimeOffsets"		Operator="And" Modifier="Not" ElementPresent=""
+	Element="ReferencedDateTime"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnnotationNeedsReferencedTimeOffsets"
+	Element="TemporalRangeType"		ElementPresent=""
+	Element="ReferencedSamplePositions"	Operator="And" Modifier="Not" ElementPresent=""
+	Element="ReferencedDateTime"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnnotationNeedsReferencedDateTime"
+	Element="TemporalRangeType"		ElementPresent=""
+	Element="ReferencedSamplePositions"	Operator="And" Modifier="Not" ElementPresent=""
+	Element="ReferencedTimeOffsets"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+# for new SC objects ...
+
+# Check that FrameIncrementPointer equals FrameTime or FrameTimeVector
+#
+Condition="NeedModuleCineForSC"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x1063"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x1065"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsPageNumberVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x2001"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsFrameLabelVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x2002"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsFramePrimaryAngleVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x2003"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsFrameSecondaryAngleVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x2004"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsSliceLocationVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x2005"
+ConditionEnd
+
+Condition="FrameIncrementPointerContainsDisplayWindowLabelVector"
+	Element="FrameIncrementPointer"		ValueSelector="*"	TagValue="0x0018,0x2006"
+ConditionEnd
+
+Condition="MonochromeNotBitmapPhotometricInterpretation"
+	Element="PhotometricInterpretation"	StringValue="MONOCHROME2"
+	Element="BitsStored"			Operator="And" BinaryValue="> 1"
+ConditionEnd
+
+Condition="ConversionTypeDigitizedFilm"
+	Element="ConversionType"		StringValue="DF"
+ConditionEnd
+
+Condition="NotSCMultiFrameOrNumberOfFramesGreaterThanOne"
+	Element="SOPClassUID"			               Modifier="Not" StringValue="1.2.840.10008.5.1.4.1.1.7.1"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringValue="1.2.840.10008.5.1.4.1.1.7.2"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringValue="1.2.840.10008.5.1.4.1.1.7.3"
+	Element="SOPClassUID"			Operator="And" Modifier="Not" StringValue="1.2.840.10008.5.1.4.1.1.7.4"
+	Element="NumberOfFrames"		Operator="Or"  BinaryValue="> 1"
+ConditionEnd
+
+Condition="ModalityIsIVUS"
+	Element="Modality"			StringValue="IVUS"
+ConditionEnd
+
+Condition="IVUSAcquisitionIsMotor"
+	Element="IVUSAcquisition"		StringValue="MOTOR_PULLBACK"
+ConditionEnd
+
+Condition="IVUSAcquisitionIsGated"
+	Element="IVUSAcquisition"		StringValue="GATED_PULLBACK"
+ConditionEnd
+
+Condition="IVUSAcquisitionIsMotorOrGated"
+	Element="IVUSAcquisition"		StringValue="MOTOR_PULLBACK"
+	Element="IVUSAcquisition"		Operator="Or"  StringValue="GATED_PULLBACK"
+ConditionEnd
+
+Condition="CertifiedTimestampIsPresent"
+	Element="CertifiedTimestamp"		ElementPresent=""
+ConditionEnd
+
+# for new MR objects ...
+
+Condition="NeedModuleMRPulseSequence"
+	Element="PulseSequenceName"				ElementPresent=""
+	Element="MRAcquisitionType"				Operator="Or" ElementPresent=""
+	# could add all the other attributes of the module
+	# the following is the condition from the IOD table ...
+	Element="ImageType"					Operator="Or" ValueSelector="0" StringValue="ORIGINAL"
+ConditionEnd
+
+Condition="NeedModuleMRSpectroscopyPulseSequence"
+	Element="PulseSequenceName"				ElementPresent=""
+	Element="MRSpectroscopyAcquisitionType"			Operator="Or" ElementPresent=""
+	# could add all the other attributes of the module
+	# the following is the condition from the IOD table ...
+	Element="ImageType"					Operator="Or" ValueSelector="0" StringValue="ORIGINAL"
+ConditionEnd
+
+Condition="NeedModuleCardiacSynchronization"
+	Element="CardiacSynchronizationTechnique"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleRespiratorySynchronization"
+	Element="RespiratoryMotionCompensationTechnique"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleBulkMotion"
+	Element="BulkMotionCompensationTechnique"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleSupplementalPaletteColorLUT"
+	Element="PixelPresentation"				StringValue="COLOR"
+	Element="PixelPresentation"				Operator="Or" StringValue="MIXED"
+ConditionEnd
+
+Condition="StackIDIsPresent"
+	Element="StackID"					ElementPresent=""
+ConditionEnd
+
+Condition="RealWorldValueLUTDataNotPresent"
+	Element="RealWorldValueLUTData"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="RealWorldValueInterceptNotPresent"
+	Element="RealWorldValueIntercept"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="CardiacSynchronizationTechniqueNotNoneAndOriginalOrMixed"
+	Element="ImageType"								ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CardiacSynchronizationTechnique"		Operator="And" ElementPresent=""
+	Element="CardiacSynchronizationTechnique"		Operator="And" Modifier="Not" StringValue="NONE"
+ConditionEnd
+
+Condition="CardiacSynchronizationTechniqueProspectiveOrRetrospective"
+	Element="CardiacSynchronizationTechnique"		StringValue="PROSPECTIVE"
+	Element="CardiacSynchronizationTechnique"		Operator="Or" StringValue="RETROSPECTIVE"
+ConditionEnd
+
+Condition="RespiratoryMotionCompensationTechniqueNotNone"
+	Element="RespiratoryMotionCompensationTechnique"	ElementPresent=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValue="NONE"
+ConditionEnd
+
+Condition="RespiratoryMotionCompensationTechniqueNotNoneOrRealTimeOrBreathHoldAndOriginalOrMixed"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" ElementPresent=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValue="NONE"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValue="BREATH_HOLD"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValue="REALTIME"
+ConditionEnd
+
+Condition="BulkMotionCompensationTechniqueNotNoneAndOriginalOrMixed"
+	Element="ImageType"								ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="BulkMotionCompensationTechnique"		Operator="And" ElementPresent=""
+	Element="BulkMotionCompensationTechnique"		Operator="And" Modifier="Not" StringValue="NONE"
+ConditionEnd
+
+Condition="ImageTypeValue1Original"
+	Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+ConditionEnd
+
+Condition="ImageTypeValue1Derived"
+	Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="DERIVED"
+ConditionEnd
+
+Condition="ImageTypeValue1NotDerived"
+	Element="ImageType"		Modifier="Not"	ValueSelector="0"	StringValueFromRootAttribute="DERIVED"
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixed"
+	Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="MIXED"
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedMR"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="LegacyConvertedEnhancedMRImageStorageSOPClassUID"
+	(
+		Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+		Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="MIXED"
+	) Operator="And"
+}
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedCT"
+	Element="SOPClassUID"		Modifier="Not" StringConstantFromRootAttribute="LegacyConvertedEnhancedCTImageStorageSOPClassUID"
+	(
+		Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+		Element="ImageType"		ValueSelector="0"	StringValueFromRootAttribute="MIXED"
+	) Operator="And"
+}
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalAndNotLegacyConvertedPET"
+	Element="ImageType"			ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="SOPClassUID"		Operator="And"	Modifier="Not" StringConstantFromRootAttribute="LegacyConvertedEnhancedPETImageStorageSOPClassUID"
+}
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixedAndRectilinear"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="GeometryOfKSpaceTraversal"	Operator="And"	StringValueFromRootAttribute="RECTILINEAR"
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixedAnd3D"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRAcquisitionType"	Operator="And"	StringValueFromRootAttribute="3D"
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixedAndSpectroscopyVolume"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRSpectroscopyAcquisitionType"	Operator="And"	StringValueFromRootAttribute="VOLUME"
+ConditionEnd
+
+Condition="ImageTypeValue1OriginalOrMixedAndEchoPulseSequenceNotGradient"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="EchoPulseSequence"	Operator="And"	Modifier="Not"	StringValueFromRootAttribute="GRADIENT"
+ConditionEnd
+
+Condition="ImageTypeValue3ASL"
+	Element="ImageType"		ValueSelector="2"	StringValueFromRootAttribute="ASL"
+ConditionEnd
+
+Condition="ConcatenationUIDIsPresent"
+	Element="ConcatenationUID"				ElementPresent=""
+ConditionEnd
+
+Condition="ReferencedImageSequenceIsPresent"
+	Element="ReferencedImageSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="ReferencedImageSequenceIsPresentInFunctionalGroups"
+	Element="ReferencedImageSequence"					ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ReferencedImageSequence"	Operator="Or"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="SourceImageSequenceIsPresent"
+	Element="SourceImageSequence"				ElementPresent=""
+ConditionEnd
+
+Condition="SourceImageSequenceIsPresentInFunctionalGroups"
+	Element="SourceImageSequence"						ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="SourceImageSequence"		Operator="Or"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ImageTypeNotPresent"
+	Element="ImageType"					Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FrameTypeNotPresent"
+	Element="FrameType"					Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="GradientOutputIsPresent"
+	Element="GradientOutput"				ElementPresent=""
+ConditionEnd
+
+Condition="GradientOutputTypeIsPresent"
+	Element="GradientOutputType"				ElementPresent=""
+ConditionEnd
+
+Condition="InversionRecoveryIsYes"
+	Element="InversionRecovery"				StringValue="YES"
+ConditionEnd
+
+Condition="FlowCompensationNotNone"
+	Element="FlowCompensation"				Modifier="Not" StringValue="NONE"
+ConditionEnd
+
+Condition="EchoPulseSequenceGradientOrBoth"
+	Element="EchoPulseSequence"				StringValueFromRootAttribute="GRADIENT"
+	Element="EchoPulseSequence"				Operator="Or" StringValueFromRootAttribute="BOTH"
+ConditionEnd
+
+Condition="PartialFourierIsYes"
+	Element="PartialFourier"				StringValue="YES"
+ConditionEnd
+
+Condition="ParallelAcquisitionIsYes"
+	Element="ParallelAcquisition"				StringValue="YES"
+ConditionEnd
+
+Condition="TaggingIsGridOrLine"
+	Element="Tagging"					StringValue="GRID"
+	Element="Tagging"					StringValue="LINE"
+ConditionEnd
+
+Condition="TaggingIsGrid"
+	Element="Tagging"					StringValue="GRID"
+ConditionEnd
+
+Condition="ReceiveCoilTypeIsMultiCoil"
+	Element="ReceiveCoilType"				StringValue="MULTICOIL"
+ConditionEnd
+
+Condition="DiffusionDirectionalityIsDirectional"
+	Element="DiffusionDirectionality"			StringValue="DIRECTIONAL"
+ConditionEnd
+
+Condition="DiffusionDirectionalityIsBMatrix"
+	Element="DiffusionDirectionality"			StringValue="BMATRIX"
+ConditionEnd
+
+# really should check FrameType[3] == DIFFUSION_ANISO for current frame :(
+Condition="NeedDiffusionAnisotropyType"
+	Element="ImageType"							ValueSelector="3"  StringValueFromRootAttribute="DIFFUSION_ANISO"
+ConditionEnd
+
+Condition="DerivationImageFunctionalGroupPresent"
+	Element="DerivationImageSequence"			ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="DerivationImageSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="DerivationImageFunctionalGroupNotPresent"
+	Element="DerivationImageSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="DerivationImageSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="DerivationImageFunctionalGroupNotPresentOrFrameOfReferenceUIDPresent"
+	Element="DerivationImageSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="DerivationImageSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameOfReferenceUID"				Operator="Or" ElementPresent=""
+ConditionEnd
+
+Condition="RadiopharmaceuticalUsageSequenceNotInSharedFunctionalGroupSequence"
+	Element="RadiopharmaceuticalUsageSequence"	Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RadiopharmaceuticalUsageSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="RadiopharmaceuticalUsageSequence"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="SegmentIdentificationSequenceNotInSharedFunctionalGroupSequence"
+	Element="SegmentIdentificationSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="SegmentIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="SegmentIdentificationSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelMeasuresOrPlanePositionOrPlaneOrientationSequenceIsPresent"
+	Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+	Element="PixelMeasuresSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+	Element="PixelMeasuresSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="PixelMeasuresSequence"				ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		(
+			Element="DerivationImageSequence"					  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="DerivationImageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequenceAndPlanePositionSequenceOrPlaneOrientationSequencePresent"
+	Element="PixelMeasuresSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="PlanePositionSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	) Operator="And"
+ConditionEnd
+
+
+Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="PixelMeasuresSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+	Element="PixelMeasuresSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="PixelMeasuresSequence"				ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		(
+			Element="DerivationImageSequence"					  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="DerivationImageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequenceAndPlanePositionSequenceOrPlaneOrientationSequencePresent"
+	Element="PixelMeasuresSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="PlanePositionSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	) Operator="And"
+ConditionEnd
+
+
+Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+	Element="PlanePositionSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+	Element="PlanePositionSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="PlanePositionSequence"				ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		(
+			Element="DerivationImageSequence"					  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="DerivationImageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlaneOrientationSequencePresent"
+	Element="PlanePositionSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	) Operator="And"
+ConditionEnd
+
+Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="PlanePositionSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+	Element="PlanePositionSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="PlanePositionSequence"				ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		(
+			Element="DerivationImageSequence"					  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="DerivationImageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlaneOrientationSequencePresent"
+	Element="PlanePositionSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlaneOrientationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	) Operator="And"
+ConditionEnd
+
+
+
+Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+	Element="PlaneOrientationSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+	Element="PlaneOrientationSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="PlaneOrientationSequence"				ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		(
+			Element="DerivationImageSequence"					  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="DerivationImageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlanePositionSequencePresent"
+	Element="PlaneOrientationSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	) Operator="And"
+ConditionEnd
+
+Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="PlaneOrientationSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+	Element="PlaneOrientationSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="PlaneOrientationSequence"				ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		(
+			Element="DerivationImageSequence"					  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="DerivationImageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlanePositionSequencePresent"
+	Element="PlaneOrientationSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	) Operator="And"
+ConditionEnd
+
+Condition="DerivationImageSequenceNotInSharedFunctionalGroupSequenceAndPixelMeasuresPlanePositionPlaneOrientationNotPresentInEitherMBPO"
+	Element="DerivationImageSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="DerivationImageSequence"				ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		(
+			Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+			Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+Condition="DerivationImageSequenceNotInPerFrameFunctionalGroupSequenceAndPixelMeasuresPlanePositionPlaneOrientationNotPresentInEitherMBPO"
+	Element="DerivationImageSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="DerivationImageSequence"				ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		(
+			Element="PixelMeasuresSequence"						  ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="PixelMeasuresSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+			Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+			Element="PlanePositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		) Operator="Or" Modifier="Not"
+	) Operator="And"
+ConditionEnd
+
+
+Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+	Element="FrameAnatomySequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameAnatomySequence"				Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+	Element="FrameAnatomySequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+	Element="FrameAnatomySequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameAnatomySequence"				Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+	Element="FrameAnatomySequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+	Element="PixelValueTransformationSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+	Element="PixelValueTransformationSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PhotometricInterpretation"				Operator="And" StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="PixelValueTransformationSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+	Element="PixelValueTransformationSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PhotometricInterpretation"				Operator="And" StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="MRImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="MRImageFrameTypeSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="MRImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="MRImageFrameTypeSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="MRSpectroscopyFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="MRSpectroscopyFrameTypeSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="MRSpectroscopyFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="MRSpectroscopyFrameTypeSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PETFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="PETFrameTypeSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PETFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="PETFrameTypeSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+# more specific conditions for particular macros that have to also be only in one or the other functional groups sequences ...
+
+Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CardiacSynchronizationTechnique"			Operator="And" ElementPresentInRoot=""
+	Element="CardiacSynchronizationTechnique"			Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="CardiacSynchronizationSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CardiacSynchronizationTechnique"			Operator="And" ElementPresentInRoot=""
+	Element="CardiacSynchronizationTechnique"			Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="CardiacSynchronizationSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequenceRegardlessOfImageType"
+	Element="CardiacSynchronizationTechnique"			ElementPresentInRoot=""
+	Element="CardiacSynchronizationTechnique"			Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="CardiacSynchronizationSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequenceRegardlessOfImageType"
+	Element="CardiacSynchronizationTechnique"			ElementPresentInRoot=""
+	Element="CardiacSynchronizationTechnique"			Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="CardiacSynchronizationSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" ElementPresentInRoot=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="REALTIME"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="BREATH_HOLD"
+	Element="RespiratorySynchronizationSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" ElementPresentInRoot=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="REALTIME"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="BREATH_HOLD"
+	Element="RespiratorySynchronizationSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequenceRegardlessOfImageType"
+	Element="RespiratoryMotionCompensationTechnique"	ElementPresentInRoot=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="REALTIME"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="BREATH_HOLD"
+	Element="RespiratorySynchronizationSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequenceRegardlessOfImageType"
+	Element="RespiratoryMotionCompensationTechnique"	ElementPresentInRoot=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="REALTIME"
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" Modifier="Not" StringValueFromRootAttribute="BREATH_HOLD"
+	Element="RespiratorySynchronizationSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="NeedPatientPhysiologicalStateMacroInSharedFunctionalGroupSequence"
+	Element="PatientPhysiologicalStateSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="ImageType"									ValueSelector="2" StringValueFromRootAttribute="REST"
+		Element="ImageType"									Operator="Or" ValueSelector="2" StringValueFromRootAttribute="STRESS"
+	) Operator="And"
+	Element="PatientPhysiologicalStateSequence"				Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPatientPhysiologicalStateMacroInPerFrameFunctionalGroupSequence"
+	Element="PatientPhysiologicalStateSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="ImageType"									ValueSelector="2" StringValueFromRootAttribute="REST"
+		Element="ImageType"									Operator="Or" ValueSelector="2" StringValueFromRootAttribute="STRESS"
+	) Operator="And"
+	Element="PatientPhysiologicalStateSequence"				Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRTimingAndRelatedParametersMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRTimingAndRelatedParametersSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRTimingAndRelatedParametersSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRTimingAndRelatedParametersMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRTimingAndRelatedParametersSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRTimingAndRelatedParametersSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRFOVGeometryMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="GeometryOfKSpaceTraversal"		Operator="And" StringValueFromRootAttribute="RECTILINEAR"
+	Element="MRFOVGeometrySequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRFOVGeometrySequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRFOVGeometryMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="GeometryOfKSpaceTraversal"		Operator="And" StringValueFromRootAttribute="RECTILINEAR"
+	Element="MRFOVGeometrySequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRFOVGeometrySequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRSpectroscopyFOVGeometryMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="GeometryOfKSpaceTraversal"		Operator="And" StringValueFromRootAttribute="RECTILINEAR"
+	Element="MRSpectroscopyFOVGeometrySequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRSpectroscopyFOVGeometrySequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRSpectroscopyFOVGeometryMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="GeometryOfKSpaceTraversal"		Operator="And" StringValueFromRootAttribute="RECTILINEAR"
+	Element="MRSpectroscopyFOVGeometrySequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRSpectroscopyFOVGeometrySequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMREchoMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MREchoSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MREchoSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMREchoMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MREchoSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MREchoSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRModifierMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRModifierSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRModifierSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRModifierMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRModifierSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRModifierSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRImagingModifierMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRImagingModifierSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRImagingModifierSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRImagingModifierMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRImagingModifierSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRImagingModifierSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRReceiveCoilMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRReceiveCoilSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRReceiveCoilSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRReceiveCoilMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRReceiveCoilSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRReceiveCoilSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRTransmitCoilMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRTransmitCoilSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRTransmitCoilSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRTransmitCoilMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRTransmitCoilSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRTransmitCoilSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRDiffusionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="AcquisitionContrast"			Operator="And" StringValueFromRootAttribute="DIFFUSION"
+	Element="MRDiffusionSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRDiffusionSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRDiffusionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="AcquisitionContrast"			Operator="And" StringValueFromRootAttribute="DIFFUSION"
+	Element="MRDiffusionSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRDiffusionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRSpatialSaturationMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="SpatialPresaturation"					Operator="And" StringValueFromRootAttribute="SLAB"
+	Element="MRSpatialSaturationSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRSpatialSaturationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRSpatialSaturationMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="SpatialPresaturation"					Operator="And" StringValueFromRootAttribute="SLAB"
+	Element="MRSpatialSaturationSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRSpatialSaturationSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRAveragesMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRAveragesSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRAveragesSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRAveragesMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="MRAveragesSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRAveragesSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRMetaboliteMapMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"					       ValueSelector="2" StringValueFromRootAttribute="METABOLITE_MAP"
+	Element="MRMetaboliteMapSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRMetaboliteMapSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRMetaboliteMapMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"					       ValueSelector="2" StringValueFromRootAttribute="METABOLITE_MAP"
+	Element="MRMetaboliteMapSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRMetaboliteMapSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRVelocityEncodingMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="PhaseContrast"				Operator="And" StringValueFromRootAttribute="YES"
+	Element="MRVelocityEncodingSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRVelocityEncodingSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRVelocityEncodingMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="PhaseContrast"				Operator="And" StringValueFromRootAttribute="YES"
+	Element="MRVelocityEncodingSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRVelocityEncodingSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRArterialSpinLabelingMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="2" StringValueFromRootAttribute="ASL"
+	Element="MRArterialSpinLabelingSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="MRArterialSpinLabelingSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedMRArterialSpinLabelingMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="2" StringValueFromRootAttribute="ASL"
+	Element="MRArterialSpinLabelingSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="MRArterialSpinLabelingSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PhaseContrastIsYes"
+	Element="PhaseContrast"				StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="NeedPETFrameAcquisitionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETFrameAcquisitionSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PETFrameAcquisitionSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETFrameAcquisitionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETFrameAcquisitionSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PETFrameAcquisitionSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETDetectorMotionDetailsMacroInSharedFunctionalGroupSequence"
+	Element="PETDetectorMotionDetailsSequence"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="ImageType"						ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+		Element="TypeOfDetectorMotion"			Operator="And" Modifier="Not" StringValueFromRootAttribute="STATIONARY"
+	) Operator="And"
+	Element="PETDetectorMotionDetailsSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETDetectorMotionDetailsMacroInPerFrameFunctionalGroupSequence"
+	Element="PETDetectorMotionDetailsSequence"	Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="ImageType"						ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+		Element="TypeOfDetectorMotion"			Operator="And" Modifier="Not" StringValueFromRootAttribute="STATIONARY"
+	) Operator="And"
+	Element="PETDetectorMotionDetailsSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETPositionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETPositionSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PETPositionSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETPositionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETPositionSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PETPositionSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETFrameCorrectionFactorsMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETFrameCorrectionFactorsSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PETFrameCorrectionFactorsSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETFrameCorrectionFactorsMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETFrameCorrectionFactorsSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PETFrameCorrectionFactorsSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETReconstructionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETReconstructionSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PETReconstructionSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETReconstructionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+	Element="PETReconstructionSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PETReconstructionSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETTableDynamicsMacroInSharedFunctionalGroupSequence"
+	Element="PETTableDynamicsSequence"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="ImageType"				ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+		Element="TableMotion"			Operator="And" StringValueFromRootAttribute="DYNAMIC"
+	) Operator="And"
+	Element="PETTableDynamicsSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPETTableDynamicsMacroInPerFrameFunctionalGroupSequence"
+	Element="PETTableDynamicsSequence"	Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="ImageType"				ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+		Element="TableMotion"			Operator="And" StringValueFromRootAttribute="DYNAMIC"
+	) Operator="And"
+	Element="PETTableDynamicsSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="LossyImageCompressionIs01"
+	Element="LossyImageCompression"			StringValue="01"
+ConditionEnd
+
+Condition="VolumeLocalizationTechniqueNotNone"
+	Element="VolumeLocalizationTechnique"		Modifier="Not"	StringValue="NONE"
+ConditionEnd
+
+Condition="DecouplingIsYes"
+	Element="Decoupling"				StringValue="YES"
+ConditionEnd
+
+Condition="DataPointRowsGreaterThanOne"
+	Element="DataPointRows"				BinaryValue="> 1"
+ConditionEnd
+
+Condition="FirstOrderPhaseCorrectionIsYes"
+	Element="FirstOrderPhaseCorrection"				StringValue="YES"
+ConditionEnd
+
+Condition="ClinicalTrialSubjectReadingIDAbsent"
+	Element="ClinicalTrialSubjectReadingID"		Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="ClinicalTrialSubjectIDAbsent"
+	Element="ClinicalTrialSubjectID"		Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleClinicalTrialSubject"
+	Element="ClinicalTrialSponsorName"		ElementPresent=""
+	Element="ClinicalTrialProtocolID"		ElementPresent=""
+	Element="ClinicalTrialProtocolName"		ElementPresent=""
+	Element="ClinicalTrialSiteID"			ElementPresent=""
+	Element="ClinicalTrialSiteName"			ElementPresent=""
+	Element="ClinicalTrialSubjectID"		ElementPresent=""
+	Element="ClinicalTrialSubjectReadingID"	ElementPresent=""
+	Element="ClinicalTrialProtocolEthicsCommitteeName"	ElementPresent=""
+	Element="ClinicalTrialProtocolEthicsCommitteeApprovalNumber"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleClinicalTrialStudy"
+	Element="ClinicalTrialTimePointID"		ElementPresent=""
+	Element="ClinicalTrialTimePointDescription"	ElementPresent=""
+	Element="ConsentForClinicalTrialUseSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleClinicalTrialSeries"
+	Element="ClinicalTrialCoordinatingCenterName"	ElementPresent=""
+	Element="ClinicalTrialSeriesID"					ElementPresent=""
+	Element="ClinicalTrialSeriesDescription"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleEnhancedContrastBolus"
+	Element="ContrastBolusAgentSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleMultiFrameDimension"
+	Element="DimensionOrganizationSequence"		ElementPresent=""
+	Element="DimensionIndexSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+	Element="SharedFunctionalGroupsSequence"	ElementPresent=""
+	Element="PerFrameFunctionalGroupsSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+	Element="ContrastBolusAgentSequence"		ElementPresentInRoot=""
+	Element="ContrastBolusUsageSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ContrastBolusUsageSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+	Element="ContrastBolusAgentSequence"		ElementPresentInRoot=""
+	Element="ContrastBolusUsageSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ContrastBolusUsageSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ParametricMapFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="ParametricMapFrameTypeSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ParametricMapFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="ParametricMapFrameTypeSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CTImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="CTImageFrameTypeSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CTImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="CTImageFrameTypeSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTAcquisitionTypeMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTAcquisitionTypeSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTAcquisitionTypeSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTAcquisitionTypeMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTAcquisitionTypeSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTAcquisitionTypeSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTAcquisitionDetailsMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTAcquisitionDetailsSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTAcquisitionDetailsSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTAcquisitionDetailsMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTAcquisitionDetailsSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTAcquisitionDetailsSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTTableDynamicsMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTTableDynamicsSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTTableDynamicsSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTTableDynamicsMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTTableDynamicsSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTTableDynamicsSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTPositionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTPositionSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTPositionSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTPositionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTPositionSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTPositionSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTGeometryMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTGeometrySequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTGeometrySequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTGeometryMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTGeometrySequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTGeometrySequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTReconstructionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTReconstructionSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTReconstructionSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTReconstructionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTReconstructionSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTReconstructionSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTExposureMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTExposureSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTExposureSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTExposureMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTExposureSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTExposureSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTXRayDetailsMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="CTXRayDetailsSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTXRayDetailsSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedCTXRayDetailsMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0" Modifier="Not" StringValueFromRootAttribute="DERIVED"
+	Element="AcquisitionType"			Operator="And" Modifier="Not" StringValueFromRootAttribute="CONSTANT_ANGLE"
+	Element="CTXRayDetailsSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTXRayDetailsSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CTAdditionalXRaySourceMacroInSharedFunctionalGroupSequence"
+	Element="CTAdditionalXRaySourceSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CTAdditionalXRaySourceSequence"		Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CTAdditionalXRaySourceMacroInPerFrameFunctionalGroupSequence"
+	Element="CTAdditionalXRaySourceSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CTAdditionalXRaySourceSequence"		Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="AcquisitionTypeConstantAngle"
+	Element="AcquisitionType"			StringValue="CONSTANT_ANGLE"
+ConditionEnd
+
+Condition="AcquisitionTypeNotConstantAngle"
+	Element="AcquisitionType"			Modifier="Not" StringValue="CONSTANT_ANGLE"
+ConditionEnd
+
+Condition="AcquisitionTypeConstantAngleOrSpiral"
+	Element="AcquisitionType"			StringValue="CONSTANT_ANGLE"
+	Element="AcquisitionType"			Operator="Or" StringValue="SPIRAL"
+ConditionEnd
+
+Condition="AcquisitionTypeSpiral"
+	Element="AcquisitionType"			StringValue="SPIRAL"
+ConditionEnd
+
+Condition="ConvolutionKernelIsPresent"
+	Element="ConvolutionKernel"			ElementPresent=""
+ConditionEnd
+
+Condition="ReconstructionFieldOfViewAbsent"
+	Element="ReconstructionFieldOfView"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ReconstructionDiameterAbsent"
+	Element="ReconstructionDiameter"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ExposureModulationTypeIsNotNone"
+	Element="ExposureModulationType"		Modifier="Not" StringValue="NONE"
+ConditionEnd
+
+Condition="MultiFrameIODAndNotSpecimen"
+	Element="NumberOfFrames"			ElementPresent=""
+	Element="SpecimenAccessionNumber"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="VOILUTSequenceLUTDescriptorRequiredToBe8Or16"
+	Element="SOPClassUID"		               Modifier="Not" StringConstantFromRootAttribute="DigitalXRayImageStorageForProcessingSOPClassUID"
+	Element="SOPClassUID"		Operator="And" Modifier="Not" StringConstantFromRootAttribute="DigitalMammographyXRayImageStorageForProcessingSOPClassUID"
+	Element="SOPClassUID"		Operator="And" Modifier="Not" StringConstantFromRootAttribute="DigitalIntraoralXRayImageStorageForProcessingSOPClassUID"
+	Element="SOPClassUID"		Operator="And" Modifier="Not" StringConstantFromRootAttribute="DigitalXRayImageStorageForPresentationSOPClassUID"
+	Element="SOPClassUID"		Operator="And" Modifier="Not" StringConstantFromRootAttribute="DigitalMammographyXRayImageStorageForPresentationSOPClassUID"
+	Element="SOPClassUID"		Operator="And" Modifier="Not" StringConstantFromRootAttribute="DigitalIntraoralXRayImageStorageForPresentationSOPClassUID"
+ConditionEnd
+
+Condition="ReferencedImageSequenceNotPresent"
+	Element="ReferencedImageSequence"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FrameOfReferenceUIDNotPresent"
+	Element="FrameOfReferenceUID"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FiducialIdentifierNotPresent"
+	Element="FiducialIdentifier"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ContourDataIsPresent"
+	Element="ContourData"				ElementPresent=""
+ConditionEnd
+
+Condition="ContourDataNotPresent"
+	Element="ContourData"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FrameOfReferenceUIDIsPresentInParent"
+	Element="FrameOfReferenceUID"			ElementPresentAbove=""
+ConditionEnd
+
+Condition="JPEGTransferSyntaxButNotYBR_FULL_422"
+	Element="TransferSyntaxUID"					StringValue="1.2.840.10008.1.2.4.50"
+	Element="PhotometricInterpretation"			Operator="And"	Modifier="Not" StringValue="YBR_FULL_422"
+ConditionEnd
+
+Condition="JPEG2000LosslessTransferSyntaxButNotYBR_RCT"
+	Element="TransferSyntaxUID"					StringValue="1.2.840.10008.1.2.4.90"
+	Element="PhotometricInterpretation"			Operator="And"	Modifier="Not" StringValue="YBR_RCT"
+ConditionEnd
+
+Condition="JPEG2000TransferSyntaxButNotYBR_RCTorYBR_ICT"
+	Element="TransferSyntaxUID"					StringValue="1.2.840.10008.1.2.4.91"
+	Element="PhotometricInterpretation"			Operator="And"	Modifier="Not" StringValue="YBR_RCT"
+	Element="PhotometricInterpretation"			Operator="And"	Modifier="Not" StringValue="YBR_ICT"
+ConditionEnd
+
+Condition="JPEGLossyTransferSyntaxAndThreeSamples"
+	Element="SamplesPerPixel"						BinaryValue="== 3"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.50"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.51"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.52"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.53"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.54"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.55"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.56"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.59"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.60"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.61"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.62"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.63"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.64"
+	) Operator="And"
+ConditionEnd
+
+Condition="JPEGLosslessTransferSyntaxAndThreeSamples"
+	Element="SamplesPerPixel"						BinaryValue="== 3"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.57"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.58"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.65"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.66"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.70"
+	) Operator="And"
+ConditionEnd
+
+Condition="JPEG2000LosslessTransferSyntaxAndThreeSamples"
+	Element="TransferSyntaxUID"					StringValue="1.2.840.10008.1.2.4.90"
+	Element="SamplesPerPixel"			Operator="And"	BinaryValue="== 3"
+ConditionEnd
+
+Condition="JPEG2000TransferSyntaxAndThreeSamples"
+	Element="SamplesPerPixel"				BinaryValue="== 3"
+	(
+		Element="TransferSyntaxUID"							StringValue="1.2.840.10008.1.2.4.90"
+		Element="TransferSyntaxUID"			Operator="Or"	StringValue="1.2.840.10008.1.2.4.91"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2TransferSyntax"
+	Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+	Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+ConditionEnd
+
+Condition="UncompressedTransferSyntaxAndThreeSamples"
+	Element="SamplesPerPixel"				BinaryValue="== 3"
+	(
+		Element="TransferSyntaxUID"							StringValue="1.2.840.10008.1.2"
+		Element="TransferSyntaxUID"			Operator="Or"	StringValue="1.2.840.10008.1.2.1"
+		Element="TransferSyntaxUID"			Operator="Or"	StringValue="1.2.840.10008.1.2.2"
+	) Operator="And"
+ConditionEnd
+
+Condition="RLETransferSyntaxAndThreeSamples"
+	Element="TransferSyntaxUID"					StringValue="1.2.840.10008.1.2.5"
+	Element="SamplesPerPixel"			Operator="And"	BinaryValue="== 3"
+ConditionEnd
+
+Condition="MPEG2TransferSyntaxAndNotThreeSamples"
+	Element="SamplesPerPixel"		Modifier="Not" BinaryValue="== 3"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2TransferSyntaxAndNotBitsAllocated8"
+	Element="BitsAllocated"		Modifier="Not" BinaryValue="== 8"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2TransferSyntaxAndNotBitsStored8"
+	Element="BitsStored"		Modifier="Not" BinaryValue="== 8"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2TransferSyntaxAndNotHighBit7"
+	Element="HighBit"		Modifier="Not" BinaryValue="== 7"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2TransferSyntaxAndNotPixelRepresentation0"
+	Element="PixelRepresentation"		Modifier="Not" BinaryValue="== 0"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2TransferSyntaxAndNotPlanarConfiguration0"
+	Element="PixelRepresentation"		Modifier="Not" BinaryValue="== 0"
+	(
+		Element="TransferSyntaxUID"						StringValue="1.2.840.10008.1.2.4.100"
+		Element="TransferSyntaxUID"		Operator="Or"	StringValue="1.2.840.10008.1.2.4.101"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPMLTransferSyntaxAndColumnsGreaterThan720"
+	Element="Columns"					BinaryValue="> 720"
+	Element="TransferSyntaxUID"			Operator="And" StringValue="1.2.840.10008.1.2.4.100"
+ConditionEnd
+
+Condition="MPEG2MPMLTransferSyntaxAndRowsGreaterThan480NTSCOr576PAL"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.100"
+	(
+		Element="Rows"					BinaryValue="> 576"
+		(
+			Element="Rows"				BinaryValue="> 480"
+			(
+				Element="FrameTime"		BinaryValue="!= 40"
+				(
+					Element="CineRate"			ElementPresent=""
+					Element="CineRate"			Operator="And" BinaryValue="!= 25"
+				) Operator="Or"
+			) Operator="And"
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPHLTransferSyntaxAndRowsNot720Or1080"
+	Element="TransferSyntaxUID"			Operator="And" StringValue="1.2.840.10008.1.2.4.101"
+	(
+		Element="Rows"									BinaryValue="== 720"
+		Element="Rows"					Operator="Or"	BinaryValue="== 1080"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPHLTransferSyntaxAndColumnsNot1280Or1920"
+	Element="TransferSyntaxUID"			Operator="And" StringValue="1.2.840.10008.1.2.4.101"
+	(
+		Element="Columns"								BinaryValue="== 1280"
+		Element="Columns"				Operator="Or"	BinaryValue="== 1920"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPHLTransferSyntaxAndColumnsInconsistentWithRows"
+	Element="TransferSyntaxUID"			Operator="And" StringValue="1.2.840.10008.1.2.4.101"
+	(
+		(
+			Element="Rows"								BinaryValue="== 720"
+			Element="Columns"			Operator="And"	BinaryValue="== 1280"
+		) Operator="Or"
+		(
+			Element="Rows"								BinaryValue="== 1080"
+			Element="Columns"			Operator="And"	BinaryValue="== 1920"
+		) Operator="Or"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPMLTransferSyntaxAndFrameTimeNotNTSCOrPAL"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.100"
+	(
+		Element="FrameTime"								BinaryValue="== 40"
+		Element="FrameTime"				Operator="Or"	BinaryValue="== 33"	# binary values are truncated during this test
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPMLTransferSyntaxAndCineRateNotNTSCOrPAL"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.100"
+	Element="CineRate"					Operator="And" ElementPresent=""
+	(
+		Element="CineRate"								BinaryValue="== 25"
+		Element="CineRate"				Operator="Or"	BinaryValue="== 30"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPMLTransferSyntaxAndCineRateInconsistentWithFrameTime"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.100"
+	Element="CineRate"					Operator="And" ElementPresent=""
+	Element="FrameTime"					Operator="And" ElementPresent=""
+	(
+		(
+			Element="FrameTime"							BinaryValue="== 40"
+			Element="CineRate"			Operator="And"	BinaryValue="== 25"
+		) Operator="Or"
+		(
+			Element="FrameTime"							BinaryValue="== 33"
+			Element="CineRate"			Operator="And"	BinaryValue="== 30"
+		) Operator="Or"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPHLTransferSyntaxAndFrameTimeNotValid"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.101"
+	(
+		Element="FrameTime"								BinaryValue="== 40"
+		Element="FrameTime"				Operator="Or"	BinaryValue="== 33"	# 33.33 binary values are truncated during this test
+		Element="FrameTime"				Operator="Or"	BinaryValue="== 20"	# binary values are truncated during this test
+		Element="FrameTime"				Operator="Or"	BinaryValue="== 16"	# 16.17 binary values are truncated during this test
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPHLTransferSyntaxAndCineRateNotValid"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.101"
+	Element="CineRate"					Operator="And" ElementPresent=""
+	(
+		Element="CineRate"								BinaryValue="== 25"
+		Element="CineRate"				Operator="Or"	BinaryValue="== 30"
+		Element="CineRate"								BinaryValue="== 50"
+		Element="CineRate"				Operator="Or"	BinaryValue="== 60"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="MPEG2MPHLTransferSyntaxAndCineRateInconsistentWithFrameTime"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.101"
+	Element="CineRate"					Operator="And" ElementPresent=""
+	Element="FrameTime"					Operator="And" ElementPresent=""
+	(
+		(
+			Element="FrameTime"							BinaryValue="== 40"
+			Element="CineRate"			Operator="And"	BinaryValue="== 25"
+		) Operator="Or"
+		(
+			Element="FrameTime"							BinaryValue="== 33"
+			Element="CineRate"			Operator="And"	BinaryValue="== 30"
+		) Operator="Or"
+		(
+			Element="FrameTime"							BinaryValue="== 20"
+			Element="CineRate"			Operator="And"	BinaryValue="== 50"
+		) Operator="Or"
+		(
+			Element="FrameTime"							BinaryValue="== 16"
+			Element="CineRate"			Operator="And"	BinaryValue="== 60"
+		) Operator="Or"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="UnwantedPixelAspectRatioWhenMPEG2MPHLTransferSyntax"
+	Element="TransferSyntaxUID"			StringValue="1.2.840.10008.1.2.4.101"
+	Element="PixelAspectRatio"			Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="ModalityNotPresent"
+	Element="Modality"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnatomicRegionSequenceNotPresent"
+	Element="AnatomicRegionSequence"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnatomicRegionSequencePresent"
+	Element="AnatomicRegionSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="ImageSetSelectorCategoryIsRelativeTime"
+	Element="ImageSetSelectorCategory"		StringValue="RELATIVE_TIME"
+ConditionEnd
+
+Condition="RelativeTimePresent"
+	Element="RelativeTime"				ElementPresent=""
+ConditionEnd
+
+Condition="ImageSetSelectorCategoryIsAbstractPriorAndAbstractPriorCodeSequenceNotPresent"
+	Element="ImageSetSelectorCategory"		StringValue="ABSTRACT_PRIOR"
+	Element="AbstractPriorCodeSequence"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ImageSetSelectorCategoryIsAbstractPriorAndAbstractPriorValueNotPresent"
+	Element="ImageSetSelectorCategory"		StringValue="ABSTRACT_PRIOR"
+	Element="AbstractPriorValue"			Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ScreenMinimumColorBitDepthNotPresent"
+	Element="ScreenMinimumColorBitDepth"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ScreenMinimumGrayscaleBitDepthNotPresent"
+	Element="ScreenMinimumGrayscaleBitDepth"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ImageBoxLayoutTypeIsTiled"
+	Element="ImageBoxLayoutType"			StringValue="TILED"
+ConditionEnd
+
+Condition="ImageBoxLayoutTypeIsCine"
+	Element="ImageBoxLayoutType"			StringValue="CINE"
+ConditionEnd
+
+Condition="ImageBoxLayoutTypeIsStack"
+	Element="ImageBoxLayoutType"			StringValue="STACK"
+ConditionEnd
+
+Condition="ImageBoxLayoutTypeIsTiledAndMoreThanOneTile"
+	Element="ImageBoxTileHorizontalDimension"	BinaryValue="> 1"
+	Element="ImageBoxTileVerticalDimension"		BinaryValue="> 1"
+	Element="ImageBoxLayoutType"			Operator="And" StringValue="TILED"
+ConditionEnd
+
+Condition="ImageBoxSmallScrollTypePresentWithValue"
+	Element="ImageBoxSmallScrollType"		 ElementPresent=""
+	# cannot check whether value is present or not
+ConditionEnd
+
+Condition="ImageBoxLargeScrollTypePresentWithValue"
+	Element="ImageBoxLargeScrollType"		 ElementPresent=""
+	# cannot check whether value is present or not
+ConditionEnd
+
+Condition="ImageBoxLayoutTypeIsCineAndCineRelativeToRealTimeNotPresent"
+	Element="ImageBoxLayoutType"			StringValue="CINE"
+	Element="CineRelativeToRealTime"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ImageBoxLayoutTypeIsCineAndRecommendedDisplayFrameRateNotPresent"
+	Element="ImageBoxLayoutType"			StringValue="CINE"
+	Element="RecommendedDisplayFrameRate"		Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SelectorAttributeNotPresent"
+	Element="SelectorAttribute"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SelectorAttributePresentAndFilterByOperatorNotPresent"
+	Element="SelectorAttribute"			ElementPresent=""
+	Element="FilterByOperator"			Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FilterByCategoryNotPresent"
+	Element="FilterByCategory"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SelectorAttributeOrFilterByCategoryAndFilterByOperatorPresent"
+	Element="SelectorAttribute"			ElementPresent=""
+	Element="FilterByCategory"			ElementPresent=""
+	Element="FilterByOperator"			Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="SelectorAttributeAndFilterByOperatorPresent"
+	Element="SelectorAttribute"			ElementPresent=""
+	Element="FilterByOperator"			Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="SelectorAttributePresentAndFilterByAttributePresenceNotPresentOrFilterByCategoryPresent"
+	Element="SelectorAttribute"			ElementPresent=""
+	Element="FilterByAttributePresence"		Operator="And" ElementPresent=""
+	Element="FilterByCategory"			Operator="Or"  ElementPresent=""
+ConditionEnd
+
+Condition="SortByCategoryNotPresent"
+	Element="SortByCategory"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SelectorAttributePresent"
+	Element="SelectorAttribute"			ElementPresent=""
+ConditionEnd
+
+Condition="ReformattingOperationTypeIsSlabOrMPR"
+	Element="ReformattingOperationType"		StringValue="SLAB"
+	Element="ReformattingOperationType"		Operator="Or" StringValue="MPR"
+ConditionEnd
+
+Condition="ReformattingOperationTypeIsMPROr3D"
+	Element="ReformattingOperationType"		StringValue="MPR"
+	Element="ReformattingOperationType"		Operator="Or" StringValue="3D_RENDERING"
+ConditionEnd
+
+Condition="ReformattingOperationTypeIs3D"
+	Element="ReformattingOperationType"		StringValue="3D_RENDERING"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsAT"
+	Element="SelectorAttributeVR"		StringValue="AT"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsCS"
+	Element="SelectorAttributeVR"		StringValue="CS"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsIS"
+	Element="SelectorAttributeVR"		StringValue="IS"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsLO"
+	Element="SelectorAttributeVR"		StringValue="LO"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsLT"
+	Element="SelectorAttributeVR"		StringValue="LT"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsPN"
+	Element="SelectorAttributeVR"		StringValue="PN"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsSH"
+	Element="SelectorAttributeVR"		StringValue="SH"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsST"
+	Element="SelectorAttributeVR"		StringValue="ST"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsUT"
+	Element="SelectorAttributeVR"		StringValue="UT"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsDS"
+	Element="SelectorAttributeVR"		StringValue="DS"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsFD"
+	Element="SelectorAttributeVR"		StringValue="FD"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsFL"
+	Element="SelectorAttributeVR"		StringValue="FL"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsUL"
+	Element="SelectorAttributeVR"		StringValue="UL"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsUS"
+	Element="SelectorAttributeVR"		StringValue="US"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsSL"
+	Element="SelectorAttributeVR"		StringValue="SL"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsSS"
+	Element="SelectorAttributeVR"		StringValue="SS"
+ConditionEnd
+
+Condition="SelectorAttributeVRIsSQ"
+	Element="SelectorAttributeVR"		StringValue="SQ"
+ConditionEnd
+
+Condition="PatientEyeMovementCommandedIsYes"
+	Element="PatientEyeMovementCommanded"				StringValue="YES"
+ConditionEnd
+
+Condition="PupilDilatedIsYes"
+	Element="PupilDilated"						StringValue="YES"
+ConditionEnd
+
+Condition="PartialViewIsYes"
+	Element="PartialView"						StringValue="YES"
+ConditionEnd
+
+Condition="PixelPaddingValueIsAbsent"
+	Element="PixelPaddingValue"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="PixelPaddingValueIsPresentAndInstanceIsNotAnImage"
+	Element="PixelPaddingValue"						ElementPresent=""
+	Element="PixelData"								Operator="And" Modifier="Not" ElementPresent=""
+	Element="PixelDataProviderURL"					Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="PixelSpacingCalibrationTypeIsPresent"
+	Element="PixelSpacingCalibrationType"		ElementPresent=""
+ConditionEnd
+
+Condition="PatientIdentityRemovedAndNotDeidentificationMethodCodeSequence"
+	Element="PatientIdentityRemoved"				StringValue="YES"
+	Element="DeidentificationMethodCodeSequence"	Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="PatientIdentityRemovedAndNotDeidentificationMethod"
+	Element="PatientIdentityRemoved"				StringValue="YES"
+	Element="DeidentificationMethod"				Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="TransferSyntaxIsReferencedPixelData"
+	Element="TransferSyntaxUID"								StringValue="1.2.840.10008.1.2.4.94"
+	Element="TransferSyntaxUID"				Operator="Or"	StringValue="1.2.840.10008.1.2.4.95"
+ConditionEnd
+
+Condition="PixelDataProviderURLIsAbsent"
+	Element="PixelDataProviderURL"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SOPClassIsEnhancedXAXRF"
+	Element="SOPClassUID"								StringValue="1.2.840.10008.5.1.4.1.1.12.1.1"
+	Element="SOPClassUID"				Operator="Or"	StringValue="1.2.840.10008.5.1.4.1.1.12.2.1"
+ConditionEnd
+
+Condition="MaskOperationIsRevTID"
+	Element="MaskOperation"				StringValue="REV_TID"
+ConditionEnd
+
+Condition="MaskOperationIsTIDOrRevTID"
+	Element="MaskOperation"				StringValue="TID"
+	Element="MaskOperation"				Operator="Or"	StringValue="REV_TID"
+ConditionEnd
+
+Condition="ModalityIsMR"
+	Element="Modality"			StringValueFromRootAttribute="MR"
+ConditionEnd
+
+Condition="ModalityIsCT"
+	Element="Modality"			StringValueFromRootAttribute="CT"
+ConditionEnd
+
+Condition="ModalityIsMROrPET"
+	Element="Modality"							StringValueFromRootAttribute="MR"
+	Element="Modality"			Operator="Or"	StringValueFromRootAttribute="PT"
+ConditionEnd
+
+Condition="IsocenterPositionIsPresent"
+	Element="IsocenterPosition"		ElementPresent=""
+ConditionEnd
+
+Condition="RadiationTypeIsIon"
+	Element="RadiationType"			StringValue="ION"
+ConditionEnd
+
+Condition="CompensatorMountingPositionNotDoubleSided"
+	Element="CompensatorMountingPosition"			Modifier="Not" StringValue="DOUBLE_SIDED"
+ConditionEnd
+
+Condition="RangeModulatorTypeIsWhlModWeights"
+	Element="RangeModulatorType"			StringValue="WHL_MODWEIGHTS"
+ConditionEnd
+
+Condition="ScanModeIsModulated"
+	Element="ScanMode"			StringValueAbove="MODULATED"
+ConditionEnd
+
+Condition="PlanesInAcquisitionNotUndefined"
+	Element="ImageType"		Modifier="Not" StringValue="UNDEFINED"
+ConditionEnd
+
+Condition="PositionerIsCArm"
+	Element="PositionerType"							StringValueFromRootAttribute="CARM"
+ConditionEnd
+
+Condition="PositionerIsCArmWithTableTopRelationship"
+	Element="PositionerType"							StringValueFromRootAttribute="CARM"
+	Element="CArmPositionerTabletopRelationship"		Operator="And"	StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="CArmPositionerTabletopRelationshipIsYes"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="PositionerIsColumn"
+	Element="PositionerType"							StringValueFromRootAttribute="COLUMN"
+ConditionEnd
+
+Condition="BitsAllocatedIs8"
+	Element="BitsAllocated"				BinaryValue="== 8"
+ConditionEnd
+
+Condition="BitsAllocatedIs16"
+	Element="BitsAllocated"				BinaryValue="== 16"
+ConditionEnd
+
+Condition="BitsStoredIs8"
+	Element="BitsStored"				BinaryValue="== 8"
+ConditionEnd
+
+Condition="BitsStoredGreaterThan8"
+	Element="BitsStored"				BinaryValue="> 8"
+ConditionEnd
+
+Condition="ExposureInmAsNotPresent"
+	Element="ExposureInmAs"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="XRayTubeCurrentInmAOrExposureTimeInmsNotPresent"
+	Element="XRayTubeCurrentInmA"		Modifier="Not" ElementPresent=""
+	Element="ExposureTimeInms"			Operator="Or"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="IsocenterReferenceSystemSequencePresent"
+	Element="IsocenterReferenceSystemSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="XRayReceptorTypeIsImageIntensifier"
+	Element="XRayReceptorType"						StringValue="IMG_INTENSIFIER"
+	Element="XRayReceptorType"		Operator="Or"	StringValueFromRootAttribute="IMG_INTENSIFIER"
+ConditionEnd
+
+Condition="XRayReceptorTypeIsDigitalDetector"
+	Element="XRayReceptorType"						StringValue="DIGITAL_DETECTOR"
+	Element="XRayReceptorType"		Operator="Or"	StringValueFromRootAttribute="DIGITAL_DETECTOR"
+ConditionEnd
+
+Condition="ExposureControlSensingRegionShapeIsRectangular"
+	Element="ExposureControlSensingRegionShape"		StringValue="RECTANGULAR"
+ConditionEnd
+
+Condition="ExposureControlSensingRegionShapeIsCircular"
+	Element="ExposureControlSensingRegionShape"		StringValue="CIRCULAR"
+ConditionEnd
+
+Condition="ExposureControlSensingRegionShapeIsPolygonal"
+	Element="ExposureControlSensingRegionShape"		StringValue="POLYGONAL"
+ConditionEnd
+
+Condition="GeometricalPropertiesIsNonUniform"
+	Element="GeometricalProperties"		StringValue="NON_UNIFORM"
+ConditionEnd
+
+Condition="DistanceObjectToTableTopNotEmpty"
+	Element="DistanceObjectToTableTop"				ValuePresent=""
+ConditionEnd
+
+Condition="WaveformSampleInterpretationNeeds8Bit"
+	Element="WaveformSampleInterpretation"							StringValue="SB"
+	Element="WaveformSampleInterpretation"			Operator="Or"	StringValue="UB"
+	Element="WaveformSampleInterpretation"			Operator="Or"	StringValue="MB"
+	Element="WaveformSampleInterpretation"			Operator="Or"	StringValue="AB"
+ConditionEnd
+
+Condition="WaveformSampleInterpretationNeeds16Bit"
+	Element="WaveformSampleInterpretation"							StringValue="SS"
+	Element="WaveformSampleInterpretation"			Operator="Or"	StringValue="US"
+ConditionEnd
+
+Condition="InstitutionCodeSequenceNotPresent"
+	Element="InstitutionCodeSequence"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="InstitutionNameNotPresent"
+	Element="InstitutionName"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ObserverTypeIsPerson"
+	Element="ObserverType"							StringValue="PSN"
+ConditionEnd
+
+Condition="ObserverTypeIsDevice"
+	Element="ObserverType"							StringValue="DEV"
+ConditionEnd
+
+Condition="PlanePositionSequenceOKInSharedFunctionalGroupSequence"
+	Element="PlanePositionSequence"					Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PlanePositionSequence"					Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlanePositionSequenceOKInPerFrameFunctionalGroupSequence"
+	Element="PlanePositionSequence"					Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PlanePositionSequence"					Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="PlaneOrientationSequenceOKInSharedFunctionalGroupSequence"
+	Element="PlaneOrientationSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PlaneOrientationSequence"				Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlaneOrientationSequenceOKInPerFrameFunctionalGroupSequence"
+	Element="PlaneOrientationSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PlaneOrientationSequence"				Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+	Element="PixelValueTransformationSequence"		Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PixelValueTransformationSequence"		Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+	Element="PixelValueTransformationSequence"		Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PixelValueTransformationSequence"		Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+	Element="FrameVOILUTSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameVOILUTSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+	Element="FrameVOILUTSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameVOILUTSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PhotometricInterpretation"			Operator="And"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+	Element="FrameVOILUTSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameVOILUTSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+	Element="FrameVOILUTSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameVOILUTSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PhotometricInterpretation"			Operator="And"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="RealWorldValueMappingSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="RealWorldValueMappingSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+	Element="RealWorldValueMappingSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RealWorldValueMappingSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+	Element="RealWorldValueMappingSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RealWorldValueMappingSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PhotometricInterpretation"					Operator="And"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="RealWorldValueMappingSequenceNotInSharedFunctionalGroupSequence"
+	Element="RealWorldValueMappingSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+	Element="RealWorldValueMappingSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RealWorldValueMappingSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+	Element="RealWorldValueMappingSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RealWorldValueMappingSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PhotometricInterpretation"					Operator="And"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+	Element="ReferencedImageSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ReferencedImageSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+	Element="ReferencedImageSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ReferencedImageSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+	Element="DerivationImageSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="DerivationImageSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+	Element="DerivationImageSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="DerivationImageSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+	Element="CardiacSynchronizationSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+	Element="CardiacSynchronizationSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FramePixelShiftMacroOKInSharedFunctionalGroupSequence"
+	Element="FramePixelShiftSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FramePixelShiftSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FramePixelShiftMacroOKInPerFrameFunctionalGroupSequence"
+	Element="FramePixelShiftSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FramePixelShiftSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameDisplayShutterMacroOKInSharedFunctionalGroupSequence"
+	Element="FrameDisplayShutterSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameDisplayShutterSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameDisplayShutterMacroOKInPerFrameFunctionalGroupSequence"
+	Element="FrameDisplayShutterSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameDisplayShutterSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+	Element="RespiratorySynchronizationSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+	Element="RespiratorySynchronizationSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFrameCharacteristicsMacroOKInSharedFunctionalGroupSequence"
+	Element="XAXRFFrameCharacteristicsSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="XAXRFFrameCharacteristicsSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFrameCharacteristicsMacroOKInPerFrameFunctionalGroupSequence"
+	Element="XAXRFFrameCharacteristicsSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="XAXRFFrameCharacteristicsSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayExposureControlSensingRegionsMacroOKInSharedFunctionalGroupSequence"
+	Element="ExposureControlSensingRegionsSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ExposureControlSensingRegionsSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayExposureControlSensingRegionsMacroOKInPerFrameFunctionalGroupSequence"
+	Element="ExposureControlSensingRegionsSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ExposureControlSensingRegionsSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayCalibrationDeviceUsageMacroOKInSharedFunctionalGroupSequence"
+	Element="CalibrationSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CalibrationSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayCalibrationDeviceUsageMacroOKInPerFrameFunctionalGroupSequence"
+	Element="CalibrationSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CalibrationSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayObjectThicknessMacroOKInSharedFunctionalGroupSequence"
+	Element="ObjectThicknessSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ObjectThicknessSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayObjectThicknessMacroOKInPerFrameFunctionalGroupSequence"
+	Element="ObjectThicknessSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ObjectThicknessSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFrameAcquisitionMacroOKInSharedFunctionalGroupSequence"
+	Element="FrameAcquisitionSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameAcquisitionSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFrameAcquisitionMacroOKInPerFrameFunctionalGroupSequence"
+	Element="FrameAcquisitionSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameAcquisitionSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="XRayIsocenterReferenceSystemMacroOKInSharedFunctionalGroupSequence"
+	Element="IsocenterReferenceSystemSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="IsocenterReferenceSystemSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CArmPositionerTabletopRelationship"			Operator="And"	StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="XRayIsocenterReferenceSystemMacroOKInPerFrameFunctionalGroupSequence"
+	Element="IsocenterReferenceSystemSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="IsocenterReferenceSystemSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CArmPositionerTabletopRelationship"			Operator="And"	StringValueFromRootAttribute="YES"
+ConditionEnd
+
+
+Condition="PatientOrientationInFrameMacroOKInSharedFunctionalGroupSequence"
+	Element="PatientOrientationInFrameSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PatientOrientationInFrameSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PatientOrientationInFrameMacroOKInPerFrameFunctionalGroupSequence"
+	Element="PatientOrientationInFrameSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PatientOrientationInFrameSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="TemporalPositionMacroOKInSharedFunctionalGroupSequence"
+	Element="TemporalPositionSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="TemporalPositionSequence"				Operator="And"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"		Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"		Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"	Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"	Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="TemporalPositionMacroOKInPerFrameFunctionalGroupSequence"
+	Element="TemporalPositionSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="TemporalPositionSequence"				Operator="And"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"		Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CardiacSynchronizationSequence"		Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"	Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="RespiratorySynchronizationSequence"	Operator="And"	Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+	Element="FrameVOILUTSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="FrameVOILUTSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="ImageDataTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="ImageDataTypeSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ImageDataTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="ImageDataTypeSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="IrradiationEventIdentificationMacroOKInSharedFunctionalGroupSequence"
+	Element="IrradiationEventIdentificationSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="IrradiationEventIdentificationSequence"				Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IrradiationEventIdentificationMacroOKInPerFrameFunctionalGroupSequence"
+	Element="IrradiationEventIdentificationSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="IrradiationEventIdentificationSequence"				Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IrradiationEventIdentificationSequenceNotInSharedFunctionalGroupSequence"
+	Element="IrradiationEventIdentificationSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IrradiationEventIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="IrradiationEventIdentificationSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ConversionSourceAttributesSequenceNotInSharedFunctionalGroupSequence"
+	Element="ConversionSourceAttributesSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ConversionSourceAttributesSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="ConversionSourceAttributesSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FramePixelDataPropertiesSequenceNotInSharedFunctionalGroupSequence"
+	Element="FramePixelDataPropertiesSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FramePixelDataPropertiesSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="FramePixelDataPropertiesSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPixelIntensityRelationshipLUTMacroInSharedFunctionalGroupSequence"
+	Element="PixelIntensityRelationship"			StringValueFromRootAttribute="LOG"
+	Element="PixelIntensityRelationshipLUTSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PixelIntensityRelationshipLUTSequence"	Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPixelIntensityRelationshipLUTMacroInPerFrameFunctionalGroupSequence"
+	Element="PixelIntensityRelationship"			StringValueFromRootAttribute="LOG"
+	Element="PixelIntensityRelationshipLUTSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PixelIntensityRelationshipLUTSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPatientOrientationInFrameMacroInSharedFunctionalGroupSequence"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="PatientOrientationInFrameSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PatientOrientationInFrameSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedPatientOrientationInFrameMacroInPerFrameFunctionalGroupSequence"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="PatientOrientationInFrameSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PatientOrientationInFrameSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FieldOfViewSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="FieldOfViewSequence"					Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="FieldOfViewSequenceNotInSharedFunctionalGroupSequence"
+	Element="FieldOfViewSequence"					Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayFieldOfViewMacroInSharedFunctionalGroupSequence"
+	Element="IsocenterReferenceSystemSequence"		ElementPresentInRoot=""
+	Element="FieldOfViewSequence"					Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FieldOfViewSequence"					Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayFieldOfViewMacroInPerFrameFunctionalGroupSequence"
+	Element="IsocenterReferenceSystemSequence"		ElementPresentInRoot=""
+	Element="FieldOfViewSequence"					Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FieldOfViewSequence"					Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFrameDetectorParametersMacroOKInSharedFunctionalGroupSequence"
+	Element="FrameDetectorParametersSequence"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameDetectorParametersSequence"	Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFrameDetectorParametersMacroOKInPerFrameFunctionalGroupSequence"
+	Element="FrameDetectorParametersSequence"	Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameDetectorParametersSequence"	Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayFrameDetectorParametersMacroInSharedFunctionalGroupSequence"
+	Element="XRayReceptorType"					StringValueFromRootAttribute="DIGITAL_DETECTOR"
+	Element="FrameDetectorParametersSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="FrameDetectorParametersSequence"	Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayFrameDetectorParametersMacroInPerFrameFunctionalGroupSequence"
+	Element="XRayReceptorType"					StringValueFromRootAttribute="DIGITAL_DETECTOR"
+	Element="FrameDetectorParametersSequence"	Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameDetectorParametersSequence"	Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayProjectionPixelCalibrationMacroInSharedFunctionalGroupSequence"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="ProjectionPixelCalibrationSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ProjectionPixelCalibrationSequence"		Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayProjectionPixelCalibrationMacroInPerFrameFunctionalGroupSequence"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="ProjectionPixelCalibrationSequence"		Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ProjectionPixelCalibrationSequence"		Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayPositionerMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="PositionerPositionSequence"				Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PositionerPositionSequence"				Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayPositionerMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="PositionerPositionSequence"				Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PositionerPositionSequence"				Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayTablePositionMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="TablePositionSequence"						Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="TablePositionSequence"						Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayTablePositionMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="TablePositionSequence"						Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="TablePositionSequence"						Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CollimatorShapeSequenceSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="CollimatorShapeSequence"					Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="CollimatorShapeSequenceSequenceNotInSharedFunctionalGroupSequence"
+	Element="CollimatorShapeSequence"					Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayCollimatorMacroInSharedFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="CollimatorShapeSequence"					Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="CollimatorShapeSequence"					Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayCollimatorMacroInPerFrameFunctionalGroupSequence"
+	Element="ImageType"									ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+	Element="CollimatorShapeSequence"					Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="CollimatorShapeSequence"					Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+# should really check for ProjectionPixelCalibrationSequence in either shared or per-frame sequence, but cannot ... 
+
+Condition="NeedXRayGeometryMacroInSharedFunctionalGroupSequence"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="XRayGeometrySequence"						Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="XRayGeometrySequence"						Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedXRayGeometryMacroInPerFrameFunctionalGroupSequence"
+	Element="CArmPositionerTabletopRelationship"		StringValueFromRootAttribute="YES"
+	Element="XRayGeometrySequence"						Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="XRayGeometrySequence"						Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ResponsiblePersonIsPresentWithValue"
+	Element="ResponsiblePerson"	ElementPresent=""
+	Element="ResponsiblePerson"							Operator="And" ValuePresent=""
+ConditionEnd
+
+Condition="IsHuman"
+	(
+		Element="CodingSchemeDesignator"								ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="SRT"
+		(
+			Element="CodeValue"											ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85B00"	# homo sapiens retired
+			Element="CodeValue"							Operator="Or"	ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85003"	# homo sapiens
+		) Operator="And"
+	)
+	(
+		Element="PatientSpeciesDescription"								Modifier="Not" ElementPresent=""
+		Element="PatientSpeciesCodeSequence"			Operator="And"	Modifier="Not" ElementPresent=""
+		Element="PatientBreedDescription"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="PatientBreedCodeSequence"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="BreedRegistrationSequence"				Operator="And"	Modifier="Not" ElementPresent=""
+		Element="StrainDescription"						Operator="And"	Modifier="Not" ElementPresent=""
+		Element="StrainNomenclature"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="StrainCodeSequence"					Operator="And"	Modifier="Not" ElementPresent=""
+		Element="StrainAdditionalInformation"			Operator="And"	Modifier="Not" ElementPresent=""
+		Element="StrainStockSequence"					Operator="And"	Modifier="Not" ElementPresent=""
+	) Operator="Or"
+ConditionEnd
+
+Condition="IsAnimal"
+	(
+		Element="CodingSchemeDesignator"								ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="SRT"
+		(
+			Element="CodeValue"											ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85B00"	# homo sapiens retired
+			Element="CodeValue"							Operator="Or"	ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85003"	# homo sapiens
+		) Operator="And"
+	) Modifier="Not"
+	(
+		Element="PatientSpeciesDescription"								ElementPresent=""
+		Element="PatientSpeciesCodeSequence"			Operator="Or"	ElementPresent=""
+		Element="PatientBreedDescription"				Operator="Or"	ElementPresent=""
+		Element="PatientBreedCodeSequence"				Operator="Or"	ElementPresent=""
+		Element="BreedRegistrationSequence"				Operator="Or"	ElementPresent=""
+		Element="StrainDescription"						Operator="Or"	ElementPresent=""
+		Element="StrainNomenclature"					Operator="Or"	ElementPresent=""
+		Element="StrainCodeSequence"					Operator="Or"	ElementPresent=""
+		Element="StrainAdditionalInformation"			Operator="Or"	ElementPresent=""
+		Element="StrainStockSequence"					Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="IsAnimalAndPatientSpeciesCodeSequenceAbsent"
+	Element="PatientSpeciesCodeSequence"				Modifier="Not" ElementPresent=""
+	(
+		(
+			Element="CodingSchemeDesignator"							ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="SRT"
+			(
+				(
+					Element="CodeValue"									ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85B00"	# homo sapiens retired
+					Element="CodeValue"					Operator="Or"	ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85003"	# homo sapiens
+				) Modifier="Not"
+			) Operator="And"
+		) Operator="Or"
+		Element="PatientSpeciesDescription"								ElementPresent=""
+		Element="PatientBreedDescription"				Operator="Or"	ElementPresent=""
+		Element="PatientBreedCodeSequence"				Operator="Or"	ElementPresent=""
+		Element="BreedRegistrationSequence"				Operator="Or"	ElementPresent=""
+		Element="StrainDescription"						Operator="Or"	ElementPresent=""
+		Element="StrainNomenclature"					Operator="Or"	ElementPresent=""
+		Element="StrainCodeSequence"					Operator="Or"	ElementPresent=""
+		Element="StrainAdditionalInformation"			Operator="Or"	ElementPresent=""
+		Element="StrainStockSequence"					Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="IsAnimalAndPatientSpeciesDescriptionAbsent"
+	Element="PatientSpeciesDescription"					Modifier="Not" ElementPresent=""
+	(
+		(
+			Element="CodingSchemeDesignator"							ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="SRT"
+			(
+				(
+					Element="CodeValue"									ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85B00"	# homo sapiens retired
+					Element="CodeValue"					Operator="Or"	ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85003"	# homo sapiens
+				) Modifier="Not"
+			) Operator="And"
+		) Operator="Or"
+		Element="PatientSpeciesCodeSequence"							ElementPresent=""
+		Element="PatientBreedDescription"				Operator="Or"	ElementPresent=""
+		Element="PatientBreedCodeSequence"				Operator="Or"	ElementPresent=""
+		Element="BreedRegistrationSequence"				Operator="Or"	ElementPresent=""
+		Element="StrainDescription"						Operator="Or"	ElementPresent=""
+		Element="StrainNomenclature"					Operator="Or"	ElementPresent=""
+		Element="StrainCodeSequence"					Operator="Or"	ElementPresent=""
+		Element="StrainAdditionalInformation"			Operator="Or"	ElementPresent=""
+		Element="StrainStockSequence"					Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="IsAnimalAndPatientBreedCodeSequenceEmpty"
+	Element="PatientBreedCodeSequence"					Modifier="Not" SequenceHasItems=""
+	(
+		(
+			Element="CodingSchemeDesignator"							ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="SRT"
+			(
+				(
+					Element="CodeValue"									ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85B00"	# homo sapiens retired
+					Element="CodeValue"					Operator="Or"	ElementPresentWithin="PatientSpeciesCodeSequence"	StringValue="L-85003"	# homo sapiens
+				) Modifier="Not"
+			) Operator="And"
+		) Operator="Or"
+		Element="PatientSpeciesDescription"								ElementPresent=""
+		Element="PatientSpeciesCodeSequence"			Operator="Or"	ElementPresent=""
+		Element="PatientBreedDescription"				Operator="Or"	ElementPresent=""
+		Element="PatientBreedCodeSequence"				Operator="Or"	ElementPresent=""
+		Element="BreedRegistrationSequence"				Operator="Or"	ElementPresent=""
+		Element="StrainDescription"						Operator="Or"	ElementPresent=""
+		Element="StrainNomenclature"					Operator="Or"	ElementPresent=""
+		Element="StrainCodeSequence"					Operator="Or"	ElementPresent=""
+		Element="StrainAdditionalInformation"			Operator="Or"	ElementPresent=""
+		Element="StrainStockSequence"					Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="DetectorTypeIsStorage"
+	Element="DetectorType"								StringValue="STORAGE"
+ConditionEnd
+
+Condition="DetectorTypeIsNotStorage"
+	Element="DetectorType"								Modifier="Not" StringValue="STORAGE"
+ConditionEnd
+
+# Conditions to detect mapping betweeb coding scheme designator and UID ...
+#
+Condition="CodingSchemeDesignatorIsACR"
+	Element="CodingSchemeDesignator"	StringValue="ACR"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsASTMSigpurpose"
+	Element="CodingSchemeDesignator"	StringValue="ASTM-sigpurpose"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsC4"
+	Element="CodingSchemeDesignator"	StringValue="C4"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsC5"
+	Element="CodingSchemeDesignator"	StringValue="C5"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsCD2"
+	Element="CodingSchemeDesignator"	StringValue="CD2"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsDCM"
+	Element="CodingSchemeDesignator"	StringValue="DCM"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsDCMUID"
+	Element="CodingSchemeDesignator"	StringValue="DCMUID"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsHPC"
+	Element="CodingSchemeDesignator"	StringValue="HPC"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsI10"
+	Element="CodingSchemeDesignator"	StringValue="I10"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsI10P"
+	Element="CodingSchemeDesignator"	StringValue="I10P"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsI9"
+	Element="CodingSchemeDesignator"	StringValue="I9"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsI9C"
+	Element="CodingSchemeDesignator"	StringValue="I9C"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsISO3166_1"
+	Element="CodingSchemeDesignator"	StringValue="ISO3166_1"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsISO639_1"
+	Element="CodingSchemeDesignator"	StringValue="ISO639_1"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsISO639_2"
+	Element="CodingSchemeDesignator"	StringValue="ISO639_2"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsLN"
+	Element="CodingSchemeDesignator"	StringValue="LN"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsPOS"
+	Element="CodingSchemeDesignator"	StringValue="POS"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsRFC3066"
+	Element="CodingSchemeDesignator"	StringValue="RFC3066"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsSNM3"
+	Element="CodingSchemeDesignator"	StringValue="SNM3"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsSCT"
+	Element="CodingSchemeDesignator"	StringValue="SCT"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsSRT"
+	Element="CodingSchemeDesignator"	StringValue="SRT"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsCTV3"
+	Element="CodingSchemeDesignator"	StringValue="CTV3"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsUCUM"
+	Element="CodingSchemeDesignator"	StringValue="UCUM"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsUMLS"
+	Element="CodingSchemeDesignator"	StringValue="UMLS"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorIsUPC"
+	Element="CodingSchemeDesignator"	StringValue="UPC"
+ConditionEnd
+
+Condition="PixelPaddingRangeLimitIsPresent"
+	Element="PixelPaddingRangeLimit"	ElementPresent=""
+ConditionEnd
+
+Condition="PatientPositionAndPatientOrientationCodeSequencePresent"
+	Element="PatientPosition"					ElementPresent=""
+	Element="PatientOrientationCodeSequence"	Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="VOILUTSequencePresentAndPresentationIntentTypeIsNotForPresentation"
+	Element="VOILUTSequence"			ElementPresent=""
+	Element="PresentationIntentType"	Operator="And" Modifier="Not" StringValue="FOR PRESENTATION"
+ConditionEnd
+
+Condition="WindowCenterPresentAndPresentationIntentTypeIsNotForPresentation"
+	Element="WindowCenter"			ElementPresent=""
+	Element="PresentationIntentType"	Operator="And" Modifier="Not" StringValue="FOR PRESENTATION"
+ConditionEnd
+
+Condition="SpatialLocationsPreservedReorientedOnly"
+	Element="SpatialLocationsPreserved"	StringValue="REORIENTED_ONLY"
+ConditionEnd
+
+Condition="UnwantedPixelAspectRatioWhenPixelSpacingPresent"
+	Element="PixelAspectRatio"					ElementPresent=""
+	Element="PixelSpacing"						Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="UnwantedPixelAspectRatioWhenImagerPixelSpacingPresent"
+	Element="PixelAspectRatio"					ElementPresent=""
+	Element="ImagerPixelSpacing"				Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="UnwantedPixelAspectRatioWhenNominalScannedPixelSpacingPresent"
+	Element="PixelAspectRatio"					ElementPresent=""
+	Element="NominalScannedPixelSpacing"		Operator="And" ElementPresent=""
+ConditionEnd
+
+Condition="UnwantedPixelAspectRatioWhenSharedPixelMeasuresMacro"
+	Element="PixelAspectRatio"					ElementPresent=""
+	Element="PixelMeasuresSequence"				Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="UnwantedPixelAspectRatioWhenPerFramePixelMeasuresMacro"
+	Element="PixelAspectRatio"					ElementPresent=""
+	Element="PixelMeasuresSequence"				Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+# find libsrc/standard/module -name '*.tpl' -exec grep InvokeMacro '{}' ';' | grep FunctionalGroupSequence | sed -e 's/^.*InvokeMacro="//' -e 's/Macro".*$/Sequence/' | sort -u | xargs -L1 dcdict -k
+
+Condition="DimensionIndexPointerIsNotFunctionalGroup"
+	Element="DimensionIndexPointer"				               Modifier="Not" TagValue="0x0018,0x9304"	# CT Acquisition Details Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9301"	# CT Acquisition Type Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9360"	# CT Additional X-Ray Source Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9321"	# CT Exposure Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9312"	# CT Geometry Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9329"	# CT Image Frame Type Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9326"	# CT Position Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9314"	# CT Reconstruction Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9308"	# CT Table Dynamics Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9325"	# CT X-ray Details Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9455"	# Calibration Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9118"	# Cardiac Synchronization Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9407"	# Collimator Shape Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9341"	# Contrast/Bolus Usage Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9172"	# ConversionSourceAttributesSequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0008,0x9124"	# Derivation Image Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9434"	# Exposure Control Sensing Regions Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9432"	# Field of View Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9417"	# Frame Acquisition Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9071"	# Frame Anatomy Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9451"	# Frame Detector Parameters Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9472"	# Frame Display Shutter Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0028,0x9443"	# Frame Pixel Data Properties Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0028,0x9415"	# Frame Pixel Shift Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0028,0x9132"	# Frame VOI LUT Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9807"	# Image Data Type Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0052,0x0027"	# Intravascular Frame Content Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0052,0x0029"	# Intravascular OCT Frame Content Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0052,0x0025"	# Intravascular OCT Frame Type Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9477"	# Irradiation Event Identification Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9462"	# Isocenter Reference System Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9251"	# MR Arterial Spin Labeling Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9119"	# MR Averages Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9117"	# MR Diffusion Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9114"	# MR Echo Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9125"	# MR FOV/Geometry Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9226"	# MR Image Frame Type Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9006"	# MR Imaging Modifier Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9152"	# MR Metabolite Map Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9115"	# MR Modifier Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9042"	# MR Receive Coil Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9107"	# MR Spatial Saturation Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9103"	# MR Spectroscopy FOV/Geometry Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9227"	# MR Spectroscopy Frame Type Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9112"	# MR Timing and Related Parameters Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9049"	# MR Transmit Coil Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9197"	# MR Velocity Encoding Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0022,0x0031"	# Ophthalmic Frame Location Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0048,0x0207"	# Optical Path Identification Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9456"	# Object Thickness Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9733"	# PET Detector Motion Details Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9732"	# PET Frame Acquisition Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9736"	# PET Frame Correction Factors Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9751"	# PET Frame Type Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9735"	# PET Position Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9749"	# PET Reconstruction Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9734"	# PET Table Dynamics Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0040,0x9092"	# Parametric Map Frame Type Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9450"	# Patient Orientation in Frame Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9771"	# Patient Physiological State Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0028,0x9422"	# Pixel Intensity Relationship LUT Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0028,0x9110"	# Pixel Measures Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0028,0x9145"	# Pixel Value Transformation Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9116"	# Plane Orientation Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9113"	# Plane Position Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0048,0x021a"	# Plane Position (Slide) Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9405"	# Positioner Position Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9401"	# Projection Pixel Calibration Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9737"	# Radiopharmaceutical Usage Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0040,0x9096"	# Real World Value Mapping Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0008,0x1140"	# Referenced Image Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9253"	# Respiratory Synchronization Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0062,0x000a"	# Segment Identification Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0048,0x0110"	# Specimen Reference Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9406"	# Table Position Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0020,0x9310"	# Temporal Position Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9476"	# X-Ray Geometry Sequence
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9412"	# XA/XRF Frame Characteristics Sequence 
+	Element="DimensionIndexPointer"				Operator="And" Modifier="Not" TagValue="0x0018,0x9504"	# X-Ray 3D Frame Type Sequence
+
+ConditionEnd
+
+Condition="CardiacSignalSourcePresentAndCardiacSynchronizationTechniqueIsNone"
+	Element="CardiacSignalSource"				ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" StringValue="NONE"
+ConditionEnd
+
+Condition="CardiacRRIntervalSpecifiedPresentAndCardiacSynchronizationTechniqueIsNone"
+	Element="CardiacRRIntervalSpecified"		ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" StringValue="NONE"
+ConditionEnd
+
+Condition="CardiacBeatRejectionTechniquePresentAndCardiacSynchronizationTechniqueIsNotProspectiveOrRetrospective"
+	Element="CardiacBeatRejectionTechnique"		ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" Modifier="Not" StringValue="PROSPECTIVE"
+	Element="CardiacSynchronizationTechnique"	Operator="And" Modifier="Not" StringValue="RETROSPECTIVE"
+ConditionEnd
+
+Condition="LowRRValuePresentAndCardiacSynchronizationTechniqueIsNotProspectiveOrRetrospective"
+	Element="LowRRValue"						ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" Modifier="Not" StringValue="PROSPECTIVE"
+	Element="CardiacSynchronizationTechnique"	Operator="And" Modifier="Not" StringValue="RETROSPECTIVE"
+ConditionEnd
+
+Condition="HighRRValuePresentAndCardiacSynchronizationTechniqueIsNotProspectiveOrRetrospective"
+	Element="HighRRValue"						ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" Modifier="Not" StringValue="PROSPECTIVE"
+	Element="CardiacSynchronizationTechnique"	Operator="And" Modifier="Not" StringValue="RETROSPECTIVE"
+ConditionEnd
+
+Condition="IntervalsAcquiredPresentAndCardiacSynchronizationTechniqueIsNone"
+	Element="IntervalsAcquired"					ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" StringValue="NONE"
+ConditionEnd
+
+Condition="IntervalsRejectedPresentAndCardiacSynchronizationTechniqueIsNone"
+	Element="IntervalsRejected"					ElementPresent=""
+	Element="CardiacSynchronizationTechnique"	Operator="And" StringValue="NONE"
+ConditionEnd
+
+Condition="RespiratorySignalSourcePresentAndRespiratoryMotionCompensationTechniqueIsNone"
+	Element="RespiratorySignalSource"					ElementPresent=""
+	Element="RespiratoryMotionCompensationTechnique"	Operator="And" StringValue="NONE"
+ConditionEnd
+
+Condition="BulkMotionSignalSourcePresentAndBulkMotionCompensationTechniqueIsNone"
+	Element="BulkMotionSignalSource"			ElementPresent=""
+	Element="BulkMotionCompensationTechnique"	Operator="And" StringValue="NONE"
+ConditionEnd
+
+Condition="ReferencedFrameNumberAndReferencedSegmentNumberPresent"
+	Element="ReferencedFrameNumber"				ElementPresent=""
+	Element="ReferencedSegmentNumber"			Operator="And" ElementPresent=""
+ConditionEnd
+
+# Real-world condition - assume true if any of the relevant attributes are present
+Condition="IsUltrasoundStageProtocol"
+	Element="NumberOfStages"							ElementPresent=""
+	Element="NumberOfViewsInStage"						ElementPresent=""
+	Element="StageName"									ElementPresent=""
+	Element="StageCodeSequence"							ElementPresent=""
+	Element="StageNumber"								ElementPresent=""
+	Element="ViewName"									ElementPresent=""
+	Element="ViewNumber"								ElementPresent=""
+ConditionEnd
+
+Condition="NominalScannedPixelSpacingPresentAndConversionTypeNotDigitizedFilmScannedDocumentScannedImage"
+	Element="NominalScannedPixelSpacing"					ElementPresent=""
+	Element="ConversionType"	Operator="And" Modifier="Not" StringValue="DF"
+	Element="ConversionType"	Operator="And" Modifier="Not" StringValue="SD"
+	Element="ConversionType"	Operator="And" Modifier="Not" StringValue="SI"
+ConditionEnd
+
+Condition="PartialViewNotPresent"
+	Element="PartialView"		Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="CodeValueIllegalOrDeprecated"
+	Element="CodeValue"		StringValue="Y-X1770"
+	Element="CodeValue"		StringValue="Y-X1771"
+	Element="CodeValue"		StringValue="TBD"
+ConditionEnd
+
+Condition="CodingSchemeDesignatorDeprecated"
+	Element="CodingSchemeDesignator"		StringValue="SNM3"
+	Element="CodingSchemeDesignator"		StringValue="99SDM"
+ConditionEnd
+
+Condition="CodeMeaningIllegalOrDeprecated"
+	Element="CodeValue"		StringValue="TBD"
+ConditionEnd
+
+Condition="LongCodeValueAndURNCodeValueAbsent"
+	Element="LongCodeValue"						Modifier="Not" ElementPresent=""
+	Element="URNCodeValue"		Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="CodeValueOrLongCodeValuePresent"
+	Element="CodeValue"							ElementPresent=""
+	Element="LongCodeValue"		Operator="Or"	ElementPresent=""
+ConditionEnd
+
+Condition="CodeValueAndURNCodeValueAbsent"
+	Element="CodeValue"							Modifier="Not" ElementPresent=""
+	Element="URNCodeValue"		Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="CodeValueAndLongCodeValueAbsent"
+	Element="CodeValue"							Modifier="Not" ElementPresent=""
+	Element="LongCodeValue"		Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NeedOphthalmicFrameLocationMacroInSharedFunctionalGroupSequence"
+	Element="OphthalmicFrameLocationSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="OphthalmicFrameLocationSequence"		Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedOphthalmicFrameLocationMacroInPerFrameFunctionalGroupSequence"
+	Element="OphthalmicFrameLocationSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="OphthalmicFrameLocationSequence"		Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+# should check AcquisitionDeviceTypeCodeSequence contains (A-00FBE, SRT, ”Optical Coherence Tomography Scanner”) ... too hard for now :(
+Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner"
+ConditionEnd
+
+Condition="OphthalmicImageOrientationIsTransverse"
+	Element="OphthalmicImageOrientation"	StringValue="TRANSVERSE"
+ConditionEnd
+
+Condition="ReferencedSOPClassUIDInFileIsEncapsulatedCDADocument"
+	Element="ReferencedSOPClassUIDInFile"		StringConstant="EncapsulatedCDAStorageSOPClassUID"
+ConditionEnd
+
+Condition="XRay3DFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="XRay3DFrameTypeSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRay3DFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="XRay3DFrameTypeSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="NeedModulePatientOrientation"
+	Element="PatientOrientationCodeSequence"			ElementPresent=""
+	Element="PatientGantryRelationshipCodeSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleImageEquipmentCoordinateRelationship"
+	Element="ImageToEquipmentMappingMatrix"				ElementPresent=""
+	Element="EquipmentCoordinateSystemIdentification"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRay3DAngiographicImageContributingSources"
+	Element="ContributingSourcesSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRay3DCraniofacialImageContributingSources"
+	Element="ContributingSourcesSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRay3DAngiographicAcquisition"
+	Element="XRay3DAcquisitionSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRay3DCraniofacialAcquisition"
+	Element="XRay3DAcquisitionSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleXRay3DReconstruction"
+	Element="XRay3DReconstructionSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="SingleCardiacIntervalAcquired"
+	Element="IntervalsAcquired"			BinaryValue="== 1"
+ConditionEnd
+
+Condition="CardiacSynchronizationTechniqueOtherThanNoneOrRealTime"
+	Element="CardiacSynchronizationTechnique"		ElementPresentInRoot=""
+	Element="CardiacSynchronizationTechnique"		Operator="And" Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="CardiacSynchronizationTechnique"		Operator="And" Modifier="Not" StringValueFromRootAttribute="REALTIME"
+ConditionEnd
+
+Condition="NeedRespiratoryIntervalTime"
+	Element="RespiratoryMotionCompensationTechnique"		Modifier="Not" StringValueFromRootAttribute="NONE"
+	Element="RespiratoryMotionCompensationTechnique"		Operator="And" Modifier="Not" StringValueFromRootAttribute="REALTIME"
+	Element="RespiratoryTriggerType"						Operator="And" Modifier="Not" StringValueFromRootAttribute="AMPLITUDE"	# i.e., not absent, TIME or BOTH
+ConditionEnd
+
+Condition="RespiratoryTriggerTypeTimeOrBoth"
+	Element="RespiratoryTriggerType"				StringValueFromRootAttribute="TIME"
+	Element="RespiratoryTriggerType"				StringValueFromRootAttribute="BOTH"
+ConditionEnd
+
+Condition="RespiratoryTriggerTypeAmplitudeOrBoth"
+	Element="RespiratoryTriggerType"				StringValueFromRootAttribute="AMPLITUDE"
+	Element="RespiratoryTriggerType"				StringValueFromRootAttribute="BOTH"
+ConditionEnd
+
+Condition="StartingRespiratoryAmplitudeIsPresent"
+	Element="StartingRespiratoryAmplitude"			ElementPresent=""
+ConditionEnd
+
+Condition="EndingRespiratoryAmplitudeIsPresent"
+	Element="EndingRespiratoryAmplitude"			ElementPresent=""
+ConditionEnd
+
+Condition="BlendingSequenceIsNotPresent"
+	Element="BlendingSequence"						Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ReferencedSeriesSequenceIsNotPresent"
+	Element="ReferencedSeriesSequence"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AnatomicRegionSequenceIsPresent"
+	Element="AnatomicRegionSequence"				ElementPresent=""
+ConditionEnd
+
+Condition="AnatomicRegionSequenceIsNotPresent"
+	Element="AnatomicRegionSequence"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="ModalityIsNotPresent"
+	Element="Modality"								Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="AbsoluteChannelDisplayScaleIsNotPresent"
+	Element="AbsoluteChannelDisplayScale"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="FractionalChannelDisplayScaleIsNotPresent"
+	Element="FractionalChannelDisplayScale"			Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SpecimenIdentifierIsPresentWithValue"
+	Element="SpecimenIdentifier"					ElementPresent=""
+	Element="SpecimenIdentifier"					Operator="And" ValuePresent=""
+ConditionEnd
+
+Condition="ROIPhysicalPropertyIsElemFraction"
+	Element="ROIPhysicalProperty"					StringValue="ELEM_FRACTION"
+ConditionEnd
+
+Condition="PixelSpacingIsPresent"
+	Element="PixelSpacing"							ElementPresent=""
+ConditionEnd
+
+Condition="ImageTypeValue3MissingOrEmpty"
+	Element="ImageType"								Modifier="Not" ValueSelector="2" ValuePresent=""
+	Element="ImageType"								Operator="Or" ValueSelector="2" StringValue=""
+ConditionEnd
+
+Condition="ImageTypeValue4MissingOrEmpty"
+	Element="ImageType"								Modifier="Not" ValueSelector="3" ValuePresent=""
+	Element="ImageType"								Operator="Or" ValueSelector="3" StringValue=""
+ConditionEnd
+
+Condition="LateralityHasNoValue"
+	Element="Laterality"							ElementPresent=""
+	Element="Laterality"							Operator="And" Modifier="Not" ValuePresent=""
+ConditionEnd
+
+# should really check for FrameLaterality, but ElementPresentInPathFromRoot only checks one level down :(
+# checking AnatomicRegionSequence is probably futile, since ImageLaterality rather than laterality is generally used for those IODs :(
+# also don't try to check Segmentation objects that contain AnatomicRegionSequence nested within SegmentSequence instead of top level :(
+# and don't try to check specimens, since Primary Anatomic Sequence deeply nested and inside and optional sequence :(
+Condition="LateralityRequired"
+	Element="ImageLaterality"						Modifier="Not" ElementPresent=""
+	Element="FrameAnatomySequence"					Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="FrameAnatomySequence"					Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="SegmentSequence"						Operator="And" Modifier="Not" ElementPresent=""
+	Element="SpecimenDescriptionSequence"			Operator="And" Modifier="Not" ElementPresent=""
+	(
+		Element="BodyPartExamined"					              StringValue="ABDOMEN"
+		Element="BodyPartExamined"					Operator="Or" StringValue="ABDOMENPELVIS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="AORTA"
+		Element="BodyPartExamined"					Operator="Or" StringValue="BACK"
+		Element="BodyPartExamined"					Operator="Or" StringValue="BLADDER"
+		Element="BodyPartExamined"					Operator="Or" StringValue="BRAIN"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CEREBELLUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CTSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CERVIX"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CHEST"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CHESTABDOMEN"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CHESTABDPELVIS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CIRCLEOFWILLIS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="COCCYX"
+		Element="BodyPartExamined"					Operator="Or" StringValue="COLON"
+		Element="BodyPartExamined"					Operator="Or" StringValue="CORONARYARTERY"
+		Element="BodyPartExamined"					Operator="Or" StringValue="DUODENUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="WHOLEBODY"
+		Element="BodyPartExamined"					Operator="Or" StringValue="ESOPHAGUS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="FACE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="GALLBLADDER"
+		Element="BodyPartExamined"					Operator="Or" StringValue="HEAD"
+		Element="BodyPartExamined"					Operator="Or" StringValue="HEADNECK"
+		Element="BodyPartExamined"					Operator="Or" StringValue="HEART"
+		Element="BodyPartExamined"					Operator="Or" StringValue="ILEUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="ILIUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="JAW"
+		Element="BodyPartExamined"					Operator="Or" StringValue="JEJUNUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="LARYNX"
+		Element="BodyPartExamined"					Operator="Or" StringValue="LIVER"
+		Element="BodyPartExamined"					Operator="Or" StringValue="LSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="LSSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="JAW"
+		Element="BodyPartExamined"					Operator="Or" StringValue="MAXILLA"
+		Element="BodyPartExamined"					Operator="Or" StringValue="MEDIASTINUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="MOUTH"
+		Element="BodyPartExamined"					Operator="Or" StringValue="NECK"
+		Element="BodyPartExamined"					Operator="Or" StringValue="NECKCHEST"
+		Element="BodyPartExamined"					Operator="Or" StringValue="NECKCHESTABDOMEN"
+		Element="BodyPartExamined"					Operator="Or" StringValue="NECKCHESTABDPELV"
+		Element="BodyPartExamined"					Operator="Or" StringValue="NOSE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="PANCREAS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="PELVIS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="PENIS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="PHARYNX"
+		Element="BodyPartExamined"					Operator="Or" StringValue="PROSTATE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="RECTUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="SSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="SCALP"
+		Element="BodyPartExamined"					Operator="Or" StringValue="SKULL"
+		Element="BodyPartExamined"					Operator="Or" StringValue="SPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="SPLEEN"
+		Element="BodyPartExamined"					Operator="Or" StringValue="STERNUM"
+		Element="BodyPartExamined"					Operator="Or" StringValue="STOMACH"
+		Element="BodyPartExamined"					Operator="Or" StringValue="TSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="TLSPINE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="THYMUS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="THYROID"
+		Element="BodyPartExamined"					Operator="Or" StringValue="TONGUE"
+		Element="BodyPartExamined"					Operator="Or" StringValue="TRACHEA"
+		Element="BodyPartExamined"					Operator="Or" StringValue="URETER"
+		Element="BodyPartExamined"					Operator="Or" StringValue="URETHRA"
+		Element="BodyPartExamined"					Operator="Or" StringValue="UTERUS"
+		Element="BodyPartExamined"					Operator="Or" StringValue="VAGINA"
+		Element="BodyPartExamined"					Operator="Or" StringValue="VULVA"
+	) Operator="And" Modifier="Not"
+	(
+		(
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	              StringValue="T-D4000"	# Abdomen
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB57"	# Abdomen and Pelvis
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-42500"	# Abdominal aorta
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-41070"	# Abdominal aorta and its branches
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-59490"	# Anus, rectum and sigmoid colon
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-42000"	# Aorta
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-42300"	# Aortic arch
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-32602"	# Apex of left ventricle
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-32502"	# Apex of right ventricle
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-42100"	# Ascending aorta
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D2100"	# Back
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-60610"	# Bile duct
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-74000"	# Bladder
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-DD123"	# Bladder and urethra
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-A0100"	# Brain
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D6500"	# Broad ligament
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11501"	# Cervical spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D00F7"	# Cervico-thoracic spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-83200"	# Cervix
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D3000"	# Chest
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB55"	# Chest and Abdomen
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB56"	# Chest, Abdomen and Pelvis
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-45526"	# Circle of Willis
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11BF0"	# Coccyx
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-59300"	# Colon
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-42400"	# Descending aorta
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-58200"	# Duodenum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D0010"	# Entire body
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-56000"	# Esophagus
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-DD163"	# Esophagus, stomach and duodenum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-63000"	# Gall  bladder
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D1100"	# Head
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D1000"	# Head and Neck
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-32000"	# Heart
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-58600"	# Ileum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-58400"	# Jejunum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-59000"	# Large intestine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-24100"	# Larynx
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-62000"	# Liver
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11503"	# Lumbar spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D00F9"	# Lumbo-sacral spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-28000"	# Lung
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D3300"	# Mediastinum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-2300C"	# Naso pharynx 
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D1600"	# Neck
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB52"	# Neck and Chest 
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB53"	# Neck, Chest and Abdomen
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB54"	# Neck, Chest, Abdomen and Pelvis
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-21000"	# Nose
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-65000"	# Pancreas
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-65010"	# Pancreatic duct
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-65600"	# Pancreatic duct and bile duct systems
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D6000"	# Pelvis
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="R-FAB58"	# Pelvis and lower extremeties
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-91000"	# Penis
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D2700"	# Perineum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-55002"	# Pharynx
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-20101"	# Pharynx and larynx
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-9200B"	# Prostate
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-59600"	# Rectum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D4900"	# Retroperitoneum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11AD0"	# Sacrum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D1160"	# Scalp
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D1460"	# Sella turcica
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-59470"	# Sigmoid colon
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11000"	# Skeletal system structure (not in DICOM PS 3.16, but Siemens uses for bone scans)
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11100"	# Skull
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-58000"	# Small intestine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-A7010"	# Spinal cord
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D0146"	# Spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-C3000"	# Spleen
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-46460"	# Splenic artery
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-48890"	# Splenic vein
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11210"	# Sternum
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-57000"	# Stomach
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11218"	# Suprasternal notch
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-42070"	# Thoracic aorta
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-11502"	# Thoracic spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D00F8"	# Thoraco-lumbar spine
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D3000"	# Thorax
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-C8000"	# Thymus
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-B6000"	# Thyroid
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-53000"	# Tongue
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-25000"	# Trachea
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-DD006"	# Trachea and bronchus
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-F1810"	# Umbilical artery
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-D4230"	# Umbilical region
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-48817"	# Umbilical vein
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-75000"	# Urethra
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-83000"	# Uterus
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-88920"	# Uterus and fallopian tubes
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-82000"	# Vagina
+			Element="CodeValue"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="T-81000"	# Vulva
+		)
+		(
+			Element="CodingSchemeDesignator"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="SRT"
+			Element="CodingSchemeDesignator"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="SNM3"
+			Element="CodingSchemeDesignator"	ElementPresentWithin="AnatomicRegionSequence"	Operator="Or" StringValue="99SDM"
+		) Operator="And"
+	) Operator="And" Modifier="Not"
+ConditionEnd
+
+Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"
+	Element="LossyImageCompressionMethod"	ElementPresent=""
+	Element="TransferSyntaxUID"				Operator="And" ElementPresent=""
+	(
+				Element="TransferSyntaxUID"	              StringValue="1.2.840.10008.1.2"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.1"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.1.99"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.2"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.57"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.58"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.65"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.66"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.70"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.80"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.90"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.92"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.5"
+	) Modifier="Not" Operator="And"
+	(
+		(
+			Element="LossyImageCompressionMethod"	StringValue="ISO_10918_1"
+			(
+				Element="TransferSyntaxUID"	              StringValue="1.2.840.10008.1.2.4.50"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.51"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.52"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.53"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.54"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.55"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.56"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.59"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.60"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.61"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.62"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.63"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.64"
+			) Modifier="Not" Operator="And"
+		) Operator="Or"
+		(
+			Element="LossyImageCompressionMethod"	StringValue="ISO_14495_1"
+			(
+				Element="TransferSyntaxUID"	              StringValue="1.2.840.10008.1.2.4.81"
+			) Modifier="Not" Operator="And"
+		) Operator="Or"
+		(
+			Element="LossyImageCompressionMethod"	StringValue="ISO_15444_1"
+			(
+				Element="TransferSyntaxUID"	              StringValue="1.2.840.10008.1.2.4.91"
+			) Modifier="Not" Operator="And"
+		) Operator="Or"
+		(
+			Element="LossyImageCompressionMethod"	StringValue="ISO_15444_2"
+			(
+				Element="TransferSyntaxUID"	              StringValue="1.2.840.10008.1.2.4.93"
+			) Modifier="Not" Operator="And"
+		) Operator="Or"
+		(
+			Element="LossyImageCompressionMethod"	StringValue="ISO_13818_2"
+			(
+				Element="TransferSyntaxUID"	              StringValue="1.2.840.10008.1.2.4.100"
+				Element="TransferSyntaxUID"	Operator="Or" StringValue="1.2.840.10008.1.2.4.101"
+			) Modifier="Not" Operator="And"
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+Condition="UniversalEntityIDPresent"
+	Element="UniversalEntityID"						ElementPresent=""
+ConditionEnd
+
+Condition="UniversalEntityIDNotPresent"
+	Element="UniversalEntityID"						Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="LocalNamespaceEntityIDNotPresent"
+	Element="LocalNamespaceEntityID"				Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="CodeMeaningEmptyOrNotPresent"
+	Element="CodeMeaning"							Modifier="Not" ElementPresent=""
+	Element="CodeMeaning"							Operator="Or" Modifier="Not" ValuePresent=""
+ConditionEnd
+
+Condition="AnatomicRegionSequencePresentAndEmptyButBodyPartExaminedHasValue"
+	Element="AnatomicRegionSequence"				ElementPresent=""
+	Element="AnatomicRegionSequence"				Operator="And" Modifier="Not" SequenceHasItems=""
+	Element="BodyPartExamined"						Operator="And" ValuePresent=""
+ConditionEnd
+
+Condition="ViewCodeSequenceAbsentOrEmptyButViewPositionHasValue"
+	Element="ViewPosition"							ValuePresent=""
+	Element="ViewCodeSequence"						Operator="And" Modifier="Not" SequenceHasItems=""
+ConditionEnd
+
+Condition="InstanceIsNotAnImage"
+	Element="PixelData"								Modifier="Not" ElementPresent=""
+	Element="PixelDataProviderURL"					Operator="And" Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="SegmentationTypeIsBinary"
+	Element="SegmentationType"						StringValue="BINARY"
+ConditionEnd
+
+Condition="SegmentationTypeIsNotBinary"
+	Element="SegmentationType"						Modifier="Not" StringValue="BINARY"
+ConditionEnd
+
+Condition="SegmentationTypeIsFractional"
+	Element="SegmentationType"						StringValue="FRACTIONAL"
+ConditionEnd
+
+Condition="SegmentAlgorithmTypeIsNotManual"
+	Element="SegmentAlgorithmType"					Modifier="Not" StringValue="MANUAL"
+ConditionEnd
+
+Condition="InstancesAreReferencedAndStudiesContainingOtherReferencedInstancesSequenceAbsent"
+	Element="StudiesContainingOtherReferencedInstancesSequence"		Modifier="Not" ElementPresent=""
+	(
+		Element="ReferencedSOPInstanceUID"							ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="StereoPairsSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="RegistrationSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="DeformableRegistrationSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="FiducialSetSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="ReferencedImageRealWorldValueMappingSequence"
+	) Operator="And"
+ConditionEnd
+
+Condition="InstancesAreReferencedAndReferencedSeriesSequenceAbsent"
+	Element="ReferencedSeriesSequence"								Modifier="Not" ElementPresent=""
+	(
+		Element="ReferencedSOPInstanceUID"							ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="StereoPairsSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="RegistrationSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="DeformableRegistrationSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="FiducialSetSequence"
+		Element="ReferencedSOPInstanceUID"			Operator="Or"	ElementPresentInPathFromRoot="ReferencedImageRealWorldValueMappingSequence"
+	) Operator="And"
+ConditionEnd
+
+Condition="NotSecondaryCaptureSOPClass"
+	Element="SOPClassUID"					Modifier="Not"	StringConstantFromRootAttribute="SecondaryCaptureImageStorageSOPClassUID"
+	Element="SOPClassUID"	Operator="And"	Modifier="Not"	StringConstantFromRootAttribute="MultiframeSingleBitSecondaryCaptureImageStorageSOPClassUID"
+	Element="SOPClassUID"	Operator="And"	Modifier="Not"	StringConstantFromRootAttribute="MultiframeGrayscaleByteSecondaryCaptureImageStorageSOPClassUID"
+	Element="SOPClassUID"	Operator="And"	Modifier="Not"	StringConstantFromRootAttribute="MultiframeGrayscaleWordSecondaryCaptureImageStorageSOPClassUID"
+	Element="SOPClassUID"	Operator="And"	Modifier="Not"	StringConstantFromRootAttribute="MultiframeTrueColorSecondaryCaptureImageStorageSOPClassUID"
+ConditionEnd
+
+Condition="AcquisitionStartConditionDENS"
+	Element="AcquisitionStartCondition"		StringValue="DENS"
+ConditionEnd
+
+Condition="AcquisitionStartConditionRDD"
+	Element="AcquisitionStartCondition"		StringValue="RDD"
+ConditionEnd
+
+Condition="AcquisitionStartConditionCARD_TRIG"
+	Element="AcquisitionStartCondition"		StringValue="CARD_TRIG"
+ConditionEnd
+
+Condition="AcquisitionStartConditionRESP_TRIG"
+	Element="AcquisitionStartCondition"		StringValue="RESP_TRIG"
+ConditionEnd
+
+Condition="AcquisitionTerminationConditionCNTS"
+	Element="AcquisitionTerminationCondition"		StringValue="CNTS"
+ConditionEnd
+
+Condition="AcquisitionTerminationConditionDENS"
+	Element="AcquisitionTerminationCondition"		StringValue="DENS"
+ConditionEnd
+
+Condition="AcquisitionTerminationConditionRDD"
+	Element="AcquisitionTerminationCondition"		StringValue="RDD"
+ConditionEnd
+
+Condition="AcquisitionTerminationConditionTIME"
+	Element="AcquisitionTerminationCondition"		StringValue="TIME"
+ConditionEnd
+
+Condition="AcquisitionTerminationConditionCARD_TRIG"
+	Element="AcquisitionTerminationCondition"		StringValue="CARD_TRIG"
+ConditionEnd
+
+Condition="AcquisitionTerminationConditionRESP_TRIG"
+	Element="AcquisitionTerminationCondition"		StringValue="RESP_TRIG"
+ConditionEnd
+
+Condition="OriginalAndTypeOfDetectorMotionIsStationary"
+	Element="ImageType"					ValueSelector="0"	StringValue="ORIGINAL"
+	Element="TypeOfDetectorMotion"		Operator="And"		StringValue="STATIONARY"
+ConditionEnd
+
+Condition="DetectorGeometryPresentAndTypeOfDetectorMotionIsNotStationary"
+	Element="DetectorGeometry"			ElementPresent=""
+	Element="TypeOfDetectorMotion"		Operator="And" Modifier="Not" StringValue="STATIONARY"
+ConditionEnd
+
+Condition="IsRandomsCorrected"
+	Element="RandomsCorrected"			StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="IsAttenuationCorrected"
+	Element="AttenuationCorrected"		StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="IsScatterCorrected"
+	Element="ScatterCorrected"			StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="IsDecayCorrected"
+	Element="DecayCorrected"			StringValueFromRootAttribute="YES"
+ConditionEnd
+
+Condition="IsIterativeReconstruction"
+	# NOT from root !
+	Element="IterativeReconstructionMethod"		StringValue="YES"
+ConditionEnd
+
+Condition="MultiEnergyProportionalWeighting"
+	Element="CodeValue"					ElementPresentWithin="DerivationCodeSequence"					StringValue="113097"	# Multi-energy proportional weighting
+	Element="CodingSchemeDesignator"	ElementPresentWithin="DerivationCodeSequence"	Operator="And"	StringValue="DCM"
+ConditionEnd
+
+Condition="EnergyWeightingFactorPresentInRoot"
+	Element="EnergyWeightingFactor"	ElementPresentInRoot=""
+ConditionEnd
+
+Condition="ImageTypeValue1IsOriginal"
+	Element="ImageType"					ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+ConditionEnd
+
+Condition="ClinicalTrialProtocolEthicsCommitteeApprovalNumberIsPresent"
+	Element="ClinicalTrialProtocolEthicsCommitteeApprovalNumber"			ElementPresent=""
+ConditionEnd
+
+Condition="ConsentForDistributionFlagIsYesOrWithdrawn"
+	Element="ConsentForDistributionFlag"						StringValue="YES"
+	Element="ConsentForDistributionFlag"		Operator="Or"	StringValue="WITHDRAWN"
+ConditionEnd
+
+Condition="DistributionTypeIsNotNamedProtocol"
+	Element="DistributionType"		Modifier="Not"	StringValue="NAMED_PROTOCOL"
+ConditionEnd
+
+Condition="FluenceModeIsNonStandard"
+	Element="FluenceMode"		StringValue="NON_STANDARD"
+ConditionEnd
+
+Condition="DoseSummationTypeIsNotMultiPlanAndReferencedRTPlanSequenceHasMultipleItems"
+	Element="DoseSummationType"			Modifier="Not"	StringValue="MULTI_PLAN"
+	Element="ReferencedRTPlanSequence"	Operator="And" SequenceHasMultipleItems=""
+ConditionEnd
+
+Condition="DoseSummationTypeIsMultiPlanAndReferencedRTPlanSequenceHasLessThanTwoItems"
+	Element="DoseSummationType"			StringValue="MULTI_PLAN"
+	(
+		Element="ReferencedRTPlanSequence"	Modifier="Not"	SequenceHasItems=""
+		Element="ReferencedRTPlanSequence"	Operator="Or"	SequenceHasOneItem=""
+	) Operator="And"
+ConditionEnd
+
+Condition="NeedSimpleFrameListInFrameExtractionModule"
+	Element="CalculatedFrameList"						Modifier="Not"	ElementPresent=""
+	Element="TimeRange"					Operator="And"	Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedCalculatedFrameListInFrameExtractionModule"
+	Element="SimpleFrameList"							Modifier="Not"	ElementPresent=""
+	Element="TimeRange"					Operator="And"	Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedTimeRangeInFrameExtractionModule"
+	Element="SimpleFrameList"							Modifier="Not"	ElementPresent=""
+	Element="CalculatedFrameList"		Operator="And"	Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleFrameExtraction"
+	Element="FrameExtractionSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="MydriaticAgentConcentrationIsPresent"
+	Element="MydriaticAgentConcentration"	ElementPresent=""
+ConditionEnd
+
+Condition="ImageTypeValue1DerivedAndImageTypeValue3MissingOrEmpty"
+	Element="ImageType"						ValueSelector="0"	StringValue="DERIVED"
+	(
+		Element="ImageType"		Modifier="Not"	ValueSelector="2"	ValuePresent=""
+		Element="ImageType"		Operator="Or"	ValueSelector="2"	StringValue=""
+	) Operator="And"
+ConditionEnd
+
+Condition="ImageTypeValue1NotDerivedAndImageTypeValueNotMissingOrEmpty"
+	Element="ImageType"			Modifier="Not"	ValueSelector="0"	StringValue="DERIVED"
+	(
+		Element="ImageType"		Modifier="Not"	ValueSelector="2"	ValuePresent=""
+		Element="ImageType"		Operator="Or"	ValueSelector="2"	StringValue=""
+	) Operator="And" Modifier="Not"
+ConditionEnd
+
+Condition="ASLContextIsControlLOrLabel"
+	Element="ASLContext"			StringValue="CONTROL"
+	Element="ASLContext"			StringValue="LABEL"
+ConditionEnd
+
+Condition="ASLCrusherFlagIsYes"
+	Element="ASLCrusherFlag"		StringValue="YES"
+ConditionEnd
+
+Condition="ASLBolusCutoffFlagIsYes"
+	Element="ASLBolusCutoffFlag"	StringValue="YES"
+ConditionEnd
+
+Condition="GraphicTypeIsPOINT"
+	Element="GraphicType"			StringValue="POINT"
+ConditionEnd
+
+Condition="GraphicTypeIsCIRCLE"
+	Element="GraphicType"			StringValue="CIRCLE"
+ConditionEnd
+
+Condition="GraphicTypeIsELLIPSE"
+	Element="GraphicType"			StringValue="ELLIPSE"
+ConditionEnd
+
+Condition="GraphicTypeIsELLIPSOID"
+	Element="GraphicType"			StringValue="ELLIPSOID"
+ConditionEnd
+
+Condition="XRay3DReconstructionSequenceIsPresent"
+	Element="XRay3DReconstructionSequence"	ElementPresentInRoot=""
+ConditionEnd
+
+Condition="ModalityIsMG"
+	Element="Modality"				StringValue="MG"
+ConditionEnd
+
+# cannnot check values within ViewModifierCodeSequence because nested within ViewCodeSequence :(
+Condition="ViewModifierCodeSequenceIsMagnificationOrSpotCompression"
+ConditionEnd
+
+Condition="FieldOfViewDimensionsInFloatPresentAndFieldOfViewShapeIsRectangle"
+	Element="FieldOfViewDimensionsInFloat"	ElementPresent=""
+	Element="FieldOfViewShape"				Operator="And"	StringValue="StringValue="YES"
+ConditionEnd
+
+Condition="FieldOfViewDimensionsInFloatPresentAndFieldOfViewShapeIsRound"
+	Element="FieldOfViewDimensionsInFloat"	ElementPresent=""
+	Element="FieldOfViewShape"				Operator="And"	StringValue="StringValue="ROUND"
+ConditionEnd
+
+Condition="FieldOfViewDimensionsInFloatPresentAndFieldOfViewShapeIsHexagon"
+	Element="FieldOfViewDimensionsInFloat"	ElementPresent=""
+	Element="FieldOfViewShape"				Operator="And"	StringValue="StringValue="HEXAGONAL"
+ConditionEnd
+
+Condition="NeedModuleBreastTomosynthesisContributingSources"
+	Element="ContributingSourcesSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleBreastTomosynthesisAcquisition"
+	Element="XRay3DAcquisitionSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="SurfaceProcessingIsYes"
+	Element="SurfaceProcessing"				StringValue="StringValue="YES"
+ConditionEnd
+
+Condition="AxisOfRotationIsPresent"
+	Element="AxisOfRotation"				ElementPresent=""
+ConditionEnd
+
+Condition="StudyInstanceUIDIsPresent"
+	Element="StudyInstanceUID"				ElementPresent=""
+ConditionEnd
+
+Condition="PositionerMotionIsPresentAndNumberOfFramesIsAbsentOrOne"
+	Element="PositionerMotion"		ElementPresent=""
+	(
+		Element="NumberOfFrames"		Modifier="Not" ElementPresent=""
+		Element="NumberOfFrames"		Operator="Or" BinaryValue="== 1"
+	) Operator="And"
+ConditionEnd
+
+Condition="RationalNumeratorValueIsPresent"
+	Element="RationalNumeratorValue"	ElementPresent=""
+ConditionEnd
+
+Condition="FloatingPointValuePresentButValueTypeIsNotNumeric"
+	Element="FloatingPointValue"		ElementPresent=""
+	Element="ValueType"					Operator="And" Modifier="Not" StringValue="NUM"
+ConditionEnd
+
+Condition="RationalNumeratorValuePresentButValueTypeIsNotNumeric"
+	Element="RationalNumeratorValue"	ElementPresent=""
+	Element="ValueType"					Operator="And" Modifier="Not" StringValue="NUM"
+ConditionEnd
+
+Condition="RationalDenominatorValueButValueTypeIsNotNumeric"
+	Element="RationalDenominatorValue"	ElementPresent=""
+	Element="ValueType"					Operator="And" Modifier="Not" StringValue="NUM"
+ConditionEnd
+
+Condition="FloatingPointValuePresentButAcquisitionContextItemIsNotNumeric"
+	Element="FloatingPointValue"				ElementPresent=""
+	(
+		Element="ValueType"						Modifier="Not" StringValue="NUMERIC"
+		Element="NumericValue"					Operator="Or"	Modifier="Not" ElementPresent=""
+		Element="Time"							Operator="Or"	ElementPresent=""
+		Element="PersonName"					Operator="Or"	ElementPresent=""
+		Element="TextValue"						Operator="Or"	ElementPresent=""
+		Element="ConceptCodeSequence"			Operator="Or"	ElementPresent=""
+		Element="Date"							Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="RationalNumeratorValuePresentButAcquisitionContextItemIsNotNumeric"
+	Element="RationalNumeratorValue"			ElementPresent=""
+	(
+		Element="ValueType"						Modifier="Not" StringValue="NUMERIC"
+		Element="NumericValue"					Operator="Or"	Modifier="Not" ElementPresent=""
+		Element="Time"							Operator="Or"	ElementPresent=""
+		Element="PersonName"					Operator="Or"	ElementPresent=""
+		Element="TextValue"						Operator="Or"	ElementPresent=""
+		Element="ConceptCodeSequence"			Operator="Or"	ElementPresent=""
+		Element="Date"							Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="RationalDenominatorValuePresentButAcquisitionContextItemIsNotNumeric"
+	Element="RationalDenominatorValue"			ElementPresent=""
+	(
+		Element="ValueType"						Modifier="Not" StringValue="NUMERIC"
+		Element="NumericValue"					Operator="Or"	Modifier="Not" ElementPresent=""
+		Element="Time"							Operator="Or"	ElementPresent=""
+		Element="PersonName"					Operator="Or"	ElementPresent=""
+		Element="TextValue"						Operator="Or"	ElementPresent=""
+		Element="ConceptCodeSequence"			Operator="Or"	ElementPresent=""
+		Element="Date"							Operator="Or"	ElementPresent=""
+	) Operator="And"
+ConditionEnd
+
+Condition="DimensionIndexSequencePresent"
+	Element="DimensionIndexSequence"			ElementPresentInRoot=""
+ConditionEnd
+
+Condition="InStackPositionNumberIsZero"
+	Element="InStackPositionNumber"				BinaryValue="== 0"
+ConditionEnd
+
+Condition="TemporalPositionIndexIsZero"
+	Element="TemporalPositionIndex"				BinaryValue="== 0"
+ConditionEnd
+
+Condition="DimensionIndexValuesContainsZero"
+	Element="DimensionIndexValues"				BinaryValue="== 0"
+ConditionEnd
+
+Condition="WindowWidthIsNegative"
+	Element="WindowWidth"						BinaryValue="< 0"
+ConditionEnd
+
+Condition="IVUSAcquisitionIsMotorized"
+	Element="IVUSAcquisition"				StringValueFromRootAttribute="MOTORIZED"
+ConditionEnd
+
+Condition="IVUSAcquisitionIsMeasured"
+	Element="IVUSAcquisition"				StringValueFromRootAttribute="MEASURED"
+ConditionEnd
+
+Condition="IntravascularOCTFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	Element="IntravascularOCTFrameTypeSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IntravascularOCTFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="IntravascularOCTFrameTypeSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IntravascularFrameContentSequenceNotInSharedFunctionalGroupSequence"
+	Element="IntravascularFrameContentSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IntravascularFrameContentSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="IntravascularFrameContentSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IntravascularFrameContentSequenceNotInSharedFunctionalGroupSequenceAndAcquisitionIsMeasured"
+	Element="IntravascularFrameContentSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="IVUSAcquisition"								Operator="And" StringValueFromRootAttribute="MEASURED"
+ConditionEnd
+
+Condition="IntravascularFrameContentSequenceNotInPerFrameFunctionalGroupSequenceAndAcquisitionIsMeasured"
+	Element="IntravascularFrameContentSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="IVUSAcquisition"								Operator="And" StringValueFromRootAttribute="MEASURED"
+ConditionEnd
+
+Condition="IntravascularOCTFrameContentSequenceNotInSharedFunctionalGroupSequence"
+	Element="IntravascularOCTFrameContentSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IntravascularOCTFrameContentSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="IntravascularOCTFrameContentSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PresentationIntentTypeIsForProcessing"
+	Element="PresentationIntentType"				StringValueFromRootAttribute="FOR PROCESSING"
+ConditionEnd
+
+Condition="PresentationIntentTypeIsForPresentation"
+	Element="PresentationIntentType"				StringValueFromRootAttribute="FOR PRESENTATION"
+ConditionEnd
+
+Condition="PixelPresentationIsColorRef"
+	Element="PixelPresentation"						StringValueFromRootAttribute="COLOR_REF"
+ConditionEnd
+
+Condition="RotationalCatheterInformationIsPresent"
+	Element="CatheterDirectionOfRotation"			ElementPresent=""
+	Element="CatheterRotationalRate"				ElementPresent=""
+ConditionEnd
+
+Condition="ImageBoxOverlapPriorityValueNot1To100"
+	Element="ImageBoxOverlapPriority"				ElementPresent=""
+	(
+		Element="ImageBoxOverlapPriority"			BinaryValue="< 1"
+		Element="ImageBoxOverlapPriority"			BinaryValue="> 100"
+	) Operator="And"
+ConditionEnd
+
+Condition="RecommendedDisplayFrameRateNotGreaterThanZero"
+	Element="RecommendedDisplayFrameRate"			ElementPresent=""
+	Element="RecommendedDisplayFrameRate"			Operator="And"	BinaryValue="< 0"
+ConditionEnd
+
+Condition="CineRelativeToRealTimeNotGreaterThanZero"
+	Element="CineRelativeToRealTime"				ElementPresent=""
+	Element="CineRelativeToRealTime"				Operator="And"	BinaryValue="< 0"
+ConditionEnd
+
+Condition="NoReferencedPresentationStateOrStereometricInstanceOrInstance"
+	Element="ReferencedPresentationStateSequence"						Modifier="Not" ElementPresent=""
+	Element="ReferencedStereometricInstanceSequence"	Operator="And"	Modifier="Not" ElementPresent=""
+	Element="ReferencedInstanceSequence"				Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NoReferencedImageOrStereometricInstanceOrInstance"
+	Element="ReferencedImageSequence"									Modifier="Not" ElementPresent=""
+	Element="ReferencedStereometricInstanceSequence"	Operator="And"	Modifier="Not" ElementPresent=""
+	Element="ReferencedInstanceSequence"				Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NoReferencedPresentationStateOrStereometricInstanceOrImage"
+	Element="ReferencedPresentationStateSequence"						Modifier="Not" ElementPresent=""
+	Element="ReferencedStereometricInstanceSequence"	Operator="And"	Modifier="Not" ElementPresent=""
+	Element="ReferencedImageSequence"					Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NoReferencedPresentationStateOrInstanceOrImage"
+	Element="ReferencedPresentationStateSequence"						Modifier="Not" ElementPresent=""
+	Element="ReferencedInstanceSequence"				Operator="And"	Modifier="Not" ElementPresent=""
+	Element="ReferencedImageSequence"					Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleStructuredDisplayAnnotation"
+	Element="StructuredDisplayTextBoxSequence"			ElementPresent=""
+ConditionEnd
+
+Condition="ViewIsCardiacShortOrLongAxis"
+	Element="ViewCodeSequence"								ElementPresent=""
+	(
+		Element="CodingSchemeDesignator"					ElementPresentWithin="ViewCodeSequence"	StringValue="SRT"
+		Element="CodingSchemeDesignator"	Operator="Or"	ElementPresentWithin="ViewCodeSequence"	StringValue="SNM3"
+		Element="CodingSchemeDesignator"	Operator="Or"	ElementPresentWithin="ViewCodeSequence"	StringValue="99SDM"
+	) Operator="And"
+	(
+		Element="CodeValue"									ElementPresentWithin="ViewCodeSequence" StringValue="G-A186"	# Short Axis
+		Element="CodeValue"					Operator="Or"	ElementPresentWithin="ViewCodeSequence" StringValue="G-A18A"	# Vertical Long Axis
+		Element="CodeValue"					Operator="Or"	ElementPresentWithin="ViewCodeSequence" StringValue="G-A18B"	# Horizontal Long Axis
+	) Operator="And"
+ConditionEnd
+
+Condition="ViewIsNotSpecimen"
+	Element="ViewCodeSequence"								ElementPresent=""
+	(
+		Element="CodingSchemeDesignator"					ElementPresentWithin="ViewCodeSequence"	StringValue="SRT"
+		Element="CodingSchemeDesignator"	Operator="Or"	ElementPresentWithin="ViewCodeSequence"	StringValue="SNM3"
+		Element="CodingSchemeDesignator"	Operator="Or"	ElementPresentWithin="ViewCodeSequence"	StringValue="99SDM"
+	) Operator="And"
+	(
+		Element="CodeValue"									ElementPresentWithin="ViewCodeSequence" StringValue="G-8310"	# tissue specimen from breast
+	) Operator="And"
+ConditionEnd
+
+Condition="UltrasoundAcquisitionGeometryIsApex"
+	Element="UltrasoundAcquisitionGeometry"		StringValue="APEX"
+ConditionEnd
+
+Condition="NeedPatientFrameOfReferenceSource"
+	Element="ImagePositionPatient"							ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ImagePositionPatient"			Operator="Or"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ImageOrientationPatient"		Operator="Or"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="ImageOrientationPatient"		Operator="Or"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PatientFrameOfReferenceSourceIsTable"
+	Element="PatientFrameOfReferenceSource"		StringValue="TABLE"
+ConditionEnd
+
+Condition="PerformedProtocolCodeSequenceIsPresent"
+	Element="PerformedProtocolCodeSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedPositionMeasuringDeviceUsed"
+	Element="VolumetricProperties"									StringValue="VOLUME"
+	Element="VolumeBasedCalculationTechnique"		Operator="And"	StringValue="NONE"
+ConditionEnd
+
+Condition="PerformedProtocolTypeIsStaged"
+	Element="PerformedProtocolType"		StringValue="STAGED"
+ConditionEnd
+
+Condition="AnyDataPathAssignmentIsOtherThanPrimaryPValues"
+	Element="DataPathAssignment"						ElementPresentWithin="DataFrameAssignmentSequence"	StringValue="PRIMARY_SINGLE"
+	Element="DataPathAssignment"		Operator="Or"	ElementPresentWithin="DataFrameAssignmentSequence"	StringValue="SECONDARY_SINGLE"
+	Element="DataPathAssignment"		Operator="Or"	ElementPresentWithin="DataFrameAssignmentSequence"	StringValue="SECONDARY_HIGH"
+	Element="DataPathAssignment"		Operator="Or"	ElementPresentWithin="DataFrameAssignmentSequence"	StringValue="SECONDARY_LOW"
+ConditionEnd
+
+Condition="BlendingLUT1TransferFunctionIsConstant"
+	Element="BlendingLUT1TransferFunction"		StringValue="CONSTANT"
+ConditionEnd
+
+Condition="BlendingLUT2TransferFunctionIsConstant"
+	Element="BlendingLUT2TransferFunction"		StringValue="CONSTANT"
+ConditionEnd
+
+Condition="BlendingLUT1TransferFunctionIsTable"
+	Element="BlendingLUT1TransferFunction"		StringValue="TABLE"
+ConditionEnd
+
+Condition="RGBLUTTransferFunctionIsTable"
+	Element="RGBLUTTransferFunction"			StringValue="TABLE"
+ConditionEnd
+
+Condition="NeedModuleEnhancedPaletteColorLookupTable"
+	Element="DataFrameAssignmentSequence"					ElementPresent=""
+	Element="BlendingLUT1Sequence"							ElementPresent=""
+	Element="BlendingLUT2Sequence"							ElementPresent=""
+	Element="EnhancedPaletteColorLookupTableSequence"		ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleExcludedIntervals"
+	Element="ExcludedIntervalsSequence"						ElementPresent=""
+ConditionEnd
+
+Condition="ImageTypeValue3Localizer"
+	Element="ImageType"								ValueSelector="2"	StringValue="LOCALIZER"
+ConditionEnd
+
+Condition="ImageTypeValue3Label"
+	Element="ImageType"								ValueSelector="2"	StringValue="LABEL"
+ConditionEnd
+
+Condition="NeedModuleICCProfile"
+	Element="ICCProfile"							ElementPresent=""
+ConditionEnd
+
+Condition="NeedModuleOpticalPath"
+	Element="OpticalPathSequence"					ElementPresent=""
+ConditionEnd
+
+Condition="SpecimenReferenceMacroOKInSharedFunctionalGroupSequence"
+	Element="SpecimenReferenceSequence"				Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="SpecimenReferenceSequence"				Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="SpecimenReferenceMacroOKInPerFrameFunctionalGroupSequence"
+	Element="SpecimenReferenceSequence"				Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="SpecimenReferenceSequence"				Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="PlanePositionSlideSequenceNotInSharedFunctionalGroupSequence"
+	Element="PlanePositionSlideSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="PlanePositionSlideSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="PlanePositionSlideSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+
+Condition="OpticalPathIdentificationSequenceNotInSharedFunctionalGroupSequence"
+	Element="OpticalPathIdentificationSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="OpticalPathIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="OpticalPathIdentificationSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="ImageTypeValue3LocalizerOrLabel"
+	Element="ImageType"												ValueSelector="2"	StringValue="LOCALIZER"
+	Element="ImageType"								Operator="Or"	ValueSelector="2"	StringValue="LABEL"
+ConditionEnd
+
+Condition="ExtendedDepthOfFieldIsYes"
+	Element="ExtendedDepthOfField"					StringValue="YES"
+ConditionEnd
+
+Condition="IlluminationColorCodeSequenceNotPresent"
+	Element="IlluminationColorCodeSequence"			Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="IlluminationWaveLengthNotPresent"
+	Element="IlluminationWaveLength"				Modifier="Not"	ElementPresent=""
+ConditionEnd
+
+Condition="NeedICCProfileInOpticalPathSequence"
+	Element="PaletteColorLookupTableSequence"		ElementPresent=""
+	Element="PhotometricInterpretation"				Operator="Or"	Modifier="Not"	StringValueFromRootAttribute="MONOCHROME2"
+ConditionEnd
+
+Condition="NeedZeroVelocityPixelValue"
+	Element="DataType"								StringValue="TISSUE_VELOCITY"
+	Element="DataType"								StringValue="FLOW_VELOCITY"
+	Element="DataType"								StringValue="DIRECTION_POWER"
+ConditionEnd
+
+Condition="SpatialTransformOfDoseIsRigidOrNonRigid"
+	Element="SpatialTransformOfDose"				StringValue="RIGID"
+	Element="SpatialTransformOfDose"				StringValue="NON_RIGID"
+ConditionEnd
+
+# does not check that EVERY PerFrameFunctionalGroupsSequence item has it, if not in Shared, but better than no check at all :(
+Condition="PixelSpacingNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndVolumetricPropertiesIsNotDistortedSampledOrSegmentationWithFrameOfReference"
+	Element="PixelSpacing"											Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PixelSpacing"							Operator="And"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		(
+			Element="VolumetricProperties"							Modifier="Not" StringValueFromRootAttribute="DISTORTED"
+			Element="VolumetricProperties"			Operator="And"	Modifier="Not" StringValueFromRootAttribute="SAMPLED"
+		) Operator="Or"
+		(
+			Element="SOPClassUID"									StringConstantFromRootAttribute="SegmentationStorageSOPClassUID"
+			Element="FrameOfReferenceUID"			Operator="And"	ElementPresentInRoot=""
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+# does not check that EVERY PerFrameFunctionalGroupsSequence item has it, if not in Shared, but better than no check at all :(
+Condition="SliceThicknessNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndVolumetricPropertiesIsVolumeOrSampledOrSegmentationWithFrameOfReference"
+	Element="SliceThickness"										Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="SliceThickness"						Operator="And"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="VolumetricProperties"								StringValueFromRootAttribute="VOLUME"
+		Element="VolumetricProperties"				Operator="Or"	StringValueFromRootAttribute="SAMPLED"
+		(
+			Element="SOPClassUID"									StringConstantFromRootAttribute="SegmentationStorageSOPClassUID"
+			Element="FrameOfReferenceUID"			Operator="And"	ElementPresentInRoot=""
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+#cannot actually check FrameType in corresponding per-frame functional group item, so check ImageType instead :(
+Condition="ImagePositionPatientNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndEitherFrameTypeIsOriginalAndVolumetricPropertiesIsNotDistortedOrSegmentationWithFrameOfReference"
+	Element="ImagePositionPatient"									Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ImagePositionPatient"					Operator="And"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		(
+			Element="ImageType"										ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+			Element="VolumetricProperties"			Operator="And"	Modifier="Not" StringValueFromRootAttribute="DISTORTED"
+		) Operator="Or"
+		(
+			Element="SOPClassUID"									StringConstantFromRootAttribute="SegmentationStorageSOPClassUID"
+			Element="FrameOfReferenceUID"			Operator="And"	ElementPresentInRoot=""
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+#cannot actually check FrameType in corresponding per-frame functional group item, so check ImageType instead :(
+Condition="ImageOrientationPatientNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndEitherFrameTypeIsOriginalAndVolumetricPropertiesIsNotDistortedOrSegmentationWithFrameOfReference"
+	Element="ImageOrientationPatient"								Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="ImageOrientationPatient"				Operator="And"	Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		(
+			Element="ImageType"										ValueSelector="0" StringValueFromRootAttribute="ORIGINAL"
+			Element="VolumetricProperties"			Operator="And"	Modifier="Not" StringValueFromRootAttribute="DISTORTED"
+		) Operator="Or"
+		(
+			Element="SOPClassUID"									StringConstantFromRootAttribute="SegmentationStorageSOPClassUID"
+			Element="FrameOfReferenceUID"			Operator="And"	ElementPresentInRoot=""
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+Condition="BitsStoredPresent"
+	Element="BitsStored"	ElementPresent=""
+ConditionEnd
+
+Condition="HighBitPresent"
+	Element="HighBit"	ElementPresent=""
+ConditionEnd
+
+Condition="PixelRepresentationPresent"
+	Element="PixelRepresentation"	ElementPresent=""
+ConditionEnd
+
+Condition="PlanarConfigurationPresent"
+	Element="PlanarConfiguration"	ElementPresent=""
+ConditionEnd
+
+Condition="FloatPixelPaddingValuePresent"
+	Element="FloatPixelPaddingValue"	ElementPresent=""
+ConditionEnd
+
+Condition="DoubleFloatPixelPaddingValuePresent"
+	Element="DoubleFloatPixelPaddingValue"	ElementPresent=""
+ConditionEnd
+
+Condition="ImageTypeValue3IsTissueIntensity"
+	Element="ImageType"				ValueSelector="2" StringValueFromRootAttribute="TISSUE_INTENSITY"
+ConditionEnd
+
+Condition="ImageTypeValue3IsSoundSpeed"
+	Element="ImageType"				ValueSelector="2" StringValueFromRootAttribute="SOUND_SPEED"
+ConditionEnd
+
+Condition="ImageTypeValue3IsAttenuation"
+	Element="ImageType"				ValueSelector="2" StringValueFromRootAttribute="ATTENUATION"
+ConditionEnd
+
+Condition="ImageTypeValue3IsSoundSpeedOrAttenuation"
+	Element="ImageType"								ValueSelector="2" StringValueFromRootAttribute="SOUND_SPEED"
+	Element="ImageType"				Operator="Or"	ValueSelector="2" StringValueFromRootAttribute="ATTENUATION"
+ConditionEnd
+
+Condition="VisualAcuityTypeCodeSequencePresent"
+	Element="VisualAcuityTypeCodeSequence"	ElementPresent=""
+ConditionEnd
+
+Condition="RightLensSequenceAndLeftLensSequenceAbsent"
+	Element="RightLensSequence"					Modifier="Not" ElementPresent=""
+	Element="LeftLensSequence"	Operator="And"	Modifier="Not" ElementPresent=""
+ConditionEnd
+
+Condition="OptotypeIsLettersNumbersOrPictures"
+	Element="Optotype"								StringValue="LETTERS"
+	Element="Optotype"				Operator="Or"	StringValue="NUMBERS"
+	Element="Optotype"				Operator="Or"	StringValue="PICTURES"
+ConditionEnd
+
+Condition="OphthalmicAxialMeasurementsDeviceTypeIsUltrasound"
+	Element="OphthalmicAxialMeasurementsDeviceType"	StringValueFromRootAttribute="ULTRASOUND"
+ConditionEnd
+
+Condition="OphthalmicAxialMeasurementsDeviceTypeIsOptical"
+	Element="OphthalmicAxialMeasurementsDeviceType"	StringValueFromRootAttribute="OPTICAL"
+ConditionEnd
+
+Condition="MydriaticAgentConcentrationPresent"
+	Element="MydriaticAgentConcentration"	ElementPresent=""
+ConditionEnd
+
+Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsTotalLength"
+	Element="OphthalmicAxialLengthMeasurementsType"			StringValueAbove="TOTAL LENGTH"
+ConditionEnd
+
+Condition="OphthalmicAxialLengthMeasurementsTypeIsTotalLength"
+	Element="OphthalmicAxialLengthMeasurementsType"			StringValue="TOTAL LENGTH"
+ConditionEnd
+
+Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsLengthSummation"
+	Element="OphthalmicAxialLengthMeasurementsType"			StringValueAbove="LENGTH SUMMATION"
+ConditionEnd
+
+Condition="OphthalmicAxialLengthMeasurementsTypeIsLengthSummation"
+	Element="OphthalmicAxialLengthMeasurementsType"			StringValue="LENGTH SUMMATION"
+ConditionEnd
+
+Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsSegmentalLength"
+	Element="OphthalmicAxialLengthMeasurementsType"			StringValueAbove="SEGMENTAL LENGTH"
+ConditionEnd
+
+Condition="OphthalmicAxialLengthMeasurementsTypeIsSegmentalLength"
+	Element="OphthalmicAxialLengthMeasurementsType"			StringValue="SEGMENTAL LENGTH"
+ConditionEnd
+
+Condition="RefractiveProcedureOccurredIsYes"
+	Element="RefractiveProcedureOccurred"			StringValue="YES"
+ConditionEnd
+
+# specified in the order they occur in PS3.3 Annex A in order to simplify addition of new IODs ... is NOT of the list that ARE multi-frame
+Condition="ReferencedFrameNumberPresentAndReferencedSOPClassUIDIsNotMultiFrame"
+	Element="ReferencedFrameNumber"		ElementPresent=""
+	(
+		Element="ReferencedSOPClassUID"						StringConstant="NuclearMedicineImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="UltrasoundMultiframeImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="MultiframeSingleBitSecondaryCaptureImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="MultiframeGrayscaleByteSecondaryCaptureImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="MultiframeGrayscaleWordSecondaryCaptureImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="MultiframeTrueColorSecondaryCaptureImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="XRayAngiographicImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="XRayAngiographicBiplaneImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="XRayRadioFluoroscopicImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="RTImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="RTDoseStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="VideoEndoscopicImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="VideoMicroscopicImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="VideoPhotographicImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="VLWholeSlideMicroscopyImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedMRImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="MRSpectroscopyStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedMRColorImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedCTImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="OphthalmicPhotography8BitImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="OphthalmicPhotography16BitImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedXAImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedXRFImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="SegmentationStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="OphthalmicTomographyImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="XRay3DAngiographicImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="XRay3DCraniofacialImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="BreastTomosynthesisImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedPETImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="EnhancedUSVolumeStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="IVOCTImageStorageForProcessingSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="IVOCTImageStorageForPresentationSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="LegacyConvertedEnhancedCTImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="LegacyConvertedEnhancedMRImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="LegacyConvertedEnhancedPETImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="BreastProjectionXRayImageStorageForPresentationSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="BreastProjectionXRayImageStorageForProcessingSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="ParametricMapStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="WideFieldOphthalmicPhotographyStereographicProjectionImageStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="WideFieldOphthalmicPhotography3DCoordinatesImageStorageSOPClassUID"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="ReferencedSegmentNumberPresentAndReferencedSOPClassUIDIsNotSegmentationOrSurfaceSegmentation"
+	Element="ReferencedSegmentNumber"	ElementPresent=""
+	(
+		Element="ReferencedSOPClassUID"						StringConstant="SurfaceSegmentationStorageSOPClassUID"
+		Element="ReferencedSOPClassUID"		Operator="Or"	StringConstant="SegmentationStorageSOPClassUID"
+	) Modifier="Not" Operator="And"
+ConditionEnd
+
+Condition="NeedDerivationImageMacroInSharedFunctionalGroupSequenceForBreastProjection"
+	Element="DerivationImageSequence"				Modifier="Not"	ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	(
+		Element="ImageType"							ValueSelector="0"	StringValueFromRootAttribute="DERIVED"
+		(
+			Element="ImageType"						ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+			Element="PresentationIntentType"		Operator="And"		StringValueFromRootAttribute="FOR PRESENTATION"
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+Condition="NeedDerivationImageMacroInPerFrameFunctionalGroupSequenceForBreastProjection"
+	Element="DerivationImageSequence"				Modifier="Not"	ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	(
+		Element="ImageType"							ValueSelector="0"	StringValueFromRootAttribute="DERIVED"
+		(
+			Element="ImageType"						ValueSelector="0"	StringValueFromRootAttribute="ORIGINAL"
+			Element="PresentationIntentType"		Operator="And"		StringValueFromRootAttribute="FOR PRESENTATION"
+		) Operator="Or"
+	) Operator="And"
+ConditionEnd
+
+# real world ... treat as U ...
+Condition="NeedBreastXRayPositionerMacroInSharedFunctionalGroupSequence"
+	Element="PositionerPositionSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="PositionerPositionSequence"			Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+# real world ... treat as U ...
+Condition="NeedBreastXRayPositionerMacroInPerFrameFunctionalGroupSequence"
+	Element="PositionerPositionSequence"			Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="PositionerPositionSequence"			Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+# real world ... treat as U ...
+Condition="NeedBreastXRayDetectorMacroInSharedFunctionalGroupSequence"
+	Element="DetectorPositionSequence"				Operator="And" Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="DetectorPositionSequence"				Operator="Or" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+# real world ... treat as U ...
+Condition="NeedBreastXRayDetectorMacroInPerFrameFunctionalGroupSequence"
+	Element="DetectorPositionSequence"				Operator="And" Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="DetectorPositionSequence"				Operator="Or" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayGeometrySequenceNotInPerFrameFunctionalGroupSequence"
+	Element="XRayGeometrySequence"					Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayGeometrySequenceNotInSharedFunctionalGroupSequence"
+	Element="XRayGeometrySequence"					Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayAcquisitionDoseSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="XRayAcquisitionDoseSequence"			Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayAcquisitionDoseSequenceNotInSharedFunctionalGroupSequence"
+	Element="XRayAcquisitionDoseSequence"			Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IsocenterReferenceSystemSequenceNotInPerFrameFunctionalGroupSequence"
+	Element="IsocenterReferenceSystemSequence"		Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="IsocenterReferenceSystemSequenceNotInSharedFunctionalGroupSequence"
+	Element="IsocenterReferenceSystemSequence"		Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayGridMacroOKInPerFrameFunctionalGroupSequence"
+	Element="XRayGridSequence"						Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="XRayGridSequence"						Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayGridMacroOKInSharedFunctionalGroupSequence"
+	Element="XRayGridSequence"						Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="XRayGridSequence"						Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFilterMacroOKInPerFrameFunctionalGroupSequence"
+	Element="XRayFilterSequence"					Modifier="Not" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+	Element="XRayFilterSequence"					Operator="And" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+ConditionEnd
+
+Condition="XRayFilterMacroOKInSharedFunctionalGroupSequence"
+	Element="XRayFilterSequence"					Modifier="Not" ElementPresentInPathFromRoot="PerFrameFunctionalGroupsSequence"
+	Element="XRayFilterSequence"					Operator="And" ElementPresentInPathFromRoot="SharedFunctionalGroupsSequence"
+ConditionEnd
diff --git a/libsrc/standard/elmdict/Imakefile b/libsrc/standard/elmdict/Imakefile
new file mode 100755
index 0000000..c4b98b0
--- /dev/null
+++ b/libsrc/standard/elmdict/Imakefile
@@ -0,0 +1,39 @@
+all::
+
+sort:
+	for i in	\
+		acrnema	\
+		dicom3	\
+		philips	\
+		siemens	\
+		gems	\
+		retired	\
+		compress	\
+		vli	\
+		wave	\
+		softcopy	\
+		sr	\
+		security	\
+		mr \
+		papyrus	\
+		toshiba	\
+		hitachi	\
+		isg	\
+		elscint	\
+		acuson	\
+		camtron	\
+		agfa	\
+		picker	\
+		spi	\
+		other	\
+		dicos	\
+		diconde	\
+		dicondep	\
+	; do	\
+		rm -f $$i.tpl.bak;	\
+		mv $$i.tpl $$i.tpl.bak;	\
+		$(SORT) -b -n +0 -1 +4 -5 <$$i.tpl.bak >$$i.tpl;	\
+	done
+
+
+
diff --git a/libsrc/standard/elmdict/acuson.tpl b/libsrc/standard/elmdict/acuson.tpl
new file mode 100755
index 0000000..2efcc78
--- /dev/null
+++ b/libsrc/standard/elmdict/acuson.tpl
@@ -0,0 +1,105 @@
+(0009,0000) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0001) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0002) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0003) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0004) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0005) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0006) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0007) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0008) VERS="ACU"  VR="LT"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0009) VERS="ACU"  VR="LT"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,000a) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,000b) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,000c) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,000d) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,000e) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,000f) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"	Keyword="?"			Name="?"
+(0009,0010) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"			Keyword="?"				Name="?"
+(0009,0011) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"			Keyword="?"				Name="?"
+(0009,0012) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"			Keyword="?"				Name="?"
+(0009,0013) VERS="ACU"	VR="IS"   VM="1"	Owner="ACUSON"			Keyword="?"				Name="?"
+(0009,0014) VERS="ACU"	VR="LT"   VM="1"	Owner="ACUSON"			Keyword="?"				Name="?"
+(0009,0015) VERS="ACU"	VR="UN"   VM="1"	Owner="ACUSON"			Keyword="?"				Name="?"
+
+(0009,0000) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:0910"				Keyword="?"				Name="?"
+(0009,0001) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:0910"				Keyword="?"				Name="?"
+(0009,0002) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:0910"				Keyword="PatientRegistrationCustomField1"	Name="Patient Registration Custom Field 1"
+(0009,0003) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:0910"				Keyword="PatientRegistrationCustomField2"	Name="Patient Registration Custom Field 2"
+(0009,0004) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:0910"				Keyword="Indications"	Name="Indications"
+(0009,000f) VERS="ACU" VR="LT"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:0910"				Keyword="?"				Name="?"
+
+(7fdf,0002) VERS="ACU" VR="US"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,000b) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,000c) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0020) VERS="ACU" VR="FL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0022) VERS="ACU" VR="FL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+
+(7fdf,0000) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0001) VERS="ACU" VR="US"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,000d) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0010) VERS="ACU" VR="SH"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0024) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0025) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0026) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0027) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0028) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0029) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,002a) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,002b) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,002c) VERS="ACU" VR="UL"   VM="1-n"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0030) VERS="ACU" VR="SQ"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0031) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0032) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0033) VERS="ACU" VR="FL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0034) VERS="ACU" VR="FL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0035) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0036) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0037) VERS="ACU" VR="FL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0038) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0050) VERS="ACU" VR="SH"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0052) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0054) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0060) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0061) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0062) VERS="ACU" VR="FD"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0063) VERS="ACU" VR="FD"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0064) VERS="ACU" VR="FD"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0065) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0066) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0067) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0068) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0069) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,006a) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,006b) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,006c) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0072) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0073) VERS="ACU" VR="FD"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0074) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0075) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0076) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0077) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0078) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0079) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,007a) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,007b) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,007c) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,007d) VERS="ACU" VR="LO"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,007e) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,007f) VERS="ACU" VR="SL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0080) VERS="ACU" VR="UL"   VM="1-n"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0081) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0082) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0083) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,0085) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,0089) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,008a) VERS="ACU" VR="FD"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,008b) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,008c) VERS="ACU" VR="UL"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,008d) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"		Name="?"
+(7fdf,0086) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,0088) VERS="ACU" VR="FD"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,00f1) VERS="ACU" VR="UL"   VM="1-n"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+(7fdf,00f5) VERS="ACU" VR="IS"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7f10"				Keyword="?"				Name="?"
+
+(7fdf,0000) VERS="ACU" VR="OB"   VM="1"	Owner="ACUSON:1.2.840.113680.1.0:7ffe"				Keyword="?"				Name="?"
+
diff --git a/libsrc/standard/elmdict/agfa.tpl b/libsrc/standard/elmdict/agfa.tpl
new file mode 100755
index 0000000..3c6042f
--- /dev/null
+++ b/libsrc/standard/elmdict/agfa.tpl
@@ -0,0 +1,210 @@
+(0009,0010) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="?"				Name="?"
+(0009,0011) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="?"				Name="?"
+(0009,0013) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="?"				Name="?"
+(0009,0014) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="?"				Name="?"
+(0009,0015) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="?"				Name="?"
+
+(0011,0020) VERS="AGFA"	VR="LO"   VM="1"	Owner="AgilityRuntime"		Keyword="?"				Name="?"
+(0011,0021) VERS="AGFA"	VR="LO"   VM="1"	Owner="AgilityRuntime"		Keyword="?"				Name="?"
+(0011,0022) VERS="AGFA"	VR="LO"   VM="1"	Owner="AgilityRuntime"		Keyword="?"				Name="?"
+
+(0011,0011) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA-AG_HPState"		Keyword="?"				Name="?"
+
+(0019,00a0) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"		Keyword="?"				Name="?"
+(0019,00a1) VERS="AGFA"	VR="FL"   VM="1"	Owner="AGFA-AG_HPState"		Keyword="?"				Name="?"
+(0019,00a2) VERS="AGFA"	VR="FL"   VM="1"	Owner="AGFA-AG_HPState"		Keyword="?"				Name="?"
+(0019,00a3) VERS="AGFA"	VR="FL"   VM="1"	Owner="AGFA-AG_HPState"		Keyword="?"				Name="?"
+(0019,00a4) VERS="AGFA"	VR="FL"   VM="1"	Owner="AGFA-AG_HPState"		Keyword="?"				Name="?"
+
+(0019,0005) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA"		Keyword="CassetteDataStream"					Name="Cassette Data Stream"
+(0019,0010) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA"		Keyword="ImageProcessingParameters"				Name="Image Processing Parameters"
+(0019,0011) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="IdentificationData"					Name="Identification Data"
+(0019,0013) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="SensitometryName"						Name="Sensitometry Name"
+(0019,0014) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA"		Keyword="WindowLevelList"						Name="Window Level List"
+(0019,0015) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="DoseMonitoring"						Name="Dose Monitoring"
+(0019,0016) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="OtherInfo"								Name="Other Info"
+(0019,001a) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="ClippedExposureDeviation"				Name="Clipped Exposure Deviation"
+(0019,001b) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA"		Keyword="Logarithmic PLT Full Scale"			Name="Logarithmic PLT Full Scale"
+(0019,0060) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA"		Keyword="TotalNumberSeries"						Name="Total Number Series"
+(0019,0061) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA"		Keyword="SessionNumber"							Name="Session Number"
+(0019,0062) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA"		Keyword="IDStationName"							Name="ID Station Name"
+(0019,0065) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA"		Keyword="NumberOfImagesInStudyToBeTransmitted"	Name="Number of Images in Study to be Transmitted"
+(0019,0070) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA"		Keyword="TotalNumberImages"						Name="Total Number Images"
+(0019,0080) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA"		Keyword="GeometricalTransformations"			Name="Geometrical Transformations"
+(0019,0081) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA"		Keyword="RoamOrigin"							Name="Roam Origin"
+(0019,0082) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA"		Keyword="ZoomFactor"							Name="Zoom Factor"
+(0019,0093) VERS="AGFA"	VR="CS"   VM="1"	Owner="AGFA"		Keyword="Status"								Name="Status"
+
+(0019,0030) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="DataStreamFromCassette"	Name="Data stream from cassette"
+(0019,0030) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="SetOfDestinationTypes"		Name="Set of destination types"
+(0019,0040) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="SetOfDestinationIds"		Name="Set of destination Ids"
+(0019,0050) VERS="AGFA"	VR="ST"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="SetOfProcessingCodes"		Name="Set of processing codes"
+(0019,0060) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="NumberOfSeriesInStudy"		Name="Number of series in study"
+(0019,0061) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="SessionNumber"			Name="Session Number"
+(0019,0062) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="IDStationName"			Name="ID station name"
+(0019,0070) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="NumberOfImagesInSeries"	Name="Number of images in series"
+(0019,0071) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="BreakCondition"		Name="Break condition"
+(0019,0072) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="WaitOrHoldFlag"		Name="Wait (or Hold) flag"
+(0019,0073) VERS="AGFA"	VR="US"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="ScanResFlag"			Name="ScanRes flag"
+(0019,0074) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="OperationCode"			Name="Operation code"
+(0019,0095) VERS="AGFA"	VR="CS"   VM="1"	Owner="AGFA_ADC_Compact"	Keyword="ImageQuality"			Name="Image quality"
+
+(0019,0007) VERS="AGFA"	VR="CS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,0009) VERS="AGFA"	VR="SQ"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,0021) VERS="AGFA"	VR="FL"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,0028) VERS="AGFA"	VR="CS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,00f0) VERS="AGFA"	VR="LO"   VM="1"	Owner="Agfa ADC NX"	Keyword="UserDefinedField1"	Name="User Defined field 1"
+(0019,00f1) VERS="AGFA"	VR="LO"   VM="1"	Owner="Agfa ADC NX"	Keyword="UserDefinedField2"	Name="User Defined field 2"
+(0019,00f2) VERS="AGFA"	VR="LO"   VM="1"	Owner="Agfa ADC NX"	Keyword="UserDefinedField3"	Name="User Defined field 3"
+(0019,00f3) VERS="AGFA"	VR="LO"   VM="1"	Owner="Agfa ADC NX"	Keyword="UserDefinedField4"	Name="User Defined field 4"
+(0019,00f4) VERS="AGFA"	VR="LO"   VM="1"	Owner="Agfa ADC NX"	Keyword="UserDefinedField5"	Name="User Defined field 5"
+(0019,00f5) VERS="AGFA"	VR="CS"   VM="1"	Owner="Agfa ADC NX"	Keyword="CassetteOrientation"	Name="Cassette Orientation"
+(0019,00f6) VERS="AGFA"	VR="DS"   VM="1"	Owner="Agfa ADC NX"	Keyword="PlateSensitivity"	Name="Plate Sensitivity"
+(0019,00f7) VERS="AGFA"	VR="DS"   VM="1"	Owner="Agfa ADC NX"	Keyword="PlateErasability"	Name="Plate Erasability"
+(0019,00f8) VERS="AGFA"	VR="IS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,00fa) VERS="AGFA"	VR="IS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,00fc) VERS="AGFA"	VR="IS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,00fd) VERS="AGFA"	VR="CS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+(0019,00fe) VERS="AGFA"	VR="CS"   VM="1"	Owner="Agfa ADC NX"	Keyword="?"	Name="?"
+
+(0031,0000) VERS="MIT"  VR="CS"   VM="1"	Owner="AGFA PACS Archive Mirroring 1.0"	Keyword="?"		Name="?"
+(0031,0001) VERS="MIT"  VR="UL"   VM="1"	Owner="AGFA PACS Archive Mirroring 1.0"	Keyword="?"		Name="?"
+
+(0029,0000) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="Rotation"			Name="Rotation"
+(0029,0001) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="WindowWidth"		Name="Window Width"
+(0029,0002) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="WindowCentre"		Name="Window Centre"
+(0029,0003) VERS="MIT"  VR="IS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="Invert"			Name="Invert"
+(0029,0004) VERS="MIT"  VR="IS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="HasTabstop"		Name="Has Tabstop"
+(0029,0005) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="SmoothRotation"	Name="Smooth Rotation"
+(0029,0010) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="?"		Name="?"
+(0029,0011) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="?"		Name="?"
+(0029,0012) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="?"		Name="?"
+(0029,0013) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA PRESENTATION 1.0"	Keyword="?"		Name="?"
+
+(0029,0000) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT DOCUMENT 1.0"	Keyword="IMPAXObjectDocument"		Name="IMPAX Object Document"	RenderAsString="true"
+(0029,0001) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT DOCUMENT 1.0"	Keyword="IMPAXMarkupXMLStored"		Name="IMPAX Markup XML Stored"	RenderAsString="true"
+
+(0029,0000) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup1"		Name="Markup1"	RenderAsString="true"
+(0029,0001) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup2"		Name="Markup2"	RenderAsString="true"
+(0029,0002) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup3"		Name="Markup3"	RenderAsString="true"
+(0029,0003) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup4"		Name="Markup4"	RenderAsString="true"
+(0029,0004) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup5"		Name="Markup5"	RenderAsString="true"
+(0029,0005) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup6"		Name="Markup6"	RenderAsString="true"
+(0029,0006) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup7"		Name="Markup7"	RenderAsString="true"
+(0029,0007) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup8"		Name="Markup8"	RenderAsString="true"
+(0029,0008) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup9"		Name="Markup9"	RenderAsString="true"
+(0029,0009) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup10"		Name="Markup10"	RenderAsString="true"
+(0029,0010) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup11"		Name="Markup11"	RenderAsString="true"
+(0029,0011) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup12"		Name="Markup12"	RenderAsString="true"
+(0029,0012) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup13"		Name="Markup13"	RenderAsString="true"
+(0029,0013) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup14"		Name="Markup14"	RenderAsString="true"
+(0029,0014) VERS="MIT"  VR="OB"   VM="1-n"	Owner="MITRA MARKUP 1.0"	Keyword="Markup15"		Name="Markup14"	RenderAsString="true"
+
+(0029,0011) VERS="AGFA"    VR="CS"   VM="1"	Owner="AgilityRuntime"			Keyword="?"							Name="?"
+(0029,0012) VERS="AGFA"    VR="US"   VM="1"	Owner="AgilityRuntime"			Keyword="?"							Name="?"
+(0029,0013) VERS="AGFA"    VR="US"   VM="1"	Owner="AgilityRuntime"			Keyword="?"							Name="?"
+(0029,0014) VERS="AGFA"    VR="US"   VM="1"	Owner="AgilityRuntime"			Keyword="?"							Name="?"
+(0029,001f) VERS="AGFA"    VR="US"   VM="1"	Owner="AgilityRuntime"			Keyword="?"							Name="?"
+
+(0029,001f) VERS="AGFA"	VR="US"   VM="1"	Owner="AgilityRuntime"		Keyword="?"				Name="?"
+
+(0031,0020) VERS="MIT"  VR="IS"   VM="1"	Owner="MITRA LINKED ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+
+(0033,0002) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0004) VERS="MIT"  VR="CS"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0006) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0008) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,000a) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,000c) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,000e) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0013) VERS="MIT"  VR="PN"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0014) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0015) VERS="MIT"  VR="OB"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0016) VERS="MIT"  VR="PN"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0019) VERS="MIT"  VR="PN"   VM="1"	Owner="MITRA OBJECT UTF8 ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+
+(0033,0002) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA OBJECT ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0004) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA OBJECT ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0006) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA OBJECT ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,0008) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA OBJECT ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+(0033,000a) VERS="MIT"  VR="LO"   VM="1"	Owner="MITRA OBJECT ATTRIBUTES 1.0"	Keyword="?"		Name="?"
+
+(0071,0018) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,0019) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,001a) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,001c) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,001e) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,0020) VERS="AGFA"	VR="FL"   VM="1-n"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,0021) VERS="AGFA"	VR="FD"   VM="1-n"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,0022) VERS="AGFA"	VR="FD"   VM="1-n"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,0023) VERS="AGFA"	VR="FD"   VM="1-n"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,0024) VERS="AGFA"	VR="FD"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,002b) VERS="AGFA"	VR="FD"   VM="1-n"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,002c) VERS="AGFA"	VR="FD"   VM="3"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0071,002d) VERS="AGFA"	VR="FD"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+
+(0071,0001) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0002) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0003) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0005) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0006) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0007) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0008) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0009) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,000a) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0010) VERS="AGFA"	VR="FL"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0011) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0012) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0013) VERS="AGFA"	VR="US"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0014) VERS="AGFA"	VR="US"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0015) VERS="AGFA"	VR="FD"   VM="1-n"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0016) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0017) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0018) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0019) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,001b) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,001c) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,001d) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0022) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,002c) VERS="AGFA"	VR="ST"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,002d) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,002e) VERS="AGFA"	VR="US"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0050) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0051) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0052) VERS="AGFA"	VR="LT"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0053) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0054) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0055) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0056) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0057) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0059) VERS="AGFA"	VR="FL"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,005a) VERS="AGFA"	VR="FL"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,005b) VERS="AGFA"	VR="FL"   VM="2"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,005c) VERS="AGFA"	VR="FL"   VM="4"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,005d) VERS="AGFA"	VR="CS"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+(0071,0060) VERS="AGFA"	VR="FD"   VM="1"	Owner="AgilityOverlay"	Keyword="?"		Name="?"
+
+(0073,0023) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0073,0024) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0073,0028) VERS="AGFA"	VR="SQ"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0073,0080) VERS="AGFA"	VR="FL"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+
+(0075,0010) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+
+(0087,0001) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0002) VERS="AGFA"	VR="LO"   VM="1"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0003) VERS="AGFA"	VR="SL"   VM="2"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0004) VERS="AGFA"	VR="SL"   VM="2"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0005) VERS="AGFA"	VR="FD"   VM="2"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0006) VERS="AGFA"	VR="FD"   VM="2"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0007) VERS="AGFA"	VR="FD"   VM="2"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+(0087,0008) VERS="AGFA"	VR="FD"   VM="2"	Owner="AGFA-AG_HPState"	Keyword="?"		Name="?"
+
+(0035,0000) VERS="AGFA"	VR="SH"   VM="1"	Owner="AGFA KOSD 1.0"	Keyword="?"		Name="?"
+(0035,0003) VERS="AGFA"	VR="LT"   VM="1"	Owner="AGFA KOSD 1.0"	Keyword="?"		Name="?"
+
+(2e13,0010) VERS="AGFA"	VR="IS"   VM="1"	Owner="agfa/displayableImages"	Keyword="?"		Name="?"
+(2e13,0011) VERS="AGFA"	VR="IS"   VM="1"	Owner="agfa/displayableImages"	Keyword="?"		Name="?"
+
+(7fdb,0099) VERS="AGFA"	VR="LO"   VM="1"	Owner="agfa/xeroverse"	Keyword="?"		Name="?"
+
diff --git a/libsrc/standard/elmdict/camtron.tpl b/libsrc/standard/elmdict/camtron.tpl
new file mode 100755
index 0000000..5033f2c
--- /dev/null
+++ b/libsrc/standard/elmdict/camtron.tpl
@@ -0,0 +1,36 @@
+(0009,0004) VERS="CMT"	VR="IS"   VM="1"	Owner="Camtronics image level data"		Keyword="?"				Name="?"
+(0009,0006) VERS="CMT"	VR="IS"   VM="1"	Owner="Camtronics image level data"		Keyword="?"				Name="?"
+(0009,0009) VERS="CMT"	VR="LO"   VM="1"	Owner="Camtronics image level data"		Keyword="?"				Name="?"
+(0009,0016) VERS="CMT"	VR="AE"   VM="1"	Owner="Camtronics image level data"		Keyword="?"				Name="?"
+(0009,0017) VERS="CMT"	VR="CS"   VM="1"	Owner="Camtronics image level data"		Keyword="?"				Name="?"
+(0009,0018) VERS="CMT"	VR="IS"   VM="1"	Owner="Camtronics image level data"		Keyword="?"				Name="?"
+
+(0009,0000) VERS="CMT"	VR="CS"   VM="1"	Owner="QCA Results"		Keyword="AnalysisType"										Name="Analysis Type"
+(0009,0004) VERS="CMT"	VR="LO"   VM="1"	Owner="QCA Results"		Keyword="SegmentName"										Name="Segment Name"
+(0009,0012) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureCatheterSize"							Name="Pre-procedure Catheter Size"
+(0009,0013) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureReferenceDiameter"						Name="Pre-procedure Reference Diameter"
+(0009,0014) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureMinimumLumenDiameter"					Name="Pre-procedure Minimum Lumen Diameter"
+(0009,0015) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureAverageDiameter"						Name="Pre-procedure Average Diameter"
+(0009,0016) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureStenosisLength"						Name="Pre-procedure Stenosis Length"
+(0009,0017) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureStenosisPercentage"					Name="Pre-procedure Stenosis %"
+(0009,0018) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PreProcedureGeometricAreaReductionPercentage"		Name="Pre-procedure Geometric Area Reduction %"
+(0009,0022) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureCatheterSize"							Name="Post-procedure Catheter Size"
+(0009,0023) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureReferenceDiameter"					Name="Post-procedure Reference Diameter"
+(0009,0024) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureMinimumLumenDiameter"					Name="Post-procedure Minimum Lumen Diameter"
+(0009,0025) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureAverageDiameter"						Name="Post-procedure Average Diameter"
+(0009,0026) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureStenosisLength"						Name="Post-procedure Stenosis Length"
+(0009,0027) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureStenosisPercentage"					Name="Post-procedure Stenosis %"
+(0009,0028) VERS="CMT"	VR="DS"   VM="1"	Owner="QCA Results"		Keyword="PostProcedureGeometricAreaReductionPercentage"		Name="Post-procedure Geometric Area Reduction %"
+
+(0029,0010) VERS="CMT"	VR="LT"   VM="1"	Owner="CAMTRONICS IP"		Keyword="?"				Name="?"
+(0029,0010) VERS="CMT"	VR="LT"   VM="1"	Owner="CAMTRONICS"		Keyword="Commentline"			Name="Commentline"
+(0029,0020) VERS="CMT"	VR="DS"   VM="1"	Owner="CAMTRONICS"		Keyword="EdgeEnhancementCoefficient"	Name="Edge Enhancement Coefficient"
+(0029,0020) VERS="CMT"	VR="UN"   VM="1"	Owner="CAMTRONICS IP"		Keyword="?"				Name="?"
+(0029,0030) VERS="CMT"	VR="UN"   VM="1"	Owner="CAMTRONICS IP"		Keyword="?"				Name="?"
+(0029,0040) VERS="CMT"	VR="UN"   VM="1"	Owner="CAMTRONICS IP"		Keyword="?"				Name="?"
+(0029,0050) VERS="CMT"	VR="LT"   VM="1"	Owner="CAMTRONICS"		Keyword="SceneText"			Name="Scene Text"
+(0029,0060) VERS="CMT"	VR="LT"   VM="1"	Owner="CAMTRONICS"		Keyword="ImageText"			Name="Image Text"
+(0029,0070) VERS="CMT"	VR="IS"   VM="1"	Owner="CAMTRONICS"		Keyword="PixelShiftHorizontal"		Name="Pixel Shift Horizontal"
+(0029,0080) VERS="CMT"	VR="IS"   VM="1"	Owner="CAMTRONICS"		Keyword="PixelShiftVertical"		Name="Pixel Shift Vertical"
+(0029,0090) VERS="CMT"	VR="IS"   VM="1"	Owner="CAMTRONICS"		Keyword="?"				Name="?"
+
diff --git a/libsrc/standard/elmdict/dicom3.tpl b/libsrc/standard/elmdict/dicom3.tpl
new file mode 100644
index 0000000..f0da0a4
--- /dev/null
+++ b/libsrc/standard/elmdict/dicom3.tpl
@@ -0,0 +1,3802 @@
+# ^([(][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F],[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][)])[ \t]+(.*)[ \t]+([A-Za-z]+)[ \t]+([A-Z][A-Z])[ \t]+([0-9n-]+)[ \t]*$
+# \1 VERS="3"	VR="\4"   VM="\5"	Keyword="\3"				Name="\2"
+# $1 VERS="3"	VR="$4"   VM="$5"	Keyword="$3"				Name="$2"
+(0000,0000) VERS="3"	VR="UL"   VM="1"	Keyword="CommandGroupLength"			Name="Command Group Length"
+(0000,0001) VERS="RET"	VR="UL"   VM="1"	Keyword="CommandLengthToEnd"			Name="Command Length to End"
+(0000,0002) VERS="3"	VR="UI"   VM="1"	Keyword="AffectedSOPClassUID"			Name="Affected SOP Class UID"
+(0000,0003) VERS="3"	VR="UI"   VM="1"	Keyword="RequestedSOPClassUID"			Name="Requested SOP Class UID"
+(0000,0010) VERS="RET"	VR="SH"   VM="1"	Keyword="CommandRecognitionCode"		Name="Command Recognition Code"
+(0000,0100) VERS="3"	VR="US"   VM="1"	Keyword="CommandField"				Name="Command Field"
+(0000,0110) VERS="3"	VR="US"   VM="1"	Keyword="MessageID"				Name="Message ID"
+(0000,0120) VERS="3"	VR="US"   VM="1"	Keyword="MessageIDBeingRespondedTo"		Name="Message ID Being Responded To"
+(0000,0200) VERS="RET"	VR="AE"   VM="1"	Keyword="Initiator"				Name="Initiator"
+(0000,0300) VERS="RET"	VR="AE"   VM="1"	Keyword="Receiver"				Name="Receiver"
+(0000,0400) VERS="RET"	VR="AE"   VM="1"	Keyword="FindLocation"				Name="Find Location"
+(0000,0600) VERS="3"	VR="AE"   VM="1"	Keyword="MoveDestination"			Name="Move Destination"
+(0000,0700) VERS="3"	VR="US"   VM="1"	Keyword="Priority"				Name="Priority"
+(0000,0800) VERS="3"	VR="US"   VM="1"	Keyword="CommandDataSetType"				Name="Command Data Set Type"
+(0000,0850) VERS="RET"	VR="US"   VM="1"	Keyword="NumberOfMatches"			Name="Number of Matches"
+(0000,0860) VERS="RET"	VR="US"   VM="1"	Keyword="ResponseSequenceNumber"		Name="Response Sequence Number"
+(0000,0900) VERS="3"	VR="US"   VM="1"	Keyword="Status"				Name="Status"
+(0000,0901) VERS="3"	VR="AT"   VM="1-n"	Keyword="OffendingElement"			Name="Offending Element"
+(0000,0902) VERS="3"	VR="LO"   VM="1"	Keyword="ErrorComment"				Name="Error Comment"
+(0000,0903) VERS="3"	VR="US"   VM="1"	Keyword="ErrorID"				Name="Error ID"
+(0000,1000) VERS="3"	VR="UI"   VM="1"	Keyword="AffectedSOPInstanceUID"		Name="Affected SOP Instance UID"
+(0000,1001) VERS="3"	VR="UI"   VM="1"	Keyword="RequestedSOPInstanceUID"		Name="Requested SOP Instance UID"
+(0000,1002) VERS="3"	VR="US"   VM="1"	Keyword="EventTypeID"				Name="Event Type ID"
+(0000,1005) VERS="3"	VR="AT"   VM="1-n"	Keyword="AttributeIdentifierList"		Name="Attribute Identifier List"
+(0000,1008) VERS="3"	VR="US"   VM="1"	Keyword="ActionTypeID"				Name="Action Type ID"
+(0000,1020) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfRemainingSuboperations"	Name="Number of Remaining Sub-operations"
+(0000,1021) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfCompletedSuboperations"	Name="Number of Completed Sub-operations"
+(0000,1022) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfFailedSuboperations"		Name="Number of Failed Sub-operations"
+(0000,1023) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfWarningSuboperations"		Name="Number of Warning Sub-operations"
+(0000,1030) VERS="3"	VR="AE"   VM="1"	Keyword="MoveOriginatorApplicationEntityTitle"	Name="Move Originator Application Entity Title"
+(0000,1031) VERS="3"	VR="US"   VM="1"	Keyword="MoveOriginatorMessageID"		Name="Move Originator Message ID"
+(0000,4000) VERS="RET"	VR="LT"   VM="1"	Keyword="DialogReceiver"			Name="Dialog Receiver"
+(0000,4010) VERS="RET"	VR="LT"   VM="1"	Keyword="TerminalType"				Name="Terminal Type"
+(0000,5010) VERS="RET"	VR="SH"   VM="1"	Keyword="MessageSetID"				Name="Message Set ID"
+(0000,5020) VERS="RET"	VR="SH"   VM="1"	Keyword="EndMessageID"				Name="End Message ID"
+(0000,5110) VERS="RET"	VR="LT"   VM="1"	Keyword="DisplayFormat"				Name="Display Format"
+(0000,5120) VERS="RET"	VR="LT"   VM="1"	Keyword="PagePositionID"			Name="Page Position ID"
+(0000,5130) VERS="RET"	VR="CS"   VM="1"	Keyword="TextFormatID"				Name="Text Format ID"
+(0000,5140) VERS="RET"	VR="CS"   VM="1"	Keyword="NormalReverse"				Name="Normal/Reverse"
+(0000,5150) VERS="RET"	VR="CS"   VM="1"	Keyword="AddGrayScale"				Name="Add Gray Scale"
+(0000,5160) VERS="RET"	VR="CS"   VM="1"	Keyword="Borders"				Name="Borders"
+(0000,5170) VERS="RET"	VR="IS"   VM="1"	Keyword="Copies"				Name="Copies"
+(0000,5180) VERS="RET"	VR="CS"   VM="1"	Keyword="CommandMagnificationType"			Name="Command Magnification Type"
+(0000,5190) VERS="RET"	VR="CS"   VM="1"	Keyword="Erase"					Name="Erase"
+(0000,51A0) VERS="RET"	VR="CS"   VM="1"	Keyword="Print"					Name="Print"
+(0000,51B0) VERS="RET"	VR="US"   VM="1-n"	Keyword="Overlays"				Name="Overlays"
+(0002,0000) VERS="3"	VR="UL"   VM="1"	Keyword="FileMetaInformationGroupLength"	Name="File Meta Information Group Length"
+(0002,0001) VERS="3"	VR="OB"   VM="1"	Keyword="FileMetaInformationVersion"		Name="File Meta Information Version"
+(0002,0002) VERS="3"	VR="UI"   VM="1"	Keyword="MediaStorageSOPClassUID"		Name="Media Storage SOP Class UID"
+(0002,0003) VERS="3"	VR="UI"   VM="1"	Keyword="MediaStorageSOPInstanceUID"		Name="Media Storage SOP Instance UID"
+(0002,0010) VERS="3"	VR="UI"   VM="1"	Keyword="TransferSyntaxUID"			Name="Transfer Syntax UID"
+(0002,0012) VERS="3"	VR="UI"   VM="1"	Keyword="ImplementationClassUID"		Name="Implementation Class UID"
+(0002,0013) VERS="3"	VR="SH"   VM="1"	Keyword="ImplementationVersionName"		Name="Implementation Version Name"
+(0002,0016) VERS="3"	VR="AE"   VM="1"	Keyword="SourceApplicationEntityTitle"		Name="Source Application Entity Title"
+(0002,0017) VERS="3"	VR="AE"   VM="1"	Keyword="SendingApplicationEntityTitle"		Name="Sending Application Entity Title"
+(0002,0018) VERS="3"	VR="AE"   VM="1"	Keyword="ReceivingApplicationEntityTitle"	Name="Receiving Application Entity Title"
+(0002,0100) VERS="3"	VR="UI"   VM="1"	Keyword="PrivateInformationCreatorUID"		Name="Private Information Creator UID"
+(0002,0102) VERS="3"	VR="OB"   VM="1"	Keyword="PrivateInformation"			Name="Private Information"
+(0004,1130) VERS="3"	VR="CS"   VM="1"	Keyword="FileSetID"				Name="File-set ID"
+(0004,1141) VERS="3"	VR="CS"   VM="1-8"	Keyword="FileSetDescriptorFileID"		Name="File-set Descriptor File ID"
+(0004,1142) VERS="3"	VR="CS"   VM="1"	Keyword="SpecificCharacterSetOfFileSetDescriptorFile"			Name="Specific Character Set of File-set Descriptor File"
+(0004,1200) VERS="3"	VR="UL"   VM="1"	Keyword="OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity"		Name="Offset of the First Directory Record of the Root Directory Entity"
+(0004,1202) VERS="3"	VR="UL"   VM="1"	Keyword="OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity"		Name="Offset of the Last Directory Record of the Root Directory Entity"
+(0004,1212) VERS="3"	VR="US"   VM="1"	Keyword="FileSetConsistencyFlag"		Name="File-set Consistency Flag"
+(0004,1220) VERS="3"	VR="SQ"   VM="1"	Keyword="DirectoryRecordSequence"		Name="Directory Record Sequence"
+(0004,1400) VERS="3"	VR="UL"   VM="1"	Keyword="OffsetOfTheNextDirectoryRecord"		Name="Offset of the Next Directory Record"
+(0004,1410) VERS="3"	VR="US"   VM="1"	Keyword="RecordInUseFlag"			Name="Record In-use Flag"
+(0004,1420) VERS="3"	VR="UL"   VM="1"	Keyword="OffsetOfReferencedLowerLevelDirectoryEntity"		Name="Offset of Referenced Lower-Level Directory Entity"
+(0004,1430) VERS="3"	VR="CS"   VM="1"	Keyword="DirectoryRecordType"			Name="Directory Record Type"
+(0004,1432) VERS="3"	VR="UI"   VM="1"	Keyword="PrivateRecordUID"			Name="Private Record UID"
+(0004,1500) VERS="3"	VR="CS"   VM="1-8"	Keyword="ReferencedFileID"			Name="Referenced File ID"
+(0004,1504) VERS="RET"	VR="UL"   VM="1"	Keyword="MRDRDirectoryRecordOffset"		Name="MRDR Directory Record Offset"
+(0004,1510) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedSOPClassUIDInFile"		Name="Referenced SOP Class UID in File"
+(0004,1511) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedSOPInstanceUIDInFile"	Name="Referenced SOP Instance UID in File"
+(0004,1512) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedTransferSyntaxUIDInFile"	Name="Referenced Transfer Syntax UID in File"
+(0004,151A) VERS="3"	VR="UI"   VM="1-n"	Keyword="ReferencedRelatedGeneralSOPClassUIDInFile"	Name="Referenced Related General SOP Class UID in File"
+(0004,1600) VERS="RET"	VR="UL"   VM="1"	Keyword="NumberOfReferences"			Name="Number of References"
+(0008,0001) VERS="RET"	VR="UL"   VM="1"	Keyword="LengthToEnd"				Name="Length to End"
+(0008,0005) VERS="3"	VR="CS"   VM="1-n"	Keyword="SpecificCharacterSet"			Name="Specific Character Set"
+(0008,0006) VERS="3"	VR="SQ"   VM="1"	Keyword="LanguageCodeSequence"	Name="Language Code Sequence"
+(0008,0008) VERS="3"	VR="CS"   VM="2-n"	Keyword="ImageType"				Name="Image Type"
+(0008,0010) VERS="RET"	VR="SH"   VM="1"	Keyword="RecognitionCode"			Name="Recognition Code"
+(0008,0012) VERS="3"	VR="DA"   VM="1"	Keyword="InstanceCreationDate"			Name="Instance Creation Date"
+(0008,0013) VERS="3"	VR="TM"   VM="1"	Keyword="InstanceCreationTime"			Name="Instance Creation Time"
+(0008,0014) VERS="3"	VR="UI"   VM="1"	Keyword="InstanceCreatorUID"			Name="Instance Creator UID"
+(0008,0015) VERS="3"	VR="DT"   VM="1"	Keyword="InstanceCoercionDateTime"			Name="Instance Coercion DateTime"
+(0008,0016) VERS="3"	VR="UI"   VM="1"	Keyword="SOPClassUID"				Name="SOP Class UID"
+(0008,0018) VERS="3"	VR="UI"   VM="1"	Keyword="SOPInstanceUID"			Name="SOP Instance UID"
+(0008,001A) VERS="3"	VR="UI"   VM="1-n"	Keyword="RelatedGeneralSOPClassUID"			Name="Related General SOP Class UID"
+(0008,001B) VERS="3"	VR="UI"   VM="1"	Keyword="OriginalSpecializedSOPClassUID"			Name="Original Specialized SOP Class UID"
+(0008,0020) VERS="3"	VR="DA"   VM="1"	Keyword="StudyDate"				Name="Study Date"
+(0008,0021) VERS="3"	VR="DA"   VM="1"	Keyword="SeriesDate"				Name="Series Date"
+(0008,0022) VERS="3"	VR="DA"   VM="1"	Keyword="AcquisitionDate"			Name="Acquisition Date"
+(0008,0023) VERS="3"	VR="DA"   VM="1"	Keyword="ContentDate"				Name="Content Date"
+(0008,0024) VERS="RET"	VR="DA"   VM="1"	Keyword="OverlayDate"				Name="Overlay Date"
+(0008,0025) VERS="RET"	VR="DA"   VM="1"	Keyword="CurveDate"				Name="Curve Date"
+(0008,002A) VERS="3"	VR="DT"   VM="1"	Keyword="AcquisitionDateTime"			Name="Acquisition Date Time"
+(0008,0030) VERS="3"	VR="TM"   VM="1"	Keyword="StudyTime"				Name="Study Time"
+(0008,0031) VERS="3"	VR="TM"   VM="1"	Keyword="SeriesTime"				Name="Series Time"
+(0008,0032) VERS="3"	VR="TM"   VM="1"	Keyword="AcquisitionTime"			Name="Acquisition Time"
+(0008,0033) VERS="3"	VR="TM"   VM="1"	Keyword="ContentTime"				Name="Content Time"
+(0008,0034) VERS="RET"	VR="TM"   VM="1"	Keyword="OverlayTime"				Name="Overlay Time"
+(0008,0035) VERS="RET"	VR="TM"   VM="1"	Keyword="CurveTime"				Name="Curve Time"
+(0008,0040) VERS="RET"	VR="US"   VM="1"	Keyword="DataSetType"			Name="Data Set Type"
+(0008,0041) VERS="RET"	VR="LO"   VM="1"	Keyword="DataSetSubtype"			Name="Data Set Subtype"
+(0008,0042) VERS="RET"	VR="CS"   VM="1"	Keyword="NuclearMedicineSeriesType"	Name="Nuclear Medicine Series Type"
+(0008,0050) VERS="3"	VR="SH"   VM="1"	Keyword="AccessionNumber"			Name="Accession Number"
+(0008,0051) VERS="3"	VR="SQ"   VM="1"	Keyword="IssuerOfAccessionNumberSequence"			Name="Issuer of Accession Number Sequence"
+(0008,0052) VERS="3"	VR="CS"   VM="1"	Keyword="QueryRetrieveLevel"			Name="Query/Retrieve Level"
+(0008,0053) VERS="3"	VR="CS"   VM="1"	Keyword="QueryRetrieveView"				Name="Query/Retrieve View"
+(0008,0054) VERS="3"	VR="AE"   VM="1-n"	Keyword="RetrieveAETitle"			Name="Retrieve AE Title"
+(0008,0056) VERS="3"	VR="CS"   VM="1"	Keyword="InstanceAvailability"			Name="Instance Availability"
+(0008,0058) VERS="3"	VR="UI"   VM="1-n"	Keyword="FailedSOPInstanceUIDList"		Name="Failed SOP Instance UID List"
+(0008,0060) VERS="3"	VR="CS"   VM="1"	Keyword="Modality"				Name="Modality"
+(0008,0061) VERS="3"	VR="CS"   VM="1-n"	Keyword="ModalitiesInStudy"			Name="Modalities in Study"
+(0008,0062) VERS="3"	VR="UI"   VM="1-n"	Keyword="SOPClassesInStudy"			Name="SOP Classes in Study"
+(0008,0064) VERS="3"	VR="CS"   VM="1"	Keyword="ConversionType"			Name="Conversion Type"
+(0008,0068) VERS="3"	VR="CS"   VM="1"	Keyword="PresentationIntentType"		Name="Presentation Intent Type"
+(0008,0070) VERS="3"	VR="LO"   VM="1"	Keyword="Manufacturer"				Name="Manufacturer"
+(0008,0080) VERS="3"	VR="LO"   VM="1"	Keyword="InstitutionName"			Name="Institution Name"
+(0008,0081) VERS="3"	VR="ST"   VM="1"	Keyword="InstitutionAddress"			Name="Institution Address"
+(0008,0082) VERS="3"	VR="SQ"   VM="1"	Keyword="InstitutionCodeSequence"		Name="Institution Code Sequence"
+(0008,0090) VERS="3"	VR="PN"   VM="1"	Keyword="ReferringPhysicianName"		Name="Referring Physician's Name"
+(0008,0092) VERS="3"	VR="ST"   VM="1"	Keyword="ReferringPhysicianAddress"		Name="Referring Physician's Address"
+(0008,0094) VERS="3"	VR="SH"   VM="1-n"	Keyword="ReferringPhysicianTelephoneNumbers"	Name="Referring Physician's Telephone Numbers"
+(0008,0096) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferringPhysicianIdentificationSequence"	Name="Referring Physician Identification Sequence"
+(0008,009C) VERS="3"	VR="PN"   VM="1-n"	Keyword="ConsultingPhysicianName"		Name="Consulting Physician's Name"
+(0008,009D) VERS="3"	VR="SQ"   VM="1"	Keyword="ConsultingPhysicianIdentificationSequence"	Name="Consulting Physician Identification Sequence"
+(0008,0100) VERS="3"	VR="SH"   VM="1"	Keyword="CodeValue"				Name="Code Value"
+(0008,0102) VERS="3"	VR="SH"   VM="1"	Keyword="CodingSchemeDesignator"		Name="Coding Scheme Designator"
+(0008,0103) VERS="3"	VR="SH"   VM="1"	Keyword="CodingSchemeVersion"			Name="Coding Scheme Version"
+(0008,0104) VERS="3"	VR="LO"   VM="1"	Keyword="CodeMeaning"				Name="Code Meaning"
+(0008,0105) VERS="3"	VR="CS"   VM="1"	Keyword="MappingResource"			Name="Mapping Resource"
+(0008,0106) VERS="3"	VR="DT"   VM="1"	Keyword="ContextGroupVersion"			Name="Context Group Version"
+(0008,0107) VERS="3"	VR="DT"   VM="1"	Keyword="ContextGroupLocalVersion"		Name="Context Group Local Version"
+(0008,010B) VERS="3"	VR="CS"   VM="1"	Keyword="ContextGroupExtensionFlag"		Name="Context Group Extension Flag"
+(0008,010C) VERS="3"	VR="UI"   VM="1"	Keyword="CodingSchemeUID"			Name="Coding Scheme UID"
+(0008,010D) VERS="3"	VR="UI"   VM="1"	Keyword="ContextGroupExtensionCreatorUID"	Name="Context Group Extension Creator UID"
+(0008,010F) VERS="3"	VR="CS"   VM="1"	Keyword="ContextIdentifier"			Name="Context Identifier"
+(0008,0110) VERS="3"	VR="SQ"   VM="1"	Keyword="CodingSchemeIdentificationSequence"	Name="Coding Scheme Identification Sequence"
+(0008,0112) VERS="3"	VR="LO"   VM="1"	Keyword="CodingSchemeRegistry"			Name="Coding Scheme Registry"
+(0008,0114) VERS="3"	VR="ST"   VM="1"	Keyword="CodingSchemeExternalID"		Name="Coding Scheme External ID"
+(0008,0115) VERS="3"	VR="ST"   VM="1"	Keyword="CodingSchemeName"			Name="Coding Scheme Name"
+(0008,0116) VERS="3"	VR="ST"   VM="1"	Keyword="CodingSchemeResponsibleOrganization"		Name="Coding Scheme Responsible Organization"
+(0008,0117) VERS="3"	VR="UI"   VM="1"	Keyword="ContextUID"			Name="Context UID"
+(0008,0118) VERS="3"	VR="UI"   VM="1"	Keyword="MappingResourceUID"			Name="Mapping Resource UID"
+(0008,0119) VERS="3"	VR="UC"   VM="1"	Keyword="LongCodeValue"				Name="Long Code Value"
+(0008,0120) VERS="3"	VR="UR"   VM="1"	Keyword="URNCodeValue"				Name="URN Code Value"
+(0008,0121) VERS="3"	VR="SQ"   VM="1"	Keyword="EquivalentCodeSequence"	Name="Equivalent Code Sequence"
+(0008,0201) VERS="3"	VR="SH"   VM="1"	Keyword="TimezoneOffsetFromUTC"			Name="Timezone Offset From UTC"
+(0008,0300) VERS="3"	VR="SQ"   VM="1"	Keyword="PrivateDataElementCharacteristicsSequence"			Name="Private Data Element Characteristics Sequence"
+(0008,0301) VERS="3"	VR="US"   VM="1"	Keyword="PrivateGroupReference"								Name="Private Group Reference"
+(0008,0302) VERS="3"	VR="LO"   VM="1"	Keyword="PrivateCreatorReference"							Name="Private Creator Reference"
+(0008,0303) VERS="3"	VR="CS"   VM="1"	Keyword="BlockIdentifyingInformationStatus"					Name="Block Identifying Information Status"
+(0008,0304) VERS="3"	VR="US"   VM="1-n"	Keyword="NonidentifyingPrivateElements"						Name="Nonidentifying Private Elements"
+(0008,0305) VERS="3"	VR="SQ"   VM="1"	Keyword="DeidentificationActionSequence"					Name="Deidentification Action Sequence"
+(0008,0306) VERS="3"	VR="US"   VM="1-n"	Keyword="IdentifyingPrivateElements"						Name="Identifying Private Elements"
+(0008,0307) VERS="3"	VR="CS"   VM="1"	Keyword="DeidentificationAction"							Name="Deidentification Action"
+(0008,1000) VERS="RET"	VR="AE"   VM="1"	Keyword="NetworkID"				Name="Network ID"
+(0008,1010) VERS="3"	VR="SH"   VM="1"	Keyword="StationName"				Name="Station Name"
+(0008,1030) VERS="3"	VR="LO"   VM="1"	Keyword="StudyDescription"			Name="Study Description"
+(0008,1032) VERS="3"	VR="SQ"   VM="1"	Keyword="ProcedureCodeSequence"			Name="Procedure Code Sequence"
+(0008,103E) VERS="3"	VR="LO"   VM="1"	Keyword="SeriesDescription"			Name="Series Description"
+(0008,103F) VERS="3"	VR="SQ"   VM="1"	Keyword="SeriesDescriptionCodeSequence"	Name="Series Description Code Sequence"
+(0008,1040) VERS="3"	VR="LO"   VM="1"	Keyword="InstitutionalDepartmentName"		Name="Institutional Department Name"
+(0008,1048) VERS="3"	VR="PN"   VM="1-n"	Keyword="PhysiciansOfRecord"			Name="Physician(s) of Record"
+(0008,1049) VERS="3"	VR="SQ"   VM="1"	Keyword="PhysiciansOfRecordIdentificationSequence"	Name="Physician(s) of Record Identification Sequence"
+(0008,1050) VERS="3"	VR="PN"   VM="1-n"	Keyword="PerformingPhysicianName"			Name="Performing Physician's Name"
+(0008,1052) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformingPhysicianIdentificationSequence"	Name="Performing Physician Identification Sequence"
+(0008,1060) VERS="3"	VR="PN"   VM="1-n"	Keyword="NameOfPhysiciansReadingStudy"				Name="Name of Physician(s) Reading Study"
+(0008,1062) VERS="3"	VR="SQ"   VM="1"	Keyword="PhysiciansReadingStudyIdentificationSequence"	Name="Physician(s) Reading Study Identification Sequence"
+(0008,1070) VERS="3"	VR="PN"   VM="1-n"	Keyword="OperatorsName"				Name="Operators' Name"
+(0008,1072) VERS="3"	VR="SQ"   VM="1"	Keyword="OperatorIdentificationSequence"	Name="Operator Identification Sequence"
+(0008,1080) VERS="3"	VR="LO"   VM="1-n"	Keyword="AdmittingDiagnosesDescription"		Name="Admitting Diagnoses Description"
+(0008,1084) VERS="3"	VR="SQ"   VM="1"	Keyword="AdmittingDiagnosesCodeSequence"	Name="Admitting Diagnoses Code Sequence"
+(0008,1090) VERS="3"	VR="LO"   VM="1"	Keyword="ManufacturerModelName"			Name="Manufacturer's Model Name"
+(0008,1100) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedResultsSequence"		Name="Referenced Results Sequence"
+(0008,1110) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedStudySequence"		Name="Referenced Study Sequence"
+(0008,1111) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedPerformedProcedureStepSequence"	Name="Referenced Performed Procedure Step Sequence"
+(0008,1115) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSeriesSequence"		Name="Referenced Series Sequence"
+(0008,1120) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedPatientSequence"		Name="Referenced Patient Sequence"
+(0008,1125) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedVisitSequence"		Name="Referenced Visit Sequence"
+(0008,1130) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedOverlaySequence"		Name="Referenced Overlay Sequence"
+(0008,1134) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedStereometricInstanceSequence"	Name="Referenced Stereometric Instance Sequence"
+(0008,113A) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedWaveformSequence"		Name="Referenced Waveform Sequence"
+(0008,1140) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedImageSequence"		Name="Referenced Image Sequence"
+(0008,1145) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedCurveSequence"		Name="Referenced Curve Sequence"
+(0008,114A) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedInstanceSequence"		Name="Referenced Instance Sequence"
+(0008,114B) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedRealWorldValueMappingInstanceSequence"		Name="Referenced Real World Value Mapping Instance Sequence"
+(0008,1150) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedSOPClassUID"			Name="Referenced SOP Class UID"
+(0008,1155) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedSOPInstanceUID"		Name="Referenced SOP Instance UID"
+(0008,115A) VERS="3"	VR="UI"   VM="1-n"	Keyword="SOPClassesSupported"			Name="SOP Classes Supported"
+(0008,1160) VERS="3"	VR="IS"   VM="1-n"	Keyword="ReferencedFrameNumber"			Name="Referenced Frame Number"
+(0008,1161) VERS="3"	VR="UL"   VM="1-n"	Keyword="SimpleFrameList"					Name="Simple Frame List"
+(0008,1162) VERS="3"	VR="UL"   VM="3-3n"	Keyword="CalculatedFrameList"				Name="Calculated Frame List"
+(0008,1163) VERS="3"	VR="FD"   VM="2"	Keyword="TimeRange"							Name="Time Range"
+(0008,1164) VERS="3"	VR="SQ"   VM="1"	Keyword="FrameExtractionSequence"			Name="Frame Extraction Sequence"
+(0008,1167) VERS="3"	VR="UI"   VM="1"	Keyword="MultiFrameSourceSOPInstanceUID"	Name="Multi-frame Source SOP Instance UID"
+(0008,1190) VERS="3"	VR="UR"   VM="1"	Keyword="RetrieveURL"				Name="Retrieve URL"
+(0008,1195) VERS="3"	VR="UI"   VM="1"	Keyword="TransactionUID"			Name="Transaction UID"
+(0008,1196) VERS="3"	VR="US"   VM="1"	Keyword="WarningReason"				Name="Warning Reason"
+(0008,1197) VERS="3"	VR="US"   VM="1"	Keyword="FailureReason"				Name="Failure Reason"
+(0008,1198) VERS="3"	VR="SQ"   VM="1"	Keyword="FailedSOPSequence"			Name="Failed SOP Sequence"
+(0008,1199) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSOPSequence"			Name="Referenced SOP Sequence"
+(0008,119A) VERS="3"	VR="SQ"   VM="1"	Keyword="OtherFailuresSequence"			Name="Other Failures Sequence"
+(0008,1200) VERS="3"	VR="SQ"   VM="1"	Keyword="StudiesContainingOtherReferencedInstancesSequence"	Name="Studies Containing Other Referenced Instances Sequence"
+(0008,1250) VERS="3"	VR="SQ"   VM="1"	Keyword="RelatedSeriesSequence"			Name="Related Series Sequence"
+(0008,2110) VERS="RET"	VR="CS"   VM="1"	Keyword="LossyImageCompressionRetired"		Name="Lossy Image Compression (Retired)"
+(0008,2111) VERS="3"	VR="ST"   VM="1"	Keyword="DerivationDescription"			Name="Derivation Description"
+(0008,2112) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceImageSequence"			Name="Source Image Sequence"
+(0008,2120) VERS="3"	VR="SH"   VM="1"	Keyword="StageName"				Name="Stage Name"
+(0008,2122) VERS="3"	VR="IS"   VM="1"	Keyword="StageNumber"				Name="Stage Number"
+(0008,2124) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfStages"			Name="Number of Stages"
+(0008,2127) VERS="3"	VR="SH"   VM="1"	Keyword="ViewName"				Name="View Name"
+(0008,2128) VERS="3"	VR="IS"   VM="1"	Keyword="ViewNumber"				Name="View Number"
+(0008,2129) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfEventTimers"			Name="Number of Event Timers"
+(0008,212A) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfViewsInStage"			Name="Number of Views in Stage"
+(0008,2130) VERS="3"	VR="DS"   VM="1-n"	Keyword="EventElapsedTimes"			Name="Event Elapsed Time(s)"
+(0008,2132) VERS="3"	VR="LO"   VM="1-n"	Keyword="EventTimerNames"			Name="Event Timer Name(s)"
+(0008,2133) VERS="3"	VR="SQ"   VM="1"	Keyword="EventTimerSequence"						Name="Event Timer Sequence"
+(0008,2134) VERS="3"	VR="FD"   VM="1"	Keyword="EventTimeOffset"							Name="Event Time Offset"
+(0008,2135) VERS="3"	VR="SQ"   VM="1"	Keyword="EventCodeSequence"							Name="Event Code Sequence"
+(0008,2142) VERS="3"	VR="IS"   VM="1"	Keyword="StartTrim"				Name="Start Trim"
+(0008,2143) VERS="3"	VR="IS"   VM="1"	Keyword="StopTrim"				Name="Stop Trim"
+(0008,2144) VERS="3"	VR="IS"   VM="1"	Keyword="RecommendedDisplayFrameRate"		Name="Recommended Display Frame Rate"
+(0008,2200) VERS="RET"	VR="CS"   VM="1"	Keyword="TransducerPosition"			Name="Transducer Position"
+(0008,2204) VERS="RET"	VR="CS"   VM="1"	Keyword="TransducerOrientation"			Name="Transducer Orientation"
+(0008,2208) VERS="RET"	VR="CS"   VM="1"	Keyword="AnatomicStructure"			Name="Anatomic Structure"
+(0008,2218) VERS="3"	VR="SQ"   VM="1"	Keyword="AnatomicRegionSequence"		Name="Anatomic Region Sequence"
+(0008,2220) VERS="3"	VR="SQ"   VM="1"	Keyword="AnatomicRegionModifierSequence"	Name="Anatomic Region Modifier Sequence"
+(0008,2228) VERS="3"	VR="SQ"   VM="1"	Keyword="PrimaryAnatomicStructureSequence"	Name="Primary Anatomic Structure Sequence"
+(0008,2229) VERS="3"	VR="SQ"   VM="1"	Keyword="AnatomicStructureSpaceOrRegionSequence"	Name="Anatomic Structure, Space or Region Sequence"
+(0008,2230) VERS="3"	VR="SQ"   VM="1"	Keyword="PrimaryAnatomicStructureModifierSequence"	Name="Primary Anatomic Structure Modifier Sequence"
+(0008,2240) VERS="RET"	VR="SQ"   VM="1"	Keyword="TransducerPositionSequence"		Name="Transducer Position Sequence"
+(0008,2242) VERS="RET"	VR="SQ"   VM="1"	Keyword="TransducerPositionModifierSequence"	Name="Transducer Position Modifier Sequence"
+(0008,2244) VERS="RET"	VR="SQ"   VM="1"	Keyword="TransducerOrientationSequence"		Name="Transducer Orientation Sequence"
+(0008,2246) VERS="RET"	VR="SQ"   VM="1"	Keyword="TransducerOrientationModifierSequence"	Name="Transducer Orientation Modifier Sequence"
+(0008,2251) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnatomicStructureSpaceOrRegionCodeSequenceTrial"	Name="Anatomic Structure Space Or Region Code Sequence (Trial)"
+(0008,2253) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnatomicPortalOfEntranceCodeSequenceTrial"	Name="Anatomic Portal Of Entrance Code Sequence (Trial)"
+(0008,2255) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnatomicApproachDirectionCodeSequenceTrial"	Name="Anatomic Approach Direction Code Sequence (Trial)"
+(0008,2256) VERS="RET"	VR="ST"   VM="1"	Keyword="AnatomicPerspectiveDescriptionTrial"	Name="Anatomic Perspective Description (Trial)"
+(0008,2257) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnatomicPerspectiveCodeSequenceTrial"	Name="Anatomic Perspective Code Sequence (Trial)"
+(0008,2258) VERS="RET"	VR="ST"   VM="1"	Keyword="AnatomicLocationOfExaminingInstrumentDescriptionTrial"	Name="Anatomic Location Of Examining Instrument Description (Trial)"
+(0008,2259) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnatomicLocationOfExaminingInstrumentCodeSequenceTrial"	Name="Anatomic Location Of Examining Instrument Code Sequence (Trial)"
+(0008,225A) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnatomicStructureSpaceOrRegionModifierCodeSequenceTrial"	Name="Anatomic Structure Space Or Region Modifier Code Sequence (Trial)"
+(0008,225C) VERS="RET"	VR="SQ"   VM="1"	Keyword="OnAxisBackgroundAnatomicStructureCodeSequenceTrial"		Name="OnAxis Background Anatomic Structure Code Sequence (Trial)"
+(0008,3001) VERS="3"	VR="SQ"   VM="1"	Keyword="AlternateRepresentationSequence"		Name="Alternate Representation Sequence"
+(0008,3010) VERS="3"	VR="UI"   VM="1-n"	Keyword="IrradiationEventUID"		Name="Irradiation Event UID"
+(0008,3011) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceIrradiationEventSequence"		Name="Source Irradiation Event Sequence"
+(0008,3012) VERS="3"	VR="UI"   VM="1"	Keyword="RadiopharmaceuticalAdministrationEventUID"		Name="Radiopharmaceutical Administration Event UID"
+(0008,4000) VERS="RET"	VR="LT"   VM="1"	Keyword="IdentifyingComments"			Name="Identifying Comments"
+(0008,9007) VERS="3"	VR="CS"   VM="4"	Keyword="FrameType"				Name="Frame Type"
+(0008,9092) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedImageEvidenceSequence"	Name="Referenced Image Evidence Sequence"
+(0008,9121) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedRawDataSequence"		Name="Referenced Raw Data Sequence"
+(0008,9123) VERS="3"	VR="UI"   VM="1"	Keyword="CreatorVersionUID"			Name="Creator-Version UID"
+(0008,9124) VERS="3"	VR="SQ"   VM="1"	Keyword="DerivationImageSequence"		Name="Derivation Image Sequence"
+(0008,9154) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceImageEvidenceSequence"		Name="Source Image Evidence Sequence"
+(0008,9205) VERS="3"	VR="CS"   VM="1"	Keyword="PixelPresentation"			Name="Pixel Presentation"
+(0008,9206) VERS="3"	VR="CS"   VM="1"	Keyword="VolumetricProperties"			Name="Volumetric Properties"
+(0008,9207) VERS="3"	VR="CS"   VM="1"	Keyword="VolumeBasedCalculationTechnique"	Name="Volume Based Calculation Technique"
+(0008,9208) VERS="3"	VR="CS"   VM="1"	Keyword="ComplexImageComponent"			Name="Complex Image Component"
+(0008,9209) VERS="3"	VR="CS"   VM="1"	Keyword="AcquisitionContrast"			Name="Acquisition Contrast"
+(0008,9215) VERS="3"	VR="SQ"   VM="1"	Keyword="DerivationCodeSequence"		Name="Derivation Code Sequence"
+(0008,9237) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedPresentationStateSequence"	Name="Referenced Presentation State Sequence"
+(0008,9410) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedOtherPlaneSequence"		Name="Referenced Other Plane Sequence"
+(0008,9458) VERS="3"	VR="SQ"   VM="1"	Keyword="FrameDisplaySequence"		Name="Frame Display Sequence"
+(0008,9459) VERS="3"	VR="FL"   VM="1"	Keyword="RecommendedDisplayFrameRateInFloat"		Name="Recommended Display Frame Rate in Float"
+(0008,9460) VERS="3"	VR="CS"   VM="1"	Keyword="SkipFrameRangeFlag"		Name="Skip Frame Range Flag"
+(0010,0010) VERS="3"	VR="PN"   VM="1"	Keyword="PatientName"				Name="Patient's Name"
+(0010,0020) VERS="3"	VR="LO"   VM="1"	Keyword="PatientID"				Name="Patient ID"
+(0010,0021) VERS="3"	VR="LO"   VM="1"	Keyword="IssuerOfPatientID"			Name="Issuer of Patient ID"
+(0010,0022) VERS="3"	VR="CS"   VM="1"	Keyword="TypeOfPatientID"			Name="Type of Patient ID"
+(0010,0024) VERS="3"	VR="SQ"   VM="1"	Keyword="IssuerOfPatientIDQualifiersSequence"			Name="Issuer of Patient ID Qualifiers Sequence"
+(0010,0026) VERS="3"	VR="SQ"   VM="1"	Keyword="SourcePatientGroupIdentificationSequence"		Name="Source Patient Group Identification Sequence"
+(0010,0027) VERS="3"	VR="SQ"   VM="1"	Keyword="GroupOfPatientsIdentificationSequence"			Name="Group of Patients Identification Sequence"
+(0010,0028) VERS="3"	VR="US"   VM="3"	Keyword="SubjectRelativePositionInImage"				Name="Subject Relative Position in Image"
+(0010,0030) VERS="3"	VR="DA"   VM="1"	Keyword="PatientBirthDate"			Name="Patient's Birth Date"
+(0010,0032) VERS="3"	VR="TM"   VM="1"	Keyword="PatientBirthTime"			Name="Patient's Birth Time"
+(0010,0040) VERS="3"	VR="CS"   VM="1"	Keyword="PatientSex"				Name="Patient's Sex"
+(0010,0050) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientInsurancePlanCodeSequence"	Name="Patient's Insurance Plan Code Sequence"
+(0010,0101) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientPrimaryLanguageCodeSequence"	Name="Patient's Primary Language Code Sequence"
+(0010,0102) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientPrimaryLanguageModifierCodeSequence"	Name="Patient's Primary Language Modifier Code Sequence"
+(0010,0200) VERS="3"	VR="CS"   VM="1"	Keyword="QualityControlSubject"	Name="Quality Control Subject"
+(0010,0201) VERS="3"	VR="SQ"   VM="1"	Keyword="QualityControlSubjectTypeCodeSequence"	Name="Quality Control Subject Type Code Sequence"
+(0010,0212) VERS="3"	VR="UC"   VM="1"	Keyword="StrainDescription"					Name="Strain Description"
+(0010,0213) VERS="3"	VR="LO"   VM="1"	Keyword="StrainNomenclature"				Name="Strain Nomenclature"
+(0010,0214) VERS="3"	VR="LO"   VM="1"	Keyword="StrainStockNumber"					Name="Strain Stock Number"
+(0010,0215) VERS="3"	VR="SQ"   VM="1"	Keyword="StrainSourceRegistryCodeSequence"	Name="Strain Source Registry Code Sequence"
+(0010,0216) VERS="3"	VR="SQ"   VM="1"	Keyword="StrainStockSequence"				Name="Strain Stock Sequence"
+(0010,0217) VERS="3"	VR="LO"   VM="1"	Keyword="StrainSource"						Name="Strain Source"
+(0010,0218) VERS="3"	VR="UT"   VM="1"	Keyword="StrainAdditionalInformation"		Name="Strain Additional Information"
+(0010,0219) VERS="3"	VR="SQ"   VM="1"	Keyword="StrainCodeSequence"				Name="Strain Code Sequence"
+(0010,1000) VERS="3"	VR="LO"   VM="1-n"	Keyword="OtherPatientIDs"			Name="Other Patient IDs"
+(0010,1001) VERS="3"	VR="PN"   VM="1-n"	Keyword="OtherPatientNames"			Name="Other Patient Names"
+(0010,1002) VERS="3"	VR="SQ"   VM="1"	Keyword="OtherPatientIDsSequence"	Name="Other Patient IDs Sequence"
+(0010,1005) VERS="3"	VR="PN"   VM="1"	Keyword="PatientBirthName"			Name="Patient's Birth Name"
+(0010,1010) VERS="3"	VR="AS"   VM="1"	Keyword="PatientAge"				Name="Patient's Age"
+(0010,1020) VERS="3"	VR="DS"   VM="1"	Keyword="PatientSize"				Name="Patient's Size"
+(0010,1021) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientSizeCodeSequence"	Name="Patient's Size Code Sequence"
+(0010,1030) VERS="3"	VR="DS"   VM="1"	Keyword="PatientWeight"				Name="Patient's Weight"
+(0010,1040) VERS="3"	VR="LO"   VM="1"	Keyword="PatientAddress"			Name="Patient's Address"
+(0010,1050) VERS="RET"	VR="LO"   VM="1-n"	Keyword="InsurancePlanIdentification"		Name="Insurance Plan Identification"
+(0010,1060) VERS="3"	VR="PN"   VM="1"	Keyword="PatientMotherBirthName"		Name="Patient's Mother's Birth Name"
+(0010,1080) VERS="3"	VR="LO"   VM="1"	Keyword="MilitaryRank"				Name="Military Rank"
+(0010,1081) VERS="3"	VR="LO"   VM="1"	Keyword="BranchOfService"			Name="Branch of Service"
+(0010,1090) VERS="3"	VR="LO"   VM="1"	Keyword="MedicalRecordLocator"			Name="Medical Record Locator"
+(0010,1100) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedPatientPhotoSequence"	Name="Referenced Patient Photo Sequence"
+(0010,2000) VERS="3"	VR="LO"   VM="1-n"	Keyword="MedicalAlerts"				Name="Medical Alerts"
+(0010,2110) VERS="3"	VR="LO"   VM="1-n"	Keyword="Allergies"					Name="Allergies"
+(0010,2150) VERS="3"	VR="LO"   VM="1"	Keyword="CountryOfResidence"			Name="Country of Residence"
+(0010,2152) VERS="3"	VR="LO"   VM="1"	Keyword="RegionOfResidence"			Name="Region of Residence"
+(0010,2154) VERS="3"	VR="SH"   VM="1-n"	Keyword="PatientTelephoneNumbers"	Name="Patient's Telephone Numbers"
+(0010,2155) VERS="3"	VR="LT"   VM="1"	Keyword="PatientTelecomInformation"	Name="Patient's Telecom Information"
+(0010,2160) VERS="3"	VR="SH"   VM="1"	Keyword="EthnicGroup"				Name="Ethnic Group"
+(0010,2180) VERS="3"	VR="SH"   VM="1"	Keyword="Occupation"				Name="Occupation"
+(0010,21A0) VERS="3"	VR="CS"   VM="1"	Keyword="SmokingStatus"				Name="Smoking Status"
+(0010,21B0) VERS="3"	VR="LT"   VM="1"	Keyword="AdditionalPatientHistory"		Name="Additional Patient History"
+(0010,21C0) VERS="3"	VR="US"   VM="1"	Keyword="PregnancyStatus"			Name="Pregnancy Status"
+(0010,21D0) VERS="3"	VR="DA"   VM="1"	Keyword="LastMenstrualDate"			Name="Last Menstrual Date"
+(0010,21F0) VERS="3"	VR="LO"   VM="1"	Keyword="PatientReligiousPreference"		Name="Patient's Religious Preference"
+(0010,2201) VERS="3"	VR="LO"   VM="1"	Keyword="PatientSpeciesDescription"		Name="Patient Species Description"
+(0010,2202) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientSpeciesCodeSequence"	Name="Patient Species Code Sequence"
+(0010,2203) VERS="3"	VR="CS"   VM="1"	Keyword="PatientSexNeutered"			Name="Patient's Sex Neutered"
+(0010,2210) VERS="3"	VR="CS"   VM="1"	Keyword="AnatomicalOrientationType"		Name="Anatomical Orientation Type"
+(0010,2292) VERS="3"	VR="LO"   VM="1"	Keyword="PatientBreedDescription"		Name="Patient Breed Description"
+(0010,2293) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientBreedCodeSequence"		Name="Patient Breed Code Sequence"
+(0010,2294) VERS="3"	VR="SQ"   VM="1"	Keyword="BreedRegistrationSequence"		Name="Breed Registration Sequence"
+(0010,2295) VERS="3"	VR="LO"   VM="1"	Keyword="BreedRegistrationNumber"		Name="Breed Registration Number"
+(0010,2296) VERS="3"	VR="SQ"   VM="1"	Keyword="BreedRegistryCodeSequence"		Name="Breed Registry Code Sequence"
+(0010,2297) VERS="3"	VR="PN"   VM="1"	Keyword="ResponsiblePerson"				Name="Responsible Person"
+(0010,2298) VERS="3"	VR="CS"   VM="1"	Keyword="ResponsiblePersonRole"			Name="Responsible Person Role"
+(0010,2299) VERS="3"	VR="LO"   VM="1"	Keyword="ResponsibleOrganization"		Name="Responsible Organization"
+(0010,4000) VERS="3"	VR="LT"   VM="1"	Keyword="PatientComments"			Name="Patient Comments"
+(0010,9431) VERS="3"	VR="FL"   VM="1"	Keyword="ExaminedBodyThickness"			Name="ExaminedBodyThickness"
+(0012,0010) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSponsorName"		Name="Clinical Trial Sponsor Name"
+(0012,0020) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialProtocolID"		Name="Clinical Trial Protocol ID"
+(0012,0021) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialProtocolName"		Name="Clinical Trial Protocol Name"
+(0012,0030) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSiteID"			Name="Clinical Trial Site ID"
+(0012,0031) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSiteName"			Name="Clinical Trial Site Name"
+(0012,0040) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSubjectID"		Name="Clinical Trial Subject ID"
+(0012,0042) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSubjectReadingID"		Name="Clinical Trial Subject Reading ID"
+(0012,0050) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialTimePointID"		Name="Clinical Trial Time Point ID"
+(0012,0051) VERS="3"	VR="ST"   VM="1"	Keyword="ClinicalTrialTimePointDescription"	Name="Clinical Trial Time Point Description"
+(0012,0060) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialCoordinatingCenterName"	Name="Clinical Trial Coordinating Center Name"
+(0012,0062) VERS="3"	VR="CS"   VM="1"	Keyword="PatientIdentityRemoved"		Name="Patient Identity Removed"
+(0012,0063) VERS="3"	VR="LO"   VM="1-n"	Keyword="DeidentificationMethod"		Name="De-identification Method"
+(0012,0064) VERS="3"	VR="SQ"   VM="1"	Keyword="DeidentificationMethodCodeSequence"		Name="De-identification Method Code Sequence"
+(0012,0071) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSeriesID"				Name="Clinical Trial Series ID"
+(0012,0072) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialSeriesDescription"	Name="Clinical Trial Series Description"
+(0012,0081) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialProtocolEthicsCommitteeName"				Name="Clinical Trial Protocol Ethics Committee Name"
+(0012,0082) VERS="3"	VR="LO"   VM="1"	Keyword="ClinicalTrialProtocolEthicsCommitteeApprovalNumber"	Name="Clinical Trial Protocol Ethics Committee Approval Number"
+(0012,0083) VERS="3"	VR="SQ"   VM="1"	Keyword="ConsentForClinicalTrialUseSequence"					Name="Consent for Clinical Trial Use Sequence"
+(0012,0084) VERS="3"	VR="CS"   VM="1"	Keyword="DistributionType"										Name="Distribution Type"
+(0012,0085) VERS="3"	VR="CS"   VM="1"	Keyword="ConsentForDistributionFlag"							Name="Consent for Distribution Flag"
+(0018,0010) VERS="3"	VR="LO"   VM="1"	Keyword="ContrastBolusAgent"			Name="Contrast/Bolus Agent"
+(0018,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="ContrastBolusAgentSequence"		Name="Contrast/Bolus Agent Sequence"
+(0018,0013) VERS="3"	VR="FL"   VM="1"	Keyword="ContrastBolusT1Relaxivity"		Name="Contrast/Bolus T1 Relaxivity"
+(0018,0014) VERS="3"	VR="SQ"   VM="1"	Keyword="ContrastBolusAdministrationRouteSequence"	Name="Contrast/Bolus Administration Route Sequence"
+(0018,0015) VERS="3"	VR="CS"   VM="1"	Keyword="BodyPartExamined"			Name="Body Part Examined"
+(0018,0020) VERS="3"	VR="CS"   VM="1-n"	Keyword="ScanningSequence"			Name="Scanning Sequence"
+(0018,0021) VERS="3"	VR="CS"   VM="1-n"	Keyword="SequenceVariant"			Name="Sequence Variant"
+(0018,0022) VERS="3"	VR="CS"   VM="1-n"	Keyword="ScanOptions"				Name="Scan Options"
+(0018,0023) VERS="3"	VR="CS"   VM="1"	Keyword="MRAcquisitionType"			Name="MR Acquisition Type"
+(0018,0024) VERS="3"	VR="SH"   VM="1"	Keyword="SequenceName"				Name="Sequence Name"
+(0018,0025) VERS="3"	VR="CS"   VM="1"	Keyword="AngioFlag"				Name="Angio Flag"
+(0018,0026) VERS="3"	VR="SQ"   VM="1"	Keyword="InterventionDrugInformationSequence"	Name="Intervention Drug Information Sequence"
+(0018,0027) VERS="3"	VR="TM"   VM="1"	Keyword="InterventionDrugStopTime"		Name="Intervention Drug Stop Time"
+(0018,0028) VERS="3"	VR="DS"   VM="1"	Keyword="InterventionDrugDose"			Name="Intervention Drug Dose"
+(0018,0029) VERS="3"	VR="SQ"   VM="1"	Keyword="InterventionDrugCodeSequence"		Name="Intervention Drug Code Sequence"
+(0018,002A) VERS="3"	VR="SQ"   VM="1"	Keyword="AdditionalDrugSequence"		Name="Additional Drug Sequence"
+(0018,0030) VERS="RET"	VR="LO"   VM="1-n"	Keyword="Radionuclide"				Name="Radionuclide"
+(0018,0031) VERS="3"	VR="LO"   VM="1"	Keyword="Radiopharmaceutical"			Name="Radiopharmaceutical"
+(0018,0032) VERS="RET"	VR="DS"   VM="1"	Keyword="EnergyWindowCenterline"		Name="Energy Window Centerline"
+(0018,0033) VERS="RET"	VR="DS"   VM="1-n"	Keyword="EnergyWindowTotalWidth"		Name="Energy Window Total Width"
+(0018,0034) VERS="3"	VR="LO"   VM="1"	Keyword="InterventionDrugName"			Name="Intervention Drug Name"
+(0018,0035) VERS="3"	VR="TM"   VM="1"	Keyword="InterventionDrugStartTime"		Name="Intervention Drug Start Time"
+(0018,0036) VERS="3"	VR="SQ"   VM="1"	Keyword="InterventionSequence"		Name="Intervention Sequence"
+(0018,0037) VERS="RET"	VR="CS"   VM="1"	Keyword="TherapyType"				Name="Therapy Type"
+(0018,0038) VERS="3"	VR="CS"   VM="1"	Keyword="InterventionStatus"			Name="Intervention Status"
+(0018,0039) VERS="RET"	VR="CS"   VM="1"	Keyword="TherapyDescription"			Name="Therapy Description"
+(0018,003A) VERS="3"	VR="ST"   VM="1"	Keyword="InterventionDescription"			Name="Intervention Description"
+(0018,0040) VERS="3"	VR="IS"   VM="1"	Keyword="CineRate"				Name="Cine Rate"
+(0018,0042) VERS="3"	VR="CS"   VM="1"	Keyword="InitialCineRunState"						Name="Initial Cine Run State"
+(0018,0050) VERS="3"	VR="DS"   VM="1"	Keyword="SliceThickness"			Name="Slice Thickness"
+(0018,0060) VERS="3"	VR="DS"   VM="1"	Keyword="KVP"					Name="KVP"
+(0018,0070) VERS="3"	VR="IS"   VM="1"	Keyword="CountsAccumulated"			Name="Counts Accumulated"
+(0018,0071) VERS="3"	VR="CS"   VM="1"	Keyword="AcquisitionTerminationCondition"	Name="Acquisition Termination Condition"
+(0018,0072) VERS="3"	VR="DS"   VM="1"	Keyword="EffectiveDuration"		Name="Effective Duration"
+(0018,0073) VERS="3"	VR="CS"   VM="1"	Keyword="AcquisitionStartCondition"		Name="Acquisition Start Condition"
+(0018,0074) VERS="3"	VR="IS"   VM="1"	Keyword="AcquisitionStartConditionData"		Name="Acquisition Start Condition Data"
+(0018,0075) VERS="3"	VR="IS"   VM="1"	Keyword="AcquisitionTerminationConditionData"	Name="Acquisition Termination Condition Data"
+(0018,0080) VERS="3"	VR="DS"   VM="1"	Keyword="RepetitionTime"			Name="Repetition Time"
+(0018,0081) VERS="3"	VR="DS"   VM="1"	Keyword="EchoTime"				Name="Echo Time"
+(0018,0082) VERS="3"	VR="DS"   VM="1"	Keyword="InversionTime"				Name="Inversion Time"
+(0018,0083) VERS="3"	VR="DS"   VM="1"	Keyword="NumberOfAverages"			Name="Number of Averages"
+(0018,0084) VERS="3"	VR="DS"   VM="1"	Keyword="ImagingFrequency"			Name="Imaging Frequency"
+(0018,0085) VERS="3"	VR="SH"   VM="1"	Keyword="ImagedNucleus"				Name="Imaged Nucleus"
+(0018,0086) VERS="3"	VR="IS"   VM="1-n"	Keyword="EchoNumbers"				Name="Echo Number(s)"
+(0018,0087) VERS="3"	VR="DS"   VM="1"	Keyword="MagneticFieldStrength"			Name="Magnetic Field Strength"
+(0018,0088) VERS="3"	VR="DS"   VM="1"	Keyword="SpacingBetweenSlices"			Name="Spacing Between Slices"
+(0018,0089) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfPhaseEncodingSteps"		Name="Number of Phase Encoding Steps"
+(0018,0090) VERS="3"	VR="DS"   VM="1"	Keyword="DataCollectionDiameter"		Name="Data Collection Diameter"
+(0018,0091) VERS="3"	VR="IS"   VM="1"	Keyword="EchoTrainLength"			Name="Echo Train Length"
+(0018,0093) VERS="3"	VR="DS"   VM="1"	Keyword="PercentSampling"			Name="Percent Sampling"
+(0018,0094) VERS="3"	VR="DS"   VM="1"	Keyword="PercentPhaseFieldOfView"		Name="Percent Phase Field of View"
+(0018,0095) VERS="3"	VR="DS"   VM="1"	Keyword="PixelBandwidth"			Name="Pixel Bandwidth"
+(0018,1000) VERS="3"	VR="LO"   VM="1"	Keyword="DeviceSerialNumber"			Name="Device Serial Number"
+(0018,1002) VERS="3"	VR="UI"   VM="1"	Keyword="DeviceUID"				Name="Device UID"
+(0018,1003) VERS="3"	VR="LO"   VM="1"	Keyword="DeviceID"				Name="Device ID"
+(0018,1004) VERS="3"	VR="LO"   VM="1"	Keyword="PlateID"				Name="Plate ID"
+(0018,1005) VERS="3"	VR="LO"   VM="1"	Keyword="GeneratorID"			Name="Generator ID"
+(0018,1006) VERS="3"	VR="LO"   VM="1"	Keyword="GridID"				Name="Grid ID"
+(0018,1007) VERS="3"	VR="LO"   VM="1"	Keyword="CassetteID"			Name="Cassette ID"
+(0018,1008) VERS="3"	VR="LO"   VM="1"	Keyword="GantryID"				Name="Gantry ID"
+(0018,1010) VERS="3"	VR="LO"   VM="1"	Keyword="SecondaryCaptureDeviceID"		Name="Secondary Capture Device ID"
+(0018,1011) VERS="RET"	VR="LO"   VM="1"	Keyword="HardcopyCreationDeviceID"		Name="Hardcopy Creation Device ID"
+(0018,1012) VERS="3"	VR="DA"   VM="1"	Keyword="DateOfSecondaryCapture"		Name="Date of Secondary Capture"
+(0018,1014) VERS="3"	VR="TM"   VM="1"	Keyword="TimeOfSecondaryCapture"		Name="Time of Secondary Capture"
+(0018,1016) VERS="3"	VR="LO"   VM="1"	Keyword="SecondaryCaptureDeviceManufacturer"	Name="Secondary Capture Device Manufacturer"
+(0018,1017) VERS="RET"	VR="LO"   VM="1"	Keyword="HardcopyDeviceManufacturer"		Name="Hardcopy Device Manufacturer"
+(0018,1018) VERS="3"	VR="LO"   VM="1"	Keyword="SecondaryCaptureDeviceManufacturerModelName"	Name="Secondary Capture Device Manufacturer's Model Name"
+(0018,1019) VERS="3"	VR="LO"   VM="1-n"	Keyword="SecondaryCaptureDeviceSoftwareVersions"	Name="Secondary Capture Device Software Versions"
+(0018,101A) VERS="RET"	VR="LO"   VM="1-n"	Keyword="HardcopyDeviceSoftwareVersion"		Name="Hardcopy Device Software Version"
+(0018,101B) VERS="RET"	VR="LO"   VM="1"	Keyword="HardcopyDeviceManufacturerModelName"	Name="Hardcopy Device Manufacturer's Model Name"
+(0018,1020) VERS="3"	VR="LO"   VM="1-n"	Keyword="SoftwareVersions"			Name="Software Version(s)"
+(0018,1022) VERS="3"	VR="SH"   VM="1"	Keyword="VideoImageFormatAcquired"		Name="Video Image Format Acquired"
+(0018,1023) VERS="3"	VR="LO"   VM="1"	Keyword="DigitalImageFormatAcquired"		Name="Digital Image Format Acquired"
+(0018,1030) VERS="3"	VR="LO"   VM="1"	Keyword="ProtocolName"				Name="Protocol Name"
+(0018,1040) VERS="3"	VR="LO"   VM="1"	Keyword="ContrastBolusRoute"			Name="Contrast/Bolus Route"
+(0018,1041) VERS="3"	VR="DS"   VM="1"	Keyword="ContrastBolusVolume"			Name="Contrast/Bolus Volume"
+(0018,1042) VERS="3"	VR="TM"   VM="1"	Keyword="ContrastBolusStartTime"		Name="Contrast/Bolus Start Time"
+(0018,1043) VERS="3"	VR="TM"   VM="1"	Keyword="ContrastBolusStopTime"			Name="Contrast/Bolus Stop Time"
+(0018,1044) VERS="3"	VR="DS"   VM="1"	Keyword="ContrastBolusTotalDose"		Name="Contrast/Bolus Total Dose"
+(0018,1045) VERS="3"	VR="IS"   VM="1"	Keyword="SyringeCounts"				Name="Syringe Counts"
+(0018,1046) VERS="3"	VR="DS"   VM="1-n"	Keyword="ContrastFlowRate"			Name="Contrast Flow Rate"
+(0018,1047) VERS="3"	VR="DS"   VM="1-n"	Keyword="ContrastFlowDuration"			Name="Contrast Flow Duration"
+(0018,1048) VERS="3"	VR="CS"   VM="1"	Keyword="ContrastBolusIngredient"		Name="Contrast/Bolus Ingredient"
+(0018,1049) VERS="3"	VR="DS"   VM="1"	Keyword="ContrastBolusIngredientConcentration"	Name="Contrast/Bolus Ingredient Concentration"
+(0018,1050) VERS="3"	VR="DS"   VM="1"	Keyword="SpatialResolution"			Name="Spatial Resolution"
+(0018,1060) VERS="3"	VR="DS"   VM="1"	Keyword="TriggerTime"				Name="Trigger Time"
+(0018,1061) VERS="3"	VR="LO"   VM="1"	Keyword="TriggerSourceOrType"			Name="Trigger Source or Type"
+(0018,1062) VERS="3"	VR="IS"   VM="1"	Keyword="NominalInterval"			Name="Nominal Interval"
+(0018,1063) VERS="3"	VR="DS"   VM="1"	Keyword="FrameTime"				Name="Frame Time"
+(0018,1064) VERS="3"	VR="LO"   VM="1"	Keyword="CardiacFramingType"				Name="Cardiac Framing Type"
+(0018,1065) VERS="3"	VR="DS"   VM="1-n"	Keyword="FrameTimeVector"			Name="Frame Time Vector"
+(0018,1066) VERS="3"	VR="DS"   VM="1"	Keyword="FrameDelay"				Name="Frame Delay"
+(0018,1067) VERS="3"	VR="DS"   VM="1"	Keyword="ImageTriggerDelay"			Name="Image Trigger Delay"
+(0018,1068) VERS="3"	VR="DS"   VM="1"	Keyword="MultiplexGroupTimeOffset"		Name="Multiplex Group Time Offset"
+(0018,1069) VERS="3"	VR="DS"   VM="1"	Keyword="TriggerTimeOffset"			Name="Trigger Time Offset"
+(0018,106A) VERS="3"	VR="CS"   VM="1"	Keyword="SynchronizationTrigger"		Name="Synchronization Trigger"
+(0018,106C) VERS="3"	VR="US"   VM="2"	Keyword="SynchronizationChannel"		Name="Synchronization Channel"
+(0018,106E) VERS="3"	VR="UL"   VM="1"	Keyword="TriggerSamplePosition"			Name="Trigger Sample Position"
+(0018,1070) VERS="3"	VR="LO"   VM="1"	Keyword="RadiopharmaceuticalRoute"		Name="Radiopharmaceutical Route"
+(0018,1071) VERS="3"	VR="DS"   VM="1"	Keyword="RadiopharmaceuticalVolume"		Name="Radiopharmaceutical Volume"
+(0018,1072) VERS="3"	VR="TM"   VM="1"	Keyword="RadiopharmaceuticalStartTime"		Name="Radiopharmaceutical Start Time"
+(0018,1073) VERS="3"	VR="TM"   VM="1"	Keyword="RadiopharmaceuticalStopTime"		Name="Radiopharmaceutical Stop Time"
+(0018,1074) VERS="3"	VR="DS"   VM="1"	Keyword="RadionuclideTotalDose"			Name="Radionuclide Total Dose"
+(0018,1075) VERS="3"	VR="DS"   VM="1"	Keyword="RadionuclideHalfLife"			Name="Radionuclide Half Life"
+(0018,1076) VERS="3"	VR="DS"   VM="1"	Keyword="RadionuclidePositronFraction"		Name="Radionuclide Positron Fraction"
+(0018,1077) VERS="3"	VR="DS"   VM="1"	Keyword="RadiopharmaceuticalSpecificActivity"	Name="Radiopharmaceutical Specific Activity"
+(0018,1078) VERS="3"	VR="DT"   VM="1"	Keyword="RadiopharmaceuticalStartDateTime"		Name="Radiopharmaceutical Start DateTime"
+(0018,1079) VERS="3"	VR="DT"   VM="1"	Keyword="RadiopharmaceuticalStopDateTime"		Name="Radiopharmaceutical Stop DateTime"
+(0018,1080) VERS="3"	VR="CS"   VM="1"	Keyword="BeatRejectionFlag"			Name="Beat Rejection Flag"
+(0018,1081) VERS="3"	VR="IS"   VM="1"	Keyword="LowRRValue"				Name="Low R-R Value"
+(0018,1082) VERS="3"	VR="IS"   VM="1"	Keyword="HighRRValue"				Name="High R-R Value"
+(0018,1083) VERS="3"	VR="IS"   VM="1"	Keyword="IntervalsAcquired"			Name="Intervals Acquired"
+(0018,1084) VERS="3"	VR="IS"   VM="1"	Keyword="IntervalsRejected"			Name="Intervals Rejected"
+(0018,1085) VERS="3"	VR="LO"   VM="1"	Keyword="PVCRejection"				Name="PVC Rejection"
+(0018,1086) VERS="3"	VR="IS"   VM="1"	Keyword="SkipBeats"				Name="Skip Beats"
+(0018,1088) VERS="3"	VR="IS"   VM="1"	Keyword="HeartRate"				Name="Heart Rate"
+(0018,1090) VERS="3"	VR="IS"   VM="1"	Keyword="CardiacNumberOfImages"			Name="Cardiac Number of Images"
+(0018,1094) VERS="3"	VR="IS"   VM="1"	Keyword="TriggerWindow"				Name="Trigger Window"
+(0018,1100) VERS="3"	VR="DS"   VM="1"	Keyword="ReconstructionDiameter"		Name="Reconstruction Diameter"
+(0018,1110) VERS="3"	VR="DS"   VM="1"	Keyword="DistanceSourceToDetector"		Name="Distance Source to Detector"
+(0018,1111) VERS="3"	VR="DS"   VM="1"	Keyword="DistanceSourceToPatient"		Name="Distance Source to Patient"
+(0018,1114) VERS="3"	VR="DS"   VM="1"	Keyword="EstimatedRadiographicMagnificationFactor"	Name="Estimated Radiographic Magnification Factor"
+(0018,1120) VERS="3"	VR="DS"   VM="1"	Keyword="GantryDetectorTilt"			Name="Gantry/Detector Tilt"
+(0018,1121) VERS="3"	VR="DS"   VM="1"	Keyword="GantryDetectorSlew"			Name="Gantry/Detector Slew"
+(0018,1130) VERS="3"	VR="DS"   VM="1"	Keyword="TableHeight"				Name="Table Height"
+(0018,1131) VERS="3"	VR="DS"   VM="1"	Keyword="TableTraverse"				Name="Table Traverse"
+(0018,1134) VERS="3"	VR="CS"   VM="1"	Keyword="TableMotion"				Name="Table Motion"
+(0018,1135) VERS="3"	VR="DS"   VM="1-n"	Keyword="TableVerticalIncrement"		Name="Table Vertical Increment"
+(0018,1136) VERS="3"	VR="DS"   VM="1-n"	Keyword="TableLateralIncrement"			Name="Table Lateral Increment"
+(0018,1137) VERS="3"	VR="DS"   VM="1-n"	Keyword="TableLongitudinalIncrement"		Name="Table Longitudinal Increment"
+(0018,1138) VERS="3"	VR="DS"   VM="1"	Keyword="TableAngle"				Name="Table Angle"
+(0018,113A) VERS="3"	VR="CS"   VM="1"	Keyword="TableType"				Name="Table Type"
+(0018,1140) VERS="3"	VR="CS"   VM="1"	Keyword="RotationDirection"			Name="Rotation Direction"
+(0018,1141) VERS="RET"	VR="DS"   VM="1"	Keyword="AngularPosition"			Name="Angular Position"
+(0018,1142) VERS="3"	VR="DS"   VM="1-n"	Keyword="RadialPosition"			Name="Radial Position"
+(0018,1143) VERS="3"	VR="DS"   VM="1"	Keyword="ScanArc"				Name="Scan Arc"
+(0018,1144) VERS="3"	VR="DS"   VM="1"	Keyword="AngularStep"				Name="Angular Step"
+(0018,1145) VERS="3"	VR="DS"   VM="1"	Keyword="CenterOfRotationOffset"		Name="Center of Rotation Offset"
+(0018,1146) VERS="RET"	VR="DS"   VM="1-n"	Keyword="RotationOffset"			Name="Rotation Offset"
+(0018,1147) VERS="3"	VR="CS"   VM="1"	Keyword="FieldOfViewShape"			Name="Field of View Shape"
+(0018,1149) VERS="3"	VR="IS"   VM="1-2"	Keyword="FieldOfViewDimensions"			Name="Field of View Dimension(s)"
+(0018,1150) VERS="3"	VR="IS"   VM="1"	Keyword="ExposureTime"				Name="Exposure Time"
+(0018,1151) VERS="3"	VR="IS"   VM="1"	Keyword="XRayTubeCurrent"			Name="X-Ray Tube Current"
+(0018,1152) VERS="3"	VR="IS"   VM="1"	Keyword="Exposure"				Name="Exposure"
+(0018,1153) VERS="3"	VR="IS"   VM="1"	Keyword="ExposureInuAs"				Name="Exposure in uAs"
+(0018,1154) VERS="3"	VR="DS"   VM="1"	Keyword="AveragePulseWidth"			Name="Average Pulse Width"
+(0018,1155) VERS="3"	VR="CS"   VM="1"	Keyword="RadiationSetting"			Name="Radiation Setting"
+(0018,1156) VERS="3"	VR="CS"   VM="1"	Keyword="RectificationType"			Name="Rectification Type"
+(0018,115A) VERS="3"	VR="CS"   VM="1"	Keyword="RadiationMode"				Name="Radiation Mode"
+(0018,115E) VERS="3"	VR="DS"   VM="1"	Keyword="ImageAndFluoroscopyAreaDoseProduct"			Name="Image and Fluoroscopy Area Dose Product"
+(0018,1160) VERS="3"	VR="SH"   VM="1"	Keyword="FilterType"				Name="Filter Type"
+(0018,1161) VERS="3"	VR="LO"   VM="1-n"	Keyword="TypeOfFilters"				Name="Type of Filters"
+(0018,1162) VERS="3"	VR="DS"   VM="1"	Keyword="IntensifierSize"			Name="Intensifier Size"
+(0018,1164) VERS="3"	VR="DS"   VM="2"	Keyword="ImagerPixelSpacing"			Name="Imager Pixel Spacing"
+(0018,1166) VERS="3"	VR="CS"   VM="1-n"	Keyword="Grid"					Name="Grid"
+(0018,1170) VERS="3"	VR="IS"   VM="1"	Keyword="GeneratorPower"			Name="Generator Power"
+(0018,1180) VERS="3"	VR="SH"   VM="1"	Keyword="CollimatorGridName"			Name="Collimator/grid Name"
+(0018,1181) VERS="3"	VR="CS"   VM="1"	Keyword="CollimatorType"			Name="Collimator Type"
+(0018,1182) VERS="3"	VR="IS"   VM="1-2"	Keyword="FocalDistance"				Name="Focal Distance"
+(0018,1183) VERS="3"	VR="DS"   VM="1-2"	Keyword="XFocusCenter"				Name="X Focus Center"
+(0018,1184) VERS="3"	VR="DS"   VM="1-2"	Keyword="YFocusCenter"				Name="Y Focus Center"
+(0018,1190) VERS="3"	VR="DS"   VM="1-n"	Keyword="FocalSpots"				Name="Focal Spot(s)"
+(0018,1191) VERS="3"	VR="CS"   VM="1"	Keyword="AnodeTargetMaterial"			Name="Anode Target Material"
+(0018,11A0) VERS="3"	VR="DS"   VM="1"	Keyword="BodyPartThickness"			Name="Body Part Thickness"
+(0018,11A2) VERS="3"	VR="DS"   VM="1"	Keyword="CompressionForce"			Name="Compression Force"
+(0018,11A4) VERS="3"	VR="LO"   VM="1"	Keyword="PaddleDescription"			Name="Paddle Description"
+(0018,1200) VERS="3"	VR="DA"   VM="1-n"	Keyword="DateOfLastCalibration"			Name="Date of Last Calibration"
+(0018,1201) VERS="3"	VR="TM"   VM="1-n"	Keyword="TimeOfLastCalibration"			Name="Time of Last Calibration"
+(0018,1202) VERS="3"	VR="DT"   VM="1"	Keyword="DateTimeOfLastCalibration"		Name="DateTime of Last Calibration"
+(0018,1210) VERS="3"	VR="SH"   VM="1-n"	Keyword="ConvolutionKernel"			Name="Convolution Kernel"
+(0018,1240) VERS="RET"	VR="IS"   VM="1-n"	Keyword="UpperLowerPixelValues"			Name="Upper/Lower Pixel Values"
+(0018,1242) VERS="3"	VR="IS"   VM="1"	Keyword="ActualFrameDuration"			Name="Actual Frame Duration"
+(0018,1243) VERS="3"	VR="IS"   VM="1"	Keyword="CountRate"				Name="Count Rate"
+(0018,1244) VERS="3"	VR="US"   VM="1"	Keyword="PreferredPlaybackSequencing"		Name="Preferred Playback Sequencing"
+(0018,1250) VERS="3"	VR="SH"   VM="1"	Keyword="ReceiveCoilName"			Name="Receive Coil Name"
+(0018,1251) VERS="3"	VR="SH"   VM="1"	Keyword="TransmitCoilName"			Name="Transmit Coil Name"
+(0018,1260) VERS="3"	VR="SH"   VM="1"	Keyword="PlateType"				Name="Plate Type"
+(0018,1261) VERS="3"	VR="LO"   VM="1"	Keyword="PhosphorType"				Name="Phosphor Type"
+(0018,1300) VERS="3"	VR="DS"   VM="1"	Keyword="ScanVelocity"				Name="Scan Velocity"
+(0018,1301) VERS="3"	VR="CS"   VM="1-n"	Keyword="WholeBodyTechnique"			Name="Whole Body Technique"
+(0018,1302) VERS="3"	VR="IS"   VM="1"	Keyword="ScanLength"				Name="Scan Length"
+(0018,1310) VERS="3"	VR="US"   VM="4"	Keyword="AcquisitionMatrix"			Name="Acquisition Matrix"
+(0018,1312) VERS="3"	VR="CS"   VM="1"	Keyword="InPlanePhaseEncodingDirection"		Name="In-plane Phase Encoding Direction"
+(0018,1314) VERS="3"	VR="DS"   VM="1"	Keyword="FlipAngle"				Name="Flip Angle"
+(0018,1315) VERS="3"	VR="CS"   VM="1"	Keyword="VariableFlipAngleFlag"			Name="Variable Flip Angle Flag"
+(0018,1316) VERS="3"	VR="DS"   VM="1"	Keyword="SAR"					Name="SAR"
+(0018,1318) VERS="3"	VR="DS"   VM="1"	Keyword="dBdt"					Name="dB/dt"
+(0018,1320) VERS="3"	VR="FL"   VM="1"	Keyword="B1rms"					Name="B1rms"
+(0018,1400) VERS="3"	VR="LO"   VM="1"	Keyword="AcquisitionDeviceProcessingDescription"	Name="Acquisition Device Processing Description"
+(0018,1401) VERS="3"	VR="LO"   VM="1"	Keyword="AcquisitionDeviceProcessingCode"	Name="Acquisition Device Processing Code"
+(0018,1402) VERS="3"	VR="CS"   VM="1"	Keyword="CassetteOrientation"			Name="Cassette Orientation"
+(0018,1403) VERS="3"	VR="CS"   VM="1"	Keyword="CassetteSize"				Name="Cassette Size"
+(0018,1404) VERS="3"	VR="US"   VM="1"	Keyword="ExposuresOnPlate"			Name="Exposures on Plate"
+(0018,1405) VERS="3"	VR="IS"   VM="1"	Keyword="RelativeXRayExposure"			Name="Relative X-Ray Exposure"
+(0018,1411) VERS="3"	VR="DS"   VM="1"	Keyword="ExposureIndex"					Name="Exposure Index"
+(0018,1412) VERS="3"	VR="DS"   VM="1"	Keyword="TargetExposureIndex"			Name="Target Exposure Index"
+(0018,1413) VERS="3"	VR="DS"   VM="1"	Keyword="DeviationIndex"				Name="Deviation Index"
+(0018,1450) VERS="3"	VR="DS"   VM="1"	Keyword="ColumnAngulation"			Name="Column Angulation"
+(0018,1460) VERS="3"	VR="DS"   VM="1"	Keyword="TomoLayerHeight"			Name="Tomo Layer Height"
+(0018,1470) VERS="3"	VR="DS"   VM="1"	Keyword="TomoAngle"				Name="Tomo Angle"
+(0018,1480) VERS="3"	VR="DS"   VM="1"	Keyword="TomoTime"				Name="Tomo Time"
+(0018,1490) VERS="3"	VR="CS"   VM="1"	Keyword="TomoType"				Name="Tomo Type"
+(0018,1491) VERS="3"	VR="CS"   VM="1"	Keyword="TomoClass"				Name="Tomo Class"
+(0018,1495) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfTomosynthesisSourceImages"	Name="Number of Tomosynthesis Source Images"
+(0018,1500) VERS="3"	VR="CS"   VM="1"	Keyword="PositionerMotion"			Name="Positioner Motion"
+(0018,1508) VERS="3"	VR="CS"   VM="1"	Keyword="PositionerType"			Name="Positioner Type"
+(0018,1510) VERS="3"	VR="DS"   VM="1"	Keyword="PositionerPrimaryAngle"		Name="Positioner Primary Angle"
+(0018,1511) VERS="3"	VR="DS"   VM="1"	Keyword="PositionerSecondaryAngle"		Name="Positioner Secondary Angle"
+(0018,1520) VERS="3"	VR="DS"   VM="1-n"	Keyword="PositionerPrimaryAngleIncrement"	Name="Positioner Primary Angle Increment"
+(0018,1521) VERS="3"	VR="DS"   VM="1-n"	Keyword="PositionerSecondaryAngleIncrement"	Name="Positioner Secondary Angle Increment"
+(0018,1530) VERS="3"	VR="DS"   VM="1"	Keyword="DetectorPrimaryAngle"			Name="Detector Primary Angle"
+(0018,1531) VERS="3"	VR="DS"   VM="1"	Keyword="DetectorSecondaryAngle"		Name="Detector Secondary Angle"
+(0018,1600) VERS="3"	VR="CS"   VM="1-3"	Keyword="ShutterShape"				Name="Shutter Shape"
+(0018,1602) VERS="3"	VR="IS"   VM="1"	Keyword="ShutterLeftVerticalEdge"		Name="Shutter Left Vertical Edge"
+(0018,1604) VERS="3"	VR="IS"   VM="1"	Keyword="ShutterRightVerticalEdge"		Name="Shutter Right Vertical Edge"
+(0018,1606) VERS="3"	VR="IS"   VM="1"	Keyword="ShutterUpperHorizontalEdge"		Name="Shutter Upper Horizontal Edge"
+(0018,1608) VERS="3"	VR="IS"   VM="1"	Keyword="ShutterLowerHorizontalEdge"		Name="Shutter Lower Horizontal Edge"
+(0018,1610) VERS="3"	VR="IS"   VM="2"	Keyword="CenterOfCircularShutter"		Name="Center of Circular Shutter"
+(0018,1612) VERS="3"	VR="IS"   VM="1"	Keyword="RadiusOfCircularShutter"		Name="Radius of Circular Shutter"
+(0018,1620) VERS="3"	VR="IS"   VM="2-2n"	Keyword="VerticesOfThePolygonalShutter"		Name="Vertices of the Polygonal Shutter"
+(0018,1622) VERS="3"	VR="US"   VM="1"	Keyword="ShutterPresentationValue"			Name="Shutter Presentation Value"
+(0018,1623) VERS="3"	VR="US"   VM="1"	Keyword="ShutterOverlayGroup"				Name="Shutter Overlay Group"
+(0018,1624) VERS="3"	VR="US"   VM="3"	Keyword="ShutterPresentationColorCIELabValue"		Name="Shutter Presentation Color CIELab Value"
+(0018,1700) VERS="3"	VR="CS"   VM="1-3"	Keyword="CollimatorShape"			Name="Collimator Shape"
+(0018,1702) VERS="3"	VR="IS"   VM="1"	Keyword="CollimatorLeftVerticalEdge"		Name="Collimator Left Vertical Edge"
+(0018,1704) VERS="3"	VR="IS"   VM="1"	Keyword="CollimatorRightVerticalEdge"		Name="Collimator Right Vertical Edge"
+(0018,1706) VERS="3"	VR="IS"   VM="1"	Keyword="CollimatorUpperHorizontalEdge"		Name="Collimator Upper Horizontal Edge"
+(0018,1708) VERS="3"	VR="IS"   VM="1"	Keyword="CollimatorLowerHorizontalEdge"		Name="Collimator Lower Horizontal Edge"
+(0018,1710) VERS="3"	VR="IS"   VM="2"	Keyword="CenterOfCircularCollimator"		Name="Center of Circular Collimator"
+(0018,1712) VERS="3"	VR="IS"   VM="1"	Keyword="RadiusOfCircularCollimator"		Name="Radius of Circular Collimator"
+(0018,1720) VERS="3"	VR="IS"   VM="2-2n"	Keyword="VerticesOfThePolygonalCollimator"		Name="Vertices of the Polygonal Collimator"
+(0018,1800) VERS="3"	VR="CS"   VM="1"	Keyword="AcquisitionTimeSynchronized"		Name="Acquisition Time Synchronized"
+(0018,1801) VERS="3"	VR="SH"   VM="1"	Keyword="TimeSource"				Name="Time Source"
+(0018,1802) VERS="3"	VR="CS"   VM="1"	Keyword="TimeDistributionProtocol"		Name="Time Distribution Protocol"
+(0018,1803) VERS="3"	VR="LO"   VM="1"	Keyword="NTPSourceAddress"			Name="NTP Source Address"
+(0018,2001) VERS="3"	VR="IS"   VM="1-n"	Keyword="PageNumberVector"			Name="Page Number Vector"
+(0018,2002) VERS="3"	VR="SH"   VM="1-n"	Keyword="FrameLabelVector"			Name="Frame Label Vector"
+(0018,2003) VERS="3"	VR="DS"   VM="1-n"	Keyword="FramePrimaryAngleVector"		Name="Frame Primary Angle Vector"
+(0018,2004) VERS="3"	VR="DS"   VM="1-n"	Keyword="FrameSecondaryAngleVector"		Name="Frame Secondary Angle Vector"
+(0018,2005) VERS="3"	VR="DS"   VM="1-n"	Keyword="SliceLocationVector"			Name="Slice Location Vector"
+(0018,2006) VERS="3"	VR="SH"   VM="1-n"	Keyword="DisplayWindowLabelVector"		Name="Display Window Label Vector"
+(0018,2010) VERS="3"	VR="DS"   VM="2"	Keyword="NominalScannedPixelSpacing"		Name="Nominal Scanned Pixel Spacing"
+(0018,2020) VERS="3"	VR="CS"   VM="1"	Keyword="DigitizingDeviceTransportDirection"	Name="Digitizing Device Transport Direction"
+(0018,2030) VERS="3"	VR="DS"   VM="1"	Keyword="RotationOfScannedFilm"			Name="Rotation of Scanned Film"
+(0018,2041) VERS="3"	VR="SQ"   VM="1"	Keyword="BiopsyTargetSequence"		Name="Biopsy Target Sequence"
+(0018,2042) VERS="3"	VR="UI"   VM="1"	Keyword="TargetUID"					Name="Target UID"
+(0018,2043) VERS="3"	VR="FL"   VM="2"	Keyword="LocalizingCursorPosition"	Name="Localizing Cursor Position"
+(0018,2044) VERS="3"	VR="FL"   VM="3"	Keyword="CalculatedTargetPosition"	Name="Calculated Target Position"
+(0018,2045) VERS="3"	VR="SH"   VM="1"	Keyword="TargetLabel"				Name="Target Label"
+(0018,2046) VERS="3"	VR="FL"   VM="1"	Keyword="DisplayedZValue"			Name="Displayed Z Value"
+(0018,3100) VERS="3"	VR="CS"   VM="1"	Keyword="IVUSAcquisition"			Name="IVUS Acquisition"
+(0018,3101) VERS="3"	VR="DS"   VM="1"	Keyword="IVUSPullbackRate"			Name="IVUS Pullback Rate"
+(0018,3102) VERS="3"	VR="DS"   VM="1"	Keyword="IVUSGatedRate"				Name="IVUS Gated Rate"
+(0018,3103) VERS="3"	VR="IS"   VM="1"	Keyword="IVUSPullbackStartFrameNumber"		Name="IVUS Pullback Start Frame Number"
+(0018,3104) VERS="3"	VR="IS"   VM="1"	Keyword="IVUSPullbackStopFrameNumber"		Name="IVUS Pullback Stop Frame Number"
+(0018,3105) VERS="3"	VR="IS"   VM="1-n"	Keyword="LesionNumber"				Name="Lesion Number"
+(0018,4000) VERS="RET"	VR="LT"   VM="1"	Keyword="AcquisitionComments"			Name="Acquisition Comments"
+(0018,5000) VERS="3"	VR="SH"   VM="1-n"	Keyword="OutputPower"				Name="Output Power"
+(0018,5010) VERS="3"	VR="LO"   VM="1-n"	Keyword="TransducerData"			Name="Transducer Data"
+(0018,5012) VERS="3"	VR="DS"   VM="1"	Keyword="FocusDepth"				Name="Focus Depth"
+(0018,5020) VERS="3"	VR="LO"   VM="1"	Keyword="ProcessingFunction"			Name="Processing Function"
+(0018,5021) VERS="RET"	VR="LO"   VM="1"	Keyword="PostprocessingFunction"		Name="Postprocessing Function"
+(0018,5022) VERS="3"	VR="DS"   VM="1"	Keyword="MechanicalIndex"			Name="Mechanical Index"
+(0018,5024) VERS="3"	VR="DS"   VM="1"	Keyword="BoneThermalIndex"			Name="Bone Thermal Index"
+(0018,5026) VERS="3"	VR="DS"   VM="1"	Keyword="CranialThermalIndex"			Name="Cranial Thermal Index"
+(0018,5027) VERS="3"	VR="DS"   VM="1"	Keyword="SoftTissueThermalIndex"		Name="Soft Tissue Thermal Index"
+(0018,5028) VERS="3"	VR="DS"   VM="1"	Keyword="SoftTissueFocusThermalIndex"		Name="Soft Tissue-focus Thermal Index"
+(0018,5029) VERS="3"	VR="DS"   VM="1"	Keyword="SoftTissueSurfaceThermalIndex"		Name="Soft Tissue-surface Thermal Index"
+(0018,5030) VERS="RET"	VR="DS"   VM="1"	Keyword="DynamicRange"				Name="Dynamic Range"
+(0018,5040) VERS="RET"	VR="DS"   VM="1"	Keyword="TotalGain"				Name="Total Gain"
+(0018,5050) VERS="3"	VR="IS"   VM="1"	Keyword="DepthOfScanField"			Name="Depth of Scan Field"
+(0018,5100) VERS="3"	VR="CS"   VM="1"	Keyword="PatientPosition"			Name="Patient Position"
+(0018,5101) VERS="3"	VR="CS"   VM="1"	Keyword="ViewPosition"				Name="View Position"
+(0018,5104) VERS="3"	VR="SQ"   VM="1"	Keyword="ProjectionEponymousNameCodeSequence"	Name="Projection Eponymous Name Code Sequence"
+(0018,5210) VERS="RET"	VR="DS"   VM="6"	Keyword="ImageTransformationMatrix"		Name="Image Transformation Matrix"
+(0018,5212) VERS="RET"	VR="DS"   VM="3"	Keyword="ImageTranslationVector"		Name="Image Translation Vector"
+(0018,6000) VERS="3"	VR="DS"   VM="1"	Keyword="Sensitivity"				Name="Sensitivity"
+(0018,6011) VERS="3"	VR="SQ"   VM="1"	Keyword="SequenceOfUltrasoundRegions"		Name="Sequence of Ultrasound Regions"
+(0018,6012) VERS="3"	VR="US"   VM="1"	Keyword="RegionSpatialFormat"			Name="Region Spatial Format"
+(0018,6014) VERS="3"	VR="US"   VM="1"	Keyword="RegionDataType"			Name="Region Data Type"
+(0018,6016) VERS="3"	VR="UL"   VM="1"	Keyword="RegionFlags"				Name="Region Flags"
+(0018,6018) VERS="3"	VR="UL"   VM="1"	Keyword="RegionLocationMinX0"			Name="Region Location Min X0"
+(0018,601A) VERS="3"	VR="UL"   VM="1"	Keyword="RegionLocationMinY0"			Name="Region Location Min Y0"
+(0018,601C) VERS="3"	VR="UL"   VM="1"	Keyword="RegionLocationMaxX1"			Name="Region Location Max X1"
+(0018,601E) VERS="3"	VR="UL"   VM="1"	Keyword="RegionLocationMaxY1"			Name="Region Location Max Y1"
+(0018,6020) VERS="3"	VR="SL"   VM="1"	Keyword="ReferencePixelX0"			Name="Reference Pixel X0"
+(0018,6022) VERS="3"	VR="SL"   VM="1"	Keyword="ReferencePixelY0"			Name="Reference Pixel Y0"
+(0018,6024) VERS="3"	VR="US"   VM="1"	Keyword="PhysicalUnitsXDirection"		Name="Physical Units X Direction"
+(0018,6026) VERS="3"	VR="US"   VM="1"	Keyword="PhysicalUnitsYDirection"		Name="Physical Units Y Direction"
+(0018,6028) VERS="3"	VR="FD"   VM="1"	Keyword="ReferencePixelPhysicalValueX"		Name="Reference Pixel Physical Value X"
+(0018,602A) VERS="3"	VR="FD"   VM="1"	Keyword="ReferencePixelPhysicalValueY"		Name="Reference Pixel Physical Value Y"
+(0018,602C) VERS="3"	VR="FD"   VM="1"	Keyword="PhysicalDeltaX"			Name="Physical Delta X"
+(0018,602E) VERS="3"	VR="FD"   VM="1"	Keyword="PhysicalDeltaY"			Name="Physical Delta Y"
+(0018,6030) VERS="3"	VR="UL"   VM="1"	Keyword="TransducerFrequency"			Name="Transducer Frequency"
+(0018,6031) VERS="3"	VR="CS"   VM="1"	Keyword="TransducerType"			Name="Transducer Type"
+(0018,6032) VERS="3"	VR="UL"   VM="1"	Keyword="PulseRepetitionFrequency"		Name="Pulse Repetition Frequency"
+(0018,6034) VERS="3"	VR="FD"   VM="1"	Keyword="DopplerCorrectionAngle"		Name="Doppler Correction Angle"
+(0018,6036) VERS="3"	VR="FD"   VM="1"	Keyword="SteeringAngle"				Name="Steering Angle"
+(0018,6038) VERS="RET"	VR="UL"   VM="1"	Keyword="DopplerSampleVolumeXPositionRetired"	Name="Doppler Sample Volume X Position (Retired)"
+(0018,6039) VERS="3"	VR="SL"   VM="1"	Keyword="DopplerSampleVolumeXPosition"		Name="Doppler Sample Volume X Position"
+(0018,603A) VERS="RET"	VR="UL"   VM="1"	Keyword="DopplerSampleVolumeYPositionRetired"	Name="Doppler Sample Volume Y Position (Retired)"
+(0018,603B) VERS="3"	VR="SL"   VM="1"	Keyword="DopplerSampleVolumeYPosition"		Name="Doppler Sample Volume Y Position"
+(0018,603C) VERS="RET"	VR="UL"   VM="1"	Keyword="TMLinePositionX0Retired"		Name="TM-Line Position X0 (Retired)"
+(0018,603D) VERS="3"	VR="SL"   VM="1"	Keyword="TMLinePositionX0"			Name="TM-Line Position X0"
+(0018,603E) VERS="RET"	VR="UL"   VM="1"	Keyword="TMLinePositionY0Retired"		Name="TM-Line Position Y0 (Retired)"
+(0018,603F) VERS="3"	VR="SL"   VM="1"	Keyword="TMLinePositionY0"			Name="TM-Line Position Y0"
+(0018,6040) VERS="RET"	VR="UL"   VM="1"	Keyword="TMLinePositionX1Retired"		Name="TM-Line Position X1 (Retired)"
+(0018,6041) VERS="3"	VR="SL"   VM="1"	Keyword="TMLinePositionX1"			Name="TM-Line Position X1"
+(0018,6042) VERS="RET"	VR="UL"   VM="1"	Keyword="TMLinePositionY1Retired"		Name="TM-Line Position Y1 (Retired)"
+(0018,6043) VERS="3"	VR="SL"   VM="1"	Keyword="TMLinePositionY1"			Name="TM-Line Position Y1"
+(0018,6044) VERS="3"	VR="US"   VM="1"	Keyword="PixelComponentOrganization"		Name="Pixel Component Organization"
+(0018,6046) VERS="3"	VR="UL"   VM="1"	Keyword="PixelComponentMask"			Name="Pixel Component Mask"
+(0018,6048) VERS="3"	VR="UL"   VM="1"	Keyword="PixelComponentRangeStart"		Name="Pixel Component Range Start"
+(0018,604A) VERS="3"	VR="UL"   VM="1"	Keyword="PixelComponentRangeStop"		Name="Pixel Component Range Stop"
+(0018,604C) VERS="3"	VR="US"   VM="1"	Keyword="PixelComponentPhysicalUnits"		Name="Pixel Component Physical Units"
+(0018,604E) VERS="3"	VR="US"   VM="1"	Keyword="PixelComponentDataType"		Name="Pixel Component Data Type"
+(0018,6050) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfTableBreakPoints"		Name="Number of Table Break Points"
+(0018,6052) VERS="3"	VR="UL"   VM="1-n"	Keyword="TableOfXBreakPoints"			Name="Table of X Break Points"
+(0018,6054) VERS="3"	VR="FD"   VM="1-n"	Keyword="TableOfYBreakPoints"			Name="Table of Y Break Points"
+(0018,6056) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfTableEntries"			Name="Number of Table Entries"
+(0018,6058) VERS="3"	VR="UL"   VM="1-n"	Keyword="TableOfPixelValues"			Name="Table of Pixel Values"
+(0018,605A) VERS="3"	VR="FL"   VM="1-n"	Keyword="TableOfParameterValues"		Name="Table of Parameter Values"
+(0018,6060) VERS="3"	VR="FL"   VM="1-n"	Keyword="RWaveTimeVector"		Name="R Wave Time Vector"
+(0018,7000) VERS="3"	VR="CS"   VM="1"	Keyword="DetectorConditionsNominalFlag"		Name="Detector Conditions Nominal Flag"
+(0018,7001) VERS="3"	VR="DS"   VM="1"	Keyword="DetectorTemperature"			Name="Detector Temperature"
+(0018,7004) VERS="3"	VR="CS"   VM="1"	Keyword="DetectorType"				Name="Detector Type"
+(0018,7005) VERS="3"	VR="CS"   VM="1"	Keyword="DetectorConfiguration"			Name="Detector Configuration"
+(0018,7006) VERS="3"	VR="LT"   VM="1"	Keyword="DetectorDescription"			Name="Detector Description"
+(0018,7008) VERS="3"	VR="LT"   VM="1"	Keyword="DetectorMode"				Name="Detector Mode"
+(0018,700A) VERS="3"	VR="SH"   VM="1"	Keyword="DetectorID"				Name="Detector ID"
+(0018,700C) VERS="3"	VR="DA"   VM="1"	Keyword="DateOfLastDetectorCalibration"		Name="Date of Last Detector Calibration "
+(0018,700E) VERS="3"	VR="TM"   VM="1"	Keyword="TimeOfLastDetectorCalibration"		Name="Time of Last Detector Calibration"
+(0018,7010) VERS="3"	VR="IS"   VM="1"	Keyword="ExposuresOnDetectorSinceLastCalibration"	Name="Exposures on Detector Since Last Calibration"
+(0018,7011) VERS="3"	VR="IS"   VM="1"	Keyword="ExposuresOnDetectorSinceManufactured"	Name="Exposures on Detector Since Manufactured"
+(0018,7012) VERS="3"	VR="DS"   VM="1"	Keyword="DetectorTimeSinceLastExposure"		Name="Detector Time Since Last Exposure"
+(0018,7014) VERS="3"	VR="DS"   VM="1"	Keyword="DetectorActiveTime"			Name="Detector Active Time"
+(0018,7016) VERS="3"	VR="DS"   VM="1"	Keyword="DetectorActivationOffsetFromExposure"	Name="Detector Activation Offset From Exposure"
+(0018,701A) VERS="3"	VR="DS"   VM="2"	Keyword="DetectorBinning"			Name="Detector Binning"
+(0018,7020) VERS="3"	VR="DS"   VM="2"	Keyword="DetectorElementPhysicalSize"		Name="Detector Element Physical Size"
+(0018,7022) VERS="3"	VR="DS"   VM="2"	Keyword="DetectorElementSpacing"		Name="Detector Element Spacing"
+(0018,7024) VERS="3"	VR="CS"   VM="1"	Keyword="DetectorActiveShape"			Name="Detector Active Shape"
+(0018,7026) VERS="3"	VR="DS"   VM="1-2"	Keyword="DetectorActiveDimensions"		Name="Detector Active Dimension(s)"
+(0018,7028) VERS="3"	VR="DS"   VM="2"	Keyword="DetectorActiveOrigin"			Name="Detector Active Origin"
+(0018,702A) VERS="3"	VR="LO"   VM="1"	Keyword="DetectorManufacturerName"		Name="Detector Manufacturer Name"
+(0018,702B) VERS="3"	VR="LO"   VM="1"	Keyword="DetectorManufacturerModelName"		Name="Detector Manufacturer's Model Name"
+(0018,7030) VERS="3"	VR="DS"   VM="2"	Keyword="FieldOfViewOrigin"			Name="Field of View Origin"
+(0018,7032) VERS="3"	VR="DS"   VM="1"	Keyword="FieldOfViewRotation"			Name="Field of View Rotation"
+(0018,7034) VERS="3"	VR="CS"   VM="1"	Keyword="FieldOfViewHorizontalFlip"		Name="Field of View Horizontal Flip"
+(0018,7036) VERS="3"	VR="FL"   VM="2"	Keyword="PixelDataAreaOriginRelativeToFOV"			Name="Pixel Data Area Origin Relative To FOV"
+(0018,7038) VERS="3"	VR="FL"   VM="1"	Keyword="PixelDataAreaRotationAngleRelativeToFOV"	Name="Pixel Data Area Rotation Angle Relative To FOV"
+(0018,7040) VERS="3"	VR="LT"   VM="1"	Keyword="GridAbsorbingMaterial"			Name="Grid Absorbing Material"
+(0018,7041) VERS="3"	VR="LT"   VM="1"	Keyword="GridSpacingMaterial"			Name="Grid Spacing Material"
+(0018,7042) VERS="3"	VR="DS"   VM="1"	Keyword="GridThickness"				Name="Grid Thickness"
+(0018,7044) VERS="3"	VR="DS"   VM="1"	Keyword="GridPitch"				Name="Grid Pitch"
+(0018,7046) VERS="3"	VR="IS"   VM="2"	Keyword="GridAspectRatio"			Name="Grid Aspect Ratio"
+(0018,7048) VERS="3"	VR="DS"   VM="1"	Keyword="GridPeriod"				Name="Grid Period"
+(0018,704C) VERS="3"	VR="DS"   VM="1"	Keyword="GridFocalDistance"			Name="Grid Focal Distance"
+(0018,7050) VERS="3"	VR="CS"   VM="1-n"	Keyword="FilterMaterial"			Name="Filter Material"
+(0018,7052) VERS="3"	VR="DS"   VM="1-n"	Keyword="FilterThicknessMinimum"		Name="Filter Thickness Minimum"
+(0018,7054) VERS="3"	VR="DS"   VM="1-n"	Keyword="FilterThicknessMaximum"		Name="Filter Thickness Maximum"
+(0018,7056) VERS="3"	VR="FL"   VM="1-n"	Keyword="FilterBeamPathLengthMinimum"	Name="Filter Beam Path Length Minimum"
+(0018,7058) VERS="3"	VR="FL"   VM="1-n"	Keyword="FilterBeamPathLengthMaximum"	Name="Filter Beam Path Length Maximum"
+(0018,7060) VERS="3"	VR="CS"   VM="1"	Keyword="ExposureControlMode"			Name="Exposure Control Mode"
+(0018,7062) VERS="3"	VR="LT"   VM="1"	Keyword="ExposureControlModeDescription"	Name="Exposure Control Mode Description"
+(0018,7064) VERS="3"	VR="CS"   VM="1"	Keyword="ExposureStatus"			Name="Exposure Status"
+(0018,7065) VERS="3"	VR="DS"   VM="1"	Keyword="PhototimerSetting"			Name="Phototimer Setting"
+(0018,8150) VERS="3"	VR="DS"   VM="1"	Keyword="ExposureTimeInuS"			Name="Exposure Time in uS"
+(0018,8151) VERS="3"	VR="DS"   VM="1"	Keyword="XRayTubeCurrentInuA"			Name="X-Ray Tube Current in uA"
+(0018,9004) VERS="3"	VR="CS"   VM="1"	Keyword="ContentQualification"			Name="Content Qualification"
+(0018,9005) VERS="3"	VR="SH"   VM="1"	Keyword="PulseSequenceName"			Name="Pulse Sequence Name"
+(0018,9006) VERS="3"	VR="SQ"   VM="1"	Keyword="MRImagingModifierSequence"		Name="MR Imaging Modifier Sequence"
+(0018,9008) VERS="3"	VR="CS"   VM="1"	Keyword="EchoPulseSequence"			Name="Echo Pulse Sequence"
+(0018,9009) VERS="3"	VR="CS"   VM="1"	Keyword="InversionRecovery"			Name="Inversion Recovery"
+(0018,9010) VERS="3"	VR="CS"   VM="1"	Keyword="FlowCompensation"			Name="Flow Compensation"
+(0018,9011) VERS="3"	VR="CS"   VM="1"	Keyword="MultipleSpinEcho"			Name="Multiple Spin Echo"
+(0018,9012) VERS="3"	VR="CS"   VM="1"	Keyword="MultiPlanarExcitation"			Name="Multi-planar Excitation"
+(0018,9014) VERS="3"	VR="CS"   VM="1"	Keyword="PhaseContrast"				Name="Phase Contrast"
+(0018,9015) VERS="3"	VR="CS"   VM="1"	Keyword="TimeOfFlightContrast"			Name="Time of Flight Contrast"
+(0018,9016) VERS="3"	VR="CS"   VM="1"	Keyword="Spoiling"				Name="Spoiling"
+(0018,9017) VERS="3"	VR="CS"   VM="1"	Keyword="SteadyStatePulseSequence"		Name="Steady State Pulse Sequence"
+(0018,9018) VERS="3"	VR="CS"   VM="1"	Keyword="EchoPlanarPulseSequence"		Name="Echo Planar Pulse Sequence"
+(0018,9019) VERS="3"	VR="FD"   VM="1"	Keyword="TagAngleFirstAxis"			Name="Tag Angle First Axis"
+(0018,9020) VERS="3"	VR="CS"   VM="1"	Keyword="MagnetizationTransfer"			Name="Magnetization Transfer"
+(0018,9021) VERS="3"	VR="CS"   VM="1"	Keyword="T2Preparation"				Name="T2 Preparation"
+(0018,9022) VERS="3"	VR="CS"   VM="1"	Keyword="BloodSignalNulling"			Name="Blood Signal Nulling"
+(0018,9024) VERS="3"	VR="CS"   VM="1"	Keyword="SaturationRecovery"			Name="Saturation Recovery"
+(0018,9025) VERS="3"	VR="CS"   VM="1"	Keyword="SpectrallySelectedSuppression"		Name="Spectrally Selected Suppression"
+(0018,9026) VERS="3"	VR="CS"   VM="1"	Keyword="SpectrallySelectedExcitation"		Name="Spectrally Selected Excitation"
+(0018,9027) VERS="3"	VR="CS"   VM="1"	Keyword="SpatialPresaturation"			Name="Spatial Pre-saturation"
+(0018,9028) VERS="3"	VR="CS"   VM="1"	Keyword="Tagging"				Name="Tagging"
+(0018,9029) VERS="3"	VR="CS"   VM="1"	Keyword="OversamplingPhase"			Name="Oversampling Phase"
+(0018,9030) VERS="3"	VR="FD"   VM="1"	Keyword="TagSpacingFirstDimension"		Name="Tag Spacing First Dimension"
+(0018,9032) VERS="3"	VR="CS"   VM="1"	Keyword="GeometryOfKSpaceTraversal"		Name="Geometry of k-Space Traversal"
+(0018,9033) VERS="3"	VR="CS"   VM="1"	Keyword="SegmentedKSpaceTraversal"		Name="Segmented k-Space Traversal"
+(0018,9034) VERS="3"	VR="CS"   VM="1"	Keyword="RectilinearPhaseEncodeReordering"	Name="Rectilinear Phase Encode Reordering"
+(0018,9035) VERS="3"	VR="FD"   VM="1"	Keyword="TagThickness"				Name="Tag Thickness"
+(0018,9036) VERS="3"	VR="CS"   VM="1"	Keyword="PartialFourierDirection"		Name="Partial Fourier Direction"
+(0018,9037) VERS="3"	VR="CS"   VM="1"	Keyword="CardiacSynchronizationTechnique"	Name="Cardiac Synchronization Technique"
+(0018,9041) VERS="3"	VR="LO"   VM="1"	Keyword="ReceiveCoilManufacturerName"		Name="Receive Coil Manufacturer Name"
+(0018,9042) VERS="3"	VR="SQ"   VM="1"	Keyword="MRReceiveCoilSequence"			Name="MR Receive Coil Sequence"
+(0018,9043) VERS="3"	VR="CS"   VM="1"	Keyword="ReceiveCoilType"			Name="Receive Coil Type "
+(0018,9044) VERS="3"	VR="CS"   VM="1"	Keyword="QuadratureReceiveCoil"			Name="Quadrature Receive Coil "
+(0018,9045) VERS="3"	VR="SQ"   VM="1"	Keyword="MultiCoilDefinitionSequence"		Name="Multi-Coil Definition Sequence"
+(0018,9046) VERS="3"	VR="LO"   VM="1"	Keyword="MultiCoilConfiguration"		Name="Multi-Coil Configuration "
+(0018,9047) VERS="3"	VR="SH"   VM="1"	Keyword="MultiCoilElementName"			Name="Multi-Coil Element Name"
+(0018,9048) VERS="3"	VR="CS"   VM="1"	Keyword="MultiCoilElementUsed"			Name="Multi-Coil Element Used"
+(0018,9049) VERS="3"	VR="SQ"   VM="1"	Keyword="MRTransmitCoilSequence"		Name="MR Transmit Coil Sequence"
+(0018,9050) VERS="3"	VR="LO"   VM="1"	Keyword="TransmitCoilManufacturerName"		Name="Transmit Coil Manufacturer Name"
+(0018,9051) VERS="3"	VR="CS"   VM="1"	Keyword="TransmitCoilType"			Name="Transmit Coil Type"
+(0018,9052) VERS="3"	VR="FD"   VM="1-2"	Keyword="SpectralWidth"				Name="Spectral Width"
+(0018,9053) VERS="3"	VR="FD"   VM="1-2"	Keyword="ChemicalShiftReference"		Name="Chemical Shift Reference"
+(0018,9054) VERS="3"	VR="CS"   VM="1"	Keyword="VolumeLocalizationTechnique"		Name="Volume Localization Technique"
+(0018,9058) VERS="3"	VR="US"   VM="1"	Keyword="MRAcquisitionFrequencyEncodingSteps"	Name="MR Acquisition Frequency Encoding Steps"
+(0018,9059) VERS="3"	VR="CS"   VM="1"	Keyword="Decoupling"				Name="De-coupling"
+(0018,9060) VERS="3"	VR="CS"   VM="1-2"	Keyword="DecoupledNucleus"			Name="De-coupled Nucleus"
+(0018,9061) VERS="3"	VR="FD"   VM="1-2"	Keyword="DecouplingFrequency"			Name="De-coupling Frequency"
+(0018,9062) VERS="3"	VR="CS"   VM="1"	Keyword="DecouplingMethod"			Name="De-coupling Method"
+(0018,9063) VERS="3"	VR="FD"   VM="1-2"	Keyword="DecouplingChemicalShiftReference"	Name="De-coupling Chemical Shift Reference"
+(0018,9064) VERS="3"	VR="CS"   VM="1"	Keyword="KSpaceFiltering"			Name="k-space Filtering"
+(0018,9065) VERS="3"	VR="CS"   VM="1-2"	Keyword="TimeDomainFiltering"			Name="Time Domain Filtering"
+(0018,9066) VERS="3"	VR="US"   VM="1-2"	Keyword="NumberOfZeroFills"			Name="Number of Zero Fills"
+(0018,9067) VERS="3"	VR="CS"   VM="1"	Keyword="BaselineCorrection"			Name="Baseline Correction"
+(0018,9069) VERS="3"	VR="FD"   VM="1"	Keyword="ParallelReductionFactorInPlane"	Name="Parallel Reduction Factor In-plane"
+(0018,9070) VERS="3"	VR="FD"   VM="1"	Keyword="CardiacRRIntervalSpecified"		Name="Cardiac R-R Interval Specified"
+(0018,9073) VERS="3"	VR="FD"   VM="1"	Keyword="AcquisitionDuration"			Name="Acquisition Duration"
+(0018,9074) VERS="3"	VR="DT"   VM="1"	Keyword="FrameAcquisitionDateTime"		Name="Frame Acquisition DateTime"
+(0018,9075) VERS="3"	VR="CS"   VM="1"	Keyword="DiffusionDirectionality"		Name="Diffusion Directionality"
+(0018,9076) VERS="3"	VR="SQ"   VM="1"	Keyword="DiffusionGradientDirectionSequence"	Name="Diffusion Gradient Direction Sequence"
+(0018,9077) VERS="3"	VR="CS"   VM="1"	Keyword="ParallelAcquisition"			Name="Parallel Acquisition"
+(0018,9078) VERS="3"	VR="CS"   VM="1"	Keyword="ParallelAcquisitionTechnique"		Name="Parallel Acquisition Technique"
+(0018,9079) VERS="3"	VR="FD"   VM="1-n"	Keyword="InversionTimes"			Name="Inversion Times"
+(0018,9080) VERS="3"	VR="ST"   VM="1"	Keyword="MetaboliteMapDescription"		Name="Metabolite Map Description"
+(0018,9081) VERS="3"	VR="CS"   VM="1"	Keyword="PartialFourier"			Name="Partial Fourier"
+(0018,9082) VERS="3"	VR="FD"   VM="1"	Keyword="EffectiveEchoTime"			Name="Effective Echo Time"
+(0018,9083) VERS="3"	VR="SQ"   VM="1"	Keyword="MetaboliteMapCodeSequence"		Name="Metabolite MapCode Sequence"
+(0018,9084) VERS="3"	VR="SQ"   VM="1"	Keyword="ChemicalShiftSequence"			Name="Chemical Shift Sequence"
+(0018,9085) VERS="3"	VR="CS"   VM="1"	Keyword="CardiacSignalSource"			Name="Cardiac Signal Source"
+(0018,9087) VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValue"			Name="Diffusion b-value"
+(0018,9089) VERS="3"	VR="FD"   VM="3"	Keyword="DiffusionGradientOrientation"		Name="Diffusion Gradient Orientation"
+(0018,9090) VERS="3"	VR="FD"   VM="3"	Keyword="VelocityEncodingDirection"		Name="Velocity Encoding Direction"
+(0018,9091) VERS="3"	VR="FD"   VM="1"	Keyword="VelocityEncodingMinimumValue"		Name="Velocity Encoding Minimum Value"
+(0018,9092) VERS="3"	VR="SQ"   VM="1"	Keyword="VelocityEncodingAcquisitionSequence"		Name="Velocity Encoding Acquisition Sequence"
+(0018,9093) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfKSpaceTrajectories"		Name="Number of k-Space Trajectories"
+(0018,9094) VERS="3"	VR="CS"   VM="1"	Keyword="CoverageOfKSpace"			Name="Coverage of k-Space"
+(0018,9095) VERS="3"	VR="UL"   VM="1"	Keyword="SpectroscopyAcquisitionPhaseRows"	Name="Spectroscopy Acquisition Phase Rows"
+(0018,9096) VERS="RET"	VR="FD"   VM="1"	Keyword="ParallelReductionFactorInPlaneRetired"	Name="Parallel Reduction Factor In-plane (Retired)"
+(0018,9098) VERS="3"	VR="FD"   VM="1-2"	Keyword="TransmitterFrequency"			Name="Transmitter Frequency"
+(0018,9100) VERS="3"	VR="CS"   VM="1-2"	Keyword="ResonantNucleus"			Name="Resonant Nucleus"
+(0018,9101) VERS="3"	VR="CS"   VM="1"	Keyword="FrequencyCorrection"			Name="Frequency Correction"
+(0018,9103) VERS="3"	VR="SQ"   VM="1"	Keyword="MRSpectroscopyFOVGeometrySequence"	Name="MR Spectroscopy FOV/Geometry Sequence"
+(0018,9104) VERS="3"	VR="FD"   VM="1"	Keyword="SlabThickness"				Name="Slab Thickness"
+(0018,9105) VERS="3"	VR="FD"   VM="3"	Keyword="SlabOrientation"			Name="Slab Orientation"
+(0018,9106) VERS="3"	VR="FD"   VM="3"	Keyword="MidSlabPosition"			Name="Mid Slab Position"
+(0018,9107) VERS="3"	VR="SQ"   VM="1"	Keyword="MRSpatialSaturationSequence"		Name="MR Spatial Saturation Sequence"
+(0018,9112) VERS="3"	VR="SQ"   VM="1"	Keyword="MRTimingAndRelatedParametersSequence"	Name="MR Timing and Related Parameters Sequence"
+(0018,9114) VERS="3"	VR="SQ"   VM="1"	Keyword="MREchoSequence"			Name="MR Echo Sequence"
+(0018,9115) VERS="3"	VR="SQ"   VM="1"	Keyword="MRModifierSequence"			Name="MR Modifier Sequence"
+(0018,9117) VERS="3"	VR="SQ"   VM="1"	Keyword="MRDiffusionSequence"			Name="MR Diffusion Sequence"
+(0018,9118) VERS="3"	VR="SQ"   VM="1"	Keyword="CardiacSynchronizationSequence"		Name="Cardiac Synchronization Sequence"
+(0018,9119) VERS="3"	VR="SQ"   VM="1"	Keyword="MRAveragesSequence"			Name="MR Averages Sequence"
+(0018,9125) VERS="3"	VR="SQ"   VM="1"	Keyword="MRFOVGeometrySequence"			Name="MR FOV/Geometry Sequence"
+(0018,9126) VERS="3"	VR="SQ"   VM="1"	Keyword="VolumeLocalizationSequence"		Name="Volume Localization Sequence"
+(0018,9127) VERS="3"	VR="UL"   VM="1"	Keyword="SpectroscopyAcquisitionDataColumns"	Name="Spectroscopy Acquisition Data Columns"
+(0018,9147) VERS="3"	VR="CS"   VM="1"	Keyword="DiffusionAnisotropyType"		Name="Diffusion Anisotropy Type"
+(0018,9151) VERS="3"	VR="DT"   VM="1"	Keyword="FrameReferenceDateTime"		Name="Frame Reference DateTime"
+(0018,9152) VERS="3"	VR="SQ"   VM="1"	Keyword="MRMetaboliteMapSequence"		Name="MR Metabolite Map Sequence"
+(0018,9155) VERS="3"	VR="FD"   VM="1"	Keyword="ParallelReductionFactorOutOfPlane"	Name="Parallel Reduction Factor out-of-plane"
+(0018,9159) VERS="3"	VR="UL"   VM="1"	Keyword="SpectroscopyAcquisitionOutOfPlanePhaseSteps"	Name="Spectroscopy Acquisition Out-of-plane Phase Steps"
+(0018,9166) VERS="RET"	VR="CS"   VM="1"	Keyword="BulkMotionStatus"			Name="Bulk Motion Status"
+(0018,9168) VERS="3"	VR="FD"   VM="1"	Keyword="ParallelReductionFactorSecondInPlane"	Name="Parallel Reduction Factor Second In-plane"
+(0018,9169) VERS="3"	VR="CS"   VM="1"	Keyword="CardiacBeatRejectionTechnique"		Name="Cardiac Beat Rejection Technique"
+(0018,9170) VERS="3"	VR="CS"   VM="1"	Keyword="RespiratoryMotionCompensationTechnique"	Name="Respiratory Motion Compensation Technique"
+(0018,9171) VERS="3"	VR="CS"   VM="1"	Keyword="RespiratorySignalSource"		Name="Respiratory Signal Source"
+(0018,9172) VERS="3"	VR="CS"   VM="1"	Keyword="BulkMotionCompensationTechnique"	Name="Bulk Motion Compensation Technique"
+(0018,9173) VERS="3"	VR="CS"   VM="1"	Keyword="BulkMotionSignalSource"		Name="Bulk Motion Signal Source"
+(0018,9174) VERS="3"	VR="CS"   VM="1"	Keyword="ApplicableSafetyStandardAgency"	Name="Applicable Safety Standard Agency"
+(0018,9175) VERS="3"	VR="LO"   VM="1"	Keyword="ApplicableSafetyStandardDescription"	Name="Applicable Safety Standard Description"
+(0018,9176) VERS="3"	VR="SQ"   VM="1"	Keyword="OperatingModeSequence"			Name="Operating Mode Sequence"
+(0018,9177) VERS="3"	VR="CS"   VM="1"	Keyword="OperatingModeType"			Name="Operating Mode Type"
+(0018,9178) VERS="3"	VR="CS"   VM="1"	Keyword="OperatingMode"				Name="Operating Mode"
+(0018,9179) VERS="3"	VR="CS"   VM="1"	Keyword="SpecificAbsorptionRateDefinition"	Name="Specific Absorption Rate Definition"
+(0018,9180) VERS="3"	VR="CS"   VM="1"	Keyword="GradientOutputType"			Name="Gradient Output Type"
+(0018,9181) VERS="3"	VR="FD"   VM="1"	Keyword="SpecificAbsorptionRateValue"		Name="Specific Absorption Rate Value"
+(0018,9182) VERS="3"	VR="FD"   VM="1"	Keyword="GradientOutput"			Name="Gradient Output"
+(0018,9183) VERS="3"	VR="CS"   VM="1"	Keyword="FlowCompensationDirection"		Name="Flow Compensation Direction"
+(0018,9184) VERS="3"	VR="FD"   VM="1"	Keyword="TaggingDelay"				Name="Tagging Delay"
+(0018,9185) VERS="3"	VR="ST"   VM="1"	Keyword="RespiratoryMotionCompensationTechniqueDescription"				Name="Respiratory Motion Compensation Technique Description"
+(0018,9186) VERS="3"	VR="SH"   VM="1"	Keyword="RespiratorySignalSourceID"				Name="Respiratory Signal Source ID"
+(0018,9195) VERS="RET"	VR="FD"   VM="1"	Keyword="ChemicalShiftMinimumIntegrationLimitInHz"	Name="Chemical Shift Minimum Integration Limit in Hz"
+(0018,9196) VERS="RET"	VR="FD"   VM="1"	Keyword="ChemicalShiftMaximumIntegrationLimitInHz"	Name="Chemical Shift Maximum Integration Limit in Hz"
+(0018,9197) VERS="3"	VR="SQ"   VM="1"	Keyword="MRVelocityEncodingSequence"		Name="MR Velocity Encoding Sequence"
+(0018,9198) VERS="3"	VR="CS"   VM="1"	Keyword="FirstOrderPhaseCorrection"		Name="First Order Phase Correction"
+(0018,9199) VERS="3"	VR="CS"   VM="1"	Keyword="WaterReferencedPhaseCorrection"	Name="Water Referenced Phase Correction"
+(0018,9200) VERS="3"	VR="CS"   VM="1"	Keyword="MRSpectroscopyAcquisitionType"		Name="MR Spectroscopy Acquisition Type"
+(0018,9214) VERS="3"	VR="CS"   VM="1"	Keyword="RespiratoryCyclePosition"		Name="Respiratory Cycle Position"
+(0018,9217) VERS="3"	VR="FD"   VM="1"	Keyword="VelocityEncodingMaximumValue"		Name="Velocity Encoding Maximum Value"
+(0018,9218) VERS="3"	VR="FD"   VM="1"	Keyword="TagSpacingSecondDimension"		Name="Tag Spacing Second Dimension"
+(0018,9219) VERS="3"	VR="SS"   VM="1"	Keyword="TagAngleSecondAxis"			Name="Tag Angle Second Axis"
+(0018,9220) VERS="3"	VR="FD"   VM="1"	Keyword="FrameAcquisitionDuration"		Name="Frame Acquisition Duration"
+(0018,9226) VERS="3"	VR="SQ"   VM="1"	Keyword="MRImageFrameTypeSequence"		Name="MR Image Frame Type Sequence"
+(0018,9227) VERS="3"	VR="SQ"   VM="1"	Keyword="MRSpectroscopyFrameTypeSequence"	Name="MR Spectroscopy Frame Type Sequence"
+(0018,9231) VERS="3"	VR="US"   VM="1"	Keyword="MRAcquisitionPhaseEncodingStepsInPlane"	Name="MR Acquisition Phase Encoding Steps in-plane"
+(0018,9232) VERS="3"	VR="US"   VM="1"	Keyword="MRAcquisitionPhaseEncodingStepsOutOfPlane"	Name="MR Acquisition Phase Encoding Steps out-of-plane"
+(0018,9234) VERS="3"	VR="UL"   VM="1"	Keyword="SpectroscopyAcquisitionPhaseColumns"	Name="Spectroscopy Acquisition Phase Columns"
+(0018,9236) VERS="3"	VR="CS"   VM="1"	Keyword="CardiacCyclePosition"			Name="Cardiac Cycle Position"
+(0018,9239) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecificAbsorptionRateSequence"	Name="Specific Absorption Rate Sequence"
+(0018,9240) VERS="3"	VR="US"   VM="1"	Keyword="RFEchoTrainLength"			Name="RF Echo Train Length"
+(0018,9241) VERS="3"	VR="US"   VM="1"	Keyword="GradientEchoTrainLength"		Name="Gradient Echo Train Length"
+(0018,9250) VERS="3"	VR="CS"   VM="1"	Keyword="ArterialSpinLabelingContrast"		Name="Arterial Spin Labeling Contrast"
+(0018,9251) VERS="3"	VR="SQ"   VM="1"	Keyword="MRArterialSpinLabelingSequence"	Name="MR Arterial Spin Labeling Sequence"
+(0018,9252) VERS="3"	VR="LO"   VM="1"	Keyword="ASLTechniqueDescription"			Name="ASL Technique Description"
+(0018,9253) VERS="3"	VR="US"   VM="1"	Keyword="ASLSlabNumber"						Name="ASL Slab Number"
+(0018,9254) VERS="3"	VR="FD"   VM="1"	Keyword="ASLSlabThickness"					Name="ASL Slab Thickness"
+(0018,9255) VERS="3"	VR="FD"   VM="3"	Keyword="ASLSlabOrientation"				Name="ASL Slab Orientation"
+(0018,9256) VERS="3"	VR="FD"   VM="3"	Keyword="ASLMidSlabPosition"				Name="ASL Mid Slab Position"
+(0018,9257) VERS="3"	VR="CS"   VM="1"	Keyword="ASLContext"						Name="ASL Context"
+(0018,9258) VERS="3"	VR="UL"   VM="1"	Keyword="ASLPulseTrainDuration"				Name="ASL Pulse Train Duration"
+(0018,9259) VERS="3"	VR="CS"   VM="1"	Keyword="ASLCrusherFlag"					Name="ASL Crusher Flag"
+(0018,925A) VERS="3"	VR="FD"   VM="1"	Keyword="ASLCrusherFlowLimit"				Name="ASL Crusher Flow Limit"
+(0018,925B) VERS="3"	VR="LO"   VM="1"	Keyword="ASLCrusherDescription"				Name="ASL Crusher Description"
+(0018,925C) VERS="3"	VR="CS"   VM="1"	Keyword="ASLBolusCutoffFlag"				Name="ASL Bolus Cut-off Flag"
+(0018,925D) VERS="3"	VR="SQ"   VM="1"	Keyword="ASLBolusCutoffTimingSequence"		Name="ASL Bolus Cut-off Timing Sequence"
+(0018,925E) VERS="3"	VR="LO"   VM="1"	Keyword="ASLBolusCutoffTechnique"			Name="ASL Bolus Cut-off Technique"
+(0018,925F) VERS="3"	VR="UL"   VM="1"	Keyword="ASLBolusCutoffDelayTime"			Name="ASL Bolus Cut-off Delay Time"
+(0018,9260) VERS="3"	VR="SQ"   VM="1"	Keyword="ASLSlabSequence"					Name="ASL Slab Sequence"
+(0018,9295) VERS="3"	VR="FD"   VM="1"	Keyword="ChemicalShiftMinimumIntegrationLimitInppm"	Name="Chemical Shift Minimum Integration Limit in ppm"
+(0018,9296) VERS="3"	VR="FD"   VM="1"	Keyword="ChemicalShiftMaximumIntegrationLimitInppm"	Name="Chemical Shift Maximum Integration Limit in ppm"
+(0018,9297) VERS="3"	VR="CS"   VM="1"	Keyword="WaterReferenceAcquisition"			Name="Water Reference Acquisition"
+(0018,9298) VERS="3"	VR="IS"   VM="1"	Keyword="EchoPeakPosition"					Name="Echo Peak Position"
+(0018,9301) VERS="3"	VR="SQ"   VM="1"	Keyword="CTAcquisitionTypeSequence"			Name="CT Acquisition Type Sequence"
+(0018,9302) VERS="3"	VR="CS"   VM="1"	Keyword="AcquisitionType"				Name="Acquisition Type"
+(0018,9303) VERS="3"	VR="FD"   VM="1"	Keyword="TubeAngle"					Name="Tube Angle"
+(0018,9304) VERS="3"	VR="SQ"   VM="1"	Keyword="CTAcquisitionDetailsSequence"			Name="CT Acquisition Details Sequence"
+(0018,9305) VERS="3"	VR="FD"   VM="1"	Keyword="RevolutionTime"				Name="Revolution Time"
+(0018,9306) VERS="3"	VR="FD"   VM="1"	Keyword="SingleCollimationWidth"			Name="Single Collimation Width"
+(0018,9307) VERS="3"	VR="FD"   VM="1"	Keyword="TotalCollimationWidth"				Name="Total Collimation Width"
+(0018,9308) VERS="3"	VR="SQ"   VM="1"	Keyword="CTTableDynamicsSequence"			Name="CT Table Dynamics Sequence"
+(0018,9309) VERS="3"	VR="FD"   VM="1"	Keyword="TableSpeed"					Name="Table Speed"
+(0018,9310) VERS="3"	VR="FD"   VM="1"	Keyword="TableFeedPerRotation"				Name="Table Feed per Rotation"
+(0018,9311) VERS="3"	VR="FD"   VM="1"	Keyword="SpiralPitchFactor"				Name="Spiral Pitch Factor"
+(0018,9312) VERS="3"	VR="SQ"   VM="1"	Keyword="CTGeometrySequence"				Name="CT Geometry Sequence"
+(0018,9313) VERS="3"	VR="FD"   VM="3"	Keyword="DataCollectionCenterPatient"			Name="Data Collection Center (Patient)"
+(0018,9314) VERS="3"	VR="SQ"   VM="1"	Keyword="CTReconstructionSequence"			Name="CT Reconstruction Sequence"
+(0018,9315) VERS="3"	VR="CS"   VM="1"	Keyword="ReconstructionAlgorithm"			Name="Reconstruction Algorithm"
+(0018,9316) VERS="3"	VR="CS"   VM="1"	Keyword="ConvolutionKernelGroup"			Name="Convolution Kernel Group"
+(0018,9317) VERS="3"	VR="FD"   VM="2"	Keyword="ReconstructionFieldOfView"			Name="Reconstruction Field of View"
+(0018,9318) VERS="3"	VR="FD"   VM="3"	Keyword="ReconstructionTargetCenterPatient"		Name="Reconstruction Target Center (Patient)"
+(0018,9319) VERS="3"	VR="FD"   VM="1"	Keyword="ReconstructionAngle"				Name="Reconstruction Angle"
+(0018,9320) VERS="3"	VR="SH"   VM="1"	Keyword="ImageFilter"					Name="Image Filter"
+(0018,9321) VERS="3"	VR="SQ"   VM="1"	Keyword="CTExposureSequence"				Name="CT Exposure Sequence"
+(0018,9322) VERS="3"	VR="FD"   VM="2"	Keyword="ReconstructionPixelSpacing"			Name="Reconstruction Pixel Spacing"
+(0018,9323) VERS="3"	VR="CS"   VM="1"	Keyword="ExposureModulationType"			Name="Exposure Modulation Type"
+(0018,9324) VERS="3"	VR="FD"   VM="1"	Keyword="EstimatedDoseSaving"				Name="Estimated Dose Saving"
+(0018,9325) VERS="3"	VR="SQ"   VM="1"	Keyword="CTXRayDetailsSequence"				Name="CT X-Ray Details Sequence"
+(0018,9326) VERS="3"	VR="SQ"   VM="1"	Keyword="CTPositionSequence"				Name="CT Position Sequence"
+(0018,9327) VERS="3"	VR="FD"   VM="1"	Keyword="TablePosition"					Name="Table Position"
+(0018,9328) VERS="3"	VR="FD"   VM="1"	Keyword="ExposureTimeInms"				Name="Exposure Time in ms"
+(0018,9329) VERS="3"	VR="SQ"   VM="1"	Keyword="CTImageFrameTypeSequence"			Name="CT Image Frame Type Sequence"
+(0018,9330) VERS="3"	VR="FD"   VM="1"	Keyword="XRayTubeCurrentInmA"				Name="X-Ray Tube Current in mA"
+(0018,9332) VERS="3"	VR="FD"   VM="1"	Keyword="ExposureInmAs"					Name="Exposure in mAs"
+(0018,9333) VERS="3"	VR="CS"   VM="1"	Keyword="ConstantVolumeFlag"				Name="Constant Volume Flag"
+(0018,9334) VERS="3"	VR="CS"   VM="1"	Keyword="FluoroscopyFlag"				Name="Fluoroscopy Flag"
+(0018,9335) VERS="3"	VR="FD"   VM="1"	Keyword="DistanceSourceToDataCollectionCenter"		Name="Distance Source to Data Collection Center"
+(0018,9337) VERS="3"	VR="US"   VM="1"	Keyword="ContrastBolusAgentNumber"			Name="Contrast/Bolus Agent Number"
+(0018,9338) VERS="3"	VR="SQ"   VM="1"	Keyword="ContrastBolusIngredientCodeSequence"		Name="Contrast/Bolus Ingredient Code Sequence"
+(0018,9340) VERS="3"	VR="SQ"   VM="1"	Keyword="ContrastAdministrationProfileSequence"		Name="Contrast Administration Profile Sequence"
+(0018,9341) VERS="3"	VR="SQ"   VM="1"	Keyword="ContrastBolusUsageSequence"			Name="Contrast/Bolus Usage Sequence"
+(0018,9342) VERS="3"	VR="CS"   VM="1"	Keyword="ContrastBolusAgentAdministered"		Name="Contrast/Bolus Agent Administered"
+(0018,9343) VERS="3"	VR="CS"   VM="1"	Keyword="ContrastBolusAgentDetected"			Name="Contrast/Bolus Agent Detected"
+(0018,9344) VERS="3"	VR="CS"   VM="1"	Keyword="ContrastBolusAgentPhase"			Name="Contrast/Bolus Agent Phase"
+(0018,9345) VERS="3"	VR="FD"   VM="1"	Keyword="CTDIvol"					Name="CTDIvol"
+(0018,9346) VERS="3"	VR="SQ"   VM="1"	Keyword="CTDIPhantomTypeCodeSequence"			Name="CTDI Phantom Type Code Sequence"
+(0018,9351) VERS="3"	VR="FL"   VM="1"	Keyword="CalciumScoringMassFactorPatient"		Name="Calcium Scoring Mass Factor Patient"
+(0018,9352) VERS="3"	VR="FL"   VM="3"	Keyword="CalciumScoringMassFactorDevice"		Name="Calcium Scoring Mass Factor Device"
+(0018,9353) VERS="3"	VR="FL"   VM="1"	Keyword="EnergyWeightingFactor"					Name="Energy Weighting Factor"
+(0018,9360) VERS="3"	VR="SQ"   VM="1"	Keyword="CTAdditionalXRaySourceSequence"		Name="CT Additional X-Ray Source Sequence"
+(0018,9401)	VERS="3"	VR="SQ"   VM="1"	Keyword="ProjectionPixelCalibrationSequence"			Name="Projection Pixel Calibration Sequence"
+(0018,9402)	VERS="3"	VR="FL"   VM="1"	Keyword="DistanceSourceToIsocenter"			Name="Distance Source to Isocenter"
+(0018,9403)	VERS="3"	VR="FL"   VM="1"	Keyword="DistanceObjectToTableTop"			Name="Distance Object to Table Top"
+(0018,9404)	VERS="3"	VR="FL"   VM="2"	Keyword="ObjectPixelSpacingInCenterOfBeam"			Name="Object Pixel Spacing in Center of Beam"
+(0018,9405)	VERS="3"	VR="SQ"   VM="1"	Keyword="PositionerPositionSequence"			Name="Positioner Position Sequence"
+(0018,9406)	VERS="3"	VR="SQ"   VM="1"	Keyword="TablePositionSequence"			Name="Table Position Sequence"
+(0018,9407)	VERS="3"	VR="SQ"   VM="1"	Keyword="CollimatorShapeSequence"			Name="Collimator Shape Sequence"
+(0018,9410) VERS="3"	VR="CS"   VM="1"	Keyword="PlanesInAcquisition"			Name="Planes in Acquisition"
+(0018,9412)	VERS="3"	VR="SQ"   VM="1"	Keyword="XAXRFFrameCharacteristicsSequence"			Name="XA/XRF Frame Characteristics Sequence"
+(0018,9417)	VERS="3"	VR="SQ"   VM="1"	Keyword="FrameAcquisitionSequence"			Name="Frame Acquisition Sequence"
+(0018,9420)	VERS="3"	VR="CS"   VM="1"	Keyword="XRayReceptorType"			Name="X-Ray Receptor Type"
+(0018,9423)	VERS="3"	VR="LO"   VM="1"	Keyword="AcquisitionProtocolName"			Name="Acquisition Protocol Name"
+(0018,9424)	VERS="3"	VR="LT"   VM="1"	Keyword="AcquisitionProtocolDescription"			Name="Acquisition Protocol Description"
+(0018,9425)	VERS="3"	VR="CS"   VM="1"	Keyword="ContrastBolusIngredientOpaque"			Name="Contrast/Bolus Ingredient Opaque"
+(0018,9426)	VERS="3"	VR="FL"   VM="1"	Keyword="DistanceReceptorPlaneToDetectorHousing"			Name="Distance Receptor Plane to Detector Housing"
+(0018,9427)	VERS="3"	VR="CS"   VM="1"	Keyword="IntensifierActiveShape"			Name="Intensifier Active Shape"
+(0018,9428)	VERS="3"	VR="FL"   VM="1-2"	Keyword="IntensifierActiveDimensions"			Name="Intensifier Active Dimension(s)"
+(0018,9429)	VERS="3"	VR="FL"   VM="2"	Keyword="PhysicalDetectorSize"			Name="Physical Detector Size"
+(0018,9430)	VERS="3"	VR="FL"   VM="2"	Keyword="PositionOfIsocenterProjection"			Name="Position of Isocenter Projection"
+(0018,9432)	VERS="3"	VR="SQ"   VM="1"	Keyword="FieldOfViewSequence"			Name="Field of View Sequence"
+(0018,9433)	VERS="3"	VR="LO"   VM="1"	Keyword="FieldOfViewDescription"			Name="Field of View Description"
+(0018,9434)	VERS="3"	VR="SQ"   VM="1"	Keyword="ExposureControlSensingRegionsSequence"			Name="Exposure Control Sensing Regions Sequence"
+(0018,9435)	VERS="3"	VR="CS"   VM="1"	Keyword="ExposureControlSensingRegionShape"			Name="Exposure Control Sensing Region Shape"
+(0018,9436)	VERS="3"	VR="SS"   VM="1"	Keyword="ExposureControlSensingRegionLeftVerticalEdge"			Name="Exposure Control Sensing Region Left Vertical Edge"
+(0018,9437)	VERS="3"	VR="SS"   VM="1"	Keyword="ExposureControlSensingRegionRightVerticalEdge"			Name="Exposure Control Sensing Region Right Vertical Edge"
+(0018,9438)	VERS="3"	VR="SS"   VM="1"	Keyword="ExposureControlSensingRegionUpperHorizontalEdge"			Name="Exposure Control Sensing Region Upper Horizontal Edge"
+(0018,9439)	VERS="3"	VR="SS"   VM="1"	Keyword="ExposureControlSensingRegionLowerHorizontalEdge"			Name="Exposure Control Sensing Region Lower Horizontal Edge"
+(0018,9440)	VERS="3"	VR="SS"   VM="2"	Keyword="CenterOfCircularExposureControlSensingRegion"			Name="Center of Circular Exposure Control Sensing Region"
+(0018,9441)	VERS="3"	VR="US"   VM="1"	Keyword="RadiusOfCircularExposureControlSensingRegion"			Name="Radius of Circular Exposure Control Sensing Region"
+(0018,9442)	VERS="3"	VR="SS"   VM="2-n"	Keyword="VerticesOfThePolygonalExposureControlSensingRegion"			Name="Vertices of the Polygonal Exposure Control Sensing Region"
+(0018,9447)	VERS="3"	VR="FL"   VM="1"	Keyword="ColumnAngulationPatient"			Name="Column Angulation (Patient)"
+(0018,9449)	VERS="3"	VR="FL"   VM="1"	Keyword="BeamAngle"			Name="Beam Angle"
+(0018,9451)	VERS="3"	VR="SQ"   VM="1"	Keyword="FrameDetectorParametersSequence"			Name="Frame Detector Parameters Sequence"
+(0018,9452)	VERS="3"	VR="FL"   VM="1"	Keyword="CalculatedAnatomyThickness"			Name="Calculated Anatomy Thickness"
+(0018,9455)	VERS="3"	VR="SQ"   VM="1"	Keyword="CalibrationSequence"			Name="Calibration Sequence"
+(0018,9456)	VERS="3"	VR="SQ"   VM="1"	Keyword="ObjectThicknessSequence"			Name="Object Thickness Sequence"
+(0018,9457)	VERS="3"	VR="CS"   VM="1"	Keyword="PlaneIdentification"			Name="Plane Identification"
+(0018,9461)	VERS="3"	VR="FL"   VM="1-2"	Keyword="FieldOfViewDimensionsInFloat"			Name="Field of View Dimension(s) in Float"
+(0018,9462)	VERS="3"	VR="SQ"   VM="1"	Keyword="IsocenterReferenceSystemSequence"			Name="Isocenter Reference System Sequence"
+(0018,9463)	VERS="3"	VR="FL"   VM="1"	Keyword="PositionerIsocenterPrimaryAngle"			Name="Positioner Isocenter Primary Angle"
+(0018,9464)	VERS="3"	VR="FL"   VM="1"	Keyword="PositionerIsocenterSecondaryAngle"			Name="Positioner Isocenter Secondary Angle"
+(0018,9465)	VERS="3"	VR="FL"   VM="1"	Keyword="PositionerIsocenterDetectorRotationAngle"			Name="Positioner Isocenter Detector Rotation Angle"
+(0018,9466)	VERS="3"	VR="FL"   VM="1"	Keyword="TableXPositionToIsocenter"			Name="Table X Position to Isocenter"
+(0018,9467)	VERS="3"	VR="FL"   VM="1"	Keyword="TableYPositionToIsocenter"			Name="Table Y Position to Isocenter"
+(0018,9468)	VERS="3"	VR="FL"   VM="1"	Keyword="TableZPositionToIsocenter"			Name="Table Z Position to Isocenter"
+(0018,9469)	VERS="3"	VR="FL"   VM="1"	Keyword="TableHorizontalRotationAngle"			Name="Table Horizontal Rotation Angle"
+(0018,9470)	VERS="3"	VR="FL"   VM="1"	Keyword="TableHeadTiltAngle"			Name="Table Head Tilt Angle"
+(0018,9471)	VERS="3"	VR="FL"   VM="1"	Keyword="TableCradleTiltAngle"			Name="Table Cradle Tilt Angle"
+(0018,9472)	VERS="3"	VR="SQ"   VM="1"	Keyword="FrameDisplayShutterSequence"			Name="Frame Display Shutter Sequence"
+(0018,9473)	VERS="3"	VR="FL"   VM="1"	Keyword="AcquiredImageAreaDoseProduct"			Name="Acquired Image Area Dose Product"
+(0018,9474)	VERS="3"	VR="CS"   VM="1"	Keyword="CArmPositionerTabletopRelationship"			Name="C-arm Positioner Tabletop Relationship"
+(0018,9476)	VERS="3"	VR="SQ"   VM="1"	Keyword="XRayGeometrySequence"			Name="X-Ray Geometry Sequence"
+(0018,9477)	VERS="3"	VR="SQ"   VM="1"	Keyword="IrradiationEventIdentificationSequence"			Name="Irradiation Event Identification Sequence"
+(0018,9504)	VERS="3"	VR="SQ"   VM="1"	Keyword="XRay3DFrameTypeSequence"			Name="X-Ray 3D Frame Type Sequence"
+(0018,9506)	VERS="3"	VR="SQ"   VM="1"	Keyword="ContributingSourcesSequence"		Name="Contributing Sources Sequence"
+(0018,9507)	VERS="3"	VR="SQ"   VM="1"	Keyword="XRay3DAcquisitionSequence"			Name="X-Ray 3D Acquisition Sequence"
+(0018,9508)	VERS="3"	VR="FL"   VM="1"	Keyword="PrimaryPositionerScanArc"			Name="Primary Positioner Scan Arc"
+(0018,9509)	VERS="3"	VR="FL"   VM="1"	Keyword="SecondaryPositionerScanArc"		Name="Secondary Positioner Scan Arc"
+(0018,9510)	VERS="3"	VR="FL"   VM="1"	Keyword="PrimaryPositionerScanStartAngle"	Name="Primary Positioner Scan Start Angle"
+(0018,9511)	VERS="3"	VR="FL"   VM="1"	Keyword="SecondaryPositionerScanStartAngle"	Name="Secondary Positioner Scan Start Angle"
+(0018,9514)	VERS="3"	VR="FL"   VM="1"	Keyword="PrimaryPositionerIncrement"		Name="Primary Positioner Increment"
+(0018,9515)	VERS="3"	VR="FL"   VM="1"	Keyword="SecondaryPositionerIncrement"		Name="Secondary Positioner Increment"
+(0018,9516)	VERS="3"	VR="DT"   VM="1"	Keyword="StartAcquisitionDateTime"			Name="Start Acquisition DateTime"
+(0018,9517)	VERS="3"	VR="DT"   VM="1"	Keyword="EndAcquisitionDateTime"			Name="End Acquisition DateTime"
+(0018,9518)	VERS="3"	VR="SS"   VM="1"	Keyword="PrimaryPositionerIncrementSign"		Name="Primary Positioner Increment Sign"
+(0018,9519)	VERS="3"	VR="SS"   VM="1"	Keyword="SecondaryPositionerIncrementSign"		Name="Secondary Positioner Increment Sign"
+(0018,9524)	VERS="3"	VR="LO"   VM="1"	Keyword="ApplicationName"					Name="Application Name"
+(0018,9525)	VERS="3"	VR="LO"   VM="1"	Keyword="ApplicationVersion"				Name="Application Version"
+(0018,9526)	VERS="3"	VR="LO"   VM="1"	Keyword="ApplicationManufacturer"			Name="Application Manufacturer"
+(0018,9527)	VERS="3"	VR="CS"   VM="1"	Keyword="AlgorithmType"						Name="Algorithm Type"
+(0018,9528)	VERS="3"	VR="LO"   VM="1"	Keyword="AlgorithmDescription"				Name="Algorithm Description"
+(0018,9530)	VERS="3"	VR="SQ"   VM="1"	Keyword="XRay3DReconstructionSequence"		Name="X-Ray 3D Reconstruction Sequence"
+(0018,9531)	VERS="3"	VR="LO"   VM="1"	Keyword="ReconstructionDescription"			Name="Reconstruction Description"
+(0018,9538)	VERS="3"	VR="SQ"   VM="1"	Keyword="PerProjectionAcquisitionSequence"	Name="Per Projection Acquisition Sequence"
+(0018,9541) VERS="3"	VR="SQ"   VM="1"	Keyword="DetectorPositionSequence"				Name="Detector Position Sequence"
+(0018,9542) VERS="3"	VR="SQ"   VM="1"	Keyword="XRayAcquisitionDoseSequence"			Name="X-Ray Acquisition Dose Sequence"
+(0018,9543) VERS="3"	VR="FD"   VM="1"	Keyword="XRaySourceIsocenterPrimaryAngle"		Name="X-Ray Source Isocenter Primary Angle"
+(0018,9544) VERS="3"	VR="FD"   VM="1"	Keyword="XRaySourceIsocenterSecondaryAngle"		Name="X-Ray Source Isocenter Secondary Angle"
+(0018,9545) VERS="3"	VR="FD"   VM="1"	Keyword="BreastSupportIsocenterPrimaryAngle"	Name="Breast Support Isocenter Primary Angle"
+(0018,9546) VERS="3"	VR="FD"   VM="1"	Keyword="BreastSupportIsocenterSecondaryAngle"	Name="Breast Support Isocenter Secondary Angle"
+(0018,9547) VERS="3"	VR="FD"   VM="1"	Keyword="BreastSupportXPositionToIsocenter"		Name="Breast Support X Position to Isocenter"
+(0018,9548) VERS="3"	VR="FD"   VM="1"	Keyword="BreastSupportYPositionToIsocenter"		Name="Breast Support Y Position to Isocenter"
+(0018,9549) VERS="3"	VR="FD"   VM="1"	Keyword="BreastSupportZPositionToIsocenter"		Name="Breast Support Z Position to Isocenter"
+(0018,9550) VERS="3"	VR="FD"   VM="1"	Keyword="DetectorIsocenterPrimaryAngle"			Name="Detector Isocenter Primary Angle"
+(0018,9551) VERS="3"	VR="FD"   VM="1"	Keyword="DetectorIsocenterSecondaryAngle"		Name="Detector Isocenter Secondary Angle"
+(0018,9552) VERS="3"	VR="FD"   VM="1"	Keyword="DetectorXPositionToIsocenter"			Name="Detector X Position to Isocenter"
+(0018,9553) VERS="3"	VR="FD"   VM="1"	Keyword="DetectorYPositionToIsocenter"			Name="Detector Y Position to Isocenter"
+(0018,9554) VERS="3"	VR="FD"   VM="1"	Keyword="DetectorZPositionToIsocenter"			Name="Detector Z Position to Isocenter"
+(0018,9555) VERS="3"	VR="SQ"   VM="1"	Keyword="XRayGridSequence"						Name="X-Ray Grid Sequence"
+(0018,9556) VERS="3"	VR="SQ"   VM="1"	Keyword="XRayFilterSequence"					Name="X-Ray Filter Sequence"
+(0018,9557) VERS="3"	VR="FD"   VM="3"	Keyword="DetectorActiveAreaTLHCPosition"		Name="Detector Active Area TLHC Position"
+(0018,9558) VERS="3"	VR="FD"   VM="6"	Keyword="DetectorActiveAreaOrientation"			Name="Detector Active Area Orientation"
+(0018,9559) VERS="3"	VR="CS"   VM="1"	Keyword="PositionerPrimaryAngleDirection"		Name="Positioner Primary Angle Direction"
+(0018,9601)	VERS="3"	VR="SQ"   VM="1"	Keyword="DiffusionBMatrixSequence"	Name="Diffusion b-matrix Sequence"
+(0018,9602)	VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValueXX"	Name="Diffusion b-value XX"
+(0018,9603)	VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValueXY"	Name="Diffusion b-value XY"
+(0018,9604)	VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValueXZ"	Name="Diffusion b-value XZ"
+(0018,9605)	VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValueYY"	Name="Diffusion b-value YY"
+(0018,9606)	VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValueYZ"	Name="Diffusion b-value YZ"
+(0018,9607)	VERS="3"	VR="FD"   VM="1"	Keyword="DiffusionBValueZZ"	Name="Diffusion b-value ZZ"
+(0018,9701)	VERS="3"	VR="DT"   VM="1"	Keyword="DecayCorrectionDateTime"						Name="Decay Correction DateTime"
+(0018,9715)	VERS="3"	VR="FD"   VM="1"	Keyword="StartDensityThreshold"							Name="Start Density Threshold"
+(0018,9716)	VERS="3"	VR="FD"   VM="1"	Keyword="StartRelativeDensityDifferenceThreshold"		Name="Start Relative Density Difference Threshold"
+(0018,9717)	VERS="3"	VR="FD"   VM="1"	Keyword="StartCardiacTriggerCountThreshold"				Name="Start Cardiac Trigger Count Threshold"
+(0018,9718)	VERS="3"	VR="FD"   VM="1"	Keyword="StartRespiratoryTriggerCountThreshold"			Name="Start Respiratory Trigger Count Threshold"
+(0018,9719)	VERS="3"	VR="FD"   VM="1"	Keyword="TerminationCountsThreshold"					Name="Termination Counts Threshold"
+(0018,9720)	VERS="3"	VR="FD"   VM="1"	Keyword="TerminationDensityThreshold"					Name="Termination Density Threshold"
+(0018,9721)	VERS="3"	VR="FD"   VM="1"	Keyword="TerminationRelativeDensityThreshold"			Name="Termination Relative Density Threshold"
+(0018,9722)	VERS="3"	VR="FD"   VM="1"	Keyword="TerminationTimeThreshold"						Name="Termination Time Threshold"
+(0018,9723)	VERS="3"	VR="FD"   VM="1"	Keyword="TerminationCardiacTriggerCountThreshold"		Name="Termination Cardiac Trigger Count Threshold"
+(0018,9724)	VERS="3"	VR="FD"   VM="1"	Keyword="TerminationRespiratoryTriggerCountThreshold"	Name="Termination Respiratory Trigger Count Threshold"
+(0018,9725)	VERS="3"	VR="CS"   VM="1"	Keyword="DetectorGeometry"								Name="Detector Geometry"
+(0018,9726)	VERS="3"	VR="FD"   VM="1"	Keyword="TransverseDetectorSeparation"					Name="Transverse Detector Separation"
+(0018,9727)	VERS="3"	VR="FD"   VM="1"	Keyword="AxialDetectorDimension"						Name="Axial Detector Dimension"
+(0018,9729)	VERS="3"	VR="US"   VM="1"	Keyword="RadiopharmaceuticalAgentNumber"				Name="Radiopharmaceutical Agent Number"
+(0018,9732)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETFrameAcquisitionSequence"					Name="PET Frame Acquisition Sequence"
+(0018,9733)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETDetectorMotionDetailsSequence"				Name="PET Detector Motion Details Sequence"
+(0018,9734)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETTableDynamicsSequence"						Name="PET Table Dynamics Sequence"
+(0018,9735)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETPositionSequence"							Name="PET Position Sequence"
+(0018,9736)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETFrameCorrectionFactorsSequence"				Name="PET Frame Correction Factors Sequence"
+(0018,9737)	VERS="3"	VR="SQ"   VM="1"	Keyword="RadiopharmaceuticalUsageSequence"				Name="Radiopharmaceutical Usage Sequence"
+(0018,9738)	VERS="3"	VR="CS"   VM="1"	Keyword="AttenuationCorrectionSource"					Name="Attenuation Correction Source"
+(0018,9739)	VERS="3"	VR="US"   VM="1"	Keyword="NumberOfIterations"							Name="Number of Iterations"
+(0018,9740)	VERS="3"	VR="US"   VM="1"	Keyword="NumberOfSubsets"								Name="Number of Subsets"
+(0018,9749)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETReconstructionSequence"						Name="PET Reconstruction Sequence"
+(0018,9751)	VERS="3"	VR="SQ"   VM="1"	Keyword="PETFrameTypeSequence"							Name="PET Frame Type Sequence"
+(0018,9755)	VERS="3"	VR="CS"   VM="1"	Keyword="TimeOfFlightInformationUsed"					Name="Time of Flight Information Used"
+(0018,9756)	VERS="3"	VR="CS"   VM="1"	Keyword="ReconstructionType"							Name="Reconstruction Type"
+(0018,9758)	VERS="3"	VR="CS"   VM="1"	Keyword="DecayCorrected"								Name="Decay Corrected"
+(0018,9759)	VERS="3"	VR="CS"   VM="1"	Keyword="AttenuationCorrected"							Name="Attenuation Corrected"
+(0018,9760)	VERS="3"	VR="CS"   VM="1"	Keyword="ScatterCorrected"								Name="Scatter Corrected"
+(0018,9761)	VERS="3"	VR="CS"   VM="1"	Keyword="DeadTimeCorrected"								Name="Dead Time Corrected"
+(0018,9762)	VERS="3"	VR="CS"   VM="1"	Keyword="GantryMotionCorrected"							Name="Gantry Motion Corrected"
+(0018,9763)	VERS="3"	VR="CS"   VM="1"	Keyword="PatientMotionCorrected"						Name="Patient Motion Corrected"
+(0018,9764)	VERS="3"	VR="CS"   VM="1"	Keyword="CountLossNormalizationCorrected"				Name="Count Loss Normalization Corrected"
+(0018,9765)	VERS="3"	VR="CS"   VM="1"	Keyword="RandomsCorrected"								Name="Randoms Corrected"
+(0018,9766)	VERS="3"	VR="CS"   VM="1"	Keyword="NonUniformRadialSamplingCorrected"				Name="Non-uniform Radial Sampling Corrected"
+(0018,9767)	VERS="3"	VR="CS"   VM="1"	Keyword="SensitivityCalibrated"							Name="Sensitivity Calibrated"
+(0018,9768)	VERS="3"	VR="CS"   VM="1"	Keyword="DetectorNormalizationCorrection"				Name="Detector Normalization Correction"
+(0018,9769)	VERS="3"	VR="CS"   VM="1"	Keyword="IterativeReconstructionMethod"					Name="Iterative Reconstruction Method"
+(0018,9770)	VERS="3"	VR="CS"   VM="1"	Keyword="AttenuationCorrectionTemporalRelationship"		Name="Attenuation Correction Temporal Relationship"
+(0018,9771)	VERS="3"	VR="SQ"   VM="1"	Keyword="PatientPhysiologicalStateSequence"				Name="Patient Physiological State Sequence"
+(0018,9772)	VERS="3"	VR="SQ"   VM="1"	Keyword="PatientPhysiologicalStateCodeSequence"			Name="Patient Physiological State Code Sequence"
+(0018,9801) VERS="3"	VR="FD"   VM="1-n"	Keyword="DepthsOfFocus"								Name="Depth(s) of Focus"
+(0018,9803) VERS="3"	VR="SQ"   VM="1"	Keyword="ExcludedIntervalsSequence"					Name="Excluded Intervals Sequence"
+(0018,9804) VERS="3"	VR="DT"   VM="1"	Keyword="ExclusionStartDateTime"					Name="Exclusion Start DateTime"
+(0018,9805) VERS="3"	VR="FD"   VM="1"	Keyword="ExclusionDuration"							Name="Exclusion Duration"
+(0018,9806) VERS="3"	VR="SQ"   VM="1"	Keyword="USImageDescriptionSequence"				Name="US Image Description Sequence"
+(0018,9807) VERS="3"	VR="SQ"   VM="1"	Keyword="ImageDataTypeSequence"						Name="Image Data Type Sequence"
+(0018,9808) VERS="3"	VR="CS"   VM="1"	Keyword="DataType"									Name="Data Type"
+(0018,9809) VERS="3"	VR="SQ"   VM="1"	Keyword="TransducerScanPatternCodeSequence"			Name="Transducer Scan Pattern Code Sequence"
+(0018,980B) VERS="3"	VR="CS"   VM="1"	Keyword="AliasedDataType"							Name="Aliased Data Type"
+(0018,980C) VERS="3"	VR="CS"   VM="1"	Keyword="PositionMeasuringDeviceUsed"				Name="Position Measuring Device Used"
+(0018,980D) VERS="3"	VR="SQ"   VM="1"	Keyword="TransducerGeometryCodeSequence"			Name="Transducer Geometry Code Sequence"
+(0018,980E) VERS="3"	VR="SQ"   VM="1"	Keyword="TransducerBeamSteeringCodeSequence"		Name="Transducer Beam Steering Code Sequence"
+(0018,980F) VERS="3"	VR="SQ"   VM="1"	Keyword="TransducerApplicationCodeSequence"			Name="Transducer Application Code Sequence"
+(0018,9810) VERS="3"	VR="XS"   VM="1"	Keyword="ZeroVelocityPixelValue"					Name="Zero Velocity Pixel Value"
+(0018,A001) VERS="3"	VR="SQ"   VM="1"	Keyword="ContributingEquipmentSequence"		Name="Contributing Equipment Sequence"
+(0018,A002) VERS="3"	VR="DT"   VM="1"	Keyword="ContributionDateTime"			Name="Contribution DateTime"
+(0018,A003) VERS="3"	VR="ST"   VM="1"	Keyword="ContributionDescription"		Name="Contribution Description"
+(0020,000D) VERS="3"	VR="UI"   VM="1"	Keyword="StudyInstanceUID"			Name="Study Instance UID"
+(0020,000E) VERS="3"	VR="UI"   VM="1"	Keyword="SeriesInstanceUID"			Name="Series Instance UID"
+(0020,0010) VERS="3"	VR="SH"   VM="1"	Keyword="StudyID"				Name="Study ID"
+(0020,0011) VERS="3"	VR="IS"   VM="1"	Keyword="SeriesNumber"				Name="Series Number"
+(0020,0012) VERS="3"	VR="IS"   VM="1"	Keyword="AcquisitionNumber"			Name="Acquisition Number"
+(0020,0013) VERS="3"	VR="IS"   VM="1"	Keyword="InstanceNumber"			Name="Instance Number"
+(0020,0014) VERS="RET"	VR="IS"   VM="1"	Keyword="IsotopeNumber"				Name="Isotope Number"
+(0020,0015) VERS="RET"	VR="IS"   VM="1"	Keyword="PhaseNumber"				Name="Phase Number"
+(0020,0016) VERS="RET"	VR="IS"   VM="1"	Keyword="IntervalNumber"			Name="Interval Number"
+(0020,0017) VERS="RET"	VR="IS"   VM="1"	Keyword="TimeSlotNumber"			Name="Time Slot Number"
+(0020,0018) VERS="RET"	VR="IS"   VM="1"	Keyword="AngleNumber"				Name="Angle Number"
+(0020,0019) VERS="3"	VR="IS"   VM="1"	Keyword="ItemNumber"				Name="Item Number"
+(0020,0020) VERS="3"	VR="CS"   VM="2"	Keyword="PatientOrientation"			Name="Patient Orientation"
+(0020,0022) VERS="RET"	VR="IS"   VM="1"	Keyword="OverlayNumber"				Name="Overlay Number"
+(0020,0024) VERS="RET"	VR="IS"   VM="1"	Keyword="CurveNumber"				Name="Curve Number"
+(0020,0026) VERS="RET"	VR="IS"   VM="1"	Keyword="LUTNumber"				Name="LUT Number"
+(0020,0030) VERS="RET"	VR="DS"   VM="3"	Keyword="ImagePosition"				Name="Image Position"
+(0020,0032) VERS="3"	VR="DS"   VM="3"	Keyword="ImagePositionPatient"			Name="Image Position (Patient)"
+(0020,0035) VERS="RET"	VR="DS"   VM="6"	Keyword="ImageOrientation"			Name="Image Orientation"
+(0020,0037) VERS="3"	VR="DS"   VM="6"	Keyword="ImageOrientationPatient"		Name="Image Orientation (Patient)"
+(0020,0050) VERS="RET"	VR="DS"   VM="1"	Keyword="Location"				Name="Location"
+(0020,0052) VERS="3"	VR="UI"   VM="1"	Keyword="FrameOfReferenceUID"			Name="Frame of Reference UID"
+(0020,0060) VERS="3"	VR="CS"   VM="1"	Keyword="Laterality"				Name="Laterality"
+(0020,0062) VERS="3"	VR="CS"   VM="1"	Keyword="ImageLaterality"			Name="Image Laterality"
+(0020,0070) VERS="RET"	VR="LO"   VM="1"	Keyword="ImageGeometryType"			Name="Image Geometry Type"
+(0020,0080) VERS="RET"	VR="CS"   VM="1-n"	Keyword="MaskingImage"				Name="Masking Image"
+(0020,00AA) VERS="RET"	VR="IS"   VM="1"	Keyword="ReportNumber"				Name="Report Number"
+(0020,0100) VERS="3"	VR="IS"   VM="1"	Keyword="TemporalPositionIdentifier"		Name="Temporal Position Identifier"
+(0020,0105) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfTemporalPositions"		Name="Number of Temporal Positions"
+(0020,0110) VERS="3"	VR="DS"   VM="1"	Keyword="TemporalResolution"			Name="Temporal Resolution"
+(0020,0200) VERS="3"	VR="UI"   VM="1"	Keyword="SynchronizationFrameOfReferenceUID"	Name="Synchronization Frame of Reference UID"
+(0020,0242) VERS="3"	VR="UI"   VM="1"	Keyword="SOPInstanceUIDOfConcatenationSource"	Name="SOP Instance UID of Concatenation Source"
+(0020,1000) VERS="RET"	VR="IS"   VM="1"	Keyword="SeriesInStudy"				Name="Series in Study"
+(0020,1001) VERS="RET"	VR="IS"   VM="1"	Keyword="AcquisitionsInSeries"			Name="Acquisitions in Series"
+(0020,1002) VERS="3"	VR="IS"   VM="1"	Keyword="ImagesInAcquisition"			Name="Images in Acquisition"
+(0020,1003) VERS="RET"	VR="IS"   VM="1"	Keyword="ImagesInSeries"			Name="Images in Series"
+(0020,1004) VERS="RET"	VR="IS"   VM="1"	Keyword="AcquisitionsInStudy"			Name="Acquisitions in Study"
+(0020,1005) VERS="RET"	VR="IS"   VM="1"	Keyword="ImagesInStudy"				Name="Images in Study"
+(0020,1020) VERS="RET"	VR="LO"   VM="1-n"	Keyword="Reference"				Name="Reference"
+(0020,1040) VERS="3"	VR="LO"   VM="1"	Keyword="PositionReferenceIndicator"		Name="Position Reference Indicator"
+(0020,1041) VERS="3"	VR="DS"   VM="1"	Keyword="SliceLocation"				Name="Slice Location"
+(0020,1070) VERS="RET"	VR="IS"   VM="1-n"	Keyword="OtherStudyNumbers"			Name="Other Study Numbers"
+(0020,1200) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfPatientRelatedStudies"		Name="Number of Patient Related Studies"
+(0020,1202) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfPatientRelatedSeries"		Name="Number of Patient Related Series"
+(0020,1204) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfPatientRelatedInstances"	Name="Number of Patient Related Instances"
+(0020,1206) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfStudyRelatedSeries"		Name="Number of Study Related Series"
+(0020,1208) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfStudyRelatedInstances"		Name="Number of Study Related Instances"
+(0020,1209) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfSeriesRelatedInstances"	Name="Number of Series Related Instances"
+(0020,31xx) VERS="RET"	VR="CS"   VM="1-n"	Keyword="SourceImageID"				Name="Source Image IDs"
+(0020,3401) VERS="RET"	VR="CS"   VM="1"	Keyword="ModifyingDeviceID"			Name="Modifying Device ID"
+(0020,3402) VERS="RET"	VR="CS"   VM="1"	Keyword="ModifiedImageID"			Name="Modified Image ID"
+(0020,3403) VERS="RET"	VR="DA"   VM="1"	Keyword="ModifiedImageDate"			Name="Modified Image Date"
+(0020,3404) VERS="RET"	VR="LO"   VM="1"	Keyword="ModifyingDeviceManufacturer"		Name="Modifying Device Manufacturer"
+(0020,3405) VERS="RET"	VR="TM"   VM="1"	Keyword="ModifiedImageTime"			Name="Modified Image Time"
+(0020,3406) VERS="RET"	VR="LO"   VM="1"	Keyword="ModifiedImageDescription"		Name="Modified Image Description"
+(0020,4000) VERS="3"	VR="LT"   VM="1"	Keyword="ImageComments"				Name="Image Comments"
+(0020,5000) VERS="RET"	VR="AT"   VM="1-n"	Keyword="OriginalImageIdentification"		Name="Original Image Identification"
+(0020,5002) VERS="RET"	VR="LO"   VM="1-n"	Keyword="OriginalImageIdentificationNomenclature"	Name="Original Image Identification Nomenclature"
+(0020,9056) VERS="3"	VR="SH"   VM="1"	Keyword="StackID"				Name="Stack ID"
+(0020,9057) VERS="3"	VR="UL"   VM="1"	Keyword="InStackPositionNumber"			Name="In-Stack Position Number"
+(0020,9071) VERS="3"	VR="SQ"   VM="1"	Keyword="FrameAnatomySequence"			Name="Frame Anatomy Sequence"
+(0020,9072) VERS="3"	VR="CS"   VM="1"	Keyword="FrameLaterality"			Name="Frame Laterality"
+(0020,9111) VERS="3"	VR="SQ"   VM="1"	Keyword="FrameContentSequence"			Name="Frame Content Sequence"
+(0020,9113) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanePositionSequence"			Name="Plane Position Sequence"
+(0020,9116) VERS="3"	VR="SQ"   VM="1"	Keyword="PlaneOrientationSequence"		Name="Plane Orientation Sequence"
+(0020,9128) VERS="3"	VR="UL"   VM="1"	Keyword="TemporalPositionIndex"			Name="Temporal Position Index"
+(0020,9153) VERS="3"	VR="FD"   VM="1"	Keyword="NominalCardiacTriggerDelayTime"			Name="Nominal Cardiac Trigger Delay Time"
+(0020,9154) VERS="3"	VR="FL"   VM="1"	Keyword="NominalCardiacTriggerTimePriorToRPeak"		Name="Nominal Cardiac Trigger Time Prior To R-Peak"
+(0020,9155) VERS="3"	VR="FL"   VM="1"	Keyword="ActualCardiacTriggerTimePriorToRPeak"		Name="Actual Cardiac Trigger Time Prior To R-Peak"
+(0020,9156) VERS="3"	VR="US"   VM="1"	Keyword="FrameAcquisitionNumber"		Name="Frame Acquisition Number"
+(0020,9157) VERS="3"	VR="UL"   VM="1-n"	Keyword="DimensionIndexValues"			Name="Dimension Index Values"
+(0020,9158) VERS="3"	VR="LT"   VM="1"	Keyword="FrameComments"				Name="Frame Comments"
+(0020,9161) VERS="3"	VR="UI"   VM="1"	Keyword="ConcatenationUID"			Name="Concatenation UID"
+(0020,9162) VERS="3"	VR="US"   VM="1"	Keyword="InConcatenationNumber"			Name="In-concatenation Number"
+(0020,9163) VERS="3"	VR="US"   VM="1"	Keyword="InConcatenationTotalNumber"		Name="In-concatenation Total Number"
+(0020,9164) VERS="3"	VR="UI"   VM="1"	Keyword="DimensionOrganizationUID"		Name="Dimension Organization UID"
+(0020,9165) VERS="3"	VR="AT"   VM="1"	Keyword="DimensionIndexPointer"			Name="Dimension Index Pointer"
+(0020,9167) VERS="3"	VR="AT"   VM="1"	Keyword="FunctionalGroupPointer"		Name="Functional Group Pointer"
+(0020,9170) VERS="3"	VR="SQ"   VM="1"	Keyword="UnassignedSharedConvertedAttributesSequence"		Name="Unassigned Shared Converted Attributes Sequence"
+(0020,9171) VERS="3"	VR="SQ"   VM="1"	Keyword="UnassignedPerFrameConvertedAttributesSequence"		Name="Unassigned Per-Frame Converted Attributes Sequence"
+(0020,9172) VERS="3"	VR="SQ"   VM="1"	Keyword="ConversionSourceAttributesSequence"				Name="Conversion Source Attributes Sequence"
+(0020,9213) VERS="3"	VR="LO"   VM="1"	Keyword="DimensionIndexPrivateCreator"		Name="Dimension Index Private Creator"
+(0020,9221) VERS="3"	VR="SQ"   VM="1"	Keyword="DimensionOrganizationSequence"		Name="Dimension Organization Sequence"
+(0020,9222) VERS="3"	VR="SQ"   VM="1"	Keyword="DimensionIndexSequence"		Name="Dimension Index Sequence"
+(0020,9228) VERS="3"	VR="UL"   VM="1"	Keyword="ConcatenationFrameOffsetNumber"	Name="Concatenation Frame Offset Number"
+(0020,9238) VERS="3"	VR="LO"   VM="1"	Keyword="FunctionalGroupPrivateCreator"		Name="Functional Group Private Creator"
+(0020,9241) VERS="3"	VR="FL"   VM="1"	Keyword="NominalPercentageOfCardiacPhase"		Name="Nominal Percentage of Cardiac Phase"
+(0020,9245) VERS="3"	VR="FL"   VM="1"	Keyword="NominalPercentageOfRespiratoryPhase"		Name="Nominal Percentage of Respiratory Phase"
+(0020,9246) VERS="3"	VR="FL"   VM="1"	Keyword="StartingRespiratoryAmplitude"		Name="Starting Respiratory Amplitude"
+(0020,9247) VERS="3"	VR="CS"   VM="1"	Keyword="StartingRespiratoryPhase"		Name="Starting Respiratory Phase"
+(0020,9248) VERS="3"	VR="FL"   VM="1"	Keyword="EndingRespiratoryAmplitude"		Name="Ending Respiratory Amplitude"
+(0020,9249) VERS="3"	VR="CS"   VM="1"	Keyword="EndingRespiratoryPhase"		Name="Ending Respiratory Phase"
+(0020,9250) VERS="3"	VR="CS"   VM="1"	Keyword="RespiratoryTriggerType"		Name="Respiratory Trigger Type"
+(0020,9251) VERS="3"	VR="FD"   VM="1"	Keyword="RRIntervalTimeNominal"	Name="R-R Interval Time Nominal"
+(0020,9252) VERS="3"	VR="FD"   VM="1"	Keyword="ActualCardiacTriggerDelayTime"		Name="Actual Cardiac Trigger Delay Time"
+(0020,9253) VERS="3"	VR="SQ"   VM="1"	Keyword="RespiratorySynchronizationSequence"	Name="Respiratory Synchronization Sequence"
+(0020,9254) VERS="3"	VR="FD"   VM="1"	Keyword="RespiratoryIntervalTime"	Name="Respiratory Interval Time"
+(0020,9255) VERS="3"	VR="FD"   VM="1"	Keyword="NominalRespiratoryTriggerDelayTime"	Name="Nominal Respiratory Trigger Delay Time"
+(0020,9256) VERS="3"	VR="FD"   VM="1"	Keyword="RespiratoryTriggerDelayThreshold"	Name="Respiratory Trigger Delay Threshold"
+(0020,9257) VERS="3"	VR="FD"   VM="1"	Keyword="ActualRespiratoryTriggerDelayTime"		Name="Actual Respiratory Trigger Delay Time"
+(0020,9301) VERS="3"	VR="FD"   VM="3"	Keyword="ImagePositionVolume"						Name="Image Position (Volume)"
+(0020,9302) VERS="3"	VR="FD"   VM="6"	Keyword="ImageOrientationVolume"					Name="Image Orientation (Volume)"
+(0020,9307) VERS="3"	VR="CS"   VM="1"	Keyword="UltrasoundAcquisitionGeometry"				Name="Ultrasound Acquisition Geometry"
+(0020,9308) VERS="3"	VR="FD"   VM="3"	Keyword="ApexPosition"								Name="Apex Position"
+(0020,9309) VERS="3"	VR="FD"   VM="16"	Keyword="VolumeToTransducerMappingMatrix"			Name="Volume to Transducer Mapping Matrix"
+(0020,930A) VERS="3"	VR="FD"   VM="16"	Keyword="VolumeToTableMappingMatrix"				Name="Volume to Table Mapping Matrix"
+(0020,930B) VERS="3"	VR="CS"   VM="1"	Keyword="VolumeToTransducerRelationship"				Name="Volume to Transducer Relationship"
+(0020,930C) VERS="3"	VR="CS"   VM="1"	Keyword="PatientFrameOfReferenceSource"				Name="Patient Frame of Reference Source"
+(0020,930D) VERS="3"	VR="FD"   VM="1"	Keyword="TemporalPositionTimeOffset"				Name="Temporal Position Time Offset"
+(0020,930E) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanePositionVolumeSequence"				Name="Plane Position (Volume) Sequence"
+(0020,930F) VERS="3"	VR="SQ"   VM="1"	Keyword="PlaneOrientationVolumeSequence"			Name="Plane Orientation (Volume) Sequence"
+(0020,9310) VERS="3"	VR="SQ"   VM="1"	Keyword="TemporalPositionSequence"					Name="Temporal Position Sequence"
+(0020,9311) VERS="3"	VR="CS"   VM="1"	Keyword="DimensionOrganizationType"					Name="Dimension Organization Type"
+(0020,9312) VERS="3"	VR="UI"   VM="1"	Keyword="VolumeFrameOfReferenceUID"					Name="Volume Frame of Reference UID"
+(0020,9313) VERS="3"	VR="UI"   VM="1"	Keyword="TableFrameOfReferenceUID"					Name="Table Frame of Reference UID"
+(0020,9421) VERS="3"	VR="LO"   VM="1"	Keyword="DimensionDescriptionLabel"	Name="Dimension Description Label"
+(0020,9450) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientOrientationInFrameSequence"	Name="Patient Orientation in Frame Sequence"
+(0020,9453) VERS="3"	VR="LO"   VM="1"	Keyword="FrameLabel"	Name="Frame Label"
+(0020,9518)	VERS="3"	VR="US"   VM="1-n"	Keyword="AcquisitionIndex"							Name="Acquisition Index"
+(0020,9529)	VERS="3"	VR="SQ"   VM="1"	Keyword="ContributingSOPInstancesReferenceSequence"	Name="Contributing SOP Instances Reference Sequence"
+(0020,9536)	VERS="3"	VR="US"   VM="1"	Keyword="ReconstructionIndex"						Name="Reconstruction Index"
+(0022,0001) VERS="3"	VR="US"   VM="1"	Keyword="LightPathFilterPassThroughWavelength"		Name="Light Path Filter Pass-Through Wavelength"
+(0022,0002) VERS="3"	VR="US"   VM="2"	Keyword="LightPathFilterPassBand"			Name="Light Path Filter Pass Band"
+(0022,0003) VERS="3"	VR="US"   VM="1"	Keyword="ImagePathFilterPassThroughWavelength"		Name="Image Path Filter Pass-Through Wavelength"
+(0022,0004) VERS="3"	VR="US"   VM="2"	Keyword="ImagePathFilterPassBand"			Name="Image Path Filter Pass Band"
+(0022,0005) VERS="3"	VR="CS"   VM="1"	Keyword="PatientEyeMovementCommanded"			Name="Patient Eye Movement Commanded"
+(0022,0006) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientEyeMovementCommandCodeSequence"	Name="Patient Eye Movement Command Code Sequence"
+(0022,0007) VERS="3"	VR="FL"   VM="1"	Keyword="SphericalLensPower"				Name="Spherical Lens Power"
+(0022,0008) VERS="3"	VR="FL"   VM="1"	Keyword="CylinderLensPower"				Name="Cylinder Lens Power"
+(0022,0009) VERS="3"	VR="FL"   VM="1"	Keyword="CylinderAxis"					Name="Cylinder Axis"
+(0022,000A) VERS="3"	VR="FL"   VM="1"	Keyword="EmmetropicMagnification"			Name="Emmetropic Magnification"
+(0022,000B) VERS="3"	VR="FL"   VM="1"	Keyword="IntraOcularPressure"				Name="Intra Ocular Pressure"
+(0022,000C) VERS="3"	VR="FL"   VM="1"	Keyword="HorizontalFieldOfView"				Name="Horizontal Field of View"
+(0022,000D) VERS="3"	VR="CS"   VM="1"	Keyword="PupilDilated"					Name="Pupil Dilated"
+(0022,000E) VERS="3"	VR="FL"   VM="1"	Keyword="DegreeOfDilation"				Name="Degree of Dilation"
+(0022,0010) VERS="3"	VR="FL"   VM="1"	Keyword="StereoBaselineAngle"				Name="Stereo Baseline Angle"
+(0022,0011) VERS="3"	VR="FL"   VM="1"	Keyword="StereoBaselineDisplacement"			Name="Stereo Baseline Displacement"
+(0022,0012) VERS="3"	VR="FL"   VM="1"	Keyword="StereoHorizontalPixelOffset"			Name="Stereo Horizontal Pixel Offset"
+(0022,0013) VERS="3"	VR="FL"   VM="1"	Keyword="StereoVerticalPixelOffset"			Name="Stereo Vertical Pixel Offset"
+(0022,0014) VERS="3"	VR="FL"   VM="1"	Keyword="StereoRotation"				Name="Stereo Rotation"
+(0022,0015) VERS="3"	VR="SQ"   VM="1"	Keyword="AcquisitionDeviceTypeCodeSequence"		Name="Acquisition Device Type Code Sequence"
+(0022,0016) VERS="3"	VR="SQ"   VM="1"	Keyword="IlluminationTypeCodeSequence"			Name="Illumination Type Code Sequence"
+(0022,0017) VERS="3"	VR="SQ"   VM="1"	Keyword="LightPathFilterTypeStackCodeSequence"		Name="Light Path Filter Type Stack Code Sequence"
+(0022,0018) VERS="3"	VR="SQ"   VM="1"	Keyword="ImagePathFilterTypeStackCodeSequence"		Name="Image Path Filter Type Stack Code Sequence"
+(0022,0019) VERS="3"	VR="SQ"   VM="1"	Keyword="LensesCodeSequence"				Name="Lenses Code Sequence"
+(0022,001A) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelDescriptionCodeSequence"		Name="Channel Description Code Sequence"
+(0022,001B) VERS="3"	VR="SQ"   VM="1"	Keyword="RefractiveStateSequence"			Name="Refractive State Sequence"
+(0022,001C) VERS="3"	VR="SQ"   VM="1"	Keyword="MydriaticAgentCodeSequence"			Name="Mydriatic Agent Code Sequence"
+(0022,001D) VERS="3"	VR="SQ"   VM="1"	Keyword="RelativeImagePositionCodeSequence"		Name="Relative Image Position Code Sequence"
+(0022,001E) VERS="3"	VR="FL"   VM="1"	Keyword="CameraAngleOfView"		Name="Camera Angle of View"
+(0022,0020) VERS="3"	VR="SQ"   VM="1"	Keyword="StereoPairsSequence"				Name="Stereo Pairs Sequence"
+(0022,0021) VERS="3"	VR="SQ"   VM="1"	Keyword="LeftImageSequence"				Name="Left Image Sequence"
+(0022,0022) VERS="3"	VR="SQ"   VM="1"	Keyword="RightImageSequence"				Name="Right Image Sequence"
+(0022,0028) VERS="3"	VR="CS"   VM="1"	Keyword="StereoPairsPresent"				Name="Stereo Pairs Present"
+(0022,0030) VERS="3"	VR="FL"   VM="1"	Keyword="AxialLengthOfTheEye"				Name="Axial Length of the Eye"
+(0022,0031) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicFrameLocationSequence"				Name="Ophthalmic Frame Location Sequence"
+(0022,0032) VERS="3"	VR="FL"   VM="2-2n"	Keyword="ReferenceCoordinates"				Name="Reference Coordinates"
+(0022,0035) VERS="3"	VR="FL"   VM="1"	Keyword="DepthSpatialResolution"				Name="Depth Spatial Resolution"
+(0022,0036) VERS="3"	VR="FL"   VM="1"	Keyword="MaximumDepthDistortion"				Name="Maximum Depth Distortion"
+(0022,0037) VERS="3"	VR="FL"   VM="1"	Keyword="AlongScanSpatialResolution"				Name="Along-scan Spatial Resolution"
+(0022,0038) VERS="3"	VR="FL"   VM="1"	Keyword="MaximumAlongScanDistortion"				Name="Maximum Along-scan Distortion"
+(0022,0039) VERS="3"	VR="CS"   VM="1"	Keyword="OphthalmicImageOrientation"				Name="Ophthalmic Image Orientation"
+(0022,0041) VERS="3"	VR="FL"   VM="1"	Keyword="DepthOfTransverseImage"				Name="Depth of Transverse Image"
+(0022,0042) VERS="3"	VR="SQ"   VM="1"	Keyword="MydriaticAgentConcentrationUnitsSequence"				Name="Mydriatic Agent Concentration Units Sequence"
+(0022,0048) VERS="3"	VR="FL"   VM="1"	Keyword="AcrossScanSpatialResolution"				Name="Across-scan Spatial Resolution"
+(0022,0049) VERS="3"	VR="FL"   VM="1"	Keyword="MaximumAcrossScanDistortion"				Name="Maximum Across-scan Distortion"
+(0022,004E) VERS="3"	VR="DS"   VM="1"	Keyword="MydriaticAgentConcentration"				Name="Mydriatic Agent Concentration"
+(0022,0055) VERS="3"	VR="FL"   VM="1"	Keyword="IlluminationWaveLength"				Name="Illumination Wave Length"
+(0022,0056) VERS="3"	VR="FL"   VM="1"	Keyword="IlluminationPower"				Name="Illumination Power"
+(0022,0057) VERS="3"	VR="FL"   VM="1"	Keyword="IlluminationBandwidth"				Name="Illumination Bandwidth"
+(0022,0058) VERS="3"	VR="SQ"   VM="1"	Keyword="MydriaticAgentSequence"				Name="Mydriatic Agent Sequence"
+(0022,1007) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialMeasurementsRightEyeSequence"				Name="Ophthalmic Axial Measurements Right Eye Sequence"
+(0022,1008) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialMeasurementsLeftEyeSequence"				Name="Ophthalmic Axial Measurements Left Eye Sequence"
+(0022,1009) VERS="3"	VR="CS"   VM="1"	Keyword="OphthalmicAxialMeasurementsDeviceType"						Name="Ophthalmic Axial Measurements Device Type"
+(0022,1010) VERS="3"	VR="CS"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementsType"						Name="Ophthalmic Axial Length Measurements Type"
+(0022,1012) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthSequence"								Name="Ophthalmic Axial Length Sequence"
+(0022,1019) VERS="3"	VR="FL"   VM="1"	Keyword="OphthalmicAxialLength"										Name="Ophthalmic Axial Length"
+(0022,1024) VERS="3"	VR="SQ"   VM="1"	Keyword="LensStatusCodeSequence"									Name="Lens Status Code Sequence"
+(0022,1025) VERS="3"	VR="SQ"   VM="1"	Keyword="VitreousStatusCodeSequence"								Name="Vitreous Status Code Sequence"
+(0022,1028) VERS="3"	VR="SQ"   VM="1"	Keyword="IOLFormulaCodeSequence"									Name="IOL Formula Code Sequence"
+(0022,1029) VERS="3"	VR="LO"   VM="1"	Keyword="IOLFormulaDetail"											Name="IOL Formula Detail"
+(0022,1033) VERS="3"	VR="FL"   VM="1"	Keyword="KeratometerIndex"											Name="Keratometer Index"
+(0022,1035) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceOfOphthalmicAxialLengthCodeSequence"					Name="Source of Ophthalmic Axial Length Code Sequence"
+(0022,1037) VERS="3"	VR="FL"   VM="1"	Keyword="TargetRefraction"											Name="Target Refraction"
+(0022,1039) VERS="3"	VR="CS"   VM="1"	Keyword="RefractiveProcedureOccurred"								Name="Refractive Procedure Occurred"
+(0022,1040) VERS="3"	VR="SQ"   VM="1"	Keyword="RefractiveSurgeryTypeCodeSequence"							Name="Refractive Surgery Type Code Sequence"
+(0022,1044) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicUltrasoundMethodCodeSequence"					Name="Ophthalmic Ultrasound Method Code Sequence"
+(0022,1050) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementsSequence"					Name="Ophthalmic Axial Length Measurements Sequence"
+(0022,1053) VERS="3"	VR="FL"   VM="1"	Keyword="IOLPower"													Name="IOL Power"
+(0022,1054) VERS="3"	VR="FL"   VM="1"	Keyword="PredictedRefractiveError"									Name="Predicted Refractive Error"
+(0022,1059) VERS="3"	VR="FL"   VM="1"	Keyword="OphthalmicAxialLengthVelocity"								Name="Ophthalmic Axial Length Velocity"
+(0022,1065) VERS="3"	VR="LO"   VM="1"	Keyword="LensStatusDescription"										Name="Lens Status Description"
+(0022,1066) VERS="3"	VR="LO"   VM="1"	Keyword="VitreousStatusDescription"									Name="Vitreous Status Description"
+(0022,1090) VERS="3"	VR="SQ"   VM="1"	Keyword="IOLPowerSequence"											Name="IOL Power Sequence"
+(0022,1092) VERS="3"	VR="SQ"   VM="1"	Keyword="LensConstantSequence"										Name="Lens Constant Sequence"
+(0022,1093) VERS="3"	VR="LO"   VM="1"	Keyword="IOLManufacturer"											Name="IOL Manufacturer"
+(0022,1094) VERS="RET"	VR="LO"   VM="1"	Keyword="LensConstantDescription"									Name="Lens Constant Description"
+(0022,1095) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantName"												Name="Implant Name"
+(0022,1096) VERS="3"	VR="SQ"   VM="1"	Keyword="KeratometryMeasurementTypeCodeSequence"					Name="Keratometry Measurement Type Code Sequence"
+(0022,1097) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantPartNumber"											Name="Implant Part Number"
+(0022,1100) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedOphthalmicAxialMeasurementsSequence"				Name="Referenced Ophthalmic Axial Measurements Sequence"
+(0022,1101) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementsSegmentNameCodeSequence"	Name="Ophthalmic Axial Length Measurements Segment Name Code Sequence"
+(0022,1103) VERS="3"	VR="SQ"   VM="1"	Keyword="RefractiveErrorBeforeRefractiveSurgeryCodeSequence"		Name="Refractive Error Before Refractive Surgery Code Sequence"
+(0022,1121) VERS="3"	VR="FL"   VM="1"	Keyword="IOLPowerForExactEmmetropia"								Name="IOL Power For Exact Emmetropia"
+(0022,1122) VERS="3"	VR="FL"   VM="1"	Keyword="IOLPowerForExactTargetRefraction"							Name="IOL Power For Exact Target Refraction"
+(0022,1125) VERS="3"	VR="SQ"   VM="1"	Keyword="AnteriorChamberDepthDefinitionCodeSequence"				Name="Anterior Chamber Depth Definition Code Sequence"
+(0022,1127) VERS="3"	VR="SQ"   VM="1"	Keyword="LensThicknessSequence"										Name="Lens Thickness Sequence"
+(0022,1128) VERS="3"	VR="SQ"   VM="1"	Keyword="AnteriorChamberDepthSequence"								Name="Anterior Chamber Depth Sequence"
+(0022,1130) VERS="3"	VR="FL"   VM="1"	Keyword="LensThickness"												Name="Lens Thickness"
+(0022,1131) VERS="3"	VR="FL"   VM="1"	Keyword="AnteriorChamberDepth"										Name="Anterior Chamber Depth"
+(0022,1132) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceOfLensThicknessDataCodeSequence"						Name="Source of Lens Thickness Data Code Sequence"
+(0022,1133) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceOfAnteriorChamberDepthDataCodeSequence"				Name="Source of Anterior Chamber Depth Data Code Sequence"
+(0022,1134) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceOfRefractiveMeasurementsSequence"					Name="Source of Refractive Measurements Sequence"
+(0022,1135) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceOfRefractiveMeasurementsCodeSequence"				Name="Source of Refractive Measurements Code Sequence"
+(0022,1140) VERS="3"	VR="CS"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementModified"					Name="Ophthalmic Axial Length Measurement Modified"
+(0022,1150) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthDataSourceCodeSequence"				Name="Ophthalmic Axial Length Data Source Code Sequence"
+(0022,1153) VERS="RET"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthAcquisitionMethodCodeSequence"		Name="Ophthalmic Axial Length Acquisition Method Code Sequence"
+(0022,1155) VERS="3"	VR="FL"   VM="1"	Keyword="SignalToNoiseRatio"										Name="Signal to Noise Ratio"
+(0022,1159) VERS="3"	VR="LO"   VM="1"	Keyword="OphthalmicAxialLengthDataSourceDescription"				Name="Ophthalmic Axial Length Data Source Description"
+(0022,1210) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementsTotalLengthSequence"		Name="Ophthalmic Axial Length Measurements Total Length Sequence"
+(0022,1211) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementsSegmentalLengthSequence"	Name="Ophthalmic Axial Length Measurements Segmental Length Sequence"
+(0022,1212) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthMeasurementsLengthSummationSequence"	Name="Ophthalmic Axial Length Measurements Length Summation Sequence"
+(0022,1220) VERS="3"	VR="SQ"   VM="1"	Keyword="UltrasoundOphthalmicAxialLengthMeasurementsSequence"		Name="Ultrasound Ophthalmic Axial Length Measurements Sequence"
+(0022,1225) VERS="3"	VR="SQ"   VM="1"	Keyword="OpticalOphthalmicAxialLengthMeasurementsSequence"			Name="Optical Ophthalmic Axial Length Measurements Sequence"
+(0022,1230) VERS="3"	VR="SQ"   VM="1"	Keyword="UltrasoundSelectedOphthalmicAxialLengthSequence"			Name="Ultrasound Selected Ophthalmic Axial Length Sequence"
+(0022,1250) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthSelectionMethodCodeSequence"			Name="Ophthalmic Axial Length Selection Method Code Sequence"
+(0022,1255) VERS="3"	VR="SQ"   VM="1"	Keyword="OpticalSelectedOphthalmicAxialLengthSequence"				Name="Optical Selected Ophthalmic Axial Length Sequence"
+(0022,1257) VERS="3"	VR="SQ"   VM="1"	Keyword="SelectedSegmentalOphthalmicAxialLengthSequence"			Name="Selected Segmental Ophthalmic Axial Length Sequence"
+(0022,1260) VERS="3"	VR="SQ"   VM="1"	Keyword="SelectedTotalOphthalmicAxialLengthSequence"				Name="Selected Total Ophthalmic Axial Length Sequence"
+(0022,1262) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthQualityMetricSequence"				Name="Ophthalmic Axial Length Quality Metric Sequence"
+(0022,1265) VERS="RET"	VR="SQ"   VM="1"	Keyword="OphthalmicAxialLengthQualityMetricTypeCodeSequence"		Name="Ophthalmic Axial Length Quality Metric Type Code Sequence"
+(0022,1273) VERS="RET"	VR="LO"   VM="1"	Keyword="OphthalmicAxialLengthQualityMetricTypeDescription"			Name="Ophthalmic Axial Length Quality Metric Type Description"
+(0022,1300) VERS="3"	VR="SQ"   VM="1"	Keyword="IntraocularLensCalculationsRightEyeSequence"				Name="Intraocular Lens Calculations Right Eye Sequence"
+(0022,1310) VERS="3"	VR="SQ"   VM="1"	Keyword="IntraocularLensCalculationsLeftEyeSequence"				Name="Intraocular Lens Calculations Left Eye Sequence"
+(0022,1330) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedOphthalmicAxialLengthMeasurementQCImageSequence"	Name="Referenced Ophthalmic Axial Length Measurement QC Image Sequence"
+(0022,1415) VERS="3"	VR="CS"   VM="1"	Keyword="OphthalmicMappingDeviceType"						Name="Ophthalmic Mapping Device Type"
+(0022,1420) VERS="3"	VR="SQ"   VM="1"	Keyword="AcquisitionMethodCodeSequence"							Name="Acquisition Method Code Sequence"
+(0022,1423) VERS="3"	VR="SQ"   VM="1"	Keyword="AcquisitionMethodAlgorithmSequence"				Name="Acquisition Method Algorithm Sequence"
+(0022,1436) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicThicknessMapTypeCodeSequence"			Name="Ophthalmic Thickness Map Type Code Sequence"
+(0022,1443) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicThicknessMappingNormalsSequence"			Name="Ophthalmic Thickness Mapping Normals Sequence"
+(0022,1445) VERS="3"	VR="SQ"   VM="1"	Keyword="RetinalThicknessDefinitionCodeSequence"			Name="Retinal Thickness Definition Code Sequence"
+(0022,1450) VERS="3"	VR="SQ"   VM="1"	Keyword="PixelValueMappingToCodedConceptSequence"			Name="Pixel Value Mapping to Coded Concept Sequence"
+(0022,1452) VERS="3"	VR="US or SS"   VM="1"	Keyword="MappedPixelValue"								Name="Mapped Pixel Value"
+(0022,1454) VERS="3"	VR="LO"   VM="1"	Keyword="PixelValueMappingExplanation"						Name="Pixel Value Mapping Explanation"
+(0022,1458) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicThicknessMapQualityThresholdSequence"	Name="Ophthalmic Thickness Map Quality Threshold Sequence"
+(0022,1460) VERS="3"	VR="FL"   VM="1"	Keyword="OphthalmicThicknessMapThresholdQualityRating"		Name="Ophthalmic Thickness Map Threshold Quality Rating"
+(0022,1463) VERS="3"	VR="FL"   VM="2"	Keyword="AnatomicStructureReferencePoint"					Name="Anatomic Structure Reference Point"
+(0022,1465) VERS="3"	VR="SQ"   VM="1"	Keyword="RegistrationToLocalizerSequence"					Name="Registration to Localizer Sequence"
+(0022,1466) VERS="3"	VR="CS"   VM="1"	Keyword="RegisteredLocalizerUnits"							Name="Registered Localizer Units"
+(0022,1467) VERS="3"	VR="FL"   VM="2"	Keyword="RegisteredLocalizerTopLeftHandCorner"				Name="Registered Localizer Top Left Hand Corner"
+(0022,1468) VERS="3"	VR="FL"   VM="2"	Keyword="RegisteredLocalizerBottomRightHandCorner"			Name="Registered Localizer Bottom Right Hand Corner"
+(0022,1470) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicThicknessMapQualityRatingSequence"		Name="Ophthalmic Thickness Map Quality Rating Sequence"
+(0022,1472) VERS="3"	VR="SQ"   VM="1"	Keyword="RelevantOPTAttributesSequence"						Name="Relevant OPT Attributes Sequence"
+(0022,1512) VERS="3"	VR="SQ"   VM="1"	Keyword="TransformationMethodCodeSequence"							Name="Transformation Method Code Sequence"
+(0022,1513) VERS="3"	VR="SQ"   VM="1"	Keyword="TransformationAlgorithmSequence"							Name="Transformation Algorithm Sequence"
+(0022,1515) VERS="3"	VR="CS"   VM="1"	Keyword="OphthalmicAxialLengthMethod"								Name="Ophthalmic Axial Length Method"
+(0022,1517) VERS="3"	VR="FL"   VM="1"	Keyword="OphthalmicFOV"												Name="Ophthalmic FOV"
+(0022,1518) VERS="3"	VR="SQ"   VM="1"	Keyword="TwoDimensionalToThreeDimensionalMapSequence"				Name="Two Dimensional to Three Dimensional Map Sequence"
+(0022,1525) VERS="3"	VR="SQ"   VM="1"	Keyword="WideFieldOphthalmicPhotographyQualityRatingSequence"		Name="Wide Field Ophthalmic Photography Quality Rating Sequence"
+(0022,1526) VERS="3"	VR="SQ"   VM="1"	Keyword="WideFieldOphthalmicPhotographyQualityThresholdSequence"	Name="Wide Field Ophthalmic Photography Quality Threshold Sequence"
+(0022,1527) VERS="3"	VR="FL"   VM="1"	Keyword="WideFieldOphthalmicPhotographyThresholdQualityRating"		Name="Wide Field Ophthalmic Photography  Threshold Quality Rating"
+(0022,1528) VERS="3"	VR="FL"   VM="1"	Keyword="XCoordinatesCenterPixelViewAngle"							Name="X Coordinates Center Pixel View Angle"
+(0022,1529) VERS="3"	VR="FL"   VM="1"	Keyword="YCoordinatesCenterPixelViewAngle"							Name="Y Coordinates Center Pixel View Angle"
+(0022,1530) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfMapPoints"											Name="Number of Map Points"
+(0022,1531) VERS="3"	VR="OF"   VM="1"	Keyword="TwoDimensionalToThreeDimensionalMapData"					Name="Two Dimensional to Three Dimensional Map Data"
+(0024,0010) VERS="3"	VR="FL"   VM="1"	Keyword="VisualFieldHorizontalExtent"				Name="Visual Field Horizontal Extent"
+(0024,0011) VERS="3"	VR="FL"   VM="1"	Keyword="VisualFieldVerticalExtent"					Name="Visual Field Vertical Extent"
+(0024,0012) VERS="3"	VR="CS"   VM="1"	Keyword="VisualFieldShape"							Name="Visual Field Shape"
+(0024,0016) VERS="3"	VR="SQ"   VM="1"	Keyword="ScreeningTestModeCodeSequence"				Name="Screening Test Mode Code Sequence"
+(0024,0018) VERS="3"	VR="FL"   VM="1"	Keyword="MaximumStimulusLuminance"					Name="Maximum Stimulus Luminance"
+(0024,0020) VERS="3"	VR="FL"   VM="1"	Keyword="BackgroundLuminance"						Name="Background Luminance"
+(0024,0021) VERS="3"	VR="SQ"   VM="1"	Keyword="StimulusColorCodeSequence"					Name="Stimulus Color Code Sequence"
+(0024,0024) VERS="3"	VR="SQ"   VM="1"	Keyword="BackgroundIlluminationColorCodeSequence"	Name="Background Illumination Color Code Sequence"
+(0024,0025) VERS="3"	VR="FL"   VM="1"	Keyword="StimulusArea"								Name="Stimulus Area"
+(0024,0028) VERS="3"	VR="FL"   VM="1"	Keyword="StimulusPresentationTime"					Name="Stimulus Presentation Time"
+(0024,0032) VERS="3"	VR="SQ"   VM="1"	Keyword="FixationSequence"							Name="Fixation Sequence"
+(0024,0033) VERS="3"	VR="SQ"   VM="1"	Keyword="FixationMonitoringCodeSequence"			Name="Fixation Monitoring Code Sequence"
+(0024,0034) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualFieldCatchTrialSequence"				Name="Visual Field Catch Trial Sequence"
+(0024,0035) VERS="3"	VR="US"   VM="1"	Keyword="FixationCheckedQuantity"					Name="Fixation Checked Quantity"
+(0024,0036) VERS="3"	VR="US"   VM="1"	Keyword="PatientNotProperlyFixatedQuantity"			Name="Patient Not Properly Fixated Quantity"
+(0024,0037) VERS="3"	VR="CS"   VM="1"	Keyword="PresentedVisualStimuliDataFlag"			Name="Presented Visual Stimuli Data Flag"
+(0024,0038) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfVisualStimuli"						Name="Number of Visual Stimuli"
+(0024,0039) VERS="3"	VR="CS"   VM="1"	Keyword="ExcessiveFixationLossesDataFlag"			Name="Excessive Fixation Losses Data Flag"
+(0024,0040) VERS="3"	VR="CS"   VM="1"	Keyword="ExcessiveFixationLosses"					Name="Excessive Fixation Losses"
+(0024,0042) VERS="3"	VR="US"   VM="1"	Keyword="StimuliRetestingQuantity"					Name="Stimuli Retesting Quantity"
+(0024,0044) VERS="3"	VR="LT"   VM="1"	Keyword="CommentsOnPatientPerformanceOfVisualField"		Name="Comments on Patient's Performance of Visual Field"
+(0024,0045) VERS="3"	VR="CS"   VM="1"	Keyword="FalseNegativesEstimateFlag"				Name="False Negatives Estimate Flag"
+(0024,0046) VERS="3"	VR="FL"   VM="1"	Keyword="FalseNegativesEstimate"					Name="False Negatives Estimate"
+(0024,0048) VERS="3"	VR="US"   VM="1"	Keyword="NegativeCatchTrialsQuantity"				Name="Negative Catch Trials Quantity"
+(0024,0050) VERS="3"	VR="US"   VM="1"	Keyword="FalseNegativesQuantity"					Name="False Negatives Quantity"
+(0024,0051) VERS="3"	VR="CS"   VM="1"	Keyword="ExcessiveFalseNegativesDataFlag"			Name="Excessive False Negatives Data Flag"
+(0024,0052) VERS="3"	VR="CS"   VM="1"	Keyword="ExcessiveFalseNegatives"					Name="Excessive False Negatives"
+(0024,0053) VERS="3"	VR="CS"   VM="1"	Keyword="FalsePositivesEstimateFlag"				Name="False Positives Estimate Flag"
+(0024,0054) VERS="3"	VR="FL"   VM="1"	Keyword="FalsePositivesEstimate"					Name="False Positives Estimate"
+(0024,0055) VERS="3"	VR="CS"   VM="1"	Keyword="CatchTrialsDataFlag"						Name="Catch Trials Data Flag"
+(0024,0056) VERS="3"	VR="US"   VM="1"	Keyword="PositiveCatchTrialsQuantity"				Name="Positive Catch Trials Quantity"
+(0024,0057) VERS="3"	VR="CS"   VM="1"	Keyword="TestPointNormalsDataFlag"					Name="Test Point Normals Data Flag"
+(0024,0058) VERS="3"	VR="SQ"   VM="1"	Keyword="TestPointNormalsSequence"					Name="Test Point Normals Sequence"
+(0024,0059) VERS="3"	VR="CS"   VM="1"	Keyword="GlobalDeviationProbabilityNormalsFlag"		Name="Global Deviation Probability Normals Flag"
+(0024,0060) VERS="3"	VR="US"   VM="1"	Keyword="FalsePositivesQuantity"					Name="False Positives Quantity"
+(0024,0061) VERS="3"	VR="CS"   VM="1"	Keyword="ExcessiveFalsePositivesDataFlag"			Name="Excessive False Positives Data Flag"
+(0024,0062) VERS="3"	VR="CS"   VM="1"	Keyword="ExcessiveFalsePositives"					Name="Excessive False Positives"
+(0024,0063) VERS="3"	VR="CS"   VM="1"	Keyword="VisualFieldTestNormalsFlag"				Name="Visual Field Test Normals Flag"
+(0024,0064) VERS="3"	VR="SQ"   VM="1"	Keyword="ResultsNormalsSequence"					Name="Results Normals Sequence"
+(0024,0065) VERS="3"	VR="SQ"   VM="1"	Keyword="AgeCorrectedSensitivityDeviationAlgorithmSequence"	Name="Age Corrected Sensitivity Deviation Algorithm Sequence"
+(0024,0066) VERS="3"	VR="FL"   VM="1"	Keyword="GlobalDeviationFromNormal"				Name="Global Deviation From Normal"
+(0024,0067) VERS="3"	VR="SQ"   VM="1"	Keyword="GeneralizedDefectSensitivityDeviationAlgorithmSequence"				Name="Generalized Defect Sensitivity Deviation Algorithm Sequence"
+(0024,0068) VERS="3"	VR="FL"   VM="1"	Keyword="LocalizedDeviationFromNormal"				Name="Localized Deviation From Normal"
+(0024,0069) VERS="3"	VR="LO"   VM="1"	Keyword="PatientReliabilityIndicator"				Name="Patient Reliability Indicator"
+(0024,0070) VERS="3"	VR="FL"   VM="1"	Keyword="VisualFieldMeanSensitivity"				Name="Visual Field Mean Sensitivity"
+(0024,0071) VERS="3"	VR="FL"   VM="1"	Keyword="GlobalDeviationProbability"				Name="Global Deviation Probability"
+(0024,0072) VERS="3"	VR="CS"   VM="1"	Keyword="LocalDeviationProbabilityNormalsFlag"		Name="Local Deviation Probability Normals Flag"
+(0024,0073) VERS="3"	VR="FL"   VM="1"	Keyword="LocalizedDeviationProbability"				Name="Localized Deviation Probability"
+(0024,0074) VERS="3"	VR="CS"   VM="1"	Keyword="ShortTermFluctuationCalculated"			Name="Short Term Fluctuation Calculated"
+(0024,0075) VERS="3"	VR="FL"   VM="1"	Keyword="ShortTermFluctuation"						Name="Short Term Fluctuation"
+(0024,0076) VERS="3"	VR="CS"   VM="1"	Keyword="ShortTermFluctuationProbabilityCalculated"	Name="Short Term Fluctuation Probability Calculated"
+(0024,0077) VERS="3"	VR="FL"   VM="1"	Keyword="ShortTermFluctuationProbability"			Name="Short Term Fluctuation Probability"
+(0024,0078) VERS="3"	VR="CS"   VM="1"	Keyword="CorrectedLocalizedDeviationFromNormalCalculated"	Name="Corrected Localized Deviation From Normal Calculated"
+(0024,0079) VERS="3"	VR="FL"   VM="1"	Keyword="CorrectedLocalizedDeviationFromNormal"				Name="Corrected Localized Deviation From Normal"
+(0024,0080) VERS="3"	VR="CS"   VM="1"	Keyword="CorrectedLocalizedDeviationFromNormalProbabilityCalculated"	Name="Corrected Localized Deviation From Normal Probability Calculated"
+(0024,0081) VERS="3"	VR="FL"   VM="1"	Keyword="CorrectedLocalizedDeviationFromNormalProbability"				Name="Corrected Localized Deviation From Normal Probability"
+(0024,0083) VERS="3"	VR="SQ"   VM="1"	Keyword="GlobalDeviationProbabilitySequence"			Name="Global Deviation Probability Sequence"
+(0024,0085) VERS="3"	VR="SQ"   VM="1"	Keyword="LocalizedDeviationProbabilitySequence"			Name="Localized Deviation Probability Sequence"
+(0024,0086) VERS="3"	VR="CS"   VM="1"	Keyword="FovealSensitivityMeasured"						Name="Foveal Sensitivity Measured"
+(0024,0087) VERS="3"	VR="FL"   VM="1"	Keyword="FovealSensitivity"								Name="Foveal Sensitivity"
+(0024,0088) VERS="3"	VR="FL"   VM="1"	Keyword="VisualFieldTestDuration"						Name="Visual Field Test Duration"
+(0024,0089) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualFieldTestPointSequence"					Name="Visual Field Test Point Sequence"
+(0024,0090) VERS="3"	VR="FL"   VM="1"	Keyword="VisualFieldTestPointXCoordinate"				Name="Visual Field Test Point X-Coordinate"
+(0024,0091) VERS="3"	VR="FL"   VM="1"	Keyword="VisualFieldTestPointYCoordinate"				Name="Visual Field Test Point Y-Coordinate"
+(0024,0092) VERS="3"	VR="FL"   VM="1"	Keyword="AgeCorrectedSensitivityDeviationValue"			Name="Age Corrected Sensitivity Deviation Value"
+(0024,0093) VERS="3"	VR="CS"   VM="1"	Keyword="StimulusResults"								Name="Stimulus Results"
+(0024,0094) VERS="3"	VR="FL"   VM="1"	Keyword="SensitivityValue"								Name="Sensitivity Value"
+(0024,0095) VERS="3"	VR="CS"   VM="1"	Keyword="RetestStimulusSeen"							Name="Retest Stimulus Seen"
+(0024,0096) VERS="3"	VR="FL"   VM="1"	Keyword="RetestSensitivityValue"						Name="Retest Sensitivity Value"
+(0024,0097) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualFieldTestPointNormalsSequence"			Name="Visual Field Test Point Normals Sequence"
+(0024,0098) VERS="3"	VR="FL"   VM="1"	Keyword="QuantifiedDefect"								Name="Quantified Defect"
+(0024,0100) VERS="3"	VR="FL"   VM="1"	Keyword="AgeCorrectedSensitivityDeviationProbabilityValue"		Name="Age Corrected Sensitivity Deviation Probability Value"
+(0024,0102) VERS="3"	VR="CS"   VM="1"	Keyword="GeneralizedDefectCorrectedSensitivityDeviationFlag"	Name="Generalized Defect Corrected Sensitivity Deviation Flag"
+(0024,0103) VERS="3"	VR="FL"   VM="1"	Keyword="GeneralizedDefectCorrectedSensitivityDeviationValue"	Name="Generalized Defect Corrected Sensitivity Deviation Value"
+(0024,0104) VERS="3"	VR="FL"   VM="1"	Keyword="GeneralizedDefectCorrectedSensitivityDeviationProbabilityValue"	Name="Generalized Defect Corrected Sensitivity Deviation Probability Value"
+(0024,0105) VERS="3"	VR="FL "   VM="1"	Keyword="MinimumSensitivityValue"						Name="Minimum Sensitivity Value"
+(0024,0106) VERS="3"	VR="CS"   VM="1"	Keyword="BlindSpotLocalized"							Name="Blind Spot Localized"
+(0024,0107) VERS="3"	VR="FL"   VM="1"	Keyword="BlindSpotXCoordinate"							Name="Blind Spot X-Coordinate"
+(0024,0108) VERS="3"	VR="FL"   VM="1"	Keyword="BlindSpotYCoordinate"							Name="Blind Spot Y-Coordinate"
+(0024,0110) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualAcuityMeasurementSequence"				Name="Visual Acuity Measurement Sequence"
+(0024,0112) VERS="3"	VR="SQ"   VM="1"	Keyword="RefractiveParametersUsedOnPatientSequence"		Name="Refractive Parameters Used on Patient Sequence"
+(0024,0113) VERS="3"	VR="CS"   VM="1"	Keyword="MeasurementLaterality"							Name="Measurement Laterality"
+(0024,0114) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicPatientClinicalInformationLeftEyeSequence"		Name="Ophthalmic Patient Clinical Information Left Eye Sequence"
+(0024,0115) VERS="3"	VR="SQ"   VM="1"	Keyword="OphthalmicPatientClinicalInformationRightEyeSequence"		Name="Ophthalmic Patient Clinical Information Right Eye Sequence"
+(0024,0117) VERS="3"	VR="CS"   VM="1"	Keyword="FovealPointNormativeDataFlag"					Name="Foveal Point Normative Data Flag"
+(0024,0118) VERS="3"	VR="FL"   VM="1"	Keyword="FovealPointProbabilityValue"					Name="Foveal Point Probability Value"
+(0024,0120) VERS="3"	VR="CS"   VM="1"	Keyword="ScreeningBaselineMeasured"						Name="Screening Baseline Measured"
+(0024,0122) VERS="3"	VR="SQ"   VM="1"	Keyword="ScreeningBaselineMeasuredSequence"				Name="Screening Baseline Measured Sequence"
+(0024,0124) VERS="3"	VR="CS"   VM="1"	Keyword="ScreeningBaselineType"							Name="Screening Baseline Type"
+(0024,0126) VERS="3"	VR="FL"   VM="1"	Keyword="ScreeningBaselineValue"						Name="Screening Baseline Value"
+(0024,0202) VERS="3"	VR="LO"   VM="1"	Keyword="AlgorithmSource"								Name="Algorithm Source"
+(0024,0306) VERS="3"	VR="LO"   VM="1"	Keyword="DataSetName"									Name="Data Set Name"
+(0024,0307) VERS="3"	VR="LO"   VM="1"	Keyword="DataSetVersion"								Name="Data Set Version"
+(0024,0308) VERS="3"	VR="LO"   VM="1"	Keyword="DataSetSource"									Name="Data Set Source"
+(0024,0309) VERS="3"	VR="LO"   VM="1"	Keyword="DataSetDescription"							Name="Data Set Description"
+(0024,0317) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualFieldTestReliabilityGlobalIndexSequence"	Name="Visual Field Test Reliability Global Index Sequence"
+(0024,0320) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualFieldGlobalResultsIndexSequence"			Name="Visual Field Global Results Index Sequence"
+(0024,0325) VERS="3"	VR="SQ"   VM="1"	Keyword="DataObservationSequence"						Name="Data Observation Sequence"
+(0024,0338) VERS="3"	VR="CS"   VM="1"	Keyword="IndexNormalsFlag"								Name="Index Normals Flag"
+(0024,0341) VERS="3"	VR="FL"   VM="1"	Keyword="IndexProbability"								Name="Index Probability"
+(0024,0344) VERS="3"	VR="SQ"   VM="1"	Keyword="IndexProbabilitySequence"						Name="Index Probability Sequence"
+(0028,0002) VERS="3"	VR="US"   VM="1"	Keyword="SamplesPerPixel"			Name="Samples per Pixel"
+(0028,0003) VERS="3"	VR="US"   VM="1"	Keyword="SamplesPerPixelUsed"				Name="Samples per Pixel Used"
+(0028,0004) VERS="3"	VR="CS"   VM="1"	Keyword="PhotometricInterpretation"		Name="Photometric Interpretation"
+(0028,0005) VERS="RET"	VR="US"   VM="1"	Keyword="ImageDimensions"			Name="Image Dimensions"
+(0028,0006) VERS="3"	VR="US"   VM="1"	Keyword="PlanarConfiguration"			Name="Planar Configuration"
+(0028,0008) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfFrames"			Name="Number of Frames"
+(0028,0009) VERS="3"	VR="AT"   VM="1-n"	Keyword="FrameIncrementPointer"			Name="Frame Increment Pointer"
+(0028,000A) VERS="3"	VR="AT"   VM="1-n"	Keyword="FrameDimensionPointer"			Name="Frame Dimension Pointer"
+(0028,0010) VERS="3"	VR="US"   VM="1"	Keyword="Rows"					Name="Rows"
+(0028,0011) VERS="3"	VR="US"   VM="1"	Keyword="Columns"				Name="Columns"
+(0028,0012) VERS="RET"	VR="US"   VM="1"	Keyword="Planes"				Name="Planes"
+(0028,0014) VERS="3"	VR="US"   VM="1"	Keyword="UltrasoundColorDataPresent"		Name="Ultrasound Color Data Present"
+(0028,0030) VERS="3"	VR="DS"   VM="2"	Keyword="PixelSpacing"				Name="Pixel Spacing"
+(0028,0031) VERS="3"	VR="DS"   VM="2"	Keyword="ZoomFactor"				Name="Zoom Factor"
+(0028,0032) VERS="3"	VR="DS"   VM="2"	Keyword="ZoomCenter"				Name="Zoom Center"
+(0028,0034) VERS="3"	VR="IS"   VM="2"	Keyword="PixelAspectRatio"			Name="Pixel Aspect Ratio"
+(0028,0040) VERS="RET"	VR="CS"   VM="1"	Keyword="ImageFormat"				Name="Image Format"
+(0028,0050) VERS="RET"	VR="LO"   VM="1-n"	Keyword="ManipulatedImage"			Name="Manipulated Image"
+(0028,0051) VERS="3"	VR="CS"   VM="1-n"	Keyword="CorrectedImage"			Name="Corrected Image"
+(0028,005F) VERS="RET"	VR="LO"   VM="1"	Keyword="CompressionRecognitionCode"		Name="Compression Recognition Code"
+(0028,0060) VERS="RET"	VR="CS"   VM="1"	Keyword="CompressionCode"			Name="Compression Code"
+(0028,0061) VERS="RET"	VR="SH"   VM="1"	Keyword="CompressionOriginator"			Name="Compression Originator"
+(0028,0062) VERS="RET"	VR="LO"   VM="1"	Keyword="CompressionLabel"			Name="Compression Label"
+(0028,0063) VERS="RET"	VR="SH"   VM="1"	Keyword="CompressionDescription"		Name="Compression Description"
+(0028,0065) VERS="RET"	VR="CS"   VM="1-n"	Keyword="CompressionSequence"			Name="Compression Sequence"
+(0028,0066) VERS="RET"	VR="AT"   VM="1-n"	Keyword="CompressionStepPointers"		Name="Compression Step Pointers"
+(0028,0068) VERS="RET"	VR="US"   VM="1"	Keyword="RepeatInterval"			Name="Repeat Interval"
+(0028,0069) VERS="RET"	VR="US"   VM="1"	Keyword="BitsGrouped"				Name="Bits Grouped"
+(0028,0070) VERS="RET"	VR="US"   VM="1-n"	Keyword="PerimeterTable"			Name="Perimeter Table"
+(0028,0071) VERS="RET"	VR="US or SS"   VM="1"	Keyword="PerimeterValue"			Name="Perimeter Value"
+(0028,0080) VERS="RET"	VR="US"   VM="1"	Keyword="PredictorRows"				Name="Predictor Rows"
+(0028,0081) VERS="RET"	VR="US"   VM="1"	Keyword="PredictorColumns"			Name="Predictor Columns"
+(0028,0082) VERS="RET"	VR="US"   VM="1-n"	Keyword="PredictorConstants"			Name="Predictor Constants"
+(0028,0090) VERS="RET"	VR="CS"   VM="1"	Keyword="BlockedPixels"				Name="Blocked Pixels"
+(0028,0091) VERS="RET"	VR="US"   VM="1"	Keyword="BlockRows"				Name="Block Rows"
+(0028,0092) VERS="RET"	VR="US"   VM="1"	Keyword="BlockColumns"				Name="Block Columns"
+(0028,0093) VERS="RET"	VR="US"   VM="1"	Keyword="RowOverlap"				Name="Row Overlap"
+(0028,0094) VERS="RET"	VR="US"   VM="1"	Keyword="ColumnOverlap"				Name="Column Overlap"
+(0028,0100) VERS="3"	VR="US"   VM="1"	Keyword="BitsAllocated"				Name="Bits Allocated"
+(0028,0101) VERS="3"	VR="US"   VM="1"	Keyword="BitsStored"				Name="Bits Stored"
+(0028,0102) VERS="3"	VR="US"   VM="1"	Keyword="HighBit"				Name="High Bit"
+(0028,0103) VERS="3"	VR="US"   VM="1"	Keyword="PixelRepresentation"			Name="Pixel Representation"
+(0028,0104) VERS="RET"	VR="US or SS"   VM="1"	Keyword="SmallestValidPixelValue"		Name="Smallest Valid Pixel Value"
+(0028,0105) VERS="RET"	VR="US or SS"   VM="1"	Keyword="LargestValidPixelValue"		Name="Largest Valid Pixel Value"
+(0028,0106) VERS="3"	VR="US or SS"   VM="1"	Keyword="SmallestImagePixelValue"		Name="Smallest Image Pixel Value"
+(0028,0107) VERS="3"	VR="US or SS"   VM="1"	Keyword="LargestImagePixelValue"		Name="Largest Image Pixel Value"
+(0028,0108) VERS="3"	VR="US or SS"   VM="1"	Keyword="SmallestPixelValueInSeries"		Name="Smallest Pixel Value in Series"
+(0028,0109) VERS="3"	VR="US or SS"   VM="1"	Keyword="LargestPixelValueInSeries"		Name="Largest Pixel Value in Series"
+(0028,0110) VERS="RET"	VR="US or SS"   VM="1"	Keyword="SmallestImagePixelValueInPlane"		Name="Smallest Image Pixel Value in Plane"
+(0028,0111) VERS="RET"	VR="US or SS"   VM="1"	Keyword="LargestImagePixelValueInPlane"		Name="Largest Image Pixel Value in Plane"
+(0028,0120) VERS="3"	VR="US or SS"   VM="1"	Keyword="PixelPaddingValue"			Name="Pixel Padding Value"
+(0028,0121) VERS="3"	VR="US or SS"   VM="1"	Keyword="PixelPaddingRangeLimit"			Name="Pixel Padding Range Limit"
+(0028,0122) VERS="3"	VR="FL"   VM="1"	Keyword="FloatPixelPaddingValue"				Name="Float Pixel Padding Value"
+(0028,0123) VERS="3"	VR="FD"   VM="1"	Keyword="DoubleFloatPixelPaddingValue"			Name="Double Float Pixel Padding Value"
+(0028,0124) VERS="3"	VR="FL"   VM="1"	Keyword="FloatPixelPaddingRangeLimit"			Name="Float Pixel Padding Range Limit"
+(0028,0125) VERS="3"	VR="FD"   VM="1"	Keyword="DoubleFloatPixelPaddingRangeLimit"		Name="Double Float Pixel Padding Range Limit"
+(0028,0200) VERS="RET"	VR="US"   VM="1"	Keyword="ImageLocation"				Name="Image Location"
+(0028,0300) VERS="3"	VR="CS"   VM="1"	Keyword="QualityControlImage"			Name="Quality Control Image"
+(0028,0301) VERS="3"	VR="CS"   VM="1"	Keyword="BurnedInAnnotation"			Name="Burned In Annotation"
+(0028,0302) VERS="3"	VR="CS"   VM="1"	Keyword="RecognizableVisualFeatures"			Name="Recognizable Visual Features"
+(0028,0303) VERS="3"	VR="CS"   VM="1"	Keyword="LongitudinalTemporalInformationModified"			Name="Longitudinal Temporal Information Modified"
+(0028,0304) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedColorPaletteInstanceUID"	Name="Referenced Color Palette Instance UID"
+(0028,0400) VERS="RET"	VR="LO"   VM="1"	Keyword="TransformLabel"			Name="Transform Label"
+(0028,0401) VERS="RET"	VR="LO"   VM="1"	Keyword="TransformVersionNumber"		Name="Transform Version Number"
+(0028,0402) VERS="RET"	VR="US"   VM="1"	Keyword="NumberOfTransformSteps"	Name="Number of Transform Steps"
+(0028,0403) VERS="RET"	VR="LO"   VM="1-n"	Keyword="SequenceOfCompressedData"		Name="Sequence of Compressed Data"
+(0028,0404) VERS="RET"	VR="AT"   VM="1-n"	Keyword="DetailsOfCoefficients"	Name="Details of Coefficients"
+(0028,04x0) VERS="RET"	VR="US"   VM="1"	Keyword="RowsForNthOrderCoefficients"		Name="Rows For Nth Order Coefficients"
+(0028,04x1) VERS="RET"	VR="US"   VM="1"	Keyword="ColumnsForNthOrderCoefficients"	Name="Columns For Nth Order Coefficients"
+(0028,04x2) VERS="RET"	VR="LO"   VM="1-n"	Keyword="CoefficientCoding"			Name="Coefficient Coding"
+(0028,04x3) VERS="RET"	VR="AT"   VM="1-n"	Keyword="CoefficientCodingPointers"		Name="Coefficient Coding Pointers"
+(0028,0700) VERS="RET"	VR="LO"   VM="1"	Keyword="DCTLabel"				Name="DCT Label"
+(0028,0701) VERS="RET"	VR="CS"   VM="1-n"	Keyword="DataBlockDescription"			Name="Data Block Description"
+(0028,0702) VERS="RET"	VR="AT"   VM="1-n"	Keyword="DataBlock"				Name="Data Block"
+(0028,0710) VERS="RET"	VR="US"   VM="1"	Keyword="NormalizationFactorFormat"		Name="Normalization Factor Format"
+(0028,0720) VERS="RET"	VR="US"   VM="1"	Keyword="ZonalMapNumberFormat"			Name="Zonal Map Number Format"
+(0028,0721) VERS="RET"	VR="AT"   VM="1-n"	Keyword="ZonalMapLocation"			Name="Zonal Map Location"
+(0028,0722) VERS="RET"	VR="US"   VM="1"	Keyword="ZonalMapFormat"			Name="Zonal Map Format"
+(0028,0730) VERS="RET"	VR="US"   VM="1"	Keyword="AdaptiveMapFormat"			Name="Adaptive Map Format"
+(0028,0740) VERS="RET"	VR="US"   VM="1"	Keyword="CodeNumberFormat"			Name="Code Number Format"
+(0028,08x0) VERS="RET"	VR="CS"   VM="1-n"	Keyword="CodeLabel"				Name="Code Label"
+(0028,08x2) VERS="RET"	VR="US"   VM="1"	Keyword="NumberOfTables"			Name="Number of Tables"
+(0028,08x3) VERS="RET"	VR="AT"   VM="1-n"	Keyword="CodeTableLocation"			Name="Code Table Location"
+(0028,08x4) VERS="RET"	VR="US"   VM="1"	Keyword="BitsForCodeWord"			Name="Bits For Code Word"
+(0028,08x8) VERS="RET"	VR="AT"   VM="1-n"	Keyword="ImageDataLocation"			Name="Image Data Location"
+(0028,0A02) VERS="3"	VR="CS"   VM="1"	Keyword="PixelSpacingCalibrationType"		Name="Pixel Spacing Calibration Type"
+(0028,0A04) VERS="3"	VR="LO"   VM="1"	Keyword="PixelSpacingCalibrationDescription"			Name="Pixel Spacing Calibration Description"
+(0028,1040) VERS="3"	VR="CS"   VM="1"	Keyword="PixelIntensityRelationship"		Name="Pixel Intensity Relationship"
+(0028,1041) VERS="3"	VR="SS"   VM="1"	Keyword="PixelIntensityRelationshipSign"	Name="Pixel Intensity Relationship Sign"
+(0028,1050) VERS="3"	VR="DS"   VM="1-n"	Keyword="WindowCenter"				Name="Window Center"
+(0028,1051) VERS="3"	VR="DS"   VM="1-n"	Keyword="WindowWidth"				Name="Window Width"
+(0028,1052) VERS="3"	VR="DS"   VM="1"	Keyword="RescaleIntercept"			Name="Rescale Intercept"
+(0028,1053) VERS="3"	VR="DS"   VM="1"	Keyword="RescaleSlope"				Name="Rescale Slope"
+(0028,1054) VERS="3"	VR="LO"   VM="1"	Keyword="RescaleType"				Name="Rescale Type"
+(0028,1055) VERS="3"	VR="LO"   VM="1-n"	Keyword="WindowCenterWidthExplanation"		Name="Window Center & Width Explanation"
+(0028,1056) VERS="3"	VR="CS"   VM="1"	Keyword="VOILUTFunction"				Name="VOI LUT Function"
+(0028,1080) VERS="RET"	VR="CS"   VM="1"	Keyword="GrayScale"				Name="Gray Scale"
+(0028,1090) VERS="3"	VR="CS"   VM="1"	Keyword="RecommendedViewingMode"		Name="Recommended Viewing Mode"
+(0028,1100) VERS="RET"	VR="US\US or SS\US"   VM="3"	Keyword="GrayLookupTableDescriptor"	Name="Gray Lookup Table Descriptor"
+(0028,1101) VERS="3"	VR="US\US or SS\US"   VM="3"	Keyword="RedPaletteColorLookupTableDescriptor"		Name="Red Palette Color Lookup Table Descriptor"
+(0028,1102) VERS="3"	VR="US\US or SS\US"   VM="3"	Keyword="GreenPaletteColorLookupTableDescriptor"	Name="Green Palette Color Lookup Table Descriptor"
+(0028,1103) VERS="3"	VR="US\US or SS\US"   VM="3"	Keyword="BluePaletteColorLookupTableDescriptor"		Name="Blue Palette Color Lookup Table Descriptor"
+(0028,1104) VERS="3"	VR="US"   VM="3"				Keyword="AlphaPaletteColorLookupTableDescriptor"	Name="Alpha Palette Color Lookup Table Descriptor"
+(0028,1111) VERS="3"	VR="US\US or SS\US"   VM="4"	Keyword="LargeRedPaletteColorLookupTableDescriptor"	Name="Large Red Palette Color Lookup Table Descriptor"
+(0028,1112) VERS="3"	VR="US\US or SS\US"   VM="4"	Keyword="LargeGreenPaletteColorLookupTableDescriptor"	Name="Large Green Palette Color Lookup Table Descriptor"
+(0028,1113) VERS="3"	VR="US\US or SS\US"   VM="4"	Keyword="LargeBluePaletteColorLookupTableDescriptor"	Name="Large Blue Palette Color Lookup Table Descriptor"
+(0028,1199) VERS="3"	VR="UI"   VM="1"	Keyword="PaletteColorLookupTableUID"					Name="Palette Color Lookup Table UID"
+(0028,1200) VERS="RET"	VR="OW"   VM="1"	Keyword="GrayLookupTableData"							Name="Gray Lookup Table Data"
+(0028,1201) VERS="3"	VR="OW"   VM="1"	Keyword="RedPaletteColorLookupTableData"				Name="Red Palette Color Lookup Table Data"
+(0028,1202) VERS="3"	VR="OW"   VM="1"	Keyword="GreenPaletteColorLookupTableData"				Name="Green Palette Color Lookup Table Data"
+(0028,1203) VERS="3"	VR="OW"   VM="1"	Keyword="BluePaletteColorLookupTableData"				Name="Blue Palette Color Lookup Table Data"
+(0028,1204) VERS="3"	VR="OW"   VM="1"	Keyword="AlphaPaletteColorLookupTableData"				Name="Alpha Palette Color Lookup Table Data"
+(0028,1211) VERS="3"	VR="OW"   VM="1"	Keyword="LargeRedPaletteColorLookupTableData"			Name="Large Red Palette Color Lookup Table Data"
+(0028,1212) VERS="3"	VR="OW"   VM="1"	Keyword="LargeGreenPaletteColorLookupTableData"			Name="Large Green Palette Color Lookup Table Data"
+(0028,1213) VERS="3"	VR="OW"   VM="1"	Keyword="LargeBluePaletteColorLookupTableData"			Name="Large Blue Palette Color Lookup Table Data"
+(0028,1214) VERS="3"	VR="UI"   VM="1"	Keyword="LargePaletteColorLookupTableUID"				Name="Large Palette Color Lookup Table UID"
+(0028,1221) VERS="3"	VR="OW"   VM="1"	Keyword="SegmentedRedPaletteColorLookupTableData"		Name="Segmented Red Palette Color Lookup Table Data"
+(0028,1222) VERS="3"	VR="OW"   VM="1"	Keyword="SegmentedGreenPaletteColorLookupTableData"		Name="Segmented Green Palette Color Lookup Table Data"
+(0028,1223) VERS="3"	VR="OW"   VM="1"	Keyword="SegmentedBluePaletteColorLookupTableData"		Name="Segmented Blue Palette Color Lookup Table Data"
+(0028,1224) VERS="3"	VR="OW"   VM="1"	Keyword="SegmentedAlphaPaletteColorLookupTableData"		Name="Segmented Alpha Palette Color Lookup Table Data"
+(0028,1300) VERS="3"	VR="CS"   VM="1"	Keyword="BreastImplantPresent"			Name="Breast Implant Present"
+(0028,1350) VERS="3"	VR="CS"   VM="1"	Keyword="PartialView"				Name="Partial View"
+(0028,1351) VERS="3"	VR="ST"   VM="1"	Keyword="PartialViewDescription"		Name="Partial View Description"
+(0028,1352) VERS="3"	VR="SQ"   VM="1"	Keyword="PartialViewCodeSequence"		Name="Partial View Code Sequence"
+(0028,135A) VERS="3"	VR="CS"   VM="1"	Keyword="SpatialLocationsPreserved"		Name="Spatial Locations Preserved"
+(0028,1401) VERS="3"	VR="SQ"   VM="1"	Keyword="DataFrameAssignmentSequence"				Name="Data Frame Assignment Sequence"
+(0028,1402) VERS="3"	VR="CS"   VM="1"	Keyword="DataPathAssignment"						Name="Data Path Assignment"
+(0028,1403) VERS="3"	VR="US"   VM="1"	Keyword="BitsMappedToColorLookupTable"				Name="Bits Mapped to Color Lookup Table"
+(0028,1404) VERS="3"	VR="SQ"   VM="1"	Keyword="BlendingLUT1Sequence"						Name="Blending LUT 1 Sequence"
+(0028,1405) VERS="3"	VR="CS"   VM="1"	Keyword="BlendingLUT1TransferFunction"				Name="Blending LUT 1 Transfer Function"
+(0028,1406) VERS="3"	VR="FD"   VM="1"	Keyword="BlendingWeightConstant"					Name="Blending Weight Constant"
+(0028,1407) VERS="3"	VR="US"   VM="3"	Keyword="BlendingLookupTableDescriptor"				Name="Blending Lookup Table Descriptor"
+(0028,1408) VERS="3"	VR="OW"   VM="1"	Keyword="BlendingLookupTableData"					Name="Blending Lookup Table Data"
+(0028,140B) VERS="3"	VR="SQ"   VM="1"	Keyword="EnhancedPaletteColorLookupTableSequence"	Name="Enhanced Palette Color Lookup Table Sequence"
+(0028,140C) VERS="3"	VR="SQ"   VM="1"	Keyword="BlendingLUT2Sequence"						Name="Blending LUT 2 Sequence"
+(0028,140D) VERS="3"	VR="CS"   VM="1"	Keyword="BlendingLUT2TransferFunction"				Name="Blending LUT 2 Transfer Function"
+(0028,140E) VERS="3"	VR="CS"   VM="1"	Keyword="DataPathID"								Name="Data Path ID"
+(0028,140F) VERS="3"	VR="CS"   VM="1"	Keyword="RGBLUTTransferFunction"					Name="RGB LUT Transfer Function"
+(0028,1410) VERS="3"	VR="CS"   VM="1"	Keyword="AlphaLUTTransferFunction"					Name="Alpha LUT Transfer Function"
+(0028,2000) VERS="3"	VR="OB"   VM="1"	Keyword="ICCProfile"						Name="ICC Profile"
+(0028,2002) VERS="3"	VR="CS"   VM="1"	Keyword="ColorSpace"						Name="Color Space"
+(0028,2110) VERS="3"	VR="CS"   VM="1"	Keyword="LossyImageCompression"			Name="Lossy Image Compression"
+(0028,2112) VERS="3"	VR="DS"   VM="1-n"	Keyword="LossyImageCompressionRatio"		Name="Lossy Image Compression Ratio"
+(0028,2114) VERS="3"	VR="CS"   VM="1-n"	Keyword="LossyImageCompressionMethod"		Name="Lossy Image Compression Method"
+(0028,3000) VERS="3"	VR="SQ"   VM="1"	Keyword="ModalityLUTSequence"			Name="Modality LUT Sequence"
+(0028,3002) VERS="3"	VR="US"   VM="3"	Keyword="LUTDescriptor"				Name="LUT Descriptor"
+(0028,3003) VERS="3"	VR="LO"   VM="1"	Keyword="LUTExplanation"			Name="LUT Explanation"
+(0028,3004) VERS="3"	VR="LO"   VM="1"	Keyword="ModalityLUTType"			Name="Modality LUT Type"
+(0028,3006) VERS="3"	VR="US or OW"   VM="1-n"	Keyword="LUTData"				Name="LUT Data"
+(0028,3010) VERS="3"	VR="SQ"   VM="1"	Keyword="VOILUTSequence"			Name="VOI LUT Sequence"
+(0028,3110) VERS="3"	VR="SQ"   VM="1"	Keyword="SoftcopyVOILUTSequence"			Name="Softcopy VOI LUT Sequence"
+(0028,4000) VERS="RET"	VR="LT"   VM="1"	Keyword="ImagePresentationComments"		Name="Image Presentation Comments"
+(0028,5000) VERS="RET"	VR="SQ"   VM="1"	Keyword="BiPlaneAcquisitionSequence"		Name="Bi-Plane Acquisition Sequence"
+(0028,6010) VERS="3"	VR="US"   VM="1"	Keyword="RepresentativeFrameNumber"		Name="Representative Frame Number"
+(0028,6020) VERS="3"	VR="US"   VM="1-n"	Keyword="FrameNumbersOfInterest"		Name="Frame Numbers of Interest (FOI)"
+(0028,6022) VERS="3"	VR="LO"   VM="1-n"	Keyword="FrameOfInterestDescription"		Name="Frame of Interest Description"
+(0028,6023) VERS="3"	VR="CS"   VM="1-n"	Keyword="FrameOfInterestType"			Name="Frame of Interest Type"
+(0028,6030) VERS="RET"	VR="US"   VM="1-n"	Keyword="MaskPointers"				Name="Mask Pointer(s)"
+(0028,6040) VERS="3"	VR="US"   VM="1-n"	Keyword="RWavePointer"				Name="R Wave Pointer"
+(0028,6100) VERS="3"	VR="SQ"   VM="1"	Keyword="MaskSubtractionSequence"		Name="Mask Subtraction Sequence"
+(0028,6101) VERS="3"	VR="CS"   VM="1"	Keyword="MaskOperation"				Name="Mask Operation"
+(0028,6102) VERS="3"	VR="US"   VM="2-2n"	Keyword="ApplicableFrameRange"			Name="Applicable Frame Range"
+(0028,6110) VERS="3"	VR="US"   VM="1-n"	Keyword="MaskFrameNumbers"			Name="Mask Frame Numbers"
+(0028,6112) VERS="3"	VR="US"   VM="1"	Keyword="ContrastFrameAveraging"		Name="Contrast Frame Averaging"
+(0028,6114) VERS="3"	VR="FL"   VM="2"	Keyword="MaskSubPixelShift"			Name="Mask Sub-pixel Shift"
+(0028,6120) VERS="3"	VR="SS"   VM="1"	Keyword="TIDOffset"				Name="TID Offset"
+(0028,6190) VERS="3"	VR="ST"   VM="1"	Keyword="MaskOperationExplanation"		Name="Mask Operation Explanation"
+(0028,7000) VERS="3"	VR="SQ"   VM="1"	Keyword="EquipmentAdministratorSequence"				Name="Equipment Administrator Sequence"
+(0028,7001) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfDisplaySubsystems"				Name="Number of Display Subsystems"
+(0028,7002) VERS="3"	VR="US"   VM="1"	Keyword="CurrentConfigurationID"				Name="Current Configuration ID"
+(0028,7003) VERS="3"	VR="US"   VM="1"	Keyword="DisplaySystemID"				Name="Display Subsystem ID"
+(0028,7004) VERS="3"	VR="SH"   VM="1"	Keyword="DisplaySubsystemName"				Name="Display Subsystem Name"
+(0028,7005) VERS="3"	VR="LO"   VM="1"	Keyword="DisplaySubsystemDescription"				Name="Display Subsystem Description"
+(0028,7006) VERS="3"	VR="CS"   VM="1"	Keyword="SystemStatus"				Name="System Status"
+(0028,7007) VERS="3"	VR="LO"   VM="1"	Keyword="SystemStatusComment"				Name="System Status Comment"
+(0028,7008) VERS="3"	VR="SQ"   VM="1"	Keyword="TargetLuminanceCharacteristicsSequence"				Name="Target Luminance Characteristics Sequence"
+(0028,7009) VERS="3"	VR="US"   VM="1"	Keyword="LuminanceCharacteristicsID"				Name="Luminance Characteristics ID"
+(0028,700A) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplaySubsystemConfigurationSequence"				Name="Display Subsystem Configuration Sequence"
+(0028,700B) VERS="3"	VR="US"   VM="1"	Keyword="ConfigurationID"				Name="Configuration ID"
+(0028,700C) VERS="3"	VR="SH"   VM="1"	Keyword="ConfigurationName"				Name="Configuration Name"
+(0028,700D) VERS="3"	VR="LO"   VM="1"	Keyword="ConfigurationDescription"				Name="Configuration Description"
+(0028,700E) VERS="3"	VR="US"   VM="1"	Keyword="ReferencedTargetLuminanceCharacteristicsID"				Name="Referenced Target Luminance Characteristics ID"
+(0028,700F) VERS="3"	VR="SQ"   VM="1"	Keyword="QAResultsSequence"				Name="QA Results Sequence"
+(0028,7010) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplaySubsystemQAResultsSequence"				Name="Display Subsystem QA Results Sequence"
+(0028,7011) VERS="3"	VR="SQ"   VM="1"	Keyword="ConfigurationQAResultsSequence"				Name="Configuration QA Results Sequence"
+(0028,7012) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasurementEquipmentSequence"				Name="Measurement Equipment Sequence"
+(0028,7013) VERS="3"	VR="CS"   VM="1-n"	Keyword="MeasurementFunctions"				Name="Measurement Functions"
+(0028,7014) VERS="3"	VR="CS"   VM="1"	Keyword="MeasurementEquipmentType"				Name="Measurement Equipment Type"
+(0028,7015) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualEvaluationResultSequence"				Name="Visual Evaluation Result Sequence"
+(0028,7016) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplayCalibrationResultSequence"				Name="Display Calibration Result Sequence"
+(0028,7017) VERS="3"	VR="US"   VM="1"	Keyword="DDLValue"				Name="DDL Value"
+(0028,7018) VERS="3"	VR="FL"   VM="2"	Keyword="CIExyWhitePoint"				Name="CIExy White Point"
+(0028,7019) VERS="3"	VR="CS"   VM="1"	Keyword="DisplayFunctionType"				Name="Display Function Type"
+(0028,701A) VERS="3"	VR="FL"   VM="1"	Keyword="GammaValue"				Name="Gamma Value"
+(0028,701B) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfLuminancePoints"				Name="Number of Luminance Points"
+(0028,701C) VERS="3"	VR="SQ"   VM="1"	Keyword="LuminanceResponseSequence"				Name="Luminance Response Sequence"
+(0028,701D) VERS="3"	VR="FL"   VM="1"	Keyword="TargetMinimumLuminance"				Name="Target Minimum Luminance"
+(0028,701E) VERS="3"	VR="FL"   VM="1"	Keyword="TargetMaximumLuminance"				Name="Target Maximum Luminance"
+(0028,701F) VERS="3"	VR="FL"   VM="1"	Keyword="LuminanceValue"				Name="Luminance Value"
+(0028,7020) VERS="3"	VR="LO"   VM="1"	Keyword="LuminanceResponseDescription"				Name="Luminance Response Description"
+(0028,7021) VERS="3"	VR="CS"   VM="1"	Keyword="WhitePointFlag"				Name="White Point Flag"
+(0028,7022) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplayDeviceTypeCodeSequence"				Name="Display Device Type Code Sequence"
+(0028,7023) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplaySubsystemSequence"				Name="Display Subsystem Sequence"
+(0028,7024) VERS="3"	VR="SQ"   VM="1"	Keyword="LuminanceResultSequence"				Name="Luminance Result Sequence"
+(0028,7025) VERS="3"	VR="CS"   VM="1"	Keyword="AmbientLightValueSource"				Name="Ambient Light Value Source"
+(0028,7026) VERS="3"	VR="CS"   VM="1-n"	Keyword="MeasuredCharacteristics"				Name="Measured Characteristics"
+(0028,7027) VERS="3"	VR="SQ"   VM="1"	Keyword="LuminanceUniformityResultSequence"				Name="Luminance Uniformity Result Sequence"
+(0028,7028) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualEvaluationTestSequence"				Name="Visual Evaluation Test Sequence"
+(0028,7029) VERS="3"	VR="CS"   VM="1"	Keyword="TestResult"				Name="Test Result"
+(0028,702A) VERS="3"	VR="LO"   VM="1"	Keyword="TestResultComment"				Name="Test Result Comment"
+(0028,702B) VERS="3"	VR="CS"   VM="1"	Keyword="TestImageValidation"				Name="Test Image Validation"
+(0028,702C) VERS="3"	VR="SQ"   VM="1"	Keyword="TestPatternCodeSequence"				Name="Test Pattern Code Sequence"
+(0028,702D) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasurementPatternCodeSequence"				Name="Measurement Pattern Code Sequence"
+(0028,702E) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualEvaluationMethodCodeSequence"				Name="Visual Evaluation Method Code Sequence"
+(0028,7FE0) VERS="3"	VR="UR"   VM="1"	Keyword="PixelDataProviderURL"		Name="Pixel Data Provider URL"
+(0028,9001) VERS="3"	VR="UL"   VM="1"	Keyword="DataPointRows"				Name="Data Point Rows"
+(0028,9002) VERS="3"	VR="UL"   VM="1"	Keyword="DataPointColumns"			Name="Data Point Columns"
+(0028,9003) VERS="3"	VR="CS"   VM="1"	Keyword="SignalDomainColumns"			Name="Signal Domain Columns"
+(0028,9099) VERS="RET"	VR="US"   VM="1"	Keyword="LargestMonochromePixelValue"		Name="Largest Monochrome Pixel Value"
+(0028,9108) VERS="3"	VR="CS"   VM="1"	Keyword="DataRepresentation"			Name="Data Representation"
+(0028,9110) VERS="3"	VR="SQ"   VM="1"	Keyword="PixelMeasuresSequence"			Name="Pixel Measures Sequence"
+(0028,9132) VERS="3"	VR="SQ"   VM="1"	Keyword="FrameVOILUTSequence"			Name="Frame VOI LUT Sequence"
+(0028,9145) VERS="3"	VR="SQ"   VM="1"	Keyword="PixelValueTransformationSequence"	Name="Pixel Value Transformation Sequence"
+(0028,9235) VERS="3"	VR="CS"   VM="1"	Keyword="SignalDomainRows"			Name="Signal Domain Rows"
+(0028,9411)	VERS="3"	VR="FL"   VM="1"	Keyword="DisplayFilterPercentage"		Name="Display Filter Percentage"
+(0028,9415)	VERS="3"	VR="SQ"   VM="1"	Keyword="FramePixelShiftSequence"		Name="Frame Pixel Shift Sequence"
+(0028,9416)	VERS="3"	VR="US"   VM="1"	Keyword="SubtractionItemID"		Name="Subtraction Item ID"
+(0028,9422)	VERS="3"	VR="SQ"   VM="1"	Keyword="PixelIntensityRelationshipLUTSequence"		Name="Pixel Intensity Relationship LUT Sequence"
+(0028,9443)	VERS="3"	VR="SQ"   VM="1"	Keyword="FramePixelDataPropertiesSequence"		Name="Frame Pixel Data Properties Sequence"
+(0028,9444)	VERS="3"	VR="CS"   VM="1"	Keyword="GeometricalProperties"		Name="Geometrical Properties"
+(0028,9445)	VERS="3"	VR="FL"   VM="1"	Keyword="GeometricMaximumDistortion"		Name="Geometric Maximum Distortion"
+(0028,9446)	VERS="3"	VR="CS"   VM="1-n"	Keyword="ImageProcessingApplied"		Name="Image Processing Applied"
+(0028,9454)	VERS="3"	VR="CS"   VM="1"	Keyword="MaskSelectionMode"		Name="Mask Selection Mode"
+(0028,9474)	VERS="3"	VR="CS"   VM="1"	Keyword="LUTFunction"		Name="LUT Function"
+(0028,9478)	VERS="3"	VR="FL"   VM="1"	Keyword="MaskVisibilityPercentage"		Name="Mask Visibility Percentage"
+(0028,9501)	VERS="3"	VR="SQ"   VM="1"	Keyword="PixelShiftSequence"		Name="Pixel Shift Sequence"
+(0028,9502)	VERS="3"	VR="SQ"   VM="1"	Keyword="RegionPixelShiftSequence"		Name="Region Pixel Shift Sequence"
+(0028,9503)	VERS="3"	VR="SS"   VM="2-2n"	Keyword="VerticesOfTheRegion"		Name="Vertices of the Region"
+(0028,9505)	VERS="3"	VR="SQ"   VM="1"	Keyword="MultiFramePresentationSequence"		Name="Multi-frame Presentation Sequence"
+(0028,9506)	VERS="3"	VR="US"   VM="2-2n"	Keyword="PixelShiftFrameRange"		Name="Pixel Shift Frame Range"
+(0028,9507)	VERS="3"	VR="US"   VM="2-2n"	Keyword="LUTFrameRange"		Name="LUT Frame Range"
+(0028,9520)	VERS="3"	VR="DS"   VM="16"	Keyword="ImageToEquipmentMappingMatrix"				Name="Image to Equipment Mapping Matrix"
+(0028,9537)	VERS="3"	VR="CS"   VM="1"	Keyword="EquipmentCoordinateSystemIdentification"	Name="Equipment Coordinate System Identification"
+(0032,000A) VERS="RET"	VR="CS"   VM="1"	Keyword="StudyStatusID"				Name="Study Status ID"
+(0032,000C) VERS="RET"	VR="CS"   VM="1"	Keyword="StudyPriorityID"			Name="Study Priority ID"
+(0032,0012) VERS="RET"	VR="LO"   VM="1"	Keyword="StudyIDIssuer"				Name="Study ID Issuer"
+(0032,0032) VERS="RET"	VR="DA"   VM="1"	Keyword="StudyVerifiedDate"			Name="Study Verified Date"
+(0032,0033) VERS="RET"	VR="TM"   VM="1"	Keyword="StudyVerifiedTime"			Name="Study Verified Time"
+(0032,0034) VERS="RET"	VR="DA"   VM="1"	Keyword="StudyReadDate"				Name="Study Read Date"
+(0032,0035) VERS="RET"	VR="TM"   VM="1"	Keyword="StudyReadTime"				Name="Study Read Time"
+(0032,1000) VERS="RET"	VR="DA"   VM="1"	Keyword="ScheduledStudyStartDate"		Name="Scheduled Study Start Date"
+(0032,1001) VERS="RET"	VR="TM"   VM="1"	Keyword="ScheduledStudyStartTime"		Name="Scheduled Study Start Time"
+(0032,1010) VERS="RET"	VR="DA"   VM="1"	Keyword="ScheduledStudyStopDate"		Name="Scheduled Study Stop Date"
+(0032,1011) VERS="RET"	VR="TM"   VM="1"	Keyword="ScheduledStudyStopTime"		Name="Scheduled Study Stop Time"
+(0032,1020) VERS="RET"	VR="LO"   VM="1"	Keyword="ScheduledStudyLocation"		Name="Scheduled Study Location"
+(0032,1021) VERS="RET"	VR="AE"   VM="1-n"	Keyword="ScheduledStudyLocationAETitle"		Name="Scheduled Study Location AE Title"
+(0032,1030) VERS="RET"	VR="LO"   VM="1"	Keyword="ReasonForStudy"			Name="Reason for Study"
+(0032,1031) VERS="3"	VR="SQ"   VM="1"	Keyword="RequestingPhysicianIdentificationSequence"	Name="Requesting Physician Identification Sequence"
+(0032,1032) VERS="3"	VR="PN"   VM="1"	Keyword="RequestingPhysician"			Name="Requesting Physician"
+(0032,1033) VERS="3"	VR="LO"   VM="1"	Keyword="RequestingService"			Name="Requesting Service"
+(0032,1034) VERS="3"	VR="SQ"   VM="1"	Keyword="RequestingServiceCodeSequence"	Name="Requesting Service Code Sequence"
+(0032,1040) VERS="RET"	VR="DA"   VM="1"	Keyword="StudyArrivalDate"			Name="Study Arrival Date"
+(0032,1041) VERS="RET"	VR="TM"   VM="1"	Keyword="StudyArrivalTime"			Name="Study Arrival Time"
+(0032,1050) VERS="RET"	VR="DA"   VM="1"	Keyword="StudyCompletionDate"			Name="Study Completion Date"
+(0032,1051) VERS="RET"	VR="TM"   VM="1"	Keyword="StudyCompletionTime"			Name="Study Completion Time"
+(0032,1055) VERS="RET"	VR="CS"   VM="1"	Keyword="StudyComponentStatusID"		Name="Study Component Status ID"
+(0032,1060) VERS="3"	VR="LO"   VM="1"	Keyword="RequestedProcedureDescription"		Name="Requested Procedure Description"
+(0032,1064) VERS="3"	VR="SQ"   VM="1"	Keyword="RequestedProcedureCodeSequence"	Name="Requested Procedure Code Sequence"
+(0032,1070) VERS="3"	VR="LO"   VM="1"	Keyword="RequestedContrastAgent"		Name="Requested Contrast Agent"
+(0032,4000) VERS="RET"	VR="LT"   VM="1"	Keyword="StudyComments"				Name="Study Comments"
+(0038,0004) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedPatientAliasSequence"	Name="Referenced Patient Alias Sequence"
+(0038,0008) VERS="3"	VR="CS"   VM="1"	Keyword="VisitStatusID"				Name="Visit Status ID"
+(0038,0010) VERS="3"	VR="LO"   VM="1"	Keyword="AdmissionID"				Name="Admission ID"
+(0038,0011) VERS="RET"	VR="LO"   VM="1"	Keyword="IssuerOfAdmissionID"			Name="Issuer of Admission ID"
+(0038,0014) VERS="3"	VR="SQ"   VM="1"	Keyword="IssuerOfAdmissionIDSequence"	Name="Issuer of Admission ID Sequence"
+(0038,0016) VERS="3"	VR="LO"   VM="1"	Keyword="RouteOfAdmissions"			Name="Route of Admissions"
+(0038,001A) VERS="RET"	VR="DA"   VM="1"	Keyword="ScheduledAdmissionDate"		Name="Scheduled Admission Date"
+(0038,001B) VERS="RET"	VR="TM"   VM="1"	Keyword="ScheduledAdmissionTime"		Name="Scheduled Admission Time"
+(0038,001C) VERS="RET"	VR="DA"   VM="1"	Keyword="ScheduledDischargeDate"		Name="Scheduled Discharge Date"
+(0038,001D) VERS="RET"	VR="TM"   VM="1"	Keyword="ScheduledDischargeTime"		Name="Scheduled Discharge Time"
+(0038,001E) VERS="RET"	VR="LO"   VM="1"	Keyword="ScheduledPatientInstitutionResidence"	Name="Scheduled Patient Institution Residence"
+(0038,0020) VERS="3"	VR="DA"   VM="1"	Keyword="AdmittingDate"				Name="Admitting Date"
+(0038,0021) VERS="3"	VR="TM"   VM="1"	Keyword="AdmittingTime"				Name="Admitting Time"
+(0038,0030) VERS="RET"	VR="DA"   VM="1"	Keyword="DischargeDate"				Name="Discharge Date"
+(0038,0032) VERS="RET"	VR="TM"   VM="1"	Keyword="DischargeTime"				Name="Discharge Time"
+(0038,0040) VERS="RET"	VR="LO"   VM="1"	Keyword="DischargeDiagnosisDescription"		Name="Discharge Diagnosis Description"
+(0038,0044) VERS="RET"	VR="SQ"   VM="1"	Keyword="DischargeDiagnosisCodeSequence"	Name="Discharge Diagnosis Code Sequence"
+(0038,0050) VERS="3"	VR="LO"   VM="1"	Keyword="SpecialNeeds"				Name="Special Needs"
+(0038,0060) VERS="3"	VR="LO"   VM="1"	Keyword="ServiceEpisodeID"				Name="Service Episode ID"
+(0038,0061) VERS="RET"	VR="LO"   VM="1"	Keyword="IssuerOfServiceEpisodeID"		Name="Issuer of Service Episode ID"
+(0038,0062) VERS="3"	VR="LO"   VM="1"	Keyword="ServiceEpisodeDescription"		Name="Service Episode Description"
+(0038,0064) VERS="3"	VR="SQ"   VM="1"	Keyword="IssuerOfServiceEpisodeIDSequence"		Name="Issuer of Service Episode ID Sequence"
+(0038,0100) VERS="3"	VR="SQ"   VM="1"	Keyword="PertinentDocumentsSequence"				Name="Pertinent Documents Sequence"
+(0038,0101) VERS="3"	VR="SQ"   VM="1"	Keyword="PertinentResourcesSequence"				Name="Pertinent Resources Sequence"
+(0038,0102) VERS="3"	VR="LO"   VM="1"	Keyword="ResourceDescription"				Name="Resource Description"
+(0038,0300) VERS="3"	VR="LO"   VM="1"	Keyword="CurrentPatientLocation"		Name="Current Patient Location"
+(0038,0400) VERS="3"	VR="LO"   VM="1"	Keyword="PatientInstitutionResidence"		Name="Patient's Institution Residence"
+(0038,0500) VERS="3"	VR="LO"   VM="1"	Keyword="PatientState"				Name="Patient State"
+(0038,0502) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientClinicalTrialParticipationSequence"	Name="Patient Clinical Trial Participation Sequence"
+(0038,4000) VERS="3"	VR="LT"   VM="1"	Keyword="VisitComments"				Name="Visit Comments"
+(003A,0004) VERS="3"	VR="CS"   VM="1"	Keyword="WaveformOriginality"			Name="Waveform Originality"
+(003A,0005) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfWaveformChannels"		Name="Number of Waveform Channels"
+(003A,0010) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfWaveformSamples"		Name="Number of Waveform Samples"
+(003A,001A) VERS="3"	VR="DS"   VM="1"	Keyword="SamplingFrequency"			Name="Sampling Frequency"
+(003A,0020) VERS="3"	VR="SH"   VM="1"	Keyword="MultiplexGroupLabel"			Name="Multiplex Group Label"
+(003A,0200) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelDefinitionSequence"		Name="Channel Definition Sequence"
+(003A,0202) VERS="3"	VR="IS"   VM="1"	Keyword="WaveformChannelNumber"			Name="Waveform Channel Number"
+(003A,0203) VERS="3"	VR="SH"   VM="1"	Keyword="ChannelLabel"				Name="Channel Label"
+(003A,0205) VERS="3"	VR="CS"   VM="1-n"	Keyword="ChannelStatus"				Name="Channel Status"
+(003A,0208) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelSourceSequence"			Name="Channel Source Sequence"
+(003A,0209) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelSourceModifiersSequence"	Name="Channel Source Modifiers Sequence"
+(003A,020A) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceWaveformSequence"		Name="Source Waveform Sequence"
+(003A,020C) VERS="3"	VR="LO"   VM="1"	Keyword="ChannelDerivationDescription"		Name="Channel Derivation Description"
+(003A,0210) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelSensitivity"			Name="Channel Sensitivity"
+(003A,0211) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelSensitivityUnitsSequence"	Name="Channel Sensitivity Units Sequence"
+(003A,0212) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelSensitivityCorrectionFactor"	Name="Channel Sensitivity Correction Factor"
+(003A,0213) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelBaseline"			Name="Channel Baseline"
+(003A,0214) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelTimeSkew"			Name="Channel Time Skew"
+(003A,0215) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelSampleSkew"			Name="Channel Sample Skew"
+(003A,0218) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelOffset"				Name="Channel Offset"
+(003A,021A) VERS="3"	VR="US"   VM="1"	Keyword="WaveformBitsStored"			Name="Waveform Bits Stored"
+(003A,0220) VERS="3"	VR="DS"   VM="1"	Keyword="FilterLowFrequency"			Name="Filter Low Frequency"
+(003A,0221) VERS="3"	VR="DS"   VM="1"	Keyword="FilterHighFrequency"			Name="Filter High Frequency"
+(003A,0222) VERS="3"	VR="DS"   VM="1"	Keyword="NotchFilterFrequency"			Name="Notch Filter Frequency"
+(003A,0223) VERS="3"	VR="DS"   VM="1"	Keyword="NotchFilterBandwidth"			Name="Notch Filter Bandwidth"
+(003A,0230) VERS="3"	VR="FL"   VM="1"	Keyword="WaveformDataDisplayScale"				Name="Waveform Data Display Scale"
+(003A,0231) VERS="3"	VR="US"   VM="3"	Keyword="WaveformDisplayBackgroundCIELabValue"	Name="Waveform Display Background CIELab Value"
+(003A,0240) VERS="3"	VR="SQ"   VM="1"	Keyword="WaveformPresentationGroupSequence"		Name="Waveform Presentation Group Sequence"
+(003A,0241) VERS="3"	VR="US"   VM="1"	Keyword="PresentationGroupNumber"				Name="Presentation Group Number"
+(003A,0242) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelDisplaySequence"				Name="Channel Display Sequence"
+(003A,0244) VERS="3"	VR="US"   VM="3"	Keyword="ChannelRecommendedDisplayCIELabValue"	Name="Channel Recommended Display CIELab Value"
+(003A,0245) VERS="3"	VR="FL"   VM="1"	Keyword="ChannelPosition"						Name="Channel Position"
+(003A,0246) VERS="3"	VR="CS"   VM="1"	Keyword="DisplayShadingFlag"					Name="Display Shading Flag"
+(003A,0247) VERS="3"	VR="FL"   VM="1"	Keyword="FractionalChannelDisplayScale"			Name="Fractional Channel Display Scale"
+(003A,0248) VERS="3"	VR="FL"   VM="1"	Keyword="AbsoluteChannelDisplayScale"			Name="Absolute Channel Display Scale"
+(003A,0300) VERS="3"	VR="SQ"   VM="1"	Keyword="MultiplexedAudioChannelsDescriptionCodeSequence"	Name="Multiplexed Audio Channels Description Code Sequence"
+(003A,0301) VERS="3"	VR="IS"   VM="1"	Keyword="ChannelIdentificationCode"		Name="Channel Identification Code"
+(003A,0302) VERS="3"	VR="CS"   VM="1"	Keyword="ChannelMode"				Name="Channel Mode"
+(0040,0001) VERS="3"	VR="AE"   VM="1-n"	Keyword="ScheduledStationAETitle"		Name="Scheduled Station AE Title"
+(0040,0002) VERS="3"	VR="DA"   VM="1"	Keyword="ScheduledProcedureStepStartDate"	Name="Scheduled Procedure Step Start Date"
+(0040,0003) VERS="3"	VR="TM"   VM="1"	Keyword="ScheduledProcedureStepStartTime"	Name="Scheduled Procedure Step Start Time"
+(0040,0004) VERS="3"	VR="DA"   VM="1"	Keyword="ScheduledProcedureStepEndDate"		Name="Scheduled Procedure Step End Date"
+(0040,0005) VERS="3"	VR="TM"   VM="1"	Keyword="ScheduledProcedureStepEndTime"		Name="Scheduled Procedure Step End Time"
+(0040,0006) VERS="3"	VR="PN"   VM="1"	Keyword="ScheduledPerformingPhysicianName"	Name="Scheduled Performing Physician's Name"
+(0040,0007) VERS="3"	VR="LO"   VM="1"	Keyword="ScheduledProcedureStepDescription"	Name="Scheduled Procedure Step Description"
+(0040,0008) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledProtocolCodeSequence"		Name="Scheduled Protocol Code Sequence"
+(0040,0009) VERS="3"	VR="SH"   VM="1"	Keyword="ScheduledProcedureStepID"		Name="Scheduled Procedure Step ID"
+(0040,000A) VERS="3"	VR="SQ"   VM="1"	Keyword="StageCodeSequence"			Name="Stage Code Sequence"
+(0040,000B) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledPerformingPhysicianIdentificationSequence"	Name="Scheduled Performing Physician Identification Sequence"
+(0040,0010) VERS="3"	VR="SH"   VM="1-n"	Keyword="ScheduledStationName"			Name="Scheduled Station Name"
+(0040,0011) VERS="3"	VR="SH"   VM="1"	Keyword="ScheduledProcedureStepLocation"	Name="Scheduled Procedure Step Location"
+(0040,0012) VERS="3"	VR="LO"   VM="1"	Keyword="PreMedication"				Name="Pre-Medication"
+(0040,0020) VERS="3"	VR="CS"   VM="1"	Keyword="ScheduledProcedureStepStatus"		Name="Scheduled Procedure Step Status"
+(0040,0026) VERS="3"	VR="SQ"   VM="1"	Keyword="OrderPlacerIdentifierSequence"	Name="Order Placer Identifier Sequence"
+(0040,0027) VERS="3"	VR="SQ"   VM="1"	Keyword="OrderFillerIdentifierSequence"	Name="Order Filler Identifier Sequence"
+(0040,0031) VERS="3"	VR="UT"   VM="1"	Keyword="LocalNamespaceEntityID"	Name="Local Namespace Entity ID"
+(0040,0032) VERS="3"	VR="UT"   VM="1"	Keyword="UniversalEntityID"	Name="Universal Entity ID"
+(0040,0033) VERS="3"	VR="CS"   VM="1"	Keyword="UniversalEntityIDType"	Name="Universal Entity ID Type"
+(0040,0035) VERS="3"	VR="CS"   VM="1"	Keyword="IdentifierTypeCode"	Name="Identifier Type Code"
+(0040,0036) VERS="3"	VR="SQ"   VM="1"	Keyword="AssigningFacilitySequence"	Name="Assigning Facility Sequence"
+(0040,0039) VERS="3"	VR="SQ"   VM="1"	Keyword="AssigningJurisdictionCodeSequence"	Name="Assigning Jurisdiction Code Sequence"
+(0040,003A) VERS="3"	VR="SQ"   VM="1"	Keyword="AssigningAgencyOrDepartmentCodeSequence"	Name="Assigning Agency or Department Code Sequence"
+(0040,0100) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledProcedureStepSequence"	Name="Scheduled Procedure Step Sequence"
+(0040,0220) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedNonImageCompositeSOPInstanceSequence"	Name="Referenced Non-Image Composite SOP Instance Sequence"
+(0040,0241) VERS="3"	VR="AE"   VM="1"	Keyword="PerformedStationAETitle"		Name="Performed Station AE Title"
+(0040,0242) VERS="3"	VR="SH"   VM="1"	Keyword="PerformedStationName"			Name="Performed Station Name"
+(0040,0243) VERS="3"	VR="SH"   VM="1"	Keyword="PerformedLocation"			Name="Performed Location"
+(0040,0244) VERS="3"	VR="DA"   VM="1"	Keyword="PerformedProcedureStepStartDate"	Name="Performed Procedure Step Start Date"
+(0040,0245) VERS="3"	VR="TM"   VM="1"	Keyword="PerformedProcedureStepStartTime"	Name="Performed Procedure Step Start Time"
+(0040,0250) VERS="3"	VR="DA"   VM="1"	Keyword="PerformedProcedureStepEndDate"		Name="Performed Procedure Step End Date"
+(0040,0251) VERS="3"	VR="TM"   VM="1"	Keyword="PerformedProcedureStepEndTime"		Name="Performed Procedure Step End Time"
+(0040,0252) VERS="3"	VR="CS"   VM="1"	Keyword="PerformedProcedureStepStatus"		Name="Performed Procedure Step Status"
+(0040,0253) VERS="3"	VR="SH"   VM="1"	Keyword="PerformedProcedureStepID"		Name="Performed Procedure Step ID"
+(0040,0254) VERS="3"	VR="LO"   VM="1"	Keyword="PerformedProcedureStepDescription"	Name="Performed Procedure Step Description"
+(0040,0255) VERS="3"	VR="LO"   VM="1"	Keyword="PerformedProcedureTypeDescription"	Name="Performed Procedure Type Description"
+(0040,0260) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedProtocolCodeSequence"		Name="Performed Protocol Code Sequence"
+(0040,0261) VERS="3"	VR="CS"   VM="1"	Keyword="PerformedProtocolType"				Name="Performed Protocol Type"
+(0040,0270) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledStepAttributesSequence"	Name="Scheduled Step Attributes Sequence"
+(0040,0275) VERS="3"	VR="SQ"   VM="1"	Keyword="RequestAttributesSequence"		Name="Request Attributes Sequence"
+(0040,0280) VERS="3"	VR="ST"   VM="1"	Keyword="CommentsOnThePerformedProcedureStep"	Name="Comments on the Performed Procedure Step"
+(0040,0281) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedProcedureStepDiscontinuationReasonCodeSequence"	Name="Performed Procedure Step Discontinuation Reason Code Sequence"
+(0040,0293) VERS="3"	VR="SQ"   VM="1"	Keyword="QuantitySequence"			Name="Quantity Sequence"
+(0040,0294) VERS="3"	VR="DS"   VM="1"	Keyword="Quantity"				Name="Quantity"
+(0040,0295) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasuringUnitsSequence"		Name="Measuring Units Sequence"
+(0040,0296) VERS="3"	VR="SQ"   VM="1"	Keyword="BillingItemSequence"			Name="Billing Item Sequence"
+(0040,0300) VERS="3"	VR="US"   VM="1"	Keyword="TotalTimeOfFluoroscopy"		Name="Total Time of Fluoroscopy"
+(0040,0301) VERS="3"	VR="US"   VM="1"	Keyword="TotalNumberOfExposures"		Name="Total Number of Exposures"
+(0040,0302) VERS="3"	VR="US"   VM="1"	Keyword="EntranceDose"				Name="Entrance Dose"
+(0040,0303) VERS="3"	VR="US"   VM="1-2"	Keyword="ExposedArea"				Name="Exposed Area"
+(0040,0306) VERS="3"	VR="DS"   VM="1"	Keyword="DistanceSourceToEntrance"		Name="Distance Source to Entrance"
+(0040,0307) VERS="RET"	VR="DS"   VM="1"	Keyword="DistanceSourceToSupport"		Name="Distance Source to Support"
+(0040,030E) VERS="3"	VR="SQ"   VM="1"	Keyword="ExposureDoseSequence"			Name="Exposure Dose Sequence"
+(0040,0310) VERS="3"	VR="ST"   VM="1"	Keyword="CommentsOnRadiationDose"		Name="Comments on Radiation Dose"
+(0040,0312) VERS="3"	VR="DS"   VM="1"	Keyword="XRayOutput"				Name="X-Ray Output"
+(0040,0314) VERS="3"	VR="DS"   VM="1"	Keyword="HalfValueLayer"			Name="Half Value Layer"
+(0040,0316) VERS="3"	VR="DS"   VM="1"	Keyword="OrganDose"				Name="Organ Dose"
+(0040,0318) VERS="3"	VR="CS"   VM="1"	Keyword="OrganExposed"				Name="Organ Exposed"
+(0040,0320) VERS="3"	VR="SQ"   VM="1"	Keyword="BillingProcedureStepSequence"		Name="Billing Procedure Step Sequence"
+(0040,0321) VERS="3"	VR="SQ"   VM="1"	Keyword="FilmConsumptionSequence"		Name="Film Consumption Sequence"
+(0040,0324) VERS="3"	VR="SQ"   VM="1"	Keyword="BillingSuppliesAndDevicesSequence"	Name="Billing Supplies and Devices Sequence"
+(0040,0330) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedProcedureStepSequence"	Name="Referenced Procedure Step Sequence"
+(0040,0340) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedSeriesSequence"		Name="Performed Series Sequence"
+(0040,0400) VERS="3"	VR="LT"   VM="1"	Keyword="CommentsOnTheScheduledProcedureStep"	Name="Comments on the Scheduled Procedure Step"
+(0040,0440) VERS="3"	VR="SQ"   VM="1"	Keyword="ProtocolContextSequence"		Name="Protocol Context Sequence"
+(0040,0441) VERS="3"	VR="SQ"   VM="1"	Keyword="ContentItemModifierSequence"		Name="Content Item Modifier Sequence"
+(0040,0500) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledSpecimenSequence"			Name="Scheduled Specimen Sequence"
+(0040,050A) VERS="RET"	VR="LO"   VM="1"	Keyword="SpecimenAccessionNumber"		Name="Specimen Accession Number"
+(0040,0512) VERS="3"	VR="LO"   VM="1"	Keyword="ContainerIdentifier"		Name="Container Identifier"
+(0040,0513) VERS="3"	VR="SQ"   VM="1"	Keyword="IssuerOfTheContainerIdentifierSequence"		Name="Issuer of the Container Identifier Sequence"
+(0040,0515) VERS="3"	VR="SQ"   VM="1"	Keyword="AlternateContainerIdentifierSequence"		Name="Alternate Container Identifier Sequence"
+(0040,0518) VERS="3"	VR="SQ"   VM="1"	Keyword="ContainerTypeCodeSequence"		Name="Container Type Code Sequence"
+(0040,051A) VERS="3"	VR="LO"   VM="1"	Keyword="ContainerDescription"		Name="Container Description"
+(0040,0520) VERS="3"	VR="SQ"   VM="1"	Keyword="ContainerComponentSequence"		Name="Container Component Sequence"
+(0040,0550) VERS="RET"	VR="SQ"   VM="1"	Keyword="SpecimenSequence"			Name="Specimen Sequence"
+(0040,0551) VERS="3"	VR="LO"   VM="1"	Keyword="SpecimenIdentifier"			Name="Specimen Identifier"
+(0040,0552) VERS="RET"	VR="SQ"   VM="1"	Keyword="SpecimenDescriptionSequenceTrial"		Name="Specimen Description Sequence (Trial)"
+(0040,0553) VERS="RET"	VR="ST"   VM="1"	Keyword="SpecimenDescriptionTrial"			Name="Specimen Description (Trial)"
+(0040,0554) VERS="3"	VR="UI"   VM="1"	Keyword="SpecimenUID"		Name="Specimen UID"
+(0040,0555) VERS="3"	VR="SQ"   VM="1"	Keyword="AcquisitionContextSequence"		Name="Acquisition Context Sequence"
+(0040,0556) VERS="3"	VR="ST"   VM="1"	Keyword="AcquisitionContextDescription"		Name="Acquisition Context Description"
+(0040,0560) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecimenDescriptionSequence"		Name="Specimen Description Sequence"
+(0040,0562) VERS="3"	VR="SQ"   VM="1"	Keyword="IssuerOfTheSpecimenIdentifierSequence"		Name="Issuer of the Specimen Identifier Sequence"
+(0040,059A) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecimenTypeCodeSequence"		Name="Specimen Type Code Sequence"
+(0040,0600) VERS="3"	VR="LO"   VM="1"	Keyword="SpecimenShortDescription"		Name="Specimen Short Description"
+(0040,0602) VERS="3"	VR="UT"   VM="1"	Keyword="SpecimenDetailedDescription"		Name="Specimen Detailed Description"
+(0040,0610) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecimenPreparationSequence"		Name="Specimen Preparation Sequence"
+(0040,0612) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecimenPreparationStepContentItemSequence"		Name="Specimen Preparation Step Content Item Sequence"
+(0040,0620) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecimenLocalizationContentItemSequence"		Name="Specimen Localization Content Item Sequence"
+(0040,06FA) VERS="RET"	VR="LO"   VM="1"	Keyword="SlideIdentifier"			Name="Slide Identifier"
+(0040,071A) VERS="3"	VR="SQ"   VM="1"	Keyword="ImageCenterPointCoordinatesSequence"	Name="Image Center Point Coordinates Sequence"
+(0040,072A) VERS="3"	VR="DS"   VM="1"	Keyword="XOffsetInSlideCoordinateSystem"	Name="X Offset in Slide Coordinate System"
+(0040,073A) VERS="3"	VR="DS"   VM="1"	Keyword="YOffsetInSlideCoordinateSystem"	Name="Y Offset in Slide Coordinate System"
+(0040,074A) VERS="3"	VR="DS"   VM="1"	Keyword="ZOffsetInSlideCoordinateSystem"	Name="Z Offset in Slide Coordinate System"
+(0040,08D8) VERS="3"	VR="SQ"   VM="1"	Keyword="PixelSpacingSequence"			Name="Pixel Spacing Sequence"
+(0040,08DA) VERS="3"	VR="SQ"   VM="1"	Keyword="CoordinateSystemAxisCodeSequence"	Name="Coordinate System Axis Code Sequence"
+(0040,08EA) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasurementUnitsCodeSequence"		Name="Measurement Units Code Sequence"
+(0040,09F8) VERS="RET"	VR="SQ"   VM="1"	Keyword="VitalStainCodeSequenceTrial"		Name="Vital Stain Code Sequence (Trial)"
+(0040,1001) VERS="3"	VR="SH"   VM="1"	Keyword="RequestedProcedureID"			Name="Requested Procedure ID"
+(0040,1002) VERS="3"	VR="LO"   VM="1"	Keyword="ReasonForTheRequestedProcedure"		Name="Reason for the Requested Procedure"
+(0040,1003) VERS="3"	VR="SH"   VM="1"	Keyword="RequestedProcedurePriority"		Name="Requested Procedure Priority"
+(0040,1004) VERS="3"	VR="LO"   VM="1"	Keyword="PatientTransportArrangements"		Name="Patient Transport Arrangements"
+(0040,1005) VERS="3"	VR="LO"   VM="1"	Keyword="RequestedProcedureLocation"		Name="Requested Procedure Location"
+(0040,1006) VERS="RET"	VR="SH"   VM="1"	Keyword="PlacerOrderNumberProcedure"		Name="Placer Order Number / Procedure"
+(0040,1007) VERS="RET"	VR="SH"   VM="1"	Keyword="FillerOrderNumberProcedure"		Name="Filler Order Number / Procedure"
+(0040,1008) VERS="3"	VR="LO"   VM="1"	Keyword="ConfidentialityCode"			Name="Confidentiality Code"
+(0040,1009) VERS="3"	VR="SH"   VM="1"	Keyword="ReportingPriority"			Name="Reporting Priority"
+(0040,100A) VERS="3"	VR="SQ"   VM="1"	Keyword="ReasonForRequestedProcedureCodeSequence"	Name="Reason for Requested Procedure Code Sequence"
+(0040,1010) VERS="3"	VR="PN"   VM="1-n"	Keyword="NamesOfIntendedRecipientsOfResults"	Name="Names of Intended Recipients of Results"
+(0040,1011) VERS="3"	VR="SQ"   VM="1"	Keyword="IntendedRecipientsOfResultsIdentificationSequence"	Name="Intended Recipients of Results Identification Sequence"
+(0040,1012) VERS="3"	VR="SQ"   VM="1"	Keyword="ReasonForPerformedProcedureCodeSequence"	Name="Reason For Performed Procedure Code Sequence"
+(0040,1060) VERS="RET"	VR="LO"   VM="1"	Keyword="RequestedProcedureDescriptionTrial"	Name="Requested Procedure Description (Trial)"
+(0040,1101) VERS="3"	VR="SQ"   VM="1"	Keyword="PersonIdentificationCodeSequence"	Name="Person Identification Code Sequence"
+(0040,1102) VERS="3"	VR="ST"   VM="1"	Keyword="PersonAddress"				Name="Person's Address"
+(0040,1103) VERS="3"	VR="LO"   VM="1-n"	Keyword="PersonTelephoneNumbers"		Name="Person's Telephone Numbers"
+(0040,1104) VERS="3"	VR="LT"   VM="1"	Keyword="PersonTelecomInformation"		Name="Person's Telecom Information"
+(0040,1400) VERS="3"	VR="LT"   VM="1"	Keyword="RequestedProcedureComments"		Name="Requested Procedure Comments"
+(0040,2001) VERS="RET"	VR="LO"   VM="1"	Keyword="ReasonForTheImagingServiceRequest"	Name="Reason for the Imaging Service Request"
+(0040,2004) VERS="3"	VR="DA"   VM="1"	Keyword="IssueDateOfImagingServiceRequest"	Name="Issue Date of Imaging Service Request"
+(0040,2005) VERS="3"	VR="TM"   VM="1"	Keyword="IssueTimeOfImagingServiceRequest"	Name="Issue Time of Imaging Service Request"
+(0040,2006) VERS="RET"	VR="SH"   VM="1"	Keyword="PlacerOrderNumberImagingServiceRequestRetired"	Name="Placer Order Number / Imaging Service Request (Retired)"
+(0040,2007) VERS="RET"	VR="SH"   VM="1"	Keyword="FillerOrderNumberImagingServiceRequestRetired"	Name="Filler Order Number / Imaging Service Request (Retired)"
+(0040,2008) VERS="3"	VR="PN"   VM="1"	Keyword="OrderEnteredBy"			Name="Order Entered By"
+(0040,2009) VERS="3"	VR="SH"   VM="1"	Keyword="OrderEntererLocation"			Name="Order Enterer's Location"
+(0040,2010) VERS="3"	VR="SH"   VM="1"	Keyword="OrderCallbackPhoneNumber"		Name="Order Callback Phone Number"
+(0040,2011) VERS="3"	VR="LT"   VM="1"	Keyword="OrderCallbackTelecomInformation"		Name="Order Callback Telecom Information"
+(0040,2016) VERS="3"	VR="LO"   VM="1"	Keyword="PlacerOrderNumberImagingServiceRequest"	Name="Placer Order Number / Imaging Service Request"
+(0040,2017) VERS="3"	VR="LO"   VM="1"	Keyword="FillerOrderNumberImagingServiceRequest"	Name="Filler Order Number / Imaging Service Request"
+(0040,2400) VERS="3"	VR="LT"   VM="1"	Keyword="ImagingServiceRequestComments"		Name="Imaging Service Request Comments"
+(0040,3001) VERS="3"	VR="LO"   VM="1"	Keyword="ConfidentialityConstraintOnPatientDataDescription"	Name="Confidentiality Constraint on Patient Data Description"
+(0040,4001) VERS="RET"	VR="CS"   VM="1"	Keyword="GeneralPurposeScheduledProcedureStepStatus"			Name="General Purpose Scheduled Procedure Step Status"
+(0040,4002) VERS="RET"	VR="CS"   VM="1"	Keyword="GeneralPurposePerformedProcedureStepStatus"			Name="General Purpose Performed Procedure Step Status"
+(0040,4003) VERS="RET"	VR="CS"   VM="1"	Keyword="GeneralPurposeScheduledProcedureStepPriority"			Name="General Purpose Scheduled Procedure Step Priority"
+(0040,4004) VERS="RET"	VR="SQ"   VM="1"	Keyword="ScheduledProcessingApplicationsCodeSequence"			Name="Scheduled Processing Applications Code Sequence"
+(0040,4005) VERS="3"	VR="DT"   VM="1"	Keyword="ScheduledProcedureStepStartDateTime"			Name="Scheduled Procedure Step Start DateTime"
+(0040,4006) VERS="RET"	VR="CS"   VM="1"	Keyword="MultipleCopiesFlag"						Name="Multiple Copies Flag"
+(0040,4007) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedProcessingApplicationsCodeSequence"			Name="Performed Processing Applications Code Sequence"
+(0040,4009) VERS="3"	VR="SQ"   VM="1"	Keyword="HumanPerformerCodeSequence"					Name="Human Performer Code Sequence"
+(0040,4010) VERS="3"	VR="DT"   VM="1"	Keyword="ScheduledProcedureStepModificationDateTime"			Name="Scheduled Procedure Step Modification DateTime"
+(0040,4011) VERS="3"	VR="DT"   VM="1"	Keyword="ExpectedCompletionDateTime"					Name="Expected Completion DateTime"
+(0040,4015) VERS="RET"	VR="SQ"   VM="1"	Keyword="ResultingGeneralPurposePerformedProcedureStepsSequence"	Name="Resulting General Purpose Performed Procedure Steps Sequence"
+(0040,4016) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedGeneralPurposeScheduledProcedureStepSequence"	Name="Referenced General Purpose Scheduled Procedure Step Sequence"
+(0040,4018) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledWorkitemCodeSequence"					Name="Scheduled Workitem Code Sequence"
+(0040,4019) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedWorkitemCodeSequence"					Name="Performed Workitem Code Sequence"
+(0040,4020) VERS="3"	VR="CS"   VM="1"	Keyword="InputAvailabilityFlag"						Name="Input Availability Flag"
+(0040,4021) VERS="3"	VR="SQ"   VM="1"	Keyword="InputInformationSequence"					Name="Input Information Sequence"
+(0040,4022) VERS="RET"	VR="SQ"   VM="1"	Keyword="RelevantInformationSequence"					Name="Relevant Information Sequence"
+(0040,4023) VERS="RET"	VR="UI"   VM="1"	Keyword="ReferencedGeneralPurposeScheduledProcedureStepTransactionUID"	Name="Referenced General Purpose Scheduled Procedure Step Transaction UID"
+(0040,4025) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledStationNameCodeSequence"				Name="Scheduled Station Name Code Sequence"
+(0040,4026) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledStationClassCodeSequence"				Name="Scheduled Station Class Code Sequence"
+(0040,4027) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledStationGeographicLocationCodeSequence"		Name="Scheduled Station Geographic Location Code Sequence"
+(0040,4028) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedStationNameCodeSequence"				Name="Performed Station Name Code Sequence"
+(0040,4029) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedStationClassCodeSequence"				Name="Performed Station Class Code Sequence"
+(0040,4030) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedStationGeographicLocationCodeSequence"		Name="Performed Station Geographic Location Code Sequence"
+(0040,4031) VERS="RET"	VR="SQ"   VM="1"	Keyword="RequestedSubsequentWorkitemCodeSequence"			Name="Requested Subsequent Workitem Code Sequence"
+(0040,4032) VERS="RET"	VR="SQ"   VM="1"	Keyword="NonDICOMOutputCodeSequence"					Name="Non-DICOM Output Code Sequence"
+(0040,4033) VERS="3"	VR="SQ"   VM="1"	Keyword="OutputInformationSequence"					Name="Output Information Sequence"
+(0040,4034) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledHumanPerformersSequence"				Name="Scheduled Human Performers Sequence"
+(0040,4035) VERS="3"	VR="SQ"   VM="1"	Keyword="ActualHumanPerformersSequence"					Name="Actual Human Performers Sequence"
+(0040,4036) VERS="3"	VR="LO"   VM="1"	Keyword="HumanPerformerOrganization"					Name="Human Performer's Organization"
+(0040,4037) VERS="3"	VR="PN"   VM="1"	Keyword="HumanPerformerName"						Name="Human Performer's Name"
+(0040,4040) VERS="3"	VR="CS"   VM="1"	Keyword="RawDataHandling"						Name="Raw Data Handling"
+(0040,4041) VERS="3"	VR="CS"   VM="1"	Keyword="InputReadinessState"						Name="Input Readiness State"
+(0040,4050) VERS="3"	VR="DT"   VM="1"	Keyword="PerformedProcedureStepStartDateTime"		Name="Performed Procedure Step Start DateTime"
+(0040,4051) VERS="3"	VR="DT"   VM="1"	Keyword="PerformedProcedureStepEndDateTime"			Name="Performed Procedure Step End DateTime"
+(0040,4052) VERS="3"	VR="DT"   VM="1"	Keyword="ProcedureStepCancellationDateTime"			Name="Procedure Step Cancellation DateTime"
+(0040,4070) VERS="3"	VR="SQ"   VM="1"	Keyword="OutputDestinationSequence"				Name="Output Destination Sequence"
+(0040,4071) VERS="3"	VR="SQ"   VM="1"	Keyword="DICOMStorageSequence"					Name="DICOM Storage Sequence"
+(0040,4072) VERS="3"	VR="SQ"   VM="1"	Keyword="STOWRSStorageSequence"					Name="STOW-RS Storage Sequence"
+(0040,4073) VERS="3"	VR="UR"   VM="1"	Keyword="StorageURL"							Name="Storage URL"
+(0040,4074) VERS="3"	VR="SQ"   VM="1"	Keyword="XDSStorageSequence"					Name="XDS Storage Sequence"
+(0040,8302) VERS="3"	VR="DS"   VM="1"	Keyword="EntranceDoseInmGy"				Name="Entrance Dose in mGy"
+(0040,9092) VERS="3"	VR="SQ"   VM="1"	Keyword="ParametricMapFrameTypeSequence"			Name="Parametric Map Frame Type Sequence"
+(0040,9094) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedImageRealWorldValueMappingSequence"		Name="Referenced Image Real World Value Mapping Sequence"
+(0040,9096) VERS="3"	VR="SQ"   VM="1"	Keyword="RealWorldValueMappingSequence"		Name="Real World Value Mapping Sequence"
+(0040,9098) VERS="3"	VR="SQ"   VM="1"	Keyword="PixelValueMappingCodeSequence"		Name="Pixel Value Mapping Code Sequence"
+(0040,9210) VERS="3"	VR="SH"   VM="1"	Keyword="LUTLabel"				Name="LUT Label"
+(0040,9211) VERS="3"	VR="US or SS"   VM="1"	Keyword="RealWorldValueLastValueMapped"		Name="Real World Value Last Value Mapped"
+(0040,9212) VERS="3"	VR="FD"   VM="1-n"	Keyword="RealWorldValueLUTData"			Name="Real World Value LUT Data"
+(0040,9213) VERS="3"	VR="FD"   VM="1"	Keyword="DoubleFloatRealWorldValueLastValueMapped"	Name="Double Float Real World Value Last Value Mapped"
+(0040,9214) VERS="3"	VR="FD"   VM="1"	Keyword="DoubleFloatRealWorldValueFirstValueMapped"	Name="Double Float Real World Value First Value Mapped"
+(0040,9216) VERS="3"	VR="US or SS"   VM="1"	Keyword="RealWorldValueFirstValueMapped"	Name="Real World Value First Value Mapped"
+(0040,9220) VERS="3"	VR="SQ"   VM="1"	Keyword="QuantityDefinitionSequence"		Name="Quantity Definition Sequence"
+(0040,9224) VERS="3"	VR="FD"   VM="1"	Keyword="RealWorldValueIntercept"		Name="Real World Value Intercept"
+(0040,9225) VERS="3"	VR="FD"   VM="1"	Keyword="RealWorldValueSlope"			Name="Real World Value Slope"
+(0040,A007) VERS="RET"	VR="CS"   VM="1"	Keyword="FindingsFlagTrial"							Name="Findings Flag (Trial)"
+(0040,A010) VERS="3"	VR="CS"   VM="1"	Keyword="RelationshipType"						Name="Relationship Type"
+(0040,A020) VERS="RET"	VR="SQ"   VM="1"	Keyword="FindingsSequenceTrial"						Name="Findings Sequence (Trial)"
+(0040,A021) VERS="RET"	VR="UI"   VM="1"	Keyword="FindingsGroupUIDTrial"						Name="Findings Group UID (Trial)"
+(0040,A022) VERS="RET"	VR="UI"   VM="1"	Keyword="ReferencedFindingsGroupUIDTrial"			Name="Referenced Findings Group UID (Trial)"
+(0040,A023) VERS="RET"	VR="DA"   VM="1"	Keyword="FindingsGroupRecordingDateTrial"			Name="Findings Group Recording Date (Trial)"
+(0040,A024) VERS="RET"	VR="TM"   VM="1"	Keyword="FindingsGroupRecordingTimeTrial"			Name="Findings Group Recording Time (Trial)"
+(0040,A026) VERS="RET"	VR="SQ"   VM="1"	Keyword="FindingsSourceCategoryCodeSequenceTrial"	Name="Findings Source Category Code Sequence (Trial)"
+(0040,A027) VERS="3"	VR="LO"   VM="1"	Keyword="VerifyingOrganization"					Name="Verifying Organization"
+(0040,A028) VERS="RET"	VR="SQ"   VM="1"	Keyword="DocumentingOrganizationIdentifierCodeSequenceTrial"	Name="Documenting Organization Identifier Code Sequence (Trial)"
+(0040,A030) VERS="3"	VR="DT"   VM="1"	Keyword="VerificationDateTime"					Name="Verification DateTime"
+(0040,A032) VERS="3"	VR="DT"   VM="1"	Keyword="ObservationDateTime"					Name="Observation DateTime"
+(0040,A040) VERS="3"	VR="CS"   VM="1"	Keyword="ValueType"								Name="Value Type"
+(0040,A043) VERS="3"	VR="SQ"   VM="1"	Keyword="ConceptNameCodeSequence"				Name="Concept Name Code Sequence"
+(0040,A047) VERS="RET"	VR="LO"   VM="1"	Keyword="MeasurementPrecisionDescriptionTrial"		Name="Measurement Precision Description (Trial)"
+(0040,A050) VERS="3"	VR="CS"   VM="1"	Keyword="ContinuityOfContent"					Name="Continuity Of Content"
+(0040,A057) VERS="RET"	VR="CS"   VM="1-n"	Keyword="UrgencyOrPriorityAlertsTrial"				Name="Urgency or Priority Alerts (Trial)"
+(0040,A060) VERS="RET"	VR="LO"   VM="1"	Keyword="SequencingIndicatorTrial"					Name="Sequencing Indicator (Trial)"
+(0040,A066) VERS="RET"	VR="SQ"   VM="1"	Keyword="DocumentIdentifierCodeSequenceTrial"		Name="Document Identifier Code Sequence (Trial)"
+(0040,A067) VERS="RET"	VR="PN"   VM="1"	Keyword="DocumentAuthorTrial"						Name="Document Author (Trial)"
+(0040,A068) VERS="RET"	VR="SQ"   VM="1"	Keyword="DocumentAuthorIdentifierCodeSequenceTrial"	Name="Document Author Identifier Code Sequence (Trial)"
+(0040,A070) VERS="RET"	VR="SQ"   VM="1"	Keyword="IdentifierCodeSequenceTrial"				Name="Identifier Code Sequence (Trial)"
+(0040,A073) VERS="3"	VR="SQ"   VM="1"	Keyword="VerifyingObserverSequence"				Name="Verifying Observer Sequence"
+(0040,A074) VERS="RET"	VR="OB"   VM="1"	Keyword="ObjectBinaryIdentifierTrial"				Name="Object Binary Identifier (Trial)"
+(0040,A075) VERS="3"	VR="PN"   VM="1"	Keyword="VerifyingObserverName"					Name="Verifying Observer Name"
+(0040,A076) VERS="RET"	VR="SQ"   VM="1"	Keyword="DocumentingObserverIdentifierCodeSequenceTrial"	Name="Documenting Observer Identifier Code Sequence (Trial)"
+(0040,A078) VERS="3"	VR="SQ"   VM="1"	Keyword="AuthorObserverSequence"				Name="Author Observer Sequence"
+(0040,A07A) VERS="3"	VR="SQ"   VM="1"	Keyword="ParticipantSequence"					Name="Participant Sequence"
+(0040,A07C) VERS="3"	VR="SQ"   VM="1"	Keyword="CustodialOrganizationSequence"			Name="Custodial Organization Sequence"
+(0040,A080) VERS="3"	VR="CS"   VM="1"	Keyword="ParticipationType"						Name="Participation Type"
+(0040,A082) VERS="3"	VR="DT"   VM="1"	Keyword="ParticipationDateTime"					Name="Participation DateTime"
+(0040,A084) VERS="3"	VR="CS"   VM="1"	Keyword="ObserverType"							Name="Observer Type"
+(0040,A085) VERS="RET"	VR="SQ"   VM="1"	Keyword="ProcedureIdentifierCodeSequenceTrial"		Name="Procedure Identifier Code Sequence (Trial)"
+(0040,A088) VERS="3"	VR="SQ"   VM="1"	Keyword="VerifyingObserverIdentificationCodeSequence"		Name="Verifying Observer Identification Code Sequence"
+(0040,A089) VERS="RET"	VR="OB"   VM="1"	Keyword="ObjectDirectoryBinaryIdentifierTrial"		Name="Object Directory Binary Identifier (Trial)"
+(0040,A090) VERS="RET"	VR="SQ"   VM="1"	Keyword="EquivalentCDADocumentSequence"		Name="Equivalent CDA Document Sequence"
+(0040,A0B0) VERS="3"	VR="US"   VM="2-2n"	Keyword="ReferencedWaveformChannels"		Name="Referenced Waveform Channels"
+(0040,A110) VERS="RET"	VR="DA"   VM="1"	Keyword="DateOfDocumentOrVerbalTransactionTrial"	Name="Date of Document or Verbal Transaction (Trial)"
+(0040,A112) VERS="RET"	VR="TM"   VM="1"	Keyword="TimeOfDocumentCreationOrVerbalTransactionTrial"	Name="Time of Document Creation or Verbal Transaction (Trial)"
+(0040,A120) VERS="3"	VR="DT"   VM="1"	Keyword="DateTime"						Name="DateTime"
+(0040,A121) VERS="3"	VR="DA"   VM="1"	Keyword="Date"						Name="Date"
+(0040,A122) VERS="3"	VR="TM"   VM="1"	Keyword="Time"						Name="Time"
+(0040,A123) VERS="3"	VR="PN"   VM="1"	Keyword="PersonName"					Name="Person Name"
+(0040,A124) VERS="3"	VR="UI"   VM="1"	Keyword="UID"							Name="UID"
+(0040,A125) VERS="RET"	VR="CS"   VM="2"	Keyword="ReportStatusIDTrial"						Name="Report Status ID (Trial)"
+(0040,A130) VERS="3"	VR="CS"   VM="1"	Keyword="TemporalRangeType"			Name="Temporal Range Type"
+(0040,A132) VERS="3"	VR="UL"   VM="1-n"	Keyword="ReferencedSamplePositions"		Name="Referenced Sample Positions"
+(0040,A136) VERS="3"	VR="US"   VM="1-n"	Keyword="ReferencedFrameNumbers"			Name="Referenced Frame Numbers"
+(0040,A138) VERS="3"	VR="DS"   VM="1-n"	Keyword="ReferencedTimeOffsets"			Name="Referenced Time Offsets"
+(0040,A13A) VERS="3"	VR="DT"   VM="1-n"	Keyword="ReferencedDateTime"			Name="Referenced DateTime"
+(0040,A160) VERS="3"	VR="UT"   VM="1"	Keyword="TextValue"					Name="Text Value"
+(0040,A161) VERS="3"	VR="FD"   VM="1-n"	Keyword="FloatingPointValue"						Name="Floating Point Value"
+(0040,A162) VERS="3"	VR="SL"   VM="1-n"	Keyword="RationalNumeratorValue"					Name="Rational Numerator Value"
+(0040,A163) VERS="3"	VR="UL"   VM="1-n"	Keyword="RationalDenominatorValue"					Name="Rational Denominator Value"
+(0040,A167) VERS="RET"	VR="SQ"   VM="1"	Keyword="ObservationCategoryCodeSequenceTrial"		Name="Observation Category Code Sequence (Trial)"
+(0040,A168) VERS="3"	VR="SQ"   VM="1"	Keyword="ConceptCodeSequence"				Name="Concept Code Sequence"
+(0040,A16A) VERS="RET"	VR="ST"   VM="1"	Keyword="BibliographicCitationTrial"				Name="Bibliographic Citation (Trial)"
+(0040,A170) VERS="3"	VR="SQ"   VM="1"	Keyword="PurposeOfReferenceCodeSequence"		Name="Purpose of Reference Code Sequence"
+(0040,A171) VERS="3"	VR="UI"   VM="1"	Keyword="ObservationUID"							Name="Observation UID"
+(0040,A172) VERS="RET"	VR="UI"   VM="1"	Keyword="ReferencedObservationUIDTrial"				Name="Referenced Observation UID (Trial)"
+(0040,A173) VERS="RET"	VR="CS"   VM="1"	Keyword="ReferencedObservationClassTrial"			Name="Referenced Observation Class (Trial)"
+(0040,A174) VERS="RET"	VR="CS"   VM="1"	Keyword="ReferencedObjectObservationClassTrial"		Name="Referenced Object Observation Class (Trial)"
+(0040,A180) VERS="3"	VR="US"   VM="1"	Keyword="AnnotationGroupNumber"			Name="Annotation Group Number"
+(0040,A192) VERS="RET"	VR="DA"   VM="1"	Keyword="ObservationDateTrial"						Name="Observation Date (Trial)"
+(0040,A193) VERS="RET"	VR="TM"   VM="1"	Keyword="ObservationTimeTrial"						Name="Observation Time (Trial)"
+(0040,A194) VERS="RET"	VR="CS"   VM="1"	Keyword="MeasurementAutomationTrial"				Name="Measurement Automation (Trial)"
+(0040,A195) VERS="3"	VR="SQ"   VM="1"	Keyword="ModifierCodeSequence"			Name="Modifier Code Sequence"
+(0040,A224) VERS="RET"	VR="ST"   VM="1"	Keyword="IdentificationDescriptionTrial"			Name="Identification Description (Trial)"
+(0040,A290) VERS="RET"	VR="CS"   VM="1"	Keyword="CoordinatesSetGeometricTypeTrial"			Name="Coordinates Set Geometric Type (Trial)"
+(0040,A296) VERS="RET"	VR="SQ"   VM="1"	Keyword="AlgorithmCodeSequenceTrial"				Name="Algorithm Code Sequence (Trial)"
+(0040,A297) VERS="RET"	VR="ST"   VM="1"	Keyword="AlgorithmDescriptionTrial"					Name="Algorithm Description (Trial)"
+(0040,A29A) VERS="RET"	VR="SL"   VM="2-2n"	Keyword="PixelCoordinatesSetTrial"					Name="Pixel Coordinates Set (Trial)"
+(0040,A300) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasuredValueSequence"					Name="Measured Value Sequence"
+(0040,A301) VERS="3"	VR="SQ"   VM="1"	Keyword="NumericValueQualifierCodeSequence"			Name="Numeric Value Qualifier Code Sequence"
+(0040,A307) VERS="RET"	VR="PN"   VM="1"	Keyword="CurrentObserverTrial"						Name="Current Observer (Trial)"
+(0040,A30A) VERS="3"	VR="DS"   VM="1-n"	Keyword="NumericValue"					Name="Numeric Value"
+(0040,A313) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedAccessionSequenceTrial"			Name="Referenced Accession Sequence (Trial)"
+(0040,A33A) VERS="RET"	VR="ST"   VM="1"	Keyword="ReportStatusCommentTrial"					Name="Report Status Comment (Trial)"
+(0040,A340) VERS="RET"	VR="SQ"   VM="1"	Keyword="ProcedureContextSequenceTrial"				Name="Procedure Context Sequence (Trial)"
+(0040,A352) VERS="RET"	VR="PN"   VM="1"	Keyword="VerbalSourceTrial"							Name="Verbal Source (Trial)"
+(0040,A353) VERS="RET"	VR="ST"   VM="1"	Keyword="AddressTrial"				Name="Address (Trial)"
+(0040,A354) VERS="RET"	VR="LO"   VM="1"	Keyword="TelephoneNumberTrial"			Name="Telephone Number (Trial)"
+(0040,A358) VERS="RET"	VR="SQ"   VM="1"	Keyword="VerbalSourceIdentifierCodeSequenceTrial"	Name="Verbal Source Identifier Code Sequence (Trial)"
+(0040,A360) VERS="3"	VR="SQ"   VM="1"	Keyword="PredecessorDocumentsSequence"				Name="Predecessor Documents Sequence"
+(0040,A370) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedRequestSequence"				Name="Referenced Request Sequence"
+(0040,A372) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedProcedureCodeSequence"			Name="Performed Procedure Code Sequence"
+(0040,A375) VERS="3"	VR="SQ"   VM="1"	Keyword="CurrentRequestedProcedureEvidenceSequence"		Name="Current Requested Procedure Evidence Sequence"
+(0040,A380) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReportDetailSequenceTrial"					Name="Report Detail Sequence (Trial)"
+(0040,A385) VERS="3"	VR="SQ"   VM="1"	Keyword="PertinentOtherEvidenceSequence"			Name="Pertinent Other Evidence Sequence"
+(0040,A390) VERS="3"	VR="SQ"   VM="1"	Keyword="HL7StructuredDocumentReferenceSequence"			Name="HL7 Structured Document Reference Sequence"
+(0040,A402) VERS="RET"	VR="UI"   VM="1"	Keyword="ObservationSubjectUIDTrial"				Name="Observation Subject UID (Trial)"
+(0040,A403) VERS="RET"	VR="CS"   VM="1"	Keyword="ObservationSubjectClassTrial"				Name="Observation Subject Class (Trial)"
+(0040,A404) VERS="RET"	VR="SQ"   VM="1"	Keyword="ObservationSubjectTypeCodeSequenceTrial"	Name="Observation Subject Type Code Sequence (Trial)"
+(0040,A491) VERS="3"	VR="CS"   VM="1"	Keyword="CompletionFlag"					Name="Completion Flag"
+(0040,A492) VERS="3"	VR="LO"   VM="1"	Keyword="CompletionFlagDescription"				Name="Completion Flag Description"
+(0040,A493) VERS="3"	VR="CS"   VM="1"	Keyword="VerificationFlag"					Name="Verification Flag"
+(0040,A494) VERS="3"	VR="CS"   VM="1"	Keyword="ArchiveRequested"					Name="Archive Requested"
+(0040,A496) VERS="3"	VR="CS"   VM="1"	Keyword="PreliminaryFlag"					Name="Preliminary Flag"
+(0040,A504) VERS="3"	VR="SQ"   VM="1"	Keyword="ContentTemplateSequence"				Name="Content Template Sequence"
+(0040,A525) VERS="3"	VR="SQ"   VM="1"	Keyword="IdenticalDocumentsSequence"				Name="Identical Documents Sequence"
+(0040,A600) VERS="RET"	VR="CS"   VM="1"	Keyword="ObservationSubjectContextFlagTrial"		Name="Observation Subject Context Flag (Trial)"
+(0040,A601) VERS="RET"	VR="CS"   VM="1"	Keyword="ObserverContextFlagTrial"					Name="Observer Context Flag (Trial)"
+(0040,A603) VERS="RET"	VR="CS"   VM="1"	Keyword="ProcedureContextFlagTrial"					Name="Procedure Context Flag (Trial)"
+(0040,A730) VERS="3"	VR="SQ"   VM="1"	Keyword="ContentSequence"					Name="Content Sequence"
+(0040,A731) VERS="RET"	VR="SQ"   VM="1"	Keyword="RelationshipSequenceTrial"					Name="Relationship Sequence (Trial)"
+(0040,A732) VERS="RET"	VR="SQ"   VM="1"	Keyword="RelationshipTypeCodeSequenceTrial"			Name="Relationship Type Code Sequence (Trial)"
+(0040,A744) VERS="RET"	VR="SQ"   VM="1"	Keyword="LanguageCodeSequenceTrial"					Name="Language Code Sequence (Trial)"
+(0040,A992) VERS="RET"	VR="ST"   VM="1"	Keyword="UniformResourceLocatorTrial"				Name="Uniform Resource Locator (Trial)"
+(0040,B020) VERS="3"	VR="SQ"   VM="1"	Keyword="WaveformAnnotationSequence"			Name="Waveform Annotation Sequence"
+(0040,DB00) VERS="3"	VR="CS"   VM="1"	Keyword="TemplateIdentifier"					Name="Template Identifier"
+(0040,DB06) VERS="RET"	VR="DT"   VM="1"	Keyword="TemplateVersion"					Name="Template Version"
+(0040,DB07) VERS="RET"	VR="DT"   VM="1"	Keyword="TemplateLocalVersion"					Name="Template Local Version"
+(0040,DB0B) VERS="RET"	VR="CS"   VM="1"	Keyword="TemplateExtensionFlag"					Name="Template Extension Flag"
+(0040,DB0C) VERS="RET"	VR="UI"   VM="1"	Keyword="TemplateExtensionOrganizationUID"			Name="Template Extension Organization UID"
+(0040,DB0D) VERS="RET"	VR="UI"   VM="1"	Keyword="TemplateExtensionCreatorUID"				Name="Template Extension Creator UID"
+(0040,DB73) VERS="3"	VR="UL"   VM="1-n"	Keyword="ReferencedContentItemIdentifier"			Name="Referenced Content Item Identifier"
+(0040,E001) VERS="3"	VR="ST"   VM="1"	Keyword="HL7InstanceIdentifier"				Name="HL7 Instance Identifier"
+(0040,E004) VERS="3"	VR="DT"   VM="1"	Keyword="HL7DocumentEffectiveTime"			Name="HL7 Document Effective Time"
+(0040,E006) VERS="3"	VR="SQ"   VM="1"	Keyword="HL7DocumentTypeCodeSequence"		Name="HL7 Document Type Code Sequence"
+(0040,E008) VERS="3"	VR="SQ"   VM="1"	Keyword="DocumentClassCodeSequence"			Name="Document Class Code Sequence"
+(0040,E010) VERS="3"	VR="UR"   VM="1"	Keyword="RetrieveURI"						Name="Retrieve URI"
+(0040,E011) VERS="3"	VR="UI"   VM="1"	Keyword="RetrieveLocationUID"				Name="Retrieve Location UID"
+(0040,E020) VERS="3"	VR="CS"   VM="1"	Keyword="TypeOfInstances"					Name="Type of Instances"
+(0040,E021) VERS="3"	VR="SQ"   VM="1"	Keyword="DICOMRetrievalSequence"			Name="DICOM Retrieval Sequence"
+(0040,E022) VERS="3"	VR="SQ"   VM="1"	Keyword="DICOMMediaRetrievalSequence"		Name="DICOM Media Retrieval Sequence"
+(0040,E023) VERS="3"	VR="SQ"   VM="1"	Keyword="WADORetrievalSequence"				Name="WADO Retrieval Sequence"
+(0040,E024) VERS="3"	VR="SQ"   VM="1"	Keyword="XDSRetrievalSequence"				Name="XDS Retrieval Sequence"
+(0040,E025) VERS="3"	VR="SQ"   VM="1"	Keyword="WADORSRetrievalSequence"			Name="WADO-RS Retrieval Sequence"
+(0040,E030) VERS="3"	VR="UI"   VM="1"	Keyword="RepositoryUniqueID"				Name="Repository Unique ID"
+(0040,E031) VERS="3"	VR="UI"   VM="1"	Keyword="HomeCommunityID"					Name="Home Community ID"
+(0042,0010) VERS="3"	VR="ST"   VM="1"	Keyword="DocumentTitle"					Name="Document Title"
+(0042,0011) VERS="3"	VR="OB"   VM="1"	Keyword="EncapsulatedDocument"				Name="Encapsulated Document"
+(0042,0012) VERS="3"	VR="LO"   VM="1"	Keyword="MIMETypeOfEncapsulatedDocument"		Name="MIME Type of Encapsulated Document"
+(0042,0013) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceInstanceSequence"			Name="Source Instance Sequence"
+(0042,0014) VERS="3"	VR="LO"   VM="1-n"	Keyword="ListOfMIMETypes"							Name="List of MIME Types"
+(0044,0001) VERS="3"	VR="ST"   VM="1"	Keyword="ProductPackageIdentifier"					Name="Product Package Identifier"
+(0044,0002) VERS="3"	VR="CS"   VM="1"	Keyword="SubstanceAdministrationApproval"			Name="Substance Administration Approval"
+(0044,0003) VERS="3"	VR="LT"   VM="1"	Keyword="ApprovalStatusFurtherDescription"			Name="Approval Status Further Description"
+(0044,0004) VERS="3"	VR="DT"   VM="1"	Keyword="ApprovalStatusDateTime"					Name="Approval Status DateTime"
+(0044,0007) VERS="3"	VR="SQ"   VM="1"	Keyword="ProductTypeCodeSequence"					Name="Product Type Code Sequence"
+(0044,0008) VERS="3"	VR="LO"   VM="1-n"	Keyword="ProductName"								Name="Product Name"
+(0044,0009) VERS="3"	VR="LT"   VM="1"	Keyword="ProductDescription"						Name="Product Description"
+(0044,000A) VERS="3"	VR="LO"   VM="1"	Keyword="ProductLotIdentifier"						Name="Product Lot Identifier"
+(0044,000B) VERS="3"	VR="DT"   VM="1"	Keyword="ProductExpirationDateTime"					Name="Product Expiration DateTime"
+(0044,0010) VERS="3"	VR="DT"   VM="1"	Keyword="SubstanceAdministrationDateTime"			Name="Substance Administration DateTime"
+(0044,0011) VERS="3"	VR="LO"   VM="1"	Keyword="SubstanceAdministrationNotes"				Name="Substance Administration Notes"
+(0044,0012) VERS="3"	VR="LO"   VM="1"	Keyword="SubstanceAdministrationDeviceID"			Name="Substance Administration Device ID"
+(0044,0013) VERS="3"	VR="SQ"   VM="1"	Keyword="ProductParameterSequence"					Name="Product Parameter Sequence"
+(0044,0019) VERS="3"	VR="SQ"   VM="1"	Keyword="SubstanceAdministrationParameterSequence"	Name="Substance Administration Parameter Sequence"
+(0046,0012) VERS="3"	VR="LO"   VM="1"	Keyword="LensDescription"							Name="Lens Description"
+(0046,0014) VERS="3"	VR="SQ"   VM="1"	Keyword="RightLensSequence"							Name="Right Lens Sequence"
+(0046,0015) VERS="3"	VR="SQ"   VM="1"	Keyword="LeftLensSequence"							Name="Left Lens Sequence"
+(0046,0016) VERS="3"	VR="SQ"   VM="1"	Keyword="UnspecifiedLateralityLensSequence"			Name="Unspecified Laterality Lens Sequence"
+(0046,0018) VERS="3"	VR="SQ"   VM="1"	Keyword="CylinderSequence"							Name="Cylinder Sequence"
+(0046,0028) VERS="3"	VR="SQ"   VM="1"	Keyword="PrismSequence"								Name="Prism Sequence"
+(0046,0030) VERS="3"	VR="FD"   VM="1"	Keyword="HorizontalPrismPower"						Name="Horizontal Prism Power"
+(0046,0032) VERS="3"	VR="CS"   VM="1"	Keyword="HorizontalPrismBase"						Name="Horizontal Prism Base"
+(0046,0034) VERS="3"	VR="FD"   VM="1"	Keyword="VerticalPrismPower"						Name="Vertical Prism Power"
+(0046,0036) VERS="3"	VR="CS"   VM="1"	Keyword="VerticalPrismBase"							Name="Vertical Prism Base"
+(0046,0038) VERS="3"	VR="CS"   VM="1"	Keyword="LensSegmentType"							Name="Lens Segment Type"
+(0046,0040) VERS="3"	VR="FD"   VM="1"	Keyword="OpticalTransmittance"						Name="Optical Transmittance"
+(0046,0042) VERS="3"	VR="FD"   VM="1"	Keyword="ChannelWidth"								Name="Channel Width"
+(0046,0044) VERS="3"	VR="FD"   VM="1"	Keyword="PupilSize"									Name="Pupil Size"
+(0046,0046) VERS="3"	VR="FD"   VM="1"	Keyword="CornealSize"								Name="Corneal Size"
+(0046,0050) VERS="3"	VR="SQ"   VM="1"	Keyword="AutorefractionRightEyeSequence"			Name="Autorefraction Right Eye Sequence"
+(0046,0052) VERS="3"	VR="SQ"   VM="1"	Keyword="AutorefractionLeftEyeSequence"				Name="Autorefraction Left Eye Sequence"
+(0046,0060) VERS="3"	VR="FD"   VM="1"	Keyword="DistancePupillaryDistance"					Name="Distance Pupillary Distance"
+(0046,0062) VERS="3"	VR="FD"   VM="1"	Keyword="NearPupillaryDistance"						Name="Near Pupillary Distance"
+(0046,0063) VERS="3"	VR="FD"   VM="1"	Keyword="IntermediatePupillaryDistance"				Name="Intermediate Pupillary Distance"
+(0046,0064) VERS="3"	VR="FD"   VM="1"	Keyword="OtherPupillaryDistance"					Name="Other Pupillary Distance"
+(0046,0070) VERS="3"	VR="SQ"   VM="1"	Keyword="KeratometryRightEyeSequence"				Name="Keratometry Right Eye Sequence"
+(0046,0071) VERS="3"	VR="SQ"   VM="1"	Keyword="KeratometryLeftEyeSequence"				Name="Keratometry Left Eye Sequence"
+(0046,0074) VERS="3"	VR="SQ"   VM="1"	Keyword="SteepKeratometricAxisSequence"				Name="Steep Keratometric Axis Sequence"
+(0046,0075) VERS="3"	VR="FD"   VM="1"	Keyword="RadiusOfCurvature"							Name="Radius of Curvature"
+(0046,0076) VERS="3"	VR="FD"   VM="1"	Keyword="KeratometricPower"							Name="Keratometric Power"
+(0046,0077) VERS="3"	VR="FD"   VM="1"	Keyword="KeratometricAxis"							Name="Keratometric Axis"
+(0046,0080) VERS="3"	VR="SQ"   VM="1"	Keyword="FlatKeratometricAxisSequence"				Name="Flat Keratometric Axis Sequence"
+(0046,0092) VERS="3"	VR="CS"   VM="1"	Keyword="BackgroundColor"							Name="Background Color"
+(0046,0094) VERS="3"	VR="CS"   VM="1"	Keyword="Optotype"									Name="Optotype"
+(0046,0095) VERS="3"	VR="CS"   VM="1"	Keyword="OptotypePresentation"						Name="Optotype Presentation"
+(0046,0097) VERS="3"	VR="SQ"   VM="1"	Keyword="SubjectiveRefractionRightEyeSequence"		Name="Subjective Refraction Right Eye Sequence"
+(0046,0098) VERS="3"	VR="SQ"   VM="1"	Keyword="SubjectiveRefractionLeftEyeSequence"		Name="Subjective Refraction Left Eye Sequence"
+(0046,0100) VERS="3"	VR="SQ"   VM="1"	Keyword="AddNearSequence"							Name="Add Near Sequence"
+(0046,0101) VERS="3"	VR="SQ"   VM="1"	Keyword="AddIntermediateSequence"					Name="Add Intermediate Sequence"
+(0046,0102) VERS="3"	VR="SQ"   VM="1"	Keyword="AddOtherSequence"							Name="Add Other Sequence"
+(0046,0104) VERS="3"	VR="FD"   VM="1"	Keyword="AddPower"									Name="Add Power"
+(0046,0106) VERS="3"	VR="FD"   VM="1"	Keyword="ViewingDistance"							Name="Viewing Distance"
+(0046,0121) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualAcuityTypeCodeSequence"				Name="Visual Acuity Type Code Sequence"
+(0046,0122) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualAcuityRightEyeSequence"				Name="Visual Acuity Right Eye Sequence"
+(0046,0123) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualAcuityLeftEyeSequence"				Name="Visual Acuity Left Eye Sequence"
+(0046,0124) VERS="3"	VR="SQ"   VM="1"	Keyword="VisualAcuityBothEyesOpenSequence"			Name="Visual Acuity Both Eyes Open Sequence"
+(0046,0125) VERS="3"	VR="CS"   VM="1"	Keyword="ViewingDistanceType"						Name="Viewing Distance Type"
+(0046,0135) VERS="3"	VR="SS"   VM="2"	Keyword="VisualAcuityModifiers"						Name="Visual Acuity Modifiers"
+(0046,0137) VERS="3"	VR="FD"   VM="1"	Keyword="DecimalVisualAcuity"						Name="Decimal Visual Acuity"
+(0046,0139) VERS="3"	VR="LO"   VM="1"	Keyword="OptotypeDetailedDefinition"				Name="Optotype Detailed Definition"
+(0046,0145) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedRefractiveMeasurementsSequence"	Name="Referenced Refractive Measurements Sequence"
+(0046,0146) VERS="3"	VR="FD"   VM="1"	Keyword="SpherePower"								Name="Sphere Power"
+(0046,0147) VERS="3"	VR="FD"   VM="1"	Keyword="CylinderPower"								Name="Cylinder Power"
+(0046,0201) VERS="3"	VR="CS"   VM="1"	Keyword="CornealTopographySurface"					Name="Corneal Topography Surface"
+(0046,0202) VERS="3"	VR="FL"   VM="2"	Keyword="CornealVertexLocation"						Name="Corneal Vertex Location"
+(0046,0203) VERS="3"	VR="FL"   VM="1"	Keyword="PupilCentroidXCoordinate"					Name="Pupil Centroid X-Coordinate"
+(0046,0204) VERS="3"	VR="FL"   VM="1"	Keyword="PupilCentroidYCoordinate"					Name="Pupil Centroid Y-Coordinate"
+(0046,0205) VERS="3"	VR="FL"   VM="1"	Keyword="EquivalentPupilRadius"						Name="Equivalent Pupil Radius"
+(0046,0207) VERS="3"	VR="SQ"   VM="1"	Keyword="CornealTopographyMapTypeCodeSequence"		Name="Corneal Topography Map Type Code Sequence"
+(0046,0208) VERS="3"	VR="IS"   VM="2-2n"	Keyword="VerticesOfTheOutlineOfPupil"				Name="Vertices of the Outline of Pupil"
+(0046,0210) VERS="3"	VR="SQ"   VM="1"	Keyword="CornealTopographyMappingNormalsSequence"	Name="Corneal Topography Mapping Normals Sequence"
+(0046,0211) VERS="3"	VR="SQ"   VM="1"	Keyword="MaximumCornealCurvatureSequence"			Name="Maximum Corneal Curvature Sequence"
+(0046,0212) VERS="3"	VR="FL"   VM="1"	Keyword="MaximumCornealCurvature"					Name="Maximum Corneal Curvature"
+(0046,0213) VERS="3"	VR="FL"   VM="2"	Keyword="MaximumCornealCurvatureLocation"			Name="Maximum Corneal Curvature Location"
+(0046,0215) VERS="3"	VR="SQ"   VM="1"	Keyword="MinimumKeratometricSequence"				Name="Minimum Keratometric Sequence"
+(0046,0218) VERS="3"	VR="SQ"   VM="1"	Keyword="SimulatedKeratometricCylinderSequence"		Name="Simulated Keratometric Cylinder Sequence"
+(0046,0220) VERS="3"	VR="FL"   VM="1"	Keyword="AverageCornealPower"						Name="Average Corneal Power"
+(0046,0224) VERS="3"	VR="FL"   VM="1"	Keyword="CornealISValue"							Name="Corneal I-S Value"
+(0046,0227) VERS="3"	VR="FL"   VM="1"	Keyword="AnalyzedArea"								Name="Analyzed Area"
+(0046,0230) VERS="3"	VR="FL"   VM="1"	Keyword="SurfaceRegularityIndex"					Name="Surface Regularity Index"
+(0046,0232) VERS="3"	VR="FL"   VM="1"	Keyword="SurfaceAsymmetryIndex"						Name="Surface Asymmetry Index"
+(0046,0234) VERS="3"	VR="FL"   VM="1"	Keyword="CornealEccentricityIndex"					Name="Corneal Eccentricity Index"
+(0046,0236) VERS="3"	VR="FL"   VM="1"	Keyword="KeratoconusPredictionIndex"				Name="Keratoconus Prediction Index"
+(0046,0238) VERS="3"	VR="FL"   VM="1"	Keyword="DecimalPotentialVisualAcuity"				Name="Decimal Potential Visual Acuity"
+(0046,0242) VERS="3"	VR="CS"   VM="1"	Keyword="CornealTopographyMapQualityEvaluation"		Name="Corneal Topography Map Quality Evaluation"
+(0046,0244) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceImageCornealProcessedDataSequence"	Name="Source Image Corneal Processed Data Sequence"
+(0046,0247) VERS="3"	VR="FL"   VM="3"	Keyword="CornealPointLocation"						Name="Corneal Point Location"
+(0046,0248) VERS="3"	VR="CS"   VM="1"	Keyword="CornealPointEstimated"						Name="Corneal Point Estimated"
+(0046,0249) VERS="3"	VR="FL"   VM="1"	Keyword="AxialPower"								Name="Axial Power"
+(0046,0250) VERS="3"	VR="FL"   VM="1"	Keyword="TangentialPower"							Name="Tangential Power"
+(0046,0251) VERS="3"	VR="FL"   VM="1"	Keyword="RefractivePower"							Name="Refractive Power"
+(0046,0252) VERS="3"	VR="FL"   VM="1"	Keyword="RelativeElevation"							Name="Relative Elevation"
+(0046,0253) VERS="3"	VR="FL"   VM="1"	Keyword="CornealWavefront"							Name="Corneal Wavefront"
+(0048,0001) VERS="3"	VR="FL"   VM="1"	Keyword="ImagedVolumeWidth"							Name="Imaged Volume Width"
+(0048,0002) VERS="3"	VR="FL"   VM="1"	Keyword="ImagedVolumeHeight"						Name="Imaged Volume Height"
+(0048,0003) VERS="3"	VR="FL"   VM="1"	Keyword="ImagedVolumeDepth"							Name="Imaged Volume Depth"
+(0048,0006) VERS="3"	VR="UL"   VM="1"	Keyword="TotalPixelMatrixColumns"					Name="Total Pixel Matrix Columns"
+(0048,0007) VERS="3"	VR="UL"   VM="1"	Keyword="TotalPixelMatrixRows"						Name="Total Pixel Matrix Rows"
+(0048,0008) VERS="3"	VR="SQ"   VM="1"	Keyword="TotalPixelMatrixOriginSequence"			Name="Total Pixel Matrix Origin Sequence"
+(0048,0010) VERS="3"	VR="CS"   VM="1"	Keyword="SpecimenLabelInImage"						Name="Specimen Label in Image"
+(0048,0011) VERS="3"	VR="CS"   VM="1"	Keyword="FocusMethod"								Name="Focus Method"
+(0048,0012) VERS="3"	VR="CS"   VM="1"	Keyword="ExtendedDepthOfField"						Name="Extended Depth of Field"
+(0048,0013) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfFocalPlanes"						Name="Number of Focal Planes"
+(0048,0014) VERS="3"	VR="FL"   VM="1"	Keyword="DistanceBetweenFocalPlanes"				Name="Distance Between Focal Planes"
+(0048,0015) VERS="3"	VR="US"   VM="3"	Keyword="RecommendedAbsentPixelCIELabValue"			Name="Recommended Absent Pixel CIELab Value"
+(0048,0100) VERS="3"	VR="SQ"   VM="1"	Keyword="IlluminatorTypeCodeSequence"				Name="Illuminator Type Code Sequence"
+(0048,0102) VERS="3"	VR="DS"   VM="6"	Keyword="ImageOrientationSlide"						Name="Image Orientation (Slide)"
+(0048,0105) VERS="3"	VR="SQ"   VM="1"	Keyword="OpticalPathSequence"						Name="Optical Path Sequence"
+(0048,0106) VERS="3"	VR="SH"   VM="1"	Keyword="OpticalPathIdentifier"						Name="Optical Path Identifier"
+(0048,0107) VERS="3"	VR="ST"   VM="1"	Keyword="OpticalPathDescription"					Name="Optical Path Description"
+(0048,0108) VERS="3"	VR="SQ"   VM="1"	Keyword="IlluminationColorCodeSequence"				Name="Illumination Color Code Sequence"
+(0048,0110) VERS="3"	VR="SQ"   VM="1"	Keyword="SpecimenReferenceSequence"					Name="Specimen Reference Sequence"
+(0048,0111) VERS="3"	VR="DS"   VM="1"	Keyword="CondenserLensPower"						Name="Condenser Lens Power"
+(0048,0112) VERS="3"	VR="DS"   VM="1"	Keyword="ObjectiveLensPower"						Name="Objective Lens Power"
+(0048,0113) VERS="3"	VR="DS"   VM="1"	Keyword="ObjectiveLensNumericalAperture"			Name="Objective Lens Numerical Aperture"
+(0048,0120) VERS="3"	VR="SQ"   VM="1"	Keyword="PaletteColorLookupTableSequence"			Name="Palette Color Lookup Table Sequence"
+(0048,0200) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedImageNavigationSequence"			Name="Referenced Image Navigation Sequence"
+(0048,0201) VERS="3"	VR="US"   VM="2"	Keyword="TopLeftHandCornerOfLocalizerArea"			Name="Top Left Hand Corner of Localizer Area"
+(0048,0202) VERS="3"	VR="US"   VM="2"	Keyword="BottomRightHandCornerOfLocalizerArea"		Name="Bottom Right Hand Corner of Localizer Area"
+(0048,0207) VERS="3"	VR="SQ"   VM="1"	Keyword="OpticalPathIdentificationSequence"			Name="Optical Path Identification Sequence"
+(0048,021A) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanePositionSlideSequence"				Name="Plane Position (Slide) Sequence"
+(0048,021E) VERS="3"	VR="SL"   VM="1"	Keyword="ColumnPositionInTotalImagePixelMatrix"		Name="Column Position In Total Image Pixel Matrix"
+(0048,021F) VERS="3"	VR="SL"   VM="1"	Keyword="RowPositionInTotalImagePixelMatrix"		Name="Row Position In Total Image Pixel Matrix"
+(0048,0301) VERS="3"	VR="CS"   VM="1"	Keyword="PixelOriginInterpretation"					Name="Pixel Origin Interpretation"
+(0050,0004) VERS="3"	VR="CS"   VM="1"	Keyword="CalibrationImage"				Name="Calibration Image"
+(0050,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="DeviceSequence"				Name="Device Sequence"
+(0050,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="ContainerComponentTypeCodeSequence"		Name="Container Component Type Code Sequence"
+(0050,0013) VERS="3"	VR="FD"   VM="1"	Keyword="ContainerComponentThickness"		Name="Container Component Thickness"
+(0050,0014) VERS="3"	VR="DS"   VM="1"	Keyword="DeviceLength"					Name="Device Length"
+(0050,0015) VERS="3"	VR="FD"   VM="1"	Keyword="ContainerComponentWidth"		Name="Container Component Width"
+(0050,0016) VERS="3"	VR="DS"   VM="1"	Keyword="DeviceDiameter"				Name="Device Diameter"
+(0050,0017) VERS="3"	VR="CS"   VM="1"	Keyword="DeviceDiameterUnits"				Name="Device Diameter Units"
+(0050,0018) VERS="3"	VR="DS"   VM="1"	Keyword="DeviceVolume"					Name="Device Volume"
+(0050,0019) VERS="3"	VR="DS"   VM="1"	Keyword="InterMarkerDistance"				Name="Inter-Marker Distance"
+(0050,001A) VERS="3"	VR="CS"   VM="1"	Keyword="ContainerComponentMaterial"		Name="Container Component Material"
+(0050,001B) VERS="3"	VR="LO"   VM="1"	Keyword="ContainerComponentID"		Name="Container Component ID"
+(0050,001C) VERS="3"	VR="FD"   VM="1"	Keyword="ContainerComponentLength"		Name="Container Component Length"
+(0050,001D) VERS="3"	VR="FD"   VM="1"	Keyword="ContainerComponentDiameter"		Name="Container Component Diameter"
+(0050,001E) VERS="3"	VR="LO"   VM="1"	Keyword="ContainerComponentDescription"		Name="Container Component Description"
+(0050,0020) VERS="3"	VR="LO"   VM="1"	Keyword="DeviceDescription"				Name="Device Description"
+(0052,0001) VERS="3"	VR="FL"   VM="1"	Keyword="ContrastBolusIngredientPercentByVolume"	Name="Contrast/Bolus Ingredient Percent by Volume"
+(0052,0002) VERS="3"	VR="FD"   VM="1"	Keyword="OCTFocalDistance"						Name="OCT Focal Distance"
+(0052,0003) VERS="3"	VR="FD"   VM="1"	Keyword="BeamSpotSize"							Name="Beam Spot Size"
+(0052,0004) VERS="3"	VR="FD"   VM="1"	Keyword="EffectiveRefractiveIndex"				Name="Effective Refractive Index"
+(0052,0006) VERS="3"	VR="CS"   VM="1"	Keyword="OCTAcquisitionDomain"					Name="OCT Acquisition Domain"
+(0052,0007) VERS="3"	VR="FD"   VM="1"	Keyword="OCTOpticalCenterWavelength"			Name="OCT Optical Center Wavelength"
+(0052,0008) VERS="3"	VR="FD"   VM="1"	Keyword="AxialResolution"						Name="Axial Resolution"
+(0052,0009) VERS="3"	VR="FD"   VM="1"	Keyword="RangingDepth"							Name="Ranging Depth"
+(0052,0011) VERS="3"	VR="FD"   VM="1"	Keyword="ALineRate"								Name="A line Rate"
+(0052,0012) VERS="3"	VR="US"   VM="1"	Keyword="ALinesPerFrame"						Name="A lines Per Frame"
+(0052,0013) VERS="3"	VR="FD"   VM="1"	Keyword="CatheterRotationalRate"				Name="Catheter Rotational Rate"
+(0052,0014) VERS="3"	VR="FD"   VM="1"	Keyword="ALinePixelSpacing"						Name="A line Pixel Spacing"
+(0052,0016) VERS="3"	VR="SQ"   VM="1"	Keyword="ModeOfPercutaneousAccessSequence"		Name="Mode of Percutaneous Access Sequence"
+(0052,0025) VERS="3"	VR="SQ"   VM="1"	Keyword="IntravascularOCTFrameTypeSequence"		Name="Intravascular OCT Frame Type Sequence"
+(0052,0026) VERS="3"	VR="CS"   VM="1"	Keyword="OCTZOffsetApplied"						Name="OCT Z Offset Applied"
+(0052,0027) VERS="3"	VR="SQ"   VM="1"	Keyword="IntravascularFrameContentSequence"		Name="Intravascular Frame Content Sequence"
+(0052,0028) VERS="3"	VR="FD"   VM="1"	Keyword="IntravascularLongitudinalDistance"		Name="Intravascular Longitudinal Distance"
+(0052,0029) VERS="3"	VR="SQ"   VM="1"	Keyword="IntravascularOCTFrameContentSequence"	Name="Intravascular OCT Frame Content Sequence"
+(0052,0030) VERS="3"	VR="SS"   VM="1"	Keyword="OCTZOffsetCorrection"					Name="OCT Z Offset Correction"
+(0052,0031) VERS="3"	VR="CS"   VM="1"	Keyword="CatheterDirectionOfRotation"			Name="Catheter Direction of Rotation"
+(0052,0033) VERS="3"	VR="FD"   VM="1"	Keyword="SeamLineLocation"						Name="Seam Line Location"
+(0052,0034) VERS="3"	VR="FD"   VM="1"	Keyword="FirstALineLocation"					Name="First A line Location"
+(0052,0036) VERS="3"	VR="US"   VM="1"	Keyword="SeamLineIndex"							Name="Seam Line Index"
+(0052,0038) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfPaddedALines"					Name="Number of Padded A lines"
+(0052,0039) VERS="3"	VR="CS"   VM="1"	Keyword="InterpolationType"						Name="Interpolation Type"
+(0052,003A) VERS="3"	VR="CS"   VM="1"	Keyword="RefractiveIndexApplied"				Name="Refractive Index Applied"
+(0054,0010) VERS="3"	VR="US"   VM="1-n"	Keyword="EnergyWindowVector"				Name="Energy Window Vector"
+(0054,0011) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfEnergyWindows"				Name="Number of Energy Windows"
+(0054,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="EnergyWindowInformationSequence"		Name="Energy Window Information Sequence"
+(0054,0013) VERS="3"	VR="SQ"   VM="1"	Keyword="EnergyWindowRangeSequence"			Name="Energy Window Range Sequence"
+(0054,0014) VERS="3"	VR="DS"   VM="1"	Keyword="EnergyWindowLowerLimit"			Name="Energy Window Lower Limit"
+(0054,0015) VERS="3"	VR="DS"   VM="1"	Keyword="EnergyWindowUpperLimit"			Name="Energy Window Upper Limit"
+(0054,0016) VERS="3"	VR="SQ"   VM="1"	Keyword="RadiopharmaceuticalInformationSequence"	Name="Radiopharmaceutical Information Sequence"
+(0054,0017) VERS="3"	VR="IS"   VM="1"	Keyword="ResidualSyringeCounts"				Name="Residual Syringe Counts"
+(0054,0018) VERS="3"	VR="SH"   VM="1"	Keyword="EnergyWindowName"				Name="Energy Window Name"
+(0054,0020) VERS="3"	VR="US"   VM="1-n"	Keyword="DetectorVector"				Name="Detector Vector"
+(0054,0021) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfDetectors"				Name="Number of Detectors"
+(0054,0022) VERS="3"	VR="SQ"   VM="1"	Keyword="DetectorInformationSequence"			Name="Detector Information Sequence"
+(0054,0030) VERS="3"	VR="US"   VM="1-n"	Keyword="PhaseVector"					Name="Phase Vector"
+(0054,0031) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfPhases"				Name="Number of Phases"
+(0054,0032) VERS="3"	VR="SQ"   VM="1"	Keyword="PhaseInformationSequence"			Name="Phase Information Sequence"
+(0054,0033) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfFramesInPhase"				Name="Number of Frames in Phase"
+(0054,0036) VERS="3"	VR="IS"   VM="1"	Keyword="PhaseDelay"					Name="Phase Delay"
+(0054,0038) VERS="3"	VR="IS"   VM="1"	Keyword="PauseBetweenFrames"				Name="Pause Between Frames"
+(0054,0039) VERS="3"	VR="CS"   VM="1"	Keyword="PhaseDescription"				Name="Phase Description"
+(0054,0050) VERS="3"	VR="US"   VM="1-n"	Keyword="RotationVector"				Name="Rotation Vector"
+(0054,0051) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfRotations"				Name="Number of Rotations"
+(0054,0052) VERS="3"	VR="SQ"   VM="1"	Keyword="RotationInformationSequence"			Name="Rotation Information Sequence"
+(0054,0053) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfFramesInRotation"			Name="Number of Frames in Rotation"
+(0054,0060) VERS="3"	VR="US"   VM="1-n"	Keyword="RRIntervalVector"				Name="R-R Interval Vector"
+(0054,0061) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfRRIntervals"				Name="Number of R-R Intervals"
+(0054,0062) VERS="3"	VR="SQ"   VM="1"	Keyword="GatedInformationSequence"			Name="Gated Information Sequence"
+(0054,0063) VERS="3"	VR="SQ"   VM="1"	Keyword="DataInformationSequence"			Name="Data Information Sequence"
+(0054,0070) VERS="3"	VR="US"   VM="1-n"	Keyword="TimeSlotVector"				Name="Time Slot Vector"
+(0054,0071) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfTimeSlots"				Name="Number of Time Slots"
+(0054,0072) VERS="3"	VR="SQ"   VM="1"	Keyword="TimeSlotInformationSequence"			Name="Time Slot Information Sequence"
+(0054,0073) VERS="3"	VR="DS"   VM="1"	Keyword="TimeSlotTime"					Name="Time Slot Time"
+(0054,0080) VERS="3"	VR="US"   VM="1-n"	Keyword="SliceVector"					Name="Slice Vector"
+(0054,0081) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfSlices"				Name="Number of Slices"
+(0054,0090) VERS="3"	VR="US"   VM="1-n"	Keyword="AngularViewVector"				Name="Angular View Vector"
+(0054,0100) VERS="3"	VR="US"   VM="1-n"	Keyword="TimeSliceVector"				Name="Time Slice Vector"
+(0054,0101) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfTimeSlices"				Name="Number of Time Slices"
+(0054,0200) VERS="3"	VR="DS"   VM="1"	Keyword="StartAngle"					Name="Start Angle"
+(0054,0202) VERS="3"	VR="CS"   VM="1"	Keyword="TypeOfDetectorMotion"				Name="Type of Detector Motion"
+(0054,0210) VERS="3"	VR="IS"   VM="1-n"	Keyword="TriggerVector"					Name="Trigger Vector"
+(0054,0211) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfTriggersInPhase"			Name="Number of Triggers in Phase"
+(0054,0220) VERS="3"	VR="SQ"   VM="1"	Keyword="ViewCodeSequence"				Name="View Code Sequence"
+(0054,0222) VERS="3"	VR="SQ"   VM="1"	Keyword="ViewModifierCodeSequence"			Name="View Modifier Code Sequence"
+(0054,0300) VERS="3"	VR="SQ"   VM="1"	Keyword="RadionuclideCodeSequence"			Name="Radionuclide Code Sequence"
+(0054,0302) VERS="3"	VR="SQ"   VM="1"	Keyword="AdministrationRouteCodeSequence"		Name="Administration Route Code Sequence"
+(0054,0304) VERS="3"	VR="SQ"   VM="1"	Keyword="RadiopharmaceuticalCodeSequence"		Name="Radiopharmaceutical Code Sequence"
+(0054,0306) VERS="3"	VR="SQ"   VM="1"	Keyword="CalibrationDataSequence"			Name="Calibration Data Sequence"
+(0054,0308) VERS="3"	VR="US"   VM="1"	Keyword="EnergyWindowNumber"				Name="Energy Window Number"
+(0054,0400) VERS="3"	VR="SH"   VM="1"	Keyword="ImageID"					Name="Image ID"
+(0054,0410) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientOrientationCodeSequence"		Name="Patient Orientation Code Sequence"
+(0054,0412) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientOrientationModifierCodeSequence"	Name="Patient Orientation Modifier Code Sequence"
+(0054,0414) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientGantryRelationshipCodeSequence"		Name="Patient Gantry Relationship Code Sequence"
+(0054,0500) VERS="3"	VR="CS"   VM="1"	Keyword="SliceProgressionDirection"			Name="Slice Progression Direction"
+(0054,0501) VERS="3"	VR="CS"   VM="1"	Keyword="ScanProgressionDirection"			Name="Scan Progression Direction"
+(0054,1000) VERS="3"	VR="CS"   VM="2"	Keyword="SeriesType"					Name="Series Type"
+(0054,1001) VERS="3"	VR="CS"   VM="1"	Keyword="Units"						Name="Units"
+(0054,1002) VERS="3"	VR="CS"   VM="1"	Keyword="CountsSource"					Name="Counts Source"
+(0054,1004) VERS="3"	VR="CS"   VM="1"	Keyword="ReprojectionMethod"				Name="Reprojection Method"
+(0054,1006) VERS="3"	VR="CS"   VM="1"	Keyword="SUVType"							Name="SUV Type"
+(0054,1100) VERS="3"	VR="CS"   VM="1"	Keyword="RandomsCorrectionMethod"			Name="Randoms Correction Method"
+(0054,1101) VERS="3"	VR="LO"   VM="1"	Keyword="AttenuationCorrectionMethod"			Name="Attenuation Correction Method"
+(0054,1102) VERS="3"	VR="CS"   VM="1"	Keyword="DecayCorrection"				Name="Decay Correction"
+(0054,1103) VERS="3"	VR="LO"   VM="1"	Keyword="ReconstructionMethod"				Name="Reconstruction Method"
+(0054,1104) VERS="3"	VR="LO"   VM="1"	Keyword="DetectorLinesOfResponseUsed"			Name="Detector Lines of Response Used"
+(0054,1105) VERS="3"	VR="LO"   VM="1"	Keyword="ScatterCorrectionMethod"			Name="Scatter Correction Method"
+(0054,1200) VERS="3"	VR="DS"   VM="1"	Keyword="AxialAcceptance"				Name="Axial Acceptance"
+(0054,1201) VERS="3"	VR="IS"   VM="2"	Keyword="AxialMash"					Name="Axial Mash"
+(0054,1202) VERS="3"	VR="IS"   VM="1"	Keyword="TransverseMash"				Name="Transverse Mash"
+(0054,1203) VERS="3"	VR="DS"   VM="2"	Keyword="DetectorElementSize"				Name="Detector Element Size"
+(0054,1210) VERS="3"	VR="DS"   VM="1"	Keyword="CoincidenceWindowWidth"			Name="Coincidence Window Width"
+(0054,1220) VERS="3"	VR="CS"   VM="1-n"	Keyword="SecondaryCountsType"				Name="Secondary Counts Type"
+(0054,1300) VERS="3"	VR="DS"   VM="1"	Keyword="FrameReferenceTime"				Name="Frame Reference Time"
+(0054,1310) VERS="3"	VR="IS"   VM="1"	Keyword="PrimaryPromptsCountsAccumulated"		Name="Primary (Prompts) Counts Accumulated"
+(0054,1311) VERS="3"	VR="IS"   VM="1-n"	Keyword="SecondaryCountsAccumulated"			Name="Secondary Counts Accumulated"
+(0054,1320) VERS="3"	VR="DS"   VM="1"	Keyword="SliceSensitivityFactor"			Name="Slice Sensitivity Factor"
+(0054,1321) VERS="3"	VR="DS"   VM="1"	Keyword="DecayFactor"					Name="Decay Factor"
+(0054,1322) VERS="3"	VR="DS"   VM="1"	Keyword="DoseCalibrationFactor"				Name="Dose Calibration Factor"
+(0054,1323) VERS="3"	VR="DS"   VM="1"	Keyword="ScatterFractionFactor"				Name="Scatter Fraction Factor"
+(0054,1324) VERS="3"	VR="DS"   VM="1"	Keyword="DeadTimeFactor"				Name="Dead Time Factor"
+(0054,1330) VERS="3"	VR="US"   VM="1"	Keyword="ImageIndex"					Name="Image Index"
+(0054,1400) VERS="RET"	VR="CS"   VM="1-n"	Keyword="CountsIncluded"				Name="Counts Included"
+(0054,1401) VERS="RET"	VR="CS"   VM="1"	Keyword="DeadTimeCorrectionFlag"			Name="Dead Time Correction Flag"
+(0060,3000) VERS="3"	VR="SQ"   VM="1"	Keyword="HistogramSequence"				Name="Histogram Sequence"
+(0060,3002) VERS="3"	VR="US"   VM="1"	Keyword="HistogramNumberOfBins"				Name="Histogram Number of Bins"
+(0060,3004) VERS="3"	VR="US or SS"   VM="1"	Keyword="HistogramFirstBinValue"			Name="Histogram First Bin Value"
+(0060,3006) VERS="3"	VR="US or SS"   VM="1"	Keyword="HistogramLastBinValue"				Name="Histogram Last Bin Value"
+(0060,3008) VERS="3"	VR="US"   VM="1"	Keyword="HistogramBinWidth"				Name="Histogram Bin Width"
+(0060,3010) VERS="3"	VR="LO"   VM="1"	Keyword="HistogramExplanation"				Name="Histogram Explanation"
+(0060,3020) VERS="3"	VR="UL"   VM="1-n"	Keyword="HistogramData"					Name="Histogram Data"        
+(0062,0001) VERS="3"	VR="CS"   VM="1"	Keyword="SegmentationType"	Name="Segmentation Type"
+(0062,0002) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentSequence"	Name="Segment Sequence"
+(0062,0003) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentedPropertyCategoryCodeSequence"	Name="Segmented Property Category Code Sequence"
+(0062,0004) VERS="3"	VR="US"   VM="1"	Keyword="SegmentNumber"	Name="Segment Number"
+(0062,0005) VERS="3"	VR="LO"   VM="1"	Keyword="SegmentLabel"	Name="Segment Label"
+(0062,0006) VERS="3"	VR="ST"   VM="1"	Keyword="SegmentDescription"	Name="Segment Description"
+(0062,0008) VERS="3"	VR="CS"   VM="1"	Keyword="SegmentAlgorithmType"	Name="Segment Algorithm Type"
+(0062,0009) VERS="3"	VR="LO"   VM="1"	Keyword="SegmentAlgorithmName"	Name="Segment Algorithm Name"
+(0062,000A) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentIdentificationSequence"	Name="Segment Identification Sequence"
+(0062,000B) VERS="3"	VR="US"   VM="1-n"	Keyword="ReferencedSegmentNumber"	Name="Referenced Segment Number"
+(0062,000C) VERS="3"	VR="US"   VM="1"	Keyword="RecommendedDisplayGrayscaleValue"	Name="Recommended Display Grayscale Value"
+(0062,000D) VERS="3"	VR="US"   VM="3"	Keyword="RecommendedDisplayCIELabValue"	Name="Recommended Display CIELab Value"
+(0062,000E) VERS="3"	VR="US"   VM="1"	Keyword="MaximumFractionalValue"	Name="Maximum Fractional Value"
+(0062,000F) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentedPropertyTypeCodeSequence"	Name="Segmented Property Type Code Sequence"
+(0062,0010) VERS="3"	VR="CS"   VM="1"	Keyword="SegmentationFractionalType"	Name="Segmentation Fractional Type"
+(0062,0011) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentedPropertyTypeModifierCodeSequence"	Name="Segmented Property Type Modifier Code Sequence"
+(0062,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="UsedSegmentsSequence"	Name="Used Segments Sequence"
+(0064,0002) VERS="3"	VR="SQ"   VM="1"	Keyword="DeformableRegistrationSequence"	Name="Deformable Registration Sequence"
+(0064,0003) VERS="3"	VR="UI"   VM="1"	Keyword="SourceFrameOfReferenceUID"	Name="Source Frame of Reference UID"
+(0064,0005) VERS="3"	VR="SQ"   VM="1"	Keyword="DeformableRegistrationGridSequence"	Name="Deformable Registration Grid Sequence"
+(0064,0007) VERS="3"	VR="UL"   VM="3"	Keyword="GridDimensions"	Name="Grid Dimensions"
+(0064,0008) VERS="3"	VR="FD"   VM="3"	Keyword="GridResolution"	Name="Grid Resolution"
+(0064,0009) VERS="3"	VR="OF"   VM="1"	Keyword="VectorGridData"	Name="Vector Grid Data"
+(0064,000F) VERS="3"	VR="SQ"   VM="1"	Keyword="PreDeformationMatrixRegistrationSequence"	Name="Pre Deformation Matrix Registration Sequence"
+(0064,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="PostDeformationMatrixRegistrationSequence"	Name="Post Deformation Matrix Registration Sequence"
+(0066,0001) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfSurfaces"											Name="Number of Surfaces"
+(0066,0002) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfaceSequence"											Name="Surface Sequence"
+(0066,0003) VERS="3"	VR="UL"   VM="1"	Keyword="SurfaceNumber"												Name="Surface Number"
+(0066,0004) VERS="3"	VR="LT"   VM="1"	Keyword="SurfaceComments"											Name="Surface Comments"
+(0066,0009) VERS="3"	VR="CS"   VM="1"	Keyword="SurfaceProcessing"											Name="Surface Processing"
+(0066,000A) VERS="3"	VR="FL"   VM="1"	Keyword="SurfaceProcessingRatio"									Name="Surface Processing Ratio"
+(0066,000B) VERS="3"	VR="LO"   VM="1"	Keyword="SurfaceProcessingDescription"								Name="Surface Processing Description"
+(0066,000C) VERS="3"	VR="FL"   VM="1"	Keyword="RecommendedPresentationOpacity"							Name="Recommended Presentation Opacity"
+(0066,000D) VERS="3"	VR="CS"   VM="1"	Keyword="RecommendedPresentationType"								Name="Recommended Presentation Type"
+(0066,000E) VERS="3"	VR="CS"   VM="1"	Keyword="FiniteVolume"												Name="Finite Volume"
+(0066,0010) VERS="3"	VR="CS"   VM="1"	Keyword="Manifold"													Name="Manifold"
+(0066,0011) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfacePointsSequence"										Name="Surface Points Sequence"
+(0066,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfacePointsNormalsSequence"								Name="Surface Points Normals Sequence"
+(0066,0013) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfaceMeshPrimitivesSequence"								Name="Surface Mesh Primitives Sequence"
+(0066,0015) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfSurfacePoints"										Name="Number of Surface Points"
+(0066,0016) VERS="3"	VR="OF"   VM="1"	Keyword="PointCoordinatesData"										Name="Point Coordinates Data"
+(0066,0017) VERS="3"	VR="FL"   VM="3"	Keyword="PointPositionAccuracy"										Name="Point Position Accuracy"
+(0066,0018) VERS="3"	VR="FL"   VM="1"	Keyword="MeanPointDistance"											Name="Mean Point Distance"
+(0066,0019) VERS="3"	VR="FL"   VM="1"	Keyword="MaximumPointDistance"										Name="Maximum Point Distance"
+(0066,001A) VERS="3"	VR="FL"   VM="6"	Keyword="PointsBoundingBoxCoordinates"								Name="Points Bounding Box Coordinates"
+(0066,001B) VERS="3"	VR="FL"   VM="3"	Keyword="AxisOfRotation"											Name="Axis of Rotation"
+(0066,001C) VERS="3"	VR="FL"   VM="3"	Keyword="CenterOfRotation"											Name="Center of Rotation"
+(0066,001E) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfVectors"											Name="Number of Vectors"
+(0066,001F) VERS="3"	VR="US"   VM="1"	Keyword="VectorDimensionality"										Name="Vector Dimensionality"
+(0066,0020) VERS="3"	VR="FL"   VM="1-n"	Keyword="VectorAccuracy"											Name="Vector Accuracy"
+(0066,0021) VERS="3"	VR="OF"   VM="1"	Keyword="VectorCoordinateData"										Name="Vector Coordinate Data"
+(0066,0023) VERS="3"	VR="OW"   VM="1"	Keyword="TrianglePointIndexList"									Name="Triangle Point Index List"
+(0066,0024) VERS="3"	VR="OW"   VM="1"	Keyword="EdgePointIndexList"										Name="Edge Point Index List"
+(0066,0025) VERS="3"	VR="OW"   VM="1"	Keyword="VertexPointIndexList"										Name="Vertex Point Index List"
+(0066,0026) VERS="3"	VR="SQ"   VM="1"	Keyword="TriangleStripSequence"										Name="Triangle Strip Sequence"
+(0066,0027) VERS="3"	VR="SQ"   VM="1"	Keyword="TriangleFanSequence"										Name="Triangle Fan Sequence"
+(0066,0028) VERS="3"	VR="SQ"   VM="1"	Keyword="LineSequence"												Name="Line Sequence"
+(0066,0029) VERS="3"	VR="OW"   VM="1"	Keyword="PrimitivePointIndexList"									Name="Primitive Point Index List"
+(0066,002A) VERS="3"	VR="UL"   VM="1"	Keyword="SurfaceCount"												Name="Surface Count"
+(0066,002B) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSurfaceSequence"									Name="Referenced Surface Sequence"
+(0066,002C) VERS="3"	VR="UL"   VM="1"	Keyword="ReferencedSurfaceNumber"									Name="Referenced Surface Number"
+(0066,002D) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentSurfaceGenerationAlgorithmIdentificationSequence"	Name="Segment Surface Generation Algorithm Identification Sequence"
+(0066,002E) VERS="3"	VR="SQ"   VM="1"	Keyword="SegmentSurfaceSourceInstanceSequence"						Name="Segment Surface Source Instance Sequence"
+(0066,002F) VERS="3"	VR="SQ"   VM="1"	Keyword="AlgorithmFamilyCodeSequence"								Name="Algorithm Family Code Sequence"
+(0066,0030) VERS="3"	VR="SQ"   VM="1"	Keyword="AlgorithmNameCodeSequence"									Name="Algorithm Name Code Sequence"
+(0066,0031) VERS="3"	VR="LO"   VM="1"	Keyword="AlgorithmVersion"											Name="Algorithm Version"
+(0066,0032) VERS="3"	VR="LT"   VM="1"	Keyword="AlgorithmParameters"										Name="Algorithm Parameters"
+(0066,0034) VERS="3"	VR="SQ"   VM="1"	Keyword="FacetSequence"												Name="Facet Sequence"
+(0066,0035) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfaceProcessingAlgorithmIdentificationSequence"			Name="Surface Processing Algorithm Identification Sequence"
+(0066,0036) VERS="3"	VR="LO"   VM="1"	Keyword="AlgorithmName"												Name="Algorithm Name"
+(0066,0037) VERS="3"	VR="FL"   VM="1"	Keyword="RecommendedPointRadius"									Name="Recommended Point Radius"
+(0066,0038) VERS="3"	VR="FL"   VM="1"	Keyword="RecommendedLineThickness"									Name="Recommended Line Thickness"
+(0066,0101) VERS="3"	VR="SQ"   VM="1"	Keyword="TrackSetSequence"											Name="Track Set Sequence"
+(0066,0102) VERS="3"	VR="SQ"   VM="1"	Keyword="TrackSequence"												Name="Track Sequence"
+(0066,0103) VERS="3"	VR="OW"   VM="1"	Keyword="RecommendedDisplayCIELabValueList"							Name="Recommended Display CIELab Value List"
+(0066,0104) VERS="3"	VR="SQ"   VM="1"	Keyword="TrackingAlgorithmIdentificationSequence"					Name="Tracking Algorithm Identification Sequence"
+(0066,0105) VERS="3"	VR="UL"   VM="1"	Keyword="TrackSetNumber"											Name="Track Set Number"
+(0066,0106) VERS="3"	VR="LO"   VM="1"	Keyword="TrackSetLabel"												Name="Track Set Label"
+(0066,0107) VERS="3"	VR="UT"   VM="1"	Keyword="TrackSetDescription"										Name="Track Set Description"
+(0066,0108) VERS="3"	VR="SQ"   VM="1"	Keyword="TrackSetAnatomicalTypeCodeSequence"						Name="Track Set Anatomical Type Code Sequence"
+(0066,0121) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasurementsSequence"										Name="Measurements Sequence"
+(0066,0124) VERS="3"	VR="SQ"   VM="1"	Keyword="TrackSetStatisticsSequence"								Name="Track Set Statistics Sequence"
+(0066,0125) VERS="3"	VR="OF"   VM="1"	Keyword="FloatingPointValues"										Name="Floating Point Values"
+(0066,0129) VERS="3"	VR="OL"   VM="1"	Keyword="TrackPointIndexList"										Name="Track Point Index List"
+(0066,0130) VERS="3"	VR="SQ"   VM="1"	Keyword="TrackStatisticsSequence"									Name="Track Statistics Sequence"
+(0066,0132) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasurementValuesSequence"									Name="Measurement Values Sequence"
+(0066,0133) VERS="3"	VR="SQ"   VM="1"	Keyword="DiffusionAcquisitionCodeSequence"							Name="Diffusion Acquisition Code Sequence"
+(0068,6210) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantSize"												Name="Implant Size"
+(0068,6221) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantTemplateVersion"									Name="Implant Template Version"
+(0068,6222) VERS="3"	VR="SQ"   VM="1"	Keyword="ReplacedImplantTemplateSequence"							Name="Replaced Implant Template Sequence"
+(0068,6223) VERS="3"	VR="CS"   VM="1"	Keyword="ImplantType"												Name="Implant Type"
+(0068,6224) VERS="3"	VR="SQ"   VM="1"	Keyword="DerivationImplantTemplateSequence"							Name="Derivation Implant Template Sequence "
+(0068,6225) VERS="3"	VR="SQ"   VM="1"	Keyword="OriginalImplantTemplateSequence"							Name="Original Implant Template Sequence "
+(0068,6226) VERS="3"	VR="DT"   VM="1"	Keyword="EffectiveDateTime"											Name="Effective DateTime"
+(0068,6230) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTargetAnatomySequence"								Name="Implant Target Anatomy Sequence"
+(0068,6260) VERS="3"	VR="SQ"   VM="1"	Keyword="InformationFromManufacturerSequence"						Name="Information From Manufacturer Sequence"
+(0068,6265) VERS="3"	VR="SQ"   VM="1"	Keyword="NotificationFromManufacturerSequence"						Name="Notification From Manufacturer Sequence"
+(0068,6270) VERS="3"	VR="DT"   VM="1"	Keyword="InformationIssueDateTime"									Name="Information Issue DateTime"
+(0068,6280) VERS="3"	VR="ST"   VM="1"	Keyword="InformationSummary"										Name="Information Summary"
+(0068,62A0) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantRegulatoryDisapprovalCodeSequence"					Name="Implant Regulatory Disapproval Code Sequence"
+(0068,62A5) VERS="3"	VR="FD"   VM="1"	Keyword="OverallTemplateSpatialTolerance"							Name="Overall Template Spatial Tolerance"
+(0068,62C0) VERS="3"	VR="SQ"   VM="1"	Keyword="HPGLDocumentSequence"										Name="HPGL Document Sequence"
+(0068,62D0) VERS="3"	VR="US"   VM="1"	Keyword="HPGLDocumentID"											Name="HPGL Document ID"
+(0068,62D5) VERS="3"	VR="LO"   VM="1"	Keyword="HPGLDocumentLabel"											Name="HPGL Document Label"
+(0068,62E0) VERS="3"	VR="SQ"   VM="1"	Keyword="ViewOrientationCodeSequence"								Name="View Orientation Code Sequence"
+(0068,62F0) VERS="3"	VR="FD"   VM="9"	Keyword="ViewOrientationModifier"									Name="View Orientation Modifier"
+(0068,62F2) VERS="3"	VR="FD"   VM="1"	Keyword="HPGLDocumentScaling"										Name="HPGL Document Scaling"
+(0068,6300) VERS="3"	VR="OB"   VM="1"	Keyword="HPGLDocument"												Name="HPGL Document"
+(0068,6310) VERS="3"	VR="US"   VM="1"	Keyword="HPGLContourPenNumber"										Name="HPGL Contour Pen Number"
+(0068,6320) VERS="3"	VR="SQ"   VM="1"	Keyword="HPGLPenSequence"											Name="HPGL Pen Sequence"
+(0068,6330) VERS="3"	VR="US"   VM="1"	Keyword="HPGLPenNumber"												Name="HPGL Pen Number"
+(0068,6340) VERS="3"	VR="LO"   VM="1"	Keyword="HPGLPenLabel"												Name="HPGL Pen Label"
+(0068,6345) VERS="3"	VR="ST"   VM="1"	Keyword="HPGLPenDescription"										Name="HPGL Pen Description"
+(0068,6346) VERS="3"	VR="FD"   VM="2"	Keyword="RecommendedRotationPoint"									Name="Recommended Rotation Point"
+(0068,6347) VERS="3"	VR="FD"   VM="4"	Keyword="BoundingRectangle"											Name="Bounding Rectangle"
+(0068,6350) VERS="3"	VR="US"   VM="1-n"	Keyword="ImplantTemplate3DModelSurfaceNumber"						Name="Implant Template 3D Model Surface Number"
+(0068,6360) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfaceModelDescriptionSequence"							Name="Surface Model Description Sequence"
+(0068,6380) VERS="3"	VR="LO"   VM="1"	Keyword="SurfaceModelLabel"											Name="Surface Model Label"
+(0068,6390) VERS="3"	VR="FD"   VM="1"	Keyword="SurfaceModelScalingFactor"									Name="Surface Model Scaling Factor"
+(0068,63A0) VERS="3"	VR="SQ"   VM="1"	Keyword="MaterialsCodeSequence"										Name="Materials Code Sequence"
+(0068,63A4) VERS="3"	VR="SQ"   VM="1"	Keyword="CoatingMaterialsCodeSequence"								Name="Coating Materials Code Sequence"
+(0068,63A8) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTypeCodeSequence"									Name="Implant Type Code Sequence"
+(0068,63AC) VERS="3"	VR="SQ"   VM="1"	Keyword="FixationMethodCodeSequence"								Name="Fixation Method Code Sequence"
+(0068,63B0) VERS="3"	VR="SQ"   VM="1"	Keyword="MatingFeatureSetsSequence"									Name="Mating Feature Sets Sequence"
+(0068,63C0) VERS="3"	VR="US"   VM="1"	Keyword="MatingFeatureSetID"										Name="Mating Feature Set ID"
+(0068,63D0) VERS="3"	VR="LO"   VM="1"	Keyword="MatingFeatureSetLabel"										Name="Mating Feature Set Label"
+(0068,63E0) VERS="3"	VR="SQ"   VM="1"	Keyword="MatingFeatureSequence"										Name="Mating Feature Sequence"
+(0068,63F0) VERS="3"	VR="US"   VM="1"	Keyword="MatingFeatureID"											Name="Mating Feature ID"
+(0068,6400) VERS="3"	VR="SQ"   VM="1"	Keyword="MatingFeatureDegreeOfFreedomSequence"						Name="Mating Feature Degree of Freedom Sequence"
+(0068,6410) VERS="3"	VR="US"   VM="1"	Keyword="DegreeOfFreedomID"											Name="Degree of Freedom ID"
+(0068,6420) VERS="3"	VR="CS"   VM="1"	Keyword="DegreeOfFreedomType"										Name="Degree of Freedom Type"
+(0068,6430) VERS="3"	VR="SQ"   VM="1"	Keyword="TwoDMatingFeatureCoordinatesSequence"						Name="2D Mating Feature Coordinates Sequence"
+(0068,6440) VERS="3"	VR="US"   VM="1"	Keyword="ReferencedHPGLDocumentID"									Name="Referenced HPGL Document ID"
+(0068,6450) VERS="3"	VR="FD"   VM="2"	Keyword="TwoDMatingPoint"											Name="2D Mating Point"
+(0068,6460) VERS="3"	VR="FD"   VM="4"	Keyword="TwoDMatingAxes"											Name="2D Mating Axes"
+(0068,6470) VERS="3"	VR="SQ"   VM="1"	Keyword="TwoDDegreeOfFreedomSequence"								Name="2D Degree of Freedom Sequence"
+(0068,6490) VERS="3"	VR="FD"   VM="3"	Keyword="ThreeDDegreeOfFreedomAxis"									Name="3D Degree of Freedom Axis"
+(0068,64A0) VERS="3"	VR="FD"   VM="2"	Keyword="RangeOfFreedom"											Name="Range of Freedom"
+(0068,64C0) VERS="3"	VR="FD"   VM="3"	Keyword="ThreeDMatingPoint"											Name="3D Mating Point"
+(0068,64D0) VERS="3"	VR="FD"   VM="9"	Keyword="ThreeDMatingAxes"											Name="3D Mating Axes"
+(0068,64F0) VERS="3"	VR="FD"   VM="3"	Keyword="TwoDDegreeOfFreedomAxis"									Name="2D Degree of Freedom Axis"
+(0068,6500) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanningLandmarkPointSequence"								Name="Planning Landmark Point Sequence"
+(0068,6510) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanningLandmarkLineSequence"								Name="Planning Landmark Line Sequence"
+(0068,6520) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanningLandmarkPlaneSequence"								Name="Planning Landmark Plane Sequence"
+(0068,6530) VERS="3"	VR="US"   VM="1"	Keyword="PlanningLandmarkID"										Name="Planning Landmark ID"
+(0068,6540) VERS="3"	VR="LO"   VM="1"	Keyword="PlanningLandmarkDescription"								Name="Planning Landmark Description"
+(0068,6545) VERS="3"	VR="SQ"   VM="1"	Keyword="PlanningLandmarkIdentificationCodeSequence"				Name="Planning Landmark Identification Code Sequence"
+(0068,6550) VERS="3"	VR="SQ"   VM="1"	Keyword="TwoDPointCoordinatesSequence"								Name="2D Point Coordinates Sequence"
+(0068,6560) VERS="3"	VR="FD"   VM="2"	Keyword="TwoDPointCoordinates"										Name="2D Point Coordinates"
+(0068,6590) VERS="3"	VR="FD"   VM="3"	Keyword="ThreeDPointCoordinates"									Name="3D Point Coordinates"
+(0068,65A0) VERS="3"	VR="SQ"   VM="1"	Keyword="TwoDLineCoordinatesSequence"								Name="2D Line Coordinates Sequence"
+(0068,65B0) VERS="3"	VR="FD"   VM="4"	Keyword="TwoDLineCoordinates"										Name="2D Line Coordinates"
+(0068,65D0) VERS="3"	VR="FD"   VM="6"	Keyword="ThreeDLineCoordinates"										Name="3D Line Coordinates"
+(0068,65E0) VERS="3"	VR="SQ"   VM="1"	Keyword="TwoDPlaneCoordinatesSequence"								Name="2D Plane Coordinates Sequence"
+(0068,65F0) VERS="3"	VR="FD"   VM="4"	Keyword="TwoDPlaneIntersection"										Name="2D Plane Intersection"
+(0068,6610) VERS="3"	VR="FD"   VM="3"	Keyword="ThreeDPlaneOrigin"											Name="3D Plane Origin"
+(0068,6620) VERS="3"	VR="FD"   VM="3"	Keyword="ThreeDPlaneNormal"											Name="3D Plane Normal"
+(0070,0001) VERS="3"	VR="SQ"   VM="1"	Keyword="GraphicAnnotationSequence"			Name="Graphic Annotation Sequence"
+(0070,0002) VERS="3"	VR="CS"   VM="1"	Keyword="GraphicLayer"					Name="Graphic Layer"
+(0070,0003) VERS="3"	VR="CS"   VM="1"	Keyword="BoundingBoxAnnotationUnits"			Name="Bounding Box Annotation Units"
+(0070,0004) VERS="3"	VR="CS"   VM="1"	Keyword="AnchorPointAnnotationUnits"			Name="Anchor Point Annotation Units"
+(0070,0005) VERS="3"	VR="CS"   VM="1"	Keyword="GraphicAnnotationUnits"			Name="Graphic Annotation Units"
+(0070,0006) VERS="3"	VR="ST"   VM="1"	Keyword="UnformattedTextValue"				Name="Unformatted Text Value"
+(0070,0008) VERS="3"	VR="SQ"   VM="1"	Keyword="TextObjectSequence"				Name="Text Object Sequence"
+(0070,0009) VERS="3"	VR="SQ"   VM="1"	Keyword="GraphicObjectSequence"				Name="Graphic Object Sequence"
+(0070,0010) VERS="3"	VR="FL"   VM="2"	Keyword="BoundingBoxTopLeftHandCorner"				Name="Bounding Box Top Left Hand Corner"
+(0070,0011) VERS="3"	VR="FL"   VM="2"	Keyword="BoundingBoxBottomRightHandCorner"				Name="Bounding Box Bottom Right Hand Corner"
+(0070,0012) VERS="3"	VR="CS"   VM="1"	Keyword="BoundingBoxTextHorizontalJustification"	Name="Bounding Box Text Horizontal Justification"
+(0070,0014) VERS="3"	VR="FL"   VM="2"	Keyword="AnchorPoint"					Name="Anchor Point"
+(0070,0015) VERS="3"	VR="CS"   VM="1"	Keyword="AnchorPointVisibility"				Name="Anchor Point Visibility"
+(0070,0020) VERS="3"	VR="US"   VM="1"	Keyword="GraphicDimensions"				Name="Graphic Dimensions"
+(0070,0021) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfGraphicPoints"				Name="Number of Graphic Points"
+(0070,0022) VERS="3"	VR="FL"   VM="2-n"	Keyword="GraphicData"					Name="Graphic Data"
+(0070,0023) VERS="3"	VR="CS"   VM="1"	Keyword="GraphicType"					Name="Graphic Type"
+(0070,0024) VERS="3"	VR="CS"   VM="1"	Keyword="GraphicFilled"					Name="Graphic Filled"
+(0070,0040) VERS="RET"	VR="IS"   VM="1"	Keyword="ImageRotationRetired"			Name="Image Rotation (Retired)"
+(0070,0041) VERS="3"	VR="CS"   VM="1"	Keyword="ImageHorizontalFlip"				Name="Image Horizontal Flip"
+(0070,0042) VERS="3"	VR="US"   VM="1"	Keyword="ImageRotation"					Name="Image Rotation"
+(0070,0050) VERS="RET"	VR="US"   VM="2"	Keyword="DisplayedAreaTopLeftHandCornerTrial"		Name="Displayed Area Top Left Hand Corner (Trial)"
+(0070,0051) VERS="RET"	VR="US"   VM="2"	Keyword="DisplayedAreaBottomRightHandCornerTrial"		Name="Displayed Area Bottom Right Hand Corner (Trial)"
+(0070,0052) VERS="3"	VR="SL"   VM="2"	Keyword="DisplayedAreaTopLeftHandCorner"				Name="Displayed Area Top Left Hand Corner"
+(0070,0053) VERS="3"	VR="SL"   VM="2"	Keyword="DisplayedAreaBottomRightHandCorner"				Name="Displayed Area Bottom Right Hand Corner"
+(0070,005A) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplayedAreaSelectionSequence"		Name="Displayed Area Selection Sequence"
+(0070,0060) VERS="3"	VR="SQ"   VM="1"	Keyword="GraphicLayerSequence"				Name="Graphic Layer Sequence"
+(0070,0062) VERS="3"	VR="IS"   VM="1"	Keyword="GraphicLayerOrder"				Name="Graphic Layer Order"
+(0070,0066) VERS="3"	VR="US"   VM="1"	Keyword="GraphicLayerRecommendedDisplayGrayscaleValue"	Name="Graphic Layer Recommended Display Grayscale Value"
+(0070,0067) VERS="RET"	VR="US"   VM="3"	Keyword="GraphicLayerRecommendedDisplayRGBValue"	Name="Graphic Layer Recommended Display RGB Value"
+(0070,0068) VERS="3"	VR="LO"   VM="1"	Keyword="GraphicLayerDescription"			Name="Graphic Layer Description"
+(0070,0080) VERS="3"	VR="CS"   VM="1"	Keyword="ContentLabel"					Name="Content Label"
+(0070,0081) VERS="3"	VR="LO"   VM="1"	Keyword="ContentDescription"				Name="Content Description"
+(0070,0082) VERS="3"	VR="DA"   VM="1"	Keyword="PresentationCreationDate"			Name="Presentation Creation Date"
+(0070,0083) VERS="3"	VR="TM"   VM="1"	Keyword="PresentationCreationTime"			Name="Presentation Creation Time"
+(0070,0084) VERS="3"	VR="PN"   VM="1"	Keyword="ContentCreatorName"				Name="Content Creator's Name"
+(0070,0086) VERS="3"	VR="SQ"   VM="1"	Keyword="ContentCreatorIdentificationCodeSequence"				Name="Content Creator's Identification Code Sequence"
+(0070,0087)	 VERS="3"	VR="SQ"   VM="1"	Keyword="AlternateContentDescriptionSequence"	Name="Alternate Content Description Sequence"
+(0070,0100) VERS="3"	VR="CS"   VM="1"	Keyword="PresentationSizeMode"				Name="Presentation Size Mode"
+(0070,0101) VERS="3"	VR="DS"   VM="2"	Keyword="PresentationPixelSpacing"			Name="Presentation Pixel Spacing"
+(0070,0102) VERS="3"	VR="IS"   VM="2"	Keyword="PresentationPixelAspectRatio"			Name="Presentation Pixel Aspect Ratio"
+(0070,0103) VERS="3"	VR="FL"   VM="1"	Keyword="PresentationPixelMagnificationRatio"		Name="Presentation Pixel Magnification Ratio"
+(0070,0207) VERS="3"	VR="LO"   VM="1"	Keyword="GraphicGroupLabel"				Name="Graphic Group Label"
+(0070,0208) VERS="3"	VR="ST"   VM="1"	Keyword="GraphicGroupDescription"		Name="Graphic Group Description"
+(0070,0209) VERS="3"	VR="SQ"   VM="1"	Keyword="CompoundGraphicSequence"		Name="Compound Graphic Sequence"
+(0070,0226) VERS="3"	VR="UL"   VM="1"	Keyword="CompoundGraphicInstanceID"		Name="Compound Graphic Instance ID"
+(0070,0227) VERS="3"	VR="LO"   VM="1"	Keyword="FontName"						Name="Font Name"
+(0070,0228) VERS="3"	VR="CS"   VM="1"	Keyword="FontNameType"					Name="Font Name Type"
+(0070,0229) VERS="3"	VR="LO"   VM="1"	Keyword="CSSFontName"					Name="CSS Font Name"
+(0070,0230) VERS="3"	VR="FD"   VM="1"	Keyword="RotationAngle"					Name="Rotation Angle"
+(0070,0231) VERS="3"	VR="SQ"   VM="1"	Keyword="TextStyleSequence"				Name="Text Style Sequence"
+(0070,0232) VERS="3"	VR="SQ"   VM="1"	Keyword="LineStyleSequence"				Name="Line Style Sequence"
+(0070,0233) VERS="3"	VR="SQ"   VM="1"	Keyword="FillStyleSequence"				Name="Fill Style Sequence"
+(0070,0234) VERS="3"	VR="SQ"   VM="1"	Keyword="GraphicGroupSequence"			Name="Graphic Group Sequence"
+(0070,0241) VERS="3"	VR="US"   VM="3"	Keyword="TextColorCIELabValue"			Name="Text Color CIELab Value"
+(0070,0242) VERS="3"	VR="CS"   VM="1"	Keyword="HorizontalAlignment"			Name="Horizontal Alignment"
+(0070,0243) VERS="3"	VR="CS"   VM="1"	Keyword="VerticalAlignment"				Name="Vertical Alignment"
+(0070,0244) VERS="3"	VR="CS"   VM="1"	Keyword="ShadowStyle"					Name="Shadow Style"
+(0070,0245) VERS="3"	VR="FL"   VM="1"	Keyword="ShadowOffsetX"					Name="Shadow Offset X"
+(0070,0246) VERS="3"	VR="FL"   VM="1"	Keyword="ShadowOffsetY"					Name="Shadow Offset Y"
+(0070,0247) VERS="3"	VR="US"   VM="3"	Keyword="ShadowColorCIELabValue"		Name="Shadow Color CIELab Value"
+(0070,0248) VERS="3"	VR="CS"   VM="1"	Keyword="Underlined"					Name="Underlined"
+(0070,0249) VERS="3"	VR="CS"   VM="1"	Keyword="Bold"							Name="Bold"
+(0070,0250) VERS="3"	VR="CS"   VM="1"	Keyword="Italic"						Name="Italic"
+(0070,0251) VERS="3"	VR="US"   VM="3"	Keyword="PatternOnColorCIELabValue"		Name="Pattern On Color CIELab Value"
+(0070,0252) VERS="3"	VR="US"   VM="3"	Keyword="PatternOffColorCIELabValue"	Name="Pattern Off Color CIELab Value"
+(0070,0253) VERS="3"	VR="FL"   VM="1"	Keyword="LineThickness"					Name="Line Thickness"
+(0070,0254) VERS="3"	VR="CS"   VM="1"	Keyword="LineDashingStyle"				Name="Line Dashing Style"
+(0070,0255) VERS="3"	VR="UL"   VM="1"	Keyword="LinePattern"					Name="Line Pattern"
+(0070,0256) VERS="3"	VR="OB"   VM="1"	Keyword="FillPattern"					Name="Fill Pattern"
+(0070,0257) VERS="3"	VR="CS"   VM="1"	Keyword="FillMode"						Name="Fill Mode"
+(0070,0258) VERS="3"	VR="FL"   VM="1"	Keyword="ShadowOpacity"					Name="Shadow Opacity"
+(0070,0261) VERS="3"	VR="FL"   VM="1"	Keyword="GapLength"						Name="Gap Length"
+(0070,0262) VERS="3"	VR="FL"   VM="1"	Keyword="DiameterOfVisibility"			Name="Diameter of Visibility"
+(0070,0273) VERS="3"	VR="FL"   VM="2"	Keyword="RotationPoint"					Name="Rotation Point"
+(0070,0274) VERS="3"	VR="CS"   VM="1"	Keyword="TickAlignment"					Name="Tick Alignment"
+(0070,0278) VERS="3"	VR="CS"   VM="1"	Keyword="ShowTickLabel"					Name="Show Tick Label"
+(0070,0279) VERS="3"	VR="CS"   VM="1"	Keyword="TickLabelAlignment"			Name="Tick Label Alignment"
+(0070,0282) VERS="3"	VR="CS"   VM="1"	Keyword="CompoundGraphicUnits"			Name="Compound Graphic Units"
+(0070,0284) VERS="3"	VR="FL"   VM="1"	Keyword="PatternOnOpacity"				Name="Pattern On Opacity"
+(0070,0285) VERS="3"	VR="FL"   VM="1"	Keyword="PatternOffOpacity"				Name="Pattern Off Opacity"
+(0070,0287) VERS="3"	VR="SQ"   VM="1"	Keyword="MajorTicksSequence"			Name="Major Ticks Sequence"
+(0070,0288) VERS="3"	VR="FL"   VM="1"	Keyword="TickPosition"					Name="Tick Position"
+(0070,0289) VERS="3"	VR="SH"   VM="1"	Keyword="TickLabel"						Name="Tick Label"
+(0070,0294) VERS="3"	VR="CS"   VM="1"	Keyword="CompoundGraphicType"			Name="Compound Graphic Type"
+(0070,0295) VERS="3"	VR="UL"   VM="1"	Keyword="GraphicGroupID"				Name="Graphic Group ID"
+(0070,0306) VERS="3"	VR="CS"   VM="1"	Keyword="ShapeType"					Name="Shape Type"
+(0070,0308) VERS="3"	VR="SQ"   VM="1"	Keyword="RegistrationSequence"				Name="Registration Sequence"
+(0070,0309) VERS="3"	VR="SQ"   VM="1"	Keyword="MatrixRegistrationSequence"			Name="Matrix Registration Sequence"
+(0070,030A) VERS="3"	VR="SQ"   VM="1"	Keyword="MatrixSequence"				Name="Matrix Sequence"
+(0070,030B) VERS="3"	VR="FD"   VM="16"	Keyword="FrameOfReferenceToDisplayedCoordinateSystemTransformationMatrix"	Name="Frame of Reference to Displayed Coordinate System Transformation Matrix"
+(0070,030C) VERS="3"	VR="CS"   VM="1"	Keyword="FrameOfReferenceTransformationMatrixType"	Name="Frame of Reference Transformation Matrix Type"
+(0070,030D) VERS="3"	VR="SQ"   VM="1"	Keyword="RegistrationTypeCodeSequence"			Name="Registration Type Code Sequence"
+(0070,030F) VERS="3"	VR="ST"   VM="1"	Keyword="FiducialDescription"				Name="Fiducial Description"
+(0070,0310) VERS="3"	VR="SH"   VM="1"	Keyword="FiducialIdentifier"				Name="Fiducial Identifier"
+(0070,0311) VERS="3"	VR="SQ"   VM="1"	Keyword="FiducialIdentifierCodeSequence"		Name="Fiducial Identifier Code Sequence"
+(0070,0312) VERS="3"	VR="FD"   VM="1"	Keyword="ContourUncertaintyRadius"			Name="Contour Uncertainty Radius"
+(0070,0314) VERS="3"	VR="SQ"   VM="1"	Keyword="UsedFiducialsSequence"				Name="Used Fiducials Sequence"
+(0070,0318) VERS="3"	VR="SQ"   VM="1"	Keyword="GraphicCoordinatesDataSequence"		Name="Graphic Coordinates Data Sequence"
+(0070,031A) VERS="3"	VR="UI"   VM="1"	Keyword="FiducialUID"					Name="Fiducial UID"
+(0070,031C) VERS="3"	VR="SQ"   VM="1"	Keyword="FiducialSetSequence"				Name="Fiducial Set Sequence"
+(0070,031E) VERS="3"	VR="SQ"   VM="1"	Keyword="FiducialSequence"				Name="Fiducial Sequence"
+(0070,0401) VERS="3"	VR="US"   VM="3"	Keyword="GraphicLayerRecommendedDisplayCIELabValue"				Name="Graphic Layer Recommended Display CIELab Value"
+(0070,0402) VERS="3"	VR="SQ"   VM="1"	Keyword="BlendingSequence"					Name="Blending Sequence"
+(0070,0403) VERS="3"	VR="FL"   VM="1"	Keyword="RelativeOpacity"					Name="Relative Opacity"
+(0070,0404) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSpatialRegistrationSequence"				Name="Referenced Spatial Registration Sequence"
+(0070,0405) VERS="3"	VR="CS"   VM="1"	Keyword="BlendingPosition"					Name="Blending Position"
+(0070,1101) VERS="3"	VR="UI"   VM="1"	Keyword="PresentationDisplayCollectionUID"				Name="Presentation Display Collection UID"
+(0070,1102) VERS="3"	VR="UI"   VM="1"	Keyword="PresentationSequenceCollectionUID"				Name="Presentation Sequence Collection UID"
+(0070,1103) VERS="3"	VR="US"   VM="1"	Keyword="PresentationSequencePositionIndex"				Name="Presentation Sequence Position Index"
+(0070,1104) VERS="3"	VR="SQ"   VM="1"	Keyword="RenderedImageReferenceSequence"				Name="Rendered Image Reference Sequence"
+(0070,1201) VERS="3"	VR="SQ"   VM="1"	Keyword="VolumetricPresentationStateInputSequence"				Name="Volumetric Presentation State Input Sequence"
+(0070,1202) VERS="3"	VR="CS"   VM="1"	Keyword="PresentationInputType"				Name="Presentation Input Type"
+(0070,1203) VERS="3"	VR="US"   VM="1"	Keyword="InputSequencePositionIndex"				Name="Input Sequence Position Index"
+(0070,1204) VERS="3"	VR="CS"   VM="1"	Keyword="Crop"				Name="Crop"
+(0070,1205) VERS="3"	VR="US"   VM="1-n"	Keyword="CroppingSpecificationIndex"				Name="Cropping Specification Index"
+(0070,1206) VERS="3"	VR="CS"   VM="1"	Keyword="CompositingMethod"				Name="Compositing Method"
+(0070,1207) VERS="3"	VR="US"   VM="1"	Keyword="VolumetricPresentationInputNumber"				Name="Volumetric Presentation Input Number"
+(0070,1208) VERS="3"	VR="CS"   VM="1"	Keyword="ImageVolumeGeometry"				Name="Image Volume Geometry"
+(0070,1301) VERS="3"	VR="SQ"   VM="1"	Keyword="VolumeCroppingSequence"				Name="Volume Cropping Sequence"
+(0070,1302) VERS="3"	VR="CS"   VM="1"	Keyword="VolumeCroppingMethod"				Name="Volume Cropping Method"
+(0070,1303) VERS="3"	VR="FD"   VM="6"	Keyword="BoundingBoxCrop"				Name="Bounding Box Crop"
+(0070,1304) VERS="3"	VR="SQ"   VM="1"	Keyword="ObliqueCroppingPlaneSequence"				Name="Oblique Cropping Plane Sequence"
+(0070,1305) VERS="3"	VR="FD"   VM="4"	Keyword="ObliqueCroppingPlane"				Name="Oblique Cropping Plane"
+(0070,1306) VERS="3"	VR="FD"   VM="3"	Keyword="ObliqueCroppingPlaneNormal"				Name="Oblique Cropping Plane Normal"
+(0070,1309) VERS="3"	VR="US"   VM="1"	Keyword="CroppingSpecificationNumber"				Name="Cropping Specification Number"
+(0070,1501) VERS="3"	VR="CS"   VM="1"	Keyword="MultiPlanarReconstructionStyle"				Name="Multi-Planar Reconstruction Style"
+(0070,1502) VERS="3"	VR="CS"   VM="1"	Keyword="MPRThicknessType"				Name="MPR Thickness Type"
+(0070,1503) VERS="3"	VR="FD"   VM="1"	Keyword="MPRSlabThickness"				Name="MPR Slab Thickness"
+(0070,1505) VERS="3"	VR="FD"   VM="3"	Keyword="MPRTopLeftHandCorner"				Name="MPR Top Left Hand Corner"
+(0070,1507) VERS="3"	VR="FD"   VM="3"	Keyword="MPRViewWidthDirection"				Name="MPR View Width Direction"
+(0070,1508) VERS="3"	VR="FD"   VM="1"	Keyword="MPRViewWidth"				Name="MPR View Width"
+(0070,150C) VERS="3"	VR="UL"   VM="1"	Keyword="NumberOfVolumetricCurvePoints"				Name="Number of Volumetric Curve Points"
+(0070,150D) VERS="3"	VR="OD"   VM="1"	Keyword="VolumetricCurvePoints"				Name="Volumetric Curve Points"
+(0070,1511) VERS="3"	VR="FD"   VM="3"	Keyword="MPRViewHeightDirection"				Name="MPR View Height Direction"
+(0070,1512) VERS="3"	VR="FD"   VM="1"	Keyword="MPRViewHeight"				Name="MPR View Height"
+(0070,1801) VERS="3"	VR="SQ"   VM="1"	Keyword="PresentationStateClassificationComponentSequence"				Name="Presentation State Classification Component Sequence"
+(0070,1802) VERS="3"	VR="CS"   VM="1"	Keyword="ComponentType"				Name="Component Type"
+(0070,1803) VERS="3"	VR="SQ"   VM="1"	Keyword="ComponentInputSequence"				Name="Component Input Sequence"
+(0070,1804) VERS="3"	VR="US"   VM="1"	Keyword="VolumetricPresentationInputIndex"				Name="Volumetric Presentation Input Index"
+(0070,1805) VERS="3"	VR="SQ"   VM="1"	Keyword="PresentationStateCompositorComponentSequence"				Name="Presentation State Compositor Component Sequence"
+(0070,1806) VERS="3"	VR="SQ"   VM="1"	Keyword="WeightingTransferFunctionSequence"				Name="Weighting Transfer Function Sequence"
+(0070,1807) VERS="3"	VR="US"   VM="3"	Keyword="WeightingLookupTableDescriptor"				Name="Weighting Lookup Table Descriptor"
+(0070,1808) VERS="3"	VR="OB"   VM="1"	Keyword="WeightingLookupTableData"				Name="Weighting Lookup Table Data"
+(0070,1901) VERS="3"	VR="SQ"   VM="1"	Keyword="VolumetricAnnotationSequence"				Name="Volumetric Annotation Sequence"
+(0070,1903) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedStructuredContextSequence"				Name="Referenced Structured Context Sequence"
+(0070,1904) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedContentItem"				Name="Referenced Content Item"
+(0070,1905) VERS="3"	VR="SQ"   VM="1"	Keyword="VolumetricPresentationInputAnnotationSequence"				Name="Volumetric Presentation Input Annotation Sequence"
+(0070,1907) VERS="3"	VR="CS"   VM="1"	Keyword="AnnotationClipping"				Name="Annotation Clipping"
+(0070,1A01) VERS="3"	VR="CS"   VM="1"	Keyword="PresentationAnimationStyle"				Name="Presentation Animation Style"
+(0070,1A03) VERS="3"	VR="FD"   VM="1"	Keyword="RecommendedAnimationRate"				Name="Recommended Animation Rate"
+(0070,1A04) VERS="3"	VR="SQ"   VM="1"	Keyword="AnimationCurveSequence"				Name="Animation Curve Sequence"
+(0070,1A05) VERS="3"	VR="FD"   VM="1"	Keyword="AnimationStepSize"				Name="Animation Step Size"
+(0072,0002) VERS="3"	VR="SH"   VM="1"	Keyword="HangingProtocolName"				Name="Hanging Protocol Name"
+(0072,0004) VERS="3"	VR="LO"   VM="1"	Keyword="HangingProtocolDescription"			Name="Hanging Protocol Description"
+(0072,0006) VERS="3"	VR="CS"   VM="1"	Keyword="HangingProtocolLevel"				Name="Hanging Protocol Level"
+(0072,0008) VERS="3"	VR="LO"   VM="1"	Keyword="HangingProtocolCreator"			Name="Hanging Protocol Creator"
+(0072,000A) VERS="3"	VR="DT"   VM="1"	Keyword="HangingProtocolCreationDateTime"		Name="Hanging Protocol Creation DateTime"
+(0072,000C) VERS="3"	VR="SQ"   VM="1"	Keyword="HangingProtocolDefinitionSequence"		Name="Hanging Protocol Definition Sequence"
+(0072,000E) VERS="3"	VR="SQ"   VM="1"	Keyword="HangingProtocolUserIdentificationCodeSequence"	Name="Hanging Protocol User Identification Code Sequence"
+(0072,0010) VERS="3"	VR="LO"   VM="1"	Keyword="HangingProtocolUserGroupName"			Name="Hanging Protocol User Group Name"
+(0072,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceHangingProtocolSequence"			Name="Source Hanging Protocol Sequence"
+(0072,0014) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfPriorsReferenced"			Name="Number of Priors Referenced"
+(0072,0020) VERS="3"	VR="SQ"   VM="1"	Keyword="ImageSetsSequence"				Name="Image Sets Sequence"
+(0072,0022) VERS="3"	VR="SQ"   VM="1"	Keyword="ImageSetSelectorSequence"			Name="Image Set Selector Sequence"
+(0072,0024) VERS="3"	VR="CS"   VM="1"	Keyword="ImageSetSelectorUsageFlag"			Name="Image Set Selector Usage Flag"
+(0072,0026) VERS="3"	VR="AT"   VM="1"	Keyword="SelectorAttribute"				Name="Selector Attribute"
+(0072,0028) VERS="3"	VR="US"   VM="1"	Keyword="SelectorValueNumber"				Name="Selector Value Number"
+(0072,0030) VERS="3"	VR="SQ"   VM="1"	Keyword="TimeBasedImageSetsSequence"			Name="Time Based Image Sets Sequence"
+(0072,0032) VERS="3"	VR="US"   VM="1"	Keyword="ImageSetNumber"				Name="Image Set Number"
+(0072,0034) VERS="3"	VR="CS"   VM="1"	Keyword="ImageSetSelectorCategory"			Name="Image Set Selector Category"
+(0072,0038) VERS="3"	VR="US"   VM="2"	Keyword="RelativeTime"					Name="Relative Time"
+(0072,003A) VERS="3"	VR="CS"   VM="1"	Keyword="RelativeTimeUnits"				Name="Relative Time Units"
+(0072,003C) VERS="3"	VR="SS"   VM="2"	Keyword="AbstractPriorValue"				Name="Abstract Prior Value"
+(0072,003E) VERS="3"	VR="SQ"   VM="1"	Keyword="AbstractPriorCodeSequence"			Name="Abstract Prior Code Sequence"
+(0072,0040) VERS="3"	VR="LO"   VM="1"	Keyword="ImageSetLabel"					Name="Image Set Label"
+(0072,0050) VERS="3"	VR="CS"   VM="1"	Keyword="SelectorAttributeVR"				Name="Selector Attribute VR"
+(0072,0052) VERS="3"	VR="AT"   VM="1-n"	Keyword="SelectorSequencePointer"			Name="Selector Sequence Pointer"
+(0072,0054) VERS="3"	VR="LO"   VM="1-n"	Keyword="SelectorSequencePointerPrivateCreator"		Name="Selector Sequence Pointer Private Creator"
+(0072,0056) VERS="3"	VR="LO"   VM="1"	Keyword="SelectorAttributePrivateCreator"		Name="Selector Attribute Private Creator"
+(0072,0060) VERS="3"	VR="AT"   VM="1-n"	Keyword="SelectorATValue"				Name="Selector AT Value"
+(0072,0062) VERS="3"	VR="CS"   VM="1-n"	Keyword="SelectorCSValue"				Name="Selector CS Value"
+(0072,0064) VERS="3"	VR="IS"   VM="1-n"	Keyword="SelectorISValue"				Name="Selector IS Value"
+(0072,0066) VERS="3"	VR="LO"   VM="1-n"	Keyword="SelectorLOValue"				Name="Selector LO Value"
+(0072,0068) VERS="3"	VR="LT"   VM="1"	Keyword="SelectorLTValue"				Name="Selector LT Value"
+(0072,006A) VERS="3"	VR="PN"   VM="1-n"	Keyword="SelectorPNValue"				Name="Selector PN Value"
+(0072,006C) VERS="3"	VR="SH"   VM="1-n"	Keyword="SelectorSHValue"				Name="Selector SH Value"
+(0072,006E) VERS="3"	VR="ST"   VM="1"	Keyword="SelectorSTValue"				Name="Selector ST Value"
+(0072,0070) VERS="3"	VR="UT"   VM="1"	Keyword="SelectorUTValue"				Name="Selector UT Value"
+(0072,0072) VERS="3"	VR="DS"   VM="1-n"	Keyword="SelectorDSValue"				Name="Selector DS Value"
+(0072,0074) VERS="3"	VR="FD"   VM="1-n"	Keyword="SelectorFDValue"				Name="Selector FD Value"
+(0072,0076) VERS="3"	VR="FL"   VM="1-n"	Keyword="SelectorFLValue"				Name="Selector FL Value"
+(0072,0078) VERS="3"	VR="UL"   VM="1-n"	Keyword="SelectorULValue"				Name="Selector UL Value"
+(0072,007A) VERS="3"	VR="US"   VM="1-n"	Keyword="SelectorUSValue"				Name="Selector US Value"
+(0072,007C) VERS="3"	VR="SL"   VM="1-n"	Keyword="SelectorSLValue"				Name="Selector SL Value"
+(0072,007E) VERS="3"	VR="SS"   VM="1-n"	Keyword="SelectorSSValue"				Name="Selector SS Value"
+(0072,007F) VERS="3"	VR="UI"   VM="1-n"	Keyword="SelectorUIValue"				Name="Selector UI Value"
+(0072,0080) VERS="3"	VR="SQ"   VM="1"	Keyword="SelectorCodeSequenceValue"			Name="Selector Code Sequence Value"
+(0072,0100) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfScreens"				Name="Number of Screens"
+(0072,0102) VERS="3"	VR="SQ"   VM="1"	Keyword="NominalScreenDefinitionSequence"		Name="Nominal Screen Definition Sequence"
+(0072,0104) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfVerticalPixels"			Name="Number of Vertical Pixels"
+(0072,0106) VERS="3"	VR="US"   VM="1"	Keyword="NumberOfHorizontalPixels"			Name="Number of Horizontal Pixels"
+(0072,0108) VERS="3"	VR="FD"   VM="4"	Keyword="DisplayEnvironmentSpatialPosition"		Name="Display Environment Spatial Position"
+(0072,010A) VERS="3"	VR="US"   VM="1"	Keyword="ScreenMinimumGrayscaleBitDepth"		Name="Screen Minimum Grayscale Bit Depth"
+(0072,010C) VERS="3"	VR="US"   VM="1"	Keyword="ScreenMinimumColorBitDepth"			Name="Screen Minimum Color Bit Depth"
+(0072,010E) VERS="3"	VR="US"   VM="1"	Keyword="ApplicationMaximumRepaintTime"			Name="Application Maximum Repaint Time"
+(0072,0200) VERS="3"	VR="SQ"   VM="1"	Keyword="DisplaySetsSequence"				Name="Display Sets Sequence"
+(0072,0202) VERS="3"	VR="US"   VM="1"	Keyword="DisplaySetNumber"				Name="Display Set Number"
+(0072,0203) VERS="3"	VR="LO"   VM="1"	Keyword="DisplaySetLabel"				Name="Display Set Label"
+(0072,0204) VERS="3"	VR="US"   VM="1"	Keyword="DisplaySetPresentationGroup"			Name="Display Set Presentation Group"
+(0072,0206) VERS="3"	VR="LO"   VM="1"	Keyword="DisplaySetPresentationGroupDescription"	Name="Display Set Presentation Group Description"
+(0072,0208) VERS="3"	VR="CS"   VM="1"	Keyword="PartialDataDisplayHandling"			Name="Partial Data Display Handling"
+(0072,0210) VERS="3"	VR="SQ"   VM="1"	Keyword="SynchronizedScrollingSequence"			Name="Synchronized Scrolling Sequence"
+(0072,0212) VERS="3"	VR="US"   VM="2-n"	Keyword="DisplaySetScrollingGroup"			Name="Display Set Scrolling Group"	
+(0072,0214) VERS="3"	VR="SQ"   VM="1"	Keyword="NavigationIndicatorSequence"			Name="Navigation Indicator Sequence"
+(0072,0216) VERS="3"	VR="US"   VM="1"	Keyword="NavigationDisplaySet"				Name="Navigation Display Set"
+(0072,0218) VERS="3"	VR="US"   VM="1-n"	Keyword="ReferenceDisplaySets"				Name="Reference Display Sets"
+(0072,0300) VERS="3"	VR="SQ"   VM="1"	Keyword="ImageBoxesSequence"				Name="Image Boxes Sequence"
+(0072,0302) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxNumber"				Name="Image Box Number"
+(0072,0304) VERS="3"	VR="CS"   VM="1"	Keyword="ImageBoxLayoutType"				Name="Image Box Layout Type"
+(0072,0306) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxTileHorizontalDimension"		Name="Image Box Tile Horizontal Dimension"
+(0072,0308) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxTileVerticalDimension"			Name="Image Box Tile Vertical Dimension"
+(0072,0310) VERS="3"	VR="CS"   VM="1"	Keyword="ImageBoxScrollDirection"			Name="Image Box Scroll Direction"
+(0072,0312) VERS="3"	VR="CS"   VM="1"	Keyword="ImageBoxSmallScrollType"			Name="Image Box Small Scroll Type"
+(0072,0314) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxSmallScrollAmount"			Name="Image Box Small Scroll Amount"
+(0072,0316) VERS="3"	VR="CS"   VM="1"	Keyword="ImageBoxLargeScrollType"			Name="Image Box Large Scroll Type"
+(0072,0318) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxLargeScrollAmount"			Name="Image Box Large Scroll Amount"
+(0072,0320) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxOverlapPriority"			Name="Image Box Overlap Priority"
+(0072,0330) VERS="3"	VR="FD"   VM="1"	Keyword="CineRelativeToRealTime"			Name="Cine Relative to Real-Time"
+(0072,0400) VERS="3"	VR="SQ"   VM="1"	Keyword="FilterOperationsSequence"			Name="Filter Operations Sequence"
+(0072,0402) VERS="3"	VR="CS"   VM="1"	Keyword="FilterByCategory"				Name="Filter-by Category"
+(0072,0404) VERS="3"	VR="CS"   VM="1"	Keyword="FilterByAttributePresence"			Name="Filter-by Attribute Presence"
+(0072,0406) VERS="3"	VR="CS"   VM="1"	Keyword="FilterByOperator"				Name="Filter-by Operator"
+(0072,0420) VERS="3"	VR="US"   VM="3"	Keyword="StructuredDisplayBackgroundCIELabValue"	Name="Structured Display Background CIELab Value"
+(0072,0421) VERS="3"	VR="US"   VM="3"	Keyword="EmptyImageBoxCIELabValue"					Name="Empty Image Box CIELab Value"
+(0072,0422) VERS="3"	VR="SQ"   VM="1"	Keyword="StructuredDisplayImageBoxSequence"			Name="Structured Display Image Box Sequence"
+(0072,0424) VERS="3"	VR="SQ"   VM="1"	Keyword="StructuredDisplayTextBoxSequence"			Name="Structured Display Text Box Sequence"
+(0072,0427) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedFirstFrameSequence"				Name="Referenced First Frame Sequence"
+(0072,0430) VERS="3"	VR="SQ"   VM="1"	Keyword="ImageBoxSynchronizationSequence"			Name="Image Box Synchronization Sequence"
+(0072,0432) VERS="3"	VR="US"   VM="2-n"	Keyword="SynchronizedImageBoxList"					Name="Synchronized Image Box List"
+(0072,0434) VERS="3"	VR="CS"   VM="1"	Keyword="TypeOfSynchronization"						Name="Type of Synchronization"
+(0072,0500) VERS="3"	VR="CS"   VM="1"	Keyword="BlendingOperationType"				Name="Blending Operation Type"
+(0072,0510) VERS="3"	VR="CS"   VM="1"	Keyword="ReformattingOperationType"			Name="Reformatting Operation Type"
+(0072,0512) VERS="3"	VR="FD"   VM="1"	Keyword="ReformattingThickness"				Name="Reformatting Thickness"
+(0072,0514) VERS="3"	VR="FD"   VM="1"	Keyword="ReformattingInterval"				Name="Reformatting Interval"
+(0072,0516) VERS="3"	VR="CS"   VM="1"	Keyword="ReformattingOperationInitialViewDirection"	Name="Reformatting Operation Initial View Direction"
+(0072,0520) VERS="3"	VR="CS"   VM="1-n"	Keyword="ThreeDRenderingType"				Name="3D Rendering Type"
+(0072,0600) VERS="3"	VR="SQ"   VM="1"	Keyword="SortingOperationsSequence"			Name="Sorting Operations Sequence"
+(0072,0602) VERS="3"	VR="CS"   VM="1"	Keyword="SortByCategory"				Name="Sort-by Category"
+(0072,0604) VERS="3"	VR="CS"   VM="1"	Keyword="SortingDirection"				Name="Sorting Direction"
+(0072,0700) VERS="3"	VR="CS"   VM="2"	Keyword="DisplaySetPatientOrientation"			Name="Display Set Patient Orientation"
+(0072,0702) VERS="3"	VR="CS"   VM="1"	Keyword="VOIType"					Name="VOI Type"
+(0072,0704) VERS="3"	VR="CS"   VM="1"	Keyword="PseudoColorType"				Name="Pseudo-Color Type"
+(0072,0705) VERS="3"	VR="SQ"   VM="1"	Keyword="PseudoColorPaletteInstanceReferenceSequence"				Name="Pseudo-Color Palette Instance Reference Sequence"
+(0072,0706) VERS="3"	VR="CS"   VM="1"	Keyword="ShowGrayscaleInverted"				Name="Show Grayscale Inverted"
+(0072,0710) VERS="3"	VR="CS"   VM="1"	Keyword="ShowImageTrueSizeFlag"				Name="Show Image True Size Flag"
+(0072,0712) VERS="3"	VR="CS"   VM="1"	Keyword="ShowGraphicAnnotationFlag"			Name="Show Graphic Annotation Flag"
+(0072,0714) VERS="3"	VR="CS"   VM="1"	Keyword="ShowPatientDemographicsFlag"			Name="Show Patient Demographics Flag"
+(0072,0716) VERS="3"	VR="CS"   VM="1"	Keyword="ShowAcquisitionTechniquesFlag"			Name="Show Acquisition Techniques Flag"
+(0072,0717) VERS="3"	VR="CS"   VM="1"	Keyword="DisplaySetHorizontalJustification"			Name="Display Set Horizontal Justification"
+(0072,0718) VERS="3"	VR="CS"   VM="1"	Keyword="DisplaySetVerticalJustification"			Name="Display Set Vertical Justification"
+(0074,0120) VERS="3"	VR="FD"   VM="1"	Keyword="ContinuationStartMeterset"			Name="Continuation Start Meterset"
+(0074,0121) VERS="3"	VR="FD"   VM="1"	Keyword="ContinuationEndMeterset"			Name="Continuation End Meterset"
+(0074,1000) VERS="3"	VR="CS"   VM="1"	Keyword="ProcedureStepState"										Name="Procedure Step State"
+(0074,1002) VERS="3"	VR="SQ"   VM="1"	Keyword="ProcedureStepProgressInformationSequence"					Name="Procedure Step Progress Information Sequence"
+(0074,1004) VERS="3"	VR="DS"   VM="1"	Keyword="ProcedureStepProgress"										Name="Procedure Step Progress"
+(0074,1006) VERS="3"	VR="ST"   VM="1"	Keyword="ProcedureStepProgressDescription"							Name="Procedure Step Progress Description"
+(0074,1008) VERS="3"	VR="SQ"   VM="1"	Keyword="ProcedureStepCommunicationsURISequence"					Name="Procedure Step Communications URI Sequence"
+(0074,100a) VERS="3"	VR="UR"   VM="1"	Keyword="ContactURI"												Name="Contact URI"
+(0074,100c) VERS="3"	VR="LO"   VM="1"	Keyword="ContactDisplayName"										Name="Contact Display Name"
+(0074,100e) VERS="3"	VR="SQ"   VM="1"	Keyword="ProcedureStepDiscontinuationReasonCodeSequence"			Name="Procedure Step Discontinuation Reason Code Sequence"
+(0074,1020) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamTaskSequence"											Name="Beam Task Sequence"
+(0074,1022) VERS="3"	VR="CS"   VM="1"	Keyword="BeamTaskType"												Name="Beam Task Type"
+(0074,1024) VERS="RET"	VR="IS"   VM="1"	Keyword="BeamOrderIndexTrial"										Name="Beam Order Index (Trial)"
+(0074,1025) VERS="3"	VR="CS"   VM="1"	Keyword="AutosequenceFlag"											Name="Autosequence Flag"
+(0074,1026) VERS="3"	VR="FD"   VM="1"	Keyword="TableTopVerticalAdjustedPosition"							Name="Table Top Vertical Adjusted Position"
+(0074,1027) VERS="3"	VR="FD"   VM="1"	Keyword="TableTopLongitudinalAdjustedPosition"						Name="Table Top Longitudinal Adjusted Position"
+(0074,1028) VERS="3"	VR="FD"   VM="1"	Keyword="TableTopLateralAdjustedPosition"							Name="Table Top Lateral Adjusted Position"
+(0074,102A) VERS="3"	VR="FD"   VM="1"	Keyword="PatientSupportAdjustedAngle"								Name="Patient Support Adjusted Angle"
+(0074,102B) VERS="3"	VR="FD"   VM="1"	Keyword="TableTopEccentricAdjustedAngle"							Name="Table Top Eccentric Adjusted Angle"
+(0074,102C) VERS="3"	VR="FD"   VM="1"	Keyword="TableTopPitchAdjustedAngle"								Name="Table Top Pitch Adjusted Angle"
+(0074,102D) VERS="3"	VR="FD"   VM="1"	Keyword="TableTopRollAdjustedAngle"									Name="Table Top Roll Adjusted Angle"
+(0074,1030) VERS="3"	VR="SQ"   VM="1"	Keyword="DeliveryVerificationImageSequence"							Name="Delivery Verification Image Sequence"
+(0074,1032) VERS="3"	VR="CS"   VM="1"	Keyword="VerificationImageTiming"									Name="Verification Image Timing"
+(0074,1034) VERS="3"	VR="CS"   VM="1"	Keyword="DoubleExposureFlag"										Name="Double Exposure Flag"
+(0074,1036) VERS="3"	VR="CS"   VM="1"	Keyword="DoubleExposureOrdering"									Name="Double Exposure Ordering"
+(0074,1038) VERS="RET"	VR="DS"   VM="1"	Keyword="DoubleExposureMetersetTrial"								Name="Double Exposure Meterset (Trial)"
+(0074,103A) VERS="RET"	VR="DS"   VM="4"	Keyword="DoubleExposureFieldDeltaTrial"								Name="Double Exposure Field Delta (Trial)"
+(0074,1040) VERS="3"	VR="SQ"   VM="1"	Keyword="RelatedReferenceRTImageSequence"							Name="Related Reference RT Image Sequence"
+(0074,1042) VERS="3"	VR="SQ"   VM="1"	Keyword="GeneralMachineVerificationSequence"						Name="General Machine Verification Sequence"
+(0074,1044) VERS="3"	VR="SQ"   VM="1"	Keyword="ConventionalMachineVerificationSequence"					Name="Conventional Machine Verification Sequence"
+(0074,1046) VERS="3"	VR="SQ"   VM="1"	Keyword="IonMachineVerificationSequence"							Name="Ion Machine Verification Sequence"
+(0074,1048) VERS="3"	VR="SQ"   VM="1"	Keyword="FailedAttributesSequence"									Name="Failed Attributes Sequence"
+(0074,104A) VERS="3"	VR="SQ"   VM="1"	Keyword="OverriddenAttributesSequence"								Name="Overridden Attributes Sequence"
+(0074,104C) VERS="3"	VR="SQ"   VM="1"	Keyword="ConventionalControlPointVerificationSequence"				Name="Conventional Control Point Verification Sequence"
+(0074,104E) VERS="3"	VR="SQ"   VM="1"	Keyword="IonControlPointVerificationSequence"						Name="Ion Control Point Verification Sequence"
+(0074,1050) VERS="3"	VR="SQ"   VM="1"	Keyword="AttributeOccurrenceSequence"								Name="Attribute Occurrence Sequence"
+(0074,1052) VERS="3"	VR="AT"   VM="1"	Keyword="AttributeOccurrencePointer"								Name="Attribute Occurrence Pointer"
+(0074,1054) VERS="3"	VR="UL"   VM="1"	Keyword="AttributeItemSelector"										Name="Attribute Item Selector"
+(0074,1056) VERS="3"	VR="LO"   VM="1"	Keyword="AttributeOccurrencePrivateCreator"							Name="Attribute Occurrence Private Creator"
+(0074,1057) VERS="3"	VR="IS"   VM="1-n"	Keyword="SelectorSequencePointerItems"								Name="Selector Sequence Pointer Items"
+(0074,1200) VERS="3"	VR="CS"   VM="1"	Keyword="ScheduledProcedureStepPriority"							Name="Scheduled Procedure Step Priority"
+(0074,1202) VERS="3"	VR="LO"   VM="1"	Keyword="WorklistLabel"												Name="Worklist Label"
+(0074,1204) VERS="3"	VR="LO"   VM="1"	Keyword="ProcedureStepLabel"										Name="Procedure Step Label"
+(0074,1210) VERS="3"	VR="SQ"   VM="1"	Keyword="ScheduledProcessingParametersSequence"						Name="Scheduled Processing Parameters Sequence"
+(0074,1212) VERS="3"	VR="SQ"   VM="1"	Keyword="PerformedProcessingParametersSequence"						Name="Performed Processing Parameters Sequence"
+(0074,1216) VERS="3"	VR="SQ"   VM="1"	Keyword="UnifiedProcedureStepPerformedProcedureSequence"			Name="Unified Procedure Step Performed Procedure Sequence"
+(0074,1220) VERS="3"	VR="SQ"   VM="1"	Keyword="RelatedProcedureStepSequence"								Name="Related Procedure Step Sequence"
+(0074,1222) VERS="3"	VR="LO"   VM="1"	Keyword="ProcedureStepRelationshipType"								Name="Procedure Step Relationship Type"
+(0074,1224) VERS="3"	VR="SQ"   VM="1"	Keyword="ReplacedProcedureStepSequence"								Name="Replaced Procedure Step Sequence"
+(0074,1230) VERS="3"	VR="LO"   VM="1"	Keyword="DeletionLock"												Name="Deletion Lock"
+(0074,1234) VERS="3"	VR="AE"   VM="1"	Keyword="ReceivingAE"												Name="Receiving AE"
+(0074,1236) VERS="3"	VR="AE"   VM="1"	Keyword="RequestingAE"												Name="Requesting AE"
+(0074,1238) VERS="3"	VR="LT"   VM="1"	Keyword="ReasonForCancellation"										Name="Reason for Cancellation"
+(0074,1242) VERS="3"	VR="CS"   VM="1"	Keyword="SCPStatus"													Name="SCP Status"
+(0074,1244) VERS="3"	VR="CS"   VM="1"	Keyword="SubscriptionListStatus"									Name="Subscription List Status"
+(0074,1246) VERS="3"	VR="CS"   VM="1"	Keyword="UnifiedProcedureStepListStatus"							Name="Unified Procedure Step List Status"
+(0074,1324) VERS="3"	VR="UL"   VM="1"	Keyword="BeamOrderIndex"											Name="Beam Order Index"
+(0074,1338) VERS="3"	VR="FD"   VM="1"	Keyword="DoubleExposureMeterset"									Name="Double Exposure Meterset"
+(0074,133A) VERS="3"	VR="FD"   VM="4"	Keyword="DoubleExposureFieldDelta"									Name="Double Exposure Field Delta"
+(0074,1401) VERS="3"	VR="SQ"   VM="1"	Keyword="BrachyTaskSequence"										Name="Brachy Task Sequence"
+(0074,1402) VERS="3"	VR="DS"   VM="1"	Keyword="ContinuationStartTotalReferenceAirKerma"					Name="Continuation Start Total Reference Air Kerma "
+(0074,1403) VERS="3"	VR="DS"   VM="1"	Keyword="ContinuationEndTotalReferenceAirKerma"						Name="Continuation End Total Reference Air Kerma "
+(0074,1404) VERS="3"	VR="IS"   VM="1"	Keyword="ContinuationPulseNumber"									Name="Continuation Pulse Number"
+(0074,1405) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelDeliveryOrderSequence"								Name="Channel Delivery Order Sequence"
+(0074,1406) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedChannelNumber"									Name="Referenced Channel Number"
+(0074,1407) VERS="3"	VR="DS"   VM="1"	Keyword="StartCumulativeTimeWeight"									Name="Start Cumulative Time Weight"
+(0074,1408) VERS="3"	VR="DS"   VM="1"	Keyword="EndCumulativeTimeWeight"									Name="End Cumulative Time Weight"
+(0074,1409) VERS="3"	VR="SQ"   VM="1"	Keyword="OmittedChannelSequence"									Name="Omitted Channel Sequence"
+(0074,140A) VERS="3"	VR="CS"   VM="1"	Keyword="ReasonForChannelOmission"									Name="Reason for Channel Omission"
+(0074,140B) VERS="3"	VR="LO"   VM="1"	Keyword="ReasonForChannelOmissionDescription"						Name="Reason for Channel Omission Description"
+(0074,140C) VERS="3"	VR="IS"   VM="1"	Keyword="ChannelDeliveryOrderIndex"									Name="Channel Delivery Order Index"
+(0074,140D) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelDeliveryContinuationSequence"						Name="Channel Delivery Continuation Sequence"
+(0074,140E) VERS="3"	VR="SQ"   VM="1"	Keyword="OmittedApplicationSetupSequence"							Name="Omitted Application Setup Sequence"
+(0076,0001) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantAssemblyTemplateName"								Name="Implant Assembly Template Name"
+(0076,0003) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantAssemblyTemplateIssuer"								Name="Implant Assembly Template Issuer"
+(0076,0006) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantAssemblyTemplateVersion"							Name="Implant Assembly Template Version"
+(0076,0008) VERS="3"	VR="SQ"   VM="1"	Keyword="ReplacedImplantAssemblyTemplateSequence"					Name="Replaced Implant Assembly Template Sequence "
+(0076,000A) VERS="3"	VR="CS"   VM="1"	Keyword="ImplantAssemblyTemplateType"								Name="Implant Assembly Template Type"
+(0076,000C) VERS="3"	VR="SQ"   VM="1"	Keyword="OriginalImplantAssemblyTemplateSequence"					Name="Original Implant Assembly Template Sequence "
+(0076,000E) VERS="3"	VR="SQ"   VM="1"	Keyword="DerivationImplantAssemblyTemplateSequence"					Name="Derivation Implant Assembly Template Sequence "
+(0076,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantAssemblyTemplateTargetAnatomySequence"				Name="Implant Assembly Template Target Anatomy Sequence"
+(0076,0020) VERS="3"	VR="SQ"   VM="1"	Keyword="ProcedureTypeCodeSequence"									Name="Procedure Type Code Sequence"
+(0076,0030) VERS="3"	VR="LO"   VM="1"	Keyword="SurgicalTechnique"											Name="Surgical Technique "
+(0076,0032) VERS="3"	VR="SQ"   VM="1"	Keyword="ComponentTypesSequence"									Name="Component Types Sequence"
+(0076,0034) VERS="3"	VR="CS"   VM="1"	Keyword="ComponentTypeCodeSequence"									Name="Component Type Code Sequence"
+(0076,0036) VERS="3"	VR="CS"   VM="1"	Keyword="ExclusiveComponentType"									Name="Exclusive Component Type"
+(0076,0038) VERS="3"	VR="CS"   VM="1"	Keyword="MandatoryComponentType"									Name="Mandatory Component Type"
+(0076,0040) VERS="3"	VR="SQ"   VM="1"	Keyword="ComponentSequence"											Name="Component Sequence"
+(0076,0055) VERS="3"	VR="US"   VM="1"	Keyword="ComponentID"												Name="Component ID"
+(0076,0060) VERS="3"	VR="SQ"   VM="1"	Keyword="ComponentAssemblySequence"									Name="Component Assembly Sequence"
+(0076,0070) VERS="3"	VR="US"   VM="1"	Keyword="Component1ReferencedID"									Name="Component 1 Referenced ID"
+(0076,0080) VERS="3"	VR="US"   VM="1"	Keyword="Component1ReferencedMatingFeatureSetID"					Name="Component 1 Referenced Mating Feature Set ID"
+(0076,0090) VERS="3"	VR="US"   VM="1"	Keyword="Component1ReferencedMatingFeatureID"						Name="Component 1 Referenced Mating Feature ID"
+(0076,00A0) VERS="3"	VR="US"   VM="1"	Keyword="Component2ReferencedID"									Name="Component 2 Referenced ID"
+(0076,00B0) VERS="3"	VR="US"   VM="1"	Keyword="Component2ReferencedMatingFeatureSetID"					Name="Component 2 Referenced Mating Feature Set ID"
+(0076,00C0) VERS="3"	VR="US"   VM="1"	Keyword="Component2ReferencedMatingFeatureID"						Name="Component 2 Referenced Mating Feature ID "
+(0078,0001) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantTemplateGroupName"									Name="Implant Template Group Name"
+(0078,0010) VERS="3"	VR="ST"   VM="1"	Keyword="ImplantTemplateGroupDescription"							Name="Implant Template Group Description"
+(0078,0020) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantTemplateGroupIssuer"								Name="Implant Template Group Issuer"
+(0078,0024) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantTemplateGroupVersion"								Name="Implant Template Group Version"
+(0078,0026) VERS="3"	VR="SQ"   VM="1"	Keyword="ReplacedImplantTemplateGroupSequence"						Name="Replaced Implant Template Group Sequence "
+(0078,0028) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTemplateGroupTargetAnatomySequence"					Name="Implant Template Group Target Anatomy Sequence"
+(0078,002A) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTemplateGroupMembersSequence"						Name="Implant Template Group Members Sequence"
+(0078,002E) VERS="3"	VR="US"   VM="1"	Keyword="ImplantTemplateGroupMemberID"								Name="Implant Template Group Member ID"
+(0078,0050) VERS="3"	VR="FD"   VM="3"	Keyword="ThreeDImplantTemplateGroupMemberMatchingPoint"				Name="3D Implant Template Group Member Matching Point"
+(0078,0060) VERS="3"	VR="FD"   VM="9"	Keyword="ThreeDImplantTemplateGroupMemberMatchingAxes"				Name="3D Implant Template Group Member Matching Axes"
+(0078,0070) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTemplateGroupMemberMatching2DCoordinatesSequence"	Name="Implant Template Group Member Matching 2D Coordinates Sequence"
+(0078,0090) VERS="3"	VR="FD"   VM="2"	Keyword="TwoDImplantTemplateGroupMemberMatchingPoint"				Name="2D Implant Template Group Member Matching Point "
+(0078,00A0) VERS="3"	VR="FD"   VM="4"	Keyword="TwoDImplantTemplateGroupMemberMatchingAxes"				Name="2D Implant Template Group Member Matching Axes"
+(0078,00B0) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTemplateGroupVariationDimensionSequence"			Name="Implant Template Group Variation Dimension Sequence"
+(0078,00B2) VERS="3"	VR="LO"   VM="1"	Keyword="ImplantTemplateGroupVariationDimensionName"				Name="Implant Template Group Variation Dimension Name"
+(0078,00B4) VERS="3"	VR="SQ"   VM="1"	Keyword="ImplantTemplateGroupVariationDimensionRankSequence"		Name="Implant Template Group Variation Dimension Rank Sequence"
+(0078,00B6) VERS="3"	VR="US"   VM="1"	Keyword="ReferencedImplantTemplateGroupMemberID"					Name="Referenced Implant Template Group Member ID"
+(0078,00B8) VERS="3"	VR="US"   VM="1"	Keyword="ImplantTemplateGroupVariationDimensionRank"				Name="Implant Template Group Variation Dimension Rank"
+(0080,0001) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfaceScanAcquisitionTypeCodeSequence"					Name="Surface Scan Acquisition Type Code Sequence"
+(0080,0002) VERS="3"	VR="SQ"   VM="1"	Keyword="SurfaceScanModeCodeSequence"								Name="Surface Scan Mode Code Sequence"
+(0080,0003) VERS="3"	VR="SQ"   VM="1"	Keyword="RegistrationMethodCodeSequence"							Name="Registration Method Code Sequence"
+(0080,0004) VERS="3"	VR="FD"   VM="1"	Keyword="ShotDurationTime"											Name="Shot Duration Time"
+(0080,0005) VERS="3"	VR="FD"   VM="1"	Keyword="ShotOffsetTime"											Name="Shot Offset Time"
+(0080,0006) VERS="3"	VR="US"   VM="1-n"	Keyword="SurfacePointPresentationValueData"							Name="Surface Point Presentation Value Data"
+(0080,0007) VERS="3"	VR="US"   VM="3-3n"	Keyword="SurfacePointColorCIELabValueData"							Name="Surface Point Color CIELab Value Data"
+(0080,0008) VERS="3"	VR="SQ"   VM="1"	Keyword="UVMappingSequence"											Name="UV Mapping Sequence"
+(0080,0009) VERS="3"	VR="SH"   VM="1"	Keyword="TextureLabel"												Name="Texture Label"
+(0080,0010) VERS="3"	VR="OF"   VM="1-n"	Keyword="UValueData"												Name="U Value Data"
+(0080,0011) VERS="3"	VR="OF"   VM="1-n"	Keyword="VValueData"												Name="V Value Data"
+(0080,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedTextureSequence"									Name="Referenced Texture Sequence"
+(0080,0013) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSurfaceDataSequence"								Name="Referenced Surface Data Sequence"
+(0088,0130) VERS="3"	VR="SH"   VM="1"	Keyword="StorageMediaFileSetID"			Name="Storage Media File-set ID"
+(0088,0140) VERS="3"	VR="UI"   VM="1"	Keyword="StorageMediaFileSetUID"		Name="Storage Media File-set UID"
+(0088,0200) VERS="3"	VR="SQ"   VM="1"	Keyword="IconImageSequence"			Name="Icon Image Sequence"
+(0088,0904) VERS="RET"	VR="LO"   VM="1"	Keyword="TopicTitle"				Name="Topic Title"
+(0088,0906) VERS="RET"	VR="ST"   VM="1"	Keyword="TopicSubject"				Name="Topic Subject"
+(0088,0910) VERS="RET"	VR="LO"   VM="1"	Keyword="TopicAuthor"				Name="Topic Author"
+(0088,0912) VERS="RET"	VR="LO"   VM="1-32"	Keyword="TopicKeywords"				Name="Topic Keywords"
+(0100,0410) VERS="3"	VR="CS"   VM="1"	Keyword="SOPInstanceStatus"					Name="SOP Instance Status"
+(0100,0420) VERS="3"	VR="DT"   VM="1"	Keyword="SOPAuthorizationDateTime"				Name="SOP Authorization DateTime"
+(0100,0424) VERS="3"	VR="LT"   VM="1"	Keyword="SOPAuthorizationComment"				Name="SOP Authorization Comment"
+(0100,0426) VERS="3"	VR="LO"   VM="1"	Keyword="AuthorizationEquipmentCertificationNumber"		Name="Authorization Equipment Certification Number"
+(0400,0005) VERS="3"	VR="US"   VM="1"	Keyword="MACIDNumber"				Name="MAC ID Number"
+(0400,0010) VERS="3"	VR="UI"   VM="1"	Keyword="MACCalculationTransferSyntaxUID"	Name="MAC Calculation Transfer Syntax UID"
+(0400,0015) VERS="3"	VR="CS"   VM="1"	Keyword="MACAlgorithm"				Name="MAC Algorithm"
+(0400,0020) VERS="3"	VR="AT"   VM="1-n"	Keyword="DataElementsSigned"			Name="Data Elements Signed"
+(0400,0100) VERS="3"	VR="UI"   VM="1"	Keyword="DigitalSignatureUID"			Name="Digital Signature UID"
+(0400,0105) VERS="3"	VR="DT"   VM="1"	Keyword="DigitalSignatureDateTime"		Name="Digital Signature DateTime"
+(0400,0110) VERS="3"	VR="CS"   VM="1"	Keyword="CertificateType"			Name="Certificate Type"
+(0400,0115) VERS="3"	VR="OB"   VM="1"	Keyword="CertificateOfSigner"			Name="Certificate of Signer"
+(0400,0120) VERS="3"	VR="OB"   VM="1"	Keyword="Signature"				Name="Signature"
+(0400,0305) VERS="3"	VR="CS"   VM="1"	Keyword="CertifiedTimestampType"		Name="Certified Timestamp Type"
+(0400,0310) VERS="3"	VR="OB"   VM="1"	Keyword="CertifiedTimestamp"			Name="Certified Timestamp"
+(0400,0401) VERS="3"	VR="SQ"   VM="1"	Keyword="DigitalSignaturePurposeCodeSequence"		Name="Digital Signature Purpose Code Sequence"
+(0400,0402) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedDigitalSignatureSequence"		Name="Referenced Digital Signature Sequence"
+(0400,0403) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSOPInstanceMACSequence"			Name="Referenced SOP Instance MAC Sequence"
+(0400,0404) VERS="3"	VR="OB"   VM="1"	Keyword="MAC"										Name="MAC"
+(0400,0500) VERS="3"	VR="SQ"   VM="1"	Keyword="EncryptedAttributesSequence"		Name="Encrypted Attributes Sequence"
+(0400,0510) VERS="3"	VR="UI"   VM="1"	Keyword="EncryptedContentTransferSyntaxUID"	Name="Encrypted Content Transfer Syntax UID"
+(0400,0520) VERS="3"	VR="OB"   VM="1"	Keyword="EncryptedContent"			Name="Encrypted Content"
+(0400,0550) VERS="3"	VR="SQ"   VM="1"	Keyword="ModifiedAttributesSequence"		Name="Modified Attributes Sequence"
+(0400,0561) VERS="3"	VR="SQ"   VM="1"	Keyword="OriginalAttributesSequence"		Name="Original Attributes Sequence"
+(0400,0562) VERS="3"	VR="DT"   VM="1"	Keyword="AttributeModificationDateTime"		Name="Attribute Modification DateTime"
+(0400,0563) VERS="3"	VR="LO"   VM="1"	Keyword="ModifyingSystem"					Name="Modifying System"
+(0400,0564) VERS="3"	VR="LO"   VM="1"	Keyword="SourceOfPreviousValues"			Name="Source of Previous Values"
+(0400,0565) VERS="3"	VR="CS"   VM="1"	Keyword="ReasonForTheAttributeModification"	Name="Reason for the Attribute Modification"
+(1000,00x0) VERS="RET"	VR="US"   VM="3"	Keyword="EscapeTriplet"				Name="Escape Triplet"
+(1000,00x1) VERS="RET"	VR="US"   VM="3"	Keyword="RunLengthTriplet"			Name="Run Length Triplet"
+(1000,00x2) VERS="RET"	VR="US"   VM="1"	Keyword="HuffmanTableSize"			Name="Huffman Table Size"
+(1000,00x3) VERS="RET"	VR="US"   VM="3"	Keyword="HuffmanTableTriplet"			Name="Huffman Table Triplet"
+(1000,00x4) VERS="RET"	VR="US"   VM="1"	Keyword="ShiftTableSize"			Name="Shift Table Size"
+(1000,00x5) VERS="RET"	VR="US"   VM="3"	Keyword="ShiftTableTriplet"			Name="Shift Table Triplet"
+(1010,xxxx) VERS="RET"	VR="US"   VM="1-n"	Keyword="ZonalMap"				Name="Zonal Map"
+(2000,0010) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfCopies"			Name="Number of Copies"
+(2000,001E) VERS="3"	VR="SQ"   VM="1"	Keyword="PrinterConfigurationSequence"		Name="Printer Configuration Sequence"
+(2000,0020) VERS="3"	VR="CS"   VM="1"	Keyword="PrintPriority"				Name="Print Priority"
+(2000,0030) VERS="3"	VR="CS"   VM="1"	Keyword="MediumType"				Name="Medium Type"
+(2000,0040) VERS="3"	VR="CS"   VM="1"	Keyword="FilmDestination"			Name="Film Destination"
+(2000,0050) VERS="3"	VR="LO"   VM="1"	Keyword="FilmSessionLabel"			Name="Film Session Label"
+(2000,0060) VERS="3"	VR="IS"   VM="1"	Keyword="MemoryAllocation"			Name="Memory Allocation"
+(2000,0061) VERS="3"	VR="IS"   VM="1"	Keyword="MaximumMemoryAllocation"		Name="Maximum Memory Allocation"
+(2000,0062) VERS="RET"	VR="CS"   VM="1"	Keyword="ColorImagePrintingFlag"		Name="Color Image Printing Flag"
+(2000,0063) VERS="RET"	VR="CS"   VM="1"	Keyword="CollationFlag"				Name="Collation Flag"
+(2000,0065) VERS="RET"	VR="CS"   VM="1"	Keyword="AnnotationFlag"			Name="Annotation Flag"
+(2000,0067) VERS="RET"	VR="CS"   VM="1"	Keyword="ImageOverlayFlag"			Name="Image Overlay Flag"
+(2000,0069) VERS="RET"	VR="CS"   VM="1"	Keyword="PresentationLUTFlag"			Name="Presentation LUT Flag"
+(2000,006A) VERS="RET"	VR="CS"   VM="1"	Keyword="ImageBoxPresentationLUTFlag"		Name="Image Box Presentation LUT Flag"
+(2000,00A0) VERS="3"	VR="US"   VM="1"	Keyword="MemoryBitDepth"			Name="Memory Bit Depth"
+(2000,00A1) VERS="3"	VR="US"   VM="1"	Keyword="PrintingBitDepth"			Name="Printing Bit Depth"
+(2000,00A2) VERS="3"	VR="SQ"   VM="1"	Keyword="MediaInstalledSequence"		Name="Media Installed Sequence"
+(2000,00A4) VERS="3"	VR="SQ"   VM="1"	Keyword="OtherMediaAvailableSequence"		Name="Other Media Available Sequence"
+(2000,00A8) VERS="3"	VR="SQ"   VM="1"	Keyword="SupportedImageDisplayFormatsSequence"	Name="Supported Image Display Formats Sequence"
+(2000,0500) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedFilmBoxSequence"		Name="Referenced Film Box Sequence"
+(2000,0510) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedStoredPrintSequence"		Name="Referenced Stored Print Sequence"
+(2010,0010) VERS="3"	VR="ST"   VM="1"	Keyword="ImageDisplayFormat"			Name="Image Display Format"
+(2010,0030) VERS="3"	VR="CS"   VM="1"	Keyword="AnnotationDisplayFormatID"		Name="Annotation Display Format ID"
+(2010,0040) VERS="3"	VR="CS"   VM="1"	Keyword="FilmOrientation"			Name="Film Orientation"
+(2010,0050) VERS="3"	VR="CS"   VM="1"	Keyword="FilmSizeID"				Name="Film Size ID"
+(2010,0052) VERS="3"	VR="CS"   VM="1"	Keyword="PrinterResolutionID"			Name="Printer Resolution ID"
+(2010,0054) VERS="3"	VR="CS"   VM="1"	Keyword="DefaultPrinterResolutionID"		Name="Default Printer Resolution ID"
+(2010,0060) VERS="3"	VR="CS"   VM="1"	Keyword="MagnificationType"			Name="Magnification Type"
+(2010,0080) VERS="3"	VR="CS"   VM="1"	Keyword="SmoothingType"				Name="Smoothing Type"
+(2010,00A6) VERS="3"	VR="CS"   VM="1"	Keyword="DefaultMagnificationType"		Name="Default Magnification Type"
+(2010,00A7) VERS="3"	VR="CS"   VM="1-n"	Keyword="OtherMagnificationTypesAvailable"	Name="Other Magnification Types Available"
+(2010,00A8) VERS="3"	VR="CS"   VM="1"	Keyword="DefaultSmoothingType"			Name="Default Smoothing Type"
+(2010,00A9) VERS="3"	VR="CS"   VM="1-n"	Keyword="OtherSmoothingTypesAvailable"		Name="Other Smoothing Types Available"
+(2010,0100) VERS="3"	VR="CS"   VM="1"	Keyword="BorderDensity"				Name="Border Density"
+(2010,0110) VERS="3"	VR="CS"   VM="1"	Keyword="EmptyImageDensity"			Name="Empty Image Density"
+(2010,0120) VERS="3"	VR="US"   VM="1"	Keyword="MinDensity"				Name="Min Density"
+(2010,0130) VERS="3"	VR="US"   VM="1"	Keyword="MaxDensity"				Name="Max Density"
+(2010,0140) VERS="3"	VR="CS"   VM="1"	Keyword="Trim"					Name="Trim"
+(2010,0150) VERS="3"	VR="ST"   VM="1"	Keyword="ConfigurationInformation"		Name="Configuration Information"
+(2010,0152) VERS="3"	VR="LT"   VM="1"	Keyword="ConfigurationInformationDescription"	Name="Configuration Information Description"
+(2010,0154) VERS="3"	VR="IS"   VM="1"	Keyword="MaximumCollatedFilms"			Name="Maximum Collated Films"
+(2010,015E) VERS="3"	VR="US"   VM="1"	Keyword="Illumination"				Name="Illumination"
+(2010,0160) VERS="3"	VR="US"   VM="1"	Keyword="ReflectedAmbientLight"			Name="Reflected Ambient Light"
+(2010,0376) VERS="3"	VR="DS"   VM="2"	Keyword="PrinterPixelSpacing"			Name="Printer Pixel Spacing"
+(2010,0500) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedFilmSessionSequence"		Name="Referenced Film Session Sequence"
+(2010,0510) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedImageBoxSequence"		Name="Referenced Image Box Sequence"
+(2010,0520) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedBasicAnnotationBoxSequence"	Name="Referenced Basic Annotation Box Sequence"
+(2020,0010) VERS="3"	VR="US"   VM="1"	Keyword="ImageBoxPosition"			Name="Image Box Position"
+(2020,0020) VERS="3"	VR="CS"   VM="1"	Keyword="Polarity"				Name="Polarity"
+(2020,0030) VERS="3"	VR="DS"   VM="1"	Keyword="RequestedImageSize"			Name="Requested Image Size"
+(2020,0040) VERS="3"	VR="CS"   VM="1"	Keyword="RequestedDecimateCropBehavior"		Name="Requested Decimate/Crop Behavior"
+(2020,0050) VERS="3"	VR="CS"   VM="1"	Keyword="RequestedResolutionID"			Name="Requested Resolution ID"
+(2020,00A0) VERS="3"	VR="CS"   VM="1"	Keyword="RequestedImageSizeFlag"		Name="Requested Image Size Flag"
+(2020,00A2) VERS="3"	VR="CS"   VM="1"	Keyword="DecimateCropResult"			Name="Decimate/Crop Result"
+(2020,0110) VERS="3"	VR="SQ"   VM="1"	Keyword="BasicGrayscaleImageSequence"		Name="Basic Grayscale Image Sequence"
+(2020,0111) VERS="3"	VR="SQ"   VM="1"	Keyword="BasicColorImageSequence"		Name="Basic Color Image Sequence"
+(2020,0130) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedImageOverlayBoxSequence"	Name="Referenced Image Overlay Box Sequence"
+(2020,0140) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedVOILUTBoxSequence"		Name="Referenced VOI LUT Box Sequence"
+(2030,0010) VERS="3"	VR="US"   VM="1"	Keyword="AnnotationPosition"			Name="Annotation Position"
+(2030,0020) VERS="3"	VR="LO"   VM="1"	Keyword="TextString"				Name="Text String"
+(2040,0010) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedOverlayPlaneSequence"	Name="Referenced Overlay Plane Sequence"
+(2040,0011) VERS="RET"	VR="US"   VM="1-99"	Keyword="ReferencedOverlayPlaneGroups"		Name="Referenced Overlay Plane Groups"
+(2040,0020) VERS="RET"	VR="SQ"   VM="1"	Keyword="OverlayPixelDataSequence"		Name="Overlay Pixel Data Sequence"
+(2040,0060) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlayMagnificationType"		Name="Overlay Magnification Type"
+(2040,0070) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlaySmoothingType"			Name="Overlay Smoothing Type"
+(2040,0072) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlayOrImageMagnification"		Name="Overlay or Image Magnification"
+(2040,0074) VERS="RET"	VR="US"   VM="1"	Keyword="MagnifyToNumberOfColumns"		Name="Magnify to Number of Columns"
+(2040,0080) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlayForegroundDensity"		Name="Overlay Foreground Density"
+(2040,0082) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlayBackgroundDensity"		Name="Overlay Background Density"
+(2040,0090) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlayMode"				Name="Overlay Mode"
+(2040,0100) VERS="RET"	VR="CS"   VM="1"	Keyword="ThresholdDensity"			Name="Threshold Density"
+(2040,0500) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedImageBoxSequenceRetired"	Name="Referenced Image Box Sequence (Retired)"
+(2050,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="PresentationLUTSequence"		Name="Presentation LUT Sequence"
+(2050,0020) VERS="3"	VR="CS"   VM="1"	Keyword="PresentationLUTShape"			Name="Presentation LUT Shape"
+(2050,0500) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedPresentationLUTSequence"	Name="Referenced Presentation LUT Sequence"
+(2100,0010) VERS="RET"	VR="SH"   VM="1"	Keyword="PrintJobID"				Name="Print Job ID"
+(2100,0020) VERS="3"	VR="CS"   VM="1"	Keyword="ExecutionStatus"			Name="Execution Status"
+(2100,0030) VERS="3"	VR="CS"   VM="1"	Keyword="ExecutionStatusInfo"			Name="Execution Status Info"
+(2100,0040) VERS="3"	VR="DA"   VM="1"	Keyword="CreationDate"				Name="Creation Date"
+(2100,0050) VERS="3"	VR="TM"   VM="1"	Keyword="CreationTime"				Name="Creation Time"
+(2100,0070) VERS="3"	VR="AE"   VM="1"	Keyword="Originator"				Name="Originator"
+(2100,0140) VERS="RET"	VR="AE"   VM="1"	Keyword="DestinationAE"				Name="Destination AE"
+(2100,0160) VERS="3"	VR="SH"   VM="1"	Keyword="OwnerID"				Name="OwnerID"
+(2100,0170) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfFilms"				Name="Number of Films"
+(2100,0500) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedPrintJobSequencePullStoredPrint"	Name="Referenced Print Job Sequence (Pull Stored Print)"
+(2110,0010) VERS="3"	VR="CS"   VM="1"	Keyword="PrinterStatus"				Name="Printer Status"
+(2110,0020) VERS="3"	VR="CS"   VM="1"	Keyword="PrinterStatusInfo"			Name="Printer Status Info"
+(2110,0030) VERS="3"	VR="LO"   VM="1"	Keyword="PrinterName"				Name="Printer Name"
+(2110,0099) VERS="RET"	VR="SH"   VM="1"	Keyword="PrintQueueID"				Name="Print Queue ID"
+(2120,0010) VERS="RET"	VR="CS"   VM="1"	Keyword="QueueStatus"				Name="Queue Status"
+(2120,0050) VERS="RET"	VR="SQ"   VM="1"	Keyword="PrintJobDescriptionSequence"		Name="Print Job Description Sequence"
+(2120,0070) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedPrintJobSequence"	Name="Referenced Print Job Sequence"
+(2130,0010) VERS="RET"	VR="SQ"   VM="1"	Keyword="PrintManagementCapabilitiesSequence"	Name="Print Management Capabilities Sequence"
+(2130,0015) VERS="RET"	VR="SQ"   VM="1"	Keyword="PrinterCharacteristicsSequence"	Name="Printer Characteristics Sequence"
+(2130,0030) VERS="RET"	VR="SQ"   VM="1"	Keyword="FilmBoxContentSequence"		Name="Film Box Content Sequence"
+(2130,0040) VERS="RET"	VR="SQ"   VM="1"	Keyword="ImageBoxContentSequence"		Name="Image Box Content Sequence"
+(2130,0050) VERS="RET"	VR="SQ"   VM="1"	Keyword="AnnotationContentSequence"		Name="Annotation Content Sequence"
+(2130,0060) VERS="RET"	VR="SQ"   VM="1"	Keyword="ImageOverlayBoxContentSequence"	Name="Image Overlay Box Content Sequence"
+(2130,0080) VERS="RET"	VR="SQ"   VM="1"	Keyword="PresentationLUTContentSequence"	Name="Presentation LUT Content Sequence"
+(2130,00A0) VERS="RET"	VR="SQ"   VM="1"	Keyword="ProposedStudySequence"			Name="Proposed Study Sequence"
+(2130,00C0) VERS="RET"	VR="SQ"   VM="1"	Keyword="OriginalImageSequence"			Name="Original Image Sequence"
+(2200,0001)	VERS="3"	VR="CS"   VM="1"	Keyword="LabelUsingInformationExtractedFromInstances"			Name="Label Using Information Extracted From Instances"
+(2200,0002)	VERS="3"	VR="UT"   VM="1"	Keyword="LabelText"			Name="Label Text"
+(2200,0003)	VERS="3"	VR="CS"   VM="1"	Keyword="LabelStyleSelection"			Name="Label Style Selection"
+(2200,0004)	VERS="3"	VR="LT"   VM="1"	Keyword="MediaDisposition"			Name="Media Disposition"
+(2200,0005)	VERS="3"	VR="LT"   VM="1"	Keyword="BarcodeValue"			Name="Barcode Value"
+(2200,0006)	VERS="3"	VR="CS"   VM="1"	Keyword="BarcodeSymbology"			Name="Barcode Symbology"
+(2200,0007)	VERS="3"	VR="CS"   VM="1"	Keyword="AllowMediaSplitting"			Name="Allow Media Splitting"
+(2200,0008)	VERS="3"	VR="CS"   VM="1"	Keyword="IncludeNonDICOMObjects"			Name="Include Non-DICOM Objects"
+(2200,0009)	VERS="3"	VR="CS"   VM="1"	Keyword="IncludeDisplayApplication"			Name="Include Display Application"
+(2200,000A)	VERS="3"	VR="CS"   VM="1"	Keyword="PreserveCompositeInstancesAfterMediaCreation"			Name="Preserve Composite Instances After Media Creation"
+(2200,000B)	VERS="3"	VR="US"   VM="1"	Keyword="TotalNumberOfPiecesOfMediaCreated"			Name="Total Number of Pieces of Media Created"
+(2200,000C)	VERS="3"	VR="LO"   VM="1"	Keyword="RequestedMediaApplicationProfile"			Name="Requested Media Application Profile"
+(2200,000D)	VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedStorageMediaSequence"			Name="Referenced Storage Media Sequence"
+(2200,000E)	VERS="3"	VR="AT"   VM="1-n"	Keyword="FailureAttributes"			Name="Failure Attributes"
+(2200,000F)	VERS="3"	VR="CS"   VM="1"	Keyword="AllowLossyCompression"			Name="Allow Lossy Compression"
+(2200,0020)	VERS="3"	VR="CS"   VM="1"	Keyword="RequestPriority"			Name="Request Priority"
+(3002,0002) VERS="3"	VR="SH"   VM="1"	Keyword="RTImageLabel"				Name="RT Image Label"
+(3002,0003) VERS="3"	VR="LO"   VM="1"	Keyword="RTImageName"				Name="RT Image Name"
+(3002,0004) VERS="3"	VR="ST"   VM="1"	Keyword="RTImageDescription"			Name="RT Image Description"
+(3002,000A) VERS="3"	VR="CS"   VM="1"	Keyword="ReportedValuesOrigin"			Name="Reported Values Origin"
+(3002,000C) VERS="3"	VR="CS"   VM="1"	Keyword="RTImagePlane"				Name="RT Image Plane"
+(3002,000D) VERS="3"	VR="DS"   VM="3"	Keyword="XRayImageReceptorTranslation"		Name="X-Ray Image Receptor Translation"
+(3002,000E) VERS="3"	VR="DS"   VM="1"	Keyword="XRayImageReceptorAngle"		Name="X-Ray Image Receptor Angle"
+(3002,0010) VERS="3"	VR="DS"   VM="6"	Keyword="RTImageOrientation"			Name="RTImageOrientation"
+(3002,0011) VERS="3"	VR="DS"   VM="2"	Keyword="ImagePlanePixelSpacing"		Name="Image Plane Pixel Spacing"
+(3002,0012) VERS="3"	VR="DS"   VM="2"	Keyword="RTImagePosition"			Name="RT Image Position"
+(3002,0020) VERS="3"	VR="SH"   VM="1"	Keyword="RadiationMachineName"			Name="Radiation Machine Name"
+(3002,0022) VERS="3"	VR="DS"   VM="1"	Keyword="RadiationMachineSAD"			Name="Radiation Machine SAD"
+(3002,0024) VERS="3"	VR="DS"   VM="1"	Keyword="RadiationMachineSSD"			Name="Radiation Machine SSD"
+(3002,0026) VERS="3"	VR="DS"   VM="1"	Keyword="RTImageSID"				Name="RT Image SID"
+(3002,0028) VERS="3"	VR="DS"   VM="1"	Keyword="SourceToReferenceObjectDistance"	Name="Source to Reference Object Distance"
+(3002,0029) VERS="3"	VR="IS"   VM="1"	Keyword="FractionNumber"			Name="Fraction Number"
+(3002,0030) VERS="3"	VR="SQ"   VM="1"	Keyword="ExposureSequence"			Name="Exposure Sequence"
+(3002,0032) VERS="3"	VR="DS"   VM="1"	Keyword="MetersetExposure"			Name="Meterset Exposure"
+(3002,0034) VERS="3"	VR="DS"   VM="4"	Keyword="DiaphragmPosition"			Name="Diaphragm Position"
+(3002,0040) VERS="3"	VR="SQ"   VM="1"	Keyword="FluenceMapSequence"			Name="Fluence Map Sequence"
+(3002,0041) VERS="3"	VR="CS"   VM="1"	Keyword="FluenceDataSource"			Name="Fluence Data Source"
+(3002,0042) VERS="3"	VR="DS"   VM="1"	Keyword="FluenceDataScale"			Name="Fluence Data Scale"
+(3002,0050) VERS="3"	VR="SQ"   VM="1"	Keyword="PrimaryFluenceModeSequence"	Name="Primary Fluence Mode Sequence"
+(3002,0051) VERS="3"	VR="CS"   VM="1"	Keyword="FluenceMode"					Name="Fluence Mode"
+(3002,0052) VERS="3"	VR="SH"   VM="1"	Keyword="FluenceModeID"					Name="Fluence Mode ID"
+(3004,0001) VERS="3"	VR="CS"   VM="1"	Keyword="DVHType"				Name="DVH Type"
+(3004,0002) VERS="3"	VR="CS"   VM="1"	Keyword="DoseUnits"				Name="Dose Units"
+(3004,0004) VERS="3"	VR="CS"   VM="1"	Keyword="DoseType"				Name="Dose Type"
+(3004,0005) VERS="3"	VR="CS"   VM="1"	Keyword="SpatialTransformOfDose"	Name="Spatial Transform of Dose"
+(3004,0006) VERS="3"	VR="LO"   VM="1"	Keyword="DoseComment"				Name="Dose Comment"
+(3004,0008) VERS="3"	VR="DS"   VM="3"	Keyword="NormalizationPoint"			Name="Normalization Point"
+(3004,000A) VERS="3"	VR="CS"   VM="1"	Keyword="DoseSummationType"			Name="Dose Summation Type"
+(3004,000C) VERS="3"	VR="DS"   VM="2-n"	Keyword="GridFrameOffsetVector"			Name="GridFrame Offset Vector"
+(3004,000E) VERS="3"	VR="DS"   VM="1"	Keyword="DoseGridScaling"			Name="Dose Grid Scaling"
+(3004,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="RTDoseROISequence"			Name="RT Dose ROI Sequence"
+(3004,0012) VERS="3"	VR="DS"   VM="1"	Keyword="DoseValue"				Name="Dose Value"
+(3004,0014) VERS="3"	VR="CS"   VM="1-3"	Keyword="TissueHeterogeneityCorrection"		Name="Tissue Heterogeneity Correction"
+(3004,0040) VERS="3"	VR="DS"   VM="3"	Keyword="DVHNormalizationPoint"			Name="DVH Normalization Point"
+(3004,0042) VERS="3"	VR="DS"   VM="1"	Keyword="DVHNormalizationDoseValue"		Name="DVH Normalization Dose Value"
+(3004,0050) VERS="3"	VR="SQ"   VM="1"	Keyword="DVHSequence"				Name="DVH Sequence"
+(3004,0052) VERS="3"	VR="DS"   VM="1"	Keyword="DVHDoseScaling"			Name="DVH Dose Scaling"
+(3004,0054) VERS="3"	VR="CS"   VM="1"	Keyword="DVHVolumeUnits"			Name="DVH Volume Units"
+(3004,0056) VERS="3"	VR="IS"   VM="1"	Keyword="DVHNumberOfBins"			Name="DVH Number of Bins"
+(3004,0058) VERS="3"	VR="DS"   VM="2-2n"	Keyword="DVHData"				Name="DVH Data"
+(3004,0060) VERS="3"	VR="SQ"   VM="1"	Keyword="DVHReferencedROISequence"		Name="DVH Referenced ROI Sequence"
+(3004,0062) VERS="3"	VR="CS"   VM="1"	Keyword="DVHROIContributionType"		Name="DVH ROI Contribution Type"
+(3004,0070) VERS="3"	VR="DS"   VM="1"	Keyword="DVHMinimumDose"			Name="DVH Minimum Dose"
+(3004,0072) VERS="3"	VR="DS"   VM="1"	Keyword="DVHMaximumDose"			Name="DVH Maximum Dose"
+(3004,0074) VERS="3"	VR="DS"   VM="1"	Keyword="DVHMeanDose"				Name="DVH Mean Dose"
+(3006,0002) VERS="3"	VR="SH"   VM="1"	Keyword="StructureSetLabel"			Name="Structure Set Label"
+(3006,0004) VERS="3"	VR="LO"   VM="1"	Keyword="StructureSetName"			Name="Structure Set Name"
+(3006,0006) VERS="3"	VR="ST"   VM="1"	Keyword="StructureSetDescription"		Name="Structure Set Description"
+(3006,0008) VERS="3"	VR="DA"   VM="1"	Keyword="StructureSetDate"			Name="Structure Set Date"
+(3006,0009) VERS="3"	VR="TM"   VM="1"	Keyword="StructureSetTime"			Name="Structure Set Time"
+(3006,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedFrameOfReferenceSequence"	Name="Referenced Frame of Reference Sequence"
+(3006,0012) VERS="3"	VR="SQ"   VM="1"	Keyword="RTReferencedStudySequence"		Name="RT Referenced Study Sequence"
+(3006,0014) VERS="3"	VR="SQ"   VM="1"	Keyword="RTReferencedSeriesSequence"		Name="RT Referenced Series Sequence"
+(3006,0016) VERS="3"	VR="SQ"   VM="1"	Keyword="ContourImageSequence"			Name="Contour Image Sequence"
+(3006,0018) VERS="3"	VR="SQ"   VM="1"	Keyword="PredecessorStructureSetSequence"	Name="Predecessor Structure Set Sequence"
+(3006,0020) VERS="3"	VR="SQ"   VM="1"	Keyword="StructureSetROISequence"		Name="Structure Set ROI Sequence"
+(3006,0022) VERS="3"	VR="IS"   VM="1"	Keyword="ROINumber"				Name="ROI Number"
+(3006,0024) VERS="3"	VR="UI"   VM="1"	Keyword="ReferencedFrameOfReferenceUID"		Name="Referenced Frame of Reference UID"
+(3006,0026) VERS="3"	VR="LO"   VM="1"	Keyword="ROIName"				Name="ROI Name"
+(3006,0028) VERS="3"	VR="ST"   VM="1"	Keyword="ROIDescription"			Name="ROI Description"
+(3006,002A) VERS="3"	VR="IS"   VM="3"	Keyword="ROIDisplayColor"			Name="ROI Display Color"
+(3006,002C) VERS="3"	VR="DS"   VM="1"	Keyword="ROIVolume"				Name="ROI Volume"
+(3006,0030) VERS="3"	VR="SQ"   VM="1"	Keyword="RTRelatedROISequence"			Name="RT Related ROI Sequence"
+(3006,0033) VERS="3"	VR="CS"   VM="1"	Keyword="RTROIRelationship"			Name="RT ROI Relationship"
+(3006,0036) VERS="3"	VR="CS"   VM="1"	Keyword="ROIGenerationAlgorithm"		Name="ROI Generation Algorithm"
+(3006,0038) VERS="3"	VR="LO"   VM="1"	Keyword="ROIGenerationDescription"		Name="ROI Generation Description"
+(3006,0039) VERS="3"	VR="SQ"   VM="1"	Keyword="ROIContourSequence"			Name="ROI Contour Sequence"
+(3006,0040) VERS="3"	VR="SQ"   VM="1"	Keyword="ContourSequence"			Name="Contour Sequence"
+(3006,0042) VERS="3"	VR="CS"   VM="1"	Keyword="ContourGeometricType"			Name="Contour Geometric Type"
+(3006,0044) VERS="3"	VR="DS"   VM="1"	Keyword="ContourSlabThickness"			Name="Contour SlabT hickness"
+(3006,0045) VERS="3"	VR="DS"   VM="3"	Keyword="ContourOffsetVector"			Name="Contour Offset Vector"
+(3006,0046) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfContourPoints"			Name="Number of Contour Points"
+(3006,0048) VERS="3"	VR="IS"   VM="1"	Keyword="ContourNumber"				Name="Contour Number"
+(3006,0049) VERS="3"	VR="IS"   VM="1-n"	Keyword="AttachedContours"			Name="Attached Contours"
+(3006,0050) VERS="3"	VR="DS"   VM="3-3n"	Keyword="ContourData"				Name="Contour Data"
+(3006,0080) VERS="3"	VR="SQ"   VM="1"	Keyword="RTROIObservationsSequence"		Name="RT ROI Observations Sequence"
+(3006,0082) VERS="3"	VR="IS"   VM="1"	Keyword="ObservationNumber"			Name="Observation Number"
+(3006,0084) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedROINumber"			Name="Referenced ROI Number"
+(3006,0085) VERS="3"	VR="SH"   VM="1"	Keyword="ROIObservationLabel"			Name="ROI Observation Label"
+(3006,0086) VERS="3"	VR="SQ"   VM="1"	Keyword="RTROIIdentificationCodeSequence"	Name="RT ROI Identification Code Sequence"
+(3006,0088) VERS="3"	VR="ST"   VM="1"	Keyword="ROIObservationDescription"		Name="ROI Observation Description"
+(3006,00A0) VERS="3"	VR="SQ"   VM="1"	Keyword="RelatedRTROIObservationsSequence"	Name="Related RT ROI Observations Sequence"
+(3006,00A4) VERS="3"	VR="CS"   VM="1"	Keyword="RTROIInterpretedType"			Name="RT ROI Interpreted Type"
+(3006,00A6) VERS="3"	VR="PN"   VM="1"	Keyword="ROIInterpreter"			Name="ROI Interpreter"
+(3006,00B0) VERS="3"	VR="SQ"   VM="1"	Keyword="ROIPhysicalPropertiesSequence"		Name="ROI Physical Properties Sequence"
+(3006,00B2) VERS="3"	VR="CS"   VM="1"	Keyword="ROIPhysicalProperty"			Name="ROI Physical Property"
+(3006,00B4) VERS="3"	VR="DS"   VM="1"	Keyword="ROIPhysicalPropertyValue"		Name="ROI Physical Property Value"
+(3006,00B6) VERS="3"	VR="SQ"   VM="1"	Keyword="ROIElementalCompositionSequence"				Name="ROI Elemental Composition Sequence"
+(3006,00B7) VERS="3"	VR="US"   VM="1"	Keyword="ROIElementalCompositionAtomicNumber"			Name="ROI Elemental Composition Atomic Number"
+(3006,00B8) VERS="3"	VR="FL"   VM="1"	Keyword="ROIElementalCompositionAtomicMassFraction"		Name="ROI Elemental Composition Atomic Mass Fraction"
+(3006,00B9) VERS="3"	VR="SQ"   VM="1"	Keyword="AdditionalRTROIClassificationCodeSequence"				Name="Additional RT ROI Classification Code Sequence"
+(3006,00C0) VERS="RET"	VR="SQ"   VM="1"	Keyword="FrameOfReferenceRelationshipSequence"	Name="Frame of Reference Relationship Sequence"
+(3006,00C2) VERS="RET"	VR="UI"   VM="1"	Keyword="RelatedFrameOfReferenceUID"		Name="Related Frame of Reference UID"
+(3006,00C4) VERS="RET"	VR="CS"   VM="1"	Keyword="FrameOfReferenceTransformationType"	Name="Frame of Reference Transformation Type"
+(3006,00C6) VERS="3"	VR="DS"   VM="16"	Keyword="FrameOfReferenceTransformationMatrix"	Name="Frame of Reference Transformation Matrix"
+(3006,00C8) VERS="3"	VR="LO"   VM="1"	Keyword="FrameOfReferenceTransformationComment"	Name="Frame of Reference Transformation Comment"
+(3008,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="MeasuredDoseReferenceSequence"				Name="Measured Dose Reference Sequence"
+(3008,0012) VERS="3"	VR="ST"   VM="1"	Keyword="MeasuredDoseDescription"				Name="Measured Dose Description"
+(3008,0014) VERS="3"	VR="CS"   VM="1"	Keyword="MeasuredDoseType"					Name="Measured Dose Type"
+(3008,0016) VERS="3"	VR="DS"   VM="1"	Keyword="MeasuredDoseValue"					Name="Measured Dose Value"
+(3008,0020) VERS="3"	VR="SQ"   VM="1"	Keyword="TreatmentSessionBeamSequence"				Name="Treatment Session Beam Sequence"
+(3008,0021) VERS="3"	VR="SQ"   VM="1"	Keyword="TreatmentSessionIonBeamSequence"			Name="Treatment Session Ion Beam Sequence"
+(3008,0022) VERS="3"	VR="IS"   VM="1"	Keyword="CurrentFractionNumber"					Name="Current Fraction  Number"
+(3008,0024) VERS="3"	VR="DA"   VM="1"	Keyword="TreatmentControlPointDate"				Name="Treatment Control Point Date"
+(3008,0025) VERS="3"	VR="TM"   VM="1"	Keyword="TreatmentControlPointTime"				Name="Treatment Control Point Time"
+(3008,002A) VERS="3"	VR="CS"   VM="1"	Keyword="TreatmentTerminationStatus"				Name="Treatment Termination Status"
+(3008,002B) VERS="3"	VR="SH"   VM="1"	Keyword="TreatmentTerminationCode"				Name="Treatment Termination Code"
+(3008,002C) VERS="3"	VR="CS"   VM="1"	Keyword="TreatmentVerificationStatus"				Name="Treatment Verification Status"
+(3008,0030) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedTreatmentRecordSequence"			Name="Referenced Treatment Record Sequence"
+(3008,0032) VERS="3"	VR="DS"   VM="1"	Keyword="SpecifiedPrimaryMeterset" 				Name="Specified Primary Meterset"
+(3008,0033) VERS="3"	VR="DS"   VM="1"	Keyword="SpecifiedSecondaryMeterset" 				Name="Specified Secondary Meterset"
+(3008,0036) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveredPrimaryMeterset" 				Name="Delivered Primary Meterset"
+(3008,0037) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveredSecondaryMeterset" 				Name="Delivered Secondary Meterset"
+(3008,003A) VERS="3"	VR="DS"   VM="1"	Keyword="SpecifiedTreatmentTime"				Name="Specified Treatment  Time"
+(3008,003B) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveredTreatmentTime"				Name="Delivered Treatment Time"
+(3008,0040) VERS="3"	VR="SQ"   VM="1"	Keyword="ControlPointDeliverySequence"				Name="Control Point Delivery Sequence"
+(3008,0041) VERS="3"	VR="SQ"   VM="1"	Keyword="IonControlPointDeliverySequence"			Name="Ion Control Point Delivery Sequence"
+(3008,0042) VERS="3"	VR="DS"   VM="1"	Keyword="SpecifiedMeterset"					Name="Specified Meterset"
+(3008,0044) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveredMeterset"					Name="Delivered Meterset"
+(3008,0045) VERS="3"	VR="FL"   VM="1"	Keyword="MetersetRateSet"						Name="Meterset Rate Set"
+(3008,0046) VERS="3"	VR="FL"   VM="1"	Keyword="MetersetRateDelivered"					Name="Meterset Rate Delivered"
+(3008,0047) VERS="3"	VR="FL"   VM="1-n"	Keyword="ScanSpotMetersetsDelivered"			Name="Scan Spot Metersets Delivered"
+(3008,0048) VERS="3"	VR="DS"   VM="1"	Keyword="DoseRateDelivered"					Name="Dose Rate Delivered"
+(3008,0050) VERS="3"	VR="SQ"   VM="1"	Keyword="TreatmentSummaryCalculatedDoseReferenceSequence"	Name="Treatment Summary Calculated Dose Reference Sequence"
+(3008,0052) VERS="3"	VR="DS"   VM="1"	Keyword="CumulativeDoseToDoseReference"				Name="Cumulative Dose to Dose Reference"
+(3008,0054) VERS="3"	VR="DA"   VM="1"	Keyword="FirstTreatmentDate"					Name="First Treatment Date"
+(3008,0056) VERS="3"	VR="DA"   VM="1"	Keyword="MostRecentTreatmentDate"				Name="Most Recent Treatment Date"
+(3008,005A) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfFractionsDelivered"				Name="Number of Fractions Delivered"
+(3008,0060) VERS="3"	VR="SQ"   VM="1"	Keyword="OverrideSequence"					Name="Override Sequence"
+(3008,0061) VERS="3"	VR="AT"   VM="1"	Keyword="ParameterSequencePointer"				Name="Parameter Sequence Pointer"
+(3008,0062) VERS="3"	VR="AT"   VM="1"	Keyword="OverrideParameterPointer"				Name="Override Parameter Pointer"
+(3008,0063) VERS="3"	VR="IS"   VM="1"	Keyword="ParameterItemIndex"				Name="Parameter Item Index"
+(3008,0064) VERS="3"	VR="IS"   VM="1"	Keyword="MeasuredDoseReferenceNumber"				Name="Measured Dose Reference Number"
+(3008,0065) VERS="3"	VR="AT"   VM="1"	Keyword="ParameterPointer"				Name="Parameter Pointer"
+(3008,0066) VERS="3"	VR="ST"   VM="1"	Keyword="OverrideReason"					Name="Override Reason"
+(3008,0068) VERS="3"	VR="SQ"   VM="1"	Keyword="CorrectedParameterSequence"					Name="Corrected Parameter Sequence"
+(3008,006A) VERS="3"	VR="FL"   VM="1"	Keyword="CorrectionValue"					Name="Correction Value"
+(3008,0070) VERS="3"	VR="SQ"   VM="1"	Keyword="CalculatedDoseReferenceSequence"			Name="Calculated Dose Reference Sequence"
+(3008,0072) VERS="3"	VR="IS"   VM="1"	Keyword="CalculatedDoseReferenceNumber"				Name="Calculated Dose Reference Number"
+(3008,0074) VERS="3"	VR="ST"   VM="1"	Keyword="CalculatedDoseReferenceDescription"			Name="Calculated Dose Reference Description"
+(3008,0076) VERS="3"	VR="DS"   VM="1"	Keyword="CalculatedDoseReferenceDoseValue"			Name="Calculated Dose Reference Dose Value"
+(3008,0078) VERS="3"	VR="DS"   VM="1"	Keyword="StartMeterset"						Name="Start Meterset"
+(3008,007A) VERS="3"	VR="DS"   VM="1"	Keyword="EndMeterset"						Name="End Meterset"
+(3008,0080) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedMeasuredDoseReferenceSequence"		Name="Referenced Measured Dose Reference Sequence"
+(3008,0082) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedMeasuredDoseReferenceNumber"			Name="Referenced Measured Dose Reference Number"
+(3008,0090) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedCalculatedDoseReferenceSequence"		Name="Referenced Calculated Dose Reference Sequence"
+(3008,0092) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedCalculatedDoseReferenceNumber"		Name="Referenced Calculated Dose Reference Number"
+(3008,00A0) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamLimitingDeviceLeafPairsSequence"			Name="Beam Limiting Device Leaf Pairs Sequence"
+(3008,00B0) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedWedgeSequence"					Name="Recorded Wedge Sequence"
+(3008,00C0) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedCompensatorSequence"				Name="Recorded Compensator Sequence"
+(3008,00D0) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedBlockSequence"					Name="Recorded Block Sequence"
+(3008,00E0) VERS="3"	VR="SQ"   VM="1"	Keyword="TreatmentSummaryMeasuredDoseReferenceSequence"		Name="Treatment Summary Measured Dose Reference Sequence "
+(3008,00F0) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedSnoutSequence"						Name="Recorded Snout Sequence"
+(3008,00F2) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedRangeShifterSequence"				Name="Recorded Range Shifter Sequence"
+(3008,00F4) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedLateralSpreadingDeviceSequence"	Name="Recorded Lateral Spreading Device Sequence"
+(3008,00F6) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedRangeModulatorSequence"			Name="Recorded Range Modulator Sequence"
+(3008,0100) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedSourceSequence"				Name="Recorded Source Sequence"
+(3008,0105) VERS="3"	VR="LO"   VM="1"	Keyword="SourceSerialNumber"					Name="Source Serial Number"
+(3008,0110) VERS="3"	VR="SQ"   VM="1"	Keyword="TreatmentSessionApplicationSetupSequence"		Name="Treatment Session Application Setup Sequence"
+(3008,0116) VERS="3"	VR="CS"   VM="1"	Keyword="ApplicationSetupCheck"					Name="Application Setup  Check"
+(3008,0120) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedBrachyAccessoryDeviceSequence"			Name="Recorded Brachy Accessory Device Sequence"
+(3008,0122) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedBrachyAccessoryDeviceNumber"			Name="Referenced Brachy Accessory Device Number"
+(3008,0130) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedChannelSequence"				Name="Recorded Channel Sequence"
+(3008,0132) VERS="3"	VR="DS"   VM="1"	Keyword="SpecifiedChannelTotalTime"				Name="Specified Channel Total Time"
+(3008,0134) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveredChannelTotalTime"				Name="Delivered Channel Total Time"
+(3008,0136) VERS="3"	VR="IS"   VM="1"	Keyword="SpecifiedNumberOfPulses"				Name="Specified Number of Pulses"
+(3008,0138) VERS="3"	VR="IS"   VM="1"	Keyword="DeliveredNumberOfPulses"				Name="Delivered Number of Pulses"
+(3008,013A) VERS="3"	VR="DS"   VM="1"	Keyword="SpecifiedPulseRepetitionInterval"			Name="Specified Pulse Repetition Interval"
+(3008,013C) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveredPulseRepetitionInterval"			Name="Delivered Pulse Repetition Interval"
+(3008,0140) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedSourceApplicatorSequence"			Name="Recorded Source Applicator Sequence"
+(3008,0142) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedSourceApplicatorNumber"			Name="Referenced Source Applicator Number"
+(3008,0150) VERS="3"	VR="SQ"   VM="1"	Keyword="RecordedChannelShieldSequence"				Name="Recorded Channel Shield Sequence"
+(3008,0152) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedChannelShieldNumber"				Name="Referenced Channel Shield Number"
+(3008,0160) VERS="3"	VR="SQ"   VM="1"	Keyword="BrachyControlPointDeliveredSequence"			Name="Brachy Control Point Delivered Sequence"
+(3008,0162) VERS="3"	VR="DA"   VM="1"	Keyword="SafePositionExitDate"					Name="Safe Position Exit Date"
+(3008,0164) VERS="3"	VR="TM"   VM="1"	Keyword="SafePositionExitTime"					Name="Safe Position Exit Time"
+(3008,0166) VERS="3"	VR="DA"   VM="1"	Keyword="SafePositionReturnDate"				Name="Safe Position Return  Date"
+(3008,0168) VERS="3"	VR="TM"   VM="1"	Keyword="SafePositionReturnTime"				Name="Safe Position Return Time"
+(3008,0171) VERS="3"	VR="SQ"   VM="1"	Keyword="PulseSpecificBrachyControlPointDeliveredSequence"	Name="Pulse Specific Brachy Control Point Delivered Sequence"
+(3008,0172) VERS="3"	VR="US"   VM="1"	Keyword="PulseNumber"										Name="Pulse Number"
+(3008,0173) VERS="3"	VR="SQ"   VM="1"	Keyword="BrachyPulseControlPointDeliveredSequence"			Name="Brachy Pulse Control Point Delivered Sequence"
+(3008,0200) VERS="3"	VR="CS"   VM="1"	Keyword="CurrentTreatmentStatus"				Name="Current Treatment  Status"
+(3008,0202) VERS="3"	VR="ST"   VM="1"	Keyword="TreatmentStatusComment"				Name="Treatment Status Comment"
+(3008,0220) VERS="3"	VR="SQ"   VM="1"	Keyword="FractionGroupSummarySequence"				Name="Fraction Group Summary Sequence"
+(3008,0223) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedFractionNumber"				Name="Referenced Fraction Number"
+(3008,0224) VERS="3"	VR="CS"   VM="1"	Keyword="FractionGroupType"					Name="Fraction Group Type"
+(3008,0230) VERS="3"	VR="CS"   VM="1"	Keyword="BeamStopperPosition"					Name="Beam Stopper Position"
+(3008,0240) VERS="3"	VR="SQ"   VM="1"	Keyword="FractionStatusSummarySequence"				Name="Fraction Status Summary Sequence"
+(3008,0250) VERS="3"	VR="DA"   VM="1"	Keyword="TreatmentDate"						Name="Treatment Date"
+(3008,0251) VERS="3"	VR="TM"   VM="1"	Keyword="TreatmentTime"						Name="Treatment Time"
+(300A,0002) VERS="3"	VR="SH"   VM="1"	Keyword="RTPlanLabel"				Name="RT Plan Label"
+(300A,0003) VERS="3"	VR="LO"   VM="1"	Keyword="RTPlanName"				Name="RT Plan Name"
+(300A,0004) VERS="3"	VR="ST"   VM="1"	Keyword="RTPlanDescription"			Name="RT Plan Description"
+(300A,0006) VERS="3"	VR="DA"   VM="1"	Keyword="RTPlanDate"				Name="RT Plan Date"
+(300A,0007) VERS="3"	VR="TM"   VM="1"	Keyword="RTPlanTime"				Name="RT Plan Time"
+(300A,0009) VERS="3"	VR="LO"   VM="1-n"	Keyword="TreatmentProtocols"			Name="Treatment Protocols"
+(300A,000A) VERS="3"	VR="CS"   VM="1"	Keyword="PlanIntent"				Name="Plan Intent"
+(300A,000B) VERS="3"	VR="LO"   VM="1-n"	Keyword="TreatmentSites"			Name="Treatment Sites"
+(300A,000C) VERS="3"	VR="CS"   VM="1"	Keyword="RTPlanGeometry"			Name="RT Plan Geometry"
+(300A,000E) VERS="3"	VR="ST"   VM="1"	Keyword="PrescriptionDescription"		Name="Prescription Description"
+(300A,0010) VERS="3"	VR="SQ"   VM="1"	Keyword="DoseReferenceSequence"			Name="Dose Reference Sequence"
+(300A,0012) VERS="3"	VR="IS"   VM="1"	Keyword="DoseReferenceNumber"			Name="Dose Reference Number"
+(300A,0013) VERS="3"	VR="UI"   VM="1"	Keyword="DoseReferenceUID"			Name="Dose Reference UID"
+(300A,0014) VERS="3"	VR="CS"   VM="1"	Keyword="DoseReferenceStructureType"		Name="Dose Reference Structure Type"
+(300A,0015) VERS="3"	VR="CS"   VM="1"	Keyword="NominalBeamEnergyUnit"			Name="Nominal Beam Energy Unit"
+(300A,0016) VERS="3"	VR="LO"   VM="1"	Keyword="DoseReferenceDescription"		Name="Dose Reference Description"
+(300A,0018) VERS="3"	VR="DS"   VM="3"	Keyword="DoseReferencePointCoordinates"		Name="Dose Reference Point Coordinates"
+(300A,001A) VERS="3"	VR="DS"   VM="1"	Keyword="NominalPriorDose"			Name="Nominal Prior Dose"
+(300A,0020) VERS="3"	VR="CS"   VM="1"	Keyword="DoseReferenceType"			Name="Dose Reference Type"
+(300A,0021) VERS="3"	VR="DS"   VM="1"	Keyword="ConstraintWeight"			Name="Constraint Weight"
+(300A,0022) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveryWarningDose"			Name="Delivery Warning Dose"
+(300A,0023) VERS="3"	VR="DS"   VM="1"	Keyword="DeliveryMaximumDose"			Name="Delivery Maximum Dose"
+(300A,0025) VERS="3"	VR="DS"   VM="1"	Keyword="TargetMinimumDose"			Name="Target Minimum Dose"
+(300A,0026) VERS="3"	VR="DS"   VM="1"	Keyword="TargetPrescriptionDose"		Name="Target Prescription Dose"
+(300A,0027) VERS="3"	VR="DS"   VM="1"	Keyword="TargetMaximumDose"			Name="Target Maximum Dose"
+(300A,0028) VERS="3"	VR="DS"   VM="1"	Keyword="TargetUnderdoseVolumeFraction"		Name="Target Underdose Volume Fraction"
+(300A,002A) VERS="3"	VR="DS"   VM="1"	Keyword="OrganAtRiskFullVolumeDose"		Name="Organ at Risk Full-volume Dose"
+(300A,002B) VERS="3"	VR="DS"   VM="1"	Keyword="OrganAtRiskLimitDose"			Name="Organ at Risk Limit Dose"
+(300A,002C) VERS="3"	VR="DS"   VM="1"	Keyword="OrganAtRiskMaximumDose"		Name="Organ at Risk Maximum Dose"
+(300A,002D) VERS="3"	VR="DS"   VM="1"	Keyword="OrganAtRiskOverdoseVolumeFraction"	Name="Organ at Risk Overdose Volume Fraction"
+(300A,0040) VERS="3"	VR="SQ"   VM="1"	Keyword="ToleranceTableSequence"		Name="Tolerance Table Sequence"
+(300A,0042) VERS="3"	VR="IS"   VM="1"	Keyword="ToleranceTableNumber"			Name="Tolerance Table Number"
+(300A,0043) VERS="3"	VR="SH"   VM="1"	Keyword="ToleranceTableLabel"			Name="Tolerance Table Label"
+(300A,0044) VERS="3"	VR="DS"   VM="1"	Keyword="GantryAngleTolerance"			Name="Gantry Angle Tolerance"
+(300A,0046) VERS="3"	VR="DS"   VM="1"	Keyword="BeamLimitingDeviceAngleTolerance"	Name="Beam Limiting Device Angle Tolerance"
+(300A,0048) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamLimitingDeviceToleranceSequence"	Name="Beam Limiting Device Tolerance Sequence"
+(300A,004A) VERS="3"	VR="DS"   VM="1"	Keyword="BeamLimitingDevicePositionTolerance"	Name="Beam Limiting Device Position Tolerance"
+(300A,004B) VERS="3"	VR="FL"   VM="1"	Keyword="SnoutPositionTolerance"	Name="Snout Position Tolerance"
+(300A,004C) VERS="3"	VR="DS"   VM="1"	Keyword="PatientSupportAngleTolerance"		Name="Patient Support Angle Tolerance"
+(300A,004E) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopEccentricAngleTolerance"	Name="Table Top Eccentric Angle Tolerance"
+(300A,004F) VERS="3"	VR="FL"   VM="1"	Keyword="TableTopPitchAngleTolerance"	Name="Table Top Pitch Angle Tolerance"
+(300A,0050) VERS="3"	VR="FL"   VM="1"	Keyword="TableTopRollAngleTolerance"	Name="Table Top Roll Angle Tolerance"
+(300A,0051) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopVerticalPositionTolerance"	Name="Table Top Vertical Position Tolerance"
+(300A,0052) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopLongitudinalPositionTolerance"	Name="Table Top Longitudinal Position Tolerance"
+(300A,0053) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopLateralPositionTolerance"	Name="Table Top Lateral Position Tolerance"
+(300A,0055) VERS="3"	VR="CS"   VM="1"	Keyword="RTPlanRelationship"			Name="RT Plan Relationship"
+(300A,0070) VERS="3"	VR="SQ"   VM="1"	Keyword="FractionGroupSequence"			Name="Fraction Group Sequence"
+(300A,0071) VERS="3"	VR="IS"   VM="1"	Keyword="FractionGroupNumber"			Name="Fraction Group Number"
+(300A,0072) VERS="3"	VR="LO"   VM="1"	Keyword="FractionGroupDescription"		Name="Fraction Group Description"
+(300A,0078) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfFractionsPlanned"		Name="Number of Fractions Planned"
+(300A,0079) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfFractionPatternDigitsPerDay"	Name="Number of Fraction Pattern Digits Per Day"
+(300A,007A) VERS="3"	VR="IS"   VM="1"	Keyword="RepeatFractionCycleLength"		Name="Repeat Fraction Cycle Length"
+(300A,007B) VERS="3"	VR="LT"   VM="1"	Keyword="FractionPattern"			Name="Fraction Pattern"
+(300A,0080) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfBeams"				Name="Number of Beams"
+(300A,0082) VERS="3"	VR="DS"   VM="3"	Keyword="BeamDoseSpecificationPoint"		Name="Beam Dose Specification Point"
+(300A,0084) VERS="3"	VR="DS"   VM="1"	Keyword="BeamDose"				Name="Beam Dose"
+(300A,0086) VERS="3"	VR="DS"   VM="1"	Keyword="BeamMeterset"				Name="Beam Meterset"
+(300A,0088) VERS="RET"	VR="FL"   VM="1"	Keyword="BeamDosePointDepth"				Name="Beam Dose Point Depth"
+(300A,0089) VERS="RET"	VR="FL"   VM="1"	Keyword="BeamDosePointEquivalentDepth"	Name="Beam Dose Point Equivalent Depth"
+(300A,008A) VERS="RET"	VR="FL"   VM="1"	Keyword="BeamDosePointSSD"				Name="Beam Dose Point SSD"
+(300A,008B) VERS="3"	VR="CS"   VM="1"	Keyword="BeamDoseMeaning"				Name="Beam Dose Meaning"
+(300A,008C) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamDoseVerificationControlPointSequence"	Name="Beam Dose Verification Control Point Sequence"
+(300A,008D) VERS="3"	VR="FL"   VM="1"	Keyword="AverageBeamDosePointDepth"					Name="Average Beam Dose Point Depth"
+(300A,008E) VERS="3"	VR="FL"   VM="1"	Keyword="AverageBeamDosePointEquivalentDepth"		Name="Average Beam Dose Point Equivalent Depth"
+(300A,008F) VERS="3"	VR="FL"   VM="1"	Keyword="AverageBeamDosePointSSD"					Name="Average Beam Dose Point SSD"
+(300A,0090) VERS="3"	VR="CS"   VM="1"	Keyword="BeamDoseType"						Name="Beam Dose Type"
+(300A,0091) VERS="3"	VR="DS"   VM="1"	Keyword="AlternateBeamDose"					Name="Alternate Beam Dose"
+(300A,0092) VERS="3"	VR="CS"   VM="1"	Keyword="AlternateBeamDoseType"				Name="Alternate Beam Dose Type"
+(300A,00A0) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfBrachyApplicationSetups"	Name="Number of Brachy Application Setups"
+(300A,00A2) VERS="3"	VR="DS"   VM="3"	Keyword="BrachyApplicationSetupDoseSpecificationPoint"	Name="Brachy Application Setup Dose Specification Point"
+(300A,00A4) VERS="3"	VR="DS"   VM="1"	Keyword="BrachyApplicationSetupDose"		Name="Brachy Application Setup Dose"
+(300A,00B0) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamSequence"				Name="Beam Sequence"
+(300A,00B2) VERS="3"	VR="SH"   VM="1"	Keyword="TreatmentMachineName"			Name="Treatment Machine Name "
+(300A,00B3) VERS="3"	VR="CS"   VM="1"	Keyword="PrimaryDosimeterUnit"			Name="Primary Dosimeter Unit"
+(300A,00B4) VERS="3"	VR="DS"   VM="1"	Keyword="SourceAxisDistance"			Name="Source-Axis Distance"
+(300A,00B6) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamLimitingDeviceSequence"		Name="Beam Limiting Device Sequence"
+(300A,00B8) VERS="3"	VR="CS"   VM="1"	Keyword="RTBeamLimitingDeviceType"		Name="RT Beam Limiting Device Type"
+(300A,00BA) VERS="3"	VR="DS"   VM="1"	Keyword="SourceToBeamLimitingDeviceDistance"	Name="Source to Beam Limiting Device Distance"
+(300A,00BB) VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToBeamLimitingDeviceDistance"	Name="Isocenter to Beam Limiting Device Distance"
+(300A,00BC) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfLeafJawPairs"			Name="Number of Leaf/Jaw Pairs"
+(300A,00BE) VERS="3"	VR="DS"   VM="3-n"	Keyword="LeafPositionBoundaries"		Name="Leaf Position Boundaries"
+(300A,00C0) VERS="3"	VR="IS"   VM="1"	Keyword="BeamNumber"				Name="Beam Number"
+(300A,00C2) VERS="3"	VR="LO"   VM="1"	Keyword="BeamName"				Name="Beam Name"
+(300A,00C3) VERS="3"	VR="ST"   VM="1"	Keyword="BeamDescription"			Name="Beam Description"
+(300A,00C4) VERS="3"	VR="CS"   VM="1"	Keyword="BeamType"				Name="Beam Type"
+(300A,00C5) VERS="3"	VR="FD"   VM="1"	Keyword="BeamDeliveryDurationLimit"	Name="Beam Delivery Duration Limit"
+(300A,00C6) VERS="3"	VR="CS"   VM="1"	Keyword="RadiationType"				Name="Radiation Type"
+(300A,00C7) VERS="3"	VR="CS"   VM="1"	Keyword="HighDoseTechniqueType"			Name="High-Dose Technique Type"
+(300A,00C8) VERS="3"	VR="IS"   VM="1"	Keyword="ReferenceImageNumber"			Name="Reference Image Number"
+(300A,00CA) VERS="3"	VR="SQ"   VM="1"	Keyword="PlannedVerificationImageSequence"	Name="Planned Verification Image Sequence"
+(300A,00CC) VERS="3"	VR="LO"   VM="1-n"	Keyword="ImagingDeviceSpecificAcquisitionParameters"	Name="Imaging Device-Specific Acquisition Parameters"
+(300A,00CE) VERS="3"	VR="CS"   VM="1"	Keyword="TreatmentDeliveryType"			Name="Treatment Delivery Type"
+(300A,00D0) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfWedges"			Name="Number of Wedges"
+(300A,00D1) VERS="3"	VR="SQ"   VM="1"	Keyword="WedgeSequence"				Name="Wedge Sequence"
+(300A,00D2) VERS="3"	VR="IS"   VM="1"	Keyword="WedgeNumber"				Name="Wedge Number"
+(300A,00D3) VERS="3"	VR="CS"   VM="1"	Keyword="WedgeType"				Name="Wedge Type"
+(300A,00D4) VERS="3"	VR="SH"   VM="1"	Keyword="WedgeID"				Name="Wedge ID"
+(300A,00D5) VERS="3"	VR="IS"   VM="1"	Keyword="WedgeAngle"				Name="Wedge Angle"
+(300A,00D6) VERS="3"	VR="DS"   VM="1"	Keyword="WedgeFactor"				Name="Wedge Factor"
+(300A,00D7) VERS="3"	VR="FL"   VM="1"	Keyword="TotalWedgeTrayWaterEquivalentThickness"				Name="Total Wedge Tray Water-Equivalent Thickness"
+(300A,00D8) VERS="3"	VR="DS"   VM="1"	Keyword="WedgeOrientation"			Name="Wedge Orientation"
+(300A,00D9) VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToWedgeTrayDistance"				Name="Isocenter to Wedge Tray Distance"
+(300A,00DA) VERS="3"	VR="DS"   VM="1"	Keyword="SourceToWedgeTrayDistance"		Name="Source to Wedge Tray Distance"
+(300A,00DB) VERS="3"	VR="FL"   VM="1"	Keyword="WedgeThinEdgePosition"			Name="Wedge Thin Edge Position"
+(300A,00DC) VERS="3"	VR="SH"   VM="1"	Keyword="BolusID"						Name="Bolus ID"
+(300A,00DD) VERS="3"	VR="ST"   VM="1"	Keyword="BolusDescription"				Name="Bolus Description"
+(300A,00DE) VERS="3"	VR="DS"   VM="1"	Keyword="EffectiveWedgeAngle"			Name="Effective Wedge Angle"
+(300A,00E0) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfCompensators"			Name="Number of Compensators"
+(300A,00E1) VERS="3"	VR="SH"   VM="1"	Keyword="MaterialID"				Name="Material ID"
+(300A,00E2) VERS="3"	VR="DS"   VM="1"	Keyword="TotalCompensatorTrayFactor"		Name="Total Compensator Tray Factor"
+(300A,00E3) VERS="3"	VR="SQ"   VM="1"	Keyword="CompensatorSequence"			Name="Compensator Sequence"
+(300A,00E4) VERS="3"	VR="IS"   VM="1"	Keyword="CompensatorNumber"			Name="Compensator Number"
+(300A,00E5) VERS="3"	VR="SH"   VM="1"	Keyword="CompensatorID"				Name="Compensator ID"
+(300A,00E6) VERS="3"	VR="DS"   VM="1"	Keyword="SourceToCompensatorTrayDistance"	Name="Source to Compensator Tray Distance"
+(300A,00E7) VERS="3"	VR="IS"   VM="1"	Keyword="CompensatorRows"			Name="Compensator Rows"
+(300A,00E8) VERS="3"	VR="IS"   VM="1"	Keyword="CompensatorColumns"			Name="Compensator Columns"
+(300A,00E9) VERS="3"	VR="DS"   VM="2"	Keyword="CompensatorPixelSpacing"		Name="Compensator Pixel Spacing"
+(300A,00EA) VERS="3"	VR="DS"   VM="2"	Keyword="CompensatorPosition"			Name="Compensator Position"
+(300A,00EB) VERS="3"	VR="DS"   VM="1-n"	Keyword="CompensatorTransmissionData"		Name="Compensator Transmission Data"
+(300A,00EC) VERS="3"	VR="DS"   VM="1-n"	Keyword="CompensatorThicknessData"		Name="Compensator Thickness Data"
+(300A,00ED) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfBoli"				Name="Number of Boli"
+(300A,00EE) VERS="3"	VR="CS"   VM="1"	Keyword="CompensatorType"			Name="Compensator Type"
+(300A,00EF) VERS="3"	VR="SH"   VM="1"	Keyword="CompensatorTrayID"			Name="Compensator Tray ID"
+(300A,00F0) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfBlocks"			Name="Number of Blocks"
+(300A,00F2) VERS="3"	VR="DS"   VM="1"	Keyword="TotalBlockTrayFactor"			Name="Total Block Tray Factor"
+(300A,00F3) VERS="3"	VR="FL"   VM="1"	Keyword="TotalBlockTrayWaterEquivalentThickness"			Name="Total Block Tray Water-Equivalent Thickness"
+(300A,00F4) VERS="3"	VR="SQ"   VM="1"	Keyword="BlockSequence"				Name="Block Sequence"
+(300A,00F5) VERS="3"	VR="SH"   VM="1"	Keyword="BlockTrayID"				Name="Block Tray ID"
+(300A,00F6) VERS="3"	VR="DS"   VM="1"	Keyword="SourceToBlockTrayDistance"		Name="Source to Block Tray Distance"
+(300A,00F7) VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToBlockTrayDistance"			Name="Isocenter to Block Tray Distance"
+(300A,00F8) VERS="3"	VR="CS"   VM="1"	Keyword="BlockType"				Name="Block Type"
+(300A,00F9) VERS="3"	VR="LO"   VM="1"	Keyword="AccessoryCode"				Name="Accessory Code"
+(300A,00FA) VERS="3"	VR="CS"   VM="1"	Keyword="BlockDivergence"			Name="Block Divergence"
+(300A,00FB) VERS="3"	VR="CS"   VM="1"	Keyword="BlockMountingPosition"			Name="Block Mounting Position"
+(300A,00FC) VERS="3"	VR="IS"   VM="1"	Keyword="BlockNumber"				Name="Block Number"
+(300A,00FE) VERS="3"	VR="LO"   VM="1"	Keyword="BlockName"				Name="Block Name"
+(300A,0100) VERS="3"	VR="DS"   VM="1"	Keyword="BlockThickness"			Name="Block Thickness"
+(300A,0102) VERS="3"	VR="DS"   VM="1"	Keyword="BlockTransmission"			Name="Block Transmission"
+(300A,0104) VERS="3"	VR="IS"   VM="1"	Keyword="BlockNumberOfPoints"			Name="Block Number of Points"
+(300A,0106) VERS="3"	VR="DS"   VM="2-2n"	Keyword="BlockData"				Name="Block Data"
+(300A,0107) VERS="3"	VR="SQ"   VM="1"	Keyword="ApplicatorSequence"			Name="Applicator Sequence"
+(300A,0108) VERS="3"	VR="SH"   VM="1"	Keyword="ApplicatorID"				Name="Applicator ID"
+(300A,0109) VERS="3"	VR="CS"   VM="1"	Keyword="ApplicatorType"			Name="Applicator Type"
+(300A,010A) VERS="3"	VR="LO"   VM="1"	Keyword="ApplicatorDescription"			Name="Applicator Description"
+(300A,010C) VERS="3"	VR="DS"   VM="1"	Keyword="CumulativeDoseReferenceCoefficient"	Name="Cumulative Dose Reference Coefficient"
+(300A,010E) VERS="3"	VR="DS"   VM="1"	Keyword="FinalCumulativeMetersetWeight"		Name="Final Cumulative Meterset Weight"
+(300A,0110) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfControlPoints"			Name="Number of Control Points"
+(300A,0111) VERS="3"	VR="SQ"   VM="1"	Keyword="ControlPointSequence"			Name="Control Point Sequence"
+(300A,0112) VERS="3"	VR="IS"   VM="1"	Keyword="ControlPointIndex"			Name="Control Point Index"
+(300A,0114) VERS="3"	VR="DS"   VM="1"	Keyword="NominalBeamEnergy"			Name="Nominal Beam Energy"
+(300A,0115) VERS="3"	VR="DS"   VM="1"	Keyword="DoseRateSet"				Name="Dose Rate Set"
+(300A,0116) VERS="3"	VR="SQ"   VM="1"	Keyword="WedgePositionSequence"			Name="Wedge Position Sequence"
+(300A,0118) VERS="3"	VR="CS"   VM="1"	Keyword="WedgePosition"				Name="Wedge Position"
+(300A,011A) VERS="3"	VR="SQ"   VM="1"	Keyword="BeamLimitingDevicePositionSequence"	Name="Beam Limiting Device Position Sequence"
+(300A,011C) VERS="3"	VR="DS"   VM="2-2n"	Keyword="LeafJawPositions"			Name="Leaf Jaw Positions"
+(300A,011E) VERS="3"	VR="DS"   VM="1"	Keyword="GantryAngle"				Name="Gantry Angle"
+(300A,011F) VERS="3"	VR="CS"   VM="1"	Keyword="GantryRotationDirection"		Name="Gantry Rotation Direction"
+(300A,0120) VERS="3"	VR="DS"   VM="1"	Keyword="BeamLimitingDeviceAngle"		Name="Beam Limiting Device Angle"
+(300A,0121) VERS="3"	VR="CS"   VM="1"	Keyword="BeamLimitingDeviceRotationDirection"	Name="Beam Limiting Device Rotation Direction"
+(300A,0122) VERS="3"	VR="DS"   VM="1"	Keyword="PatientSupportAngle"			Name="Patient Support Angle"
+(300A,0123) VERS="3"	VR="CS"   VM="1"	Keyword="PatientSupportRotationDirection"	Name="Patient Support Rotation Direction"
+(300A,0124) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopEccentricAxisDistance"		Name="Table Top Eccentric Axis Distance"
+(300A,0125) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopEccentricAngle"		Name="Table Top Eccentric Angle"
+(300A,0126) VERS="3"	VR="CS"   VM="1"	Keyword="TableTopEccentricRotationDirection"	Name="Table Top Eccentric Rotation Direction"
+(300A,0128) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopVerticalPosition"		Name="Table Top Vertical Position"
+(300A,0129) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopLongitudinalPosition"		Name="Table Top Longitudinal Position"
+(300A,012A) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopLateralPosition"		Name="Table Top Lateral Position"
+(300A,012C) VERS="3"	VR="DS"   VM="3"	Keyword="IsocenterPosition"			Name="Isocenter Position"
+(300A,012E) VERS="3"	VR="DS"   VM="3"	Keyword="SurfaceEntryPoint"			Name="Surface Entry Point"
+(300A,0130) VERS="3"	VR="DS"   VM="1"	Keyword="SourceToSurfaceDistance"		Name="Source to Surface Distance"
+(300A,0131) VERS="3"	VR="FL"   VM="1"	Keyword="AverageBeamDosePointSourceToExternalContourSurfaceDistance"	Name="Average Beam Dose Point Source to External Contour Surface Distance"
+(300A,0132) VERS="3"	VR="FL"   VM="1"	Keyword="SourceToExternalContourDistance"		Name="Source to External Contour Distance"
+(300A,0133) VERS="3"	VR="FL"   VM="3"	Keyword="ExternalContourEntryPoint"		Name="External Contour Entry Point"
+(300A,0134) VERS="3"	VR="DS"   VM="1"	Keyword="CumulativeMetersetWeight"		Name="Cumulative Meterset Weight"
+(300A,0140)	VERS="3"	VR="FL"   VM="1"	Keyword="TableTopPitchAngle"					Name="Table Top Pitch Angle"
+(300A,0142)	VERS="3"	VR="CS"   VM="1"	Keyword="TableTopPitchRotationDirection"	Name="Table Top Pitch Rotation Direction"
+(300A,0144)	VERS="3"	VR="FL"   VM="1"	Keyword="TableTopRollAngle"					Name="Table Top Roll Angle"
+(300A,0146)	VERS="3"	VR="CS"   VM="1"	Keyword="TableTopRollRotationDirection"		Name="Table Top Roll Rotation Direction"
+(300A,0148)	VERS="3"	VR="FL"   VM="1"	Keyword="HeadFixationAngle"					Name="Head Fixation Angle"
+(300A,014A)	VERS="3"	VR="FL"   VM="1"	Keyword="GantryPitchAngle"					Name="Gantry Pitch Angle"
+(300A,014C)	VERS="3"	VR="CS"   VM="1"	Keyword="GantryPitchRotationDirection"		Name="Gantry Pitch Rotation Direction"
+(300A,014E)	VERS="3"	VR="FL"   VM="1"	Keyword="GantryPitchAngleTolerance"			Name="Gantry Pitch Angle Tolerance"
+(300A,0180) VERS="3"	VR="SQ"   VM="1"	Keyword="PatientSetupSequence"			Name="Patient Setup Sequence"
+(300A,0182) VERS="3"	VR="IS"   VM="1"	Keyword="PatientSetupNumber"			Name="Patient Setup Number"
+(300A,0183)	VERS="3"	VR="LO"   VM="1"	Keyword="PatientSetupLabel"				Name="Patient Setup Label"
+(300A,0184) VERS="3"	VR="LO"   VM="1"	Keyword="PatientAdditionalPosition"		Name="Patient Additional Position"
+(300A,0190) VERS="3"	VR="SQ"   VM="1"	Keyword="FixationDeviceSequence"		Name="Fixation Device Sequence"
+(300A,0192) VERS="3"	VR="CS"   VM="1"	Keyword="FixationDeviceType"			Name="Fixation Device Type"
+(300A,0194) VERS="3"	VR="SH"   VM="1"	Keyword="FixationDeviceLabel"			Name="Fixation Device Label"
+(300A,0196) VERS="3"	VR="ST"   VM="1"	Keyword="FixationDeviceDescription"		Name="Fixation Device Description"
+(300A,0198) VERS="3"	VR="SH"   VM="1"	Keyword="FixationDevicePosition"		Name="Fixation Device Position"
+(300A,0199)	VERS="3"	VR="FL"   VM="1"	Keyword="FixationDevicePitchAngle"		Name="Fixation Device Pitch Angle"
+(300A,019A)	VERS="3"	VR="FL"   VM="1"	Keyword="FixationDeviceRollAngle"		Name="Fixation Device Roll Angle"
+(300A,01A0) VERS="3"	VR="SQ"   VM="1"	Keyword="ShieldingDeviceSequence"		Name="Shielding Device Sequence"
+(300A,01A2) VERS="3"	VR="CS"   VM="1"	Keyword="ShieldingDeviceType"			Name="Shielding Device Type"
+(300A,01A4) VERS="3"	VR="SH"   VM="1"	Keyword="ShieldingDeviceLabel"			Name="Shielding Device Label"
+(300A,01A6) VERS="3"	VR="ST"   VM="1"	Keyword="ShieldingDeviceDescription"		Name="Shielding Device Description"
+(300A,01A8) VERS="3"	VR="SH"   VM="1"	Keyword="ShieldingDevicePosition"		Name="Shielding Device Position"
+(300A,01B0) VERS="3"	VR="CS"   VM="1"	Keyword="SetupTechnique"			Name="Setup Technique"
+(300A,01B2) VERS="3"	VR="ST"   VM="1"	Keyword="SetupTechniqueDescription"		Name="Setup TechniqueDescription"
+(300A,01B4) VERS="3"	VR="SQ"   VM="1"	Keyword="SetupDeviceSequence"			Name="Setup Device Sequence"
+(300A,01B6) VERS="3"	VR="CS"   VM="1"	Keyword="SetupDeviceType"			Name="Setup Device Type"
+(300A,01B8) VERS="3"	VR="SH"   VM="1"	Keyword="SetupDeviceLabel"			Name="Setup Device Label"
+(300A,01BA) VERS="3"	VR="ST"   VM="1"	Keyword="SetupDeviceDescription"		Name="Setup Device Description"
+(300A,01BC) VERS="3"	VR="DS"   VM="1"	Keyword="SetupDeviceParameter"			Name="Setup Device Parameter"
+(300A,01D0) VERS="3"	VR="ST"   VM="1"	Keyword="SetupReferenceDescription"		Name="Setup ReferenceDescription"
+(300A,01D2) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopVerticalSetupDisplacement"	Name="Table Top Vertical Setup Displacement"
+(300A,01D4) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopLongitudinalSetupDisplacement"	Name="Table Top Longitudinal Setup Displacement"
+(300A,01D6) VERS="3"	VR="DS"   VM="1"	Keyword="TableTopLateralSetupDisplacement"	Name="Table Top Lateral Setup Displacement"
+(300A,0200) VERS="3"	VR="CS"   VM="1"	Keyword="BrachyTreatmentTechnique"		Name="Brachy Treatment Technique"
+(300A,0202) VERS="3"	VR="CS"   VM="1"	Keyword="BrachyTreatmentType"			Name="Brachy Treatment Type"
+(300A,0206) VERS="3"	VR="SQ"   VM="1"	Keyword="TreatmentMachineSequence"		Name="Treatment Machine Sequence"
+(300A,0210) VERS="3"	VR="SQ"   VM="1"	Keyword="SourceSequence"			Name="Source Sequence"
+(300A,0212) VERS="3"	VR="IS"   VM="1"	Keyword="SourceNumber"				Name="Source Number"
+(300A,0214) VERS="3"	VR="CS"   VM="1"	Keyword="SourceType"				Name="Source Type"
+(300A,0216) VERS="3"	VR="LO"   VM="1"	Keyword="SourceManufacturer"			Name="Source Manufacturer"
+(300A,0218) VERS="3"	VR="DS"   VM="1"	Keyword="ActiveSourceDiameter"			Name="Active Source Diameter"
+(300A,021A) VERS="3"	VR="DS"   VM="1"	Keyword="ActiveSourceLength"			Name="Active Source Length"
+(300A,021B) VERS="3"	VR="SH"   VM="1"	Keyword="SourceModelID"					Name="Source Model ID"
+(300A,021C) VERS="3"	VR="LO"   VM="1"	Keyword="SourceDescription"				Name="Source Description"
+(300A,0222) VERS="3"	VR="DS"   VM="1"	Keyword="SourceEncapsulationNominalThickness"	Name="Source Encapsulation Nominal Thickness"
+(300A,0224) VERS="3"	VR="DS"   VM="1"	Keyword="SourceEncapsulationNominalTransmission"	Name="Source Encapsulation Nominal Transmission"
+(300A,0226) VERS="3"	VR="LO"   VM="1"	Keyword="SourceIsotopeName"			Name="Source IsotopeName"
+(300A,0228) VERS="3"	VR="DS"   VM="1"	Keyword="SourceIsotopeHalfLife"			Name="Source Isotope Half Life"
+(300A,0229)	VERS="3"	VR="CS"   VM="1"	Keyword="SourceStrengthUnits"			Name="Source Strength Units"
+(300A,022A) VERS="3"	VR="DS"   VM="1"	Keyword="ReferenceAirKermaRate"			Name="Reference Air Kerma Rate"
+(300A,022B)	VERS="3"	VR="DS"   VM="1"	Keyword="SourceStrength"				Name="Source Strength"
+(300A,022C) VERS="3"	VR="DA"   VM="1"	Keyword="SourceStrengthReferenceDate"		Name="Source Strength Reference Date"
+(300A,022E) VERS="3"	VR="TM"   VM="1"	Keyword="SourceStrengthReferenceTime"		Name="Source Strength Reference Time"
+(300A,0230) VERS="3"	VR="SQ"   VM="1"	Keyword="ApplicationSetupSequence"		Name="Application Setup Sequence"
+(300A,0232) VERS="3"	VR="CS"   VM="1"	Keyword="ApplicationSetupType"			Name="Application Setup Type"
+(300A,0234) VERS="3"	VR="IS"   VM="1"	Keyword="ApplicationSetupNumber"		Name="Application Setup Number"
+(300A,0236) VERS="3"	VR="LO"   VM="1"	Keyword="ApplicationSetupName"			Name="Application Setup Name"
+(300A,0238) VERS="3"	VR="LO"   VM="1"	Keyword="ApplicationSetupManufacturer"		Name="Application Setup Manufacturer"
+(300A,0240) VERS="3"	VR="IS"   VM="1"	Keyword="TemplateNumber"			Name="Template Number"
+(300A,0242) VERS="3"	VR="SH"   VM="1"	Keyword="TemplateType"				Name="Template Type"
+(300A,0244) VERS="3"	VR="LO"   VM="1"	Keyword="TemplateName"				Name="Template Name"
+(300A,0250) VERS="3"	VR="DS"   VM="1"	Keyword="TotalReferenceAirKerma"		Name="Total Reference Air Kerma"
+(300A,0260) VERS="3"	VR="SQ"   VM="1"	Keyword="BrachyAccessoryDeviceSequence"		Name="Brachy Accessory Device Sequence"
+(300A,0262) VERS="3"	VR="IS"   VM="1"	Keyword="BrachyAccessoryDeviceNumber"		Name="Brachy Accessory Device Number"
+(300A,0263) VERS="3"	VR="SH"   VM="1"	Keyword="BrachyAccessoryDeviceID"		Name="Brachy Accessory Device ID"
+(300A,0264) VERS="3"	VR="CS"   VM="1"	Keyword="BrachyAccessoryDeviceType"		Name="Brachy Accessory Device Type"
+(300A,0266) VERS="3"	VR="LO"   VM="1"	Keyword="BrachyAccessoryDeviceName"		Name="Brachy Accessory Device Name"
+(300A,026A) VERS="3"	VR="DS"   VM="1"	Keyword="BrachyAccessoryDeviceNominalThickness"	Name="Brachy Accessory Device Nominal Thickness"
+(300A,026C) VERS="3"	VR="DS"   VM="1"	Keyword="BrachyAccessoryDeviceNominalTransmission"	Name="Brachy Accessory Device Nominal Transmission"
+(300A,0280) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelSequence"			Name="Channel Sequence"
+(300A,0282) VERS="3"	VR="IS"   VM="1"	Keyword="ChannelNumber"				Name="Channel Number"
+(300A,0284) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelLength"				Name="Channel Length"
+(300A,0286) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelTotalTime"			Name="Channel Total Time"
+(300A,0288) VERS="3"	VR="CS"   VM="1"	Keyword="SourceMovementType"			Name="Source Movement Type"
+(300A,028A) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfPulses"			Name="Number of Pulses"
+(300A,028C) VERS="3"	VR="DS"   VM="1"	Keyword="PulseRepetitionInterval"		Name="Pulse Repetition Interval"
+(300A,0290) VERS="3"	VR="IS"   VM="1"	Keyword="SourceApplicatorNumber"		Name="Source Applicator Number"
+(300A,0291) VERS="3"	VR="SH"   VM="1"	Keyword="SourceApplicatorID"			Name="Source Applicator ID"
+(300A,0292) VERS="3"	VR="CS"   VM="1"	Keyword="SourceApplicatorType"			Name="Source Applicator Type"
+(300A,0294) VERS="3"	VR="LO"   VM="1"	Keyword="SourceApplicatorName"			Name="Source Applicator Name"
+(300A,0296) VERS="3"	VR="DS"   VM="1"	Keyword="SourceApplicatorLength"		Name="Source Applicator Length"
+(300A,0298) VERS="3"	VR="LO"   VM="1"	Keyword="SourceApplicatorManufacturer"		Name="Source Applicator Manufacturer"
+(300A,029C) VERS="3"	VR="DS"   VM="1"	Keyword="SourceApplicatorWallNominalThickness"	Name="Source Applicator Wall Nominal Thickness"
+(300A,029E) VERS="3"	VR="DS"   VM="1"	Keyword="SourceApplicatorWallNominalTransmission"	Name="Source Applicator Wall Nominal Transmission"
+(300A,02A0) VERS="3"	VR="DS"   VM="1"	Keyword="SourceApplicatorStepSize"		Name="Source Applicator Step Size"
+(300A,02A2) VERS="3"	VR="IS"   VM="1"	Keyword="TransferTubeNumber"			Name="Transfer Tube Number"
+(300A,02A4) VERS="3"	VR="DS"   VM="1"	Keyword="TransferTubeLength"			Name="Transfer Tube Length"
+(300A,02B0) VERS="3"	VR="SQ"   VM="1"	Keyword="ChannelShieldSequence"			Name="Channel Shield Sequence"
+(300A,02B2) VERS="3"	VR="IS"   VM="1"	Keyword="ChannelShieldNumber"			Name="Channel Shield Number"
+(300A,02B3) VERS="3"	VR="SH"   VM="1"	Keyword="ChannelShieldID"			Name="Channel Shield ID"
+(300A,02B4) VERS="3"	VR="LO"   VM="1"	Keyword="ChannelShieldName"			Name="Channel Shield Name"
+(300A,02B8) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelShieldNominalThickness"		Name="Channel Shield Nominal Thickness"
+(300A,02BA) VERS="3"	VR="DS"   VM="1"	Keyword="ChannelShieldNominalTransmission"	Name="Channel Shield Nominal Transmission"
+(300A,02C8) VERS="3"	VR="DS"   VM="1"	Keyword="FinalCumulativeTimeWeight"		Name="Final Cumulative Time Weight"
+(300A,02D0) VERS="3"	VR="SQ"   VM="1"	Keyword="BrachyControlPointSequence"		Name="Brachy Control Point Sequence"
+(300A,02D2) VERS="3"	VR="DS"   VM="1"	Keyword="ControlPointRelativePosition"		Name="Control Point Relative Position"
+(300A,02D4) VERS="3"	VR="DS"   VM="3"	Keyword="ControlPoint3DPosition"		Name="Control Point 3D Position"
+(300A,02D6) VERS="3"	VR="DS"   VM="1"	Keyword="CumulativeTimeWeight"			Name="Cumulative Time Weight"
+(300A,02E0) VERS="3"	VR="CS"   VM="1"	Keyword="CompensatorDivergence"			Name="Compensator Divergence"
+(300A,02E1) VERS="3"	VR="CS"   VM="1"	Keyword="CompensatorMountingPosition"		Name="Compensator Mounting Position"
+(300A,02E2) VERS="3"	VR="DS"   VM="1-n"	Keyword="SourceToCompensatorDistance"		Name="Source to Compensator Distance"
+(300A,02E3)	VERS="3"	VR="FL"   VM="1"	Keyword="TotalCompensatorTrayWaterEquivalentThickness"		Name="Total Compensator Tray Water-Equivalent Thickness"
+(300A,02E4)	VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToCompensatorTrayDistance"		Name="Isocenter to Compensator Tray Distance"
+(300A,02E5)	VERS="3"	VR="FL"   VM="1"	Keyword="CompensatorColumnOffset"		Name="Compensator Column Offset"
+(300A,02E6)	VERS="3"	VR="FL"   VM="1-n"	Keyword="IsocenterToCompensatorDistances"		Name="Isocenter to Compensator Distances"
+(300A,02E7)	VERS="3"	VR="FL"   VM="1"	Keyword="CompensatorRelativeStoppingPowerRatio"		Name="Compensator Relative Stopping Power Ratio"
+(300A,02E8)	VERS="3"	VR="FL"   VM="1"	Keyword="CompensatorMillingToolDiameter"		Name="Compensator Milling Tool Diameter"
+(300A,02EA)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonRangeCompensatorSequence"		Name="Ion Range Compensator Sequence"
+(300A,02EB)	VERS="3"	VR="LT"   VM="1"	Keyword="CompensatorDescription"		Name="Compensator Description"
+(300A,0302)	VERS="3"	VR="IS"   VM="1"	Keyword="RadiationMassNumber"		Name="Radiation Mass Number"
+(300A,0304)	VERS="3"	VR="IS"   VM="1"	Keyword="RadiationAtomicNumber"		Name="Radiation Atomic Number"
+(300A,0306)	VERS="3"	VR="SS"   VM="1"	Keyword="RadiationChargeState"		Name="Radiation Charge State"
+(300A,0308)	VERS="3"	VR="CS"   VM="1"	Keyword="ScanMode"		Name="Scan Mode"
+(300A,0309)	VERS="3"	VR="CS"   VM="1"	Keyword="ModulatedScanModeType"		Name="Modulated Scan Mode Type"
+(300A,030A)	VERS="3"	VR="FL"   VM="2"	Keyword="VirtualSourceAxisDistances"		Name="Virtual Source-Axis Distances"
+(300A,030C)	VERS="3"	VR="SQ"   VM="1"	Keyword="SnoutSequence"		Name="Snout Sequence"
+(300A,030D)	VERS="3"	VR="FL"   VM="1"	Keyword="SnoutPosition"		Name="Snout Position"
+(300A,030F)	VERS="3"	VR="SH"   VM="1"	Keyword="SnoutID"		Name="Snout ID"
+(300A,0312)	VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfRangeShifters"		Name="Number of Range Shifters"
+(300A,0314)	VERS="3"	VR="SQ"   VM="1"	Keyword="RangeShifterSequence"		Name="Range Shifter Sequence"
+(300A,0316)	VERS="3"	VR="IS"   VM="1"	Keyword="RangeShifterNumber"		Name="Range Shifter Number"
+(300A,0318)	VERS="3"	VR="SH"   VM="1"	Keyword="RangeShifterID"		Name="Range Shifter ID"
+(300A,0320)	VERS="3"	VR="CS"   VM="1"	Keyword="RangeShifterType"		Name="Range Shifter Type"
+(300A,0322)	VERS="3"	VR="LO"   VM="1"	Keyword="RangeShifterDescription"		Name="Range Shifter Description"
+(300A,0330)	VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfLateralSpreadingDevices"		Name="Number of Lateral Spreading Devices"
+(300A,0332)	VERS="3"	VR="SQ"   VM="1"	Keyword="LateralSpreadingDeviceSequence"		Name="Lateral Spreading Device Sequence"
+(300A,0334)	VERS="3"	VR="IS"   VM="1"	Keyword="LateralSpreadingDeviceNumber"		Name="Lateral Spreading Device Number"
+(300A,0336)	VERS="3"	VR="SH"   VM="1"	Keyword="LateralSpreadingDeviceID"		Name="Lateral Spreading Device ID"
+(300A,0338)	VERS="3"	VR="CS"   VM="1"	Keyword="LateralSpreadingDeviceType"		Name="Lateral Spreading Device Type"
+(300A,033A)	VERS="3"	VR="LO"   VM="1"	Keyword="LateralSpreadingDeviceDescription"		Name="Lateral Spreading Device Description"
+(300A,033C)	VERS="3"	VR="FL"   VM="1"	Keyword="LateralSpreadingDeviceWaterEquivalentThickness"		Name="Lateral Spreading Device Water Equivalent Thickness"
+(300A,0340)	VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfRangeModulators"		Name="Number of Range Modulators"
+(300A,0342)	VERS="3"	VR="SQ"   VM="1"	Keyword="RangeModulatorSequence"		Name="Range Modulator Sequence"
+(300A,0344)	VERS="3"	VR="IS"   VM="1"	Keyword="RangeModulatorNumber"		Name="Range Modulator Number"
+(300A,0346)	VERS="3"	VR="SH"   VM="1"	Keyword="RangeModulatorID"		Name="Range Modulator ID"
+(300A,0348)	VERS="3"	VR="CS"   VM="1"	Keyword="RangeModulatorType"		Name="Range Modulator Type"
+(300A,034A)	VERS="3"	VR="LO"   VM="1"	Keyword="RangeModulatorDescription"		Name="Range Modulator Description"
+(300A,034C)	VERS="3"	VR="SH"   VM="1"	Keyword="BeamCurrentModulationID"		Name="Beam Current Modulation ID"
+(300A,0350)	VERS="3"	VR="CS"   VM="1"	Keyword="PatientSupportType"		Name="Patient Support Type"
+(300A,0352)	VERS="3"	VR="SH"   VM="1"	Keyword="PatientSupportID"		Name="Patient Support ID"
+(300A,0354)	VERS="3"	VR="LO"   VM="1"	Keyword="PatientSupportAccessoryCode"		Name="Patient Support Accessory Code"
+(300A,0356)	VERS="3"	VR="FL"   VM="1"	Keyword="FixationLightAzimuthalAngle"		Name="Fixation Light Azimuthal Angle"
+(300A,0358)	VERS="3"	VR="FL"   VM="1"	Keyword="FixationLightPolarAngle"		Name="Fixation Light Polar Angle"
+(300A,035A)	VERS="3"	VR="FL"   VM="1"	Keyword="MetersetRate"		Name="Meterset Rate"
+(300A,0360)	VERS="3"	VR="SQ"   VM="1"	Keyword="RangeShifterSettingsSequence"		Name="Range Shifter Settings Sequence"
+(300A,0362)	VERS="3"	VR="LO"   VM="1"	Keyword="RangeShifterSetting"		Name="Range Shifter Setting"
+(300A,0364)	VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToRangeShifterDistance"		Name="Isocenter to Range Shifter Distance"
+(300A,0366)	VERS="3"	VR="FL"   VM="1"	Keyword="RangeShifterWaterEquivalentThickness"		Name="Range Shifter Water Equivalent Thickness"
+(300A,0370)	VERS="3"	VR="SQ"   VM="1"	Keyword="LateralSpreadingDeviceSettingsSequence"		Name="Lateral Spreading Device Settings Sequence"
+(300A,0372)	VERS="3"	VR="LO"   VM="1"	Keyword="LateralSpreadingDeviceSetting"		Name="Lateral Spreading Device Setting"
+(300A,0374)	VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToLateralSpreadingDeviceDistance"		Name="Isocenter to Lateral Spreading Device Distance"
+(300A,0380)	VERS="3"	VR="SQ"   VM="1"	Keyword="RangeModulatorSettingsSequence"		Name="Range Modulator Settings Sequence"
+(300A,0382)	VERS="3"	VR="FL"   VM="1"	Keyword="RangeModulatorGatingStartValue"		Name="Range Modulator Gating Start Value"
+(300A,0384)	VERS="3"	VR="FL"   VM="1"	Keyword="RangeModulatorGatingStopValue"		Name="Range Modulator Gating Stop Value"
+(300A,0386)	VERS="3"	VR="FL"   VM="1"	Keyword="RangeModulatorGatingStartWaterEquivalentThickness"		Name="Range Modulator Gating Start Water Equivalent Thickness"
+(300A,0388)	VERS="3"	VR="FL"   VM="1"	Keyword="RangeModulatorGatingStopWaterEquivalentThickness"		Name="Range Modulator Gating Stop Water Equivalent Thickness"
+(300A,038A)	VERS="3"	VR="FL"   VM="1"	Keyword="IsocenterToRangeModulatorDistance"		Name="Isocenter to Range Modulator Distance"
+(300A,0390)	VERS="3"	VR="SH"   VM="1"	Keyword="ScanSpotTuneID"		Name="Scan Spot Tune ID"
+(300A,0392)	VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfScanSpotPositions"		Name="Number of Scan Spot Positions"
+(300A,0394)	VERS="3"	VR="FL"   VM="1-n"	Keyword="ScanSpotPositionMap"		Name="Scan Spot Position Map"
+(300A,0396)	VERS="3"	VR="FL"   VM="1-n"	Keyword="ScanSpotMetersetWeights"		Name="Scan Spot Meterset Weights"
+(300A,0398)	VERS="3"	VR="FL"   VM="2"	Keyword="ScanningSpotSize"		Name="Scanning Spot Size"
+(300A,039A)	VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfPaintings"		Name="Number of Paintings"
+(300A,03A0)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonToleranceTableSequence"		Name="Ion Tolerance Table Sequence"
+(300A,03A2)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonBeamSequence"		Name="Ion Beam Sequence"
+(300A,03A4)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonBeamLimitingDeviceSequence"		Name="Ion Beam Limiting Device Sequence"
+(300A,03A6)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonBlockSequence"		Name="Ion Block Sequence"
+(300A,03A8)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonControlPointSequence"		Name="Ion Control Point Sequence"
+(300A,03AA)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonWedgeSequence"		Name="Ion Wedge Sequence"
+(300A,03AC)	VERS="3"	VR="SQ"   VM="1"	Keyword="IonWedgePositionSequence"		Name="Ion Wedge Position Sequence"
+(300A,0401)	VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedSetupImageSequence"		Name="Referenced Setup Image Sequence"
+(300A,0402)	VERS="3"	VR="ST"   VM="1"	Keyword="SetupImageComment"		Name="Setup Image Comment"
+(300A,0410)	VERS="3"	VR="SQ"   VM="1"	Keyword="MotionSynchronizationSequence"		Name="Motion Synchronization Sequence"
+(300A,0412)	VERS="3"	VR="FL"   VM="3"	Keyword="ControlPointOrientation"		Name="Control Point Orientation"
+(300A,0420)	VERS="3"	VR="SQ"   VM="1"	Keyword="GeneralAccessorySequence"		Name="General Accessory Sequence"
+(300A,0421)	VERS="3"	VR="SH"   VM="1"	Keyword="GeneralAccessoryID"			Name="General Accessory ID"
+(300A,0422)	VERS="3"	VR="ST"   VM="1"	Keyword="GeneralAccessoryDescription"	Name="General Accessory Description"
+(300A,0423)	VERS="3"	VR="CS"   VM="1"	Keyword="GeneralAccessoryType"			Name="General Accessory Type"
+(300A,0424)	VERS="3"	VR="IS"   VM="1"	Keyword="GeneralAccessoryNumber"		Name="General Accessory Number"
+(300A,0425)	VERS="3"	VR="FL"   VM="1"	Keyword="SourceToGeneralAccessoryDistance"				Name="Source to General Accessory Distance"
+(300A,0431)	VERS="3"	VR="SQ"   VM="1"	Keyword="ApplicatorGeometrySequence"					Name="Applicator Geometry Sequence"
+(300A,0432)	VERS="3"	VR="CS"   VM="1"	Keyword="ApplicatorApertureShape"						Name="Applicator Aperture Shape"
+(300A,0433)	VERS="3"	VR="FL"   VM="1"	Keyword="ApplicatorOpening"								Name="Applicator Opening"
+(300A,0434)	VERS="3"	VR="FL"   VM="1"	Keyword="ApplicatorOpeningX"							Name="Applicator Opening X"
+(300A,0435)	VERS="3"	VR="FL"   VM="1"	Keyword="ApplicatorOpeningY"							Name="Applicator Opening Y"
+(300A,0436)	VERS="3"	VR="FL"   VM="1"	Keyword="SourceToApplicatorMountingPositionDistance"	Name="Source to Applicator Mounting Position Distance"
+(300A,0440)	VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfBlockSlabItems"		Name="Number of Block Slab Items"
+(300A,0441)	VERS="3"	VR="SQ"   VM="1"	Keyword="BlockSlabSequence"				Name="Block Slab Sequence"
+(300A,0442)	VERS="3"	VR="DS"   VM="1"	Keyword="BlockSlabThickness"			Name="Block Slab Thickness"
+(300A,0443)	VERS="3"	VR="US"   VM="1"	Keyword="BlockSlabNumber"				Name="Block Slab Number"
+(300A,0450)	VERS="3"	VR="SQ"   VM="1"	Keyword="DeviceMotionControlSequence"			Name="Device Motion Control Sequence"
+(300A,0451)	VERS="3"	VR="CS"   VM="1"	Keyword="DeviceMotionExecutionMode"			Name="Device Motion Execution Mode"
+(300A,0452)	VERS="3"	VR="CS"   VM="1"	Keyword="DeviceMotionObservationMode"		Name="Device Motion Observation Mode"
+(300A,0453)	VERS="3"	VR="SQ"   VM="1"	Keyword="DeviceMotionParameterCodeSequence"	Name="Device Motion Parameter Code Sequence"
+(300C,0002) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedRTPlanSequence"		Name="Referenced RT Plan Sequence"
+(300C,0004) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedBeamSequence"		Name="Referenced Beam Sequence"
+(300C,0006) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedBeamNumber"			Name="Referenced Beam Number"
+(300C,0007) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedReferenceImageNumber"	Name="Referenced Reference Image Number"
+(300C,0008) VERS="3"	VR="DS"   VM="1"	Keyword="StartCumulativeMetersetWeight"		Name="Start Cumulative Meterset Weight"
+(300C,0009) VERS="3"	VR="DS"   VM="1"	Keyword="EndCumulativeMetersetWeight"		Name="End Cumulative Meterset Weight"
+(300C,000A) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedBrachyApplicationSetupSequence"	Name="Referenced Brachy Application Setup Sequence"
+(300C,000C) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedBrachyApplicationSetupNumber"	Name="Referenced Brachy Application Setup Number"
+(300C,000E) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedSourceNumber"		Name="Referenced Source Number"
+(300C,0020) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedFractionGroupSequence"	Name="Referenced Fraction Group Sequence"
+(300C,0022) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedFractionGroupNumber"		Name="Referenced Fraction Group Number"
+(300C,0040) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedVerificationImageSequence"	Name="Referenced Verification Image Sequence"
+(300C,0042) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedReferenceImageSequence"	Name="Referenced Reference Image Sequence"
+(300C,0050) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedDoseReferenceSequence"	Name="Referenced Dose Reference Sequence"
+(300C,0051) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedDoseReferenceNumber"		Name="Referenced Dose Reference Number"
+(300C,0055) VERS="3"	VR="SQ"   VM="1"	Keyword="BrachyReferencedDoseReferenceSequence"	Name="Brachy Referenced Dose Reference Sequence"
+(300C,0060) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedStructureSetSequence"	Name="Referenced Structure Set Sequence"
+(300C,006A) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedPatientSetupNumber"		Name="Referenced Patient Setup Number"
+(300C,0080) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedDoseSequence"		Name="Referenced Dose Sequence"
+(300C,00A0) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedToleranceTableNumber"	Name="Referenced Tolerance Table Number"
+(300C,00B0) VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedBolusSequence"		Name="Referenced Bolus Sequence"
+(300C,00C0) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedWedgeNumber"			Name="Referenced Wedge Number"
+(300C,00D0) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedCompensatorNumber"		Name="Referenced Compensator Number"
+(300C,00E0) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedBlockNumber"			Name="Referenced Block Number"
+(300C,00F0) VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedControlPointIndex"		Name="Referenced Control Point Index"
+(300C,00F2)	VERS="3"	VR="SQ"   VM="1"	Keyword="ReferencedControlPointSequence"		Name="Referenced Control Point Sequence"
+(300C,00F4)	VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedStartControlPointIndex"		Name="Referenced Start Control Point Index"
+(300C,00F6)	VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedStopControlPointIndex"		Name="Referenced Stop Control Point Index"
+(300C,0100)	VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedRangeShifterNumber"			Name="Referenced Range Shifter Number"
+(300C,0102)	VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedLateralSpreadingDeviceNumber"		Name="Referenced Lateral Spreading Device Number"
+(300C,0104)	VERS="3"	VR="IS"   VM="1"	Keyword="ReferencedRangeModulatorNumber"		Name="Referenced Range Modulator Number"
+(300C,0111)	VERS="3"	VR="SQ"   VM="1"	Keyword="OmittedBeamTaskSequence"			Name="Omitted Beam Task Sequence"
+(300C,0112)	VERS="3"	VR="CS"   VM="1"	Keyword="ReasonForOmission"					Name="Reason for Omission"
+(300C,0113)	VERS="3"	VR="LO"   VM="1"	Keyword="ReasonForOmissionDescription"		Name="Reason for Omission Description"
+(300E,0002) VERS="3"	VR="CS"   VM="1"	Keyword="ApprovalStatus"			Name="Approval Status"
+(300E,0004) VERS="3"	VR="DA"   VM="1"	Keyword="ReviewDate"				Name="Review Date"
+(300E,0005) VERS="3"	VR="TM"   VM="1"	Keyword="ReviewTime"				Name="Review Time"
+(300E,0008) VERS="3"	VR="PN"   VM="1"	Keyword="ReviewerName"				Name="Reviewer Name"
+(4000,0010) VERS="RET"	VR="LT"   VM="1"	Keyword="Arbitrary"					Name="Arbitrary"
+(4000,4000) VERS="RET"	VR="LT"   VM="1"	Keyword="TextComments"				Name="Text Comments"
+(4008,0040) VERS="RET"	VR="SH"   VM="1"	Keyword="ResultsID"				Name="Results ID"
+(4008,0042) VERS="RET"	VR="LO"   VM="1"	Keyword="ResultsIDIssuer"			Name="Results ID Issuer"
+(4008,0050) VERS="RET"	VR="SQ"   VM="1"	Keyword="ReferencedInterpretationSequence"	Name="Referenced Interpretation Sequence"
+(4008,00FF) VERS="RET"	VR="CS"   VM="1"	Keyword="ReportProductionStatusTrial"				Name="Report Production Status (Trial)"
+(4008,0100) VERS="RET"	VR="DA"   VM="1"	Keyword="InterpretationRecordedDate"		Name="Interpretation Recorded Date"
+(4008,0101) VERS="RET"	VR="TM"   VM="1"	Keyword="InterpretationRecordedTime"		Name="Interpretation Recorded Time"
+(4008,0102) VERS="RET"	VR="PN"   VM="1"	Keyword="InterpretationRecorder"		Name="Interpretation Recorder"
+(4008,0103) VERS="RET"	VR="LO"   VM="1"	Keyword="ReferenceToRecordedSound"		Name="Reference to Recorded Sound"
+(4008,0108) VERS="RET"	VR="DA"   VM="1"	Keyword="InterpretationTranscriptionDate"	Name="Interpretation Transcription Date"
+(4008,0109) VERS="RET"	VR="TM"   VM="1"	Keyword="InterpretationTranscriptionTime"	Name="Interpretation Transcription Time"
+(4008,010A) VERS="RET"	VR="PN"   VM="1"	Keyword="InterpretationTranscriber"		Name="Interpretation Transcriber"
+(4008,010B) VERS="RET"	VR="ST"   VM="1"	Keyword="InterpretationText"			Name="Interpretation Text"
+(4008,010C) VERS="RET"	VR="PN"   VM="1"	Keyword="InterpretationAuthor"			Name="Interpretation Author"
+(4008,0111) VERS="RET"	VR="SQ"   VM="1"	Keyword="InterpretationApproverSequence"	Name="Interpretation Approver Sequence"
+(4008,0112) VERS="RET"	VR="DA"   VM="1"	Keyword="InterpretationApprovalDate"		Name="Interpretation Approval Date"
+(4008,0113) VERS="RET"	VR="TM"   VM="1"	Keyword="InterpretationApprovalTime"		Name="Interpretation Approval Time"
+(4008,0114) VERS="RET"	VR="PN"   VM="1"	Keyword="PhysicianApprovingInterpretation"	Name="Physician Approving Interpretation"
+(4008,0115) VERS="RET"	VR="LT"   VM="1"	Keyword="InterpretationDiagnosisDescription"	Name="Interpretation Diagnosis Description"
+(4008,0117) VERS="RET"	VR="SQ"   VM="1"	Keyword="InterpretationDiagnosisCodeSequence"	Name="Interpretation Diagnosis Code Sequence"
+(4008,0118) VERS="RET"	VR="SQ"   VM="1"	Keyword="ResultsDistributionListSequence"	Name="Results Distribution List Sequence"
+(4008,0119) VERS="RET"	VR="PN"   VM="1"	Keyword="DistributionName"			Name="Distribution Name"
+(4008,011A) VERS="RET"	VR="LO"   VM="1"	Keyword="DistributionAddress"			Name="Distribution Address"
+(4008,0200) VERS="RET"	VR="SH"   VM="1"	Keyword="InterpretationID"			Name="Interpretation ID"
+(4008,0202) VERS="RET"	VR="LO"   VM="1"	Keyword="InterpretationIDIssuer"		Name="Interpretation ID Issuer"
+(4008,0210) VERS="RET"	VR="CS"   VM="1"	Keyword="InterpretationTypeID"			Name="Interpretation Type ID"
+(4008,0212) VERS="RET"	VR="CS"   VM="1"	Keyword="InterpretationStatusID"		Name="Interpretation Status ID"
+(4008,0300) VERS="RET"	VR="ST"   VM="1"	Keyword="Impressions"				Name="Impressions"
+(4008,4000) VERS="RET"	VR="ST"   VM="1"	Keyword="ResultsComments"			Name="Results Comments"
+(4FFE,0001) VERS="3"	VR="SQ"   VM="1"	Keyword="MACParametersSequence"			Name="MAC Parameters Sequence"
+(50xx,0005) VERS="RET"	VR="US"   VM="1"	Keyword="CurveDimensions"			Name="Curve Dimensions"
+(50xx,0010) VERS="RET"	VR="US"   VM="1"	Keyword="NumberOfPoints"			Name="Number of Points"
+(50xx,0020) VERS="RET"	VR="CS"   VM="1"	Keyword="TypeOfData"				Name="Type of Data"
+(50xx,0022) VERS="RET"	VR="LO"   VM="1"	Keyword="CurveDescription"			Name="Curve Description"
+(50xx,0030) VERS="RET"	VR="SH"   VM="1-n"	Keyword="AxisUnits"				Name="Axis Units"
+(50xx,0040) VERS="RET"	VR="SH"   VM="1-n"	Keyword="AxisLabels"				Name="Axis Labels"
+(50xx,0103) VERS="RET"	VR="US"   VM="1"	Keyword="DataValueRepresentation"		Name="Data Value Representation"
+(50xx,0104) VERS="RET"	VR="US"   VM="1-n"	Keyword="MinimumCoordinateValue"		Name="Minimum Coordinate Value"
+(50xx,0105) VERS="RET"	VR="US"   VM="1-n"	Keyword="MaximumCoordinateValue"		Name="Maximum Coordinate Value"
+(50xx,0106) VERS="RET"	VR="SH"   VM="1-n"	Keyword="CurveRange"				Name="Curve Range"
+(50xx,0110) VERS="RET"	VR="US"   VM="1-n"	Keyword="CurveDataDescriptor"			Name="Curve Data Descriptor"
+(50xx,0112) VERS="RET"	VR="US"   VM="1-n"	Keyword="CoordinateStartValue"			Name="Coordinate Start Value"
+(50xx,0114) VERS="RET"	VR="US"   VM="1-n"	Keyword="CoordinateStepValue"			Name="Coordinate Step Value"
+(50xx,1001) VERS="RET"	VR="CS"   VM="1"	Keyword="CurveActivationLayer"				Name="Curve Activation Layer"
+(50xx,2000) VERS="RET"	VR="US"   VM="1"	Keyword="AudioType"				Name="Audio Type"
+(50xx,2002) VERS="RET"	VR="US"   VM="1"	Keyword="AudioSampleFormat"			Name="Audio Sample Format"
+(50xx,2004) VERS="RET"	VR="US"   VM="1"	Keyword="NumberOfChannels"			Name="Number of Channels"
+(50xx,2006) VERS="RET"	VR="UL"   VM="1"	Keyword="NumberOfSamples"			Name="Number of Samples"
+(50xx,2008) VERS="RET"	VR="UL"   VM="1"	Keyword="SampleRate"				Name="Sample Rate"
+(50xx,200A) VERS="RET"	VR="UL"   VM="1"	Keyword="TotalTime"				Name="Total Time"
+(50xx,200C) VERS="RET"	VR="OW/OB"   VM="1"	Keyword="AudioSampleData"			Name="Audio Sample Data"
+(50xx,200E) VERS="RET"	VR="LT"   VM="1"	Keyword="AudioComments"				Name="Audio Comments"
+(50xx,2500) VERS="RET"	VR="LO"   VM="1"	Keyword="CurveLabel"				Name="Curve Label"
+(50xx,2600) VERS="RET"	VR="SQ"   VM="1"	Keyword="CurveReferencedOverlaySequence"	Name="Curve Referenced Overlay Sequence"
+(50xx,2610) VERS="RET"	VR="US"   VM="1"	Keyword="CurveReferencedOverlayGroup"		Name="Curve Referenced Overlay Group"
+(50xx,3000) VERS="RET"	VR="OW/OB"   VM="1"	Keyword="CurveData"				Name="Curve Data"
+(5200,9229) VERS="3"	VR="SQ"   VM="1"	Keyword="SharedFunctionalGroupsSequence"	Name="Shared Functional Groups Sequence"
+(5200,9230) VERS="3"	VR="SQ"   VM="1"	Keyword="PerFrameFunctionalGroupsSequence"	Name="Per-frame Functional Groups Sequence"
+(5400,0100) VERS="3"	VR="SQ"   VM="1"	Keyword="WaveformSequence"			Name="Waveform Sequence"
+(5400,0110) VERS="3"	VR="OW/OB" VM="1"	Keyword="ChannelMinimumValue"			Name="Channel Minimum Value"
+(5400,0112) VERS="3"	VR="OW/OB" VM="1"	Keyword="ChannelMaximumValue"			Name="Channel Maximum Value"
+(5400,1004) VERS="3"	VR="US"   VM="1"	Keyword="WaveformBitsAllocated"			Name="Waveform Bits Allocated"
+(5400,1006) VERS="3"	VR="CS"   VM="1"	Keyword="WaveformSampleInterpretation"		Name="Waveform Sample Interpretation"
+(5400,100A) VERS="3"	VR="OW/OB" VM="1"	Keyword="WaveformPaddingValue"			Name="Waveform Padding Value"
+(5400,1010) VERS="3"	VR="OW/OB" VM="1"	Keyword="WaveformData"				Name="Waveform Data"
+(5600,0010) VERS="3"	VR="OF"   VM="1"	Keyword="FirstOrderPhaseCorrectionAngle"	Name="First Order Phase Correction Angle"
+(5600,0020) VERS="3"	VR="OF"   VM="1"	Keyword="SpectroscopyData"			Name="Spectroscopy Data"
+(60xx,0010) VERS="3"	VR="US"   VM="1"	Keyword="OverlayRows"				Name="Overlay Rows"
+(60xx,0011) VERS="3"	VR="US"   VM="1"	Keyword="OverlayColumns"			Name="Overlay Columns"
+(60xx,0012) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayPlanes"				Name="Overlay Planes"
+(60xx,0015) VERS="3"	VR="IS"   VM="1"	Keyword="NumberOfFramesInOverlay"		Name="Number of Frames in Overlay"
+(60xx,0022) VERS="3"	VR="LO"   VM="1"	Keyword="OverlayDescription"			Name="Overlay Description"
+(60xx,0040) VERS="3"	VR="CS"   VM="1"	Keyword="OverlayType"				Name="Overlay Type"
+(60xx,0045) VERS="3"	VR="LO"   VM="1"	Keyword="OverlaySubtype"			Name="Overlay Subtype"
+(60xx,0050) VERS="3"	VR="SS"   VM="2"	Keyword="OverlayOrigin"				Name="Overlay Origin"
+(60xx,0051) VERS="3"	VR="US"   VM="1"	Keyword="ImageFrameOrigin"			Name="Image Frame Origin"
+(60xx,0052) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayPlaneOrigin"				Name="OverlayPlane Origin"
+(60xx,0060) VERS="RET"	VR="LT"   VM="1"	Keyword="OverlayCompressionCode"		Name="Overlay Compression Code"
+(60xx,0061) VERS="RET"	VR="SH"   VM="1"	Keyword="OverlayCompressionOriginator"		Name="Overlay Compression Originator"
+(60xx,0062) VERS="RET"	VR="SH"   VM="1"	Keyword="OverlayCompressionLabel"		Name="Overlay Compression Label"
+(60xx,0063) VERS="RET"	VR="CS"   VM="1"	Keyword="OverlayCompressionDescription"		Name="Overlay Compression Description"
+(60xx,0066) VERS="RET"	VR="AT"   VM="1-n"	Keyword="OverlayCompressionStepPointers"	Name="Overlay Compression Step Pointers"
+(60xx,0068) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayRepeatInterval"			Name="Overlay Repeat Interval"
+(60xx,0069) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayBitsGrouped"			Name="Overlay Bits Grouped"
+(60xx,0100) VERS="3"	VR="US"   VM="1"	Keyword="OverlayBitsAllocated"			Name="Overlay Bits Allocated"
+(60xx,0102) VERS="3"	VR="US"   VM="1"	Keyword="OverlayBitPosition"			Name="Overlay Bit Position"
+(60xx,0110) VERS="RET"	VR="LT"   VM="1"	Keyword="OverlayFormat"				Name="Overlay Format"
+(60xx,0200) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayLocation"			Name="Overlay Location"
+(60xx,0800) VERS="RET"	VR="CS"   VM="1-n"	Keyword="OverlayCodeLabel"			Name="Overlay Code Label"
+(60xx,0802) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayNumberOfTables"			Name="Overlay Number of Tables"
+(60xx,0803) VERS="RET"	VR="AT"   VM="1-n"	Keyword="OverlayCodeTableLocation"		Name="Overlay Code Table Location"
+(60xx,0804) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayBitsForCodeWord"		Name="Overlay Bits For Code Word"
+(60xx,1001) VERS="3"	VR="CS"   VM="1"	Keyword="OverlayActivationLayer"			Name="Overlay Activation Layer"
+(60xx,1100) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayDescriptorGray"			Name="Overlay Descriptor - Gray"
+(60xx,1101) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayDescriptorRed"			Name="Overlay Descriptor - Red"
+(60xx,1102) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayDescriptorGreen"		Name="Overlay Descriptor - Green"
+(60xx,1103) VERS="RET"	VR="US"   VM="1"	Keyword="OverlayDescriptorBlue"			Name="Overlay Descriptor - Blue"
+(60xx,1200) VERS="RET"	VR="US"   VM="1-n"	Keyword="OverlayGray"				Name="Overlays - Gray"
+(60xx,1201) VERS="RET"	VR="US"   VM="1-n"	Keyword="OverlayRed"				Name="Overlays - Red"
+(60xx,1202) VERS="RET"	VR="US"   VM="1-n"	Keyword="OverlayGreen"				Name="Overlays - Green"
+(60xx,1203) VERS="RET"	VR="US"   VM="1-n"	Keyword="OverlayBlue"				Name="Overlays - Blue"
+(60xx,1301) VERS="3"	VR="IS"   VM="1"	Keyword="ROIArea"				Name="ROI Area"
+(60xx,1302) VERS="3"	VR="DS"   VM="1"	Keyword="ROIMean"				Name="ROI Mean"
+(60xx,1303) VERS="3"	VR="DS"   VM="1"	Keyword="ROIStandardDeviation"			Name="ROI Standard Deviation"
+(60xx,1500) VERS="3"	VR="LO"   VM="1"	Keyword="OverlayLabel"				Name="Overlay Label"
+(60xx,3000) VERS="3"	VR="OW/OB"   VM="1"	Keyword="OverlayData"				Name="Overlay Data"
+(60xx,4000) VERS="RET"	VR="LT"   VM="1-n"	Keyword="OverlayComments"			Name="Overlay Comments"
+(7FE0,0008) VERS="3"	VR="OF"   VM="1"	Keyword="FloatPixelData"			Name="Float Pixel Data"
+(7FE0,0009) VERS="3"	VR="OD"   VM="1"	Keyword="DoubleFloatPixelData"		Name="Double Float Pixel Data"
+(7FE0,0010) VERS="3"	VR="OW/OB"   VM="1"	Keyword="PixelData"				Name="Pixel Data"
+(7FE0,0020) VERS="RET"	VR="OW"   VM="1"	Keyword="CoefficientsSDVN"			Name="Coefficients SDVN"
+(7FE0,0030) VERS="RET"	VR="OW"   VM="1"	Keyword="CoefficientsSDHN"			Name="Coefficients SDHN"
+(7FE0,0040) VERS="RET"	VR="OW"   VM="1"	Keyword="CoefficientsSDDN"			Name="Coefficients SDDN"
+(7Fxx,0010) VERS="RET"	VR="OW/OB"   VM="1"	Keyword="VariablePixelData"			Name="Variable Pixel Data"
+(7Fxx,0011) VERS="RET"	VR="US"   VM="1"	Keyword="VariableNextDataGroup"			Name="Variable Next Data Group"
+(7Fxx,0020) VERS="RET"	VR="OW"   VM="1"	Keyword="VariableCoefficientsSDVN"		Name="Variable Coefficients SDVN"
+(7Fxx,0030) VERS="RET"	VR="OW"   VM="1"	Keyword="VariableCoefficientsSDHN"		Name="Variable Coefficients SDHN"
+(7Fxx,0040) VERS="RET"	VR="OW"   VM="1"	Keyword="VariableCoefficientsSDDN"		Name="Variable Coefficients SDDN"
+(FFFA,FFFA) VERS="3"	VR="SQ"   VM="1"	Keyword="DigitalSignaturesSequence"		Name="Digital Signatures Sequence"
+(FFFC,FFFC) VERS="3"	VR="OB"   VM="1"	Keyword="DataSetTrailingPadding"		Name="Data Set Trailing Padding"
+(FFFE,E000) VERS="3"	VR="NONE" VM="1"	Keyword="Item"					Name="Item"
+(FFFE,E00D) VERS="3"	VR="NONE" VM="1"	Keyword="ItemDelimitationItem"			Name="Item Delimitation Item"
+(FFFE,E0DD) VERS="3"	VR="NONE" VM="1"	Keyword="SequenceDelimitationItem"		Name="Sequence Delimitation Item"
diff --git a/libsrc/standard/elmdict/diconde.tpl b/libsrc/standard/elmdict/diconde.tpl
new file mode 100644
index 0000000..32ef198
--- /dev/null
+++ b/libsrc/standard/elmdict/diconde.tpl
@@ -0,0 +1,192 @@
+(0014,0023) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="CADFileFormatRetired"								Name="CAD File Format (Retired)"
+(0014,0024) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="ComponentReferenceSystemRetired"					Name="Component Reference System (Retired)"
+(0014,0025) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="ComponentManufacturingProcedure"					Name="Component Manufacturing Procedure"
+(0014,0028) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="ComponentManufacturer"								Name="Component Manufacturer"
+(0014,0030) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="MaterialThickness"									Name="Material Thickness"
+(0014,0032) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="MaterialPipeDiameter"								Name="Material Pipe Diameter"
+(0014,0034) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="MaterialIsolationDiameter"							Name="Material Isolation Diameter"
+(0014,0042) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="MaterialGrade"										Name="Material Grade"
+(0014,0044) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="MaterialPropertiesDescription"						Name="Material Properties Description"
+(0014,0045) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="MaterialPropertiesFileFormatRetired"				Name="Material Properties File Format (Retired)"
+(0014,0046) VERS="DICONDE"	VR="LT"   VM="1"	Keyword="MaterialNotes"										Name="Material Notes"
+(0014,0050) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="ComponentShape"									Name="Component Shape"
+(0014,0052) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="CurvatureType"										Name="Curvature Type"
+(0014,0054) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="OuterDiameter"										Name="Outer Diameter"
+(0014,0056) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="InnerDiameter"										Name="Inner Diameter"
+(0014,0100) VERS="DICONDE"	VR="LO"   VM="1-n"	Keyword="ComponentWelderIDs"								Name="Component Welder IDs"
+(0014,0101) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="SecondaryApprovalStatus"							Name="Secondary Approval Status"
+(0014,0102) VERS="DICONDE"	VR="DA"   VM="1"	Keyword="SecondaryReviewDate"								Name="Secondary Review Date"
+(0014,0103) VERS="DICONDE"	VR="TM"   VM="1"	Keyword="SecondaryReviewTime"								Name="Secondary Review Time"
+(0014,0104) VERS="DICONDE"	VR="PN"   VM="1"	Keyword="SecondaryReviewerName"								Name="Secondary Reviewer Name"
+(0014,0105) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="RepairID"											Name="Repair ID"
+(0014,0106) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="MultipleComponentApprovalSequence"					Name="Multiple Component Approval Sequence"
+(0014,0107) VERS="DICONDE"	VR="CS"   VM="1-n"	Keyword="OtherApprovalStatus"								Name="Other Approval Status"
+(0014,0108) VERS="DICONDE"	VR="CS"   VM="1-n"	Keyword="OtherSecondaryApprovalStatus"						Name="Other Secondary Approval Status"
+(0014,1010) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="ActualEnvironmentalConditions"						Name="Actual Environmental Conditions"
+(0014,1020) VERS="DICONDE"	VR="DA"   VM="1"	Keyword="ExpiryDate"										Name="Expiry Date"
+(0014,1040) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="EnvironmentalConditions"							Name="Environmental Conditions"
+(0014,2002) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="EvaluatorSequence"									Name="Evaluator Sequence"
+(0014,2004) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="EvaluatorNumber"									Name="Evaluator Number"
+(0014,2006) VERS="DICONDE"	VR="PN"   VM="1"	Keyword="EvaluatorName"										Name="Evaluator Name"
+(0014,2008) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="EvaluationAttempt"									Name="Evaluation Attempt"
+(0014,2012) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="IndicationSequence"								Name="Indication Sequence"
+(0014,2014) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="IndicationNumber"									Name="Indication Number "
+(0014,2016) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="IndicationLabel"									Name="Indication Label"
+(0014,2018) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="IndicationDescription"								Name="Indication Description"
+(0014,201A) VERS="DICONDE"	VR="CS"   VM="1-n"	Keyword="IndicationType"									Name="Indication Type"
+(0014,201C) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="IndicationDisposition"								Name="Indication Disposition"
+(0014,201E) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="IndicationROISequence"								Name="Indication ROI Sequence"
+(0014,2030) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="IndicationPhysicalPropertySequence"				Name="Indication Physical Property Sequence"
+(0014,2032) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="PropertyLabel"										Name="Property Label"
+(0014,2202) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="CoordinateSystemNumberOfAxes"						Name="Coordinate System Number of Axes "
+(0014,2204) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="CoordinateSystemAxesSequence"						Name="Coordinate System Axes Sequence"
+(0014,2206) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="CoordinateSystemAxisDescription"					Name="Coordinate System Axis Description"
+(0014,2208) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="CoordinateSystemDataSetMapping"					Name="Coordinate System Data Set Mapping"
+(0014,220A) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="CoordinateSystemAxisNumber"						Name="Coordinate System Axis Number"
+(0014,220C) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="CoordinateSystemAxisType"							Name="Coordinate System Axis Type"
+(0014,220E) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="CoordinateSystemAxisUnits"							Name="Coordinate System Axis Units"
+(0014,2210) VERS="DICONDE"	VR="OB"   VM="1"	Keyword="CoordinateSystemAxisValues"						Name="Coordinate System Axis Values"
+(0014,2220) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="CoordinateSystemTransformSequence"					Name="Coordinate System Transform Sequence"
+(0014,2222) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="TransformDescription"								Name="Transform Description"
+(0014,2224) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="TransformNumberOfAxes"								Name="Transform Number of Axes"
+(0014,2226) VERS="DICONDE"	VR="IS"   VM="1-n"	Keyword="TransformOrderOfAxes"								Name="Transform Order of Axes"
+(0014,2228) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="TransformedAxisUnits"								Name="Transformed Axis Units"
+(0014,222A) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="CoordinateSystemTransformRotationAndScaleMatrix"	Name="Coordinate System Transform Rotation and Scale Matrix"
+(0014,222C) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="CoordinateSystemTransformTranslationMatrix"		Name="Coordinate System Transform Translation Matrix"
+(0014,3011) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="InternalDetectorFrameTime"							Name="Internal Detector Frame Time"
+(0014,3012) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="NumberOfFramesIntegrated"							Name="Number of Frames Integrated"
+(0014,3020) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="DetectorTemperatureSequence"						Name="Detector Temperature Sequence"
+(0014,3022) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="SensorName"										Name="Sensor Name"
+(0014,3024) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="HorizontalOffsetOfSensor"							Name="Horizontal Offset of Sensor"
+(0014,3026) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="VerticalOffsetOfSensor"							Name="Vertical Offset of Sensor"
+(0014,3028) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="SensorTemperature"									Name="Sensor Temperature"
+(0014,3040) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="DarkCurrentSequence"								Name="Dark Current Sequence"
+(0014,3050) VERS="DICONDE"	VR="OW/OB" VM="1"	Keyword="DarkCurrentCounts"									Name="Dark Current Counts"
+(0014,3060) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="GainCorrectionReferenceSequence"					Name="Gain Correction Reference Sequence"
+(0014,3070) VERS="DICONDE"	VR="OW/OB" VM="1"	Keyword="AirCounts"											Name="Air Counts"
+(0014,3071) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="KVUsedInGainCalibration"							Name="KV Used in Gain Calibration"
+(0014,3072) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MAUsedInGainCalibration"							Name="MA Used in Gain Calibration"
+(0014,3073) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="NumberOfFramesUsedForIntegration"					Name="Number of Frames Used for Integration"
+(0014,3074) VERS="DICONDE"	VR="LO"   VM="1"	Keyword="FilterMaterialUsedInGainCalibration"				Name="Filter Material Used in Gain Calibration"
+(0014,3075) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="FilterThicknessUsedInGainCalibration"				Name="Filter Thickness Used in Gain Calibration"
+(0014,3076) VERS="DICONDE"	VR="DA"   VM="1"	Keyword="DateOfGainCalibration"								Name="Date of Gain Calibration"
+(0014,3077) VERS="DICONDE"	VR="TM"   VM="1"	Keyword="TimeOfGainCalibration"								Name="Time of Gain Calibration"
+(0014,3080) VERS="DICONDE"	VR="OB"   VM="1"	Keyword="BadPixelImage"										Name="Bad Pixel Image"
+(0014,3099) VERS="DICONDE"	VR="LT"   VM="1"	Keyword="CalibrationNotes"									Name="Calibration Notes"
+(0014,4002) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="PulserEquipmentSequence"							Name="Pulser Equipment Sequence"
+(0014,4004) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="PulserType"										Name="Pulser Type"
+(0014,4006) VERS="DICONDE"	VR="LT"   VM="1"	Keyword="PulserNotes"										Name="Pulser Notes"
+(0014,4008) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ReceiverEquipmentSequence"							Name="Receiver Equipment Sequence"
+(0014,400A) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="AmplifierType"										Name="Amplifier Type"
+(0014,400C) VERS="DICONDE"	VR="LT"   VM="1"	Keyword="ReceiverNotes"										Name="Receiver Notes"
+(0014,400E) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="PreAmplifierEquipmentSequence"						Name="Pre-Amplifier Equipment Sequence"
+(0014,400F) VERS="DICONDE"	VR="LT"   VM="1"	Keyword="PreAmplifierNotes"									Name="Pre-Amplifier Notes"
+(0014,4010) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="TransmitTransducerSequence"						Name="Transmit Transducer Sequence"
+(0014,4011) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ReceiveTransducerSequence"							Name="Receive Transducer Sequence"
+(0014,4012) VERS="DICONDE"	VR="US"   VM="1"	Keyword="NumberOfElements"									Name="Number of Elements"
+(0014,4013) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="ElementShape"										Name="Element Shape"
+(0014,4014) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ElementDimensionA"									Name="Element Dimension A"
+(0014,4015) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ElementDimensionB"									Name="Element Dimension B"
+(0014,4016) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ElementPitchA"										Name="Element Pitch A"
+(0014,4017) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MeasuredBeamDimensionA"							Name="Measured Beam Dimension A"
+(0014,4018) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MeasuredBeamDimensionB"							Name="Measured Beam Dimension B"
+(0014,4019) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="LocationOfMeasuredBeamDiameter"					Name="Location of Measured Beam Diameter"
+(0014,401A) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="NominalFrequency"									Name="Nominal Frequency"
+(0014,401B) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MeasuredCenterFrequency"							Name="Measured Center Frequency"
+(0014,401C) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MeasuredBandwidth"									Name="Measured Bandwidth"
+(0014,401D) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ElementPitchB"										Name="Element Pitch B"
+(0014,4020) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="PulserSettingsSequence"							Name="Pulser Settings Sequence"
+(0014,4022) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="PulseWidth"										Name="Pulse Width"
+(0014,4024) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ExcitationFrequency"								Name="Excitation Frequency"
+(0014,4026) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="ModulationType"									Name="Modulation Type"
+(0014,4028) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="Damping"											Name="Damping"
+(0014,4030) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ReceiverSettingsSequence"							Name="Receiver Settings Sequence"
+(0014,4031) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="AcquiredSoundpathLength"							Name="Acquired Soundpath Length"
+(0014,4032) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="AcquisitionCompressionType"						Name="Acquisition Compression Type"
+(0014,4033) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="AcquisitionSampleSize"								Name="Acquisition Sample Size"
+(0014,4034) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="RectifierSmoothing"								Name="Rectifier Smoothing"
+(0014,4035) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="DACSequence"										Name="DAC Sequence"
+(0014,4036) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="DACType"											Name="DAC Type"
+(0014,4038) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="DACGainPoints"										Name="DAC Gain Points"
+(0014,403A) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="DACTimePoints"										Name="DAC Time Points"
+(0014,403C) VERS="DICONDE"	VR="DS"   VM="1-n"	Keyword="DACAmplitude"										Name="DAC Amplitude"
+(0014,4040) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="PreAmplifierSettingsSequence"						Name="Pre-Amplifier Settings Sequence"
+(0014,4050) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="TransmitTransducerSettingsSequence"				Name="Transmit Transducer Settings Sequence"
+(0014,4051) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ReceiveTransducerSettingsSequence"					Name="Receive Transducer Settings Sequence"
+(0014,4052) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="IncidentAngle"										Name="Incident Angle"
+(0014,4054) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="CouplingTechnique"									Name="Coupling Technique"
+(0014,4056) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="CouplingMedium"									Name="Coupling Medium"
+(0014,4057) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="CouplingVelocity"									Name="Coupling Velocity"
+(0014,4058) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ProbeCenterLocationX"								Name="Probe Center Location X"
+(0014,4059) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ProbeCenterLocationZ"								Name="Probe Center Location Z"
+(0014,405A) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="SoundPathLength"									Name="Sound Path Length"
+(0014,405C) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="DelayLawIdentifier"								Name="Delay Law Identifier"
+(0014,4060) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="GateSettingsSequence"								Name="Gate Settings Sequence"
+(0014,4062) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="GateThreshold"										Name="Gate Threshold"
+(0014,4064) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="VelocityOfSound"									Name="Velocity of Sound"
+(0014,4070) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="CalibrationSettingsSequence"						Name="Calibration Settings Sequence"
+(0014,4072) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="CalibrationProcedure"								Name="Calibration Procedure"
+(0014,4074) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="ProcedureVersion"									Name="Procedure Version"
+(0014,4076) VERS="DICONDE"	VR="DA"   VM="1"	Keyword="ProcedureCreationDate"								Name="Procedure Creation Date"
+(0014,4078) VERS="DICONDE"	VR="DA"   VM="1"	Keyword="ProcedureExpirationDate"							Name="Procedure Expiration Date"
+(0014,407A) VERS="DICONDE"	VR="DA"   VM="1"	Keyword="ProcedureLastModifiedDate"							Name="Procedure Last Modified Date"
+(0014,407C) VERS="DICONDE"	VR="TM"   VM="1-n"	Keyword="CalibrationTime"									Name="Calibration Time"
+(0014,407E) VERS="DICONDE"	VR="DA"   VM="1-n"	Keyword="CalibrationDate"									Name="Calibration Date"
+(0014,4080) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ProbeDriveEquipmentSequence"						Name="Probe Drive Equipment Sequence"
+(0014,4081) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="DriveType"											Name="Drive Type"
+(0014,4082) VERS="DICONDE"	VR="LT"   VM="1"	Keyword="ProbeDriveNotes"									Name="Probe Drive Notes"
+(0014,4083) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="DriveProbeSequence"								Name="Drive Probe Sequence"
+(0014,4084) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ProbeInductance"									Name="Probe Inductance"
+(0014,4085) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ProbeResistance"									Name="Probe Resistance"
+(0014,4086) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ReceiveProbeSequence"								Name="Receive Probe Sequence"
+(0014,4087) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ProbeDriveSettingsSequence"						Name="Probe Drive Settings Sequence"
+(0014,4088) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="BridgeResistors"									Name="Bridge Resistors"
+(0014,4089) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ProbeOrientationAngle"								Name="Probe Orientation Angle"
+(0014,408B) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="UserSelectedGainY"									Name="User Selected Gain Y"
+(0014,408C) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="UserSelectedPhase"									Name="User Selected Phase"
+(0014,408D) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="UserSelectedOffsetX"								Name="User Selected Offset X"
+(0014,408E) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="UserSelectedOffsetY"								Name="User Selected Offset Y"
+(0014,4091) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ChannelSettingsSequence"							Name="Channel Settings Sequence"
+(0014,4092) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ChannelThreshold"									Name="Channel Threshold"
+(0014,409A) VERS="DICONDE"	VR="SQ"   VM="1"	Keyword="ScannerSettingsSequence"							Name="Scanner Settings Sequence"
+(0014,409B) VERS="DICONDE"	VR="ST"   VM="1"	Keyword="ScanProcedure"										Name="Scan Procedure"
+(0014,409C) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="TranslationRateX"									Name="Translation Rate X"
+(0014,409D) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="TranslationRateY"									Name="Translation Rate Y"
+(0014,409F) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ChannelOverlap"									Name="Channel Overlap"
+(0014,40A0) VERS="DICONDE"	VR="LO"   VM="1"	Keyword="ImageQualityIndicatorType"							Name="Image Quality Indicator Type"
+(0014,40A1) VERS="DICONDE"	VR="LO"   VM="1"	Keyword="ImageQualityIndicatorMaterial"						Name="Image Quality Indicator Material"
+(0014,40A2) VERS="DICONDE"	VR="LO"   VM="1"	Keyword="ImageQualityIndicatorSize"							Name="Image Quality Indicator Size"
+(0014,5002) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="LINACEnergy"										Name="LINAC Energy"
+(0014,5004) VERS="DICONDE"	VR="IS"   VM="1"	Keyword="LINACOutput"										Name="LINAC Output"
+(0014,5100) VERS="DICONDE"	VR="US"   VM="1"	Keyword="ActiveAperture"									Name="Active Aperture"
+(0014,5101) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="TotalAperture"										Name="Total Aperture"
+(0014,5102) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="ApertureElevation"									Name="Aperture Elevation"
+(0014,5103) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MainLobeAngle"										Name="Main Lobe Angle"
+(0014,5104) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="MainRoofAngle"										Name="Main Roof Angle"
+(0014,5105) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="ConnectorType"										Name="Connector Type"
+(0014,5106) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="WedgeModelNumber"									Name="Wedge Model Number"
+(0014,5107) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeAngleFloat"									Name="Wedge Angle Float"
+(0014,5108) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeRoofAngle"									Name="Wedge Roof Angle"
+(0014,5109) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="WedgeElement1Position"								Name="Wedge Element 1 Position"
+(0014,510A) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeMaterialVelocity"								Name="Wedge Material Velocity"
+(0014,510B) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="WedgeMaterial"										Name="Wedge Material"
+(0014,510C) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeOffsetZ"										Name="Wedge Offset Z"
+(0014,510D) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeOriginOffsetX"								Name="Wedge Origin Offset X"
+(0014,510E) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeTimeDelay"									Name="Wedge Time Delay"
+(0014,510F) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="WedgeName"											Name="Wedge Name"
+(0014,5110) VERS="DICONDE"	VR="SH"   VM="1"	Keyword="WedgeManufacturerName"								Name="Wedge Manufacturer Name"
+(0014,5111) VERS="DICONDE"	VR="LO"   VM="1"	Keyword="WedgeDescription"									Name="Wedge Description"
+(0014,5112) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="NominalBeamAngle"									Name="Nominal Beam Angle"
+(0014,5113) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeOffsetX"										Name="Wedge Offset X"
+(0014,5114) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeOffsetY"										Name="Wedge Offset Y"
+(0014,5115) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeTotalLength"									Name="Wedge Total Length"
+(0014,5116) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeInContactLength"								Name="Wedge In Contact Length"
+(0014,5117) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeFrontGap"										Name="Wedge Front Gap"
+(0014,5118) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeTotalHeight"									Name="Wedge Total Height"
+(0014,5119) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeFrontHeight"									Name="Wedge Front Height"
+(0014,511A) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeRearHeight"									Name="Wedge Rear Height"
+(0014,511B) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeTotalWidth"									Name="Wedge Total Width"
+(0014,511C) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeInContactWidth"								Name="Wedge In Contact Width"
+(0014,511D) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="WedgeChamferHeight"								Name="Wedge Chamfer Height"
+(0014,511E) VERS="DICONDE"	VR="CS"   VM="1"	Keyword="WedgeCurve"										Name="Wedge Curve"
+(0014,511F) VERS="DICONDE"	VR="DS"   VM="1"	Keyword="RadiusAlongWedge"									Name="Radius Along the Wedge"
diff --git a/libsrc/standard/elmdict/dicondep.tpl b/libsrc/standard/elmdict/dicondep.tpl
new file mode 100644
index 0000000..ad7bb32
--- /dev/null
+++ b/libsrc/standard/elmdict/dicondep.tpl
@@ -0,0 +1,155 @@
+(0011,0023) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="CADFileFormat"										Name="CAD File Format"
+(0011,0024) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="ComponentReferenceSystem"							Name="Component Reference System"
+(0011,0025) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="ComponentManufacturingProcedure"					Name="Component Manufacturing Procedure"
+(0011,0028) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="ComponentManufacturer"								Name="Component Manufacturer"
+(0011,0030) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialThickness"									Name="Material Thickness"
+(0011,0032) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialPipeDiameter"								Name="Material Pipe Diameter"
+(0011,0034) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialIsolationDiameter"							Name="Material Isolation Diameter"
+(0011,0042) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialGrade"										Name="Material Grade"
+(0011,0044) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialPropertiesFileID"							Name="Material Properties File ID"
+(0011,0045) VERS="DICONDE"	VR="ST"   VM="1-n"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialPropertiesFileFormat"						Name="Material Properties File Format"
+(0011,0046) VERS="DICONDE"	VR="LT"   VM="1"	Owner="astm.org/diconde/iod/Component"	Keyword="MaterialNotes"										Name="Material Notes"
+(0011,0050) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/Component"	Keyword="ComponentShape"									Name="Component Shape"
+(0011,0052) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/Component"	Keyword="CurvatureType"										Name="Curvature Type"
+(0011,0054) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/Component"	Keyword="OuterDiameter"										Name="Outer Diameter"
+(0011,0056) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/Component"	Keyword="InnerDiameter"										Name="Inner Diameter"
+
+(0009,0020) VERS="DICONDE"	VR="DA"   VM="1"	Owner="astm.org/diconde/iod/ComponentStudy"	Keyword="ExpiryDate"										Name="Expiry Date"
+
+(0009,0010) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/ComponentSeries"	Keyword="ActualEnvironmentalConditions"						Name="Actual Environmental Conditions"
+(0009,0040) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/ComponentSeries"	Keyword="EnvironmentalConditions"							Name="Environmental Conditions"
+
+(0021,0002) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="EvaluatorSequence"									Name="Evaluator Sequence"
+(0021,0004) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="EvaluatorNumber"									Name="Evaluator Number"
+(0021,0006) VERS="DICONDE"	VR="PN"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="EvaluatorName"										Name="Evaluator Name"
+(0021,0008) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="EvaluationAttempt"									Name="Evaluation Attempt"
+(0021,0012) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationSequence"								Name="Indication Sequence"
+(0021,0014) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationNumber"									Name="Indication Number "
+(0021,0016) VERS="DICONDE"	VR="SH"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationLabel"									Name="Indication Label"
+(0021,0018) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationDescription"								Name="Indication Description"
+(0021,001A) VERS="DICONDE"	VR="CS"   VM="1-n"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationType"									Name="Indication Type"
+(0021,001C) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationDisposition"								Name="Indication Disposition"
+(0021,001E) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationROISequence"								Name="Indication ROI Sequence"
+(0021,0030) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="IndicationPhysicalPropertySequence"				Name="Indication Physical Property Sequence"
+(0021,0032) VERS="DICONDE"	VR="SH"   VM="1"	Owner="astm.org/diconde/iod/NdeIndication"	Keyword="PropertyLabel"										Name="Property Label"
+
+(0021,0002) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemNumberOfAxes"						Name="Coordinate System Number of Axes "
+(0021,0004) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemAxesSequence"						Name="Coordinate System Axes Sequence"
+(0021,0006) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemAxisDescription"					Name="Coordinate System Axis Description"
+(0021,0008) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemDataSetMapping"					Name="Coordinate System Data Set Mapping"
+(0021,000A) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemAxisNumber"						Name="Coordinate System Axis Number"
+(0021,000C) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemAxisType"							Name="Coordinate System Axis Type"
+(0021,000E) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemAxisUnits"							Name="Coordinate System Axis Units"
+(0021,0010) VERS="DICONDE"	VR="OB"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemAxisValues"						Name="Coordinate System Axis Values"
+(0021,0020) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemTransformSequence"					Name="Coordinate System Transform Sequence"
+(0021,0022) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="TransformDescription"								Name="Transform Description"
+(0021,0024) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="TransformNumberOfAxes"								Name="Transform Number of Axes"
+(0021,0026) VERS="DICONDE"	VR="IS"   VM="1-n"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="TransformOrderOfAxes"								Name="Transform Order of Axes"
+(0021,0028) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="TransformedAxisUnits"								Name="Transformed Axis Units"
+(0021,002A) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemTransformRotationAndScaleMatrix"	Name="Coordinate System Transform Rotation and Scale Matrix"
+(0021,002C) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/NDEGeometry"	Keyword="CoordinateSystemTransformTranslationMatrix"		Name="Coordinate System Transform Translation Matrix"
+
+(0009,0011) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="InternalDetectorFrameTime"							Name="Internal Detector Frame Time"
+(0009,0012) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="NumberOfFramesIntegrated"							Name="Number of Frames Integrated"
+(0009,0020) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="DetectorTemperatureSequence"						Name="Detector Temperature Sequence"
+(0009,0022) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="SensorName"										Name="Sensor Name"
+(0009,0024) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="HorizontalOffsetOfSensor"							Name="Horizontal Offset of Sensor"
+(0009,0026) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="VerticalOffsetOfSensor"							Name="Vertical Offset of Sensor"
+(0009,0028) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxDetector"			Keyword="SensorTemperature"									Name="Sensor Temperature"
+(0009,0040) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="DarkCurrentSequence"								Name="Dark Current Sequence"
+(0009,0050) VERS="DICONDE"	VR="OW/OB" VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="DarkCurrentCounts"									Name="Dark Current Counts"
+(0009,0060) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="GainCorrectionReferenceSequence"					Name="Gain Correction Reference Sequence"
+(0009,0070) VERS="DICONDE"	VR="OW/OB" VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="AirCounts"											Name="Air Counts"
+(0009,0071) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="KVUsedInGainCalibration"							Name="KV Used in Gain Calibration"
+(0009,0072) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="MAUsedInGainCalibration"							Name="MA Used in Gain Calibration"
+(0009,0073) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="NumberOfFramesUsedForIntegration"					Name="Number of Frames Used for Integration"
+(0009,0074) VERS="DICONDE"	VR="LO"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="FilterMaterialUsedInGainCalibration"				Name="Filter Material Used in Gain Calibration"
+(0009,0075) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="FilterThicknessUsedInGainCalibration"				Name="Filter Thickness Used in Gain Calibration"
+(0009,0076) VERS="DICONDE"	VR="DA"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="DateOfGainCalibration"								Name="Date of Gain Calibration"
+(0009,0077) VERS="DICONDE"	VR="TM"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="TimeOfGainCalibration"								Name="Time of Gain Calibration"
+(0009,0080) VERS="DICONDE"	VR="OB"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="BadPixelImage"										Name="Bad Pixel Image"
+(0009,0099) VERS="DICONDE"	VR="LT"   VM="1"	Owner="astm.org/diconde/iod/NdeDxCalibrationData"	Keyword="CalibrationNotes"									Name="Calibration Notes"
+
+(0009,0002) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="PulserEquipmentSequence"							Name="Pulser Equipment Sequence"
+(0009,0004) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="PulserType"										Name="Pulser Type"
+(0009,0006) VERS="DICONDE"	VR="LT"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="PulserNotes"										Name="Pulser Notes"
+(0009,0008) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ReceiverEquipmentSequence"							Name="Receiver Equipment Sequence"
+(0009,000A) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="AmplifierType"										Name="Amplifier Type"
+(0009,000C) VERS="DICONDE"	VR="LT"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ReceiverNotes"										Name="Receiver Notes"
+(0009,000E) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="PreAmplifierEquipmentSequence"						Name="Pre-Amplifier Equipment Sequence"
+(0009,000F) VERS="DICONDE"	VR="LT"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="PreAmplifierNotes"									Name="Pre-Amplifier Notes"
+(0009,0010) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="TransmitTransducerSequence"						Name="Transmit Transducer Sequence"
+(0009,0011) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ReceiveTransducerSequence"							Name="Receive Transducer Sequence"
+(0009,0012) VERS="DICONDE"	VR="US"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="NumberOfElements"									Name="Number of Elements"
+(0009,0013) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ElementShape"										Name="Element Shape"
+(0009,0014) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ElementDimensionA"									Name="Element Dimension A"
+(0009,0015) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ElementDimensionB"									Name="Element Dimension B"
+(0009,0016) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="ElementPitch"										Name="Element Pitch"
+(0009,0017) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="MeasuredBeamDimensionA"							Name="Measured Beam Dimension A"
+(0009,0018) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="MeasuredBeamDimensionB"							Name="Measured Beam Dimension B"
+(0009,0019) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="LocationOfMeasuredBeamDiameter"					Name="Location of Measured Beam Diameter"
+(0009,001A) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="NominalFrequency"									Name="Nominal Frequency"
+(0009,001B) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="MeasuredCenterFrequency"							Name="Measured Center Frequency"
+(0009,001C) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipment"	Keyword="MeasuredBandwidth"									Name="Measured Bandwidth"
+
+(0009,0020) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="PulserSettingsSequence"							Name="Pulser Settings Sequence"
+(0009,0022) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="PulseWidth"										Name="Pulse Width"
+(0009,0024) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ExcitationFrequency"								Name="Excitation Frequency"
+(0009,0026) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ModulationType"									Name="Modulation Type"
+(0009,0028) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="Damping"											Name="Damping"
+(0009,0030) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ReceiverSettingsSequence"							Name="Receiver Settings Sequence"
+(0009,0031) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="AcquiredSoundpathLength"							Name="Acquired Soundpath Length"
+(0009,0032) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="AcquisitionCompressionType"						Name="Acquisition Compression Type"
+(0009,0033) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="AcquisitionSampleSize"								Name="Acquisition Sample Size"
+(0009,0034) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="RectifierSmoothing"								Name="Rectifier Smoothing"
+(0009,0035) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="DACSequence"										Name="DAC Sequence"
+(0009,0036) VERS="DICONDE"	VR="CS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="DACType"											Name="DAC Type"
+(0009,0038) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="DACGainPoints"										Name="DAC Gain Points"
+(0009,003A) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="DACTimePoints"										Name="DAC Time Points"
+(0009,003C) VERS="DICONDE"	VR="DS"   VM="1-n"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="DACAmplitude"										Name="DAC Amplitude"
+(0009,0040) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="PreAmplifierSettingsSequence"						Name="Pre-Amplifier Settings Sequence"
+(0009,0050) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="TransmitTransducerSettingsSequence"				Name="Transmit Transducer Settings Sequence"
+(0009,0051) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ReceiveTransducerSettingsSequence"					Name="Receive Transducer Settings Sequence"
+(0009,0052) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="IncidentAngle"										Name="Incident Angle"
+(0009,0054) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CouplingTechnique"									Name="Coupling Technique"
+(0009,0056) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CouplingMedium"									Name="Coupling Medium"
+(0009,0057) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CouplingVelocity"									Name="Coupling Velocity"
+(0009,0058) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CrystalCenterLocationX"							Name="Crystal Center Location X"
+(0009,0059) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CrystalCenterLocationZ"							Name="Crystal Center Location Z"
+(0009,005A) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="SoundPathLength"									Name="Sound Path Length"
+(0009,005C) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="DelayLawIdentifier"								Name="Delay Law Identifier"
+(0009,0060) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="GateSettingsSequence"								Name="Gate Settings Sequence"
+(0009,0062) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="GateThreshold"										Name="Gate Threshold"
+(0009,0064) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="VelocityOfSound"									Name="Velocity of Sound"
+(0009,0070) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CalibrationSettingsSequence"						Name="Calibration Settings Sequence"
+(0009,0072) VERS="DICONDE"	VR="ST"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CalibrationProcedure"								Name="Calibration Procedure"
+(0009,0074) VERS="DICONDE"	VR="SH"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ProcedureVersion"									Name="Procedure Version"
+(0009,0076) VERS="DICONDE"	VR="DA"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ProcedureCreationDate"								Name="Procedure Creation Date"
+(0009,0078) VERS="DICONDE"	VR="DA"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ProcedureExpirationDate"							Name="Procedure Expiration Date"
+(0009,007A) VERS="DICONDE"	VR="DA"   VM="1"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="ProcedureLastModifiedDate"							Name="Procedure Last Modified Date"
+(0009,007C) VERS="DICONDE"	VR="TM"   VM="1-n"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CalibrationTime"									Name="Calibration Time"
+(0009,007E) VERS="DICONDE"	VR="DA"   VM="1-n"	Owner="astm.org/diconde/iod/NdeUsEquipmentSettings"	Keyword="CalibrationDate"									Name="Calibration Date"
+
+(0009,0002) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtImage"				Keyword="LINACEnergy"										Name="LINAC Energy"
+(0009,0004) VERS="DICONDE"	VR="IS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtImage"				Keyword="LINACOutput"										Name="LINAC Output"
+(0009,0011) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="InternalDetectorFrameTime"							Name="Internal Detector Frame Time"
+(0009,0012) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="NumberOfFramesIntegrated"							Name="Number of Frames Integrated"
+(0009,0020) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="DetectorTemperatureSequence"						Name="Detector Temperature Sequence"
+(0009,0022) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="SensorName"										Name="Sensor Name"
+(0009,0024) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="HorizontalOffsetOfSensor"							Name="Horizontal Offset of Sensor"
+(0009,0026) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="VerticalOffsetOfSensor"							Name="Vertical Offset of Sensor"
+(0009,0028) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtDetector"			Keyword="SensorTemperature"									Name="Sensor Temperature"
+(0009,0040) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="DarkCurrentSequence"								Name="Dark Current Sequence"
+(0009,0050) VERS="DICONDE"	VR="OW/OB" VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="DarkCurrentCounts"									Name="Dark Current Counts"
+(0009,0060) VERS="DICONDE"	VR="SQ"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="GainCorrectionReferenceSequence"					Name="Gain Correction Reference Sequence"
+(0009,0070) VERS="DICONDE"	VR="OW/OB" VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="AirCounts"											Name="Air Counts"
+(0009,0071) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="KVUsedInGainCalibration"							Name="KV Used in Gain Calibration"
+(0009,0072) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="MAUsedInGainCalibration"							Name="MA Used in Gain Calibration"
+(0009,0073) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="NumberOfFramesUsedForIntegration"					Name="Number of Frames Used for Integration"
+(0009,0074) VERS="DICONDE"	VR="LO"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="FilterMaterialUsedInGainCalibration"				Name="Filter Material Used in Gain Calibration"
+(0009,0075) VERS="DICONDE"	VR="DS"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="FilterThicknessUsedInGainCalibration"				Name="Filter Thickness Used in Gain Calibration"
+(0009,0076) VERS="DICONDE"	VR="DA"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="DateOfGainCalibration"								Name="Date of Gain Calibration"
+(0009,0077) VERS="DICONDE"	VR="TM"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="TimeOfGainCalibration"								Name="Time of Gain Calibration"
+(0009,0080) VERS="DICONDE"	VR="OB"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="BadPixelImage"										Name="Bad Pixel Image"
+(0009,0099) VERS="DICONDE"	VR="LT"   VM="1"	Owner="astm.org/diconde/iod/NdeCtCalibrationData"	Keyword="CalibrationNotes"									Name="Calibration Notes"
+
diff --git a/libsrc/standard/elmdict/dicos.tpl b/libsrc/standard/elmdict/dicos.tpl
new file mode 100644
index 0000000..724d6c0
--- /dev/null
+++ b/libsrc/standard/elmdict/dicos.tpl
@@ -0,0 +1,89 @@
+(0008,0101) VERS="DICOS"	VR="LO"   VM="1"	Keyword="ExtendedCodeValue"						Name="Extended Code Value"
+(0008,0108) VERS="DICOS"	VR="LT"   VM="1"	Keyword="ExtendedCodeMeaning"					Name="Extended Code Meaning"
+(4010,0001) VERS="DICOS"	VR="CS"   VM="1"	Keyword="LowEnergyDetectors"					Name="Low Energy Detectors"
+(4010,0002) VERS="DICOS"	VR="CS"   VM="1"	Keyword="HighEnergyDetectors"					Name="High Energy Detectors"
+(4010,0004) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="DetectorGeometrySequence"				Name="Detector Geometry Sequence"
+(4010,1001) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="ThreatROIVoxelSequence"				Name="Threat ROI Voxel Sequence"
+(4010,1004) VERS="DICOS"	VR="FL"   VM="3"	Keyword="ThreatROIBase"							Name="Threat ROI Base"
+(4010,1005) VERS="DICOS"	VR="FL"   VM="3"	Keyword="ThreatROIExtents"						Name="Threat ROI Extents"
+(4010,1006) VERS="DICOS"	VR="OB"   VM="1"	Keyword="ThreatROIBitmap"						Name="Threat ROI Bitmap"
+(4010,1007) VERS="DICOS"	VR="SH"   VM="1"	Keyword="RouteSegmentID"						Name="Route Segment ID"
+(4010,1008) VERS="DICOS"	VR="CS"   VM="1"	Keyword="GantryType"							Name="Gantry Type"
+(4010,1009) VERS="DICOS"	VR="CS"   VM="1"	Keyword="OOIOwnerType"							Name="OOI Owner Type"
+(4010,100A) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="RouteSegmentSequence"					Name="Route Segment Sequence"
+(4010,1010) VERS="DICOS"	VR="US"   VM="1"	Keyword="PotentialThreatObjectID"				Name="Potential Threat Object ID"
+(4010,1011) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="ThreatSequence"						Name="Threat Sequence"
+(4010,1012) VERS="DICOS"	VR="CS"   VM="1"	Keyword="ThreatCategory"						Name="Threat Category"
+(4010,1013) VERS="DICOS"	VR="LT"   VM="1"	Keyword="ThreatCategoryDescription"				Name="Threat Category Description"
+(4010,1014) VERS="DICOS"	VR="CS"   VM="1"	Keyword="ATDAbilityAssessment"					Name="ATD Ability Assessment"
+(4010,1015) VERS="DICOS"	VR="CS"   VM="1"	Keyword="ATDAssessmentFlag"						Name="ATD Assessment Flag"
+(4010,1016) VERS="DICOS"	VR="FL"   VM="1"	Keyword="ATDAssessmentProbability"				Name="ATD Assessment Probability"
+(4010,1017) VERS="DICOS"	VR="FL"   VM="1"	Keyword="Mass"									Name="Mass"
+(4010,1018) VERS="DICOS"	VR="FL"   VM="1"	Keyword="Density"								Name="Density"
+(4010,1019) VERS="DICOS"	VR="FL"   VM="1"	Keyword="ZEffective"							Name="Z Effective"
+(4010,101A) VERS="DICOS"	VR="SH"   VM="1"	Keyword="BoardingPassID"						Name="Boarding Pass ID"
+(4010,101B) VERS="DICOS"	VR="FL"   VM="3"	Keyword="CenterOfMass"							Name="Center of Mass"
+(4010,101C) VERS="DICOS"	VR="FL"   VM="3"	Keyword="CenterOfPTO"							Name="Center of PTO"
+(4010,101D) VERS="DICOS"	VR="FL"   VM="6-n"	Keyword="BoundingPolygon"						Name="Bounding Polygon"
+(4010,101E) VERS="DICOS"	VR="SH"   VM="1"	Keyword="RouteSegmentStartLocationID"			Name="Route Segment Start Location ID"
+(4010,101F) VERS="DICOS"	VR="SH"   VM="1"	Keyword="RouteSegmentEndLocationID"				Name="Route Segment End Location ID"
+(4010,1020) VERS="DICOS"	VR="CS"   VM="1"	Keyword="RouteSegmentLocationIDType"			Name="Route Segment Location ID Type"
+(4010,1021) VERS="DICOS"	VR="CS"   VM="1-n"	Keyword="AbortReason"							Name="Abort Reason"
+(4010,1023) VERS="DICOS"	VR="FL"   VM="1"	Keyword="VolumeOfPTO"							Name="Volume of PTO"
+(4010,1024) VERS="DICOS"	VR="CS"   VM="1"	Keyword="AbortFlag"								Name="Abort Flag"
+(4010,1025) VERS="DICOS"	VR="DT"   VM="1"	Keyword="RouteSegmentStartTime"					Name="Route Segment Start Time"
+(4010,1026) VERS="DICOS"	VR="DT"   VM="1"	Keyword="RouteSegmentEndTime"					Name="Route Segment End Time"
+(4010,1027) VERS="DICOS"	VR="CS"   VM="1"	Keyword="TDRType"								Name="TDR Type"
+(4010,1028) VERS="DICOS"	VR="CS"   VM="1"	Keyword="InternationalRouteSegment"				Name="International Route Segment"
+(4010,1029) VERS="DICOS"	VR="LO"   VM="1-n"	Keyword="ThreatDetectionAlgorithmAndVersion"	Name="Threat Detection Algorithm and Version"
+(4010,102A) VERS="DICOS"	VR="SH"   VM="1"	Keyword="AssignedLocation"						Name="Assigned Location"
+(4010,102B) VERS="DICOS"	VR="DT"   VM="1"	Keyword="AlarmDecisionTime"						Name="Alarm Decision Time"
+(4010,1031) VERS="DICOS"	VR="CS"   VM="1"	Keyword="AlarmDecision"							Name="Alarm Decision"
+(4010,1033) VERS="DICOS"	VR="US"   VM="1"	Keyword="NumberOfTotalObjects"					Name="Number of Total Objects"
+(4010,1034) VERS="DICOS"	VR="US"   VM="1"	Keyword="NumberOfAlarmObjects"					Name="Number of Alarm Objects"
+(4010,1037) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="PTORepresentationSequence"				Name="PTO Representation Sequence"
+(4010,1038) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="ATDAssessmentSequence"					Name="ATD Assessment Sequence"
+(4010,1039) VERS="DICOS"	VR="CS"   VM="1"	Keyword="TIPType"								Name="TIP Type"
+(4010,103A) VERS="DICOS"	VR="CS"   VM="1"	Keyword="DICOSVersion"							Name="DICOS Version"
+(4010,1041) VERS="DICOS"	VR="DT"   VM="1"	Keyword="OOIOwnerCreationTime"					Name="OOI Owner Creation Time"
+(4010,1042) VERS="DICOS"	VR="CS"   VM="1"	Keyword="OOIType"								Name="OOI Type"
+(4010,1043) VERS="DICOS"	VR="FL"   VM="3"	Keyword="OOISize"								Name="OOI Size"
+(4010,1044) VERS="DICOS"	VR="CS"   VM="1"	Keyword="AcquisitionStatus"						Name="Acquisition Status"
+(4010,1045) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="BasisMaterialsCodeSequence"			Name="Basis Materials Code Sequence"
+(4010,1046) VERS="DICOS"	VR="CS"   VM="1"	Keyword="PhantomType"							Name="Phantom Type"
+(4010,1047) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="OOIOwnerSequence"						Name="OOI Owner Sequence"
+(4010,1048) VERS="DICOS"	VR="CS"   VM="1"	Keyword="ScanType"								Name="Scan Type"
+(4010,1051) VERS="DICOS"	VR="LO"   VM="1"	Keyword="ItineraryID"							Name="Itinerary ID"
+(4010,1052) VERS="DICOS"	VR="SH"   VM="1"	Keyword="ItineraryIDType"						Name="Itinerary ID Type"
+(4010,1053) VERS="DICOS"	VR="LO"   VM="1"	Keyword="ItineraryIDAssigningAuthority"			Name="Itinerary ID Assigning Authority"
+(4010,1054) VERS="DICOS"	VR="SH"   VM="1"	Keyword="RouteID"								Name="Route ID"
+(4010,1055) VERS="DICOS"	VR="SH"   VM="1"	Keyword="RouteIDAssigningAuthority"				Name="Route ID Assigning Authority"
+(4010,1056) VERS="DICOS"	VR="CS"   VM="1"	Keyword="InboundArrivalType"					Name="Inbound Arrival Type"
+(4010,1058) VERS="DICOS"	VR="SH"   VM="1"	Keyword="CarrierID"								Name="Carrier ID"
+(4010,1059) VERS="DICOS"	VR="CS"   VM="1"	Keyword="CarrierIDAssigningAuthority"			Name="Carrier ID Assigning Authority"
+(4010,1060) VERS="DICOS"	VR="FL"   VM="3"	Keyword="SourceOrientation"						Name="Source Orientation"
+(4010,1061) VERS="DICOS"	VR="FL"   VM="3"	Keyword="SourcePosition"						Name="Source Position"
+(4010,1062) VERS="DICOS"	VR="FL"   VM="1"	Keyword="BeltHeight"							Name="Belt Height"
+(4010,1064) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="AlgorithmRoutingCodeSequence"			Name="Algorithm Routing Code Sequence"
+(4010,1067) VERS="DICOS"	VR="CS"   VM="1"	Keyword="TransportClassification"				Name="Transport Classification"
+(4010,1068) VERS="DICOS"	VR="LT"   VM="1"	Keyword="OOITypeDescriptor"						Name="OOI Type Descriptor"
+(4010,1069) VERS="DICOS"	VR="FL"   VM="1"	Keyword="TotalProcessingTime"					Name="Total Processing Time"
+(4010,106C) VERS="DICOS"	VR="OB"   VM="1"	Keyword="DetectorCalibrationData"				Name="Detector Calibration Data"
+(4010,106D) VERS="DICOS"	VR="CS"   VM="1"	Keyword="AdditionalScreeningPerformed"			Name="Additional Screening Performed"	
+(4010,106E) VERS="DICOS"	VR="CS"   VM="1"	Keyword="AdditionalInspectionSelectionCriteria"	Name="Additional Inspection Selection Criteria"	
+(4010,106F) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="AdditionalInspectionMethodSequence"	Name="Additional Inspection Method Sequence"	
+(4010,1070) VERS="DICOS"	VR="CS"   VM="1"	Keyword="AITDeviceType"							Name="AIT Device Type"	
+(4010,1071) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="QRMeasurementsSequence"				Name="QR Measurements Sequence"	
+(4010,1072) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="TargetMaterialSequence"				Name="Target Material Sequence"	
+(4010,1073) VERS="DICOS"	VR="FD"   VM="1"	Keyword="SNRThreshold"							Name="SNR Threshold"	
+(4010,1075) VERS="DICOS"	VR="DS"   VM="1"	Keyword="ImageScaleRepresentation"				Name="Image Scale Representation"	
+(4010,1076) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="ReferencedPTOSequence"					Name="Referenced PTO Sequence"	
+(4010,1077) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="ReferencedTDRInstanceSequence"			Name="Referenced TDR Instance Sequence"	
+(4010,1078) VERS="DICOS"	VR="ST"   VM="1"	Keyword="PTOLocationDescription"				Name="PTO Location Description"	
+(4010,1079) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="AnomalyLocatorIndicatorSequence"		Name="Anomaly Locator Indicator Sequence"	
+(4010,107A) VERS="DICOS"	VR="FL"   VM="3"	Keyword="AnomalyLocatorIndicator"				Name="Anomaly Locator Indicator"	
+(4010,107B) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="PTORegionSequence"						Name="PTO Region Sequence"	
+(4010,107C) VERS="DICOS"	VR="CS"   VM="1"	Keyword="InspectionSelectionCriteria"			Name="Inspection Selection Criteria"	
+(4010,107D) VERS="DICOS"	VR="SQ"   VM="1"	Keyword="SecondaryInspectionMethodSequence"		Name="Secondary Inspection Method Sequence"	
+(4010,107E) VERS="DICOS"	VR="DS"   VM="6"	Keyword="PRCSToRCSOrientation"					Name="PRCS to RCS Orientation"	
+
diff --git a/libsrc/standard/elmdict/elscint.tpl b/libsrc/standard/elmdict/elscint.tpl
new file mode 100755
index 0000000..6859ef3
--- /dev/null
+++ b/libsrc/standard/elmdict/elscint.tpl
@@ -0,0 +1,220 @@
+(0003,0001) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="OffsetListStructure"			Name="Offset List Structure"
+(00E1,0001) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="DataDictionaryVersion"			Name="Data Dictionary Version"
+(00E1,0005) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0006) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0007) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0014) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0018) VERS="EL1"  VR="OB"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0021) VERS="EL1"  VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="DLPTotal"			Name="DLP Total"
+(00E1,0022) VERS="EL1"	VR="DS"   VM="2"	Owner="ELSCINT1"	Keyword="PresentationRelativeCenter"		Name="Presentation Relative Center"
+(00E1,0023) VERS="EL1"	VR="DS"   VM="2"	Owner="ELSCINT1"	Keyword="PresentationRelativePart"		Name="Presentation Relative Part"
+(00E1,0024) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0025) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0030) VERS="EL1"  VR="UI"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0031) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0032) VERS="EL1"  VR="US"   VM="2"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0037) VERS="EL1"  VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="TotalDoseSavings"	Name="Total Dose Savings"
+(00E1,0039) VERS="EL1"  VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,003E) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,003F) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0040) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="ImageLabel"				Name="Image Label"
+(00E1,0041) VERS="EL1"  VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0042) VERS="EL1"  VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0043) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0050) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="AcquisitionDuration"			Name="Acquisition Duration"
+(00E1,0051) VERS="EL1"  VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0060) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0061) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="ProtocolFileName"			Name="Protocol File Name"
+(00E1,0062) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,0063) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="PatientLanguage"			Name="Patient Language"
+(00E1,0065) VERS="EL1"  VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,006A) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,006B) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,00A0) VERS="EL1"  VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,00C2) VERS="EL1"  VR="UI"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,00C4) VERS="EL1"  VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,00CF) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,00EB) VERS="EL1"  VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(00E1,00EC) VERS="EL1"  VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(01E1,0018) VERS="EL1"  VR="OB"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01E1,0021) VERS="EL1"  VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01E1,0026) VERS="EL1"  VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="PhantomType"		Name="Phantom Type"
+(01E1,0034) VERS="EL1"  VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01E1,0040) VERS="EL1"  VR="UI"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01E1,0041) VERS="EL1"  VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(01F1,0001) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="AcquisitionType"				Name="Acquisition Type"
+(01F1,0002) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="FocalSpotResolution"			Name="Focal Spot Resolution"
+(01F1,0003) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="ConcurrentSlicesGeneration"	Name="Concurrent Slices Generation"
+(01F1,0004) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="AngularSamplingDensity"		Name="Angular Sampling Density"
+(01F1,0005) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="ReconstructionArc"				Name="Reconstruction Arc"
+(01F1,0007) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="TableVelocity"					Name="Table Velocity"
+(01F1,0008) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="AcquisitionLength"				Name="Acquisition Length"
+(01F1,000A) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="EdgeEnhancementWeight"			Name="Edge Enhancement Weight"
+(01F1,000C) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="ScannerRelativeCenter"			Name="Scanner Relative Center"
+(01F1,000D) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="RotationAngle"					Name="Rotation Angle"
+(01F1,000E) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"								Name="?"
+(01F1,0026) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="Pitch"							Name="Pitch"
+(01F1,0027) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="RotationTime"					Name="Rotation Time"
+(01F1,0028) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="TableIncrement"				Name="Table Increment"
+(01F1,0030) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"								Name="?"
+(01F1,0032) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="ImageViewConvention"			Name="Image View Convention"
+(01F1,0033) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="CycleTime"						Name="Cycle Time" 
+(01F1,0036) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0037) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0038) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0039) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0040) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0042) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0043) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(01F1,0044) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,0045) VERS="EL1"	VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,0046) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,0047) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,0049) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,004A) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,004B) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,004C) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,004D) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,004E) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F1,0053) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(01F3,0001) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0002) VERS="EL1"	VR="SS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0003) VERS="EL1"	VR="FL"   VM="2"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0004) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0011) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0012) VERS="EL1"	VR="SS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0013) VERS="EL1"	VR="FL"   VM="2"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0014) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0015) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0016) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0017) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0018) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0019) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0023) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F3,0024) VERS="EL1"	VR="IS"   VM="2"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(01F7,0010) VERS="EL1"	VR="OB"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0011) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0013) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0014) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0015) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0016) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0017) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0018) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0019) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,001A) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,001B) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,001C) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,001E) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,001F) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0022) VERS="EL1"	VR="UI"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0023) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0025) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0026) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0027) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0028) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0029) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,002B) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,002C) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,002D) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,002E) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0030) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0031) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,005C) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0070) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0073) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0074) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,0075) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F7,007F) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(01F9,0001) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="SPFilter"			Name="SP Filter"
+(01F9,0004) VERS="EL1"	VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="AdaptiveFilter"	Name="Adaptive Filter"
+(01F9,0005) VERS="EL1"	VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="ReconIncrement"	Name="Recon Increment"
+(01F9,0008) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(01F9,0009) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(0601,0000) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="ImplementationVersion"			Name="Implementation Version"
+(0601,0020) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="RelativeTablePosition"			Name="Relative Table Position"
+(0601,0021) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="RelativeTableHeight"			Name="Relative Table Height"
+(0601,0030) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="SurviewDirection"			Name="Surview Direction"
+(0601,0031) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="SurviewLength"				Name="Surview Length"
+(0601,0050) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="ImageViewType"				Name="Image View Type"
+(0601,0070) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="BatchNumber"				Name="Batch Number"
+(0601,0071) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="BatchSize"				Name="Batch Size"
+(0601,0072) VERS="EL1"	VR="DS"   VM="1"	Owner="ELSCINT1"	Keyword="BatchSliceNumber"			Name="Batch Slice Number"
+
+(07A1,0002) VERS="EL1"	VR="UL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0007) VERS="EL1"	VR="US"   VM="3"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0008) VERS="EL1"	VR="DS"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0009) VERS="EL1"	VR="OW"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,000A) VERS="EL1"	VR="OB"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,000C) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0010) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0011) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0012) VERS="EL1"	VR="FL"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0013) VERS="EL1"	VR="UL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0016) VERS="EL1"	VR="FL"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0018) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0019) VERS="EL1"	VR="FL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,001C) VERS="EL1"	VR="FL"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,002A) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,002B) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0036) VERS="EL1"	VR="AE"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,003D) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0040) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0043) VERS="EL1"	VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0047) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0050) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0056) VERS="EL1"	VR="US"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0070) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0071) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0075) VERS="EL1"	VR="LO"   VM="2"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0085) VERS="EL1"	VR="UL"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A1,0087) VERS="EL1"	VR="LT"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0088) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,0098) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A1,009F) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(07A3,0001) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0003) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0005) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0006) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0013) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0014) VERS="EL1"	VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0015) VERS="EL1"	VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0017) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,001B) VERS="EL1"	VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,001F) VERS="EL1"	VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0022) VERS="EL1"	VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0023) VERS="EL1"	VR="ST"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0034) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0043) VERS="EL1"	VR="DS"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0055) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0061) VERS="EL1"	VR="LT"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0062) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0063) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0064) VERS="EL1"	VR="IS"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0065) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0066) VERS="EL1"	VR="IS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A3,0080) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,0099) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,009C) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,009F) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,00B9) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+(07A3,00BB) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?"
+
+(07A5,0000) VERS="EL1"	VR="LO"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(07A5,0056) VERS="EL1"	VR="CS"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+
+(5001,0070) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(5001,0071) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(5001,0080) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(5001,0081) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(5001,0082) VERS="EL1"	VR="US"   VM="3"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(5001,0083) VERS="EL1"	VR="FL"   VM="1-n"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(5001,0084) VERS="EL1"	VR="SQ"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(7FDF,00F0) VERS="EL1"	VR="OB"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
+(7FDF,00FF) VERS="EL1"	VR="SH"   VM="1"	Owner="ELSCINT1"	Keyword="?"					Name="?" 
diff --git a/libsrc/standard/elmdict/gems.tpl b/libsrc/standard/elmdict/gems.tpl
new file mode 100755
index 0000000..157a431
--- /dev/null
+++ b/libsrc/standard/elmdict/gems.tpl
@@ -0,0 +1,2167 @@
+(0009,0001) VERS="GEM"	VR="LO"   VM="2"	Owner="GEMS_PETD_01"		Keyword="ImplementationVersionName"	Name="Implementation Version Name"
+(0009,0002) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PatientID"			Name="Patient ID"
+(0009,0003) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PatientCompatibleVersion"	Name="Patient Compatible Version"
+(0009,0004) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PatientSoftwareVersion"	Name="Patient Software Version"
+(0009,0005) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PatientDateTime"		Name="Patient DateTime"
+(0009,0006) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PatientType"			Name="Patient Type"
+(0009,0007) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ExamID"			Name="Exam ID"
+(0009,0008) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ExamCompatibleVersion"		Name="Exam Compatible Version"
+(0009,0009) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ExamSoftwareVersion"		Name="Exam Software Version"
+(0009,000a) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanID"			Name="Scan ID"
+(0009,000b) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanCompatibleVersion"		Name="Scan Compatible Version"
+(0009,000c) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanSoftwareVersion"		Name="Scan Software Version"
+(0009,000d) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanDateTime"			Name="Scan Date Time"
+(0009,000e) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanReady"			Name="Scan Ready"
+(0009,000f) VERS="GEM"	VR="ST"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanDescription"		Name="Scan Description"
+(0009,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="HospitalName"			Name="Hospital Name"
+(0009,0011) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScannerDescription"		Name="Scanner Description"
+(0009,0012) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Manufacturer"			Name="Manufacturer"
+(0009,0013) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="FORIdentifier"			Name="FOR Identifier"
+(0009,0014) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LandmarkName"			Name="Landmark Name"
+(0009,0015) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LandmarkAbbrev"		Name="Landmark Abbrev"
+(0009,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PatientPosition"		Name="Patient Position"
+(0009,0017) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanPerspective"		Name="Scan Perspective"
+(0009,0018) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanType"			Name="Scan Type"
+(0009,0019) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanMode"			Name="Scan Mode"
+(0009,001a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="StartCondition"		Name="Start Condition"
+(0009,001b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="StartConditionData"		Name="Start Condition Data"
+(0009,001c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="SelStopCondition"		Name="Sel Stop Condition"
+(0009,001d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="SelStopConditionData"		Name="Sel Stop Condition Data"
+(0009,001e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CollectDeadtime"		Name="Collect Deadtime"
+(0009,001f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CollectSingles"		Name="Collect Singles"
+(0009,0020) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CollectCountRate"		Name="Collect Count Rate"
+(0009,0021) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CountRatePeriod"		Name="Count Rate Period"
+(0009,0022) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="DelayedEvents"			Name="Delayed Events"
+(0009,0023) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="DelayedBias"			Name="Delayed Bias"
+(0009,0024) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="WordSize"			Name="Word Size"
+(0009,0025) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialAcceptance"		Name="Axial Acceptance"
+(0009,0026) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialAngle3D"			Name="Axial Angle 3D"
+(0009,0027) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ThetaCompression"		Name="Theta Compression"
+(0009,0028) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialCompression"		Name="Axial Compression"
+(0009,0029) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GantryTiltAngle"		Name="Gantry Tilt Angle"
+(0009,002a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Collimation"			Name="Collimation"
+(0009,002b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScanFOV"			Name="Scan FOV"
+(0009,002c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialFOV"			Name="Axial FOV"
+(0009,002d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="EventSeparation"		Name="Event Separation"
+(0009,002e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="MaskWidth"			Name="Mask Width"
+(0009,002f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BinningMode"			Name="Binning Mode"
+(0009,0030) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TrigRejMethod"			Name="Trig Rej Method"
+(0009,0031) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="NumberForReject"		Name="Number For Reject"
+(0009,0032) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LowerRejectLimit"		Name="Lower Reject Limit"
+(0009,0033) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="UpperRejectLimit"		Name="Upper Reject Limit"
+(0009,0034) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TriggersAcquired"		Name="Triggers Acquired"
+(0009,0035) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TriggersRejected"		Name="Triggers Rejected"
+(0009,0036) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TracerName"			Name="Tracer Name"
+(0009,0037) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BatchDescription"		Name="Batch Description"
+(0009,0038) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TracerActivity"		Name="Tracer Activity"
+(0009,0039) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="MeasuredDateTime"		Name="Measured Date Time"
+(0009,003a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PreInjVolume"			Name="Pre Inj Volume"
+(0009,003b) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AdministeredDateTime"	Name="Administered Date Time"
+(0009,003c) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PostInjectedActivity"	Name="Post Injected Activity"
+(0009,003d) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PostInjectedDateTime"	Name="Post Injected Date Time"
+(0009,003e) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="RadioNuclideName"		Name="Radio Nuclide Name"
+(0009,003f) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="HalfLife"				Name="Half Life"
+(0009,0040) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PositronFraction"		Name="Positron Fraction"
+(0009,0041) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source1Holder"			Name="Source 1 Holder"
+(0009,0042) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source1Activity"		Name="Source 1 Activity"
+(0009,0043) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source1MeasDT"			Name="Source 1 Meas DT"
+(0009,0044) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source1RadioNuclide"		Name="Source 1 Radio Nuclide"
+(0009,0045) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source1HalfLife"		Name="Source 1 Half Life"
+(0009,0046) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source2Holder"			Name="Source 2 Holder"
+(0009,0047) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source2Activity"		Name="Source 2 Activity"
+(0009,0048) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source2MeasDT"			Name="Source 2 Meas DT"
+(0009,0049) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source2RadioNuclide"		Name="Source 2 Radio Nuclide"
+(0009,004a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Source2HalfLife"		Name="Source 2 Half Life"
+(0009,004b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="SourceSpeed"			Name="Source Speed"
+(0009,004c) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="SourceLocation"		Name="Source Location"
+(0009,004d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="EmissionPresent"		Name="Emission Present"
+(0009,004e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LowerAxialAcc"			Name="Lower Axial Acc"
+(0009,004f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="UpperAxialAcc"			Name="Upper Axial Acc"
+(0009,0050) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LowerCoincLimit"		Name="Lower Coinc Limit"
+(0009,0051) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="UpperCoincLimit"		Name="Upper Coinc Limit"
+(0009,0052) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CoincDelayOffset"		Name="Coinc Delay Offset"
+(0009,0053) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CoincOutputMode"		Name="Coinc Output Mode"
+(0009,0054) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="UpperEnergyLimit"		Name="Upper Energy Limit"
+(0009,0055) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LowerEnergyLimit"		Name="Lower Energy Limit"
+(0009,0056) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="NormalCalID"			Name="Normal Cal ID"
+(0009,0057) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Normal2DCalID"			Name="Normal 2D Cal ID"
+(0009,0058) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BlankCalID"			Name="Blank Cal ID"
+(0009,0059) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="WCCalID"			Name="WC Cal ID"
+(0009,005a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Derived"			Name="Derived"
+(0009,005b) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ContrastAgent"			Name="Contrast Agent"
+(0009,005c) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="frame_id"				Name="frame_id"
+(0009,005d) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="scan_id"				Name="scan_id"
+(0009,005e) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="exam_id"				Name="exam_id"
+(0009,005f) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="patient_id"			Name="patient_id"
+(0009,0060) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="compatible_version"				Name="compatible_version"
+(0009,0061) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="software_version"				Name="software_version"
+(0009,0062) VERS="GEM"	VR="ST"   VM="1"	Owner="GEMS_PETD_01"		Keyword="where_is_frame"				Name="where_is_frame"
+(0009,0063) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="frame_size"				Name="frame_size"
+(0009,0064) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="file_exists"				Name="file_exists"
+(0009,0065) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="patient_entry"				Name="patient_entry"
+(0009,0066) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="table_height"				Name="table_height"
+(0009,0067) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="table_z_position"				Name="table_z_position"
+(0009,0068) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="landmark_datetime"				Name="landmark_datetime"
+(0009,0069) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="slice_count"				Name="slice_count"
+(0009,006a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="start_location"				Name="start_location"
+(0009,006b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_delay"				Name="acq_delay"
+(0009,006c) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_start"				Name="acq_start"
+(0009,006d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_duration"				Name="acq_duration"
+(0009,006e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_bin_dur"				Name="acq_bin_dur"
+(0009,006f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_bin_start"				Name="acq_bin_start"
+(0009,0070) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="actual_stop_cond"				Name="actual_stop_cond"
+(0009,0071) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_PETD_01"		Keyword="total_prompts"				Name="total_prompts"
+(0009,0072) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_PETD_01"		Keyword="total_delays"				Name="total_delays"
+(0009,0073) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="frame_valid"				Name="frame_valid"
+(0009,0074) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="validity_info"				Name="validity_info"
+(0009,0075) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="archived"				Name="archived"
+(0009,0076) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="compression"				Name="compression"
+(0009,0077) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="uncompressed_size"				Name="uncompressed_size"
+(0009,0078) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="accum_bin_dur"				Name="accum_bin_dur"
+(0009,0079) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetCompatibleVersion"	Name="Image Set Compatible Version"
+(0009,007a) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetSoftwareVersion"	Name="Image Set Software Version"
+(0009,007b) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetDateTime"		Name="Image Set Date Time"
+(0009,007c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetSource"		Name="Image Set Source"
+(0009,007d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetContents"		Name="Image Set Contents"
+(0009,007e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetType"			Name="Image Set Type"
+(0009,007f) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ImageSetReference"		Name="Image Set Reference"
+(0009,0080) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="MultiPatient"			Name="Multi Patient"
+(0009,0081) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="NumberOfNormals"		Name="Number of Normals"
+(0009,0082) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ColorMapID"			Name="Color Map ID"
+(0009,0083) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="WindowLevelType"		Name="Window Level Type"
+(0009,0084) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Rotate"			Name="Rotate"
+(0009,0085) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Flip"				Name="Flip"
+(0009,0086) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Zoom"				Name="Zoom"
+(0009,0087) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PanX"				Name="PanX"
+(0009,0088) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PanY"				Name="PanY"
+(0009,0089) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="WindowLevelMin"		Name="Window Level Min"
+(0009,008a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="WindowLevelMax"		Name="Window Level Max"
+(0009,008b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ReconMethod"			Name="ReconMethod"
+(0009,008c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Attenuation"			Name="Attenuation"
+(0009,008d) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AttenuationCoefficient"	Name="Attenuation Coefficient"
+(0009,008e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BPFilter"			Name="BP Filter"
+(0009,008f) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BPFilterCutoff"		Name="BP Filter Cutoff"
+(0009,0090) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BPFilterOrder"			Name="BP Filter Order"
+(0009,0091) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BPFilterCenterI"		Name="BP Filter Center I"
+(0009,0092) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BPFilterCenterP"		Name="BP Filter Center P"
+(0009,0093) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AttenSmooth"			Name="Atten Smooth"
+(0009,0094) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AttenSmoothParam"		Name="Atten Smooth Param"
+(0009,0095) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AngleSmoothParam"		Name="Angle Smooth Param"
+(0009,0096) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="WellCounterCalID"		Name="Well CounterCal ID"
+(0009,0097) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TransScanID"			Name="Trans Scan ID"
+(0009,0098) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="NormCalID"			Name="Norm Cal ID"
+(0009,0099) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BlnkCalID"			Name="Blnk Cal ID"
+(0009,009a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CACEdgeThreshold"		Name="CAC Edge Threshold"
+(0009,009b) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CACSkullOffset"		Name="CAC Skull Offset"
+(0009,009c) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="EmissSubID"			Name="Emiss Sub ID"
+(0009,009d) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="RadialFilter3D"		Name="Radial Filter 3D"
+(0009,009e) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="RadialCutoff3D"		Name="Radial Cutoff 3D"
+(0009,009f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialFilter3D"			Name="Axial Filter 3D"
+(0009,00a0) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialCutoff3D"			Name="Axial Cutoff 3D"
+(0009,00a1) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialStart"			Name="Axial Start"
+(0009,00a2) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialSpacing"			Name="Axial Spacing"
+(0009,00a3) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxialAnglesUsed"		Name="Axial Angles Used"
+(0009,00a4) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="compatible_version"	Name="compatible_version"
+(0009,00a5) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="software_version"		Name="software_version"
+(0009,00a6) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="slice_number"			Name="slice_number"
+(0009,00a7) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="total_counts"			Name="total_counts"
+(0009,00a8) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_PETD_01"		Keyword="other_atts"			Name="other_atts"
+(0009,00a9) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="other_atts_size"		Name="other_atts_size"
+(0009,00aa) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="archived"				Name="archived"
+(0009,00ab) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="bp_center_x"			Name="bp_center_x"
+(0009,00ac) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="bp_center_y"			Name="bp_center_y"
+(0009,00ad) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="trans_frame_id"		Name="trans_frame_id"
+(0009,00ae) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="tpluse_frame_id"		Name="tpluse_frame_id"
+(0009,00b1) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="profile_spacing"		Name="profile_spacing"
+(0009,00b2) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRNumIterations"		Name="IR Num Iterations"
+(0009,00b3) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRNumSubsets"			Name="IR Num Subsets"
+(0009,00b4) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRReconFOV"			Name="IR Recon FOV"
+(0009,00b5) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRCorrModel"			Name="IR Corr Model"
+(0009,00b6) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRLoopFilter"			Name="IR Loop Filter"
+(0009,00b7) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRPreFiltParam"		Name="IR Pre Filt Param"
+(0009,00b8) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRLoopFiltParam"		Name="IR Loop Filt Param"
+(0009,00b9) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ResponseFiltParam"		Name="Response Filt Param"
+(0009,00ba) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PostFilter"			Name="Post Filter"
+(0009,00bb) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PostFilterParam"		Name="Post Filter Param"
+(0009,00bc) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRRegularize"			Name="IR Regularize"
+(0009,00bd) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="IRRegularizeParam"		Name="IR Regularize Param"
+(0009,00be) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ACBPFilter"			Name="AC BP Filter"
+(0009,00bf) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ACBPFiltCutoff"		Name="AC BP Filt Cutoff"
+(0009,00c0) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ACBPFiltOrder"			Name="AC BP Filt Order"
+(0009,00c1) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ACImgSmooth"			Name="AC Img Smooth"
+(0009,00c2) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ACImgSmoothParm"		Name="AC Img Smooth Parm"
+(0009,00c3) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScatterMethod"			Name="Scatter Method"
+(0009,00c4) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScatterNumIter"		Name="Scatter Num Iter"
+(0009,00c5) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ScatterParm"			Name="Scatter Parm"
+(0009,00c6) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="seg_qc_parm"			Name="seg_qc_parm"
+(0009,00c7) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="overlap"				Name="overlap"
+(0009,00c8) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ovlp_frm_id"			Name="ovlp_frm_id"
+(0009,00c9) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ovlp_trans_frm_id"		Name="ovlp_trans_frm_id"
+(0009,00ca) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ovlp_tpulse_frm_id"	Name="ovlp_tpulse_frm_id"
+(0009,00cb) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="vqc_x_axis_trans"				Name="vqc_x_axis_trans"
+(0009,00cc) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="vqc_x_axis_tilt"				Name="vqc_x_axis_tilt"
+(0009,00cd) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="vqc_y_axis_trans"				Name="vqc_y_axis_trans"
+(0009,00ce) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="vqc_y_axis_swivel"				Name="vqc_y_axis_swivel"
+(0009,00cf) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="vqc_z_axis_trans"				Name="vqc_z_axis_trans"
+(0009,00d0) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="vqc_z_axis_roll"				Name="vqc_z_axis_roll"
+(0009,00d1) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ctac_conv_scale"				Name="ctac_conv_scale"
+(0009,00d2) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="image_set_id"					Name="image_set_id"
+(0009,00d3) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="contrast_route"				Name="contrast_route"
+(0009,00d4) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ctac_conv_scale"				Name="ctac_conv_scale"
+(0009,00d5) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="loop_filter_parm"				Name="loop_filter_parm"
+(0009,00d6) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="image_one_loc"					Name="image_one_loc"
+(0009,00d7) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="image_index_loc"				Name="image_index_loc"
+(0009,00d8) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="frame_number"					Name="frame_number"
+(0009,00d9) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="list_file_exists"				Name="list_file_exists"
+(0009,00da) VERS="GEM"	VR="ST"   VM="1"	Owner="GEMS_PETD_01"		Keyword="where_is_list_frame"			Name="where_is_list_frame"
+(0009,00db) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ir_z_filter_flag"				Name="ir_z_filter_flag"
+(0009,00dc) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ir_z_filter_ratio"				Name="ir_z_filter_ratio"
+(0009,00dd) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_PETD_01"		Keyword="num_of_rr_interval"			Name="num_of_rr_interval"
+(0009,00de) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_PETD_01"		Keyword="num_of_time_slots"				Name="num_of_time_slots"
+(0009,00df) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_PETD_01"		Keyword="num_of_slices"					Name="num_of_slices"
+(0009,00e0) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_PETD_01"		Keyword="num_of_time_slices"			Name="num_of_time_slices"
+(0009,00e1) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="unlisted_scan"					Name="unlisted_scan"
+(0009,00e2) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="rest_stress"					Name="rest_stress"
+(0009,00e3) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="phase_percentage"				Name="phase percentage"
+(0009,00e4) VERS="GEM"	VR="ST"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"								Name="?"
+(0009,00e5) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="left_shift"					Name="left shift"
+(0009,00e6) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="posterior_shift"				Name="posterior shift"
+(0009,00e7) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="superior_shift"				Name="superior shift"
+(0009,00e8) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_bin_num"					Name="acq_bin_num"
+(0009,00e9) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="acq_bin_dur_percent"			Name="acq_bin_dur_percent"
+(0009,00ea) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"								Name="?"
+(0009,00eb) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"								Name="?"
+(0009,00ec) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"								Name="?"
+(0011,0001) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"				Name="?"
+(0011,0018) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"				Name="?"
+(0013,0001) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_PETD_01"		Keyword="?"				Name="?"
+(0017,0001) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="correction_cal_id"				Name="correction_cal_id"
+(0017,0002) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="compatible_version"			Name="compatible_version"
+(0017,0003) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="software_version"				Name="software_version"
+(0017,0004) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_datetime"					Name="cal_datetime"
+(0017,0005) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_description"				Name="cal_datetime"
+(0017,0006) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_type"						Name="cal_type"
+(0017,0007) VERS="GEM"	VR="ST"   VM="1"	Owner="GEMS_PETD_01"		Keyword="where_is_corr"					Name="where_is_corr"
+(0017,0008) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="corr_file_size"				Name="corr_file_size"
+(0017,0009) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="scan_id"						Name="scan_id"
+(0017,000a) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="scan_datetime"					Name="scan_datetime"
+(0017,000b) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="norm_2d_cal_id"				Name="norm_2d_cal_id"
+(0017,000c) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="hosp_identifier"				Name="hosp_identifier"
+(0017,000d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="archived"						Name="archived"
+(0019,0001) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="wc_cal_id"				Name="wc_cal_id"
+(0019,0002) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="compatible_version"				Name="compatible_version"
+(0019,0003) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="software_version"				Name="software_version"
+(0019,0004) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_datetime"				Name="cal_datetime"
+(0019,0005) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_type"				Name="cal_type"
+(0019,0006) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_description"				Name="cal_description"
+(0019,0007) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="cal_hardware"				Name="cal_hardware"
+(0019,0008) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_PETD_01"		Keyword="coefficients"				Name="coefficients"
+(0019,0009) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="activity_factor_hr"				Name="activity_factor_hr"
+(0019,000a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="activity_factor_hs"				Name="activity_factor_hs"
+(0019,000b) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="activity_factor_3d"				Name="activity_factor_3d"
+(0019,000c) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="scan_id"				Name="scan_id"
+(0019,000d) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="scan_datetime"				Name="scan_datetime"
+(0019,000e) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="hosp_identifier"				Name="hosp_identifier"
+(0019,000f) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="meas_activity"				Name="meas_activity"
+(0019,0010) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="meas_datetime"				Name="meas_datetime"
+(0019,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="axial_filter_3d"				Name="axial_filter_3d"
+(0019,0012) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="axial_cutoff_3d"				Name="axial_cutoff_3d"
+(0019,0013) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="default_flag"				Name="default_flag"
+(0019,0014) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="archived"				Name="archived"
+(0019,0015) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="wc_cal_rec_method"				Name="wc_cal_rec_method"
+(0019,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="activity_factor_2d"				Name="activity_factor_2d"
+(0019,0017) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="isotope"				Name="isotope"
+(0021,0001) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_PETD_01"		Keyword="raw_data_type"					Name="raw_data_type"
+(0021,0002) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="raw_data_size"					Name="raw_data_size"
+(0023,0001) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_PETD_01"		Keyword="raw_data_blob"					Name="raw_data_blob"
+(5001,0001) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurveID"			Name="Curve ID"
+(5001,0002) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurveCompatibleVersion"	Name="Curve Compatible Version"
+(5001,0003) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurveSoftwareVersion"		Name="Curve Software Version"
+(5001,0004) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="StatisticsType"		Name="Statistics Type"
+(5001,0005) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="HowDerived"			Name="How Derived"
+(5001,0006) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="HowDerivedSize"		Name="How Derived Size"
+(5001,0007) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="MultiPatient"			Name="Multi Patient"
+(5001,0008) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Deadtime"			Name="Deadtime"
+(5003,0001) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphSequence"			Name="Graph Sequence"
+(5003,0002) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphID"			Name="Graph ID"
+(5003,0003) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphCompatibleVersion"	Name="Graph Compatible Version"
+(5003,0004) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphSoftwareVersion"		Name="Graph Software Version"
+(5003,0005) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Title"				Name="Title"
+(5003,0006) VERS="GEM"	VR="DT"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphDateTime"			Name="Graph Date Time"
+(5003,0007) VERS="GEM"	VR="ST"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphDescription"		Name="Graph Description"
+(5003,0008) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TitleFontName"			Name="Title Font Name"
+(5003,0009) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="TitleFontSize"			Name="Title Font Size"
+(5003,000a) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Footer"			Name="Footer"
+(5003,000b) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="FooterFontSize"		Name="Footer Font Size"
+(5003,000c) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="ForegroundColor"		Name="Foreground Color"
+(5003,000d) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="BackgroundColor"		Name="Background Color"
+(5003,000e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphBorder"			Name="Graph Border"
+(5003,000f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphWidth"			Name="Graph Width"
+(5003,0010) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphHeight"			Name="Graph Height"
+(5003,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Grid"				Name="Grid"
+(5003,0012) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LabelFontName"			Name="Label Font Name"
+(5003,0013) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LabelFontSize"			Name="Label Font Size"
+(5003,0014) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="AxesColor"			Name="Axes Color"
+(5003,0015) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="XAxisLabel"			Name="X Axis Label"
+(5003,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="XAxisUnits"			Name="X Axis Units"
+(5003,0017) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="XMajorTics"			Name="X Major Tics"
+(5003,0018) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="XAxisMin"			Name="X Axis Min"
+(5003,0019) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="XAxisMax"			Name="X Axis Max"
+(5003,001a) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="YAxisLabel"			Name="Y Axis Label"
+(5003,001b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="YAxisUnits"			Name="Y Axis Units"
+(5003,001c) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="YMajorTics"			Name="Y Major Tics"
+(5003,001d) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="YAxisMin"			Name="Y Axis Min"
+(5003,001e) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="YAxisMax"			Name="Y Axis Max"
+(5003,001f) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendFontName"		Name="Legend Font Name"
+(5003,0020) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendFontSize"		Name="Legend Font Size"
+(5003,0021) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendLocationX"		Name="Legend Location X"
+(5003,0022) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendLocationY"		Name="Legend Location Y"
+(5003,0023) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendWidth"			Name="Legend Width"
+(5003,0024) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendHeight"			Name="Legend Height"
+(5003,0025) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LegendBorder"			Name="Legend Border"
+(5003,0026) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="MultiPatient"			Name="Multi Patient"
+(5005,0001) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurvePresentationSequence"	Name="Curve Presentation Sequence"
+(5005,0002) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurvePresentationID"		Name="Curve Presentation ID"
+(5005,0003) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="GraphID"			Name="Graph ID"
+(5005,0004) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurveID"			Name="Curve ID"
+(5005,0005) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurvePresentationCompatibleVersion"	Name="Curve Presentation Compatible Version"
+(5005,0006) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurvePresentationSoftwareVersion"	Name="Curve Presentation Software Version"
+(5005,0007) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="CurveLabel"			Name="Curve Label"
+(5005,0008) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="Color"				Name="Color"
+(5005,0009) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LineType"			Name="Line Type"
+(5005,000a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="LineWidth"			Name="Line Width"
+(5005,000b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PointSymbol"			Name="Point Symbol"
+(5005,000c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PointSymbolDim"		Name="Point Symbol Dim"
+(5005,000d) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_PETD_01"		Keyword="PointColor"			Name="Point Color"
+(0009,0001) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="?"				Name="?"
+(0009,0001) VERS="GEM"	VR="LO"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="FullFidelity"			Name="Full Fidelity"
+(0009,0002) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="SuiteId"			Name="Suite Id"
+(0009,0004) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="ProductId"			Name="Product Id"
+(0009,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StudyName"			Name="Study Name"
+(0009,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StudyFlags"			Name="Study Flags"
+(0009,0012) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StudyType"			Name="Study Type"
+(0009,0017) VERS="GEM"  VR="LT"   VM="1"        Owner="GEMS_IDEN_01" 		Keyword="?" 				Name="?"
+(0009,001a) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_IDEN_01"		Keyword="?"				Name="?"
+(0009,001e) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetUID"			Name="Dataset UID"
+(0009,0020) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeriesObjectName"		Name="Series Object Name"
+(0009,0020) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_IDEN_01" 		Keyword="?" 				Name="?"
+(0009,0021) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeriesFlags"			Name="Series Flags"
+(0009,0022) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="UserOrientation"		Name="User Orientation"
+(0009,0023) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InitiationType"		Name="Initiation Type"
+(0009,0024) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,0024) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InitiationDelay"		Name="Initiation Delay"
+(0009,0025) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InitiationCountRate"		Name="Initiation Count Rate"
+(0009,0025) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,0026) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumberEnergySets"		Name="Number Energy Sets"
+(0009,0027) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="ImageActualDate"		Name="Image Actual Date"
+(0009,0027) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumberDetectors"		Name="Number Detectors"
+(0009,0028) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumberRRWindows"		Name="Number RR Windows"
+(0009,0029) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumberMGTimeSlots"		Name="Number MG Time Slots"
+(0009,002a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumberViewSets"		Name="Number View Sets"
+(0009,002b) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TriggerHistoryUID"		Name="Trigger History UID"
+(0009,002c) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeriesComments"		Name="Series Comments"
+(0009,002d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TrackBeatAverage"		Name="Track Beat Average"
+(0009,002e) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DistancePrescribed"		Name="Distance Prescribed"
+(0009,002f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TableDirection"		Name="Table Direction"
+(0009,002f) VERS="GEM"  VR="SH"   VM="1"    Owner="GEMS_IDEN_01" 		Keyword="?" 				Name="?"
+(0009,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="?"				Name="?"
+(0009,0030) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="ServiceId"			Name="Service Id"
+(0009,0031) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="MobileLocationNumber"		Name="Mobile Location Number"
+(0009,0033) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RotationalContinuousSpeed"	Name="Rotational Continuous Speed"
+(0009,0034) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="GantryMotionTypeRetired"	Name="Gantry Motion Type (Retired)"
+(0009,0035) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="GantryLocusType"		Name="Gantry Locus Type"
+(0009,0037) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StartingHeartRate"		Name="Starting Heart Rate"
+(0009,0038) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RRWindowWidth"			Name="RR Window Width"
+(0009,0039) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RRWindowOffset"		Name="RR Window Offset"
+(0009,003a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PercentCycleImaged"		Name="Percent Cycle Imaged"
+(0009,003e) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,003f) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,0040) VERS="GEM"	VR="PN"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PatientObjectName"		Name="Patient Object Name"
+(0009,0041) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PatientFlags"			Name="Patient Flags"
+(0009,0042) VERS="GEM"	VR="DA"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PatientCreationDate"		Name="Patient Creation Date"
+(0009,0042) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,0043) VERS="GEM"	VR="TM"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PatientCreationTime"		Name="Patient Creation Time"
+(0009,0043) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,0044) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumViewsAcquiredRetired"	Name="Num Views Acquired (Retired)"
+(0009,0045) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="?"				Name="?"
+(0009,0046) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="?"				Name="?"
+(0009,00e2) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_IDEN_01"		Keyword="?"				Name="?"
+(0009,00e3) VERS="GEM"	VR="UI"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="EquipmentUID"			Name="Equipment UID"
+(0009,00e6) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="GenesisVersionNow"		Name="Genesis Version Now"
+(0009,00e7) VERS="GEM"	VR="UL"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="ExamRecordChecksum"		Name="Exam Record Checksum"
+(0009,00e8) VERS="GEM"	VR="UL"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="SeriesSuiteID"			Name="Series Suite ID"
+(0009,00e9) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IDEN_01"		Keyword="ActualSeriesDataTimeStamp"	Name="Actual Series Data Time Stamp"
+(0009,00f8) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0009,00fb) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_ACQU_01"		Keyword="?"				Name="?"
+(0011,0001) VERS="GEM"	VR="LT"   VM="1"	Owner="DLX_PATNT_01"		Keyword="PatientDOB"			Name="Patient DOB"
+(0011,000a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeriesType"			Name="Series Type"
+(0011,000b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="EffectiveSeriesDuration"	Name="Effective Series Duration"
+(0011,000c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumBeats"			Name="Num Beats"
+(0011,000d) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RadioNuclideName"		Name="Radio Nuclide Name"
+(0011,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetObjectName"		Name="Dataset Object Name"
+(0011,0010) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_PATI_01"		Keyword="PatientStatus"			Name="Patient Status"
+(0011,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetModified"		Name="Dataset Modified"
+(0011,0012) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetName"			Name="Dataset Name"
+(0011,0013) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetType"			Name="Dataset Type"
+(0011,0014) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CompletionTime"		Name="Completion Time"
+(0011,0015) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DetectorNumber"		Name="Detector Number"
+(0011,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="EnergyNumber"			Name="Energy Number"
+(0011,0017) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RRIntervalWindowNumber"	Name="RR Interval Window Number"
+(0011,0018) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="MGBinNumber"			Name="MG Bin Number"
+(0011,0019) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RadiusOfRotation"		Name="Radius Of Rotation"
+(0011,001a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DetectorCountZone"		Name="Detector Count Zone"
+(0011,001b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumEnergyWindows"		Name="Num Energy Windows"
+(0011,001c) VERS="GEM"	VR="SL"   VM="4"	Owner="GEMS_GENIE_1"		Keyword="EnergyOffset"			Name="Energy Offset"
+(0011,001d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="EnergyRange"			Name="Energy Range"
+(0011,001e) VERS="GEM"	VR="SL"   VM="4"	Owner="GEMS_GENIE_1"		Keyword="EnergyWidthRetired"		Name="Energy Width (Retired)"
+(0011,001f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ImageOrientation"		Name="Image Orientation"
+(0011,0021) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AcqZoomRetired"		Name="Acq Zoom (Retired)"
+(0011,0022) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AcqPanRetired"			Name="Acq Pan (Retired)"
+(0011,0023) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="UseFOVMask"			Name="Use FOV Mask"
+(0011,0024) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FOVMaskYCutoffAngle"		Name="FOV Mask Y Cutoff Angle"
+(0011,0025) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FOVMaskCutoffAngle"		Name="FOV Mask Cutoff Angle"
+(0011,0026) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TableOrientation"		Name="Table Orientation"
+(0011,0027) VERS="GEM"	VR="SL"   VM="2"	Owner="GEMS_GENIE_1"		Keyword="ROITopLeft"			Name="ROI Top Left"
+(0011,0028) VERS="GEM"	VR="SL"   VM="2"	Owner="GEMS_GENIE_1"		Keyword="ROIBottomRight"		Name="ROI Bottom Right"
+(0011,0029) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="UniformityMean"		Name="Uniformity Mean"
+(0011,002a) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PhaseDurationRetired"		Name="Phase Duration (Retired)"
+(0011,002c) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ViewXAdjustment"		Name="View X Adjustment"
+(0011,002d) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ViewYAdjustment"		Name="View Y Adjustment"
+(0011,002e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PixelOverflowFlag"		Name="Pixel Overflow Flag"
+(0011,002f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="OverflowLevel"			Name="Overflow Level"
+(0011,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PictureObjectName"		Name="Picture Object Name"
+(0011,0031) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AcquisitionParentUID"		Name="Acquisition Parent UID"
+(0011,0032) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ProcessingParentUID"		Name="Processing Parent UID"
+(0011,0033) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="EnergyCorrectName"		Name="Energy Correct Name"
+(0011,0034) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SpatialCorrectName"		Name="Spatial Correct Name"
+(0011,0035) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TuningCalibName"		Name="Tuning Calib Name"
+(0011,0036) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="UniformityCorrectName"		Name="Uniformity Correct Name"
+(0011,0037) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AcquisitionSpecificCorrectName"	Name="Acquisition Specific Correct Name"
+(0011,0038) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ByteOrder"			Name="Byte Order"
+(0011,0039) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CompressionType"		Name="Compression Type"
+(0011,003a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PictureFormat"			Name="Picture Format"
+(0011,003b) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PixelScale"			Name="Pixel Scale"
+(0011,003c) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PixelOffset"			Name="Pixel Offset"
+(0011,003d) VERS="GEM"	VR="SL"   VM="4"	Owner="GEMS_GENIE_1"		Keyword="EnergyPeakRetired"		Name="Energy Peak (Retired)"
+(0011,003e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FOVShape"			Name="FOV Shape"
+(0011,003f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetFlags"			Name="Dataset Flags"
+(0011,0040) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ViewingObjectName"		Name="Viewing Object Name"
+(0011,0041) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="OrientationAngle"		Name="Orientation Angle"
+(0011,0042) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RotationAngle"			Name="Rotation Angle"
+(0011,0043) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="WindowInverseFlag"		Name="Window Inverse Flag"
+(0011,0044) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ThresholdCenter"		Name="Threshold Center"
+(0011,0045) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ThresholdWidth"		Name="Threshold Width"
+(0011,0046) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InterpolationType"		Name="Interpolation Type"
+(0011,0050) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="WhereObjectName"		Name="Where Object Name"
+(0011,0055) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Period"			Name="Period"
+(0011,0056) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ElapsedTime"			Name="ElapsedTime"
+(0011,0057) VERS="GEM"	VR="FD"   VM="2"	Owner="GEMS_GENIE_1"		Keyword="FOV"				Name="FOV"
+(0011,0061) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ImageSize"			Name="Image Size"
+(0011,0062) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="LinearFOV"			Name="Linear FOV"
+(0011,0063) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SpatialOffset"			Name="Spatial Offset"
+(0011,0064) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SpatialOrientation"		Name="Spatial Orientation"
+(0011,0065) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReferenceDatasetUID"		Name="Reference Dataset UID"
+(0011,0066) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StarcamReferenceDataset"	Name="Starcam Reference Dataset"
+(0011,0067) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReferenceFrameNumber"		Name="Reference Frame Number"
+(0011,0068) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CursorLength"			Name="Cursor Length"
+(0011,0069) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumberOfCursors"		Name="Number of Cursors"
+(0011,006a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CursorCoordinates"		Name="Cursor Coordinates"
+(0011,006b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReconOptionsFlag"		Name="Recon Options Flag"
+(0011,006c) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="MotionThreshold"		Name="Motion Threshold"
+(0011,006d) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="MotionCurveUID"		Name="Motion Curve UID"
+(0011,006e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReconType"			Name="Recon Type"
+(0011,006f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PreFilterType"			Name="Pre Filter Type"
+(0011,0071) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="BackProjFilterType"		Name="Back Proj Filter Type"
+(0011,0072) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReconArc"			Name="Recon Arc"
+(0011,0073) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReconPanAPOffset"		Name="Recon Pan AP Offset"
+(0011,0074) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReconPanLROffset"		Name="Recon Pan LR Offset"
+(0011,0075) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ReconArea"			Name="Recon Area"
+(0011,0076) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StartView"			Name="Start View"
+(0011,0077) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AttenuationType"		Name="Attenuation Type"
+(0011,0078) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DualEnergyProcessing"		Name="Dua lEnergy Processing"
+(0011,0079) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PreFilterParam"		Name="Pre Filter Param"
+(0011,007a) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PreFilterParam2"		Name="Pre Filter Param 2"
+(0011,007b) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="BackProjFilterParam"		Name="Back Proj Filter Param"
+(0011,007c) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="BackProjFilterParam2"		Name="Back Proj Filter Param 2"
+(0011,007d) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AttenuationCoef"		Name="Attenuation Coef"
+(0011,007e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RefSliceWidth"			Name="Ref Slice Width"
+(0011,007f) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RefTransPixelVolume"		Name="Ref Trans Pixel Volume"
+(0011,0081) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AttenuationThreshold"		Name="Attenuation Threshold"
+(0011,0082) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InterpolationDistance"		Name="Interpolation Distance"
+(0011,0083) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InterpolationCenterX"		Name="Interpolation Center X"
+(0011,0084) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="InterpolationCenterY"		Name="Interpolation Center Y"
+(0011,0085) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="QuantFilterFlag"		Name="Quant Filter Flag"
+(0011,0086) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="HeadConversion"		Name="Head Conversion"
+(0011,0087) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SliceWidthPixels"		Name="Slice Width Pixels"
+(0011,0088) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RfmtrTransRef"			Name="Rfmtr Trans Ref"
+(0011,0089) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RfmtrTransRefmm"		Name="Rfmtr Trans Ref mm"
+(0011,008a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TwoLineTransRef"		Name="Two Line Trans Ref"
+(0011,008b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ThreeDZero"			Name="Three-D Zero"
+(0011,008c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ThreeDZeroLength"		Name="Three-D Zero Length"
+(0011,008d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ThreeDZeroIn"			Name="Three-D Zero In"
+
+(0011,0080) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_DL_PATNT_01"	Keyword="PatientInstanceUid"	Name="Patient Instance Uid"
+(0011,0081) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_PATNT_01"	Keyword="LastStudyNumber"		Name="Last Study Number"
+(0011,0082) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_PATNT_01"	Keyword="PatientRepaired"		Name="Patient Repaired"
+(0011,0083) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_PATNT_01"	Keyword="LockDemographics"		Name="Lock Demographics"
+
+(0013,0010) VERS="GEM"	VR="FD"   VM="2"	Owner="GEMS_GENIE_1"		Keyword="DigitalFOV"			Name="Digital FOV"
+(0013,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SourceTranslator"		Name="Source Translator"
+(0013,0012) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="RALFlags"			Name="RAL Flags"
+(0013,0013) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRAFrameSequence"		Name="eNTEGRA Frame Sequence"
+(0013,0014) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="OriginalImageNumber"		Name="Original Image Number"
+(0013,0015) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Fscalar"			Name="Fscalar"
+(0013,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AutoTrackPeak"			Name="AutoTrack Peak"
+(0013,0017) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AutoTrackWidth"		Name="AutoTrack Width"
+(0013,0018) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TransmissionScanTime"		Name="Transmission Scan Time"
+(0013,0019) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TransmissionMaskWidth"		Name="Transmission Mask Width"
+(0013,001a) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CopperAttenuatorThickness"	Name="Copper Attenuator Thickness"
+(0013,001b) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DetAngSeparation"		Name="Det Ang Separation"
+(0013,001c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AxialAcceptanceAngle"		Name="Axial Acceptance Angle"
+(0013,001d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ThetaAcceptanceValue"		Name="Theta Acceptance Value"
+(0013,001e) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="TomoViewOffset"		Name="Tomo View Offset"
+(0013,0020) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="AcceptedBeatsTime"		Name="Accepted Beats Time"
+(0013,0021) VERS="GEM"	VR="FD"   VM="2"	Owner="GEMS_GENIE_1"		Keyword="Threshold"			Name="Threshold"
+(0013,0022) VERS="GEM"	VR="FD"   VM="2"	Owner="GEMS_GENIE_1"		Keyword="LinearDepth"			Name="Linear Depth"
+(0013,0023) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="UnifDateTime"			Name="Unif Date Time"
+(0013,0024) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeriesAcceptedBeats"		Name="Series Accepted Beats"
+(0013,0025) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeriesRejectedBeats"		Name="Series Rejected Beats"
+(0013,0026) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StudyComments"			Name="Study Comments"
+(0015,0001) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_EXAMS_01"		Keyword="StenosisCalibrationRatio"	Name="Stenosis Calibration Ratio"
+(0015,0002) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_EXAMS_01"		Keyword="StenosisMagnification"		Name="Stenosis Magnification"
+(0015,0003) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_EXAMS_01"		Keyword="CardiacCalibrationRatio"	Name="Cardiac Calibration Ratio"
+(0015,0010) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FrameTerminationCondition"	Name="Frame Termination Condition"
+(0015,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FrameTerminationValue"		Name="Frame Termination Value"
+(0015,0012) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumECTPhases"			Name="Num ECT Phases"
+(0015,0013) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NumWBScans"			Name="Num WB Scans"
+(0015,0014) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ECTPhaseNum"			Name="ECT Phase Num"
+(0015,0015) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="WBScanNum"			Name="WB Scan Num"
+(0015,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CombHeadNumber"		Name="Comb Head Number"
+(0015,0017) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="PrecedingBeat"			Name="Preceding Beat"
+
+(0015,0080) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="Study Dose"					Name="Study Dose"
+(0015,0081) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="StudyTotalDap"					Name="Study Total Dap"
+(0015,0082) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="FluoroDoseAreaProduct"			Name="Fluoro Dose Area Product"
+(0015,0083) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="Study luoroTime"				Name="Study Fluoro Time"
+(0015,0084) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="CineDoseAreaProduct"			Name="Cine Dose Area Product"
+(0015,0085) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="StudyRecordTime"				Name="Study Record Time"
+(0015,0086) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="LastXANumber"					Name="Last XA Number"
+(0015,0088) VERS="GEM"	VR="PN"   VM="1-n"	Owner="GEMS_DL_STUDY_01"		Keyword="DefOperatorName"				Name="Def Operator Name"
+(0015,0089) VERS="GEM"	VR="PN"   VM="1-n"	Owner="GEMS_DL_STUDY_01"		Keyword="DefPerformingPhysicianName"	Name="Def Performing Physician Name"
+(0015,008A) VERS="GEM"	VR="CS"   VM="2"	Owner="GEMS_DL_STUDY_01"		Keyword="DefPatientOrientation"			Name="Def Patient Orientation"
+(0015,008B) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="LastScNumber"					Name="Last Sc Number"
+(0015,008E) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="CommonSeriesInstanceUID"		Name="Common Series Instance UID"
+(0015,008F) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="StudyNumber"					Name="Study Number"
+(0015,0092) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,0093) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,0094) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,0095) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,0096) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,0097) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,0098) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?" 
+(0015,0099) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,009a) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,009b) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,009c) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+(0015,009d) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_STUDY_01"		Keyword="?"			Name="?"
+
+(0015,0085) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_SERIES_01"		Keyword="SeriesFileName"	Name="Series File Name"
+(0015,0087) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_SERIES_01"		Keyword="NumberOfImages"	Name="Number of Images"
+(0015,008C) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_SERIES_01"		Keyword="SentFlag"			Name="Sent Flag"
+(0015,008D) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_SERIES_01"		Keyword="ItemLocked"		Name="Item Locked"
+
+(0019,0001) VERS="GEM"  VR="LT"   VM="1"    Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0002) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="NumberOfCellsInDetector"		Name="Number Of Cells In Detector"
+(0019,0003) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CellNumberAtTheta"			Name="Cell Number At Theta"
+(0019,0004) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CellSpacing"				Name="Cell Spacing"
+(0019,0005) VERS="GEM"  VR="LT"   VM="1"    Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0006) VERS="GEM"  VR="UN"   VM="1"    Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,000e) VERS="GEM"  VR="US"   VM="1"    Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,000f) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="HorizontalFrameOfReference"		Name="Horizontal Frame Of Reference"
+(0019,0011) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SeriesContrast"			Name="Series Contrast"
+(0019,0012) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="LastPseq"				Name="Last Pseq"
+(0019,0013) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="StartNumberForBaseline"		Name="Start Number For Baseline"
+(0019,0014) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="End NumberForBaseline"			Name="End Number For Baseline"
+(0019,0015) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="StartNumberForEnhancedScans"		Name="Start Number For Enhanced Scans"
+(0019,0016) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="EndNumberForEnhancedScans"		Name="End Number For Enhanced Scans"
+(0019,0017) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SeriesPlane"				Name="Series Plane"
+(0019,0018) VERS="GEM"	VR="LO"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="FirstScanRAS"				Name="First Scan RAS"
+(0019,0019) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="FirstScanLocation"			Name="First Scan Location"
+(0019,001a) VERS="GEM"	VR="LO"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="LastScanRAS"				Name="Last Scan RAS"
+(0019,001b) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="LastScanLocation"			Name="Last Scan Location"
+(0019,001e) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="DisplayFieldOfView"			Name="Display Field Of View"
+(0019,0020) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0022) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0023) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TableSpeed"				Name="Table Speed [mm/rotation]"
+(0019,0024) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="MidScanTime"				Name="Mid Scan Time [sec]"
+(0019,0025) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="MidScanFlag"				Name="Mid Scan Flag"
+(0019,0026) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TubeAzimuth"				Name="Tube Azimuth [degrees]"
+(0019,0027) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="RotationSpeed"				Name="Rotation Speed (Gantry Period)"
+(0019,002a) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="XrayOnPosition"			Name="Xray On Position"
+(0019,002b) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="XrayOffPosition"			Name="Xray Off Position"
+(0019,002c) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="NumberOfTriggers"			Name="Number of Triggers"
+(0019,002d) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,002e) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AngleOfFirstView"			Name="Angle Of First View"
+(0019,002f) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TriggerFrequency"			Name="Trigger Frequency"
+(0019,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GE ??? From Adantage Review CS"	Keyword="CREDRMode"			Name="CR EDR Mode"
+(0019,0039) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ScanFOVType"				Name="Scan FOV Type"
+(0019,0039) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="AxialType"				Name="Axial Type"
+(0019,003a) VERS="GEM"  VR="IS"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,003b) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,003c) VERS="GEM"  VR="UN"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,003e) VERS="GEM"  VR="UN"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,003f) VERS="GEM"  VR="UN"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0040) VERS="GEM"	VR="LO"   VM="1"	Owner="GE ??? From Adantage Review CS"	Keyword="CRLatitude"			Name="CR Latitude"
+(0019,0040) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="StatReconFlag"				Name="Stat Recon Flag"
+(0019,0041) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ComputeType"				Name="Compute Type"
+(0019,0042) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SegmentNumber"				Name="Segment Number"
+(0019,0043) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TotalSegmentsRequired"			Name="Total Segments Required"
+(0019,0044) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="InterscanDelay"			Name="Interscan Delay"
+(0019,0047) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ViewCompressionFactor"			Name="View Compression Factor"
+(0019,0048) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0049) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,004a) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TotalNumberOfRefChannels"		Name="Total Number Of Ref Channels"
+(0019,004b) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="DataSizeForScanData"			Name="Data Size For Scan Data"
+(0019,0050) VERS="GEM"	VR="LO"   VM="1"	Owner="GE ??? From Adantage Review CS"	Keyword="CRGroupNumber"			Name="CR Group Number"
+(0019,0052) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ReconPostProcessingFlag"		Name="Recon Post Processing Flag"
+(0019,0054) VERS="GEM"  VR="UN"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0057) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CTWaterNumber"				Name="CT Water Number"
+(0019,0058) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CTBoneNumber"				Name="CT Bone Number"
+(0019,005a) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AcquisitionDuration"			Name="Acquisition Duration"
+(0019,005d) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,005e) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="NumberOfChannels1To512"		Name="Number Of Channels 1 To 512"
+(0019,005f) VERS="GEM"	VR="SQ"	  VM="1"	Owner="GEMS_GENIE_1"	Keyword="?"					Name="?"
+(0019,005f) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="IncrementBetweenChannels"		Name="Increment Between Channels"
+(0019,0060) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="StartingView"				Name="Starting View"
+(0019,0061) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="NumberOfViews"				Name="Number Of Views"
+(0019,0062) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="IncrementBetweenViews"			Name="Increment Between Views"
+(0019,006a) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="DependantOnNumberOfViewsProcessed"	Name="Dependant On Number Of Views Processed"
+(0019,006b) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="FieldOfViewInDetectorCells"		Name="Field Of View In Detector Cells"
+(0019,0070) VERS="GEM"	VR="LO"   VM="1"	Owner="GE ??? From Adantage Review CS"	Keyword="CRImageSerialNumber"		Name="CR Image Serial Number"
+(0019,0070) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ValueOfBackProjectionButton"		Name="Value Of Back Projection Button"
+(0019,0071) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SetIfFatqEstimatesWereUsed"		Name="Set If Fatq Estimates Were Used"
+(0019,0072) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ZChannelAvgOverViews"			Name="Z Channel Avg Over Views"
+(0019,0073) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AvgOfLeftRefChannelsOverViews"		Name="Avg Of Left Ref Channels Over Views"
+(0019,0074) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="MaxLeftChannelOverViews"		Name="Max Left Channel Over Views"
+(0019,0075) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AvgOfRightRefChannelsOverViews"	Name="Avg Of Right Ref Channels Over Views"
+(0019,0076) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="MaxRightChannelOverViews"		Name="Max Right Channel Over Views"
+(0019,007d) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SecondEcho"				Name="Second Echo"
+(0019,007e) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="NumberOfEchos"				Name="Number Of Echos"
+(0019,007f) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TableDelta"				Name="Table Delta"
+(0019,0080) VERS="GEM"	VR="LO"   VM="1"	Owner="GE ??? From Adantage Review CS"	Keyword="CRBarCodeNumber"		Name="CR Bar Code Number"
+(0019,0081) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="Contiguous"				Name="Contiguous"
+(0019,0082) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0083) VERS="GEM"  VR="DS"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0084) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PeakSAR"				Name="Peak SAR"
+(0019,0085) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="MonitorSAR"				Name="Monitor SAR"
+(0019,0086) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,0087) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CardiacRepetition Time"		Name="Cardiac Repetition Time"
+(0019,0088) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ImagesPerCardiacCycle"			Name="Images Per Cardiac Cycle"
+(0019,008a) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ActualReceiveGainAnalog"		Name="Actual Receive Gain Analog"
+(0019,008b) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ActualReceiveGainDigital"		Name="Actual Receive Gain Digital"
+(0019,008d) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="DelayAfterTrigger"			Name="Delay After Trigger"
+(0019,008f) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SwapPhaseFrequency"			Name="Swap Phase Frequency"
+(0019,008f) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="SwapPhaseFrequency"		Name="Swap Phase Frequency"
+(0019,0090) VERS="GEM"	VR="LO"   VM="1"	Owner="GE ??? From Adantage Review CS"	Keyword="CRFilmOutputExposures"		Name="CR Film Output Exposures"
+(0019,0090) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PauseInterval"				Name="Pause Interval"
+(0019,0091) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PauseTime"				Name="Pause Time"
+(0019,0092) VERS="GEM"	VR="SL"	VM="1"	Owner="GEMS_ACQU_01"	Keyword="SliceOffsetOnFrequencyAxis"		Name="Slice Offset On Frequency Axis"
+(0019,0093) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AutoPrescanCenterFrequency"			Name="Auto Prescan Center Frequency"
+(0019,0094) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AutoPrescanTransmitGain"				Name="Auto Prescan Transmit Gain"
+(0019,0095) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AutoPrescanAnalogReceiverGain"			Name="Auto Prescan Analog Receiver Gain"
+(0019,0096) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="AutoPrescanDigitalReceiverGain"			Name="Auto Prescan Digital Receiver Gain"
+(0019,0097) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="BitmapDefiningCVs"			Name="Bitmap Defining CVs"
+(0019,0098) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CenterFrequencyMethod"			Name="Center Frequency Method"
+(0019,0099) VERS="GEM"  VR="US"   VM="1"        Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,009b) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PulseSequenceMode"			Name="Pulse Sequence Mode"
+(0019,009c) VERS="GEM"	VR="LO"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PulseSequenceName"			Name="Pulse Sequence Name"
+(0019,009c) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PulseSequenceName"			Name="Pulse Sequence Name"
+(0019,009d) VERS="GEM"	VR="DT"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PulseSequenceDate"			Name="Pulse Sequence Date"
+(0019,009e) VERS="GEM"	VR="LO"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="InternalPulseSequenceName"		Name="Internal Pulse Sequence Name"
+(0019,009f) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TransmittingCoil"			Name="Transmitting Coil"
+(0019,009f) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="CoilType"				Name="Coil Type"
+(0019,00a0) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SurfaceCoilType"			Name="Surface Coil Type"
+(0019,00a1) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ExtremityCoilFlag"			Name="Extremity Coil Flag"
+(0019,00a2) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="RawDataRunNumber"			Name="Raw Data Run Number"
+(0019,00a3) VERS="GEM"	VR="UL"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CalibratedFieldStrength"		Name="Calibrated Field Strength"
+(0019,00a4) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATFatWaterBone"			Name="SAT Fat Water Bone"
+(0019,00a4) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="SATFatWaterBone"		Name="SAT Fat Water Bone"
+(0019,00a5) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ReceiveBandwidth"			Name="Receive Bandwidth"
+(0019,00a7) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData0"					Name="User Data 0"
+(0019,00a8) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData1"					Name="User Data 1"
+(0019,00a9) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData2"					Name="User Data 2"
+(0019,00aa) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData3"					Name="User Data 3"
+(0019,00ab) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData4"					Name="User Data 4"
+(0019,00ac) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData5"					Name="User Data 5"
+(0019,00ad) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData6"					Name="User Data 6"
+(0019,00ae) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData7"					Name="User Data 7"
+(0019,00af) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData8"					Name="User Data 8"
+(0019,00b0) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData9"					Name="User Data 9"
+(0019,00b1) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData10"				Name="User Data 10"
+(0019,00b2) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData11"				Name="User Data 11"
+(0019,00b3) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData12"				Name="User Data 12"
+(0019,00b4) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData13"				Name="User Data 13"
+(0019,00b5) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData14"				Name="User Data 14"
+(0019,00b6) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData15"				Name="User Data 15"
+(0019,00b7) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData16"				Name="User Data 16"
+(0019,00b8) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData17"				Name="User Data 17"
+(0019,00b9) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData18"				Name="User Data 18"
+(0019,00ba) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData19"				Name="User Data 19"
+(0019,00bb) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData20"				Name="User Data 20"
+(0019,00bc) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData21"				Name="User Data 21"
+(0019,00bd) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData22"				Name="User Data 22"
+(0019,00be) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ProjectionAngle"			Name="Projection Angle"
+(0019,00c0) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SaturationPlanes"			Name="Saturation Planes"
+(0019,00c0) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="BitmapOfSATSelections"			Name="Bitmap Of SAT Selections"
+(0019,00c1) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SurfaceCoilIntensityCorrectionFlag"			Name="Surface Coil Intensity Correction Flag"
+(0019,00c1) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="SurfaceCoilIntensityCorrectionFlag"	Name="Surface Coil Intensity Correction Flag"
+(0019,00c2) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATLocationR"				Name="SAT Location R"
+(0019,00c3) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATLocationL"				Name="SAT Location L"
+(0019,00c4) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATLocationA"				Name="SAT Location A"
+(0019,00c5) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATLocationP"				Name="SAT Location P"
+(0019,00c6) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATLocationH"				Name="SAT Location H"
+(0019,00c7) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATLocationF"				Name="SAT Location F"
+(0019,00c8) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATThicknessRL"			Name="SAT Thickness R L"
+(0019,00c9) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATThicknessAP"			Name="SAT Thickness A P"
+(0019,00ca) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="SATThicknessHF"			Name="SAT Thickness H F"
+(0019,00cb) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PhaseContrastFlowAxis"		Name="PhaseContrast Flow Axis"
+(0019,00cb) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PhaseContrastFlowAxis"			Name="Phase Contrast Flow Axis"
+(0019,00cc) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="VelocityEncoding"			Name="Velocity Encoding"
+(0019,00cc) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PhaseContrastVelocityEncoding"		Name="Phase Contrast Velocity Encoding"
+(0019,00cd) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ThicknessDisclaimer"		Name="Thickness Disclaimer"
+(0019,00ce) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PrescanType"				Name="Prescan Type"
+(0019,00cf) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PrescanStatus"				Name="Prescan Status"
+(0019,00d0) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="RawDataType"				Name="Raw Data Type"
+(0019,00d2) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ProjectionAlgorithm"		Name="Projection Algorithm"
+(0019,00d3) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ProjectionAlgorithmName"	Name="Projection Algorithm Name"
+(0019,00d4) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ACQU_01" Keyword="?" Name="?"
+(0019,00d5) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="FractionalEcho"			Name="Fractional Echo"
+(0019,00d5) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="FractionalEcho"			Name="Fractional Echo"
+(0019,00d6) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PrepPulse"				Name="Prep Pulse"
+(0019,00d7) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="CardiacPhases"				Name="Cardiac Phases"
+(0019,00d8) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="VariableEchoFlag"			Name="Variable Echo Flag"
+(0019,00d8) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="VariableEchoFlag"			Name="Variable Echo Flag"
+(0019,00d9) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ConcatenatedSatOrDTIDiffusionDirection"			Name="Concatenated Sat or DTI Diffusion Direction"
+(0019,00d9) VERS="GEM"  VR="DS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="ConcatenatedSat"			Name="Concatenated Sat"
+(0019,00da) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="ReferenceChannelUsed"			Name="Reference Channel Used"
+(0019,00db) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="BackProjectorCoefficient"		Name="Back Projector Coefficient"
+(0019,00dc) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="PrimarySpeedCorrectionUsed"		Name="Primary Speed Correction Used"
+(0019,00dd) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="OverrangeCorrectionUsed"		Name="Overrange Correction Used"
+(0019,00de) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="DynamicZAlphaValue"			Name="Dynamic Z Alpha Value"
+(0019,00df) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData23"				Name="User Data 23 or DTI Diffusion Direction"
+(0019,00e0) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="UserData24"				Name="User Data 24 or DTI Diffusion Direction"
+(0019,00e1) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ACQU_01"	Keyword="?"					Name="?"
+(0019,00e2) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="VelocityEncodeScale"			Name="Velocity Encode Scale"
+(0019,00e3) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?"					Name="?"
+(0019,00e4) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00e5) VERS="GEM"  VR="IS"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00e6) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00e8) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00e9) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00eb) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00ec) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00f0) VERS="GEM"  VR="UN"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00f1) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00f2) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="FastPhases"				Name="Fast Phases"
+(0019,00f2) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="NumberOfPhases"			Name="Number Of Phases"
+(0019,00f3) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00f4) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_ACQU_01" 	Keyword="?" Name="?"
+(0019,00f9) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_ACQU_01"	Keyword="TransmitGain"			Name="Transmit Gain"
+
+(0019,000B) VERS="GEM"	VR="DS"   VM="1-2"	Owner="GEMS_DL_IMG_01"		Keyword="FOVDimensionDouble"			Name="FOV Dimension Double"
+(0019,002B) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DistanceToTableTop"			Name="Distance to table top"
+(0019,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ImageFileName"					Name="Image File Name"
+(0019,0031) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DefaultSpatialFilterFamily"	Name="Default Spatial Filter Family"
+(0019,0032) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DefaultSpatialFilterStrength"	Name="Default Spatial Filter Strength"
+(0019,0033) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="MinSaturationDose"				Name="Min Saturation Dose"
+(0019,0034) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DetectorGain"					Name="Detector Gain"
+(0019,0035) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="PatientDoseLimit"				Name="Patient Dose Limit"
+(0019,0036) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="PreprocImageRateMax"			Name="Preproc Image Rate Max"
+(0019,0037) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SensorRoiShape"				Name="Sensor Roi Shape"
+(0019,0038) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SensorRoixPosition"			Name="Sensor Roi x Position"
+(0019,0039) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SensorRoiyPosition"			Name="Sensor Roi y Position"
+(0019,003A) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SensorRoixSize"				Name="Sensor Roi x Size"
+(0019,003B) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SensorRoiySize"				Name="Sensor Roi y Size"
+(0019,003D) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="NoiseSensitivity"				Name="Noise Sensitivity"
+(0019,003E) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SharpSensitivity"				Name="Sharp Sensitivity"
+(0019,003F) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ContrastSensitivity"			Name="Contrast Sensitivity"
+(0019,0040) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="LagSensitivity"				Name="Lag Sensitivity"
+(0019,0041) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="Tube"							Name="Tube"
+(0019,0042) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DetectorSizeRows"				Name="Detector Size Rows"
+(0019,0043) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DetectorSizeColumns"			Name="Detector Size Columns"
+(0019,0044) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="MinObjectSize"					Name="Min Object Size"
+(0019,0045) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="MaxObjectSize"					Name="Max Object Size"
+(0019,0046) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="MaxObjectSpeed"				Name="Max Object Speed"
+(0019,0047) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ObjectBackMotion"				Name="Object Back Motion"
+(0019,0048) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ExposureTrajectoryFamily"		Name="Exposure Trajectory Family"
+(0019,0049) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="WindowTimeDuration"			Name="Window Time Duration"
+(0019,004A) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="PositionerAngleDisplayMode"	Name="Positioner Angle Display Mode"
+(0019,004B) VERS="GEM"  VR="IS"   VM="2"	Owner="GEMS_DL_IMG_01"		Keyword="DetectorOrigin"				Name="Detector Origin"
+(0019,004C) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,004E) VERS="GEM"	VR="DS"   VM="2"	Owner="GEMS_DL_IMG_01"		Keyword="DefaultBrightnessContrast"		Name="Default Brightness and Contrast"
+(0019,004F) VERS="GEM"	VR="DS"   VM="2"	Owner="GEMS_DL_IMG_01"		Keyword="UserBrightnessContrast"		Name="User Brightness and Contrast"
+(0019,0050) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SourceSeriesNumber"			Name="Source Series Number"
+(0019,0051) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SourceImageNumber"				Name="Source Image Number"
+(0019,0052) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SourceFrameNumber"				Name="Source Frame Number"
+(0019,0053) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SourceSeriesItemId"			Name="Source Series Item Id"
+(0019,0054) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SourceImageItemId"				Name="Source Image Item Id"
+(0019,0055) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SourceFrameItemId"				Name="Source Frame Item Id"
+(0019,0060) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="NumberOfPointsBeforeAcquisition"	Name="Number of Points Before Acquisition"
+(0019,0061) VERS="GEM"  VR="OW"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CurveDataBeforeAcquisition"	Name="Curve Data Before Acquisition"
+(0019,0062) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="NumberOfPointsTrigger"			Name="Number of Points Trigger"
+(0019,0063) VERS="GEM"  VR="OW"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CurveDataTrigger"				Name="Curve Data Trigger"
+(0019,0064) VERS="GEM"  VR="SH"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ECGSynchronization"			Name="ECG Synchronization"
+(0019,0065) VERS="GEM"  VR="SH"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ECGDelayMode"					Name="ECG Delay Mode"
+(0019,0066) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="ECGDelayVector"				Name="ECG Delay Vector"
+(0019,0067) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,0068) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,0069) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,007A) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,007B) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,007C) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,0080) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ImageDose"						Name="Image Dose"
+(0019,0081) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationFrame"				Name="Calibration Frame"
+(0019,0082) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationObject"				Name="Calibration Object"
+(0019,0083) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationObjectSize"			Name="Calibration Object Size mm"
+(0019,0084) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationFactor"				Name="Calibration Factor"
+(0019,0085) VERS="GEM"	VR="DA"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationDate"				Name="Calibration Date"
+(0019,0086) VERS="GEM"	VR="TM"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationTime"				Name="Calibration Time"
+(0019,0087) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationAccuracy"			Name="Calibration Accuracy"
+(0019,0088) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationExtended"			Name="Calibration Extended"
+(0019,0089) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationImageOriginal"		Name="Calibration Image Original"
+(0019,008A) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationFrameOriginal"		Name="Calibration Frame Original"
+(0019,008B) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationNbPointsUif"		Name="Calibration nb points uif"
+(0019,008C) VERS="GEM"	VR="US"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationPointsRow"			Name="Calibration Points Row"
+(0019,008D) VERS="GEM"	VR="US"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationPointsColumn"		Name="Calibration Points Column"
+(0019,008E) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationMagnificationRatio"	Name="Calibration Magnification Ratio"
+(0019,008F) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationSoftwareVersion"	Name="Calibration Software Version"
+(0019,0090) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ExtendedCalibrationSoftwareVersion"	Name="Extended Calibration Software Version"
+(0019,0091) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CalibrationReturnCode"			Name="Calibration Return Code"
+(0019,0092) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DetectorRotationAngle"			Name="Detector Rotation Angle"
+(0019,0093) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SpatialChange"					Name="Spatial Change"
+(0019,0094) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="InconsistentFlag"				Name="Inconsistent Flag"
+(0019,0095) VERS="GEM"	VR="CS"   VM="2"	Owner="GEMS_DL_IMG_01"		Keyword="HorizontalAndVerticalImageFlip"	Name="Horizontal and Vertical Image Flip"
+(0019,0096) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="InternalLabelImage"			Name="Internal Label Image"
+(0019,0097) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="Angle1Increment"				Name="Angle 1 increment"
+(0019,0098) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="Angle2Increment"				Name="Angle 2 increment"
+(0019,0099) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="Angle3Increment"				Name="Angle 3 increment"
+(0019,009a) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="SensorFeedback"				Name="Sensor Feedback"
+(0019,009B) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="Grid"							Name="Grid"
+(0019,009C) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="DefaultMaskPixelShift"			Name="Default Mask Pixel Shift"
+(0019,009D) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ApplicableReviewMode"			Name="Applicable Review Mode"
+(0019,009E) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="LogLUTControlPoints"			Name="Log LUT Control Points"
+(0019,009F) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="ExpLUTSUBControlPoints"		Name="Exp LUT SUB Control Points"
+(0019,00A0) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ABDValue"						Name="ABD Value" 
+(0019,00A1) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SubtractionWindowCenter"		Name="Subtraction Window Center" 
+(0019,00A2) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="SubtractionWindowWidth"		Name="Subtraction Window Width" 
+(0019,00A3) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ImageRotation"					Name="Image Rotation"
+(0019,00A4) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="AutoInjectionEnabled"			Name="Auto Injection Enabled"
+(0019,00A5) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="InjectionPhase"				Name="Injection Phase"
+(0019,00A6) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="InjectionDelay"				Name="Injection Delay" 
+(0019,00A7) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="ReferenceInjectionFrameNumber"	Name="Reference Injection Frame Number"
+(0019,00A8) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="InjectionDuration"				Name="Injection Duration"
+(0019,00A9) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="EPT"							Name="EPT"
+(0019,00AA) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CanDownscan512"				Name="Can Downscan 512"
+(0019,00AB) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="CurrentSpatialFilterStrength"	Name="Current Spatial Filter Strength"
+(0019,00AC) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="BrightnessSensitivity"			Name="Brightness Sensitivity"
+(0019,00AD) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="ExpLUTNOSUBControlPoints"		Name="Exp LUT NOSUB Control Points"
+(0019,00AF) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00b0) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00b1) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="AcquisitionModeDescription"	Name="Acquisition Mode Description"
+(0019,00b2) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="AcquisitionModeDescriptionLabel"	Name="Acquisition Mode Description Label"
+(0019,00b3) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00b8) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00ba) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="AcquisitionRegion"				Name="Acquisition Region"
+(0019,00bb) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="AcquisitionSUBMode"			Name="Acquisition SUB Mode"
+(0019,00bc) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="TableCradleAngle"				Name="Table Cradle Angle"
+(0019,00bd) VERS="GEM"	VR="CS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="TableRotationStatusVector"		Name="Table Rotation Status Vector"
+(0019,00be) VERS="GEM"	VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="SourceToImageDistancePerFrameVector"	Name="Source to Image Distance per Frame Vector"
+(0019,00c2) VERS="GEM"	VR="DS"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00c3) VERS="GEM"	VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="TableRotationAngleIncrement"	Name="Table Rotation Angle Increment"
+(0019,00c4) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00c7) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="PatientPositionPerImage"		Name="Patient Position per Image"
+(0019,00d7) VERS="GEM"  VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="TableXPositionToIsocenterIncrement"		Name="Table X Position to Iso‐center Increment"
+(0019,00d8) VERS="GEM"  VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="TableYPositionToIsocenterIncrement"		Name="Table Y Position to Iso‐center Increment"
+(0019,00d9) VERS="GEM"  VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="TableZPositionToIsocenterIncrement"		Name="Table Z Position to Iso‐center Increment"
+(0019,00da) VERS="GEM"  VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="TableHeadTiltAngleIncrement"	Name="Table Head Tilt Angle Increment"
+(0019,00dc) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00de) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="AcquisitionPlane"				Name="Acquisition Plane"
+(0019,00dd) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00e0) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+(0019,00e9) VERS="GEM"  VR="FL"   VM="1-n"	Owner="GEMS_DL_IMG_01"		Keyword="SourceToDetectorDistancePerFrameVector"	Name="Source to Detector Distance per Frame Vector"
+(0019,00ea) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="TableRotationAngle"			Name="Table Rotation Angle"
+(0019,00eb) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="TableXPositionToIsocenter"		Name="Table X Position to Iso‐center"
+(0019,00ec) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="TableYPositionToIsocenter"		Name="Table Y Position to Iso‐center"
+(0019,00ed) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="TableZPositionToIsocenter"		Name="Table Z Position to Iso‐center"
+(0019,00ee) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="TableHeadTiltAngle"			Name="Table Head Tilt Angle"
+(0019,00ef) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_DL_IMG_01"		Keyword="?"								Name="?"
+
+(0019,0001) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AngleValueLArm"			Name="Angle Value L Arm"
+(0019,0002) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AngleValuePArm"			Name="Angle Value P Arm"
+(0019,0003) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AngleValueCArm"			Name="Angle Value C Arm"
+(0019,0004) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AngleLabelLArm"			Name="Angle Label L Arm"
+(0019,0005) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AngleLabelPArm"			Name="Angle Label P Arm"
+(0019,0006) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AngleLabelCArm"			Name="Angle Label C Arm"
+(0019,0007) VERS="GEM"	VR="ST"   VM="1"	Owner="DLX_SERIE_01"	Keyword="ProcedureName"				Name="Procedure Name"
+(0019,0008) VERS="GEM"	VR="ST"   VM="1"	Owner="DLX_SERIE_01"	Keyword="ExamName"					Name="Exam Name"
+(0019,0009) VERS="GEM"	VR="SH"   VM="1"	Owner="DLX_SERIE_01"	Keyword="PatientSize"				Name="Patient Size"
+(0019,000A) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="RecordView"				Name="Record View"
+(0019,0010) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="InjectorDelay"				Name="Injector Delay"
+(0019,0011) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AutoInject"				Name="Auto Inject"
+(0019,0014) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="AcquisitionMode"			Name="Acquisition Mode"
+(0019,0015) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="CameraRotationEnabled"		Name="Camera Rotation Enabled"
+(0019,0016) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="ReverseSweep"				Name="Reverse Sweep"
+(0019,0017) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="UserSpatialFilterStrength"	Name="User Spatial Filter Strength"
+(0019,0018) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="UserZoomFactor"			Name="User Zoom Factor"
+(0019,0019) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="XZoomCenter"				Name="X Zoom Center"
+(0019,001A) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="YZoomCenter"				Name="Y Zoom Center"
+(0019,001B) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="Focus"						Name="Focus"
+(0019,001C) VERS="GEM"	VR="CS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="Dose"						Name="Dose"
+(0019,001D) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="SideMark"					Name="Side Mark"
+(0019,001E) VERS="GEM"	VR="IS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="PercentageLandscape"		Name="Percentage Landscape"
+(0019,001F) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="ExposureDuration"			Name="Exposure Duration"
+(0019,0020) VERS="GEM"	VR="LO"   VM="1"	Owner="DLX_SERIE_01"	Keyword="IpAddress"					Name="Ip Address"
+(0019,0021) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="TablePositionZ"			Name="Table position Z (vertical) first frame"
+(0019,0022) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="TablePositionX"			Name="Table position X (longitudinal) first frame"
+(0019,0023) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="TablePositionY"			Name="Table position Y (lateral) first frame"
+(0019,0024) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="Lambda"					Name="Lambda cm Pincushion Distortion"
+(0019,0025) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="RegressionSlope"			Name="LV Regression Slope Coefficient"
+(0019,0026) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="RegressionIntercept"		Name="LV Regression Intercept Coefficient"
+(0019,1027) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="ImageChainFWHMPsfMmMin"	Name="Image chain FWHM psf mm min"
+(0019,1028) VERS="GEM"	VR="DS"   VM="1"	Owner="DLX_SERIE_01"	Keyword="ImageChainFWHMPsfMmMax"	Name="Image chain FWHM psf mm max"
+
+(0019,004c) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_SERIES_01"	Keyword="InternalLabel"					Name="Internal Label"
+(0019,004d) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_SERIES_01"	Keyword="BrowserHide"					Name="Browser Hide"
+(0021,0003) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="SeriesFromWhichPrescribed"		Name="Series From Which Prescribed"
+(0021,0005) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="GenesisVersionNow"			Name="Genesis Version Now"
+(0021,0007) VERS="GEM"	VR="UL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="SeriesRecordChecksum"			Name="Series Record Checksum"
+(0021,0015) VERS="GEM"	VR="US"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="?"			Name="?"
+(0021,0016) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="?"			Name="?"
+(0021,0018) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="GenesisVersionNow"			Name="Genesis Version Now"
+(0021,0019) VERS="GEM"	VR="UL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="AcqReconRecordChecksum"		Name="Acq Recon Record Checksum"
+(0021,0020) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="TableStartLocation"			Name="Table Start Location"
+(0021,0035) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="SeriesFromWhichPrescribed"		Name="Series From Which Prescribed"
+(0021,0036) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="ImageFromWhichPrescribed"		Name="Image From Which Prescribed"
+(0021,0037) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="ScreenFormat"				Name="Screen Format"
+(0021,004a) VERS="GEM"	VR="LO"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="AnatomicalReferenceForScout"		Name="Anatomical Reference For Scout"
+(0021,004e) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_RELA_01"	Keyword="?" Name="?"
+(0021,004f) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="LocationsInAcquisition"		Name="Locations In Acquisition"
+(0021,0050) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="GraphicallyPrescribed"			Name="Graphically Prescribed"
+(0021,0051) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="RotationFromSourceXRot"		Name="Rotation From Source X Rot"
+(0021,0052) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="RotationFromSourceYRot"		Name="Rotation From Source Y Rot"
+(0021,0053) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="RotationFromSourceZRot"		Name="Rotation From Source Z Rot"
+(0021,0054) VERS="GEM"	VR="SH"	  VM="3"	Owner="GEMS_RELA_01"	Keyword="ImagePosition"				Name="Image Position"
+(0021,0055) VERS="GEM"	VR="SH"	  VM="6"	Owner="GEMS_RELA_01"	Keyword="ImageOrientation"			Name="Image Orientation"
+(0021,0056) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="Num3DSlabs"				Name="Num 3D slabs"
+(0021,0057) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="LocsPer3DSlab"				Name="Locs per 3D slab"
+(0021,0058) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="Overlaps"					Name="Overlaps"
+(0021,0059) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="ImageFiltering"			Name="Image Filtering 0.5/0.2T"
+(0021,005a) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="DiffusionDirection"		Name="Diffusion direction"
+(0021,005b) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="TaggingFlipAngle"			Name="Tagging Flip Angle"
+(0021,005c) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="TaggingFlipAngle"			Name="Tagging Orientation"
+(0021,005d) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="TagSpacing"				Name="Tag Spacing"
+(0021,005e) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="RTIATimer"					Name="RTIA_timer"
+(0021,005f) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="Fps"						Name="Fps"
+(0021,0070) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_RELA_01"	Keyword="?"			Name="?"
+(0021,0071) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_RELA_01"	Keyword="?"			Name="?"
+(0021,0081) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="AutoWindowLevelAlpha"			Name="Auto Window Level Alpha"
+(0021,0082) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="AutoWindowLevelBeta"			Name="Auto Window Level Beta"
+(0021,0083) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="AutoWindowLevelWindow"			Name="Auto Window Level Window"
+(0021,0084) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="AutoWindowLevelLevel"			Name="Auto Window Level Level"
+(0021,0090) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="TubeFocalSpotPosition"			Name="Tube Focal Spot Position"
+(0021,0091) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="BiopsyPosition"			Name="Biopsy Position"
+(0021,0092) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="BiopsyTLocation"			Name="Biopsy T Location"
+(0021,0093) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_RELA_01"	Keyword="BiopsyRefLocation"			Name="Biopsy Ref Location"
+
+(0021,0020) VERS="GEM"	VR="LT"	  VM="1"	Owner="GEMS_XR3DCAL_01"	Keyword="GeneralizedCalibration"	Name="Generalized Calibration"
+
+(0021,0001) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0010) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0011) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0012) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0013) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0014) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0015) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0016) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0017) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0018) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0019) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,001a) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,001b) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,001c) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,001d) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,001e) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,001f) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0020) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0040) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0041) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?" 
+(0021,0050) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0060) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+(0021,0065) VERS="MIBM"	VR="UN"	  VM="1"	Owner="Mayo/IBM Archive Project"	Keyword="?"	Name="?"
+
+(0023,0000) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRDRE"			Name="CR DRE"
+(0023,0000) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRDRE"			Name="CR DRE"
+(0023,0000) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRExposureMenuCode"	Name="CR Exposure Menu Code"
+(0023,0000) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRExposureMenuCode"	Name="CR Exposure Menu Code"
+(0023,0000) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRSShift"		Name="CR S Shift"
+(0023,0000) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRSShift"		Name="CR S Shift"
+(0023,0001) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_STDY_01"		Keyword="NumberOfSeriesInStudy"		Name="Number Of Series In Study"
+(0023,0002) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_STDY_01"		Keyword="NumberOfUnarchivedSeries"	Name="Number Of Unarchived Series"
+(0023,0010) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRCShift"		Name="CR C Shift"
+(0023,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRExposureMenuString"	Name="CR Exposure Menu String"
+(0023,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRExposureMenuString"	Name="CR Exposure Menu String"
+(0023,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRCShift"		Name="CR C Shift"
+(0023,0010) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_STDY_01"		Keyword="ReferenceImageField"	Name="Reference Image Field"
+(0023,0010) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRDRN"			Name="CR DRN"
+(0023,0010) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRDRN"			Name="CR DRN"
+(0023,0020) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRGT"			Name="CR GT"
+(0023,0020) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRORE"			Name="CR ORE"
+(0023,0020) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRORE"			Name="CR ORE"
+(0023,0020) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CREDRMode"		Name="CR EDR Mode"
+(0023,0020) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CREDRMode"		Name="CR EDR Mode"
+(0023,0020) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRGT"			Name="CR GT"
+(0023,0030) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRGA"			Name="CR GA"
+(0023,0030) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRGA"			Name="CR GA"
+(0023,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRLatitude"		Name="CR Latitude"
+(0023,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRLatitude"		Name="CR Latitude"
+(0023,0030) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRORN"			Name="CR ORN"
+(0023,0030) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRORN"			Name="CR ORN"
+(0023,0040) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRGC"			Name="CR GC"
+(0023,0040) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRGC"			Name="CR GC"
+(0023,0040) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRGroupNumber"		Name="CR Group Number"
+(0023,0040) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRGroupNumber"		Name="CR Group Number"
+(0023,0040) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRORD"			Name="CR ORD"
+(0023,0040) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRORD"			Name="CR ORD"
+(0023,0050) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRGS"			Name="CR GS"
+(0023,0050) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRGS"			Name="CR GS"
+(0023,0050) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRCassetteSize"	Name="CR Cassette Size"
+(0023,0050) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRCassetteSize"	Name="CR Cassette Size"
+(0023,0050) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_STDY_01"		Keyword="SummaryImage"		Name="Summary Image"
+(0023,0050) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRImageSerialNumber"	Name="CR Image Serial Number"
+(0023,0050) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRImageSerialNumber"	Name="CR Image Serial Number"
+(0023,0060) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRRT"			Name="CR RT"
+(0023,0060) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRBarCodeNumber"	Name="CR Bar Code Number"
+(0023,0060) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRMachineID"		Name="CR Machine ID"
+(0023,0060) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRBarCodeNumber"	Name="CR Bar Code Number"
+(0023,0060) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRRT"			Name="CR RT"
+(0023,0060) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRMachineID"		Name="CR Machine ID"
+(0023,0070) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRRE"			Name="CR RE"
+(0023,0070) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRRE"			Name="CR RE"
+(0023,0070) VERS="GEM"	VR="FD"	  VM="1"	Owner="GEMS_STDY_01"	Keyword="StartTimeSecsInFirstAxial"	Name="Start Time Secs In First Axial"
+(0023,0070) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRFilmOutputExposure"	Name="CR Film Output Exposure"
+(0023,0070) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRMachineType"		Name="CR Machine Type"
+(0023,0070) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRFilmOutputExposure"	Name="CR Film Output Exposure"
+(0023,0070) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRMachineType"		Name="CR Machine Type"
+(0023,0074) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_STDY_01"	Keyword="NumberOfUpdatesToHeader"		Name="Number Of Updates To Header"
+(0023,007d) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_STDY_01"	Keyword="IndicatesIfStudyHasCompleteInfo"	Name="Indicates If Study Has Complete Info"
+(0023,0080) VERS="GEM"	VR="SQ"	  VM="1"	Owner="GEMS_STDY_01"			Keyword="HasMPPSRelatedTags"	Name="Has MPPS Related Tags"
+(0023,0080) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRFilmFormat"		Name="CR Film Format"
+(0023,0080) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CRTechnicianCode"	Name="CR Technician Code"
+(0023,0080) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRFilmFormat"		Name="CR Film Format"
+(0023,0080) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRTechnicianCode"	Name="CR Technician Code"
+(0023,0080) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRRN"			Name="CR RN"
+(0023,0080) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRRN"			Name="CR RN"
+(0023,0090) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK2"	Keyword="CRDRT"			Name="CR DRT"
+(0023,0090) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK2"	Keyword="CRDRT"			Name="CR DRT"
+(0023,0090) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK1"	Keyword="CRSShiftString"	Name="CR S Shift String"
+(0023,0090) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_1.0 BLOCK3"	Keyword="CREnergySubtractionParameters"	Name="CR Energy Subtraction Parameters"
+(0023,0090) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK1"	Keyword="CRSShiftString"	Name="CR S Shift String"
+(0023,0090) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CREnergySubtractionParameters"	Name="CR Energy Subtraction Parameters"
+(0023,00f0) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRDistributionCode"	Name="CR Distribution Code"
+(0023,00ff) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_ACRQA_2.0 BLOCK3"	Keyword="CRShuttersApplied"	Name="CR Shutters Applied"
+
+(0023,0001) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="XRayMarkerSequence"			Name="X-Ray Marker Sequence"
+(0023,0002) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerID"						Name="Marker ID"
+(0023,0003) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerType"					Name="Marker Type"
+(0023,0004) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerSize"					Name="Marker Size"
+(0023,0005) VERS="GEM"	VR="US"   VM="3"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerColorCIELabValue"		Name="Marker Color CIELab Value"
+(0023,0006) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerLabel"					Name="Marker Label"
+(0023,0007) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerVisibleState"			Name="Marker Visible State"
+(0023,0008) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerDescription"				Name="Marker Description"
+(0023,0010) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointsSequence"			Name="Marker Points Sequence"
+(0023,0011) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointID"					Name="Marker Point ID"
+(0023,0012) VERS="GEM"	VR="FL"   VM="3"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointPosition"			Name="Marker Point Position"
+(0023,0013) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointSize"				Name="Marker Point Size"
+(0023,0014) VERS="GEM"	VR="US"   VM="3"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointColorCIELabValue"	Name="Marker Point Color CIELab Value"
+(0023,0016) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointVisibleState"		Name="Marker Point Visible State"
+(0023,0017) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="MarkerPointOrder"				Name="Marker Point Order"
+(0023,0018) VERS="GEM"	VR="FL"   VM="3"	Owner="GEMS_3D_INTVL_01"		Keyword="VolumeManualRegistration"		Name="Volume Manual Registration"
+(0023,0020) VERS="GEM"	VR="IS"   VM="1-n"	Owner="GEMS_3D_INTVL_01"		Keyword="VolumesThreshold"				Name="Volumes Threshold"
+(0023,0025) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="CutPlaneActivationFlag"		Name="Cut Plane Activation Flag"
+(0023,0026) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="CutPlanePositionValue"			Name="Cut Plane Position Value"
+(0023,0027) VERS="GEM"	VR="FL"   VM="3"	Owner="GEMS_3D_INTVL_01"		Keyword="CutPlaneNormalValue"			Name="Cut Plane Normal Value"
+(0023,0028) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="VolumeScalingFactor"			Name="Volume Scaling Factor"
+(0023,0029) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="ROIToTableTopDistance"			Name="ROI to Table Top Distance"
+(0023,0030) VERS="GEM"	VR="IS"   VM="1-n"	Owner="GEMS_3D_INTVL_01"		Keyword="DRRThreshold"					Name="DRR Threshold"
+(0023,0031) VERS="GEM"	VR="FL"   VM="3"	Owner="GEMS_3D_INTVL_01"		Keyword="VolumeTablePosition"			Name="Volume Table Position"
+(0023,0032) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="RenderingMode"					Name="Rendering Mode"
+(0023,0033) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="ThreeDObjectOpacity"			Name="3D Object Opacity"
+(0023,0034) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="InvertImage"					Name="Invert Image"
+(0023,0035) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="EnhanceFull"					Name="Enhance Full"
+(0023,0036) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="Zoom"							Name="Zoom"
+(0023,0037) VERS="GEM"	VR="IS"   VM="2"	Owner="GEMS_3D_INTVL_01"		Keyword="Roam"							Name="Roam"
+(0023,0038) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="WindowLevel"					Name="Window Level"
+(0023,0039) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="WindowWidth"					Name="Window Width"
+(0023,0040) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="BMCSetting"					Name="BMC Setting"
+(0023,0041) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="BackViewSetting"				Name="Back View Setting"
+(0023,0042) VERS="GEM"	VR="CS"   VM="1-n"	Owner="GEMS_3D_INTVL_01"		Keyword="SubVolumeVisibility"			Name="Sub Volume Visibility"
+(0023,0043) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="ThreeDLandmarksVisibility"		Name="3D Landmarks Visibility"
+(0023,0044) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3D_INTVL_01"		Keyword="AblationPointVisibility"		Name="Ablation Point Visibility"
+
+(0025,0006) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="LastPulseSequenceUsed"			Name="Last Pulse Sequence Used"
+(0025,0007) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="ImagesInSeries"			Name="Images In Series"
+(0025,0010) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="LandmarkCounter"			Name="Landmark Counter"
+(0025,0011) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="NumberOfAcquisitions"			Name="Number Of Acquisitions"
+(0025,0014) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="IndicatesNumberOfUpdatesToHeader"	Name="Indicates Number Of Updates To Header"
+(0025,0017) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="SeriesCompleteFlag"			Name="Series Complete Flag"
+(0025,0018) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="NumberOfImagesArchived"		Name="Number Of Images Archived"
+(0025,0019) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="LastInstanceNumberUsed"		Name="Last Instance Number Used"
+(0025,001a) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="PrimaryReceiverSuiteAndHost"		Name="Primary Receiver Suite And Host"
+(0025,001b) VERS="GEM"	VR="OB"	  VM="1"	Owner="GEMS_SERS_01"	Keyword="ProtocolDataBlockCompressed"		Name="Protocol Data Block (compressed)"
+(0025,0002) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="FrameID"						Name="Frame ID"
+(0025,0003) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="DistanceSourceToDetector"		Name="Distance Source to Detector"
+(0025,0004) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="DistanceSourceToPatient"		Name="Distance Source to Patient"
+(0025,0005) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="DistanceSourceToSkin"			Name="Distance Source to Skin"
+(0025,0006) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="PositionerPrimaryAngle"		Name="Positioner Primary Angle"
+(0025,0007) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="PositionerSecondaryAngle"		Name="Positioner Secondary Angle"
+(0025,0008) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="BeamOrientation"				Name="Beam Orientation"
+(0025,0009) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="LArmAngle"						Name="L Arm Angle"
+(0025,000A) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="FrameSequence"					Name="Frame Sequence"
+(0025,0010) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="PivotAngle"					Name="Pivot Angle"
+(0025,001A) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="ArcAngle"						Name="Arc Angle"
+(0025,001B) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="TableVerticalPosition"			Name="Table Vertical Position"
+(0025,001C) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="TableLongitudinalPosition"		Name="Table Longitudinal Position"
+(0025,001D) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="Table Lateral Position"		Name="Table Lateral Position"
+(0025,001E) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="BeamCoverArea"					Name="Beam Cover Area"
+(0025,001F) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="kVPActual"						Name="kVP Actual"
+(0025,0020) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="mASActual"						Name="mAS Actual"
+(0025,0021) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="PWActual"						Name="PW Actual"
+(0025,0022) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="KvpCommanded"					Name="Kvp Commanded"
+(0025,0023) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="MasCommanded"					Name="Mas Commanded"
+(0025,0024) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="PwCommanded"					Name="Pw Commanded"
+(0025,0025) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="Grid"							Name="Grid"
+(0025,0026) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="SensorFeedback"				Name="Sensor Feedback"
+(0025,0027) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="TargetEntranceDose"			Name="Target Entrance Dose"
+(0025,0028) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="CnrCommanded"					Name="Cnr Commanded"
+(0025,0029) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="ContrastCommanded"				Name="Contrast Commanded"
+(0025,002A) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="EPTActual"						Name="EPT Actual"
+(0025,002B) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="SpectralFilterZnb"				Name="Spectral Filter Znb"
+(0025,002C) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="SpectralFilterWeight"			Name="Spectral Filter Weight"
+(0025,002D) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="SpectralFilterDensity"			Name="Spectral Filter Density"
+(0025,002E) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="SpectralFilterThickness"		Name="Spectral Filter Thickness"
+(0025,002F) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="SpectralFilterStatus"			Name="Spectral Filter Status"
+(0025,0030) VERS="GEM"	VR="IS"   VM="2"	Owner="GEMS_DL_FRAME_01"	Keyword="FOVDimension"					Name="FOV Dimension"
+(0025,0033) VERS="GEM"	VR="IS"   VM="2"	Owner="GEMS_DL_FRAME_01"	Keyword="FOVOrigin"						Name="FOV Origin"
+(0025,0034) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="CollimatorLeftVerticalEdge"	Name="Collimator Left Vertical Edge"
+(0025,0035) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="CollimatorRightVerticalEdge"	Name="Collimator Right Vertical Edge"
+(0025,0036) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="CollimatorUpHorizontalEdge"	Name="Collimator Up Horizontal Edge"
+(0025,0037) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="CollimatorLowHorizontalEdge"	Name="Collimator Low Horizontal Edge"
+(0025,0038) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="VerticesPolygonalCollimator"	Name="Vertices Polygonal Collimator"
+(0025,0039) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="ContourFilterDistance"			Name="Contour Filter Distance"
+(0025,003A) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="ContourFilterAngle"			Name="Contour Filter Angle"
+(0025,003B) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="TableRotationStatus"			Name="Table Rotation Status"
+(0025,003C) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DL_FRAME_01"	Keyword="InternalLabelFrame"			Name="Internal Label Frame"
+
+(0027,0006) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ImageArchiveFlag"			Name="Image Archive Flag"
+(0027,0010) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ScoutType"				Name="Scout Type"
+(0027,001c) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="VmaMamp"				Name="Vma Mamp"
+(0027,001d) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="VmaPhase"				Name="Vma Phase"
+(0027,001e) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="VmaMod"				Name="Vma Mod"
+(0027,001f) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="VmaClipOrNoiseIndexBy10"		Name="Vma Clip or Noise Index by 10"
+(0027,0020) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="SmartScanOnOffFlag"			Name="Smart Scan On Off Flag"
+(0027,0030) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ForeignImageRevision"			Name="Foreign Image Revision"
+(0027,0031) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ImagingMode"				Name="Imaging Mode"
+(0027,0032) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="PulseSequence"				Name="Pulse Sequence"
+(0027,0033) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ImagingOptions"			Name="Imaging Options"
+(0027,0035) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="PlaneType"				Name="Plane Type"
+(0027,0036) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ObliquePlane"				Name="Oblique Plane"
+(0027,0040) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RASLetterOfImageLocation"		Name="RAS Letter Of Image Location"
+(0027,0041) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ImageLocation"				Name="Image Location"
+(0027,0042) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="CenterRCoordOfPlaneImage"		Name="Center R Coord Of Plane Image"
+(0027,0043) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="CenterACoordOfPlaneImage"		Name="Center A Coord Of Plane Image"
+(0027,0044) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="CenterSCoordOfPlaneImage"		Name="Center S Coord Of Plane Image"
+(0027,0045) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="NormalRCoord"				Name="Normal R Coord"
+(0027,0046) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="NormalACoord"				Name="Normal A Coord"
+(0027,0047) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="NormalSCoord"				Name="Normal S Coord"
+(0027,0048) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RCoordOfTopRightCorner"		Name="R Coord Of Top Right Corner"
+(0027,0049) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ACoordOfTopRightCorner"		Name="A Coord Of Top Right Corner"
+(0027,004a) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="SCoordOfTopRightCorner"		Name="S Coord Of Top Right Corner"
+(0027,004b) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RCoordOfBottomRightCorner"		Name="R Coord Of Bottom Right Corner"
+(0027,004c) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ACoordOfBottomRightCorner"		Name="A Coord Of Bottom Right Corner"
+(0027,004d) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="SCoordOfBottomRightCorner"		Name="S Coord Of Bottom Right Corner"
+(0027,0050) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="TableStartLocation"			Name="Table Start Location (Scout)"
+(0027,0051) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="TableEndLocation"			Name="Table End Location (Scout)"
+(0027,0052) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RASLetterForSideOfImage"		Name="RAS Letter For Side Of Image"
+(0027,0053) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RASLetterForAnteriorPosterior"		Name="RAS Letter For Anterior Posterior"
+(0027,0054) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RASLetterForScoutStartLoc"		Name="RAS Letter For Scout Start Loc"
+(0027,0055) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="RASLetterForScoutEndLoc"		Name="RAS Letter For Scout End Loc"
+(0027,0060) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ImageDimensionX"			Name="Image Dimension X"
+(0027,0061) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="ImageDimensionY"			Name="Image Dimension Y"
+(0027,0062) VERS="GEM"	VR="FL"	  VM="1"	Owner="GEMS_IMAG_01"	Keyword="NumberOfExcitations"			Name="Number Of Excitations"
+(0029,0004) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,0005) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,0006) VERS="GEM"	VR="DS"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,0007) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,0008) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,0009) VERS="GEM"	VR="SH"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,000a) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels"			Name="Lower Range Of Pixels"
+(0029,0015) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels1"			Name="Lower Range Of Pixels1"
+(0029,0016) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="UpperRangeOfPixels1"			Name="Upper Range Of Pixels1"
+(0029,0017) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LowerRangeOfPixels2"			Name="Lower Range Of Pixels2"
+(0029,0018) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="UpperRangeOfPixels2"			Name="Upper Range Of Pixels2"
+(0029,001a) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="LengthOfTotalHeaderInBytes"	Name="Length Of Total Header In Bytes"
+(0029,0026) VERS="GEM"	VR="SS"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="VersionOfHeaderStructure"		Name="Version Of Header Structure"
+(0029,0034) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="AdvantageCompOverflow"			Name="Advantage Comp Overflow"
+(0029,0035) VERS="GEM"	VR="SL"	  VM="1"	Owner="GEMS_IMPS_01"	Keyword="AdvantageCompUnderflow"		Name="Advantage Comp Underflow"
+
+(0033,0001) VERS="GEM"  VR="UN"   VM="1"    Owner="GEMS_GNHD_01"	Keyword="?"					Name="?"
+(0033,0002) VERS="GEM"  VR="UN"   VM="1"    Owner="GEMS_CTHD_01"	Keyword="?" 					Name="?"
+(0033,0002) VERS="GEM"  VR="UN"   VM="1"    Owner="GEMS_GNHD_01"	Keyword="?" 					Name="?"
+(0033,0005) VERS="GEM"	VR="UN"   VM="1"	Owner="GEMS_YMHD_01"	Keyword="?"					Name="?"
+(0033,0006) VERS="GEM"	VR="UN"   VM="1"	Owner="GEMS_YMHD_01"	Keyword="?"					Name="?"
+
+(0033,0007) VERS="GEM"	VR="LO"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="OriginalSOPInstanceUID"		Name="Original SOP Instance UID"
+(0033,0008) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="eNTEGRADataObjectType"			Name="eNTEGRA Data Object Type"
+(0033,0010) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="Modified"				Name="Modified"
+(0033,0011) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="Name"					Name="Name"
+(0033,0016) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="ProtocolDataUID"			Name="Protocol Data UID"
+(0033,0017) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="Date"					Name="Date"
+(0033,0018) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="Time"					Name="Time"
+(0033,0019) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="ProtocolDataFlags"			Name="Protocol Data Flags"
+(0033,001a) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="ProtocolName"				Name="Protocol Name"
+(0033,001b) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="RelevantDataUID"			Name="Relevant Data UID"
+(0033,001c) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="BulkData"				Name="Bulk Data"
+(0033,001d) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="IntData"				Name="Int Data"
+(0033,001e) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="DoubleData"				Name="Double Data"
+(0033,001f) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="StringData"				Name="String Data"
+(0033,0020) VERS="GEM"	VR="LT"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="BulkDataFormat"			Name="Bulk Data Format"
+(0033,0021) VERS="GEM"	VR="LT"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="IntDataFormat"				Name="Int Data Format"
+(0033,0022) VERS="GEM"	VR="LT"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="DoubleDataFormat"			Name="Double Data Format"
+(0033,0023) VERS="GEM"	VR="LT"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="StringDataFormat"			Name="String Data Format"
+(0033,0024) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="Description"				Name="Description"
+(0033,0030) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="AllocateTriggerBuffer"		Name="Allocate Trigger Buffer"
+(0033,0033) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="NumberOfTriggers"			Name="Number of Triggers"
+(0033,0034) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="TriggerSize"				Name="Trigger Size"
+(0033,0035) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="TriggerDataSize"			Name="Trigger Data Size"
+(0033,0036) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_GENIE_1"	Keyword="TriggerData"				Name="Trigger Data"
+
+(0035,0001) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"	Keyword="StartAngle"				Name="Start Angle"
+(0037,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_DRS_1"	Keyword="ReferringDepartment"		Name="ReferringDepartment"
+(0037,0020) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DRS_1"	Keyword="ScreenNumber"			Name="ScreenNumber"
+(0037,0040) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_DRS_1"	Keyword="LeftOrientation"		Name="LeftOrientation"
+(0037,0042) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_DRS_1"	Keyword="RightOrientation"		Name="RightOrientation"
+(0037,0050) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_DRS_1"	Keyword="Inversion"			Name="Inversion"
+(0037,0060) VERS="GEM"	VR="US"   VM="1"	Owner="GEMS_DRS_1"	Keyword="DSA"				Name="DSA"
+(0039,0080) VERS="GEM"  VR="IS"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityNumber"			Name="Private Entity Number"
+(0039,0085) VERS="GEM"  VR="DA"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityDate"			Name="Private Entity Date"
+(0039,0090) VERS="GEM"  VR="TM"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityTime"			Name="Private Entity Time"
+(0039,0095) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityLaunchCommand"		Name="Private Entity Launch Command"
+(0039,00AA) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityType"			Name="Private Entity Type"
+(0039,0095) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_ADWSoft_DPO1"		Keyword="?"			Name="?"
+(0039,0050) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_AWSoft_SB1"		Keyword="ReferenceToStudyUID"			Name="Reference to Study UID"
+(0039,0051) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_AWSoft_SB1"		Keyword="ReferenceToSeriesUID"			Name="Reference to Series UID"
+(0039,0052) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_AWSoft_SB1"		Keyword="ReferenceToOriginalInstance"		Name="Reference to Original Instance Number"
+(0039,0095) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_AWSoft_SB1"		Keyword="PrivateEntityLaunchCommand"		Name="Private Entity Launch Command"
+(0039,0065) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="ReferenceToStudyUID"			Name="Reference to Study UID"
+(0039,0070) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="ReferenceToSeriesUID"			Name="Reference to Series UID"
+(0039,0075) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="ReferenceToOriginalInstance"		Name="Reference to Original Instance Number"
+(0039,0080) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="DPONumber"				Name="DPO Number"
+(0039,0085) VERS="GEM"	VR="DA"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="DPODate"				Name="DPO Date"
+(0039,0090) VERS="GEM"	VR="TM"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="DPOTime"				Name="DPO Time"
+(0039,0095) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="DPOInvocationString"			Name="DPO Invocation String"
+(0039,00AA) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="DPOType"				Name="DPO Type"
+(0039,00FF) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_AWSOFT_CD1"		Keyword="DPOData"				Name="DPO Data"
+(0043,0001) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="BitmapOfPrescanOptions"		Name="Bitmap Of Prescan Options"
+(0043,0002) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="GradientOffsetInX"			Name="Gradient Offset In X"
+(0043,0003) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="GradientOffsetInY"			Name="Gradient Offset In Y"
+(0043,0004) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="GradientOffsetInZ"			Name="Gradient Offset In Z"
+(0043,0005) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ImageIsOriginalOrUnoriginal"		Name="Image Is Original Or Unoriginal"
+(0043,0006) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="NumberOfEPIShots"			Name="Number Of EPI Shots"
+(0043,0007) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ViewsPerSegment"			Name="Views Per Segment"
+(0043,0008) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="RespiratoryRateInBPM"			Name="Respiratory Rate In BPM"
+(0043,0009) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="RespiratoryTriggerPoint"		Name="Respiratory Trigger Point"
+(0043,000a) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="TypeOfReceiverUsed"			Name="Type Of Receiver Used"
+(0043,000b) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PeakRateOfChangeOfGradientField"	Name="dB/dt Peak Rate Of Change Of Gradient Field"
+(0043,000c) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="LimitsInUnitsOfPercent"		Name="dB/dt Limits In Units Of Percent"
+(0043,000d) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PSDEstimatedLimit"			Name="PSD Estimated Limit"
+(0043,000e) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PSDEstimatedLimitInTeslaPerSecond"	Name="PSD Estimated Limit In Tesla Per Second"
+(0043,000f) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="SARAvgHead"				Name="SAR Avg Head"
+(0043,0010) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="WindowValue"				Name="Window Value"
+(0043,0011) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="TotalInputViews"			Name="Total Input Views"
+(0043,0012) VERS="GEM"	VR="SS"	VM="3"	Owner="GEMS_PARM_01"	Keyword="XrayChain"				Name="Xray Chain"
+(0043,0013) VERS="GEM"	VR="SS"	VM="5"	Owner="GEMS_PARM_01"	Keyword="ReconKernelParameters"			Name="Recon Kernel Parameters"
+(0043,0014) VERS="GEM"	VR="SS"	VM="3"	Owner="GEMS_PARM_01"	Keyword="CalibrationParameters"			Name="Calibration Parameters"
+(0043,0015) VERS="GEM"	VR="SS"	VM="3"	Owner="GEMS_PARM_01"	Keyword="TotalOutputViews"			Name="Total Output Views"
+(0043,0016) VERS="GEM"	VR="SS"	VM="5"	Owner="GEMS_PARM_01"	Keyword="NumberOfOverranges"			Name="Number Of Overranges"
+(0043,0017) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="IBHImageScaleFactors"			Name="IBH Image Scale Factors"
+(0043,0018) VERS="GEM"	VR="DS"	VM="3"	Owner="GEMS_PARM_01"	Keyword="BBH Coefficients"			Name="BBH Coefficients"
+(0043,0019) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="NumberOfBBHChainsToBlend"		Name="Number Of BBH Chains To Blend"
+(0043,001a) VERS="GEM"	VR="SL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="StartingChannelNumber"			Name="Starting Channel Number"
+(0043,001b) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PPScanParameters"			Name="PPScan Parameters"
+(0043,001c) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="GEImageIntegrity"			Name="GE Image Integrity"
+(0043,001d) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="LevelValue"				Name="Level Value"
+(0043,001e) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="DeltaStartTime"			Name="Delta Start Time"
+(0043,001e) VERS="GEM"  VR="DS" VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="DeltaStartTime"		Name="Delta Start Time"
+(0043,001f) VERS="GEM"	VR="SL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="MaxOverrangesInAView"			Name="Max Overranges In A View"
+(0043,0020) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="AvgOverrangesAllViews"			Name="Avg Overranges All Views"
+(0043,0021) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="CorrectedAfterglowTerms"		Name="Corrected Afterglow Terms"
+(0043,0025) VERS="GEM"	VR="SS"	VM="6"	Owner="GEMS_PARM_01"	Keyword="ReferenceChannels"			Name="Reference Channels"
+(0043,0026) VERS="GEM"	VR="US"	VM="6"	Owner="GEMS_PARM_01"	Keyword="NoViewsRefChannelsBlocked"		Name="No Views Ref Channels Blocked"
+(0043,0027) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ScanPitchRatio"			Name="Scan Pitch Ratio"
+(0043,0027) VERS="GEM"  VR="SH" VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="ScanPitchRatio"		Name="Scan Pitch Ratio"
+(0043,0028) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_PARM_01"	Keyword="UniqueImageIdentifier"			Name="Unique Image Identifier"
+(0043,0029) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_PARM_01"	Keyword="HistogramTables"			Name="Histogram Tables"
+(0043,002a) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_PARM_01"	Keyword="UserDefinedData"			Name="User Defined Data"
+(0043,002b) VERS="GEM"	VR="SS"	VM="4"	Owner="GEMS_PARM_01"	Keyword="PrivateScanOptions"			Name="Private Scan Options"
+(0043,002c) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="EffectiveEchoSpacing"			Name="Effective Echo Spacing"
+(0043,002d) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="FilterMode"				Name="Filter Mode"
+(0043,002e) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="StringSlopField2"			Name="String Slop Field 2"
+(0043,002f) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ImageType"				Name="Image Type (Real,Imaginary,Phase,Magnitude)"
+(0043,0030) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="VasCollapseFlag"			Name="Vas Collapse Flag"
+(0043,0031) VERS="GEM"	VR="DS"	VM="2"	Owner="GEMS_PARM_01"	Keyword="ReconCenterCoordinates"		Name="Recon Center Coordinates"
+(0043,0032) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="VasFlags"				Name="Vas Flags"
+(0043,0033) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="NegScanSpacing"			Name="Neg Scan Spacing"
+(0043,0034) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="OffsetFrequency"			Name="Offset Frequency"
+(0043,0035) VERS="GEM"	VR="UL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="UserUsageTag"				Name="User Usage Tag"
+(0043,0036) VERS="GEM"	VR="UL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="UserFillMapMSW"			Name="User Fill Map MSW"
+(0043,0037) VERS="GEM"	VR="UL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="UserFillMapLSW"			Name="User Fill Map LSW"
+(0043,0038) VERS="GEM"	VR="FL"	VM="24"	Owner="GEMS_PARM_01"	Keyword="User25ToUser48"			Name="User 25 To User 48"
+(0043,0039) VERS="GEM"	VR="IS"	VM="4"	Owner="GEMS_PARM_01"	Keyword="SlopInteger6ToSlopInteger9"		Name="Slop Integer 6 To Slop Integer 9"
+(0043,0040) VERS="GEM"	VR="FL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="TriggerOnPosition"			Name="Trigger On Position"
+(0043,0041) VERS="GEM"	VR="FL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DegreeOfRotation"			Name="Degree Of Rotation"
+(0043,0042) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASTriggerSource"			Name="DAS Trigger Source"
+(0043,0043) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASFpaGain"				Name="DAS Fpa Gain"
+(0043,0044) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASOutputSource"			Name="DAS Output Source"
+(0043,0045) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASAdInput"				Name="DAS Ad Input"
+(0043,0046) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASCalMode"				Name="DAS Cal Mode"
+(0043,0047) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASCalFrequency"			Name="DAS Cal Frequency"
+(0043,0048) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASRegXm"				Name="DAS Reg Xm"
+(0043,0049) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASAutoZero"				Name="DAS Auto Zero"
+(0043,004a) VERS="GEM"	VR="SS"	VM="4"	Owner="GEMS_PARM_01"	Keyword="StartingChannelOfView"			Name="Starting Channel Of View"
+(0043,004b) VERS="GEM"	VR="SL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DASXmPattern"				Name="DAS Xm Pattern"
+(0043,004c) VERS="GEM"	VR="SS"	VM="4"	Owner="GEMS_PARM_01"	Keyword="TGGCTriggerMode"			Name="TGGC Trigger Mode"
+(0043,004d) VERS="GEM"	VR="FL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="StartScanToXrayOnDelay"		Name="Start Scan To Xray On Delay"
+(0043,004e) VERS="GEM"	VR="FL"	VM="4"	Owner="GEMS_PARM_01"	Keyword="DurationOfXrayOn"			Name="Duration Of Xray On"
+(0043,0060) VERS="GEM"	VR="IS"	VM="8"	Owner="GEMS_PARM_01"	Keyword="SlopInteger10ToSlopInteger17"		Name="Slop Integer 10 To Slop Integer 17"
+(0043,0061) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ScannerStudyEntityUID"			Name="Scanner Study Entity UID"
+(0043,0062) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ScannerStudyID"			Name="Scanner Study ID"
+(0043,0063) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="RawDataID"				Name="Raw Data ID"
+(0043,0064) VERS="GEM"	VR="CS"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="ImageFilter"			Name="Image Filter"
+(0043,0065) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="MotionCorrectionIndicator"		Name="Motion Correction Indicator"
+(0043,0066) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="HelicalCorrectionIndicator"		Name="Helical Correction Indicator"
+(0043,0067) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="IBOCorrectionIndicator"		Name="IBO Correction Indicator"
+(0043,0068) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="IXTCorrectionIndicator"		Name="XT Correction Indicator"
+(0043,0069) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="QcalCorrectionIndicator"		Name="Q-cal Correction Indicator"
+(0043,006a) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="AVCorrectionIndicator"			Name="AV Correction Indicator"
+(0043,006b) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="LMDKCorrectionIndicator"		Name="L-MDK Correction Indicator"
+(0043,006c) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="DetectorRow"				Name="Detector Row"
+(0043,006d) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="AreaSize"				Name="Area Size"
+(0043,006e) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="AutoMAMode"				Name="Auto mA Mode"
+(0043,006f) VERS="GEM"	VR="DS"	VM="3-4"	Owner="GEMS_PARM_01"	Keyword="ScannerTableEntry"		Name="Scanner Table Entry + Gradient Coil Selected"
+(0043,0070) VERS="GEM"	VR="LO"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ParadigmName"				Name="Paradigm Name"
+(0043,0071) VERS="GEM"	VR="ST"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ParadigmDescription"				Name="Paradigm Description"
+(0043,0072) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ParadigmUID"						Name="Paradigm UID"
+(0043,0073) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ExperimentType"					Name="Experiment Type"
+(0043,0074) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="NumberOfRestVolumes"				Name="Number of Rest Volumes"
+(0043,0075) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="NumberOfActiveVolumes"				Name="Number of Active Volumes"
+(0043,0076) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="NumberOfDummyScans"				Name="Number of Dummy Scans"
+(0043,0077) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ApplicationName"					Name="Application Name"
+(0043,0078) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ApplicationVersion"				Name="Application Version"
+(0043,0079) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="SlicesPerVolume"					Name="Slices Per Volume"
+(0043,007a) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ExpectedTimePoints"				Name="Expected Time Points"
+(0043,007b) VERS="GEM"	VR="FL"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="RegressorValues"				Name="Regressor Values"
+(0043,007c) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_PARM_01"	Keyword="DelayAfterSliceGroup"				Name="Delay After Slice Group"
+(0043,007d) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ReconModeFlagWord"					Name="Recon Mode Flag Word"
+(0043,007e) VERS="GEM"	VR="LO"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="PACCSpecificInformation"		Name="PACC Specific Information"
+(0043,007f) VERS="GEM"	VR="DS"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="Reserved"						Name="Reserved"
+(0043,0080) VERS="GEM"	VR="LO"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="CoilIDData"					Name="Coil ID Data"
+(0043,0081) VERS="GEM"	VR="LO"	VM="1"	Owner="GEMS_PARM_01"	Keyword="GECoilName"						Name="GE Coil Name"
+(0043,0082) VERS="GEM"	VR="LO"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="SystemConfigurationInformation"	Name="System Configuration Information"
+(0043,0083) VERS="GEM"	VR="DS"	VM="1-2"	Owner="GEMS_PARM_01"	Keyword="AssetRFactors"					Name="Asset R Factors"
+(0043,0084) VERS="GEM"	VR="LO"	VM="5"	Owner="GEMS_PARM_01"	Keyword="AdditionalAssetData"				Name="Additional Asset Data"
+(0043,0085) VERS="GEM"	VR="UT"	VM="1"	Owner="GEMS_PARM_01"	Keyword="DebugDataTextFormat"				Name="Debug Data (Text Format)"
+(0043,0086) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_PARM_01"	Keyword="DebugDataBinaryFormat"				Name="Debug Data (Binary Format)"
+(0043,0087) VERS="GEM"	VR="UT"	VM="1"	Owner="GEMS_PARM_01"	Keyword="Reserved"							Name="Reserved"
+(0043,0088) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PUREAcquisitionCalibrationSeriesUID"		Name="PURE Acquisition Calibration Series UID"
+(0043,0089) VERS="GEM"	VR="LO"	VM="3"	Owner="GEMS_PARM_01"	Keyword="GoverningBodyDBdtSARDefinition"			Name="Governing Body, dB/dt, and SAR definition"
+(0043,008a) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PrivateInPlanePhaseEncodingDirection"		Name="Private In-Plane Phase Encoding Direction"
+(0043,008b) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_PARM_01"	Keyword="FMRIBinaryDataBlock"				Name="FMRI Binary Data Block"
+(0043,008c) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="VoxelLocation"						Name="Voxel Location"
+(0043,008d) VERS="GEM"	VR="DS"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="SATBandLocations"				Name="SAT Band Locations"
+(0043,008e) VERS="GEM"	VR="DS"	VM="3"	Owner="GEMS_PARM_01"	Keyword="SpectroPrescanValues"				Name="Spectro Prescan Values"
+(0043,008f) VERS="GEM"	VR="DS"	VM="3"	Owner="GEMS_PARM_01"	Keyword="SpectroParameters"					Name="Spectro Parameters"
+(0043,0090) VERS="GEM"	VR="LO"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="SARDefinition"					Name="SAR Definition"
+(0043,0091) VERS="GEM"	VR="DS"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="SARValue"						Name="SAR Value"
+(0043,0092) VERS="GEM"	VR="LO"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ImageErrorText"					Name="Image Error Text"
+(0043,0093) VERS="GEM"	VR="DS"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="SpectroQuantitationValues"		Name="Spectro Quantitation Values"
+(0043,0094) VERS="GEM"	VR="DS"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="SpectroRatioValues"			Name="Spectro Ratio Values"
+(0043,0095) VERS="GEM"	VR="LO"	VM="1"	Owner="GEMS_PARM_01"	Keyword="PrescanReuseString"				Name="Prescan Reuse String"
+(0043,0096) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ContentQualification"				Name="Content Qualification"
+(0043,0097) VERS="GEM"	VR="LO"	VM="8"	Owner="GEMS_PARM_01"	Keyword="ImageFilteringParameters"			Name="Image Filtering Parameters"
+(0043,0098) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_PARM_01"	Keyword="ASSETAcquisitionCalibrationSeriesUID"		Name="ASSET Acquisition Calibration Series UID"
+(0043,0099) VERS="GEM"	VR="LO"	VM="1-n"	Owner="GEMS_PARM_01"	Keyword="ExtendedOptions"				Name="Extended Options"
+(0043,009a) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_PARM_01"	Keyword="RxStackIdentification"				Name="Rx Stack Identification"
+(0045,0004) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="AES"					Name="AES"
+(0045,0006) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="Angulation"				Name="Angulation"
+(0045,0009) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="RealMagnificationFactor"		Name="Real Magnification Factor"
+(0045,000b) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="SenographType"				Name="Senograph Type"
+(0045,000c) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="IntegrationTime"			Name="Integration Time"
+(0045,000d) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="ROIOriginXY"				Name="ROI Origin X and Y"
+(0045,0011) VERS="GEM"	VR="DS"	VM="2"	Owner="GEMS_SENO_02"	Keyword="ReceptorSizeCmXY"			Name="Receptor Size cm X and Y"
+(0045,0012) VERS="GEM"	VR="IS"	VM="2"	Owner="GEMS_SENO_02"	Keyword="ReceptorSizePixelsXY"			Name="Receptor Size Pixels X and Y"
+(0045,0013) VERS="GEM"	VR="ST"	VM="1"	Owner="GEMS_SENO_02"	Keyword="Screen"				Name="Screen"
+(0045,0014) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="PixelPitchMicrons"			Name="Pixel Pitch Microns"
+(0045,0015) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="PixelDepthBits"			Name="Pixel Depth Bits"
+(0045,0016) VERS="GEM"	VR="IS"	VM="2"	Owner="GEMS_SENO_02"	Keyword="BinningFactorXY"			Name="Binning Factor X and Y"
+(0045,001B) VERS="GEM"	VR="LO"	VM="1"	Owner="GEMS_SENO_02"	Keyword="ClinicalView"				Name="Clinical View"
+(0045,001D) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="MeanOfRawGrayLevels"			Name="Mean Of Raw Gray Levels"
+(0045,001E) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="MeanOfOffsetGrayLevels"		Name="Mean Of Offset Gray Levels"
+(0045,001F) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="MeanOfCorrectedGrayLevels"		Name="Mean Of Corrected Gray Levels"
+(0045,0020) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="MeanOfRegionGrayLevels"		Name="Mean Of Region Gray Levels"
+(0045,0021) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="MeanOfLogRegionGrayLevels"		Name="Mean Of Log Region Gray Levels"
+(0045,0022) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="StandardDeviationOfRawGrayLevels"		Name="Standard Deviation Of Raw Gray Levels"
+(0045,0023) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="StandardDeviationOfCorrectedGrayLevels"	Name="Standard Deviation Of Corrected Gray Levels"
+(0045,0024) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="StandardDeviationOfRegionGrayLevels"		Name="Standard Deviation Of Region Gray Levels"
+(0045,0025) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="StandardDeviationOfLogRegionGrayLevels"	Name="Standard Deviation Of Log Region Gray Levels"
+(0045,0026) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_SENO_02"	Keyword="MAOBuffer"				Name="MAO Buffer"
+(0045,0027) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="SetNumber"				Name="Set Number"
+(0045,0028) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="WindowingType"				Name="WindowingType (LINEAR or GAMMA)"
+(0045,0029) VERS="GEM"	VR="DS"	VM="1-n"	Owner="GEMS_SENO_02"	Keyword="WindowingParameters"		Name="WindowingParameters"
+(0045,002a) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="CrosshairCursorXCoordinates"		Name="Crosshair Cursor X Coordinates"
+(0045,002b) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="CrosshairCursorYCoordinates"		Name="Crosshair Cursor Y Coordinates"
+(0045,0039) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignetteRows"				Name="Vignette Rows"
+(0045,003a) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignetteColumns"			Name="Vignette Columns"
+(0045,003b) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignetteBitsAllocated"			Name="Vignette Bits Allocated"
+(0045,003c) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignetteBitsStored"			Name="Vignette Bits Stored"
+(0045,003d) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignetteHighBit"			Name="Vignette High Bit"
+(0045,003e) VERS="GEM"	VR="US"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignettePixelRepresentation"		Name="Vignette Pixel Representation"
+(0045,003f) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_SENO_02"	Keyword="VignettePixelData"			Name="Vignette Pixel Data"
+(0045,0049) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="RadiologicalThickness"			Name="Radiological Thickness"
+(0045,0050) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_SENO_02"	Keyword="FallbackInstanceUID"			Name="Fallback Instance UID (CR or SC)"
+(0045,0051) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_SENO_02"	Keyword="FallbackSeriesUID"			Name="Fallback Series UID (CR or SC)"
+(0045,0052) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="RawDiagnosticLow"			Name="Raw Diagnostic Low"
+(0045,0053) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="RawDiagnosticHigh"			Name="Raw Diagnostic High"
+(0045,0054) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="Exponent"				Name="Exponent"
+(0045,0055) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="ACoefficients"				Name="A Coefficients"
+(0045,0056) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="NoiseReductionSensitivity"		Name="Noise Reduction Sensitivity"
+(0045,0057) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="NoiseReductionThreshold"		Name="Noise Reduction Threshold"
+(0045,0058) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="Mu"					Name="Mu"
+(0045,0059) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="Threshold"				Name="Threshold"
+(0045,0060) VERS="GEM"	VR="IS"	VM="4"	Owner="GEMS_SENO_02"	Keyword="BreastROIX"				Name="Breast ROI X"
+(0045,0061) VERS="GEM"	VR="IS"	VM="4"	Owner="GEMS_SENO_02"	Keyword="BreastROIY"				Name="Breast ROI Y"
+(0045,0062) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="UserWindowCenter"			Name="User Window Center"
+(0045,0063) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="UserWindowWidth"			Name="User Window Width"
+(0045,0064) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="SegmentationThreshold"			Name="Segmentation Threshold"
+(0045,0065) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="DetectorEntranceDose"			Name="Detector Entrance Dose"
+(0045,0066) VERS="GEM"	VR="IS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="AsymmetricalCollimationInformation"	Name="Asymmetrical Collimation Information"
+(0045,0071) VERS="GEM"	VR="OB"	VM="1"	Owner="GEMS_SENO_02"	Keyword="STXBuffer"							Name="STX Buffer"
+(0045,0072) VERS="GEM"	VR="DS"	VM="2"	Owner="GEMS_SENO_02"	Keyword="ImageCropPoint"							Name="Image Crop Point"
+(0045,0090) VERS="GEM"	VR="SH"	VM="1"	Owner="GEMS_SENO_02"	Keyword="PremiumViewBeta"				Name="Premium View Beta"
+(0045,00A0) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="SignalAverageFactor"				Name="Signal Average Factor"
+(0045,00A1) VERS="GEM"	VR="DS"	VM="2-n"	Owner="GEMS_SENO_02"	Keyword="OrganDoseForSourceImages"		Name="Organ Dose for Source Images"
+(0045,00A2) VERS="GEM"	VR="DS"	VM="2-n"	Owner="GEMS_SENO_02"	Keyword="EntranceDoseInmGyForSourceImages"	Name="Entrance dose in mGy for Source Images"
+(0045,00A4) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="OrganDoseIndGyForCompleteDBTSequence"	Name="Organ Dose in dGy for Complete DBT Sequence"
+(0045,00A6) VERS="GEM"	VR="UI"	VM="1"	Owner="GEMS_SENO_02"	Keyword="SOPInstanceUIDForLossyCompression"		Name="SOP Instance UID for Lossy Compression"
+(0045,00A7) VERS="GEM"	VR="LT"	VM="1"	Owner="GEMS_SENO_02"	Keyword="ReconstructionParameters"				Name="Reconstruction Parameters"
+(0045,00A8) VERS="GEM"	VR="DS"	VM="1"	Owner="GEMS_SENO_02"	Keyword="EntranceDoseIndGyForCompleteDBTSequence"	Name="Entrance Dose in dGy for Complete DBT Sequence"
+(0045,0001) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NumberOfMacroRowsInDetector"		Name="Number of Macro Rows in Detector"
+(0045,0002) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="MacroWidthAtISOCenter"			Name="Macro width at ISO Center"
+(0045,0003) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="DASType"				Name="DAS type"
+(0045,0004) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="DASGain"				Name="DAS gain"
+(0045,0005) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="DASTemprature"				Name="DAS Temprature"
+(0045,0006) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="TableDirection"			Name="Table Direction"
+(0045,0007) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="ZSmoothingFactor"			Name="Z smoothing Factor"
+(0045,0008) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="ViewWeightingMode"			Name="View Weighting Mode"
+(0045,0009) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="SigmaRowNumber"			Name="Sigma Row number"
+(0045,000A) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="MinimumDASValue"			Name="Minimum DAS value"
+(0045,000B) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="MaximumOffsetValue"			Name="Maximum Offset Value"
+(0045,000C) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NumberOfViewsShifted"			Name="Number of Views shifted"
+(0045,000D) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="ZTrackingFlag"				Name="Z tracking Flag"
+(0045,000E) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="MeanZError"				Name="Mean Z error"
+(0045,000F) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="ZTrackingError"			Name="Z tracking Error"
+(0045,0010) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="StartView2A"				Name="Start View 2A"
+(0045,0011) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NumberOfViews2A"			Name="Number of Views 2A"
+(0045,0012) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="StartView1A"				Name="Start View 1A"
+(0045,0013) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="SigmaMode"				Name="Sigma Mode"
+(0045,0014) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NumberOfViews1A"			Name="Number of Views 1A"
+(0045,0015) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="StartView2B"				Name="Start View 2B"
+(0045,0016) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NumberViews2B"				Name="Number Views 2B"
+(0045,0017) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="StartView1B"				Name="Start View 1B"
+(0045,0018) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NumberOfViews1B"			Name="Number of Views 1B"
+(0045,0021) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="IterboneFlag"				Name="Iterbone Flag"
+(0045,0022) VERS="GEM"	VR="SS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="PeristalticFlag"			Name="PeristalticFlag"
+(0045,0030) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="CardiacReconAlgorithm"			Name="CardiacReconAlgorithm"
+(0045,0031) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="AvgHeartRateForImage"			Name="AvgHeartRateForImage"
+(0045,0032) VERS="GEM"	VR="FL"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="TemporalResolution"			Name="TemporalResolution"
+(0045,0033) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="PctRpeakDelay"				Name="PctRpeakDelay"
+(0045,0036) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="EkgFullMaStartPhase"					Name="EkgFullMaStartPhase"
+(0045,0037) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="EkgFullMaEndPhase"					Name="EkgFullMaEndPhase"
+(0045,0038) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="EkgModulationMaxMa"					Name="EkgModulationMaxMa"
+(0045,0039) VERS="GEM"	VR="CS"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="EkgModulationMinMa"					Name="EkgModulationMinMa"
+(0045,003B) VERS="GEM"	VR="LO"	VM="1"	Owner="GEMS_HELIOS_01"	Keyword="NoiseReductionImageFilterDesc"					Name="NoiseReductionImageFilterDesc"
+(0047,0001) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="Reconstruction Parameters Sequence"	Name="Reconstruction Parameters Sequence"
+(0047,0050) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeVoxelCount"			Name="Volume Voxel Count"
+(0047,0051) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSegmentCount"			Name="Volume Segment Count"
+(0047,0053) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSliceSize"			Name="Volume Slice Size"
+(0047,0054) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSliceCount"			Name="Volume Slice Count"
+(0047,0055) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeThresholdValue"			Name="Volume Threshold Value"
+(0047,0057) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeVoxelRatio"			Name="Volume Voxel Ratio"
+(0047,0058) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeVoxelSize"			Name="Volume Voxel Size"
+(0047,0059) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeZPositionSize"			Name="Volume Z Position Size"
+(0047,0060) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeBaseLine"			Name="Volume Base Line"
+(0047,0061) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeCenterPoint"			Name="Volume Center Point"
+(0047,0063) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSkewBase"			Name="Volume Skew Base"
+(0047,0064) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeRegistrationTransformRotationMatrix"	Name="Volume Registration Transform Rotation Matrix"
+(0047,0065) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeRegistrationTransformTranslationVector"	Name="Volume Registration Transform Translation Vector"
+(0047,0070) VERS="GEM"  VR="DS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="KVPList"				Name="KVP List"
+(0047,0071) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="XRayTubeCurrentList"			Name="XRay Tube Current List"
+(0047,0072) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="ExposureList"				Name="Exposure List"
+(0047,0080) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="AcquisitionDLXIdentifier"		Name="Acquisition DLX Identifier"
+(0047,0085) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="AcquisitionDLX2DSeriesSequence"	Name="Acquisition DLX 2D Series Sequence"
+(0047,0089) VERS="GEM"  VR="DS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="ContrastAgentVolumeList"		Name="Contrast Agent Volume List"
+(0047,008A) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="NumberOfInjections"			Name="Number Of Injections"
+(0047,008B) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="FrameCount"				Name="Frame Count"
+(0047,0091) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="XA3DReconstructionAlgorithmName"	Name="XA 3D Reconstruction Algorithm Name"
+(0047,0092) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="XA3DReconstructionAlgorithmVersion"	Name="XA 3D Reconstruction Algorithm Version"
+(0047,0093) VERS="GEM"  VR="DA"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="DLXCalibrationDate"			Name="DLX Calibration Date"
+(0047,0094) VERS="GEM"  VR="TM"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="DLXCalibrationTime"			Name="DLX Calibration Time"
+(0047,0095) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="DLXCalibrationStatus"			Name="DLX Calibration Status"
+(0047,0096) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="UsedFrames"				Name="Used Frames"
+(0047,0098) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformCount"			Name="Transform Count"
+(0047,0099) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformSequence"			Name="Transform Sequence"
+(0047,009A) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformRotationMatrix"		Name="Transform Rotation Matrix"
+(0047,009B) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformTranslationVector"		Name="Transform Translation Vector"
+(0047,009C) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformLabel"			Name="Transform Label"
+(0047,00B0) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeList"				Name="Wireframe List"
+(0047,00B1) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeCount"			Name="Wireframe Count"
+(0047,00B2) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="LocationSystem"			Name="Location System"
+(0047,00B5) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeName"				Name="Wireframe Name"
+(0047,00B6) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeGroupName"			Name="Wireframe Group Name"
+(0047,00B7) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeColor"			Name="Wireframe Color"
+(0047,00B8) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeAttributes"			Name="Wireframe Attributes"
+(0047,00B9) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframePointCount"			Name="Wireframe Point Count"
+(0047,00BA) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeTimestamp"			Name="Wireframe Timestamp"
+(0047,00BB) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframePointList"			Name="Wireframe Point List"
+(0047,00BC) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframePointsCoordinates"		Name="Wireframe Points Coordinates"
+(0047,00C0) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeUpperLeftHighCornerRAS"		Name="Volume Upper Left High Corner RAS"
+(0047,00C1) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSliceToRASRotationMatrix"	Name="Volume Slice To RAS Rotation Matrix"
+(0047,00C2) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeUpperLeftHighCornerTLOC"		Name="Volume Upper Left High Corner TLOC"
+(0047,00D1) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSegmentList"			Name="Volume Segment List"
+(0047,00D2) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeGradientList"			Name="Volume Gradient List"
+(0047,00D3) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeDensityList"			Name="Volume Density List"
+(0047,00D4) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeZPositionList"			Name="Volume Z Position List"
+(0047,00D5) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeOriginalIndexList"		Name="Volume Original Index List"
+(0047,00e9) VERS="GEM"	VR="FL"   VM="3"	Owner="GEMS_3DSTATE_001"	Keyword="?"					Name="?"
+(0047,00ea) VERS="GEM"	VR="DS"   VM="3"	Owner="GEMS_3DSTATE_001"	Keyword="?"					Name="?"
+(0047,00eb) VERS="GEM"	VR="DS"   VM="3"	Owner="GEMS_3DSTATE_001"	Keyword="?"					Name="?"
+(0047,00ec) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_3DSTATE_001"	Keyword="?"					Name="?"
+(0047,00ed) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_3DSTATE_001"	Keyword="?"					Name="?"
+(0047,0002) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_IQTB_IDEN_47"	Keyword="?"					Name="?"
+(0049,0001) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="CTCardiacSequence"			Name="CT Cardiac Sequence"
+(0049,0002) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="HeartRateAtConfirm"			Name="HeartRateAtConfirm"
+(0049,0003) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="AvgHeartRatePriorToConfirm"		Name="AvgHeartRatePriorToConfirm"
+(0049,0004) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="MinHeartRatePriorToConfirm"		Name="MinHeartRatePriorToConfirm"
+(0049,0005) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="MaxHeartRatePriorToConfirm"		Name="MaxHeartRatePriorToConfirm"
+(0049,0006) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="StdDevHeartRatePriorToConfirm"		Name="StdDevHeartRatePriorToConfirm"
+(0049,0007) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="NumHeartRateSamplesPriorToConfirm"	Name="NumHeartRateSamplesPriorToConfirm"
+(0049,0008) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="AutoHeartRateDetectPredict"		Name="AutoHeartRateDetectPredict"
+(0049,0009) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="SystemOptimizedHeartRate"		Name="SystemOptimizedHeartRate"
+(0049,000A) VERS="GEM"  VR="ST"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="EkgMonitorType"			Name="EkgMonitorType"
+(0049,000B) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_CT_CARDIAC_001"	Keyword="NumReconSectors"			Name="NumReconSectors"
+(0049,000C) VERS="GEM"  VR="FL"   VM="256"	Owner="GEMS_CT_CARDIAC_001"	Keyword="RpeakTimeStamps"			Name="RpeakTimeStamps"
+(004B,0001) VERS="GEM"  VR="DS"   VM="1-n"	Owner="GEMS_CT_HINO_01"		Keyword="BeamThickess"				Name="Beam Thickess"
+(004B,0002) VERS="GEM"  VR="DS"   VM="1-n"	Owner="GEMS_CT_HINO_01"		Keyword="RTime"					Name="R Time"
+(004B,0003) VERS="GEM"  VR="IS"   VM="1"	Owner="GEMS_CT_HINO_01"		Keyword="HBCNumber"				Name="HBC Number"
+(004B,0013) VERS="GEM"  VR="IS"   VM="1"	Owner="GEIIS"		Keyword="?"				Name="?"
+(004B,0015) VERS="GEM"  VR="LT"   VM="1"	Owner="GEIIS"		Keyword="?"				Name="?"
+(0051,1001) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_CT_VES_01"		Keyword="CTVESSequence"				Name="CTVESequence"
+(0055,0012) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRAEnergyWindowInformationSequence"	Name="eNTEGRA Energy Window Information Sequence"
+(0055,0013) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRAEnergyWindowRangeSequence"	Name="eNTEGRA Energy Window Range Sequence"
+(0055,0022) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRADetectorInformationSequence"	Name="eNTEGRA Detector Information Sequence"
+(0055,0052) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRARotationInformationSequence"	Name="eNTEGRA Rotation Information Sequence"
+(0055,0062) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRAGatedInformationSequence"	Name="eNTEGRA Gated Information Sequence"
+(0055,0063) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="eNTEGRADataInformationSequence"	Name="eNTEGRA Data Information Sequence"
+(0055,0064) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SDODoubleDataSequence"				Name="SDO Double Data Sequence"
+(0055,0065) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="?"									Name="?"
+
+(3101,0010) VERS="GEM"	VR="SQ"   VM="1"	Owner="AMI Annotations_01"				Keyword="AnnotationSequence"			Name="Annotation Sequence"
+(3101,0020) VERS="GEM"	VR="SQ"   VM="1"	Owner="AMI Annotations_02"				Keyword="AnnotationSequence"			Name="Annotation Sequence"
+(3103,0010) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationSequence"			Name="Annotation Sequence"
+(3103,0020) VERS="GEM"	VR="UI"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationUID"					Name="Annotation UID"
+(3103,0030) VERS="GEM"	VR="US"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationColor"				Name="Annotation Color"
+(3103,0050) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationLineStyle"			Name="Annotation Line Style"
+(3103,0060) VERS="GEM"	VR="SQ"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationElements"			Name="Annotation Elements"
+(3103,0070) VERS="GEM"	VR="SH"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationLabel"				Name="Annotation Label"
+(3103,0080) VERS="GEM"	VR="PN"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationCreator"				Name="Annotation Creator"
+(3103,0090) VERS="GEM"	VR="PN"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationModifiers"			Name="Annotation Modifiers"
+(3103,00A0) VERS="GEM"	VR="DA"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationCreationDate"		Name="Annotation Creation Date"
+(3103,00B0) VERS="GEM"	VR="TM"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationCreationTime"		Name="Annotation Creation Time"
+(3103,00C0) VERS="GEM"	VR="DA"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationModificationDates"	Name="Annotation Modification Dates"
+(3103,00D0) VERS="GEM"	VR="TM"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationMofificationTimes"	Name="Annotation Mofification Times"
+(3103,00E0) VERS="GEM"	VR="US"   VM="1"	Owner="AMI Sequence Annotations_01"		Keyword="AnnotationFrameNumber"			Name="Annotation Frame Number"
+(3103,0010) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationSequence"			Name="Annotation Sequence"
+(3103,0020) VERS="GEM"	VR="UI"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationUID"					Name="Annotation UID"
+(3103,0030) VERS="GEM"	VR="US"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationColor"				Name="Annotation Color"
+(3103,0050) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationLineStyle"			Name="Annotation Line Style"
+(3103,0060) VERS="GEM"	VR="SQ"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationElements"			Name="Annotation Elements"
+(3103,0070) VERS="GEM"	VR="SH"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationLabel"				Name="Annotation Label"
+(3103,0080) VERS="GEM"	VR="PN"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationCreator"				Name="Annotation Creator"
+(3103,0090) VERS="GEM"	VR="PN"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationModifiers"			Name="Annotation Modifiers"
+(3103,00A0) VERS="GEM"	VR="DA"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationCreationDate"		Name="Annotation Creation Date"
+(3103,00B0) VERS="GEM"	VR="TM"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationCreationTime"		Name="Annotation Creation Time"
+(3103,00C0) VERS="GEM"	VR="DA"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationModificationDates"	Name="Annotation Modification Dates"
+(3103,00D0) VERS="GEM"	VR="TM"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationModificationTimes"	Name="Annotation Modification Times"
+(3103,00E0) VERS="GEM"	VR="US"   VM="1"	Owner="AMI Sequence Annotations_02"		Keyword="AnnotationFrame Number"		Name="Annotation Frame Number"
+(3105,0010) VERS="GEM"	VR="DS"   VM="1-n"	Owner="AMI Sequence AnnotElements_01"	Keyword="AnnotationElementPosition"		Name="Annotation Element Position"
+(3105,0020) VERS="GEM"	VR="LT"   VM="1"	Owner="AMI Sequence AnnotElements_01"	Keyword="AnnotationElementText"			Name="Annotation Element Text"
+(3107,0010) VERS="GEM"	VR="DS"   VM="1-n"	Owner="AMI ImageTransform_01"			Keyword="Transformation Matrix"			Name="Transformation Matrix"
+(3107,0020) VERS="GEM"	VR="DS"   VM="1"	Owner="AMI ImageTransform_01"			Keyword="CenterOffset"					Name="Center Offset"
+(3107,0030) VERS="GEM"	VR="DS"   VM="1"	Owner="AMI ImageTransform_01"			Keyword="Magnification"					Name="Magnification"
+(3107,0040) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageTransform_01"			Keyword="MagnificationType"				Name="Magnification Type"
+(3107,0050) VERS="GEM"	VR="DS"   VM="1"	Owner="AMI ImageTransform_01"			Keyword="DisplayedArea"					Name="Displayed Area"
+(3107,0060) VERS="GEM"	VR="DS"   VM="1"	Owner="AMI ImageTransform_01"			Keyword="CalibrationFactor"				Name="Calibration Factor"
+(3107,00A0) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContextExt_01"			Keyword="WindowFunction"				Name="Window Function"
+(3107,00B0) VERS="GEM"	VR="DS"   VM="1"	Owner="AMI ImageContextExt_01"			Keyword="WindowSlope"					Name="Window Slope"
+(3109,0001) VERS="GEM"	VR="ST"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="WorklistFilename"				Name="Worklist Filename"
+(3109,0002) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="NewSeenStatus"					Name="NEW/SEEN Status"
+(3109,0003) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="DeleteLock"					Name="Delete Lock"
+(3109,0004) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="?"								Name="?"
+(3109,0005) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="?"								Name="?"
+(3109,0006) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="?"								Name="?"
+(3109,0007) VERS="GEM"	VR="UL"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="?"								Name="?"
+(3109,0008) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ReceiveOrigin"					Name="Receive Origin"
+(3109,0009) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="Folder"						Name="Folder"
+(3109,000A) VERS="GEM"	VR="DA"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ReceiveDate"					Name="Receive Date"
+(3109,000B) VERS="GEM"	VR="TM"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ReceiveTime"					Name="Receive Time"
+(3109,000C) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="Prior"							Name="Prior"
+(3109,000D) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="StatStudy"						Name="STAT Study"
+(3109,000E) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="Key"							Name="Is Key Image Or Study"
+(3109,0010) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="LocalStudy"					Name="Local Study"
+(3109,0011) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ResultMessage"					Name="Result Message"
+(3109,0012) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="CurrentUser"					Name="Current User"
+(3109,0013) VERS="GEM"	VR="DA"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="SystemDate"					Name="System Date"
+(3109,0014) VERS="GEM"	VR="TM"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="SystemTime"					Name="System Time"
+(3109,0019) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="WorklistName"					Name="Worklist Name"
+(3109,0020) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="WorklistUID"					Name="Worklist UID"
+(3109,0021) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="Hostname"						Name="Hostname"
+(3109,0022) VERS="GEM"	VR="AE"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="DICOMAETitle"					Name="DICOM AE Title"
+(3109,0023) VERS="GEM"	VR="US"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="DICOMPortNumber"				Name="DICOM Port Number"
+(3109,0024) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="DestinationName"				Name="Destination Name"
+(3109,0025) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="OriginName"					Name="Origin Name"
+(3109,0026) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ModalityStudyInstanceUID"		Name="Modality Study Instance UID"
+(3109,0027) VERS="GEM"	VR="SQ"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ExamRouting"					Name="Exam Routing"
+(3109,0028) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="NotificationComments"			Name="Notification Comments"
+(3109,0029) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="TransactionComments"			Name="Transaction Comments"
+(3109,002A) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="SendFlag"						Name="Send Flag"
+(3109,002B) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="PrintFlag"						Name="Print Flag"
+(3109,002C) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ArchiveFlag"					Name="Archive Flag"
+(3109,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="RequestingFacilityName"		Name="Requesting Facility Name"
+(3109,0031) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="RequestingProcedureName"		Name="Requesting Procedure Name"
+(3109,0032) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="RequestingProcedureCode"		Name="Requesting Procedure Code"
+(3109,0033) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="RequestStorage ommitment"		Name="Request Storage Commitment"
+(3109,0034) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="RequestedCompression"			Name="Requested Compression"
+(3109,0035) VERS="GEM"	VR="SQ"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="StudySequence"					Name="Study Sequence"
+(3109,0037) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ReplacedStudyUID"				Name="Replaced Study UID"
+(3109,0038) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="TeachingACRCode"				Name="Teaching ACR Code"
+(3109,0039) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="TeachingSpecialInterestCode"	Name="Teaching Special Interest Code"
+(3109,0040) VERS="GEM"	VR="IS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="NumberOfStudyRelatedImages"	Name="Number of Study Related Images"
+(3109,0041) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="StudyLocked"					Name="Study Locked"
+(3109,0042) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="WorkstationName"				Name="Workstation Name"
+(3109,0043) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="ArchiveStatus"					Name="Archive Status"
+(3109,00EE) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="InternalListUID"				Name="Internal List UID"
+(3109,00EF) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 5.0"	Keyword="Action"						Name="Action (Add,Remove,Change)"
+
+(3109,0001) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/RadWorks/Version 6.0/Summary"	Keyword="Status"						Name="Status"
+(3109,0011) VERS="GEM"	VR="ST"   VM="1"	Owner="Applicare/RadWorks/Version 6.0/Summary"	Keyword="ReceiveOriginSiteName"			Name="Receive Origin Site Name"
+(3109,0012) VERS="GEM"	VR="ST"   VM="1"	Owner="Applicare/RadWorks/Version 6.0/Summary"	Keyword="ReceiveOriginDescription"		Name="Receive Origin Description"
+(3109,0015) VERS="GEM"	VR="DA"   VM="1"	Owner="Applicare/RadWorks/Version 6.0/Summary"	Keyword="ReceiveDate"					Name="Receive Date"
+(3109,0016) VERS="GEM"	VR="TM"   VM="1"	Owner="Applicare/RadWorks/Version 6.0/Summary"	Keyword="ReceiveTime"					Name="Receive Time"
+
+(3115,0001) VERS="GEM"	VR="UT"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/rad_pacs/"	Keyword="?"	Name="?"
+
+(4101,0001) VERS="GEM"	VR="UL"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="MaskState"								Name="Mask State"
+(4101,0002) VERS="GEM"	VR="SQ"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="Annotations"							Name="Annotations"
+(4101,0003) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="Font"									Name="Font"
+(4101,0004) VERS="GEM"	VR="UL"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="FontSize"								Name="Font Size"
+(4101,0005) VERS="GEM"	VR="FD"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="FontRelativeSize"						Name="Font Relative Size"
+(4101,0006) VERS="GEM"	VR="US"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="Overlay"								Name="Overlay"
+(4101,0007) VERS="GEM"	VR="US"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="PixelRep"								Name="Pixel Rep"
+(4101,0008) VERS="GEM"	VR="US"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="AnnotationLevel"						Name="Annotation Level"
+(4101,0009) VERS="GEM"	VR="US"   VM="1"	Owner="Applicare/Print/Version 5.1"	Keyword="ShowCaliper"							Name="Show Caliper"
+
+(4103,0001) VERS="GEM"	VR="AT"   VM="1-n"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="NonExistentTags"					Name="Non-existent tags"
+(4103,0002) VERS="GEM"	VR="UI"   VM="1-n"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="NonExistentObjects"				Name="Non-existent objects"
+
+(4105,0001) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationType"					Name="Annotation Type"
+(4105,0002) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationValue"					Name="Annotation Value"
+(4105,0003) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="CutlineImageUID"					Name="Cutline Image UID"
+(4105,0004) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="CutlineSetUID"						Name="Cutline Set UID"
+(4105,0005) VERS="GEM"	VR="US"   VM="3"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationColor"					Name="Annotation Color (RGB)"
+(4105,0006) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationLineStyle"				Name="Annotation Line Style"
+(4105,0007) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationLabel"					Name="Annotation Label"
+(4105,0008) VERS="GEM"	VR="PN"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationCreator"					Name="Annotation Creator"
+(4105,0009) VERS="GEM"	VR="DA"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationCreationDate"			Name="Annotation Creation Date"
+(4105,000A) VERS="GEM"	VR="TM"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationCreationTime"			Name="Annotation Creation Time"
+(4105,000B) VERS="GEM"	VR="SQ"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationModificationSequence"	Name="Annotation Modification Sequence"
+(4105,000C) VERS="GEM"	VR="PN"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationModifier"				Name="Annotation Modifier"
+(4105,000D) VERS="GEM"	VR="DA"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationModificationDate"		Name="Annotation Modification Date"
+(4105,000E) VERS="GEM"	VR="TM"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="AnnotationModificationTime"		Name="Annotation Modification Time"
+(4105,0010) VERS="GEM"	VR="US"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="?"									Name="?"
+
+(4107,0001) VERS="GEM"	VR="SQ"   VM="1"	Owner="Applicare/RadWorks/Version 6.0"	Keyword="RequestedPaletteColorLUT"	Name="Requested Palette Color LUT"
+
+(5001,0001) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Modified"				Name="Modified"
+(5001,0002) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Name"					Name="Name"
+(5001,0003) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Cid"					Name="Cid"
+(5001,0004) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Srid"					Name="Srid"
+(5001,0005) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SOPClassUID"				Name="SOP Class UID"
+(5001,0006) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SOPInstanceUID"			Name="SOP Instance UID"
+(5001,0007) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CurveType"				Name="Curve Type"
+(5001,0008) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="GraphType"				Name="Graph Type"
+(5001,0009) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Legend"				Name="Legend"
+(5001,000a) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="XUnits"				Name="X Units"
+(5001,000b) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="YUnits"				Name="Y Units"
+(5001,000c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Edit"					Name="Edit"
+(5001,000d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Suspend"				Name="Suspend"
+(5001,000e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StyleLine"				Name="Style Line"
+(5001,000f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StyleFill"				Name="Style Fill"
+(5001,0010) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StyleColour"				Name="Style Colour"
+(5001,0011) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StyleWidth"				Name="Style Width"
+(5001,0012) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StylePoint"				Name="Style Point"
+(5001,0013) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StylePColour"				Name="Style P Colour"
+(5001,0014) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StylePSize"				Name="Style P Size"
+(5001,0015) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Segments"				Name="Segments"
+(5001,0016) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SegType"				Name="Seg Type"
+(5001,0017) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegStart"				Name="Seg Start"
+(5001,0018) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegEnd"				Name="Seg End"
+(5001,0019) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegStyleLine"				Name="Seg Style Line"
+(5001,001a) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegStyleFill"				Name="SegStyleFill"
+(5001,001b) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SegStyleColour"			Name="Seg Style Colour"
+(5001,001c) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegStyleWidth"				Name="Seg Style Width"
+(5001,001d) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegStylePoint"				Name="Seg Style Point"
+(5001,001e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SegStylePColour"			Name="Seg Style P Colour"
+(5001,001f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SegStylePSize"				Name="Seg Style P Size"
+(5001,0020) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SegName"				Name="Seg Name"
+(5001,0021) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="SegAllowDirInt"			Name="Seg Allow Dir Int"
+(5001,0022) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TextAnnots"				Name="Text Annots"
+(5001,0023) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="TxtX"					Name="Txt X"
+(5001,0024) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="TxtY"					Name="Txt Y"
+(5001,0025) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TxtText"				Name="Txt Text"
+(5001,0026) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="TxtName"				Name="Txt Name"
+(5001,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ROIName"				Name="ROI Name"
+(5001,0031) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DerivedFromImageUID"			Name="Derived From Image UID"
+(5001,0032) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="DerivedFromImages"			Name="Derived From Images"
+(5001,0033) VERS="GEM"	VR="UL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CurveFlags"				Name="Curve Flags"
+(5001,0034) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CurveName"				Name="Curve Name"
+(5001,0035) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DatasetName"				Name="Dataset Name"
+(5001,0036) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CurveUID"				Name="Curve UID"
+(5001,0037) VERS="GEM"	VR="FD"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ROIArea"				Name="ROI Area"
+(5001,0038) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Modified"				Name="Modified"
+(5001,0039) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Name"					Name="Name"
+(5001,003a) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SoftwareVersion"			Name="Software Version"
+(5001,003b) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="StartDate"				Name="Start Date"
+(5001,003c) VERS="GEM"	VR="SH"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="CompletionDate"			Name="Completion Date"
+(5001,003d) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="DetectorName"				Name="Detector Name"
+(5001,0041) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Modified"				Name="Modified"
+(5001,0042) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Name"					Name="Name"
+(5001,0043) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Name"					Name="Name"
+(5001,0044) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Name"					Name="Name"
+(5001,0045) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SOPClassUID"				Name="SOP Class UID"
+(5001,0046) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SOPInstanceUID"			Name="SOP Instance UID"
+(5001,0047) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NormalColor"				Name="Normal Color"
+(5001,0048) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NameFont"				Name="Name Font"
+(5001,0049) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FillPattern"				Name="Fill Pattern"
+(5001,004a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="LineStyle"				Name="Line Style"
+(5001,004b) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="LineDashLength"			Name="Line Dash Length"
+(5001,004c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="LineThickness"				Name="Line Thickness"
+(5001,004d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Interactivity"				Name="Interactivity"
+(5001,004e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NamePos"				Name="Name Pos"
+(5001,004f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="NameDisplay"				Name="Name Display"
+(5001,0050) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="Label"					Name="Label"
+(5001,0051) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="BpSeg"					Name="Bp Seg"
+(5001,0052) VERS="GEM"	VR="US"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="BpSegPairs"				Name="Bp Seg Pairs"
+(5001,0053) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="SeedSpace"				Name="Seed Space"
+(5001,0054) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="Seeds"					Name="Seeds"
+(5001,0055) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="Shape"					Name="Shape"
+(5001,0056) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="ShapeTilt"				Name="Shape Tilt"
+(5001,0059) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="ShapePtsSpace"				Name="Shape Pts Space"
+(5001,005a) VERS="GEM"	VR="SL"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="ShapeCtrlPtsCounts"			Name="Shape Ctrl Pts Counts"
+(5001,005b) VERS="GEM"	VR="FD"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="ShapeCtrlPts"				Name="Shape Ctrl Pts"
+(5001,005c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ShapeCtrlPSpace"			Name="Shape Ctrl P Space"
+(5001,005d) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ROIFlags"				Name="ROI Flags"
+(5001,005e) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="FrameNumber"				Name="Frame Number"
+(5001,005f) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GENIE_1"		Keyword="ID"					Name="ID"
+(5001,0060) VERS="GEM"	VR="LO"   VM="1-n"	Owner="GEMS_GENIE_1"		Keyword="DatasetROIMapping"			Name="Dataset ROI Mapping"
+(60xx,0001) VERS="GEM"	VR="US"   VM="3"	Owner="DLX_LKUP_01"			Keyword="GrayPaletteColorLookupTableDescriptor"	Name="Gray Palette Color Lookup Table Descriptor"
+(60xx,0002) VERS="GEM"	VR="US"   VM="1"	Owner="DLX_LKUP_01"			Keyword="GrayPaletteColorLookupTableData"	Name="Gray Palette Color Lookup Table Data"
+(70xx,0004) VERS="GEM"	VR="ST"   VM="1"	Owner="DLX_ANNOT_01"		Keyword="TextAnnotation"			Name="TextAnnotation"
+(70xx,0005) VERS="GEM"	VR="IS"   VM="2"	Owner="DLX_ANNOT_01"		Keyword="Box"					Name="Box"
+(70xx,0007) VERS="GEM"	VR="IS"   VM="2"	Owner="DLX_ANNOT_01"		Keyword="ArrowEnd"				Name="ArrowEnd"
+(0009,0010) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEIIS"				Keyword="GEPrivateImageThumbnailSequence"	Name="GE Private Image Thumbnail Sequence"
+(0009,0012) VERS="GEM"	VR="IS"   VM="1"	Owner="GEIIS"				Keyword="?"	Name="?"
+(0029,0010) VERS="GEM"	VR="UL"   VM="1"	Owner="GEIIS"				Keyword="ShiftCount"						Name="Shift Count"
+(0029,0012) VERS="GEM"	VR="UL"   VM="1"	Owner="GEIIS"				Keyword="Offset"							Name="Offset"
+(0029,0014) VERS="GEM"	VR="UL"   VM="1"	Owner="GEIIS"				Keyword="ActualFrameNumber"					Name="Actual Frame Number"
+(0903,0010) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="RejectImageFlag"					Name="Reject Image Flag"
+(0903,0011) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="SignificantFlag"					Name="Significant Flag"
+(0903,0012) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="ConfidentialFlag"					Name="Confidential Flag"
+(0903,0020) VERS="GEM"	VR="CS"   VM="1"	Owner="GEIIS PACS"			Keyword="?"									Name="?"
+(0905,0030) VERS="GEM"	VR="LO"   VM="1"	Owner="GEIIS"				Keyword="AssigningAuthorityForPatientID"	Name="Assigning Authority For Patient ID"
+(0907,0010) VERS="GEM"	VR="UI"   VM="1"	Owner="GEIIS"				Keyword="OriginalStudyInstanceUID"			Name="Original Study Instance UID"
+(0907,0020) VERS="GEM"	VR="UI"   VM="1"	Owner="GEIIS"				Keyword="OriginalSeriesInstanceUID" 		Name="Original Series Instance UID"
+(0907,0021) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="PrefetchAlgorithm"					Name="Prefetch Algorithm"
+(0907,0022) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="LimitRecentStudies"				Name="Limit Recent Studies"
+(0907,0023) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="LimitOldestStudies"				Name="Limit Oldest Studies"
+(0907,0024) VERS="GEM"	VR="US"   VM="1"	Owner="GEIIS PACS"			Keyword="LimitRecentMonths"					Name="Limit Recent Months"
+(0907,0030) VERS="GEM"	VR="UI"   VM="1"	Owner="GEIIS"				Keyword="OriginalSOPInstanceUID"			Name="Original SOP Instance UID"
+(0907,0031) VERS="GEM"	VR="UI"   VM="1-n"	Owner="GEIIS PACS"			Keyword="ExcludeStudyUIDs"					Name="Exclude Study UIDs"
+
+(7fd1,0010) VERS="GEM"	VR="UL"   VM="1"	Owner="GEIIS"				Keyword="CompressionType"					Name="Compression Type"
+(7fd1,0020) VERS="GEM"	VR="UL"   VM="1-n"	Owner="GEIIS"				Keyword="MultiframeOffsets"					Name="Multiframe Offsets"
+(7fd1,0030) VERS="GEM"  VR="UL"   VM="1"	Owner="GEIIS"				Keyword="MultiResolutionLevels"		Name="Multi-Resolution Levels"
+(7fd1,0040) VERS="GEM"  VR="UL"   VM="1-n"	Owner="GEIIS"				Keyword="SubbandRows"				Name="Subband Rows"
+(7fd1,0050) VERS="GEM"  VR="UL"   VM="1-n"	Owner="GEIIS"				Keyword="SubbandColumns"			Name="Subband Columns"
+(7fd1,0060) VERS="GEM"  VR="UL"   VM="1-n"	Owner="GEIIS"				Keyword="SubbandBytecounts"			Name="Subband Bytecounts"
+
+(0011,0003) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ProcessedSeriesUID"				Name="Processed Series UID"
+(0011,0004) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="AcquisitionType"					Name="Acquisition Type"
+(0011,0005) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="AcquisitionUID"					Name="Acquisition UID"
+(0011,0006) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ImageDose"							Name="Image Dose"
+(0011,0007) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="StudyDose"							Name="Study Dose"
+(0011,0008) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="StudyDAP"							Name="Study DAP"
+(0011,0009) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="NonDigitalExposures"				Name="Non-Digital Exposures"
+(0011,0010) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="TotalExposures"					Name="Total Exposures"
+(0011,0011) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ROI"								Name="ROI"
+(0011,0012) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="PatientSizeString"					Name="Patient Size String"
+(0011,0013) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="SPSUID"							Name="SPS UID"
+(0011,0014) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0015) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="DetectorARCGain"					Name="Detector ARC Gain"
+(0011,0016) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ProcessingDebugInfo"				Name="Processing Debug Info"
+(0011,0017) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="OverrideMode"						Name="Override Mode"
+(0011,0019) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="FilmSpeedSelection"				Name="Film Speed Selection"
+(0011,0027) VERS="GEM"	VR="UN"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0028) VERS="GEM"	VR="UN"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0029) VERS="GEM"	VR="UN"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0030) VERS="GEM"	VR="UN"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0031) VERS="GEM"	VR="IS"   VM="1-n"	Owner="GEMS_GDXE_FALCON_04"					Keyword="DetectedFieldOfView"				Name="Detected Field of View"
+(0011,0032) VERS="GEM"	VR="IS"   VM="1-n"	Owner="GEMS_GDXE_FALCON_04"					Keyword="AdjustedFieldOfView"				Name="Adjusted Field of View"
+(0011,0033) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="DetectorExposureIndex"				Name="Detector Exposure Index"
+(0011,0034) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="CompensatedDetectorExposure"		Name="Compensated Detector Exposure"
+(0011,0035) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="UncompensatedDetectorExposure"		Name="Uncompensated Detector Exposure"
+(0011,0036) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="MedianAnatomyCountValue"			Name="Median Anatomy Count Value"
+(0011,0037) VERS="GEM"	VR="DS"   VM="2"	Owner="GEMS_GDXE_FALCON_04"					Keyword="DEILowerAndUpperLimitValues"		Name="DEI Lower & Upper Limit Values"
+(0011,0038) VERS="GEM"	VR="SL"   VM="6"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ShiftVectorForPasting"				Name="Shift Vector for Pasting"
+(0011,0039) VERS="GEM"	VR="CS"   VM="6"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ImageNumberInPasting"				Name="Image Number in Pasting"
+(0011,0040) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="PastingOverlap"					Name="Pasting Overlap"
+(0011,0041) VERS="GEM"	VR="IS"   VM="24"	Owner="GEMS_GDXE_FALCON_04"					Keyword="SubImageCollimatorVertices"		Name="Sub-image Collimator Vertices"
+(0011,0042) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ViewIP"							Name="View IP"
+(0011,0043) VERS="GEM"	VR="IS"   VM="24"	Owner="GEMS_GDXE_FALCON_04"					Keyword="KeystoneCoordinates"				Name="Keystone Coordinates"
+(0011,0044) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="ReceptorType"						Name="Receptor Type"
+(0011,0046) VERS="GEM"	VR="LO"   VM="1-n"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0047) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0059) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,0060) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+(0011,006d) VERS="GEM"	VR="DS"   VM="1"	Owner="GEMS_GDXE_FALCON_04"					Keyword="?"									Name="?"
+
+(0045,0055) VERS="GEM"	VR="DS"   VM="8"	Owner="GEMS_FALCON_03"						Keyword="A_Coefficients"					Name="A_Coefficients used in Multiresolution Algorithm"
+(0045,0062) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_FALCON_03"						Keyword="UserWindowCenter"					Name="User Window Center"
+(0045,0063) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_FALCON_03"						Keyword="UserWindowWidth"					Name="User Window Width"
+(0045,0065) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_FALCON_03"						Keyword="RequestedDetectorEntranceDose"		Name="Requested Detector Entrance Dose"
+(0045,0067) VERS="GEM"	VR="DS"   VM="3"	Owner="GEMS_FALCON_03"						Keyword="VOILUTAssymmetryParameterBeta"		Name="VOI LUT Assymmetry Parameter Beta"
+(0045,0069) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_FALCON_03"						Keyword="CollimatorRotation"				Name="Collimator Rotation"
+(0045,0072) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_FALCON_03"						Keyword="CollimatorWidth"					Name="Collimator Width"
+(0045,0073) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_FALCON_03"						Keyword="CollimatorHeight"					Name="Collimator Height"
+
+(0045,0055) VERS="GEM"	VR="DS"   VM="8"	Owner="GEMS_SEND_02"						Keyword="A_Coefficients"					Name="A_Coefficients used in Multiresolution Algorithm"
+(0045,0062) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_SEND_02"						Keyword="UserWindowCenter"					Name="User Window Center"
+(0045,0063) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_SEND_02"						Keyword="UserWindowWidth"					Name="User Window Width"
+(0045,0065) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_SEND_02"						Keyword="RequestedDetectorEntranceDose"		Name="Requested Detector Entrance Dose"
+(0045,0067) VERS="GEM"	VR="DS"   VM="3"	Owner="GEMS_SEND_02"						Keyword="VOILUTAssymmetryParameterBeta"		Name="VOI LUT Assymmetry Parameter Beta"
+(0045,0069) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_SEND_02"						Keyword="CollimatorRotation"				Name="Collimator Rotation"
+(0045,0072) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_SEND_02"						Keyword="CollimatorWidth"					Name="Collimator Width"
+(0045,0073) VERS="GEM"	VR="IS"   VM="1"	Owner="GEMS_SEND_02"						Keyword="CollimatorHeight"					Name="Collimator Height"
+
+(7FDF,0010) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GDXE_ATHENAV2_INTERNAL_USE"		Keyword="PixelDataReferences"				Name="Pixel Data References"
+(7FDF,0011) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_GDXE_ATHENAV2_INTERNAL_USE"		Keyword="PixelDataReferencesTemporary"		Name="Pixel Data References (temporary)"
+(7FDF,0020) VERS="GEM"	VR="SS"   VM="1"	Owner="GEMS_GDXE_ATHENAV2_INTERNAL_USE"		Keyword="AutoPushTag"						Name="Auto Push Tag"
+(7FDF,0025) VERS="GEM"	VR="CS"   VM="1"	Owner="GEMS_GDXE_ATHENAV2_INTERNAL_USE"		Keyword="PPSStatus"							Name="PPS Status"
+
+(6003,0010) VERS="GEM"	VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_ImageGroup_001"		Keyword="?"	Name="?"
+(6003,0011) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_Ultrasound_ImageGroup_001"		Keyword="?"	Name="?"
+(6003,0012) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_Ultrasound_ImageGroup_001"		Keyword="?"	Name="?"
+(6003,0015) VERS="GEM"	VR="LT"   VM="1-n"	Owner="GEMS_Ultrasound_ImageGroup_001"		Keyword="?"	Name="?"
+
+(6005,0010) VERS="GEM"	VR="UT"   VM="1"	Owner="GEMS_Ultrasound_ExamGroup_001"		Keyword="?"	Name="?"
+(6005,0020) VERS="GEM"	VR="UT"   VM="1"	Owner="GEMS_Ultrasound_ExamGroup_001"		Keyword="?"	Name="?"
+
+(7fe1,0001) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0002) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0003) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0008) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0010) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0012) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0018) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0020) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0024) VERS="GEM"  VR="SH"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0026) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0030) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0032) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0036) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0037) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,003a) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,003c) VERS="GEM"  VR="FD"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0043) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0048) VERS="GEM"  VR="FD"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0049) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0051) VERS="GEM"  VR="FL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0052) VERS="GEM"  VR="FD"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0053) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0054) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0055) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0057) VERS="GEM"  VR="LT"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0060) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0061) VERS="GEM"  VR="OW"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0062) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0069) VERS="GEM"  VR="OW"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0070) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0071) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0072) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0073) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0074) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0075) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0077) VERS="GEM"  VR="FD"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0079) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0083) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0084) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0085) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0086) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0087) VERS="GEM"  VR="FD"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+(7fe1,0088) VERS="GEM"  VR="FD"   VM="1"	Owner="GEMS_Ultrasound_MovieGroup_001" 	Keyword="?" 	Name="?"
+
+(7fe1,0001) VERS="GEM"	VR="OB"   VM="1"	Owner="KRETZ_US"		Keyword="?"	Name="?"
+
+(0009,0001) VERS="GEM"  VR="UL"   VM="1-n"      Owner="QUASAR_INTERNAL_USE" 		Keyword="RateVector" 				Name="Rate Vector" 
+(0009,0002) VERS="GEM"  VR="UL"   VM="1-n"      Owner="QUASAR_INTERNAL_USE" 		Keyword="CountVector" 				Name="Count Vector" 
+(0009,0003) VERS="GEM"  VR="UL"   VM="1-n"      Owner="QUASAR_INTERNAL_USE" 		Keyword="TimeVector" 				Name="Time Vector" 
+(0009,0007) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="AngleVector" 				Name="Angle Vector" 
+(0009,0008) VERS="GEM"  VR="US"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="CameraShape" 				Name="Camera Shape" 
+(0009,0010) VERS="GEM"  VR="US"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="WholeBodySpots" 			Name="Whole Body Spots" 
+(0009,0011) VERS="GEM"  VR="US"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="WorklistFlag"				Name="Worklist Flag" 
+(0009,0012) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?"							Name="?" 
+(0009,0013) VERS="GEM"  VR="ST"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="SequenceType" 				Name="Sequence Type" 
+(0009,0014) VERS="GEM"  VR="ST"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="SequenceName" 				Name="Sequence Name" 
+(0009,0015) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="AverageRRTimeVector" 		Name="Average RR Time Vector" 
+(0009,0016) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="LowLimitVector" 			Name="Low Limit Vector" 
+(0009,0017) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="HighLimitVector" 			Name="High Limit Vector" 
+(0009,0018) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="BeginIndexVector" 			Name="Begin Index Vector" 
+(0009,0019) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="EndIndexVector" 			Name="End Index Vector" 
+(0009,001a) VERS="GEM"  VR="UL"   VM="1-n"		Owner="QUASAR_INTERNAL_USE" 		Keyword="RawTimeVector" 			Name="Raw Time Vector" 
+(0009,001b) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="ImageTypeString" 			Name="Image Type String" 
+(0009,001d) VERS="GEM"  VR="US"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,001e) VERS="GEM"  VR="ST"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0022) VERS="GEM"  VR="FL"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0023) VERS="GEM"  VR="US"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0039) VERS="GEM"  VR="UI"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0040) VERS="GEM"  VR="DA"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0041) VERS="GEM"  VR="TM"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0042) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0044) VERS="GEM"  VR="SH"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0045) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0009,0048) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+
+(0037,0010) VERS="GEM"  VR="SQ"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,001b) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0030) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0040) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0050) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0060) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0070) VERS="GEM"  VR="LO"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+
+(0037,0071) VERS="GEM"  VR="FD"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0072) VERS="GEM"  VR="SH"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0073) VERS="GEM"  VR="FD"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0078) VERS="GEM"  VR="FD"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0090) VERS="GEM"  VR="IS"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+(0037,0092) VERS="GEM"  VR="DS"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+
+(0041,0001) VERS="GEM"  VR="UT"   VM="1"        Owner="QUASAR_INTERNAL_USE" 		Keyword="?" 				Name="?" 
+
+(0027,0011) VERS="GEM"  VR="DS"   VM="1"        Owner="APEX_PRIVATE"				Keyword="BedPosition" 				Name="Bed Position"
+
+(0033,0008) VERS="GEM"  VR="CS"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0010) VERS="GEM"  VR="SL"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0011) VERS="GEM"  VR="LO"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0016) VERS="GEM"  VR="UI"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+(0033,0017) VERS="GEM"  VR="DA"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0018) VERS="GEM"  VR="TM"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0019) VERS="GEM"  VR="UL"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,001a) VERS="GEM"  VR="LO"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,001b) VERS="GEM"  VR="LO"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,001c) VERS="GEM"  VR="OB"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+(0033,001d) VERS="GEM"  VR="UL"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,001e) VERS="GEM"  VR="FD"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,001f) VERS="GEM"  VR="OB"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0020) VERS="GEM"  VR="OB"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0021) VERS="GEM"  VR="OB"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0022) VERS="GEM"  VR="OB"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+(0033,0023) VERS="GEM"  VR="OB"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+(0033,0024) VERS="GEM"  VR="LT"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+(0033,0070) VERS="GEM"  VR="SQ"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+(0033,0071) VERS="GEM"  VR="UI"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?" 
+(0033,0072) VERS="GEM"  VR="UI"   VM="1"        Owner="GEMS_XELPRV_01" 		Keyword="?" 				Name="?"
+
+(0039,0095) VERS="GEM"  VR="LO"   VM="1"        Owner="REPORT_FROM_APP" 		Keyword="?" 				Name="?"
+
+(0047,0011) VERS="GEM"  VR="LT"   VM="1"        Owner="GEMS_VXTL_USERDATA_01" 		Keyword="?" 				Name="?"
+
+(0015,008f) VERS="GEM"  VR="IS"   VM="1"		Owner="DL_INTERNAL_USE" 	Keyword="?" 	Name="?"
+
+(7003,0001) VERS="GEM"  VR="ST"   VM="1"		Owner="GEMS_LUNAR_RAW" 	Keyword="enCOREFileName"			Name="enCORE File Name"
+(7003,0002) VERS="GEM"  VR="OB"   VM="1"		Owner="GEMS_LUNAR_RAW" 	Keyword="enCOREFileData"			Name="enCORE File Data"
+(7003,0003) VERS="GEM"  VR="UL"   VM="1"		Owner="GEMS_LUNAR_RAW" 	Keyword="enCOREFileLength"			Name="enCORE File Length"
+(7003,0004) VERS="GEM"  VR="LO"   VM="1"		Owner="GEMS_LUNAR_RAW" 	Keyword="enCOREFileModifiedTime" 	Name="enCORE File Modified Time"
+
+(0053,0020) VERS="GEM"  VR="IS"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="ShuttleFlag"						Name="Shuttle Flag"
+(0053,0020) VERS="GEM"  VR="IS"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="TableSpeedNotReachesTargetFlag" 	Name="Table Speed Not Reaches Target Flag"
+(0053,0040) VERS="GEM"  VR="SH"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="IterativeReconAnnotation"			Name="Iterative Recon Annotation"
+(0053,0041) VERS="GEM"  VR="SH"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="IterativeReconMode"				Name="Iterative Recon Mode"
+(0053,0042) VERS="GEM"  VR="LO"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="IterativeReconConfiguration"		Name="Iterative Recon Configuration"
+(0053,0043) VERS="GEM"  VR="SH"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="IterativeReconLevel"				Name="Iterative Recon Level"
+(0053,0060) VERS="GEM"  VR="SH"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="ReconFlipRotateAnno"				Name="Recon Flip RotateA nno"
+(0053,0061) VERS="GEM"  VR="SH"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="HighResolutionFlag"				Name="High Resolution Flag"
+(0053,0062) VERS="GEM"  VR="SH"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="RespiratoryFlag"					Name="Respiratory Flag"
+(0053,009D) VERS="GEM"  VR="LO"   VM="1"		Owner="GEHC_CT_ADVAPP_001" 	Keyword="?"									Name="?"
+
+(6005,0010) VERS="GEM"  VR="UT"   VM="1"		Owner="GE_GROUP" 	Keyword="?" 	Name="?"
+
+(0039,0095) VERS="GEM"  VR="LO"   VM="1"		Owner="GEMS_0039" 	Keyword="?" 	Name="?"
+
+(0087,0010) VERS="GEM"  VR="CS"   VM="1"		Owner="1.2.840.113708.794.1.1.2.0" 	Keyword="MediaType"				Name="Media Type"
+(0087,0020) VERS="GEM"  VR="CS"   VM="1"		Owner="1.2.840.113708.794.1.1.2.0" 	Keyword="MediaLocation"			Name="Media Location"
+(0087,0030) VERS="GEM"  VR="ST"   VM="1"		Owner="1.2.840.113708.794.1.1.2.0" 	Keyword="StorageFileID"			Name="Storage File ID"
+(0087,0040) VERS="GEM"  VR="DS"   VM="1"		Owner="1.2.840.113708.794.1.1.2.0" 	Keyword="StudyOrImageSizeInMB" 	Name="Study or Image Size in MB"
+(0087,0050) VERS="GEM"  VR="IS"   VM="1"		Owner="1.2.840.113708.794.1.1.2.0" 	Keyword="EstimatedRetrieveTime" Name="Estimated Retrieve Time"
+
+(0045,0111) VERS="GEM"  VR="OW"   VM="1"		Owner="GEMS_IT_US_REPORT" 	Keyword="VividExcelFile" 	Name="Vivid excel file"
+(0045,0112) VERS="GEM"  VR="OW"   VM="1"		Owner="GEMS_IT_US_REPORT" 	Keyword="VividCHMFile"		Name="Vivid CHM file"
+(0045,0113) VERS="GEM"  VR="OW"   VM="1"		Owner="GEMS_IT_US_REPORT" 	Keyword="VividPDFFile"		Name="Vivid PDF file"
+
+(3113,0001) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="OrderControl"								Name="Order Control"
+(3113,0010) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="ScheduledActionItemCodeValue"				Name="Scheduled Action Item Code Value"
+(3113,0011) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="ScheduledActionItemCodingSchemeDesignator"	Name="Scheduled Action Item Coding Scheme Designator"
+(3113,0012) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="ScheduledActionItemCodeMeaning"			Name="Scheduled Action Item Code Meaning"
+(3113,0015) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="RequestedActionItemCodeValue"				Name="Requested Action Item Code Value"
+(3113,0016) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="RequestedActionItemCodingSchemeDesignator"	Name="Requested Action Item Coding Scheme Designator"
+(3113,0017) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="RequestedActionItemCodeMeaning"			Name="Requested Action Item Code Meaning"
+(3113,0020) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="PerformedActionItemCodeValue"				Name="Performed Action Item Code Value"
+(3113,0021) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="PerformedActionItemCodingSchemeDesignator"	Name="Performed Action Item Coding Scheme Designator"
+(3113,0022) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="PerformedActionItemCodeMeaning"			Name="Performed Action Item Code Meaning"
+(3113,0025) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="PerformedProcedureCodeValue"				Name="Performed Procedure Code Value"
+(3113,0026) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="PerformedProcedureCodingSchemeDesignator"	Name="Performed Procedure Coding Scheme Designator"
+(3113,0027) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="PerformedProcedureCodeMeaning"				Name="Performed Procedure Code Meaning"
+(3113,0030) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="ReferencedImageSOPClassUID"				Name="Referenced Image SOP Class UID"
+(3113,0031) VERS="GEM"	VR="UI"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="ReferencedImageSOPInstanceUID"				Name="Referenced Image SOP Instance UID"
+(3113,00E0) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="LockedByHostname"							Name="Locked By Hostname"
+(3113,00E1) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="LockedByUser"								Name="Locked By User"
+(3113,00E2) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/Workflow/Version 1.0"	Keyword="KfEditLockUser"							Name="KfEdit Lock User"
+
+(0045,0067) VERS="GEM"  VR="DS"   VM="1"	Owner="GE LUT Asymmetry Parameter"	Keyword="LUTAssymetry" 	Name="LUT Assymetry"
+
+(4109,0001) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Centricity Radiology Web/Version 1.0"	Keyword="MammographyLaterality"		Name="Mammography Laterality"
+(4109,0002) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Centricity Radiology Web/Version 1.0"	Keyword="MammographyViewName"		Name="Mammography View Name"
+(4109,0003) VERS="GEM"	VR="SH"   VM="1"	Owner="Applicare/Centricity Radiology Web/Version 1.0"	Keyword="MammographyViewModifier"	Name="Mammography View Modifier"
+
+(4111,0001) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/Centricity Radiology Web/Version 2.0"	Keyword="Secondary pineLabel"					Name="Secondary Spine Label"
+(4111,0002) VERS="GEM"	VR="IS"   VM="1"	Owner="Applicare/Centricity Radiology Web/Version 2.0"	Keyword="AdditionalTagsForPresentationState"	Name="Additional tags for Presentation State"
+
+(4113,0010) VERS="GEM"	VR="UI"   VM="1"	Owner="GEMS-IT/Centricity RA600/7.0"	Keyword="NumberOfImagesInStudy"			Name="Number of images in study"
+
+(3111,0001) VERS="GEM"	VR="UL"   VM="1"	Owner="AMI StudyExtensions_01"	Keyword="Last Released Annot Label"			Name="Last Released Annot Label"
+
+(3111,0002) VERS="GEM"	VR="CS"   VM="1"	Owner="RadWorksTBR"	Keyword="Compression Type"			Name="Compression Type"
+(3111,00FF) VERS="GEM"	VR="SQ"   VM="1"	Owner="RadWorksTBR"	Keyword="QueryResult"			Name="Query Result"
+
+(3113,0001) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0002) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Id1"					Name="Internal Id of Study"
+(3113,0003) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Id2"					Name="Internal Id of Series"
+(3113,0004) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Id3"					Name="Internal Id of Instance"
+(3113,0011) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0012) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="InstanceState"			Name="Instance State"
+(3113,0013) VERS="GEM"	VR="DT"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="DateLastModified"		Name="Date Last Modified"
+(3113,0014) VERS="GEM"	VR="DT"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="DateLastAccessed"		Name="Date Last Accessed"
+(3113,0015) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0016) VERS="GEM"	VR="FD"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="InstanceSizeInBytes"	Name="Instance Size in Bytes"
+(3113,0017) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="LibraryId"				Name="Library Id"
+(3113,0018) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Pathnames"				Name="Pathnames"
+(3113,0019) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="DriverPath"			Name="Driver Path"
+(3113,001A) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Source"				Name="Source"
+(3113,001B) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Destination"			Name="Destination"
+(3113,001C) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="MediumId"				Name="Medium Id"
+(3113,001D) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="ArchiveId"				Name="Archive Id"
+(3113,001E) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="InstanceOrigin"		Name="Instance Origin"
+(3113,0021) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="InstanceVersion"		Name="Instance Version"
+(3113,0022) VERS="GEM"	VR="SL"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0023) VERS="GEM"	VR="ST"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="InstanceFileLocation"	Name="Instance File Location"
+(3113,0031) VERS="GEM"	VR="IS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0032) VERS="GEM"	VR="IS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0033) VERS="GEM"	VR="IS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="?"						Name="?"
+(3113,0035) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="ImageMediumLocation"	Name="Image Medium Location"
+(3113,0036) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="ImageMediumLabel"		Name="Image Medium Label"
+(3113,0037) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="ImageMediumState"		Name="Image Medium State"
+(3113,0038) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="SeriesMediumLocation"	Name="Series Medium Location"
+(3113,0039) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="SeriesMediumLabel"		Name="Series Medium Label"
+(3113,003A) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="SeriesMediumState"		Name="Series Medium State"
+(3113,003B) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="StudyMediumLocation"	Name="Study Medium Location"
+(3113,003C) VERS="GEM"	VR="LO"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="StudyMediumLabel"		Name="Study Medium Label"
+(3113,003D) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="StudyMediumState"		Name="Study Medium State"
+(3113,0052) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="StudyState"			Name="Study State"
+(3113,0053) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="SeriesState"			Name="Series State"
+(3113,0055) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="ImageStateText"		Name="Image State Text"
+(3113,0056) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="SeriesStateText"		Name="Series State Text"
+(3113,0057) VERS="GEM"	VR="CS"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="StudyStateText"		Name="Study State Text"
+(3113,0060) VERS="GEM"	VR="DT"   VM="1"	Owner="Applicare/RadStore/Version 1.0"	Keyword="Expiration"			Name="Expiration"
+(3113,0069) VERS="GEM"	VR="AT"   VM="1-n"	Owner="Applicare/RadStore/Version 1.0"	Keyword="DeletedTags"			Name="Deleted Tags"
+
+(3115,0001) VERS="GEM"	VR="UT"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/rad_pacs/"	Keyword="Reference to pacs study"			Name="Reference to pacs study"
+(3115,0002) VERS="GEM"	VR="UT"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/rad_pacs/"	Keyword="Reference to pacs image"			Name="Reference to pacs image"
+(3115,0003) VERS="GEM"	VR="CS"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/rad_pacs/"	Keyword="Pacs examnotes flag"			Name="Pacs examnotes flag"
+
+(3117,0010) VERS="GEM"	VR="DT"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/orthoview/2.1"	Keyword="OrthoView Session Date/Time"			Name="OrthoView Session Date/Time"
+(3117,0020) VERS="GEM"	VR="PN"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/orthoview/2.1"	Keyword="OrthoView Session Creator"			Name="OrthoView Session Creator"
+(3117,0030) VERS="GEM"	VR="CS"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/orthoview/2.1"	Keyword="OrthoView Session Completion Flag"			Name="OrthoView Session Completion Flag"
+(3117,0040) VERS="GEM"	VR="SQ"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/orthoview/2.1"	Keyword="OrthoView File Sequence"			Name="OrthoView File Sequence"
+(3117,0050) VERS="GEM"	VR="ST"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/orthoview/2.1"	Keyword="OrthoView File Name"			Name="OrthoView File Name"
+(3117,0060) VERS="GEM"	VR="OB"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/orthoview/2.1"	Keyword="OrthoView File Content"			Name="OrthoView File Content"
+
+(3118,0010) VERS="GEM"	VR="DT"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/bamwallthickness/1.0"	Keyword="BAM WallThickness Session Date/Time"			Name="BAM WallThickness Session Date/Time"
+(3118,0020) VERS="GEM"	VR="PN"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/bamwallthickness/1.0"	Keyword="BAM WallThickness Session Creator"			Name="BAM WallThickness Session Creator"
+(3118,0030) VERS="GEM"	VR="CS"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/bamwallthickness/1.0"	Keyword="BAM WallThickness Session Completion Flag"			Name="BAM WallThickness Session Completion Flag"
+(3118,0040) VERS="GEM"	VR="SQ"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/bamwallthickness/1.0"	Keyword="BAM WallThickness File Sequence"			Name="BAM WallThickness File Sequence"
+(3118,0050) VERS="GEM"	VR="ST"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/bamwallthickness/1.0"	Keyword="BAM WallThickness File Name"			Name="BAM WallThickness File Name"
+(3118,0060) VERS="GEM"	VR="OB"   VM="1"	Owner="http://www.gemedicalsystems.com/it_solutions/bamwallthickness/1.0"	Keyword="BAM WallThickness File Content"			Name="BAM WallThickness File Content"
+
+(3109,0010) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="WindowInvert"					Name="Window Invert"
+(3109,0020) VERS="GEM"	VR="IS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="WindowCenter"					Name="Window Center"
+(3109,0030) VERS="GEM"	VR="IS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="WindowWidth"					Name="Window Width"
+(3109,0040) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="PixelAspectRatioSwap"			Name="Pixel Aspect Ratio Swap"
+(3109,0050) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="EnableAveraging"				Name="Enable Averaging"
+(3109,0060) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="Quality"						Name="Quality"
+(3109,0070) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="ViewportAnnotationLevel"		Name="Viewport Annotation Level"
+(3109,0080) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="ShowImageAnnotation"			Name="Show Image Annotation"
+(3109,0090) VERS="GEM"	VR="CS"   VM="1"	Owner="AMI ImageContext_01"	Keyword="Show mageOverlay"				Name="Show Image Overlay"
+
+(0051,0001) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="GroupName"						Name="Group Name"
+(0051,0002) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="FunctionName"					Name="Function Name"
+(0051,0003) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="Bias"							Name="Bias"
+(0051,0004) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="Scale"							Name="Scale"
+(0051,0005) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="ParameterCount"				Name="Parameter Count"
+(0051,0006) VERS="GEM"	VR="LT"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="Parameters"					Name="Parameters"
+(0051,0007) VERS="GEM"	VR="LO"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="Version"						Name="Version"
+(0051,0008) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="ColorRampIndex"				Name="Color Ramp Index"
+(0051,0009) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="WindowWidth"					Name="Window Width"
+(0051,000a) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="WindowLevel"					Name="Window Level"
+(0051,000b) VERS="GEM"	VR="FL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="BValue"						Name="B-Value"
+(0051,000c) VERS="GEM"	VR="SL"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="WizardStateDataSize"			Name="Wizard State Data Size"		# in MRI, this has been used as VR LO Analysis Package :(
+(0051,000d) VERS="GEM"	VR="OB"   VM="1"	Owner="GEMS_FUNCTOOL_01"	Keyword="WizardState"					Name="Wizard State"
+
+
diff --git a/libsrc/standard/elmdict/hitachi.tpl b/libsrc/standard/elmdict/hitachi.tpl
new file mode 100755
index 0000000..3faa80a
--- /dev/null
+++ b/libsrc/standard/elmdict/hitachi.tpl
@@ -0,0 +1,211 @@
+(0019,0000) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0001) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0002) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0003) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0004) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0005) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0006) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0007) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0008) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0009) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,000a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,000b) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,000c) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,000d) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,000e) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,000f) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0010) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0011) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0012) VERS="HIT"  VR="TM"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0013) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0014) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0015) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0016) VERS="HIT"  VR="IS"   VM="1-n"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0017) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0018) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0019) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,001a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,001b) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,001c) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,001d) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,001e) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,001f) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0020) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0024) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0025) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0026) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0029) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,002a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,002b) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,002d) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,002e) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,002f) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0030) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0031) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0032) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0033) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0034) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0035) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0036) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0037) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0038) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0039) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,003a) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,003b) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,003c) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,003d) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,003e) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,003f) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0040) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0041) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0042) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0043) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0044) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0045) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0046) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0047) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0048) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0049) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,004a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,004b) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,004c) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,004e) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,004f) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0050) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0051) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0052) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0054) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0055) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0056) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0057) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0058) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0059) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,005a) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,005b) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,005c) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,005d) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,005f) VERS="HIT"  VR="UI"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0060) VERS="HIT"  VR="UI"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0063) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0064) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0065) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0066) VERS="HIT"  VR="DS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0067) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0068) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0069) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,006a) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,006b) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0070) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0071) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0072) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0073) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0074) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0075) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0078) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0079) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,007a) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,007b) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,007c) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,007d) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,007e) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,007f) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0080) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0081) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0082) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+(0019,0083) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0"	Keyword="?"	Name="?"
+
+(0019,0000) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0001) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0002) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0003) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0004) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0005) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0006) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0007) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0008) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0009) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,000a) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,006a) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,006c) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,006d) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,006e) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0074) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0076) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0078) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0079) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,007a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0080) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0081) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0082) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0083) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0084) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+(0019,0091) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C2"	Keyword="?"	Name="?"
+
+(0019,0000) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0003) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0007) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,000b) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0050) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0051) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0052) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0053) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,005a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,005b) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,005c) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,005f) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0078) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0079) VERS="HIT"  VR="PN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,007a) VERS="HIT"  VR="PN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,007b) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,007c) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,007d) VERS="HIT"  VR="CS"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,007e) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,007f) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0080) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0083) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0094) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0095) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0096) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0097) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,0098) VERS="HIT"  VR="IS"   VM="1-n"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00e4) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00e5) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00e6) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00e7) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00e8) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00e9) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00ea) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00eb) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00ec) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00ed) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00ee) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00ef) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00f0) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00f1) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+(0019,00f2) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R1.0 C3"	Keyword="?"	Name="?"
+
+(0019,0079) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,007c) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,007d) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0081) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0082) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0083) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0084) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0085) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0086) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0087) VERS="HIT"  VR="UN"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0088) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0089) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,008a) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,008c) VERS="HIT"  VR="IS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,008d) VERS="HIT"  VR="DS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,008f) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0090) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0091) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0092) VERS="HIT"  VR="US"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0093) VERS="HIT"  VR="DS"   VM="2"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0094) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0095) VERS="HIT"  VR="LO"   VM="1-n"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0096) VERS="HIT"  VR="DS"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0097) VERS="HIT"  VR="IS"   VM="2"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
+(0019,0099) VERS="HIT"  VR="LO"   VM="1"	Owner="Harmony R2.0"	Keyword="?"	Name="?"
diff --git a/libsrc/standard/elmdict/isg.tpl b/libsrc/standard/elmdict/isg.tpl
new file mode 100755
index 0000000..4abf2b6
--- /dev/null
+++ b/libsrc/standard/elmdict/isg.tpl
@@ -0,0 +1,127 @@
+(0029,0070) VERS="ISG"	VR="IS"   VM="1"	Owner="ISG shadow"	Keyword="?"						Name="?"
+(0029,0080) VERS="ISG"	VR="IS"   VM="1"	Owner="ISG shadow"	Keyword="?"						Name="?"
+(0029,0090) VERS="ISG"	VR="IS"   VM="1"	Owner="ISG shadow"	Keyword="?"						Name="?"
+
+(0029,0013) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0014) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0017) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0018) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0019) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,001a) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,001b) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,001c) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,001d) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,001e) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0021) VERS="ISG"	VR="US"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0022) VERS="ISG"	VR="US"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0023) VERS="ISG"	VR="US"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0024) VERS="ISG"	VR="US"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0025) VERS="ISG"	VR="US"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0027) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0028) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0029) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0030) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0031) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0046) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0047) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0052) VERS="ISG"	VR="US"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0053) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0054) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0055) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0056) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0057) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0073) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0074) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0077) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0078) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0088) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0089) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0090) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+(0029,0091) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette V1.0"	Keyword="?"						Name="?"
+
+(0029,0000) VERS="ISG"	VR="UI"   VM="1"	Owner="Silhouette Graphics Export V1.0"	Keyword="?"				Name="?"
+
+(0029,0011) VERS="ISG"	VR="IS"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineName"				Name="Line Name"
+(0029,0012) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineNameFont"				Name="Line Name Font"
+(0029,0013) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineNameDisplay"			Name="Line Name Display"
+(0029,0014) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineNormalColor"			Name="Line Normal Color"
+(0029,0015) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineType"				Name="Line Type"
+(0029,0016) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineThickness"				Name="Line Thickness"
+(0029,0017) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineStyle"				Name="Line Style"
+(0029,0018) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineDashLength"			Name="Line Dash Length"
+(0029,0019) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineInteractivity"			Name="Line Interactivity"
+(0029,0020) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineMeasurementColor"			Name="Line Measurement Color"
+(0029,0021) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineMeasurementFont"			Name="Line Measurement Font"
+(0029,0022) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineMeasurementDashLength"		Name="Line Measurement Dash Length"
+(0029,0023) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LinePointSpace"			Name="Line Point Space"
+(0029,0024) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LinePoints"				Name="Line Points"
+(0029,0025) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineControlPointSize"			Name="Line Control Point Size"
+(0029,0026) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineControlPointSpace"			Name="Line Control Point Space"
+(0029,0027) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineControlPoints"			Name="Line Control Points"
+(0029,0028) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineLabel"				Name="Line Label"
+(0029,0029) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Line V1.0"	Keyword="LineDontSave"				Name="Line Don't Save"
+
+(0029,0041) VERS="ISG"	VR="SQ"   VM="1"	Owner="Silhouette Sequence Ids V1.0"	Keyword="?"				Name="?"
+(0029,0042) VERS="ISG"	VR="SQ"   VM="1"	Owner="Silhouette Sequence Ids V1.0"	Keyword="?"				Name="?"
+(0029,0043) VERS="ISG"	VR="SQ"   VM="1"	Owner="Silhouette Sequence Ids V1.0"	Keyword="?"				Name="?"
+
+(0029,0011) VERS="ISG"	VR="IS"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationName"			Name="Annotation Name"
+(0029,0012) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationFont"			Name="Annotation Font"
+(0029,0013) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextForegroundColor"		Name="Annotation Text Foreground Color"
+(0029,0014) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextBackgroundColor"		Name="Annotation Text Background Color"
+(0029,0015) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextBackingMode"		Name="Annotation Text Backing Mode"
+(0029,0016) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextJustification"		Name="Annotation Text Justification"
+(0029,0017) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextLocation"		Name="Annotation Text Location"
+(0029,0018) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextString"			Name="Annotation Text String"
+(0029,0019) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextAttachMode"		Name="Annotation Text Attach Mode"
+(0029,0020) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextCursorMode"		Name="Annotation Text Cursor Mode"
+(0029,0021) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextShadowOffsetX"		Name="Annotation Text Shadow Offset X"
+(0029,0022) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationTextShadowOffsetY"		Name="Annotation Text Shadow Offset Y"
+(0029,0023) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineColor"			Name="Annotation Line Color"
+(0029,0024) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineThickness"		Name="Annotation Line Thickness"
+(0029,0025) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineType"			Name="Annotation Line Type"
+(0029,0026) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineStyle"			Name="Annotation Line Style"
+(0029,0027) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineDashLength"		Name="Annotation Line Dash Length"
+(0029,0028) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineAttachMode"		Name="Annotation Line Attach Mode"
+(0029,0029) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLinePointCount"		Name="Annotation Line Point Count"
+(0029,0030) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLinePoints"			Name="Annotation Line Points"
+(0029,0031) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationLineControlSize"		Name="Annotation Line Control Size"
+(0029,0032) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationMarkerColor"			Name="Annotation Marker Color"
+(0029,0033) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationMarkerType"			Name="Annotation Marker Type"
+(0029,0034) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationMarkerSize"			Name="Annotation Marker Size"
+(0029,0035) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationMarkerLocation"		Name="Annotation Marker Location"
+(0029,0036) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationMarkerAttachMode"		Name="Annotation Marker Attach Mode"
+(0029,0037) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationGeomColor"			Name="Annotation Geom Color"
+(0029,0038) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationGeomThickness"		Name="Annotation Geom Thickness"
+(0029,0039) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationGeomLineStyle"		Name="Annotation Geom Line Style"
+(0029,0040) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationGeomDashLength"		Name="Annotation Geom Dash Length"
+(0029,0041) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationGeomFillPattern"		Name="Annotation Geom Fill Pattern"
+(0029,0042) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationInteractivity"		Name="Annotation Interactivity"
+(0029,0043) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationArrowLength"			Name="Annotation Arrow Length"
+(0029,0044) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationArrowAngle"			Name="Annotation Arrow Angle"
+(0029,0045) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette Annot V1.0"	Keyword="AnnotationDontSave"			Name="Annotation Don't Save"
+
+(0029,0011) VERS="ISG"	VR="IS"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIName"				Name="ROI Name"
+(0029,0012) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROINameFont"				Name="ROI Name Font"
+(0029,0013) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROINormalColor"			Name="ROI Normal Color"
+(0029,0014) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIFillPattern"			Name="ROI Fill Pattern"
+(0029,0015) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIBpSeg"				Name="ROI Bp Seg"
+(0029,0016) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIBpSegPairs"				Name="ROI Bp Seg Pairs"
+(0029,0017) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROISeedSpace"				Name="ROI Seed Space"
+(0029,0018) VERS="ISG"	VR="UN"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROISeeds"				Name="ROI Seeds"
+(0029,0019) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROILineThickness"			Name="ROI Line Thickness"
+(0029,0020) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROILineStyle"				Name="ROI Line Style"
+(0029,0021) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROILineDashLength"			Name="ROI Line Dash Length"
+(0029,0022) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIInteractivity"			Name="ROI Interactivity"
+(0029,0023) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROINamePosition"			Name="ROI Name Position"
+(0029,0024) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROINameDisplay"			Name="ROI Name Display"
+(0029,0025) VERS="ISG"	VR="LT"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROILabel"				Name="ROI Label"
+(0029,0026) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShape"				Name="ROI Shape"
+(0029,0027) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapeTilt"				Name="ROI Shape Tilt"
+(0029,0028) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapePointsCount"			Name="ROI Shape Points Count"
+(0029,0029) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapePointsSpace"			Name="ROI Shape Points Space"
+(0029,0030) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapePoints"			Name="ROI Shape Points"
+(0029,0031) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapeControlPointsCount"		Name="ROI Shape Control Points Count"
+(0029,0032) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapeControlPointsSpace"		Name="ROI Shape Control Points Space"
+(0029,0033) VERS="ISG"	VR="FD"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIShapeControlPoints"			Name="ROI Shape Control Points"
+(0029,0034) VERS="ISG"	VR="UL"   VM="1"	Owner="Silhouette ROI V1.0"	Keyword="ROIDontSave"				Name="ROI Don't Save"
diff --git a/libsrc/standard/elmdict/other.tpl b/libsrc/standard/elmdict/other.tpl
new file mode 100755
index 0000000..e3fed1c
--- /dev/null
+++ b/libsrc/standard/elmdict/other.tpl
@@ -0,0 +1,2078 @@
+(0003,0000) VERS="AEG"	VR="US"   VM="1-n"	Owner="AEGIS_DICOM_2.00"	Keyword="?"			Name="?"
+(0005,0000) VERS="AEG"	VR="US"   VM="1-n"	Owner="AEGIS_DICOM_2.00"	Keyword="?"			Name="?"
+(0009,0000) VERS="AEG"	VR="US"   VM="1-n"	Owner="AEGIS_DICOM_2.00"	Keyword="?"			Name="?"
+(0009,0000) VERS="MRG"	VR="OB"   VM="1"	Owner="MERGE TECHNOLOGIES, INC."	Keyword="?"			Name="?"
+
+(0011,0000) VERS="HOL"	VR="OB"   VM="1"	Owner="Hologic"	Keyword="HxQuestionnaire"			Name="Hx Questionnaire"	RenderAsString="true"
+(0011,0000) VERS="HOL"	VR="OB"   VM="1"	Owner="HOLOGIC"	Keyword="HxQuestionnaire"			Name="Hx Questionnaire" RenderAsString="true"
+
+(0013,0000) VERS="HOL"	VR="LO"   VM="1"	Owner="Hologic"	Keyword="IVAResultsFlag"			Name="IVA Results Flag"
+(0013,0000) VERS="HOL"	VR="LO"   VM="1"	Owner="HOLOGIC"	Keyword="IVAResultsFlag"			Name="IVA Results Flag"
+
+(0019,0000) VERS="HOL"	VR="UT"   VM="1"	Owner="Hologic"	Keyword="ReportData"				Name="Report Data"
+(0019,0000) VERS="HOL"	VR="UT"   VM="1"	Owner="HOLOGIC"	Keyword="ReportData"				Name="Report Data"
+
+(0019,0000) VERS="AEG"	VR="US"   VM="1-n"	Owner="AEGIS_DICOM_2.00"	Keyword="?"			Name="?"
+(0019,0010) VERS="DUP"	VR="ST"   VM="1"	Owner="1.2.840.113681"	Keyword="CRImageParamsCommon"			Name="CR Image Params Common"
+(0019,0011) VERS="DUP"	VR="ST"   VM="1"	Owner="1.2.840.113681"	Keyword="CRImageIPParamsSingle"			Name="CR Image IP Params Single"
+(0019,0012) VERS="DUP"	VR="ST"   VM="1"	Owner="1.2.840.113681"	Keyword="CRImageIPParamsLeft"			Name="CR Image IP Params Left"
+(0019,0013) VERS="DUP"	VR="ST"   VM="1"	Owner="1.2.840.113681"	Keyword="CRImageIPParamsRight"			Name="CR Image IP Params Right"
+(0019,0001) VERS="LDX"  VR="IS"   VM="1-n"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0019,0002) VERS="LDX"  VR="IS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?"
+(0019,0003) VERS="LDX"  VR="DS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0019,0004) VERS="LDX"  VR="DS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0019,0005) VERS="LDX"  VR="DS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0019,0006) VERS="LDX"  VR="DS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0019,0007) VERS="LDX"  VR="DS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0019,0008) VERS="LDX"  VR="DS"   VM="1"	Owner="LODOX_STATSCAN"	Keyword="?"			Name="?" 
+(0021,0001) VERS="SCH"	VR="UI"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change List Creator ID"	Keyword="?"			Name="?"
+(0021,0002) VERS="SCH"	VR="SQ"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change List Creator ID"	Keyword="?"			Name="?"
+(0021,0001) VERS="SCH"	VR="UI"   VM="1"	Owner="SCHICK TECHNOLOGIES - Note List Creator ID"	Keyword="?"			Name="?"
+(0021,0002) VERS="SCH"	VR="SQ"   VM="1"	Owner="SCHICK TECHNOLOGIES - Note List Creator ID"	Keyword="?"			Name="?"
+(0021,0001) VERS="SCH"	VR="UI"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change Item Creator ID"	Keyword="?"			Name="?"
+(0021,0002) VERS="SCH"	VR="US"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change Item Creator ID"	Keyword="?"			Name="?" 
+(0021,0003) VERS="SCH"	VR="DT"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change Item Creator ID"	Keyword="?"			Name="?"
+(0021,0004) VERS="SCH"	VR="PN"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change Item Creator ID"	Keyword="?"			Name="?"
+(0021,0005) VERS="SCH"	VR="OB"   VM="1"	Owner="SCHICK TECHNOLOGIES - Change Item Creator ID"	Keyword="?"			Name="?"
+
+(0021,0001) VERS="HOL"	VR="LT"   VM="1"	Owner="Hologic"	Keyword="ImageAnalysisDataInXML"	Name="Image Analysis Data in XML"
+(0021,0001) VERS="HOL"	VR="LT"   VM="1"	Owner="HOLOGIC"	Keyword="ImageAnalysisDataInXML"	Name="Image Analysis Data in XML"
+
+(0023,0000) VERS="HOL"	VR="LO"   VM="1"	Owner="Hologic"	Keyword="EncodingSchemeVersion"		Name="Encoding Scheme Version"
+(0023,0000) VERS="HOL"	VR="LO"   VM="1"	Owner="HOLOGIC"	Keyword="EncodingSchemeVersion"		Name="Encoding Scheme Version"
+(0023,0001) VERS="HOL"	VR="LO"   VM="1"	Owner="Hologic"	Keyword="PFileName"					Name="P File Name"
+(0023,0001) VERS="HOL"	VR="LO"   VM="1"	Owner="HOLOGIC"	Keyword="PFileName"					Name="P File Name"
+(0023,0002) VERS="HOL"	VR="OB"   VM="1"	Owner="Hologic"	Keyword="PFileData"					Name="P File Data"
+(0023,0002) VERS="HOL"	VR="OB"   VM="1"	Owner="HOLOGIC"	Keyword="PFileData"					Name="P File Data"
+(0023,0003) VERS="HOL"	VR="UL"   VM="1"	Owner="Hologic"	Keyword="PFileLength"				Name="P File Length"
+(0023,0003) VERS="HOL"	VR="UL"   VM="1"	Owner="HOLOGIC"	Keyword="PFileLength"				Name="P File Length"
+(0023,0004) VERS="HOL"	VR="OB"   VM="1"	Owner="Hologic"	Keyword="RFileData"					Name="R File Data"
+(0023,0004) VERS="HOL"	VR="OB"   VM="1"	Owner="HOLOGIC"	Keyword="RFileData"					Name="R File Data"
+(0023,0005) VERS="HOL"	VR="UL"   VM="1"	Owner="Hologic"	Keyword="RFileLength"				Name="R File Length"
+(0023,0005) VERS="HOL"	VR="UL"   VM="1"	Owner="HOLOGIC"	Keyword="RFileLength"				Name="R File Length"
+
+(0029,0000) VERS="HOL"	VR="OB"   VM="1"	Owner="Hologic"	Keyword="GraphBitmapData"			Name="Graph Bitmap Data"
+(0029,0000) VERS="HOL"	VR="OB"   VM="1"	Owner="HOLOGIC"	Keyword="GraphBitmapData"			Name="Graph Bitmap Data"
+(0029,0001) VERS="HOL"	VR="UL"   VM="1"	Owner="Hologic"	Keyword="GraphBitmapSize"			Name="Graph Bitmap Size"
+(0029,0001) VERS="HOL"	VR="UL"   VM="1"	Owner="HOLOGIC"	Keyword="GraphBitmapSize"			Name="Graph Bitmap Size"
+
+(0029,0000) VERS="AEG"	VR="US"   VM="1-n"	Owner="AEGIS_DICOM_2.00"	Keyword="?"			Name="?"
+(0029,0001) VERS="SCH"	VR="UL"   VM="1"	Owner="SCHICK TECHNOLOGIES - Image Security Creator ID"	Keyword="?"			Name="?"
+(0029,0020) VERS="DEX"	VR="LT"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0021) VERS="DEX"	VR="ST"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0022) VERS="DEX"	VR="ST"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0023) VERS="DEX"	VR="ST"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0024) VERS="DEX"	VR="LO"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0025) VERS="DEX"	VR="LO"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0026) VERS="DEX"	VR="LO"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+(0029,0027) VERS="DEX"	VR="LO"   VM="1"	Owner="2.16.840.1.114059.1.1.6.1.50.1"	Keyword="?"			Name="?"
+
+(0073,0001) VERS="STE"  VR="ST"   VM="1"	Owner="STENTOR"	Keyword="?"			Name="?" 
+(0073,0002) VERS="STE"  VR="ST"   VM="1"	Owner="STENTOR"	Keyword="?"			Name="?" 
+(0073,0003) VERS="STE"  VR="ST"   VM="1"	Owner="STENTOR"	Keyword="?"			Name="?" 
+(0073,0004) VERS="STE"  VR="ST"   VM="1"	Owner="STENTOR"	Keyword="?"			Name="?" 
+(0073,0006) VERS="STE"  VR="LO"   VM="1"	Owner="STENTOR"	Keyword="?"			Name="?" 
+
+(0087,0010) VERS="ARM"  VR="CS"   VM="1"	Owner="1.2.840.113708.794.1.1.2.0"	Keyword="MediaType"		Name="Media Type"
+(0087,0020) VERS="ARM"  VR="CS"   VM="1"	Owner="1.2.840.113708.794.1.1.2.0"	Keyword="MediaLocation"		Name="Media Location"
+(0087,0050) VERS="ARM"  VR="IS"   VM="1"	Owner="1.2.840.113708.794.1.1.2.0"	Keyword="EstimatedRetrieveTime"	Name="Estimated Retrieve Time"
+(1369,0000) VERS="AEG"	VR="US"   VM="1-n"	Owner="AEGIS_DICOM_2.00"	Keyword="?"			Name="?"
+(0009,0004) VERS="FUJ"  VR="SH"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageControlUnit"						Name="Image Control Unit"
+(0009,0005) VERS="FUJ"  VR="OW"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageUID"								Name="Image UID"
+(0009,0006) VERS="FUJ"  VR="OW"   VM="1"	Owner="FDMS 1.0"	Keyword="RouteImageUID"							Name="Route Image UID"
+(0009,0008) VERS="FUJ"  VR="UL"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageDisplayInformationVersionNumber"	Name="Image Display Information Version Number"
+(0009,0009) VERS="FUJ"  VR="UL"   VM="1"	Owner="FDMS 1.0"	Keyword="PatientInformationVersionNumber"		Name="Patient Information Version Number"
+(0009,000C) VERS="FUJ"  VR="OW"   VM="1"	Owner="FDMS 1.0"	Keyword="FilmUID"								Name="Film UID"
+(0009,0010) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ExposureUnitTypeCode"					Name="Exposure Unit Type Code"
+(0009,0080) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="KanjiHospitalName"						Name="Kanji Hospital Name"
+(0009,0090) VERS="FUJ"  VR="ST"   VM="1"	Owner="FDMS 1.0"	Keyword="DistributionCode"						Name="Distribution Code"
+(0009,0092) VERS="FUJ"  VR="SH"   VM="1"	Owner="FDMS 1.0"	Keyword="KanjiDepartmentName"					Name="Kanji Department Name"
+(0009,00F0) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="BlackeningProcessFlag"					Name="Blackening Process Flag"
+(0009,00F1) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="ProcessingInformationFlag"				Name="Processing Information Flag"
+(0019,0015) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="KanjiBodyPartForExposure"				Name="Kanji Body Part for Exposure"
+(0019,0030) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="MenuCharacterString"					Name="Menu Character String"
+(0019,0032) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="KanjiMenuName"							Name="Kanji Menu Name"
+(0019,0040) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageProcessingType"					Name="Image Processing Type"
+(0019,0050) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="EDRMode"								Name="EDR Mode"
+(0019,0060) VERS="FUJ"  VR="SH"   VM="1"	Owner="FDMS 1.0"	Keyword="RadiographersCode"						Name="Radiographer's Code"
+(0019,0070) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="SplitExposureFormat"					Name="Split Exposure Format"
+(0019,0071) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="NumberOfSplitExposureFrames"			Name="Number of Split Exposure Frames"
+(0019,0080) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="ReadingPositionSpecification"			Name="Reading Position Specification"
+(0019,0081) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="ReadingSensitivityCenter"				Name="Reading Sensitivity Center"
+(0019,0090) VERS="FUJ"  VR="SH"   VM="1"	Owner="FDMS 1.0"	Keyword="FilmAnnotationCharacterString1"		Name="Film Annotation Character String 1"
+(0019,0091) VERS="FUJ"  VR="SH"   VM="1"	Owner="FDMS 1.0"	Keyword="FilmAnnotationCharacterString2"		Name="Film Annotation Character String 2"
+(0021,0010) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="FCRImageID"							Name="FCR Image ID"
+(0021,0030) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="SetNumber"								Name="Set Number"
+(0021,0040) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageNumberInTheSet"					Name="Image Number in the Set"
+(0021,0050) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="PairProcessingInformation"				Name="Pair Processing Information"
+(0021,0070) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="FilmNumberWithinTheSeries"				Name="Film Number within the Series"
+(0021,0080) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="EquipmentTypeSpecificInformation"		Name="Equipment Type-Specific Information"
+(0021,0090) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="LUTNumber"								Name="LUT Number"
+(0023,0010) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0023,0020) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0023,0030) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0010) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="RelativeLightEmissionAmountSk"			Name="Relative Light Emission Amount Sk"
+(0025,0011) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="TermOfCorrectionForEachIPTypeSt"		Name="Term of Correction for Each IP Type St"
+(0025,0012) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="ReadingGainGp"							Name="Reading Gain Gp"
+(0025,0013) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0015) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0020) VERS="FUJ"  VR="US"   VM="2"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0021) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0030) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0030) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0031) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0032) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0033) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0034) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0040) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0041) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0042) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0042) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0043) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0050) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0051) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0052) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0053) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0060) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0061) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0062) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0063) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0070) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0071) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0072) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0072) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0073) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0074) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0080) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0081) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0081) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0081) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0082) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0082) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0082) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0083) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0083) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0084) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0084) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0084) VERS="FUJ"  VR="US"   VM="6"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0090) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0091) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0092) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0093) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0094) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0095) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,0096) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a0) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a0) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a0) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a1) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a1) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a2) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a2) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a3) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0025,00a3) VERS="FUJ"  VR="SS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,0010) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0020) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0030) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0040) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0050) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0060) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0070) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,0080) VERS="FUJ"  VR="SQ"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?" 
+(0027,00a0) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a0) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a0) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a0) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a0) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a0) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a1) VERS="FUJ"  VR="CS"   VM="2"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a1) VERS="FUJ"  VR="CS"   VM="2"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a2) VERS="FUJ"  VR="CS"   VM="2"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a2) VERS="FUJ"  VR="CS"   VM="2"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a2) VERS="FUJ"  VR="CS"   VM="2"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0027,00a3) VERS="FUJ"  VR="SS"   VM="1-n"	Owner="FDMS 1.0"	Keyword="?"										Name="?"
+(0029,0020) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageScanningDirection"				Name="Image Scanning Direction"
+(0029,0025) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageRotationReversalInformation"		Name="Image Rotation/Reversal Information"
+(0029,0030) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ExtendedReadingSizeValue"				Name="Extended Reading Size Value"
+(0029,0034) VERS="FUJ"  VR="US"   VM="1"	Owner="FDMS 1.0"	Keyword="MagReducRatio"							Name="Mag./Reduc. Ratio"
+(0029,0044) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="LineDensityCode"						Name="Line Density Code"
+(0029,0050) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="DataCompressionCode"					Name="Data Compression Code"
+(0032,0032) VERS="FUJ"  VR="PN"   VM="1"	Owner="FDMS 1.0"	Keyword="RequestingPhysician"					Name="Requesting Physician"
+(0032,0033) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="RequestingService"						Name="Requesting Service"
+(2011,0000) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="TrimDensity"							Name="Trim Density"
+(2011,0001) VERS="FUJ"  VR="IS"   VM="1"	Owner="FDMS 1.0"	Keyword="TrimWidth"								Name="Trim Width"
+(2011,0002) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageMagReducRatio"					Name="Image Mag./Reduc. Range"
+(2011,0010) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageDisplayFormat"					Name="Image Display Format"
+(2011,0011) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImagePositionSpecifyingFlag"			Name="Image Position Specifying Flag"
+(2011,0020) VERS="FUJ"  VR="OW"   VM="1"	Owner="FDMS 1.0"	Keyword="InterpolationAVRSSystemFormat"			Name="Interpolation A-VRS System Format"
+(50F1,0006) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="EnergySubtractionParameter"			Name="Energy Subtraction Parameter"
+(50F1,0007) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="SubtractionRegistrationResult"			Name="Subtraction Registration Result"
+(50F1,0008) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="EnergySubtractionParameter2"			Name="Energy Subtraction Parameter 2"
+(50F1,0009) VERS="FUJ"  VR="SL"   VM="1"	Owner="FDMS 1.0"	Keyword="AfinConversionCoefficient"				Name="Afin Conversion Coefficient"
+(50F1,000A) VERS="FUJ"  VR="LO"   VM="1"	Owner="FDMS 1.0"	Keyword="FNCParameters"							Name="FNC Parameters"
+(50F1,0010) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="FilmOutputFormat"						Name="Film Output Format"
+(50F1,0020) VERS="FUJ"  VR="CS"   VM="1"	Owner="FDMS 1.0"	Keyword="ImageProcessingModificationFlag"		Name="Image Processing Modification Flag"
+
+(0019,0010) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0013) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0015) VERS="CAN"  VR="DS"   VM="2"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0016) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0017) VERS="CAN"  VR="DS"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0018) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0019) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,001a) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,001b) VERS="CAN"  VR="LO"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,001c) VERS="CAN"  VR="IS"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,001e) VERS="CAN"  VR="IS"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,001f) VERS="CAN"  VR="UN"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+(0019,0021) VERS="CAN"  VR="IS"   VM="1"	Owner="Canon Inc."	Keyword="?"		Name="?"
+
+(0019,0002) VERS="ADAC" VR="IS"   VM="1"	Owner="ADAC_IMG"	Keyword="ADACPegasysFileSize"		Name="ADAC Pegasys File Size"
+(0019,0021) VERS="ADAC" VR="US"   VM="1"	Owner="ADAC_IMG"	Keyword="NumberOfADACHeaders"		Name="Number of ADAC Headers"
+(0019,0041) VERS="ADAC" VR="IS"   VM="1-n"	Owner="ADAC_IMG"	Keyword="ADACHeaderImageSize"		Name="ADAC Header/Image Size"
+(0019,0061) VERS="ADAC" VR="OB"   VM="1"	Owner="ADAC_IMG"	Keyword="ADACPegasysHeaders"		Name="ADAC Pegasys Headers"
+
+(0009,0001) VERS="SEC"  VR="SH"   VM="1"	Owner="SECTRA_Ident_01"			Keyword="RequestNumber"		Name="Request number"
+(0009,0002) VERS="SEC"  VR="SH"   VM="1"	Owner="SECTRA_Ident_01"			Keyword="ExaminationNumber"	Name="Examination number"
+(0009,0004) VERS="SEC"  VR="LO"   VM="1"	Owner="SECTRA_Ident_01"			Keyword="SeriesIdentifier"	Name="Series Identifier"
+(0009,0005) VERS="SEC"  VR="LO"   VM="1"	Owner="SECTRA_Ident_01"			Keyword="SeriesOrder"		Name="Series Order"
+(0009,0006) VERS="SEC"  VR="LO"   VM="1"	Owner="SECTRA_Ident_01"			Keyword="FileName"			Name="File Name"
+(0009,0007) VERS="SEC"  VR="LO"   VM="1"	Owner="SECTRA_Ident_01"			Keyword="ImageDataID"		Name="Image Data ID"
+(0029,0001) VERS="SEC"  VR="OB"   VM="1"	Owner="SECTRA_ImageInfo_01"		Keyword="ImageInfo"			Name="Image info"
+(0029,0002) VERS="SEC"  VR="CS"   VM="1"	Owner="SECTRA_ImageInfo_01"		Keyword="Marking"			Name="Marking"
+(0029,0003) VERS="SEC"  VR="LO"   VM="1"	Owner="SECTRA_ImageInfo_01"		Keyword="NoDecompression"	Name="No decompression"
+(0029,0004) VERS="SEC"  VR="OB"   VM="1"	Owner="SECTRA_ImageInfo_01"		Keyword="ImageInfoNew"		Name="Image info new"
+(6001,0001) VERS="SEC"  VR="LO"   VM="1"	Owner="SECTRA_OverlayInfo_01"	Keyword="SectraOverlay"		Name="Sectra Overlay"
+
+(0009,0000) VERS="BIO"  VR="LO"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0001) VERS="BIO"  VR="UN"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0002) VERS="BIO"  VR="UN"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0003) VERS="BIO"  VR="LO"   VM="1-n"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0004) VERS="BIO"  VR="LO"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0005) VERS="BIO"  VR="LO"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0007) VERS="BIO"  VR="LO"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0008) VERS="BIO"  VR="LO"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0009) VERS="BIO"  VR="LO"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+(0009,0010) VERS="BIO"  VR="UN"   VM="1"	Owner="BioPri"			Keyword="?"		Name="?"
+
+(0029,0013) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0014) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0017) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0018) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0019) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,001a) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,001b) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,001c) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,001d) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,001e) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0027) VERS="ISG"  VR="US"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0028) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0030) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0032) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0034) VERS="ISG"  VR="UN"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0035) VERS="ISG"  VR="CS"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+(0029,0036) VERS="ISG"  VR="US"   VM="1"	Owner="Silhouette VRS 3.0"		Keyword="?"			Name="?"
+
+(0011,0001) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedInstanceCreatorID"					Name="Encrypted Instance Creator ID"
+(0011,0002) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedSOPInstanceUID"						Name="Encrypted SOP Instance UID"
+(0011,0003) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedAccessionNumber"						Name="Encrypted Accession Number"
+(0011,0004) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedInstitutionName"						Name="Encrypted Institution Name"
+(0011,0005) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedInstitutionAddress"					Name="Encrypted Institution Address"
+(0011,0006) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedReferringPhysicianName"				Name="Encrypted Referring Physician's Name"
+(0011,0007) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedReferringPhysicianAddress"			Name="Encrypted Referring Physician's Address"
+(0011,0008) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedStationName"							Name="Encrypted Station Name"
+(0011,0009) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedStudyDescription"						Name="Encrypted Study Description"
+(0011,0010) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedSeriesDescription"					Name="Encrypted Series Description"
+(0011,0011) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedInstitutionalDepartmentName"			Name="Encrypted Institutional Department Name"
+(0011,0012) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPhysiciansOfRecord"					Name="Encrypted Physicians of Record"
+(0011,0013) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPerformingPhysicianName"				Name="Encrypted Performing Physician's Name"
+(0011,0014) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedNameOfPhysiciansReadingStudy"			Name="Encrypted Name of Physicians Reading Study"
+(0011,0015) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedOperatorName"							Name="Encrypted Operator's Name"
+(0011,0016) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedAdmittingDiagnosesDescription"		Name="Encrypted Admitting Diagnoses Description"
+(0011,0017) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedReferencedSOPInstanceUID"				Name="Encrypted Referenced SOP Instance UID"
+(0011,0018) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedDerivationDescription"				Name="Encrypted Derivation Description"
+(0011,0019) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientName"							Name="Encrypted Patient's Name"
+(0011,0020) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientID"							Name="Encrypted Patient's ID"
+(0011,0021) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientBirthDate"						Name="Encrypted Patient's Birth Date"
+(0011,0022) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientBirthTime"						Name="Encrypted Patient's Birth Time"
+(0011,0023) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientSex"							Name="Encrypted Patient's Sex"
+(0011,0024) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedOtherPatientIDs"						Name="Encrypted Other Patient IDs"
+(0011,0025) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedOtherPatientNames"					Name="Encrypted Other Patient Names"
+(0011,0026) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientAge"							Name="Encrypted Patient's Age"
+(0011,0027) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientSize"							Name="Encrypted Patient's Size"
+(0011,0028) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientWeight"						Name="Encrypted Patient's Weight"
+(0011,0029) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedMedicalRecordLocator"					Name="Encrypted Medical Record Locator"
+(0011,0030) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedEthnicGroup"							Name="Encrypted Ethnic Group"
+(0011,0031) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedOccupation"							Name="Encrypted Occupation"
+(0011,0032) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedAdditionalPatient'sHistory"			Name="Encrypted Additional Patient's History"
+(0011,0033) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedPatientComments"						Name="Encrypted Patient Comments"
+(0011,0034) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedDeviceSerialNumber"					Name="Encrypted Device Serial Number"
+(0011,0035) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedProtocolName"							Name="Encrypted Protocol Name"
+(0011,0036) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedStudyInstanceUID"						Name="Encrypted Study Instance UID"
+(0011,0037) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedSeriesInstanceUID"					Name="Encrypted Series Instance UID"
+(0011,0038) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedStudyID"								Name="Encrypted Study ID"
+(0011,0039) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedFrameOfReferenceUID"					Name="Encrypted Frame of Reference UID"
+(0011,0040) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedSynchronizationFrameOfReferenceUID"	Name="Encrypted Synchronization Frame of Reference UID"
+(0011,0041) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedImageComments"						Name="Encrypted Image Comments"
+(0011,0042) VERS="HOL"  VR="LT"   VM="1"	Owner="Hipaa Private Creator"		Keyword="EncryptedUID"									Name="Encrypted UID"
+
+(0019,0006) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="PaddleID"								Name="Paddle ID"
+(0019,0007) VERS="HOL"  VR="SH"   VM="1"	Owner="LORAD Selenia"		Keyword="PaddlePosition"						Name="Paddle Position"
+(0019,0008) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="CollimationSize"						Name="Collimation Size"
+(0019,0016) VERS="HOL"  VR="DS"   VM="1"	Owner="LORAD Selenia"		Keyword="PaddleAngle"							Name="Paddle Angle"
+(0019,0026) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="PaddleIDDescription"					Name="Paddle ID Description"
+(0019,0027) VERS="HOL"  VR="SH"   VM="1"	Owner="LORAD Selenia"		Keyword="PaddlePositionDescription"				Name="Paddle Position Description"
+(0019,0028) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="CollimationSizeDescription"			Name="Collimation Size Description"
+(0019,0029) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="AECUserDensityScaleFactorDescription"	Name="AEC User Density Scale Factor Description"
+(0019,0030) VERS="HOL"  VR="US"   VM="1"	Owner="LORAD Selenia"		Keyword="AECUserDensityScaleFactor"				Name="AEC User Density Scale Factor"
+(0019,0031) VERS="HOL"  VR="US"   VM="1"	Owner="LORAD Selenia"		Keyword="AECSystemDensityScaleFactor"			Name="AEC System Density Scale Factor"
+(0019,0032) VERS="HOL"  VR="US"   VM="1"	Owner="LORAD Selenia"		Keyword="AECCalculatedmAs"						Name="AEC Calculated mAs"
+(0019,0033) VERS="HOL"  VR="US"   VM="1"	Owner="LORAD Selenia"		Keyword="AECAutoPixel1"							Name="AEC Auto Pixel 1"
+(0019,0034) VERS="HOL"  VR="US"   VM="1"	Owner="LORAD Selenia"		Keyword="AECAutoPixel2"							Name="AEC Auto Pixel 2"
+(0019,0035) VERS="HOL"  VR="US"   VM="1"	Owner="LORAD Selenia"		Keyword="AECSensor"								Name="AEC Sensor"
+(0019,0037) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="NPTMode"								Name="NPT Mode"
+(0019,0040) VERS="HOL"  VR="DS"   VM="1"	Owner="LORAD Selenia"		Keyword="SkinEdge"								Name="Skin Edge"
+(0019,0041) VERS="HOL"  VR="DS"   VM="1"	Owner="LORAD Selenia"		Keyword="ExposureIndex"							Name="Exposure Index"
+(0019,0050) VERS="HOL"  VR="DS"   VM="1"	Owner="LORAD Selenia"		Keyword="DisplayMinimumOD"						Name="Display Minimum OD"
+(0019,0051) VERS="HOL"  VR="DS"   VM="1"	Owner="LORAD Selenia"		Keyword="DispalyMaximumOD"						Name="Dispaly Maximum OD"
+(0019,0052) VERS="HOL"  VR="IS"   VM="1"	Owner="LORAD Selenia"		Keyword="DisplayMinimumNits"					Name="Display Minimum Nits"
+(0019,0053) VERS="HOL"  VR="IS"   VM="1"	Owner="LORAD Selenia"		Keyword="DisplayMaximumNits"					Name="Display Maximum Nits"
+(0019,0060) VERS="HOL"  VR="LT"   VM="1"	Owner="LORAD Selenia"		Keyword="GeometryCalibration"					Name="Geometry Calibration"
+(0019,0070) VERS="HOL"  VR="LO"   VM="1"	Owner="LORAD Selenia"		Keyword="FrameOfReferenceID"					Name="Frame of Reference ID"
+(0019,0071) VERS="HOL"  VR="CS"   VM="1"	Owner="LORAD Selenia"		Keyword="PairedPosition"						Name="Paired Position"
+(0019,0080) VERS="HOL"  VR="SH"   VM="1"	Owner="LORAD Selenia"		Keyword="DetectorImageOffset"					Name="Detector Image Offset"
+(0019,0090) VERS="HOL"  VR="DS"   VM="1"	Owner="LORAD Selenia"		Keyword="ConventionalTomoAngle"					Name="Conventional Tomo Angle"
+
+(0019,0001) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="?"										Name="?"
+(0019,0002) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="?"										Name="?"
+(0019,0003) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="?"										Name="?"
+(0019,0004) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="?"										Name="?"
+(0019,0006) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="PaddleID"								Name="Paddle ID"
+(0019,0007) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="PaddlePosition"						Name="Paddle Position"
+(0019,0008) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CollimationSize"						Name="Collimation Size"
+(0019,0016) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="PaddleAngle"							Name="Paddle Angle"
+(0019,0025) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="?"										Name="?"
+(0019,0026) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="PaddleIDDescription"					Name="Paddle ID Description"
+(0019,0027) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="PaddlePositionDescription"				Name="Paddle Position Description"
+(0019,0028) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CollimationSizeDescription"			Name="Collimation Size Description"
+(0019,0029) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECUserDensityScaleFactorDescription"	Name="AEC User Density Scale Factor Description"
+(0019,0030) VERS="HOL"  VR="US"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECUserDensityScaleFactor"				Name="AEC User Density Scale Factor"
+(0019,0031) VERS="HOL"  VR="US"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECSystemDensityScaleFactor"			Name="AEC System Density Scale Factor"
+(0019,0032) VERS="HOL"  VR="US"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECCalculatedmAs"						Name="AEC Calculated mAs"
+(0019,0033) VERS="HOL"  VR="US"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECAutoPixel1"							Name="AEC Auto Pixel 1"
+(0019,0034) VERS="HOL"  VR="US"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECAutoPixel2"							Name="AEC Auto Pixel 2"
+(0019,0035) VERS="HOL"  VR="US"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="AECSensor"								Name="AEC Sensor"
+(0019,0037) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="NPTMode"								Name="NPT Mode"
+(0019,0040) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="SkinEdge"								Name="Skin Edge"
+(0019,0041) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ExposureIndex"							Name="Exposure Index"
+(0019,0042) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ExposureIndexTarget"					Name="Exposure Index Target"
+(0019,0043) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ShortIndexRatio"						Name="Short Index Ratio"
+(0019,0044) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ScoutkVp"								Name="Scout kVp"
+(0019,0045) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ScoutmA"								Name="Scout mA"
+(0019,0046) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ScoutmAs"								Name="Scout mAs"
+(0019,0050) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="DisplayMinimumOD"						Name="Display Minimum OD"
+(0019,0051) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="DispalyMaximumOD"						Name="Dispaly Maximum OD"
+(0019,0052) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="DisplayMinimumNits"					Name="Display Minimum Nits"
+(0019,0053) VERS="HOL"  VR="IS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="DisplayMaximumNits"					Name="Display Maximum Nits"
+(0019,0060) VERS="HOL"  VR="LT"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="GeometryCalibration"					Name="Geometry Calibration"
+(0019,0061) VERS="HOL"  VR="OB"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ThreeDIPParameters"					Name="3D IP Parameters"
+(0019,0062) VERS="HOL"  VR="LT"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="TwoDIPParameters"						Name="2D IP Parameters"
+(0019,0070) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="FrameOfReferenceID"					Name="Frame of Reference ID"
+(0019,0071) VERS="HOL"  VR="CS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="PairedPosition"						Name="Paired Position"
+(0019,0080) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="DetectorImageOffset"					Name="Detector Image Offset"
+(0019,0085) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ImageSource"							Name="Image Source"
+(0019,0087) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="MarkerText"							Name="Marker Text"
+(0019,0088) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="MarkerTechInitials"					Name="Marker Tech Initials"
+(0019,0089) VERS="HOL"  VR="DS"   VM="2"	Owner="HOLOGIC, Inc."		Keyword="MarkerLocation"						Name="Marker Location"
+(0019,008A) VERS="HOL"  VR="SQ"   VM="2"	Owner="HOLOGIC, Inc."		Keyword="MarkerSequence"						Name="Marker Sequence"
+(0019,0090) VERS="HOL"  VR="DS"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="ConventionalTomoAngle"					Name="Conventional Tomo Angle"
+(0019,0097) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="MarkersBurnedIntoImage"				Name="Markers Burned Into Image"
+(0019,0098) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="GridLineCorrection"					Name="Grid Line Correction"
+
+(7e01,0001) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CodecVersion"							Name="Codec Version"
+(7e01,0002) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CodecContentType"						Name="Codec Content Type"
+(7e01,0010) VERS="HOL"  VR="SQ"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="HighResolutionDataSeqence"				Name="High Resolution Data Sequence"
+(7e01,0011) VERS="HOL"  VR="SQ"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="LowResolutionDataSeqence"				Name="Low Resolution Data Sequence"
+(7e01,0012) VERS="HOL"  VR="OB"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CodecContent"							Name="Codec Content"
+
+(7f01,0001) VERS="HOL"  VR="LO"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CodecVersion"							Name="Codec Version"
+(7f01,0002) VERS="HOL"  VR="SH"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CodecContentType"						Name="Codec Content Type"
+(7f01,0010) VERS="HOL"  VR="SQ"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="HighResolutionDataSeqence"				Name="High Resolution Data Sequence"
+(7f01,0011) VERS="HOL"  VR="SQ"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="LowResolutionDataSeqence"				Name="Low Resolution Data Sequence"
+(7f01,0012) VERS="HOL"  VR="OB"   VM="1"	Owner="HOLOGIC, Inc."		Keyword="CodecContent"							Name="Codec Content"
+
+(0029,0000) VERS="ATL"  VR="US"   VM="1"	Owner="1.2.840.113663.1"			Keyword="?"		Name="?"
+(0029,0001) VERS="ATL"  VR="US"   VM="1"	Owner="1.2.840.113663.1"			Keyword="?"		Name="?"
+
+(0009,0001) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Technologist"									Name="Technologist"
+(0009,0002) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ScheduledStudyDateTime"						Name="Scheduled Study DateTime"
+(0009,0003) VERS="HIT"  VR="OB"   VM="1"	Owner="MMCPrivate"			Keyword="StudyAppData"									Name="Study App Data"
+(0009,0048) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ProtocolName"									Name="Protocol Name"
+(0009,004e) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_BodyPartExamined"							Name="CMS Body Part Examined"
+(0009,004f) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsProtected"									Name="Is Protected"
+(0009,0050) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_PatientPosition"							Name="CMS Patient Position"
+(0009,0051) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cmi_contrastBolusAgent"						Name="CMI Contrast Bolus Agent"
+(0009,0052) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_institutionName"							Name="CMS institution Name" 
+(0009,0053) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_institutionalDepartmentName"				Name="CMS Institutional Department Name" 
+(0009,0054) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_seriesDescription"							Name="CMS Series Description" 
+(0009,0055) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_operatorsName"								Name="CMS Operators Name" 
+(0009,0056) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_PerformingPhysiciansName"					Name="CMS Performing Physicians Name" 
+(0009,0057) VERS="HIT"  VR="ST"   VM="1"	Owner="MMCPrivate"			Keyword="Cms_institutionAddress"						Name="CMS Institution Address" 
+(0009,0058) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cmi_imageComments"								Name="CMI Image Comments" 
+(0009,0059) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Cmi_instanceCreationDateTime"					Name="CMI Instance Creation DateTime" 
+(0009,005A) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MPPSStepStatus"								Name="MPPS Step Status" 
+(0009,005B) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="FilmedCount"									Name="Filmed Count" 
+(0009,005C) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeSave"							Name="Is Allow Cascade Save" 
+(0009,005D) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeProtect"							Name="Is Allow Cascade Protect" 
+(0009,005E) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsDeleted"										Name="Is Deleted" 
+
+(0011,0001) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsRapidRegistration"							Name="Is Rapid Registration" 
+(0011,0002) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsProtected"									Name="Is Protected" 
+(0011,0003) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="FilmedCount"									Name="Filmed Count" 
+(0011,0004) VERS="HIT"  VR="OB"   VM="1"	Owner="MMCPrivate"			Keyword="ApplicationData"								Name="Application Data" 
+(0011,0005) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeSave"							Name="Is Allow Cascade Save" 
+(0011,0006) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeProtect"							Name="Is Allow Cascade Protect" 
+(0011,0007) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsDeleted"										Name="Is Deleted" 
+
+(0019,0001) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ProcType"										Name="Proc Type" 
+(0019,0002) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Plane"											Name="Plane" 
+(0019,0003) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="IsSnapShotSeries"								Name="Is Snap Shot Series" 
+(0019,0004) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="MaxFscalor"									Name="Max Fscalor" 
+(0019,0005) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="SeriesCategoryType"							Name="Series Category Type" 
+(0019,0007) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ImageContrastBolusAgent"						Name="Image Contrast Bolus Agent" 
+(0019,0008) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="ImageSliceThickness"							Name="Image Slice Thickness" 
+(0019,0009) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="ImageReconstructionDiameter"					Name="Image Reconstruction Diameter" 
+(0019,000a) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ImageEchoTime"									Name="Image Echo Time" 
+(0019,000b) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="ImageRepetitionTime"							Name="Image Repetition Time" 
+(0019,000c) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="SequenceType"									Name="Sequence Type"
+(0019,000d) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="TaskUID"										Name="Task UID" 
+(0019,000e) VERS="HIT"  VR="OB"   VM="1"	Owner="MMCPrivate"			Keyword="SeriesAppData"									Name="Series App Data" 
+(0019,000f) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="MultiSliceNumber"								Name="Multi Slice Number" 
+(0019,0010) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ImageScanTime"									Name="Image Scan Time" 
+(0019,0011) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsProtected"									Name="Is Protected" 
+(0019,0012) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="ImageIncrement"								Name="Image Increment" 
+(0019,0013) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MPPSStepStatus"								Name="MPPS Step Status" 
+(0019,0014) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="StorageCommittedCount"							Name="Storage Committed Count" 
+(0019,0015) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="ArchivedCount"									Name="Archived Count" 
+(0019,0016) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="TransferredCount"								Name="Transferred Count" 
+(0019,0017) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeSave"							Name="Is Allow Cascade Save" 
+(0019,0018) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeProtect"							Name="Is Allow Cascade Protect" 
+(0019,0019) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsDeleted"										Name="Is Deleted" 
+(0019,001A) VERS="HIT"  VR="UI"   VM="1"	Owner="MMCPrivate"			Keyword="CharacterizedImageInstanceUID"					Name="Characterized Image Instance UID" 
+(0019,001B) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="CharacterizedImageCount"						Name="Characterized Image Count" 
+(0019,001C) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="InternalWindowWidth"							Name="Internal Window Width" 
+(0019,001D) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="InternalWindowLevel"							Name="Internal Window Level" 
+(0019,001E) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?" 
+
+(0029,0001) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="SliceNumber"									Name="Slice Number" 
+(0029,0002) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="PhaseNumber"									Name="Phase Number" 
+(0029,0003) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ProcType"										Name="Proc Type" 
+(0029,0004) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="StopwatchTime"									Name="Stopwatch Time" 
+(0029,0005) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Plane"											Name="Plane" 
+(0029,0006) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ScanTime"										Name="Scan Time" 
+(0029,0008) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="DualSliceFlag"									Name="Dual Slice Flag" 
+(0029,0009) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="SSPRatio"										Name="SSP Ratio" 
+(0029,000a) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="GatingSignalSource"							Name="Gating Signal Source" 
+(0029,000b) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="Rephase"										Name="Rephase" 
+(0029,000c) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="HalfEcho"										Name="Half Echo" 
+(0029,000d) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="RectFOVRatio"									Name="Rect FOV Ratio" 
+(0029,000e) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="HalfScan"										Name="Half Scan" 
+(0029,000f) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="NumShots"										Name="Num Shots" 
+(0029,0010) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ContrastAgent"									Name="Contrast Agent" 
+(0029,0011) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="EchoAllocation"								Name="Echo Allocation" 
+(0029,0012) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="NumEchoShift"									Name="Num Echo Shift" 
+(0029,0013) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="FatSat"										Name="Fat Sat" 
+(0029,0014) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MTC"											Name="MTC" 
+(0029,0015) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="NumPreSat"										Name="Num Pre Sat" 
+(0029,0016) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="TargetVelocity"								Name="Target Velocity" 
+(0029,0017) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="VENCAxis"										Name="VENC Axis" 
+(0029,0018) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="NumVENCDirection"								Name="Num VENC Direction" 
+(0029,001c) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsScalableWindowLevel"							Name="Is Scalable Window Level" 
+(0029,001d) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ThreeDSettingLineAngle"						Name="Three D Setting Line Angle" 
+(0029,001e) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MPGTotalAxis"									Name="MPG Total Axis" 
+(0029,001f) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MPGAxisNumber"									Name="MPG Axis Number" 
+(0029,0020) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="MultiEchoNumber"								Name="Multi Echo Number" 
+(0029,0021) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviAverageGateWidth"							Name="Navi Average Gate Width" 
+(0029,0022) VERS="HIT"  VR="ST"   VM="1"	Owner="MMCPrivate"			Keyword="ShimCompensateValue"							Name="Shim Compensate Value" 
+(0029,0023) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="GCOffset"										Name="GC Offset" 
+(0029,0024) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviMaxGateWidth"								Name="Navi Max Gate Width" 
+(0029,0025) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviMinGateWidth"								Name="Navi Min Gate Width" 
+(0029,0026) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviMaxGatePosition"							Name="Navi Max Gate Position" 
+(0029,0027) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviMinGatePosition"							Name="Navi Min Gate Position" 
+(0029,0028) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="TimeDuration"									Name="Time Duration" 
+(0029,0029) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="TablePosition"									Name="Table Position" 
+(0029,002a) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviInitialGateWidth"							Name="Navi Initial Gate Width" 
+(0029,002b) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviFinalGateWidth"							Name="Navi Final Gate Width"
+(0029,002c) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviInitialGatePosition"						Name="Navi Initial Gate Position" 
+(0029,002d) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviFinalGatePosition"							Name="Navi Final Gate Position" 
+(0029,002e) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="NaviAverageGatePosition"						Name="Navi Average Gate Position" 
+(0029,002f) VERS="HIT"  VR="OB"   VM="1"	Owner="MMCPrivate"			Keyword="ImageAppData"									Name="Image App Data" 
+(0029,0030) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="DiffusionBValue"								Name="Diffusion BValue"
+(0029,0031) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="SharedFunctionalGroupsSequence"				Name="Shared Functional Groups Sequence"
+(0029,0032) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="PerFrameFunctionalGroupsSequence"				Name="Per Frame Functional Groups Sequence" 
+(0029,0033) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="LossyImageCompressionRatio"					Name="Lossy Image Compression Ratio" 
+(0029,0034) VERS="HIT"  VR="UI"   VM="1"	Owner="MMCPrivate"			Keyword="InstanceCreatorUID"							Name="Instance Creator UID" 
+(0029,0035) VERS="HIT"  VR="UI"   VM="1"	Owner="MMCPrivate"			Keyword="RelatedGeneralSOPClassUID"						Name="Related General SOPClass UID" 
+(0029,0036) VERS="HIT"  VR="UI"   VM="1"	Owner="MMCPrivate"			Keyword="OriginalSpecializedSOPClassUID"				Name="Original Specialized SOPClass UID" 
+(0029,0037) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="TimezoneOffsetFromUTC"							Name="Timezone Offset From UTC" 
+(0029,0038) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="SOPInstanceStatus"								Name="SOPInstance Status" 
+(0029,0039) VERS="HIT"  VR="DT"   VM="1"	Owner="MMCPrivate"			Keyword="SOPAuthorizationDateandTime"					Name="SOPAuthorization Dateand Time" 
+(0029,003a) VERS="HIT"  VR="LT"   VM="1"	Owner="MMCPrivate"			Keyword="SOPAuthorizationComment"						Name="SOPAuthorization Comment" 
+(0029,003b) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="AuthorizationEquipmentCertificationNumber"		Name="Authorization Equipment Certification Number" 
+(0029,003c) VERS="HIT"  VR="UL"   VM="1"	Owner="MMCPrivate"			Keyword="ConcatenationFrameOffsetNumber"				Name="Concatenation Frame Offset Number" 
+(0029,003d) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="RepresentativeFrameNumber"						Name="Representative Frame Number" 
+(0029,003e) VERS="HIT"  VR="UI"   VM="1"	Owner="MMCPrivate"			Keyword="ConcatenationUID"								Name="Concatenation UID" 
+(0029,003f) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="InConcatenationNumber"							Name="In Concatenation Number" 
+(0029,0040) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="CardiacSynchronizationTechnique"				Name="Cardiac Synchronization Technique" 
+(0029,0041) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="CardiacSignalSource"							Name="Cardiac Signal Source" 
+(0029,0042) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="CardiacRRIntervalSpecified"					Name="Cardiac RRInterval Specified"
+(0029,0043) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="CardiacBeatRejectionTechnique"					Name="Cardiac Beat Rejection Technique" 
+(0029,0044) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="LowRRValue"									Name="Low RR Value" 
+(0029,0045) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="HighRRValue"									Name="High RR Value" 
+(0029,0046) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="IntervalsAcquired"								Name="Intervals Acquired" 
+(0029,0047) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="IntervalsRejected"								Name="Intervals Rejected" 
+(0029,0048) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="RespiratoryMotionCompensationTechnique"		Name="Respiratory Motion Compensation Technique" 
+(0029,0049) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="RespiratorySignalSource"						Name="Respiratory Signal Source" 
+(0029,004a) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="BulkMotionCompensationTechnique"				Name="Bulk Motion Compensation Technique" 
+(0029,004b) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="BulkMotionSignalSource"						Name="Bulk Motion Signal Source" 
+(0029,004c) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="PixelPresentation"								Name="Pixel Presentation" 
+(0029,004d) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="VolumetricProperties"							Name="Volumetric Properties" 
+(0029,004e) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="VolumeBasedCalculationTechnique"				Name="Volume Based Calculation Technique" 
+(0029,004f) VERS="HIT"  VR="ST"   VM="1"	Owner="MMCPrivate"			Keyword="AcquisitionContextDescription"					Name="Acquisition Context Description" 
+(0029,0050) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?" 
+(0029,0051) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="LUTDescriptor"									Name="LUTDescriptor" 
+(0029,0052) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="LUTExplanation"								Name="LUTExplanation" 
+(0029,0053) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="LUTData"										Name="LUTData" 
+(0029,0054) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="PresentationLUTShape"							Name="Presentation LUT Shape" 
+(0029,0055) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="FrameAnatomySequence"							Name="Frame Anatomy Sequence" 
+(0029,0056) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="FrameLaterality"								Name="Frame Laterality" 
+(0029,0057) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="AnatomicRegionSequence"						Name="Anatomic Region Sequence" 
+(0029,0058) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="AnatomicRegionCodeValue"						Name="Anatomic Region Code Value" 
+(0029,0059) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="AnatomicRegionCodingSchemeDesignator"			Name="Anatomic Region Coding Scheme Designator"
+(0029,005a) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="AnatomicRegionCodingSchemeVersion"				Name="Anatomic Region Coding Scheme Version" 
+(0029,005b) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="AnatomicRegionCodeMeaning"						Name="Anatomic Region Code Meaning" 
+(0029,005c) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="PixelValueTransformationSequence"				Name="Pixel Value Transformation Sequence" 
+(0029,005d) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="RescaleType"									Name="Rescale Type" 
+(0029,005e) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="CardiacSynchronizationSequence"				Name="Cardiac Synchronization Sequence" 
+(0029,005f) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TriggerDelayTime"								Name="Trigger Delay Time" 
+(0029,0060) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="FrameVOILUTSequence"							Name="Frame VOILUTSequence" 
+(0029,0061) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="WindowCenterAndWidthExplanation"				Name="Window Center and Width Explanation"
+(0029,0062) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?"
+(0029,0063) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRModifierSequence"							Name="MRModifier Sequence" 
+(0029,0064) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="ParallelAcquisitionTechnique"					Name="Parallel Acquisition Technique" 
+(0029,0065) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="ParallelReductionFactorSecIn"					Name="Parallel Reduction Factor Sec In" 
+(0029,0066) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="InversionRecovery"								Name="Inversion Recovery" 
+(0029,0067) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="FlowCompensation"								Name="Flow Compensation" 
+(0029,0068) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="FlowCompensationDirection"						Name="Flow Compensation Direction" 
+(0029,0069) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="SpatialPreSaturation"							Name="Spatial PreSaturation" 
+(0029,006a) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="PartialFourier"								Name="Partial Fourier" 
+(0029,006b) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="PartialFourierDirection"						Name="Partial Fourier Direction" 
+(0029,0070) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRReceiveCoilSequence"							Name="MR Receive Coil Sequence" 
+(0029,0071) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="ReceiveCoilManufacturerName"					Name="Receive Coil Manufacturer Name" 
+(0029,0072) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="ReceiveCoilType"								Name="Receive Coil Type" 
+(0029,0073) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="QuadratureReceiveCoil"							Name="Quadrature Receive Coil" 
+(0029,0074) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MultiCoilConfiguration"						Name="Multi Coil Configuration"
+(0029,0075) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="ComplexImageComponent"							Name="Complex Image Component" 
+(0029,0076) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="PulseSequenceName"								Name="Pulse Sequence Name" 
+(0029,0077) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="EchoPulseSequence"								Name="Echo Pulse Sequence" 
+(0029,0078) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="MultipleSpinEcho"								Name="Multiple Spin Echo" 
+(0029,0079) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="MultiPlanarExcitation"							Name="Multi Planar Excitation" 
+(0029,007a) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="PhaseContrast"									Name="Phase Contrast" 
+(0029,007b) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="TimeOfFlightContrast"							Name="Time of Flight Contrast" 
+(0029,007c) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="SteadyStatePulseSequence"						Name="Steady State Pulse Sequence" 
+(0029,007d) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="EchoPlanarPulseSequence"						Name="Echo Planar Pulse Sequence" 
+(0029,007e) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="SpectrallySelectedSuppression"					Name="Spectrally Selected Suppression" 
+(0029,007f) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="OversamplingPhase"								Name="Oversampling Phase" 
+(0029,0080) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="SegmentedKSpaceTraversal"						Name="Segmented KSpace Traversal" 
+(0029,0081) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="CoverageOfKSpace"								Name="Coverage of KSpace" 
+(0029,0082) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRTimingAndRelatedParametersSequence"			Name="MR Timing and Related Parameters Sequence"
+(0029,0083) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="RFEchoTrainLength"								Name="RF Echo Train Length" 
+(0029,0084) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="GradientEchoTrainLength"						Name="Gradient Echo Train Length" 
+(0029,0085) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="GradientOutputType"							Name="Gradient Output Type" 
+(0029,0086) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="GradientOutput"								Name="Gradient Output" 
+(0029,0087) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRFOVGeometrySequence"							Name="MRFOVGeometry Sequence" 
+(0029,0088) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="MRAcquisitionFrequencyEncodingSteps"			Name="MRAcquisition Frequency Encoding Steps"
+(0029,0089) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="MRAcquisitionPhaseEncodingStepsInPlane"		Name="MRAcquisition Phase Encoding Steps In Plane" 
+(0029,008a) VERS="HIT"  VR="US"   VM="1"	Owner="MMCPrivate"			Keyword="MRAcquisitionPhaseEncodingStepsOutOfPlane"		Name="MRAcquisitionPhase Encoding Steps Out of Plane" 
+(0029,008b) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRTransmitCoilSequence"						Name="MR Transmit Coil Sequence" 
+(0029,008c) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="TransmitCoilName"								Name="Transmit Coil Name" 
+(0029,008d) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="TransmitCoilManufacturerName"					Name="Transmit Coil Manufacturer Name" 
+(0029,008e) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="TransmitCoilType"								Name="Transmit Coil Type" 
+(0029,008f) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MREchoSequence"								Name="MR Echo Sequence" 
+(0029,0090) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="EffectiveEchoTime"								Name="Effective Echo Time" 
+(0029,0091) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRMetaboliteMapSequence"						Name="MR Metabolite Map Sequence" 
+(0029,0092) VERS="HIT"  VR="ST"   VM="1"	Owner="MMCPrivate"			Keyword="MetaboliteMapDescription"						Name="Metabolite Map Description" 
+(0029,0093) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MetaboliteMapCodeSequence"						Name="Metabolite Map Code Sequence" 
+(0029,0094) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="MetaboliteMapCodeValue"						Name="Metabolite Map Code Value" 
+(0029,0095) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="MetaboliteMapCodingSchemeDesignator"			Name="Metabolite Map Coding Scheme Designator" 
+(0029,0096) VERS="HIT"  VR="SH"   VM="1"	Owner="MMCPrivate"			Keyword="MetaboliteMapCodingSchemeVersion"				Name="Metabolite Map Coding Scheme Version" 
+(0029,0097) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MetaboliteMapCodeMeaning"						Name="Metabolite Map Code Meaning" 
+(0029,0098) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRImagingModifierSequence"						Name="MR Imaging Modifier Sequence" 
+(0029,0099) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="MagnetizationTransfer"							Name="Magnetization Transfer" 
+(0029,009a) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="BloodSignalNulling"							Name="Blood Signal Nulling" 
+(0029,009b) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="Tagging"										Name="Tagging" 
+(0029,009c) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TagSpacingFirstDimension"						Name="Tag Spacing First Dimension" 
+(0029,009d) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TagSpacingSecondDimension"						Name="Tag Spacing Second Dimension" 
+(0029,009e) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TagAngleFirstAxis"								Name="Tag Angle First Axis" 
+(0029,009f) VERS="HIT"  VR="SS"   VM="1"	Owner="MMCPrivate"			Keyword="TagAngleSecondAxis"							Name="Tag Angle Second Axis" 
+(0029,00a0) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TagThickness"									Name="Tag Thickness" 
+(0029,00a1) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TaggingDelay"									Name="Tagging Delay" 
+(0029,00a2) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="TransmitterFrequency"							Name="Transmitter Frequency" 
+(0029,00a3) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="PixelBandwidth"								Name="Pixel Bandwidth" 
+(0029,00a4) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRVelocityEncodingSequence"					Name="MRVelocity Encoding Sequence" 
+(0029,00a5) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="VelocityEncodingDirection"						Name="Velocity Encoding Direction" 
+(0029,00a6) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="VelocityEncodingMinimumValue"					Name="Velocity Encoding Minimum Value" 
+(0029,00a7) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="VelocityEncodingMaximumValue"					Name="Velocity Encoding Maximum Value" 
+(0029,00a8) VERS="HIT"  VR="SQ"   VM="1"	Owner="MMCPrivate"			Keyword="MRImageFrameTypeSequence"						Name="MR Image Frame Type Sequence" 
+(0029,00a9) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="FrameType"										Name="Frame Type" 
+(0029,00aa) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="PixelPresentation"								Name="Pixel Presentation" 
+(0029,00ab) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="VolumetricProperties"							Name="Volumetric Properties" 
+(0029,00ac) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="VolumeBasedCalculationTechnique"				Name="Volume Based Calculation Technique" 
+(0029,00ad) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="FilmedCount"									Name="Filmed Count" 
+(0029,00ae) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsTransferred"									Name="Is Transferred" 
+(0029,00af) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsArchived"									Name="Is Archived" 
+(0029,00b0) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="MPPSStepStatus"								Name="MPPS Step Status" 
+(0029,00b1) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="CommitmentStatus"								Name="Commitment Status" 
+(0029,00b2) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsStorageCommitted"							Name="Is Storage Committed" 
+(0029,00b3) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsDicom"										Name="Is Dicom" 
+(0029,00b4) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeSave"							Name="Is Allow Cascade Save" 
+(0029,00b5) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeProtect"							Name="Is Allow Cascade Protect" 
+(0029,00b6) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsDeleted"										Name="Is Deleted" 
+(0029,00b7) VERS="HIT"  VR="OB"   VM="1"	Owner="MMCPrivate"			Keyword="ApplicationData"								Name="Application Data" 
+(0029,00b8) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeSave"							Name="Is Allow Cascade Save" 
+(0029,00b9) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsAllowCascadeProtect"							Name="Is Allow Cascade Protect" 
+(0029,00ba) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="IsDeleted"										Name="Is Deleted" 
+(0029,00bb) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="VOI1"											Name="VOI 1" 
+(0029,00bc) VERS="HIT"  VR="IS"   VM="1"	Owner="MMCPrivate"			Keyword="VOI2"											Name="VOI 2" 
+(0029,00bd) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="MixingTime"									Name="Mixing Time" 
+(0029,00be) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="SelectiveIRPosition"							Name="Selective IR Position" 
+(0029,00bf) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="SelectiveIRRow"								Name="Selective IR Row" 
+(0029,00c0) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="SelectiveIRColumn"								Name="Selective IR Column" 
+(0029,00c1) VERS="HIT"  VR="FD"   VM="1"	Owner="MMCPrivate"			Keyword="SelectiveIROrientation"						Name="Selective IR Orientation" 
+(0029,00c2) VERS="HIT"  VR="DS"   VM="1"	Owner="MMCPrivate"			Keyword="SelectiveIRThickness"							Name="Selective IR Thickness" 
+(0029,00c3) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="RephaseOrderSlice"								Name="Rephase Order Slice"
+(0029,00c4) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="RephaseOrderPhase"								Name="Rephase Order Phase"
+(0029,00c5) VERS="HIT"  VR="CS"   VM="1"	Owner="MMCPrivate"			Keyword="RephaseOrderFreq"								Name="Rephase Order Freq"
+(0029,00d0) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?"
+(0029,00d3) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?"
+(0029,00d5) VERS="HIT"  VR="UI"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?"
+(0029,00d6) VERS="HIT"  VR="LO"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?"
+(0029,00d7) VERS="HIT"  VR="OB"   VM="1"	Owner="MMCPrivate"			Keyword="?"												Name="?"
+
+(0019,0001) VERS="MEV"  VR="LO"   VM="1"	Owner="MeVis BreastCare"	Keyword="AnnotationVersion"				Name="Annotation Version"
+(0071,0001) VERS="MEV"  VR="LO"   VM="1"	Owner="MeVis BreastCare"	Keyword="XMLFormattedTextValue"			Name="XML Formatted Text Value"
+
+(0065,0093) VERS=""     VR="CS"   VM="1"	Owner="Viewing Protocol"	Keyword="?"		Name="?"
+
+(1455,0000) VERS="MOR"  VR="OW"   VM="1"	Owner="Mortara_Inc"			Keyword="ELIInterpretationVector"		Name="ELI Interpretation Vector"
+(1455,0001) VERS="MOR"  VR="UN"   VM="1"	Owner="Mortara_Inc"			Keyword="CustomID"						Name="Custom ID"
+(1455,0002) VERS="MOR"  VR="UT"   VM="1"	Owner="Mortara_Inc"			Keyword="Race"							Name="Race"
+(1455,0003) VERS="MOR"  VR="UT"   VM="1"	Owner="Mortara_Inc"			Keyword="SocialSecurityNumber"			Name="Social Security Number"
+(1455,0004) VERS="MOR"  VR="UT"   VM="1"	Owner="Mortara_Inc"			Keyword="AttendingPhysician"			Name="Attending Physician"
+(1455,0005) VERS="MOR"  VR="UT"   VM="1"	Owner="Mortara_Inc"			Keyword="ProceduralDiagnosis"			Name="Procedural Diagnosis"
+(1455,0006) VERS="MOR"  VR="UT"   VM="1"	Owner="Mortara_Inc"			Keyword="Note1"							Name="Note 1"
+(1455,0007) VERS="MOR"  VR="UT"   VM="1"	Owner="Mortara_Inc"			Keyword="Note2"							Name="Note 2"
+(1455,0008) VERS="MOR"  VR="LO"   VM="1"	Owner="Mortara_Inc"			Keyword="OrderRequestNumber"			Name="Order Request Number"
+(1455,0010) VERS="MOR"  VR="LO"   VM="1"	Owner="Mortara_Inc"			Keyword="ManufacturerName"				Name="Manufacturer Name"
+
+(0029,0031) VERS="SEG" VR="CS"   VM="1"		Owner="SEGAMI_HEADER"								Keyword="?"			Name="?"
+(0029,0032) VERS="SEG" VR="OW"   VM="1"		Owner="SEGAMI_HEADER"								Keyword="?"			Name="?"
+
+(0031,0098) VERS="SEG" VR="OW"   VM="1"		Owner="SEGAMI MIML"									Keyword="?"			Name="?"
+
+(0033,0097) VERS="SEG" VR="IS"   VM="1"		Owner="SEGAMI__PAGE"								Keyword="?"			Name="?"
+(0033,0098) VERS="SEG" VR="OW"   VM="1"		Owner="SEGAMI__PAGE"								Keyword="?"			Name="?"
+	
+(0035,0097) VERS="SEG" VR="SH"   VM="1"		Owner="SEGAMI__MEMO"								Keyword="?"			Name="?"
+(0035,0098) VERS="SEG" VR="LT"   VM="1"		Owner="SEGAMI__MEMO"								Keyword="?"			Name="?"
+
+(5473,0003) VERS=""     VR="LO"   VM="1"	Owner="MedIns HP Extensions"			Keyword="?"		Name="?"
+
+(0029,0001) VERS=""     VR="UL"   VM="1"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+(0029,0010) VERS=""     VR="DS"   VM="1"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+(0029,0011) VERS=""     VR="DS"   VM="1"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+(0029,0020) VERS=""     VR="DS"   VM="1"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+(0029,0021) VERS=""     VR="UL"   VM="1"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+(0029,0022) VERS=""     VR="DS"   VM="2"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+(0029,0030) VERS=""     VR="LT"   VM="1"	Owner="MEDIFACE"			Keyword="?"		Name="?"
+
+(8003,0000) VERS=""     VR="LO"   VM="1"	Owner="Image (ID, Version, Size, Dump, GUID)"			Keyword="ID"		Name="ID"
+(8003,0010) VERS=""     VR="LO"   VM="1"	Owner="Image (ID, Version, Size, Dump, GUID)"			Keyword="Version"	Name="Version"
+(8003,0020) VERS=""     VR="UL"   VM="1"	Owner="Image (ID, Version, Size, Dump, GUID)"			Keyword="Size"		Name="Size"
+(8003,0030) VERS=""     VR="OB"   VM="1"	Owner="Image (ID, Version, Size, Dump, GUID)"			Keyword="Dump"		Name="Dump"
+(8003,0040) VERS=""     VR="LO"   VM="1"	Owner="Image (ID, Version, Size, Dump, GUID)"			Keyword="GUID"		Name="GUID"
+(8101,0000) VERS=""     VR="LO"   VM="1"	Owner="ObjectModel (ID, Version, Place, PlaceDescription)"			Keyword="ID"		Name="ID"
+(8101,0010) VERS=""     VR="LO"   VM="1"	Owner="ObjectModel (ID, Version, Place, PlaceDescription)"			Keyword="Version"	Name="Version"
+
+(0015,0010) VERS=""     VR="LO"   VM="1"	Owner="INFINITT_FMX"			Keyword="?"		Name="?"
+(0015,0011) VERS=""     VR="LO"   VM="1"	Owner="INFINITT_FMX"			Keyword="?"		Name="?"
+
+(0009,0001) VERS=""     VR="LO"   VM="1"	Owner="BrainLAB_Conversion"			Keyword="ExportPlatformName"			Name="Export Platform Name" 
+(0009,0002) VERS=""     VR="OB"   VM="1"	Owner="BrainLAB_Conversion"			Keyword="ExportPlatformData"			Name="Export Platform Data"
+
+(3273,0000) VERS=""     VR="DS"   VM="3"	Owner="BrainLAB_PatientSetup"		Keyword="IsocenterPosition"				Name="Isocenter Position" 
+(3273,0001) VERS=""     VR="CS"   VM="1"	Owner="BrainLAB_PatientSetup"		Keyword="PatientPosition"				Name="Patient Position" 
+
+(3411,0001) VERS=""     VR="SQ"   VM="1"	Owner="BrainLAB_BeamProfile"		Keyword="BeamProfileSequence"			Name="Beam Profile Sequence" 
+(3411,0002) VERS=""     VR="IS"   VM="1"	Owner="BrainLAB_BeamProfile"		Keyword="BeamProfileNumber"				Name="Beam Profile Number" 
+(3411,0003) VERS=""     VR="SQ"   VM="1"	Owner="BrainLAB_BeamProfile"		Keyword="BeamParameterSequence"			Name="Beam Parameter Sequence" 
+(3411,0004) VERS=""     VR="UT"   VM="1"	Owner="BrainLAB_BeamProfile"		Keyword="ParameterDescription"			Name="Parameter Description" 
+(3411,0005) VERS=""     VR="OB"   VM="1"	Owner="BrainLAB_BeamProfile"		Keyword="ParameterData"					Name="Parameter Data" 
+(3411,0006) VERS=""     VR="IS"   VM="1"	Owner="BrainLAB_BeamProfile"		Keyword="ReferencedBeamProfileNumber"	Name="Referenced Beam Profile Number"
+
+(0011,0001) VERS=""     VR="OB"   VM="1"	Owner="V1"			Keyword="UserData"						Name="User Data"
+(0011,0002) VERS=""     VR="DS"   VM="1"	Owner="V1"			Keyword="NormalizationCoefficient"		Name="Normalization Coefficient"
+(0011,0003) VERS=""     VR="DS"   VM="1-n"	Owner="V1"			Keyword="ReceivingGain"					Name="Receiving Gain"
+(0011,0004) VERS=""     VR="DS"   VM="1"	Owner="V1"			Keyword="MeanImageNoise"				Name="Mean Image Noise"
+
+(1135,0000) VERS=""     VR="UI"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0001) VERS=""     VR="OB"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0002) VERS=""     VR="SQ"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0006) VERS=""     VR="UL"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0007) VERS=""     VR="UI"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0008) VERS=""     VR="SQ"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0009) VERS=""     VR="UI"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0010) VERS=""     VR="IS"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0013) VERS=""     VR="LO"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0014) VERS=""     VR="UN"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0016) VERS=""     VR="LO"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0017) VERS=""     VR="UN"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0018) VERS=""     VR="UN"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+(1135,0021) VERS=""     VR="UL"   VM="1"	Owner="Voxar 2.16.124.113543.6003.1999.12.20.12.5.0"			Keyword="?"		Name="?"
+
+(0029,0015) VERS=""     VR="LO"   VM="1"	Owner="Kodak Image Information"			Keyword="?"		Name="?"
+(0029,0016) VERS=""     VR="LO"   VM="1"	Owner="Kodak Image Information"			Keyword="?"		Name="?"
+(0029,0017) VERS=""     VR="LO"   VM="1"	Owner="Kodak Image Information"			Keyword="?"		Name="?"
+(0029,0018) VERS=""     VR="UT"   VM="1"	Owner="Kodak Image Information"			Keyword="?"		Name="?"
+(0029,0019) VERS=""     VR="IS"   VM="1"	Owner="Kodak Image Information"			Keyword="?"		Name="?"
+(0029,001a) VERS=""     VR="IS"   VM="1"	Owner="Kodak Image Information"			Keyword="?"		Name="?"
+
+(0037,0001) VERS=""     VR="LO"   VM="1"	Owner="MAROTECH Inc."			Keyword="?"		Name="?"
+(0037,0021) VERS=""     VR="US"   VM="1"	Owner="MAROTECH Inc."			Keyword="?"		Name="?"
+(0037,0022) VERS=""     VR="US"   VM="1"	Owner="MAROTECH Inc."			Keyword="?"		Name="?"
+(0037,0023) VERS=""     VR="OB"   VM="1"	Owner="MAROTECH Inc."			Keyword="?"		Name="?"
+
+(0021,0000) VERS=""     VR="SQ"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonInformationSequence"	Name="Person Information Sequence"
+(0021,0001) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonID"					Name="Person ID"
+(0021,0002) VERS=""     VR="PN"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonName"				Name="Person Name"
+(0021,0003) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonRole"				Name="Person Role"
+(0021,0004) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonHomePhone"			Name="Person Home Phone"
+(0021,0005) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonWorkPhone"			Name="Person Work Phone"
+(0021,0006) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonCellPhone"			Name="Person Cell Phone"
+(0021,0007) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonPagerPhone"			Name="Person Pager Phone"
+(0021,0008) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonFaxPhone"			Name="Person Fax Phone"
+(0021,0009) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonEMail"				Name="Person EMail"
+(0021,000A) VERS=""     VR="ST"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonAddress"				Name="Person Address"
+(0021,000B) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonPassword"			Name="Person Password"
+(0021,000C) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PersonEmergencyPhone"		Name="Person Emergency Phone"
+(0021,000D) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PhysicianID"				Name="Physician ID"
+(0021,0011) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="OriginalPatientID"			Name="Original Patient ID"
+(0021,0012) VERS=""     VR="UI"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="OriginalStudyInstanceUID"	Name="Original Study Instance UID"
+(0021,0013) VERS=""     VR="UI"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="OriginalSeriesInstanceUID"	Name="Original Series Instance UID"
+(0021,0014) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="MasterAccessionNumber"		Name="Master Accession Number"
+(0021,0015) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="OrderCategory"				Name="Order Category"
+(0021,0016) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PatientICN"				Name="Patient ICN"
+(0021,0017) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PatientDFS"				Name="Patient DFS"
+(0021,0018) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PatientClass"				Name="Patient Class"
+(0021,0019) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="PatientType"				Name="Patient Type"
+(0021,001F) VERS=""     VR="LT"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="GenericString"				Name="Generic String"
+(0021,0020) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCStudyAssignedBy"			Name="QC Study Assigned By"
+(0021,0021) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCStudySplitBy"			Name="QC Study Split By"
+(0021,0022) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCStudyMovedBy"			Name="QC Study Moved By"
+(0021,0023) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCStudyEditedBy"			Name="QC Study Edited By"
+(0021,0024) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCSeriesSplitBy"			Name="QC Series Split By"
+(0021,0025) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCSeriesMovedBy"			Name="QC Series Moved By"
+(0021,0026) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCSeriesEditedBy"			Name="QC Series Edited By"
+(0021,0027) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCImageMovedBy"			Name="QC Image Moved By"
+(0021,0028) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCImageEditedBy"			Name="QC Image Edited By"
+(0021,0030) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCDoneTime"				Name="QC Done Time"
+(0021,0031) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCLastModificationTime"	Name="QC Last Modification Time"
+(0021,0032) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCImageAcceptedBy"			Name="QC Image Accepted By"
+(0021,0033) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCImageRejectedBy"			Name="QC Image Rejected By"
+(0021,0034) VERS=""     VR="DA"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCDoneDate"				Name="QC Done Date"
+(0021,0034) VERS=""     VR="DA"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCLastModificationDate"	Name="QC Last Modification Date"
+(0021,0050) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="QCDeletionRequested"		Name="QC Deletion Requested"
+(0021,0090) VERS=""     VR="AE"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="OriginalSenderAETitle"		Name="Original Sender AE Title"
+(0021,0091) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="SoftwareTitle"				Name="Software Title"
+(0021,0092) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="SoftwareVersion"			Name="Software Version"
+(0021,0093) VERS=""     VR="LO"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="SerialNumber"				Name="Serial Number"
+(0021,00a0) VERS=""     VR="SQ"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="ObjectActionSequence"		Name="Object Action Sequence"
+(0021,00a1) VERS=""     VR="ST"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="ObjectAction"				Name="Object Action"
+(0021,00a2) VERS=""     VR="DA"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="ObjectActionDate"			Name="Object Action Date"
+(0021,00a3) VERS=""     VR="TM"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="ObjectActionTime"			Name="Object Action Time"
+(0021,00a5) VERS=""     VR="AE"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="LocalAETitle"				Name="Local AE Title"
+(0021,00a6) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="LocalIPAddress"			Name="Local IP Address"
+(0021,00a7) VERS=""     VR="AE"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="RemoteAETitle"				Name="Remote AE Title"
+(0021,00a8) VERS=""     VR="SH"   VM="1"	Owner="BRIT Systems, Inc."	Keyword="RemoteIPAddress"			Name="Remote IP Address"
+
+(3005,0000) VERS=""     VR="SQ"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,0002) VERS=""     VR="CS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,0004) VERS=""     VR="DS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,0006) VERS=""     VR="DS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,0008) VERS=""     VR="DS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,000a) VERS=""     VR="CS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,000c) VERS=""     VR="CS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,000e) VERS=""     VR="CS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,0010) VERS=""     VR="DS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+(3005,0012) VERS=""     VR="DS"   VM="1"	Owner="MDS NORDION OTP ANATOMY MODELLING"	Keyword="?"			Name="?"
+
+(4321,0041) VERS=""     VR="CS"   VM="1"	Owner="Imaging Dynamics Company Ltd."	Keyword="?"			Name="?" 
+(4321,0042) VERS=""     VR="US"   VM="1"	Owner="Imaging Dynamics Company Ltd."	Keyword="?"			Name="?" 
+(4321,0064) VERS=""     VR="LO"   VM="1"	Owner="Imaging Dynamics Company Ltd."	Keyword="PODMode"			Name="POD Mode" 
+
+(f001,0000) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="PatientSpecies"			Name="Patient Species"
+(f001,0001) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="PatientBreed"				Name="Patient Breed"
+(f001,0002) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="PatientCategorySize"		Name="Patient Category Size"
+(f001,0003) VERS=""     VR="CS"   VM="1"	Owner="Sound Technologies"	Keyword="PatientSexExtended"		Name="Patient Sex Extended"
+(f001,0004) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ImageView"					Name="Image View"
+(f001,0005) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="AnatomyImaged"				Name="Anatomy Imaged"
+(f001,0006) VERS=""     VR="LT"   VM="1"	Owner="Sound Technologies"	Keyword="ImageEnhancements"			Name="Image Enhancements"
+(f001,0007) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="DetectorSettings"			Name="Detector Settings"
+(f001,0008) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ApplicationVersion"		Name="Application Version"
+(f001,0009) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ImageLateralityExtended"	Name="Image Laterality Extended"
+(f001,000a) VERS=""     VR="PN"   VM="1"	Owner="Sound Technologies"	Keyword="ClientName"				Name="Client Name"
+(f001,000b) VERS=""     VR="UI"   VM="1"	Owner="Sound Technologies"	Keyword="ReferenceStudyInstanceUID"	Name="Reference Study Instance UID"
+(f001,000c) VERS=""     VR="UI"   VM="1"	Owner="Sound Technologies"	Keyword="ReferenceStudyInstanceUID"	Name="Reference Study Instance UID"
+(f001,000d) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ExamRefID"					Name="Exam Ref ID"
+(f001,000e) VERS=""     VR="ST"   VM="1"	Owner="Sound Technologies"	Keyword="PhysicianOfRecordAddress"	Name="Physician of Record Address"
+(f001,000f) VERS=""     VR="SH"   VM="1"	Owner="Sound Technologies"	Keyword="PhysicianOfRecordPhoneNumbers"	Name="Physician of Record Phone Numbers"
+(f001,0010) VERS=""     VR="LT"   VM="1"	Owner="Sound Technologies"	Keyword="ReasonForStudy"			Name="Reason For Study"
+(f001,0011) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="Protocol"					Name="Protocol"
+(f001,0012) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="CaptureInputType"			Name="Capture Input Type"
+(f001,0013) VERS=""     VR="LT"   VM="1"	Owner="Sound Technologies"	Keyword="ExamComplaint"				Name="Exam Complaint"
+(f001,0014) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ExamWebCode"				Name="Exam Web Code"
+(f001,0015) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ExamCategory"				Name="Exam Category"
+(f001,0016) VERS=""     VR="SH"   VM="1"	Owner="Sound Technologies"	Keyword="ExamDiagnosis"				Name="Exam Diagnosis"
+(f001,0017) VERS=""     VR="PN"   VM="1"	Owner="Sound Technologies"	Keyword="ExamCreatedBy"				Name="Exam Created By"
+(f001,0018) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ExamCreatedByGroup"		Name="Exam Created By Group"
+(f001,0019) VERS=""     VR="DT"   VM="1"	Owner="Sound Technologies"	Keyword="ExamRequiredByDateTime"	Name="Exam Required By DateTime"
+(f001,001a) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="CaptureType"				Name="Capture Type"
+(f001,001b) VERS=""     VR="IS"   VM="1"	Owner="Sound Technologies"	Keyword="TelemedExamID"				Name="Telemed Exam ID"
+(f001,001c) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ExamCreatedByGuid"			Name="Exam Created By Guid"
+(f001,001d) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ClientNameGuid"			Name="Client Name Guid"
+(f001,001e) VERS=""     VR="LO"   VM="1"	Owner="Sound Technologies"	Keyword="ReceptorBitsPerPixel"		Name="Receptor Bits Per Pixel"
+
+(3711,0001) VERS=""     VR="LO"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="Filename"				Name="Filename"
+(3711,0002) VERS=""     VR="OB"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="DataBlobOfAVisit"		Name="Data Blob of a Visit"
+(3711,0003) VERS=""     VR="US"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="RevisionNumber"		Name="Revision Number"
+(3711,0004) VERS=""     VR="UL"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="UnixTimestamp"			Name="Unix Timestamp"
+(3711,0005) VERS=""     VR="IS"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="BagID"					Name="Bag ID"
+(3711,000C) VERS=""     VR="UI"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="OriginalStudyUID"		Name="Original Study UID"
+(3711,000D) VERS=""     VR="US"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="OverlayGrayscaleValue"	Name="Overlay Grayscale Value"
+(3711,000E) VERS=""     VR="CS"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="AnonymizationStatus"	Name="Anonymization Status"
+(3711,000F) VERS=""     VR="CS"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="InstanceType"			Name="Instance Type"
+(3711,0030) VERS=""     VR="LO"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="IPConvertedFrame"		Name="IP Converted Frame"
+(3711,0097) VERS=""     VR="OB"   VM="1"	Owner="A.L.I. Technologies, Inc."	Keyword="?"						Name="?"
+
+(7777,0002) VERS=""     VR="UT"   VM="1"	Owner="NUD_PRIVATE"			Keyword="Interfile"			Name="Interfile"
+(7777,0005) VERS=""     VR="IS"   VM="1"	Owner="NUD_PRIVATE"			Keyword="?"					Name="?"
+
+(0011,0000) VERS=""     VR="LO"   VM="1"	Owner="IDEXX"	Keyword="BreedName"			Name="Breed Name"
+(0011,0001) VERS=""     VR="LO"   VM="1"	Owner="IDEXX"	Keyword="SpeciesName"			Name="Species Name"
+(0011,0002) VERS=""     VR="PN"   VM="1"	Owner="IDEXX"	Keyword="Owner"					Name="Owner"
+
+(0009,0001) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="EventTimerSequence"							Name="Event Timer Sequence"
+(0009,0002) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="EventTimeInterval"								Name="Event Time Interval"
+(0009,0003) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="EventCodeSequence"								Name="Event Code Sequence"
+(0019,0001) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="FocusDepth"									Name="Focus Depth(s)"
+(0019,0003) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ExcludedIntervalsSequence"						Name="Excluded Intervals Sequence"
+(0019,0004) VERS="SUP43"     VR="DT"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ExclusionStartDatetime"						Name="Exclusion Start Datetime"
+(0019,0005) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ExclusionDuration"								Name="Exclusion Duration"
+(0019,0006) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="USImageDescriptionSequence"					Name="US Image Description Sequence"
+(0019,0007) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ImageDataTypeSequence"							Name="Image Data Type Sequence"
+(0019,0008) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="DataType"										Name="Data Type"
+(0019,0009) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="TransducerScanGeometryCodeSequence"			Name="Transducer Scan Geometry Code Sequence"
+(0019,000B) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="AliasedDataType"								Name="Aliased Data Type"
+(0019,000C) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="PositionMeasuringDeviceUsed"					Name="Position Measuring Device Used"
+(0019,000D) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="TransducerScanningConfigurationCodeSequence"	Name="Transducer Scanning Configuration Code Sequence"
+(0019,000E) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="TransducerBeamSteeringCodeSequence"			Name="Transducer Beam Steering Code Sequence"
+(0019,000F) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="TransducerAccessCodeSequence"					Name="Transducer Access Code Sequence"
+(0021,0001) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ImagePositionVolume"							Name="Image Position (Volume)"
+(0021,0002) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ImageOrientationVolume"						Name="Image Orientation (Volume)"
+(0021,0007) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="UltrasoundAcquisitionGeometry"					Name="Ultrasound Acquisition Geometry"
+(0021,0008) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="ApexPosition"									Name="Apex Position"
+(0021,0009) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="VolumeToTransducerMappingMatrix"				Name="Volume to Transducer Mapping Matrix"
+(0021,000A) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="VolumeToTableMappingMatrix"					Name="Volume to Table Mapping Matrix"
+(0021,000C) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="PatientFrameOfReferenceSource"					Name="Patient Frame of Reference Source"
+(0021,000D) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="TemporalPositionTimeOffset"					Name="Temporal Position Time Offset"
+(0021,000E) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="PlanePositionVolumeSequence"					Name="Plane Position (Volume) Sequence"
+(0021,000F) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="PlaneOrientationVolumeSequence"				Name="Plane Orientation (Volume) Sequence"
+(0021,0010) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="TemporalPositionSequence"						Name="Temporal Position Sequence"
+(0021,0011) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="DimensionOrganizationType"						Name="Dimension Organization Type"
+(0029,0001) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="DataFrameAssignmentSequence"					Name="Data Frame Assignment Sequence"
+(0029,0002) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="DataPathAssignment"							Name="Data Path Assignment"
+(0029,0003) VERS="SUP43"     VR="US"   VM="1"	Owner="WG12 Supplement 43"			Keyword="BitsMappedToColorLookupTable"					Name="Bits Mapped to Color Lookup Table"
+(0029,0004) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="Opacity1LUTSequence"							Name="Opacity 1 LUT Sequence"
+(0029,0005) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="Opacity1LUTTransferFunction"					Name="Opacity 1 LUT Transfer Function"
+(0029,0006) VERS="SUP43"     VR="FD"   VM="1"	Owner="WG12 Supplement 43"			Keyword="OpacityConstant"								Name="Opacity Constant"
+(0029,0007) VERS="SUP43"     VR="US"   VM="1"	Owner="WG12 Supplement 43"			Keyword="OpacityLookupTableDescriptor"					Name="Opacity Lookup Table Descriptor"
+(0029,0008) VERS="SUP43"     VR="OW"   VM="1"	Owner="WG12 Supplement 43"			Keyword="OpacityLookupTableData"						Name="Opacity Lookup Table Data"
+(0029,000B) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="EnhancedPaletteColorLookupTableSequence"		Name="Enhanced Palette Color Lookup Table Sequence"
+(0029,000C) VERS="SUP43"     VR="SQ"   VM="1"	Owner="WG12 Supplement 43"			Keyword="Opacity2LUTSequence"							Name="Opacity 2 LUT Sequence"
+(0029,000D) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="Opacity2LUTTransferFunction"					Name="Opacity 2 LUT Transfer Function"
+(0029,000E) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="DataPathID"									Name="Data Path ID"
+(0029,000F) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="RGBLUTTransferFunction"						Name="RGB LUT Transfer Function"
+(0029,0010) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="AlphaLUTTransferFunction"						Name="Alpha LUT Transfer Function"
+(0041,0001) VERS="SUP43"     VR="CS"   VM="1"	Owner="WG12 Supplement 43"			Keyword="PerformedProtocolType"							Name="Performed Protocol Type"
+
+(0009,0000) VERS="HMC"     VR="OB"   VM="1"	Owner="HMC - CT - ID"	Keyword="ImageIDInformationPatientNameID"		Name="Image ID Information Patient Name ID"
+(0009,0001) VERS="HMC"     VR="OB"   VM="1"	Owner="HMC - CT - ID"	Keyword="ImageIDInformationPatientComment"		Name="Image ID Information Patient Comment"
+(0019,0000) VERS="HMC"     VR="SH"   VM="1"	Owner="SET WINDOW"		Keyword="SetWindowImageFilter"					Name="Set Window Image Filter"
+(0019,0001) VERS="HMC"     VR="US"   VM="1"	Owner="SET WINDOW"		Keyword="SetWindowMagnificationPower"			Name="Set Window Magnification Power" 
+
+(0017,0000) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="ExtendedBodyPart"				Name="Extended Body Part"
+(0017,0010) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="ExtendedViewPosition"			Name="Extended View Position"
+(0017,0020) VERS="SWS"     VR="SQ"   VM="1"	Owner="SVISION"	Keyword="ScheduledProcedureStepList"	Name="Scheduled Procedure Step List"
+(0017,00a0) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="FixedGridSystem"				Name="Fixed Grid System"
+(0017,00f0) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="ImagesSOPClass"				Name="Images SOP Class"
+
+(0019,0000) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="AEC Field"
+(0019,0001) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="AEC Film Screen"
+(0019,0002) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="AEC Density"
+(0019,0010) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Patient Thickness"
+(0019,0016) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="?"
+(0019,0018) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Beam Distance"
+(0019,0020) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Workstation Number"
+(0019,0028) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Tube Number"
+(0019,0030) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Bucky Grid"
+(0019,0034) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Focus"
+(0019,0038) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Age Group"
+(0019,0040) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Collimator Distance X"
+(0019,0041) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Collimator Distance Y"
+(0019,0050) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Bucky Height"
+(0019,0060) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Bucky Angle"
+(0019,0068) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="C-Arm Angle"
+(0019,0069) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Collimator Angle"
+(0019,0070) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Filter Number"
+(0019,0074) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Filter Material 1"
+(0019,0075) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Filter Material 2"
+(0019,0078) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Filter Thickness 1"
+(0019,0079) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Filter Thickness 2"
+(0019,0080) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Bucky Format"
+(0019,0081) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Object Position"
+(0019,0090) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Desk Command"
+(0019,0091) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Central Beam X"
+(0019,0092) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Central Beam Y"
+(0019,0093) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Tube Turn Angle"
+(0019,0094) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Stand Drive Level"
+(0019,00a0) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Extended Exposure Time"
+(0019,00a1) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Actual Exposure Time"
+(0019,00a8) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Extended X-ray Tube Current"
+(0019,00b0) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Dose Indicator"
+(0019,00b1) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Shift Reference Value"
+(0019,00f0) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="?"
+
+(0021,0000) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Noise Reduction"
+(0021,0001) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Contrast Amplification"
+(0021,0002) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Edge Contrast Boosting"
+(0021,0003) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Latitude Reduction"
+(0021,0010) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Find Range Algorithm"
+(0021,0011) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Threshold C-Algorithm"
+(0021,0020) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Sensometric Curve"
+(0021,0030) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Lower Window Offset"
+(0021,0031) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Upper Window Offset"
+(0021,0040) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Minimal Printable Density"
+(0021,0041) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Maximal Printable Density"
+(0021,0050) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Minimal Window Latitude"
+(0021,0051) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Maximal Window Latitude"
+(0021,0052) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Relative Window Alignment"
+(0021,0060) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Decomposition Layer"
+(0021,0090) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Brightness"
+(0021,0091) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Contrast"
+(0021,0092) VERS="SWS"     VR="DS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Shape Factor"
+
+(0023,0000) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Image Laterality"
+(0023,0001) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Letter Position"
+(0023,0002) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Burned In Annotation"
+(0023,0003) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="?"
+(0023,00f0) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Image SOP Class"
+
+(0025,0000) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Original Image"
+(0025,0001) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Not Processed Image"
+(0025,0002) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Cut Out Image"
+(0025,0003) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Duplicated Image"
+(0025,0004) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Stored Image"
+(0025,0005) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Retrieved Image"
+(0025,0006) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="New Image"
+(0025,0007) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Media Stored Image"
+(0025,0008) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Image State"
+(0025,0009) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Image Stitched Manually"
+(0025,000a) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Image Stitched Automatically"
+(0025,0020) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Source Image File"
+(0025,0021) VERS="SWS"     VR="LO"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Source UID"
+
+(0027,0000) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Number of Series" 
+(0027,0001) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Number of Studies" 
+(0027,0010) VERS="SWS"     VR="DT"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Oldest Series" 
+(0027,0011) VERS="SWS"     VR="DT"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Newest Series" 
+(0027,0012) VERS="SWS"     VR="DT"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Oldest Study" 
+(0027,0013) VERS="SWS"     VR="DT"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Newest Study" 
+
+(0029,0000) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Key Note Instance UID" 
+(0029,0001) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Storage State" 
+(0029,0002) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Referenced Image SOP Class" 
+(0029,0003) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Referenced Image Instance UID" 
+(0029,0004) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Related Presentation State Number" 
+(0029,0005) VERS="SWS"     VR="IS"   VM="1"	Owner="SVISION"	Keyword="?"		Name="Related Presentation State UID" 
+
+(5653,0010) VERS="VIT"     VR="OB"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflow"				Name="Saved Workflow"
+(5653,0011) VERS="VIT"     VR="LO"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowFileName"		Name="Saved Workflow File Name"
+(5653,0012) VERS="VIT"     VR="OB"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowFileData"		Name="Saved Workflow File Data"
+(5653,0013) VERS="VIT"     VR="SL"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowFileLength"	Name="Saved Workflow File Length"
+(5653,0014) VERS="VIT"     VR="SQ"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowFileSequence"	Name="Saved Workflow File Sequence"
+(5653,0015) VERS="VIT"     VR="SQ"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="ImageSequence"				Name="Image Sequence"
+(5653,0016) VERS="VIT"     VR="SL"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="VolumeInterpolatedSlices"	Name="Volume Interpolated Slices"
+(5653,0017) VERS="VIT"     VR="UI"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="VolumeSOPInstanceUID"		Name="Volume SOP Instance UID"
+(5653,0018) VERS="VIT"     VR="SH"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowMark"			Name="Saved Workflow Mark"
+(5653,0019) VERS="VIT"     VR="UI"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="VolumeStudyInstanceUID"	Name="Volume Study Instance UID"
+(5653,0020) VERS="VIT"     VR="SL"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="NumStudySwf"				Name="Number of Study Saved Workflow"
+(5653,0021) VERS="VIT"     VR="SL"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="NumSeriesSwf"				Name="Number of Series Saved Workflow"
+(5653,0022) VERS="VIT"     VR="UI"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="VolumeSeriesInstanceUID"	Name="Volume Series Instance UID"
+(5653,0023) VERS="VIT"     VR="LO"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowCodeMeaning"	Name="Saved Workflow Code Meaning"
+(5653,0024) VERS="VIT"     VR="OB"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowData"			Name="Saved Workflow Data"
+(5653,0025) VERS="VIT"     VR="SL"   VM="1"	Owner="Vital Images SW 3.4" 	Keyword="SavedWorkflowDataLength"	Name="Saved Workflow Data Length"
+
+(0781,0001) VERS="ALICE"   VR="US"   VM="1"	Owner="PI Private Block (0781:3000 - 0781:30FF)" 	Keyword="?"		Name="?"
+(0781,0002) VERS="ALICE"   VR="US"   VM="1"	Owner="PI Private Block (0781:3000 - 0781:30FF)" 	Keyword="?"		Name="?"
+(0781,0005) VERS="ALICE"   VR="FL"   VM="1"	Owner="PI Private Block (0781:3000 - 0781:30FF)" 	Keyword="?"		Name="?"
+(0781,0009) VERS="ALICE"   VR="FL"   VM="4"	Owner="PI Private Block (0781:3000 - 0781:30FF)" 	Keyword="?"		Name="?"
+
+(0203,0000) VERS="RVN"     VR="LO"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+(0203,0001) VERS="RVN"     VR="LO"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+(0203,0002) VERS="RVN"     VR="LO"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+(0203,0003) VERS="RVN"     VR="LO"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+(0203,0010) VERS="RVN"     VR="LO"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+(0203,00f0) VERS="RVN"     VR="UI"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+(0203,00f1) VERS="RVN"     VR="UI"   VM="1"	Owner="Riverain Medical" 	Keyword="?"		Name="?"
+
+(0029,0010) VERS="INT"     VR="CS"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0011) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0012) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0013) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0015) VERS="INT"     VR="DS"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0016) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0017) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0020) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="MD5Sum"		Name="MD5Sum"
+(0029,0021) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(0029,0022) VERS="INT"     VR="US"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+
+(0071,0001) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,0002) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,0003) VERS="INT"     VR="UN"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,0004) VERS="INT"     VR="UN"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,0005) VERS="INT"     VR="UN"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,0006) VERS="INT"     VR="UN"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,0007) VERS="INT"     VR="UN"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+(0071,000A) VERS="INT"     VR="UN"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS INTELEVIEWER" 	Keyword="?"		Name="?"
+
+(3F01,0001) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,0003) VERS="INT"     VR="AE"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,0004) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,0005) VERS="INT"     VR="AE"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,0007) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,0009) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,000A) VERS="INT"     VR="DA"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F01,000B) VERS="INT"     VR="TM"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F03,0001) VERS="INT"     VR="SQ"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F03,0002) VERS="INT"     VR="DT"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F03,0003) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+(3F03,0004) VERS="INT"     VR="LO"   VM="1"	Owner="INTELERAD MEDICAL SYSTEMS" 	Keyword="?"		Name="?"
+
+(4453,0000) VERS="DRS"     VR="LO"   VM="1"	Owner="DR Systems, Inc." 	Keyword="?"								Name="Exam ?"
+(4453,0001) VERS="DRS"     VR="LO"   VM="1"	Owner="DR Systems, Inc." 	Keyword="ExamID"						Name="Exam ID"
+(4453,0002) VERS="DRS"     VR="LO"   VM="1"	Owner="DR Systems, Inc." 	Keyword="ImageType"						Name="Image Type"
+(4453,0004) VERS="DRS"     VR="LO"   VM="1"	Owner="DR Systems, Inc." 	Keyword="FileType"						Name="File Type"
+(4453,0005) VERS="DRS"     VR="LO"   VM="1"	Owner="DR Systems, Inc." 	Keyword="FileSuffix"					Name="File Suffix"
+(4453,000A) VERS="DRS"     VR="LO"   VM="1"	Owner="DR Systems, Inc." 	Keyword="AnnotationType"				Name="Annotation Type"
+(4453,000C) VERS="DRS"     VR="SQ"   VM="1"	Owner="DR Systems, Inc." 	Keyword="OriginalInstanceUIDSequence"	Name="Original Instance UID Sequence"
+
+(0859,0040) VERS="INT"     VR="DS"   VM="1"	Owner="ETIAM DICOMDIR" 	Keyword="?"		Name="?" 
+
+(0077,0010) VERS="TER"     VR="UI"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="OriginalSeriesStudyUID"	Name="Original Series/Study UID"
+(0077,0012) VERS="TER"     VR="UI"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="OriginalSOPUID"			Name="Original SOP UID"
+(0077,0014) VERS="TER"     VR="LO"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="ReferencedVolumeID"		Name="Referenced Volume ID"
+(0077,0016) VERS="TER"     VR="CS"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="BinaryDataNameSCS"			Name="Binary Data Name SCS"
+(0077,0020) VERS="TER"     VR="LO"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="BinaryDataName"			Name="Binary Data Name"
+(0077,0022) VERS="TER"     VR="CS"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="NumberOfSOPInstanceUID"	Name="Number of SOP Instance UID"
+(0077,0024) VERS="TER"     VR="CS"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="NumberOfSeriesInstanceUID"	Name="Number of Series Instance UID"
+(0077,0026) VERS="TER"     VR="US"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="NumberOfBinaryData"		Name="Number of Binary Data"
+(0077,0028) VERS="TER"     VR="CS"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="BinaryDataType"			Name="Binary Data Type"
+(0077,0030) VERS="TER"     VR="UL"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="BinaryDataSize"			Name="Binary Data Size"
+(0077,0032) VERS="TER"     VR="LO"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="BinaryDataSubType"			Name="Binary Data SubType"
+(0077,0040) VERS="TER"     VR="LO"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="AdditionalInformation"		Name="Additional Information"
+(0077,0050) VERS="TER"     VR="OB"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="FirstBinaryData"			Name="First Binary Data"
+(0077,0060) VERS="TER"     VR="OB"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="FirstThumbnail"			Name="First Thumbnail"
+(0077,0070) VERS="TER"     VR="LO"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="AlgorithmID"				Name="Algorithm ID"
+(0077,0080) VERS="TER"     VR="LO"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="VolumeID"					Name="Volume ID"
+(0077,0084) VERS="TER"     VR="LO"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="COFObjectUID"				Name="COF Object UID"
+(0077,0086) VERS="TER"     VR="LO"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="WorkflowSceneStatus"		Name="Workflow Scene Status"
+(0077,0088) VERS="TER"     VR="UI"   VM="1-n"	Owner="TERARECON AQUARIUS" 	Keyword="ReferenceSOPInstanceUIDs"	Name="Reference SOP Instance UIDs"
+(0077,0090) VERS="TER"     VR="FL"   VM="1"		Owner="TERARECON AQUARIUS" 	Keyword="COFRefinementLevel"		Name="COF Refinement Level"
+
+(0009,0000) VERS="EMG"     VR="LO"   VM="1"	Owner="EMAGEON STUDY HOME"		Keyword="?"		Name="?" 
+(0009,0001) VERS="EMG"     VR="LO"   VM="1"	Owner="EMAGEON STUDY HOME"		Keyword="?"		Name="?" 
+(0009,0000) VERS="EMG"     VR="SQ"   VM="1"	Owner="EMAGEON JPEG2K INFO" 	Keyword="?"		Name="?" 
+(0009,0001) VERS="EMG"     VR="DT"   VM="1"	Owner="EMAGEON JPEG2K INFO" 	Keyword="?"		Name="?" 
+
+(0029,0024) VERS="RWM"     VR="US"   VM="1-n"	Owner="RadWorksMarconi" 	Keyword="KeyFrameIndices"		Name="Key Frame Indices"
+
+(0009,0010) VERS="MEV"     VR="LO"   VM="1"		Owner="MeVis eatDicom"							Keyword="eatDicomVersion"				Name="eatDicom Version"
+(0009,0011) VERS="MEV"     VR="ST"   VM="1"		Owner="MeVis eatDicom"							Keyword="eatDicomOptions"				Name="eatDicom Options"
+
+(0021,0010) VERS="MEV"     VR="LT"   VM="1"		Owner="MeVis eD: Timepoint Information"			Keyword="TimepointDateTime"				Name="Timepoint DateTime"
+(0021,0011) VERS="MEV"     VR="CS"   VM="1"		Owner="MeVis eD: Timepoint Information"			Keyword="TimepointDateTimeType"			Name="Timepoint DateTime Type"
+(0021,0012) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Timepoint Information"			Keyword="TimepointSeriesDescription"	Name="Timepoint Series Description"
+(0021,0013) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Timepoint Information"			Keyword="TimepointGradientDirections"	Name="Timepoint Gradient Directions"
+(0021,0071) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Timepoint Information"			Keyword="TimepointEmptyFrames"			Name="Timepoint Empty Frames"
+
+(0021,0010) VERS="MEV"     VR="LT"   VM="1"		Owner="MeVis eD: Absolute Temporal Positions" 	Keyword="TimepointDateTime"				Name="Timepoint DateTime"
+(0021,0011) VERS="MEV"     VR="CS"   VM="1"		Owner="MeVis eD: Absolute Temporal Positions" 	Keyword="TimepointDateTimeType"			Name="Timepoint DateTime Type"
+(0021,0012) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Absolute Temporal Positions" 	Keyword="TimepointSeriesDescription"	Name="Timepoint Series Description"
+(0021,0013) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Absolute Temporal Positions" 	Keyword="TimepointGradientDirections"	Name="Timepoint Gradient Directions"
+(0021,0071) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Absolute Temporal Positions" 	Keyword="TimepointEmptyFrames"			Name="Timepoint Empty Frames"
+
+(0021,0010) VERS="MEV"     VR="UN"   VM="1"		Owner="MeVis eD: Geometry Information"			Keyword="GeometryScannerOrigin"			Name="Geometry Scanner Origin"
+
+(0021,0010) VERS="MEV"     VR="UI"   VM="1-n"	Owner="MeVis eD: Slice Information"				Keyword="SliceSOPInstanceUIDs"			Name="Slice SOP Instance UIDs"
+
+(0029,0010) VERS=""		   VR="DS"   VM="1"		Owner="ShowcaseAppearance"						Keyword="?"				Name="?"
+(0029,0011) VERS=""		   VR="DS"   VM="1"		Owner="ShowcaseAppearance"						Keyword="?"				Name="?"
+(0029,0012) VERS=""		   VR="DS"   VM="1"		Owner="ShowcaseAppearance"						Keyword="?"				Name="?"
+(0029,0013) VERS=""        VR="DS"   VM="1"		Owner="ShowcaseAppearance"						Keyword="?"				Name="?"
+(0029,0014) VERS=""		   VR="SQ"   VM="1"		Owner="ShowcaseAppearance"						Keyword="?"				Name="?"
+
+(0009,0000) VERS="DTK" VR="SQ"   VM="1"	Owner="DCMTK_ANONYMIZER"		Keyword="AnonymizerUIDMap"							Name="Anonymizer UID Map"
+(0009,0010) VERS="DTK" VR="UI"   VM="1"	Owner="DCMTK_ANONYMIZER"		Keyword="AnonymizerUIDKey"							Name="Anonymizer UID Key"
+(0009,0020) VERS="DTK" VR="UI"   VM="1"	Owner="DCMTK_ANONYMIZER"		Keyword="AnonymizerUIDValue"						Name="Anonymizer UID Value"
+(0009,0030) VERS="DTK" VR="SQ"   VM="1"	Owner="DCMTK_ANONYMIZER"		Keyword="AnonymizerPatientIDMap"					Name="Anonymizer Patient ID Map"
+(0009,0040) VERS="DTK" VR="LO"   VM="1"	Owner="DCMTK_ANONYMIZER"		Keyword="AnonymizerPatientIDKey"					Name="Anonymizer Patient ID Key"
+(0009,0050) VERS="DTK" VR="LO"   VM="1"	Owner="DCMTK_ANONYMIZER"		Keyword="AnonymizerPatientIDValue"					Name="Anonymizer Patient ID Value"
+
+(0099,0001) VERS="NQT" VR="UI"   VM="1"		Owner="NQHeader"								Keyword="Version"									Name="Version"
+(0099,0002) VERS="NQT" VR="UI"   VM="1"		Owner="NQHeader"								Keyword="AnalyzedSeriesUID"							Name="Analyzed Series UID"
+(0099,0003) VERS="NQT" VR="LT"   VM="1"		Owner="NQHeader"								Keyword="License"									Name="License"
+(0099,0004) VERS="NQT" VR="SS"   VM="1"		Owner="NQHeader"								Keyword="ReturnCode"								Name="Return Code"
+(0099,0005) VERS="NQT" VR="LT"   VM="1"		Owner="NQHeader"								Keyword="ReturnMessage"								Name="Return Message"
+(0099,0010) VERS="NQT" VR="FL"   VM="1"		Owner="NQHeader"								Keyword="MI"										Name="MI"
+(0099,0020) VERS="NQT" VR="SH"   VM="1"		Owner="NQHeader"								Keyword="Units"										Name="Units"
+(0099,0021) VERS="NQT" VR="FL"   VM="1"		Owner="NQHeader"								Keyword="ICV"										Name="ICV"
+
+(0199,0001) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCorticalWhiteMatter"					Name="Left Cortical White Matter"
+(0199,0002) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCorticalGrayMatter"					Name="Left Cortical Gray Matter"
+(0199,0003) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="Left3rdVentricle"							Name="Left 3rd Ventricle"
+(0199,0004) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="Left4thVentricle"							Name="Left 4th Ventricle"
+(0199,0005) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="Left5thVentricle"							Name="Left 5th Ventricle"
+(0199,0006) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftLateralVentricle"						Name="Left Lateral Ventricle"
+(0199,0007) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftInferiorLateralVentricle"				Name="Left Inferior Lateral Ventricle"
+(0199,0008) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftInferiorCSF"							Name="Left Inferior CSF"
+(0199,0009) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCerebellarWhiteMatter"					Name="Left Cerebellar White Matter"
+(0199,000a) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCerebellarGrayMatter"					Name="Left Cerebellar Gray Matter"
+(0199,000b) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftHippocampus"							Name="Left Hippocampus"
+(0199,000c) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftAmygdala"								Name="Left Amygdala"
+(0199,000d) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftThalamus"								Name="Left Thalamus"
+(0199,000e) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCaudate"								Name="Left Caudate"
+(0199,000f) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftPutamen"								Name="Left Putamen"
+(0199,0010) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftPallidum"								Name="Left Pallidum"
+(0199,0011) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftVentralDiencephalon"					Name="Left Ventral Diencephalon"
+(0199,0012) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftNucleusAccumbens"						Name="Left Nucleus Accumbens"
+(0199,0013) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftBrainStem"								Name="Left Brain Stem"
+(0199,0014) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftExteriorCSF"							Name="Left Exterior CSF"
+(0199,0015) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftWMHypo"								Name="Left WM Hypo"
+(0199,0016) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftOther"									Name="Left Other"
+
+(0199,0017) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexUnkown"							Name="Left Cortex Unkown"
+(0199,0018) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexBankssts"						Name="Left Cortex Bankssts"
+(0199,0019) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexCaudalAnteriorCingulate"			Name="Left Cortex Caudal Anterior Cingulate"
+(0199,001a) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexCaudalMiddleFrontal"				Name="Left Cortex Caudal Middle Frontal"
+(0199,001b) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexCorpusCallosum"					Name="Left Cortex Corpus Callosum"
+(0199,001c) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexCuneus"							Name="Left Cortex Cuneus"
+(0199,001d) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexEntorhinal"						Name="Left Cortex Entorhinal"
+(0199,001e) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexFusiform"						Name="Left Cortex Fusiform"
+(0199,001f) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexInferiorParietal"				Name="Left Cortex Inferior Parietal"
+(0199,0020) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexInferiorTemporal"				Name="Left Cortex Inferior Temporal"
+(0199,0021) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexIsthmusCingulate"				Name="Left Cortex Isthmus Cingulate"
+(0199,0022) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexLateralOccipital"				Name="Left Cortex Lateral Occipital"
+(0199,0023) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexLateralOrbitoFrontal"			Name="Left Cortex Lateral Orbito Frontal"
+(0199,0024) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexLingual"							Name="Left Cortex Lingual"
+(0199,0025) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexMedialOrbitoFrontal"				Name="Left Cortex Medial Orbito Frontal"
+(0199,0026) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexMiddleTemporal"					Name="Left Cortex Middle Temporal"
+(0199,0027) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexParahippocampal"					Name="Left Cortex Parahippocampal"
+(0199,0028) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexParacentral"						Name="Left Cortex Paracentral"
+(0199,0029) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexParsOpercularis"					Name="Left Cortex Pars Opercularis"
+(0199,002a) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexParsOrbitalis"					Name="Left Cortex Pars Orbitalis"
+(0199,002b) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexParsTriangularis"				Name="Left Cortex Pars Triangularis"
+(0199,002c) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexPericalcarine"					Name="Left Cortex Pericalcarine"
+(0199,002d) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexPostcentral"						Name="Left Cortex Postcentral"
+(0199,002e) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexPosteriorCingulate"				Name="Left Cortex Posterior Cingulate"
+(0199,002f) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexPrecentral"						Name="Left Cortex Precentral"
+(0199,0030) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexPrecuneus"						Name="Left Cortex Precuneus"
+(0199,0031) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexRostralAnteriorCingulate"		Name="Left Cortex Rostral Anterior Cingulate"
+(0199,0032) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexRostralMiddleFrontal"			Name="Left Cortex Rostral Middle Frontal"
+(0199,0033) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexSuperiorFrontal"					Name="Left Cortex Superior Frontal"
+(0199,0034) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexSuperiorParietal"				Name="Left Cortex Superior Parietal"
+(0199,0035) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexSuperiorTemporal"				Name="Left Cortex Superior Temporal"
+(0199,0036) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexSupramarginal"					Name="Left Cortex Supramarginal"
+(0199,0037) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexFrontalPole"						Name="Left Cortex Frontal Pole"
+(0199,0038) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexTemporalPole"					Name="Left Cortex Temporal Pole"
+(0199,0039) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftCortexTransvereTemporal"				Name="Left Cortex Transvere Temporal"
+(0199,003a) VERS="NQT" VR="FL"   VM="1"		Owner="NQLeft"									Keyword="LeftMeningie"								Name="Left Meningie"
+
+(0299,0001) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCorticalWhiteMatter"					Name="Right Cortical White Matter"
+(0299,0002) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCorticalGrayMatter"					Name="Right Cortical Gray Matter"
+(0299,0003) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="Right3rdVentricle"							Name="Right 3rd Ventricle"
+(0299,0004) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="Right4thVentricle"							Name="Right 4th Ventricle"
+(0299,0005) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="Right5thVentricle"							Name="Right 5th Ventricle"
+(0299,0006) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightLateralVentricle"						Name="Right Lateral Ventricle"
+(0299,0007) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightInferiorLateralVentricle"				Name="Right Inferior Lateral Ventricle"
+(0299,0008) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightInferiorCSF"							Name="Right Inferior CSF"
+(0299,0009) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCerebellarWhiteMatter"				Name="Right Cerebellar White Matter"
+(0299,000a) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCerebellarGrayMatter"					Name="Right Cerebellar Gray Matter"
+(0299,000b) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightHippocampus"							Name="Right Hippocampus"
+(0299,000c) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightAmygdala"								Name="Right Amygdala"
+(0299,000d) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightThalamus"								Name="Right Thalamus"
+(0299,000e) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCaudate"								Name="Right Caudate"
+(0299,000f) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightPutamen"								Name="Right Putamen"
+(0299,0010) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightPallidum"								Name="Right Pallidum"
+(0299,0011) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightVentralDiencephalon"					Name="Right Ventral Diencephalon"
+(0299,0012) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightNucleusAccumbens"						Name="Right Nucleus Accumbens"
+(0299,0013) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightBrainStem"							Name="Right Brain Stem"
+(0299,0014) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightExteriorCSF"							Name="Right Exterior CSF"
+(0299,0015) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightWMHypo"								Name="Right WM Hypo"
+(0299,0016) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightOther"								Name="Right Other"
+
+(0299,0017) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexUnkown"							Name="Right Cortex Unkown"
+(0299,0018) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexBankssts"						Name="Right Cortex Bankssts"
+(0299,0019) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexCaudalAnteriorCingulate"		Name="Right Cortex Caudal Anterior Cingulate"
+(0299,001a) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexCaudalMiddleFrontal"			Name="Right Cortex Caudal Middle Frontal"
+(0299,001b) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexCorpusCallosum"					Name="Right Cortex Corpus Callosum"
+(0299,001c) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexCuneus"							Name="Right Cortex Cuneus"
+(0299,001d) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexEntorhinal"						Name="Right Cortex Entorhinal"
+(0299,001e) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexFusiform"						Name="Right Cortex Fusiform"
+(0299,001f) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexInferiorParietal"				Name="Right Cortex Inferior Parietal"
+(0299,0020) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexInferiorTemporal"				Name="Right Cortex Inferior Temporal"
+(0299,0021) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexIsthmusCingulate"				Name="Right Cortex Isthmus Cingulate"
+(0299,0022) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexLateralOccipital"				Name="Right Cortex Lateral Occipital"
+(0299,0023) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexLateralOrbitoFrontal"			Name="Right Cortex Lateral Orbito Frontal"
+(0299,0024) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexLingual"						Name="Right Cortex Lingual"
+(0299,0025) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexMedialOrbitoFrontal"			Name="Right Cortex Medial Orbito Frontal"
+(0299,0026) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexMiddleTemporal"					Name="Right Cortex Middle Temporal"
+(0299,0027) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexParahippocampal"				Name="Right Cortex Parahippocampal"
+(0299,0028) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexParacentral"					Name="Right Cortex Paracentral"
+(0299,0029) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexParsOpercularis"				Name="Right Cortex Pars Opercularis"
+(0299,002a) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexParsOrbitalis"					Name="Right Cortex Pars Orbitalis"
+(0299,002b) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexParsTriangularis"				Name="Right Cortex Pars Triangularis"
+(0299,002c) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexPericalcarine"					Name="Right Cortex Pericalcarine"
+(0299,002d) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexPostcentral"					Name="Right Cortex Postcentral"
+(0299,002e) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexPosteriorCingulate"				Name="Right Cortex Posterior Cingulate"
+(0299,002f) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexPrecentral"						Name="Right Cortex Precentral"
+(0299,0030) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexPrecuneus"						Name="Right Cortex Precuneus"
+(0299,0031) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexRostralAnteriorCingulate"		Name="Right Cortex Rostral Anterior Cingulate"
+(0299,0032) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexRostralMiddleFrontal"			Name="Right Cortex Rostral Middle Frontal"
+(0299,0033) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexSuperiorFrontal"				Name="Right Cortex Superior Frontal"
+(0299,0034) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexSuperiorParietal"				Name="Right Cortex Superior Parietal"
+(0299,0035) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexSuperiorTemporal"				Name="Right Cortex Superior Temporal"
+(0299,0036) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexSupramarginal"					Name="Right Cortex Supramarginal"
+(0299,0037) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexFrontalPole"					Name="Right Cortex Frontal Pole"
+(0299,0038) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexTemporalPole"					Name="Right Cortex Temporal Pole"
+(0299,0039) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightCortexTransvereTemporal"				Name="Right Cortex Transvere Temporal"
+(0299,003a) VERS="NQT" VR="FL"   VM="1"		Owner="NQRight"									Keyword="RightMeningie"								Name="Right Meningie"
+
+(0013,0010) VERS="SEG" VR="LO"   VM="1"		Owner="CTP"										Keyword="ProjectName"				Name="Project Name"
+(0013,0011) VERS="SEG" VR="LO"   VM="1"		Owner="CTP"										Keyword="TrialName"					Name="Trial Name"
+(0013,0012) VERS="SEG" VR="LO"   VM="1"		Owner="CTP"										Keyword="SiteName"					Name="Site Name"
+(0013,0013) VERS="SEG" VR="LO"   VM="1"		Owner="CTP"										Keyword="SiteID"					Name="Site ID"
+
+(0055,0020) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIF 3.0 DATA"						Keyword="?"									Name="?"
+(0055,0030) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIF 3.0 DATA"						Keyword="IconData"							Name="Icon Data"
+(0055,0065) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIF 3.0 DATA"						Keyword="ImageHashValue"					Name="Image Hash Value"
+
+(0055,0010) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIM 5.0 DATA"						Keyword="?"									Name="?"
+(0055,0020) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIM 5.0 DATA"						Keyword="?"									Name="?"
+(0055,0030) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIM 5.0 DATA"						Keyword="IconData"							Name="Icon Data"
+(0055,0051) VERS="VEP" VR="UI"   VM="1"		Owner="VEPRO VIM 5.0 DATA"						Keyword="?"									Name="?"
+(0055,0065) VERS="VEP" VR="OB"   VM="1"		Owner="VEPRO VIM 5.0 DATA"						Keyword="ImageHashValue"					Name="Image Hash Value"
+
+(0057,0010) VERS="VEP" VR="SQ"   VM="1"		Owner="VEPRO BROKER 1.0"						Keyword="DataReplaceSequence"				Name="Data Replace Sequence"
+
+(0057,0020) VERS="VEP" VR="SQ"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="OriginalDataSequence"				Name="Original Data Sequence"
+(0057,0030) VERS="VEP" VR="SQ"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="ReplacedDataSequence"				Name="Replaced Data Sequence"
+(0057,0040) VERS="VEP" VR="DA"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="DateOfDataReplacement"				Name="Date of Data Replacement"
+(0057,0041) VERS="VEP" VR="TM"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="TimeOfDataReplacement"				Name="Time of Data Replacement"
+(0057,0042) VERS="VEP" VR="LO"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="DicomReceiveNode"					Name="Dicom Receive Node"
+(0057,0043) VERS="VEP" VR="LO"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="ApplicationName"					Name="Application Name"
+(0057,0044) VERS="VEP" VR="LO"   VM="1"		Owner="VEPRO BROKER 1.0 DATA REPLACE"			Keyword="ComputerName"						Name="Computer Name"
+
+(0059,0010) VERS="VEP" VR="SQ"   VM="1"		Owner="VEPRO DICOM TRANSFER 1.0"				Keyword="DicomTransferInfo"					Name="Dicom Transfer Info"
+
+(0059,0040) VERS="VEP" VR="DA"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveDate"						Name="Receive Date"
+(0059,0041) VERS="VEP" VR="TM"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveTime"						Name="Receive Time"
+(0059,0042) VERS="VEP" VR="ST"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveNode"						Name="Receive Node"
+(0059,0043) VERS="VEP" VR="ST"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveApplication"				Name="Receive Application"
+(0059,0050) VERS="VEP" VR="ST"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveLocalComputer"				Name="Receive Local Computer"
+(0059,0051) VERS="VEP" VR="ST"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveLocalAETitle"				Name="Receive Local AE Title"
+(0059,0060) VERS="VEP" VR="ST"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveRemoteComputer"				Name="Receive Remote Computer"
+(0059,0061) VERS="VEP" VR="ST"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveRemoteAETitle"				Name="Receive Remote AE Title"
+(0059,0070) VERS="VEP" VR="UI"   VM="1"		Owner="VEPRO DICOM RECEIVE DATA 1.0"			Keyword="ReceiveOriginalTransferSyntax"		Name="Receive Original Transfer Syntax"
+
+(0043,0010) VERS="D4C" VR="OB"   VM="1"		Owner="dcm4che/archive"							Keyword="PatientPk"								Name="Patient Pk"
+(0043,0011) VERS="D4C" VR="OB"   VM="1"		Owner="dcm4che/archive"							Keyword="StudyPk"								Name="Study Pk"
+(0043,0012) VERS="D4C" VR="OB"   VM="1"		Owner="dcm4che/archive"							Keyword="SeriesPk"								Name="Series Pk"
+(0043,0013) VERS="D4C" VR="OB"   VM="1"		Owner="dcm4che/archive"							Keyword="InstancePk"							Name="Instance Pk"
+(0043,0014) VERS="D4C" VR="AE"   VM="1"		Owner="dcm4che/archive"							Keyword="CallingAETitle"						Name="Calling AE Title"
+(0043,0015) VERS="D4C" VR="AE"   VM="1"		Owner="dcm4che/archive"							Keyword="CalledAETitle"							Name="Called AE Title"
+(0043,0016) VERS="D4C" VR="DT"   VM="1"		Owner="dcm4che/archive"							Keyword="InstanceUpdated"						Name="Instance Updated"
+(0043,0020) VERS="D4C" VR="SQ"   VM="1"		Owner="dcm4che/archive"							Keyword="WorkItemSeq"							Name="Work Item Sequence"
+(0043,0030) VERS="D4C" VR="UI"   VM="1"		Owner="dcm4che/archive"							Keyword="Dcm4cheURIReferencedTransferSyntaxUID"	Name="Dcm4che URI Referenced Transfer Syntax UID"
+
+(1269,0001) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyImage"						Name="Biopsy Image"
+(1269,0010) VERS="IMS" VR="IS"   VM="1-n"	Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyMarkersX"					Name="Biopsy Markers X"
+(1269,0011) VERS="IMS" VR="IS"   VM="1-n"	Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyMarkersY"					Name="Biopsy Markers Y"
+(1269,0012) VERS="IMS" VR="IS"   VM="1-n"	Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyMarkersNumber"				Name="Biopsy Markers Number"
+(1269,0020) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyAreaLeftBorder"				Name="Biopsy Area Left Border"
+(1269,0021) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyAreaRightBorder"				Name="Biopsy Area Right Border"
+(1269,0022) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyAreaTopBorder"				Name="Biopsy Area Top Border"
+(1269,0023) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyAreaBottomBorder"			Name="Biopsy Area Bottom Border"
+(1269,0024) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Biopsy Private Code"			Keyword="BiopsyNumber"						Name="Biopsy Number"
+
+(1271,0001) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold1"											Name="Threshold 1"
+(1271,0002) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold2"											Name="Threshold 2"
+(1271,0010) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="SegmentationLeftBorder"								Name="Segmentation Left Border"
+(1271,0011) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="SegmentationRightBorder"								Name="Segmentation Right Border"
+(1271,0012) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="SegmentationTopBorder"									Name="Segmentation Top Border"
+(1271,0013) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="SegmentationBottomBorder"								Name="Segmentation Bottom Border"
+(1271,0020) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="CompressorStatus"										Name="Compressor Status"
+(1271,0021) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="CollimatorType"										Name="Collimator Type"
+(1271,0022) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="BiopsySpecimen"										Name="Biopsy Specimen"
+(1271,0030) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="PrinterSegmentation"									Name="Printer Segmentation"
+(1271,0031) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10Format"										Name="Printer 8x10 Format"
+(1271,0032) VERS="IMS" VR="FD"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10SizeX"										Name="Printer 8x10 Size X"
+(1271,0033) VERS="IMS" VR="FD"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10SizeY"										Name="Printer 8x10 Size Y"
+(1271,0034) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10AreaLeftBorder"								Name="Printer 8x10 Area Left Border"
+(1271,0035) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10AreaRightBorder"							Name="Printer 8x10 Area Right Border"
+(1271,0036) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10AreaTopBorder"								Name="Printer 8x10 Area Top Border"
+(1271,0037) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Printer8x10AreaBottomBorder"							Name="Printer 8x10 Area Bottom Border"
+(1271,0038) VERS="IMS" VR="LO"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="RotationAndInclinationSensorPresence"					Name="Rotation And Inclination Sensor Presence"
+(1271,0039) VERS="IMS" VR="US"   VM="1-n"	Owner="IMS s.r.l. Mammography Private Code"			Keyword="WindowCenterForForProcessingImages"					Name="Window Center For For Processing Images"
+(1271,0040) VERS="IMS" VR="US"   VM="1-n"	Owner="IMS s.r.l. Mammography Private Code"			Keyword="WindowWidthForForProcessingImages"						Name="Window Width For For Processing Images"
+(1271,0041) VERS="IMS" VR="LO"   VM="1-n"	Owner="IMS s.r.l. Mammography Private Code"			Keyword="WindowCenterAndWidthExplanationForForProcessingImages"	Name="Window Center and Width Explanation For For Processing Images"
+(1271,0042) VERS="IMS" VR="LT"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="ProcessingInformation"									Name="Processing Information"
+(1271,0043) VERS="IMS" VR="LT"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Filename"												Name="Filename"
+(1271,0044) VERS="IMS" VR="LT"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="ContrastView"											Name="Contrast View"
+(1271,0045) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold3"											Name="Threshold 3"
+(1271,0046) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold4"											Name="Threshold 4"
+(1271,0047) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold5"											Name="Threshold 5"
+(1271,0048) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold6"											Name="Threshold 6"
+(1271,0049) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold7"											Name="Threshold 7"
+(1271,0050) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold8"											Name="Threshold 8"
+(1271,0051) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold9"											Name="Threshold 9"
+(1271,0052) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Threshold9"											Name="Threshold 9"
+(1271,0053) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="ScalingFactorForProcessing"							Name="Scaling Factor For Processing"
+(1271,0054) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="ConfirmXImage"											Name="ConfirmX Image"
+(1271,0055) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Backgroundcounts"										Name="Background counts"
+(1271,0056) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="WLRoiAreaX"											Name="WL Roi Area X"
+(1271,0057) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="WLRoiAreaY"											Name="WL Roi Area Y"
+(1271,0060) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="SecondProcessingImage"									Name="Second Processing Image"
+(1271,0061) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="SFilter"												Name="S Filter"
+(1271,0062) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="UFilter"												Name="U Filter"
+(1271,0063) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="Anonymous"												Name="Anonymous"
+(1271,0070) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoSAD"												Name="Tomo SAD"
+(1271,0071) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoDetectorYAW"										Name="Tomo Detector YAW"
+(1271,0072) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoDetectorPitch"										Name="Tomo Detector Pitch"
+(1271,0073) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoDetectorRoll"										Name="Tomo Detector Roll"
+(1271,0074) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoFocalSpotX"										Name="Tomo Focal Spot X"
+(1271,0075) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoFocalSpotY"										Name="Tomo Focal Spot Y"
+(1271,0076) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoXrayStartAngle"									Name="Tomo Xray Start Angle"
+(1271,0077) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoXrayEndAngle"										Name="Tomo Xray End Angle"
+(1271,0078) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoXrayAngle"											Name="Tomo Xray Angle"
+(1271,0079) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoExposureCounter"									Name="Tomo Exposure Counter"
+(1271,0080) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoExposureNumber"									Name="Tomo Exposure Number"
+(1271,0081) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoWLModified"										Name="Tomo WL Modified"
+(1271,0082) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="TomoProjection"										Name="Tomo Projection"
+(1271,0083) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="KeyObjectSelectionTitleCode"							Name="Key Object Selection Title Code"
+(1271,0084) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="RejectedForQualityReasonsCode"							Name="Rejected for Quality Reasons Code"
+(1271,0085) VERS="IMS" VR="IS"   VM="1"		Owner="IMS s.r.l. Mammography Private Code"			Keyword="?"														Name="?"
+
+(0031,0000) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0001) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0005) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0006) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0008) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0009) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,000a) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,000b) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,000c) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,000d) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,000e) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0010) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0011) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0012) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0013) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0014) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0015) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0016) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0017) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0018) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0019) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,001a) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,001b) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,001c) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,001d) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,001e) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0020) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0021) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0022) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0023) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0024) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0025) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0026) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0027) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0028) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0029) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,002a) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,002b) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,002c) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,002d) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,002e) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,002f) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0030) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0031) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0032) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0033) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0034) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0035) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0036) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0037) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0038) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0039) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,003a) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,003b) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,003c) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,003d) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,003e) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,003f) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0040) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0041) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0042) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0044) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0045) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0046) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0047) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0048) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0049) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,004a) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,004b) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,004c) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,004d) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,004e) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,004f) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0050) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0051) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0052) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0053) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0054) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0055) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0056) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0057) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0058) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0059) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,005a) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,005b) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,005c) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0062) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0063) VERS="KON" VR="US"   VM="3"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,006b) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0070) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0071) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0072) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0073) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0074) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0075) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0077) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0078) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0079) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,007a) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,007b) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,007c) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,007d) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,007e) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,007f) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0080) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0081) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0082) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0083) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0084) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0085) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0086) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0087) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0088) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0089) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,008a) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,008b) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,008c) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,008d) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,008e) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,008f) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0090) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0091) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0092) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0093) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0094) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,0095) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00a1) VERS="KON" VR="IS"   VM="2"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00a2) VERS="KON" VR="IS"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00a5) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00a6) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00a7) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00a8) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00aa) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ab) VERS="KON" VR="DA"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ac) VERS="KON" VR="TM"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ad) VERS="KON" VR="DA"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ae) VERS="KON" VR="TM"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b0) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b1) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b2) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b3) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b4) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b5) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b6) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b7) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b8) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00b9) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ba) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00bc) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00be) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00bf) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c0) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c1) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c2) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c3) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c4) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c5) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c6) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c7) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c8) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00c9) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ca) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00cb) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00cc) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00cd) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00ce) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00cf) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d0) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d1) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d2) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d3) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d4) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d5) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d6) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d7) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d8) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00d9) VERS="KON" VR="LO"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00da) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00db) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00dc) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00dd) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00de) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00df) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e0) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e1) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e2) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e3) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e4) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e5) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00e6) VERS="KON" VR="UN"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+(0031,00f0) VERS="KON" VR="US"   VM="1"		Owner="KONICA1.0"	Keyword="?"	Name="?"
+
+(0031,00ff) VERS="KON" VR="SQ"   VM="1"		Owner="KONICA1.0"	Keyword="PrivateDataSequence"	Name="Private Data Sequence"
+
+(0009,0001) VERS="DZD" VR="UI"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0002) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0003) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0004) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0005) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0006) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0007) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0008) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0011) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0012) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0013) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0014) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0015) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0016) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0017) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0070) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0071) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0072) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,0074) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,007a) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,00a1) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,00a2) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,00f1) VERS="DZD" VR="LO"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,00f7) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+(0009,00f9) VERS="DZD" VR="IS"   VM="1"		Owner="DZDICOM 4.3.0"	Keyword="?"	Name="?"
+
+(0019,0050) VERS="FOEM"  VR="IS"   VM="1"	Owner="FOEM 1.0"	Keyword="?"	Name="?"
+(0025,0010) VERS="FOEM"  VR="US"   VM="1"	Owner="FOEM 1.0"	Keyword="?"	Name="?"
+(0025,0012) VERS="FOEM"  VR="US"   VM="1"	Owner="FOEM 1.0"	Keyword="?"	Name="?"
+(0029,0020) VERS="FOEM"  VR="IS"   VM="1"	Owner="FOEM 1.0"	Keyword="?"	Name="?"
+
+(5533,0033) VERS="VIS"  VR="SQ"   VM="1"	Owner="Visus Change"	Keyword="SaveSequence"		Name="Save Sequence"
+(5533,0035) VERS="VIS"  VR="DA"   VM="1"	Owner="Visus Change"	Keyword="SaveDate"			Name="Save Date"
+(5533,0037) VERS="VIS"  VR="LO"   VM="1"	Owner="Visus Change"	Keyword="SaveOriginator"	Name="Save Originator"
+(5533,0039) VERS="VIS"  VR="FD"   VM="1"	Owner="Visus Change"	Keyword="SaveID"			Name="Save ID"
+(5533,003b) VERS="VIS"  VR="TM"   VM="1"	Owner="Visus Change"	Keyword="SaveTime"			Name="Save Time"
+
+(0099,0001) VERS="SYN"  VR="OB"   VM="1"	Owner="SYNARC_1.0"	Keyword="?"	Name="?"
+(0099,0002) VERS="SYN"  VR="OB"   VM="1"	Owner="SYNARC_1.0"	Keyword="?"	Name="?"
+(0099,0003) VERS="SYN"  VR="LO"   VM="1"	Owner="SYNARC_1.0"	Keyword="?"	Name="?"
+(0099,0004) VERS="SYN"  VR="US"   VM="1-n"	Owner="SYNARC_1.0"	Keyword="?"	Name="?"
+(0099,0005) VERS="SYN"  VR="LO"   VM="1"	Owner="SYNARC_1.0"	Keyword="?"	Name="?"
+
+(0011,0002) VERS="PMP" VR="UC"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainDescription"					Name="Strain Description"
+(0011,0003) VERS="PMP" VR="LO"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainNomenclature"				Name="Strain Nomenclature"
+(0011,0004) VERS="PMP" VR="LO"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainStockNumber"					Name="Strain Stock Number"
+(0011,0005) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainSourceRegistryCodeSequence"	Name="Strain Source Registry Code Sequence"
+(0011,0006) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainStockSequence"				Name="Strain Stock Sequence"
+(0011,0007) VERS="PMP" VR="LO"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainSource"						Name="Strain Source"
+(0011,0008) VERS="PMP" VR="UT"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainAdditionalInformation"		Name="Strain Additional Information"
+(0011,0020) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="StrainCodeSequence"				Name="Strain Code Sequence"
+(0011,0050) VERS="PMP" VR="LO"   VM="1"		Owner="PixelMed Publishing"							Keyword="CellLineDesignation"					Name="Cell Line Designation"
+(0011,0051) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="CellLineTissueOfOriginCodeSequence"	Name="Cell Line Tissue of Origin Code Sequence"
+(0011,0052) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="CellLineHistologicTypeCodeSequence"	Name="Cell Line Histologic Type Code Sequence"
+(0011,0053) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="CellLineSpeciesOfOriginCodeSequence"	Name="Cell Line Species of Origin Code Sequence"
+(0011,0054) VERS="PMP" VR="UL"   VM="1"		Owner="PixelMed Publishing"							Keyword="CellLineNumberOfPassages"				Name="Cell Line Number of Passages"
+(0011,0071) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="SourcePatientGroupIdentificationSequence"	Name="Source Patient Group Identification Sequence"
+(0011,0072) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="GroupOfPatientsIdentificationSequence"		Name="Group of Patients Identification Sequence"
+(0011,0073) VERS="PMP" VR="US"   VM="3"		Owner="PixelMed Publishing"							Keyword="SubjectRelativePositionInImage"			Name="Subject Relative Position in Image"
+
+(0021,0001) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="UnassignedSharedConvertedAttributesSequence"			Name="Unassigned Shared Converted Attributes Sequence"
+(0021,0002) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="UnassignedPerFrameConvertedAttributesSequence"			Name="Unassigned Per-Frame Converted Attributes Sequence"
+(0021,0003) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="ConversionSourceAttributesSequence"					Name="Conversion Source Attributes Sequence"
+
+(0041,0001) VERS="PMP" VR="SQ"   VM="1"		Owner="PixelMed Publishing"							Keyword="QuantityDefinitionCodeSequence"						Name="Quantity Definition Code Sequence"
+
+(7FE1,0001) VERS="PMP" VR="OF"   VM="1"		Owner="PixelMed Publishing"							Keyword="FloatPixelData"										Name="Float Pixel Data"
+(7FE1,0002) VERS="PMP" VR="OD"   VM="1"		Owner="PixelMed Publishing"							Keyword="DoublePixelData"										Name="Double Pixel Data"
+
+(0011,0001) VERS="MEG"  VR="LT"   VM="1"	Owner="METAEMOTION GINKGO"	Keyword="KeyFileIndicator"				Name="KeyFile Indicator"
+(0011,000B) VERS="MEG"  VR="LT"   VM="1"	Owner="METAEMOTION GINKGO"	Keyword="SerializedDiagnoseAndMarkers"	Name="Serialized Diagnose and Markers"
+
+(0011,0001) VERS="MEG"  VR="LT"   VM="1"	Owner="METAEMOTION GINKGO RETINAL"	Keyword="KeyFileIndicator"				Name="KeyFile Indicator"
+(0011,000B) VERS="MEG"  VR="LT"   VM="1"	Owner="METAEMOTION GINKGO RETINAL"	Keyword="SerializedDiagnoseAndMarkers"	Name="Serialized Diagnose and Markers"
+(0011,000C) VERS="MEG"  VR="UN"   VM="1"	Owner="METAEMOTION GINKGO RETINAL"	Keyword="VirtualAneritraContrastImage"	Name="Virtual Aneritra Contrast Image"
+
+(0055,0001) VERS="PMOD" VR="FD"   VM="1-n"	Owner="PMOD_1"	Keyword="FrameStartTimesVector"		Name="Frame Start Times Vector"
+(0055,0002) VERS="PMOD" VR="FD"   VM="3-3n"	Owner="PMOD_1"	Keyword="FramePositionsVector"		Name="Frame Positions Vector"
+(0055,0003) VERS="PMOD" VR="FD"   VM="6-6n"	Owner="PMOD_1"	Keyword="FrameOrientationsVector"	Name="Frame Orientations Vector"
+(0055,0004) VERS="PMOD" VR="FD"   VM="1-n"	Owner="PMOD_1"	Keyword="FrameDurationsVector"		Name="Frame Durations Vector"
+(0055,0005) VERS="PMOD" VR="FD"   VM="1-n"	Owner="PMOD_1"	Keyword="FrameRescaleSlopeVector"	Name="Frame Rescale Slope Vector"
+
+(7fe1,0001) VERS="PMOD" VR="UT"   VM="1"	Owner="PMOD_GENPET"	Keyword="SlicesNames"			Name="Slices Names"
+(7fe1,0002) VERS="PMOD" VR="UT"   VM="1"	Owner="PMOD_GENPET"	Keyword="GeneCodes"				Name="Gene Codes"
+(7fe1,0003) VERS="PMOD" VR="UT"   VM="1"	Owner="PMOD_GENPET"	Keyword="GeneLabels"			Name="Gene Labels"
+
+(0011,0001) VERS="ULV" VR="CS"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0002) VERS="ULV" VR="UN"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0003) VERS="ULV" VR="UN"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0008) VERS="ULV" VR="LO"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0010) VERS="ULV" VR="US"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0011) VERS="ULV" VR="UN"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0012) VERS="ULV" VR="UI"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0018) VERS="ULV" VR="UL"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,0019) VERS="ULV" VR="UN"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,001a) VERS="ULV" VR="CS"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,001b) VERS="ULV" VR="IS"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,001c) VERS="ULV" VR="IS"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+(0011,001d) VERS="ULV" VR="LO"   VM="1"	Owner="ULTRAVISUAL_TAG_SET1"	Keyword="?"			Name="?"
+
+(0029,0010) VERS="CDN" VR="DS"   VM="1"	Owner="ShowcaseAppearance"	Keyword="?"			Name="?"
+(0029,0011) VERS="CDN" VR="DS"   VM="1"	Owner="ShowcaseAppearance"	Keyword="?"			Name="?"
+(0029,0012) VERS="CDN" VR="DS"   VM="1"	Owner="ShowcaseAppearance"	Keyword="?"			Name="?"
+(0029,0013) VERS="CDN" VR="DS"   VM="1"	Owner="ShowcaseAppearance"	Keyword="?"			Name="?"
+(0029,0014) VERS="CDN" VR="SQ"   VM="1"	Owner="ShowcaseAppearance"	Keyword="?"			Name="?"
+
+(0015,0028) VERS="MAT" VR="LO"   VM="1"	Owner="MATAKINA_10"	Keyword="VolparaDensityGrade"			Name="Volpara Density Grade"
+(0015,0029) VERS="MAT" VR="LT"   VM="1"	Owner="MATAKINA_10"	Keyword="VolparaRunInformation"			Name="Volpara Run Information"
+(0015,0030) VERS="MAT" VR="LO"   VM="1"	Owner="MATAKINA_10"	Keyword="VolparaDensityGradeCutoffs"	Name="Volpara Density Grade Cutoffs"
+
+(0101,0005) VERS="PM" VR="LO"   VM="1-n"	Owner="PM"	Keyword="ImageEnhancementParameterFile"		Name="Image Enhancement Parameter File"
+(0101,0006) VERS="PM" VR="IS"   VM="1"		Owner="PM"	Keyword="OriginalSigmoidRatio"				Name="Original Sigmoid Ratio"
+
+(0863,0010) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="ImageType"									Name="Image Type"
+(0863,0023) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="CalibrationFlag"							Name="Calibration Flag"
+(0863,0026) VERS="EOS" VR="UL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="AttributeVersion"							Name="Attribute Version"
+(0863,0027) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="ResizingFlag"								Name="Resizing Flag"
+(0863,0028) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="LogarithmFlag"								Name="Logarithm Flag"
+(0863,0032) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="LeftCollimatorEdge"						Name="Left Collimator Edge"
+(0863,0033) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="RightCollimatorEdge"						Name="Right Collimator Edge"
+(0863,0034) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="DistanceSourceToPatientOfBiplanePair"		Name="Distance Source to Patient of Biplane Pair"
+(0863,0035) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="LineCorrectionFlag"						Name="Line Correction Flag"
+(0863,0036) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="ContrastEnhancementFlag"					Name="Contrast Enhancement Flag"
+(0863,0037) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="CalibreValue"								Name="Calibre Value"
+(0863,0038) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="HighFrequencyLineCorrectionMaxThreshold"	Name="High Frequency Line Correction Max Threshold"
+(0863,0039) VERS="EOS" VR="SL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="HighFrequencyLineCorrectionMinThreshold"	Name="High Frequency Line Correction Min Threshold"
+(0863,0040) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="GreaterLimit"								Name="Greater Limit"
+(0863,0041) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="LowerLimit"								Name="Lower Limit"
+(0863,0042) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="FrontalDetectorBladesOpening"				Name="Frontal Detector Blades Opening"
+(0863,0043) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="FrontalTubeBladesOpening"					Name="Frontal Tube Blades Opening"
+(0863,0044) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="LateralDetectorBladesOpening"				Name="Lateral Detector Blades Opening"
+(0863,0045) VERS="EOS" VR="FL"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="LateralTubeBladesOpening"					Name="Lateral Tube Blades Opening"
+(0863,0046) VERS="EOS" VR="DS"   VM="1-n"	Owner="Biospace Med : EOS Tag"	Keyword="ThreeDCalibrationParameters"				Name="ThreeD Calibration Parameters"
+(0863,0057) VERS="EOS" VR="CS"   VM="1"		Owner="Biospace Med : EOS Tag"	Keyword="ImageHorizontalFlip"						Name="Image Horizontal Flip"
+
+(0019,0000) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_0019"	Keyword="Calibration"					Name="Calibration"
+(0019,0001) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_0019"	Keyword="DepthConversion"				Name="Depth Conversion"
+(0019,0002) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_0019"	Keyword="Stepsize"						Name="Stepsize"
+(0019,0003) VERS="ONC" VR="SL"   VM="1-n"	Owner="PRIVATE_CODE_STRING_0019"	Keyword="Warning"						Name="Warning"
+(0019,0004) VERS="ONC" VR="ST"   VM="1"		Owner="PRIVATE_CODE_STRING_0019"	Keyword="DataID"						Name="DataID"
+
+(0021,0070) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_0021"	Keyword="DistanceBasePlaneToTemplate"	Name="Distance Base Plane to Template"
+(0021,0071) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_0021"	Keyword="VolumeToPatientMatrix"			Name="Volume to Patient Matrix"
+(0021,0072) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_0021"	Keyword="PatientToWorldMatrix"			Name="Patient to World Matrix"
+(0021,0073) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_0021"	Keyword="BasePlane"						Name="Base Plane" 
+(0021,0074) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_0021"	Keyword="ReferencePlane"				Name="Reference Plane" 
+(0021,0075) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_0021"	Keyword="ApexPlane"						Name="Apex Plane" 
+(0021,0076) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_0021"	Keyword="BasePlaneOffset"				Name="Base Plane Offset" 
+
+(1001,00A0) VERS="ONC" VR="SQ"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="MarkerSequence"				Name="Marker Sequence"
+(1001,00A1) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="MarkerType"					Name="Marker Type"
+(1001,00A2) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="MarkerNumber"					Name="Marker Number"
+(1001,00A3) VERS="ONC" VR="FD"   VM="3"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Marker3DPosition"				Name="Marker 3D Position"
+
+(1001,00B0) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DistanceUnit"							Name="Distance Unit"
+(1001,00B1) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DoseUnit"								Name="Dose Unit"
+(1001,00B2) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="NormalisationMode"						Name="Normalisation Mode"
+(1001,00B3) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="NormalisationFactor"					Name="Normalisation Factor"
+(1001,00B4) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="FValue"								Name="F-Value"
+(1001,00B5) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="PrescribedDose"						Name="Prescribed Dose"
+(1001,00B6) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="AbsoluteDoseFactor"					Name="Absolute Dose Factor"
+(1001,00B7) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DecoupledSK"							Name="Decoupled sk"
+(1001,00B8) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="AbsoluteTimeFactor"					Name="Absolute Time Factor"
+(1001,00B9) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Total Treatment Time"					Name="Total Treatment Time"
+(1001,00BA) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="TG43Model"								Name="TG 43 Model"
+(1001,00BB) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ThreeDDoseGridSize"					Name="3D Dose Grid Size"
+(1001,00BC) VERS="ONC" VR="FD"   VM="3"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DoseGridCorner1"						Name="Dose Grid Corner 1"
+(1001,00BD) VERS="ONC" VR="FD"   VM="3"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DoseGridCorner2"						Name="Dose Grid Corner 2"
+(1001,00BE) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="PatientDataConversion"					Name="Patient Data Conversion"
+(1001,00BF) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VolumeDataConversion"					Name="Volume Data Conversion"
+(1001,00C0) VERS="ONC" VR="FD"   VM="3"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VolumeDataVector"						Name="Volume Data Vector"
+(1001,00C1) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="OptimizationMethod"					Name="Optimization Method"
+(1001,00C2) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DisplayMethod"							Name="Display Method"
+(1001,00C3) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="GeometricalMethod"						Name="Geometrical Method"
+(1001,00C3) VERS="ONC" VR="SQ"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIBasedOptimizationSettingsSequence"	Name="VOI Based Optimization Settings Sequence"
+(1001,00C5) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOINumber"								Name="VOI Number"
+(1001,00C6) VERS="ONC" VR="LO"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIName"								Name="VOI Name"
+(1001,00C7) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIType"								Name="VOI Type"
+(1001,00C8) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIClass"								Name="VOI Class"
+(1001,00C9) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIPriority"							Name="VOI Priority"
+(1001,00CA) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="NoOfPoints"							Name="No of Points"
+(1001,00CB) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="PercentOnSurface"						Name="Percent On Surface"
+(1001,00CC) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="SurfaceMargin"							Name="Surface Margin"
+(1001,00CD) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Selected"								Name="Selected"
+(1001,00CE) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DoseLimit"								Name="Dose Limit"
+(1001,00CF) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ImportanceFactor"						Name="Importance Factor"
+(1001,00D0) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ImportanceFactorFrom"					Name="Importance Factor From"
+(1001,00D1) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ImportanceFactorTo"					Name="Importance Factor To"
+(1001,00D2) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Focus"									Name="Focus"
+(1001,00D3) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="SurfaceSamplingMethod"					Name="Surface Sampling Method"
+(1001,00D4) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="NumberOfSamplingPointsPerccm"			Name="Number of Sampling Points Per ccm"
+(1001,00D5) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ConvergenceAccuracy"					Name="Convergence Accuracy"
+(1001,00D6) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="MaxNoOfConvergenceIterations"			Name="Max No of Convergence Iterations"
+(1001,00D7) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WeightSmoothing"						Name="Weight Smoothing"
+(1001,00D8) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="StepsPerImportanceFactor"				Name="Steps Per Importance Factor"
+(1001,00D9) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ConstraintsPTVDmax"					Name="Constraints PTVDmax"
+(1001,00DA) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="ConstraintsNTDmax"						Name="Constraints NTDmax"
+(1001,00DB) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="AlgorithmicPopulationSize"				Name="Algorithmic Population Size"
+(1001,00DC) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="AlgorithmicGenerations"				Name="Algorithmic Generations"
+(1001,00DD) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="AlgorithmicInitializations"			Name="Algorithmic Initializations"
+(1001,00DE) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="MinNoOfSDP"							Name="Min No Of SDP"
+(1001,00DF) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DepthMethod"							Name="Depth Method"
+(1001,00E0) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="DepthDefinedOn"						Name="Depth Defined On"
+(1001,00E1) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Depth"									Name="Depth"
+(1001,00E2) VERS="ONC" VR="SQ"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIBasedPlacementSettingsSequence"		Name="VOI Based Placement Settings Sequence"
+(1001,00C5) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOINumber"								Name="VOI Number"
+(1001,00C6) VERS="ONC" VR="LO"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIName"								Name="VOI Name"
+(1001,00C7) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIType"								Name="VOI Type"
+(1001,00C8) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOIClass"								Name="VOI Class"
+(1001,00E7) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="VOISelected"							Name="VOI Selected"
+(1001,00E8) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Margin"								Name="Margin"
+(1001,00E9) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="SelectionMethod"						Name="Selection Method"
+(1001,00EA) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="SelectionDistance"						Name="Selection Distance"
+(1001,00EB) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTOnContourSpacing"					Name="WBT On Contour Spacing"
+(1001,00EC) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTUrethraMargin"						Name="WBT Urethra Margin"
+(1001,00ED) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTSearchingRadiusPTV"					Name="WBT Searching Radius PTV"
+(1001,00EE) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTSearchingRadiusOAR"					Name="WBT Searching Radius OAR"
+(1001,00EF) VERS="ONC" VR="FD"   VM="3"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTStartingPoint"						Name="WBT Starting Point"
+(1001,00F0) VERS="ONC" VR="FD"   VM="4"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTSurface"							Name="WBT Surface"
+(1001,00F1) VERS="ONC" VR="FD"   VM="4"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTNoOfInteriorCatheters"				Name="WBT No of Interior Catheters"
+(1001,00F2) VERS="ONC" VR="FD"   VM="4"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="WBTRelativeRadius"						Name="WBT Relative Radius"
+(1001,00F3) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_1001"	Keyword="Sorting Method"						Name="Sorting Method"
+
+(1003,0001) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="NumberOfProbes"				Name="Number Of Probes"
+(1003,0010) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="US Probe Sequence"				Name="US Probe Sequence"
+(1003,0011) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Identifier"					Name="Identifier"
+(1003,0012) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Probe Name"					Name="Probe Name"
+(1003,0013) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Depth"							Name="Depth"
+(1003,0014) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Frequency"						Name="Frequency"
+(1003,0015) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Gain	"						Name="Gain"
+(1003,0016) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Power"							Name="Power"
+(1003,0017) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="DynamicRange"					Name="Dynamic Range"
+(1003,0018) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="FrameAveraging"				Name="Frame Averaging"
+(1003,0019) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="FieldOfView"					Name="Field Of View"
+(1003,0020) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="TGC"							Name="TGC"
+(1003,002A) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="NumberOfFocusSets"				Name="Number Of Focus Sets"
+(1003,002B) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="CurrentFocusSet"				Name="Current Focus Set"
+(1003,002C) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="ImageEnhancementFilterIndex"	Name="Image Enhancement Filter Index"
+(1003,002D) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="RejectionFilterLow"			Name="Rejection Filter Low"
+(1003,002E) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="RejectionFilterHigh"			Name="Rejection Filter High"
+(1003,002F) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Brightness"					Name="Brightness"
+(1003,0030) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Contrast"						Name="Contrast"
+(1003,0031) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Gamma"							Name="Gamma"
+(1003,0032) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="SpeckleEnabled"				Name="Speckle Enabled"
+(1003,0033) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="SpeckleLevel"					Name="Speckle Level"
+(1003,0040) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="FocusSetSequence"				Name="Focus Set Sequence"
+(1003,0041) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Identifier"					Name="Identifier"
+(1003,0042) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="NumberOfFocusZone"				Name="Number Of Focus Zone"
+(1003,0043) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_1003"	Keyword="Focus"							Name="Focus"
+
+(3007,0000) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_3007"	Keyword="VolumeToPatientMatrix"			Name="Volume to Patient Matrix"
+(3007,0001) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_3007"	Keyword="VolumeResolutionConversion"	Name="Volume Resolution Conversion"
+(3007,0002) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_3007"	Keyword="VolumeDataConversion"			Name="Volume Data Conversion"
+(3007,0003) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_3007"	Keyword="PatientDataConversion"			Name="Patient Data Conversion"
+(3007,0004) VERS="ONC" VR="FD"   VM="16"	Owner="PRIVATE_CODE_STRING_3007"	Keyword="DICOMDataConversion"			Name="DICOM Data Conversion"
+
+(300B,0000) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="TemplateMode"					Name="Template Mode" 
+(300B,0001) VERS="ONC" VR="LO"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="TemplateID"					Name="Template ID" 
+(300B,0002) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="NumberOfColumns"				Name="Number of Columns"
+(300B,0003) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="ColumnDistance"				Name="Column Distance" 
+(300B,0004) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="NumberORows"					Name="Number of Rows" 
+(300B,0005) VERS="ONC" VR="FD"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="Row Distance"					Name="Row Distance" 
+(300B,0006) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="Origin"						Name="Origin" 
+(300B,0007) VERS="ONC" VR="SH"   VM="1-n"	Owner="PRIVATE_CODE_STRING_300B"	Keyword="ColumnNumbering"				Name="Column Numbering" 
+(300B,0008) VERS="ONC" VR="SH"   VM="1-n"	Owner="PRIVATE_CODE_STRING_300B"	Keyword="RowNumbering"					Name="Row Numbering"
+(300B,0009) VERS="ONC" VR="SS"   VM="1-n"	Owner="PRIVATE_CODE_STRING_300B"	Keyword="UsedHolesArray"				Name="Used Holes Array"
+(300B,000A) VERS="ONC" VR="SL"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="LockStatus"					Name="Lock Status" 
+(300B,000C) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="Identifier"					Name="Identifier"
+(300B,000D) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="ModificationType"				Name="Modification Type"
+(300B,000E) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="ModificationValue"				Name="Modification Value"
+(300B,000F) VERS="ONC" VR="UN"   VM="1"		Owner="PRIVATE_CODE_STRING_300B"	Keyword="TransformationMatrix"			Name="Transformation Matrix"
+
+(000D,0000) VERS="INS" VR="OB"   VM="1"		Owner="INSTRU_PRIVATE_IDENT_CODE"	Keyword="ImageXmlData"					Name="Image Xml Data"	RenderAsString="true"
+(000D,0000) VERS="INS" VR="OB"   VM="1"		Owner="SCANORA_PRIVATE_IDENT_CODE"	Keyword="ImageXmlData"					Name="Image Xml Data"	RenderAsString="true"
+
+(0019,0002) VERS="NNT" VR="US"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0003) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0004) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0005) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0006) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0007) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0009) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,000a) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,000b) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,000c) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,000d) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,000e) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,000f) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0012) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0013) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,001e) VERS="NNT" VR="DS"   VM="3"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,001f) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0020) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0021) VERS="NNT" VR="DS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0022) VERS="NNT" VR="IS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0023) VERS="NNT" VR="IS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0024) VERS="NNT" VR="LO"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0025) VERS="NNT" VR="IS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0026) VERS="NNT" VR="LO"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0027) VERS="NNT" VR="LO"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0028) VERS="NNT" VR="LO"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0030) VERS="NNT" VR="LO"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0031) VERS="NNT" VR="IS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0032) VERS="NNT" VR="IS"   VM="1"		Owner="NNT"	Keyword="?"	Name="?"
+(0019,0033) VERS="NNT" VR="DS"   VM="8"		Owner="NNT"	Keyword="?"	Name="?"
+
+(3335,0000) VERS="iCAD" VR="UN"   VM="1"	Owner="CAD Sciences"	Keyword="?"	Name="?"
+(3335,0006) VERS="iCAD" VR="UN"   VM="1"	Owner="CAD Sciences"	Keyword="?"	Name="?"
+(3335,0007) VERS="iCAD" VR="UN"   VM="1"	Owner="CAD Sciences"	Keyword="?"	Name="?"
+(3335,0008) VERS="iCAD" VR="UN"   VM="1"	Owner="CAD Sciences"	Keyword="?"	Name="?"
+
+(3335,0010) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0015) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0016) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0017) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0018) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,002a) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0034) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0035) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,003b) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0040) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0050) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0051) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0052) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0053) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0054) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0055) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0056) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0057) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0070) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0071) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0072) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0073) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0074) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0075) VERS="iCAD" VR="UN"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0080) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0081) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0082) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0083) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0084) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0085) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0086) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0087) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0088) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0089) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,008a) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,008b) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,008c) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,008d) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,008e) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,008f) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0090) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0091) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0092) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0093) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0094) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,0095) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a0) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a1) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a2) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a3) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a4) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a5) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a6) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a7) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a8) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00a9) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00aa) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00ab) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00ac) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00ad) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00ae) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00af) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00b0) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00b1) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+(3335,00c0) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK"	Keyword="?"	Name="?"
+
+(3335,0000) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0001) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0002) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0003) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0004) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0005) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0006) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0007) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0008) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0009) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,000a) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,000b) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,000c) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,000d) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,000e) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,000f) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0010) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0011) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0012) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0013) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0014) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0015) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0016) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0017) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0018) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,0019) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,001a) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+(3335,001b) VERS="iCAD" VR="LO"   VM="1"	Owner="iCAD PK Study"	Keyword="?"	Name="?"
+
+(7fdf,0050) VERS="TTC" VR="OB"   VM="1"	Owner="TomTec"	Keyword="?"	Name="?"	RenderAsString="true"
+(7fdf,0051) VERS="TTC" VR="OB"   VM="1"	Owner="TomTec"	Keyword="?"	Name="?"	RenderAsString="true"
+
+(0029,0015) VERS="CARE" VR="LO"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+(0029,0016) VERS="CARE" VR="LO"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+(0029,0017) VERS="CARE" VR="LO"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+(0029,0018) VERS="CARE" VR="UT"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+(0029,0019) VERS="CARE" VR="IS"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+(0029,001a) VERS="CARE" VR="IS"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+(0029,001b) VERS="CARE" VR="IS"   VM="1"	Owner="CARESTREAM IMAGE INFORMATION"	Keyword="?"	Name="?"
+
+(ffff,00ff) VERS="CARE" VR="UN"   VM="1"	Owner="Carestream Health TIFF"	Keyword="?"	Name="?"
+
+(3111,0010) VERS="RAM" VR="CS"   VM="1"	Owner="RamSoft File Kind Identifier"		Keyword="BinaryDocumentKind"	Name="Binary Document Type"
+(3113,0010) VERS="RAM" VR="OB"   VM="1"	Owner="RamSoft Custom Report Identifier"	Keyword="BinaryDocument"		Name="Binary Document"
+(3113,0020) VERS="RAM" VR="UL"   VM="1"	Owner="RamSoft Custom Report Identifier"	Keyword="BinaryDocumentSize"	Name="Binary Document Size"
+(3129,0010) VERS="RAM" VR="LO"   VM="1"	Owner="RamSoft Race Identifier"				Keyword="?"						Name="?"
+
+(0011,0001) VERS="MDDX" VR="UT"   VM="1"	Owner="MDDX"	Keyword="AESEncryptedValues"	Name="AES Encrypted Values"
+(0011,0002) VERS="MDDX" VR="LO"   VM="1"	Owner="MDDX"	Keyword="AllupVersionDetails"	Name="Allup Version Details"
+(0011,0003) VERS="MDDX" VR="LO"   VM="1"	Owner="MDDX"	Keyword="MaskID"				Name="Mask Id"
+
+(7fe1,0001) VERS="MDDX" VR="UT"   VM="1"	Owner="MDDX"	Keyword="AESEncryptedValues"	Name="AES Encrypted Values"
+(7fe1,0002) VERS="MDDX" VR="LO"   VM="1"	Owner="MDDX"	Keyword="AllupVersionDetails"	Name="Allup Version Details"
+(7fe1,0003) VERS="MDDX" VR="LO"   VM="1"	Owner="MDDX"	Keyword="MaskID"				Name="Mask Id"
+
+(0099,0000) VERS="QTU" VR="SS"   VM="1"	Owner="QTUltrasound"	Keyword="BreastDensityValue"	Name="Breast Density Value"
+
+(0009,0035) VERS="MDSO" VR="DS"   VM="1"	Owner="BioscanMedisoScivisNanoSPECT"	Keyword="?"	Name="?"
+
+(0009,0030) VERS="MDSO" VR="DT"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,0036) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00c0) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00c1) VERS="MDSO" VR="OB"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"	RenderAsString="true"
+(0009,00c4) VERS="MDSO" VR="OB"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00d2) VERS="MDSO" VR="LO"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00d5) VERS="MDSO" VR="LO"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00dc) VERS="MDSO" VR="SQ"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00de) VERS="MDSO" VR="UL"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00df) VERS="MDSO" VR="UL"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00e0) VERS="MDSO" VR="US"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00e1) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00e6) VERS="MDSO" VR="OB"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00e9) VERS="MDSO" VR="UI"   VM="1-n"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00ee) VERS="MDSO" VR="DT"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00ef) VERS="MDSO" VR="DT"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00f0) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00f1) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00f2) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00f3) VERS="MDSO" VR="FD"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00fa) VERS="MDSO" VR="ST"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00fb) VERS="MDSO" VR="US"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+(0009,00fb) VERS="MDSO" VR="US"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+
+(0011,0006) VERS="MDSO" VR="LO"   VM="1"	Owner="MEDISO-1"	Keyword="?"	Name="?"
+
+(6001,00a0) VERS="SVIS" VR="DS"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a1) VERS="SVIS" VR="DS"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a2) VERS="SVIS" VR="US"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a3) VERS="SVIS" VR="DS"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a4) VERS="SVIS" VR="IS"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a5) VERS="SVIS" VR="ST"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a6) VERS="SVIS" VR="ST"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a7) VERS="SVIS" VR="FL"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a8) VERS="SVIS" VR="FL"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00a9) VERS="SVIS" VR="IS"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00aa) VERS="SVIS" VR="IS"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+(6001,00ab) VERS="SVIS" VR="ST"   VM="1"	Owner="SCIVIS-1"	Keyword="?"	Name="?"
+
+(0009,0031) VERS="BLB" VR="SQ"   VM="1"	Owner="Brainlab-S9-History"	Keyword="?"	Name="?"
+(0009,0032) VERS="BLB" VR="SQ"   VM="1"	Owner="Brainlab-S9-History"	Keyword="?"	Name="?"
+(0009,0033) VERS="BLB" VR="SQ"   VM="1"	Owner="Brainlab-S9-History"	Keyword="?"	Name="?"
+
+(0063,0001) VERS="BLB" VR="LO"   VM="1"	Owner="Brainlab-S32-SO"	Keyword="?"	Name="?"
+(0063,0010) VERS="BLB" VR="SQ"   VM="1"	Owner="Brainlab-S32-SO"	Keyword="?"	Name="?"
+
+(0073,0010) VERS="BLB" VR="SQ"   VM="1"	Owner="Brainlab-S23-ProjectiveFusion"	Keyword="ProjectiveRegistrationSequence"	Name="Projective Registration Sequence"
+
diff --git a/libsrc/standard/elmdict/papyrus.tpl b/libsrc/standard/elmdict/papyrus.tpl
new file mode 100755
index 0000000..732ca89
--- /dev/null
+++ b/libsrc/standard/elmdict/papyrus.tpl
@@ -0,0 +1,59 @@
+(0009,0000) VERS="PAP"  VR="LT"   VM="1"	Owner="PAPYRUS"	Keyword="OriginalFileName"			Name="Original File Name"
+(0009,0010) VERS="PAP"  VR="LT"   VM="1"	Owner="PAPYRUS"			Keyword="OriginalFileLocation"		Name="Original File Location"
+(0009,0018) VERS="PAP"  VR="LT"   VM="1"	Owner="PAPYRUS"			Keyword="DataSetIdentifier"		Name="Data Set Identifier"
+(0041,0000) VERS="PA3"	VR="LT"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="PapyrusComments"			Name="Papyrus Comments"
+(0041,0000) VERS="PAP"	VR="LT"   VM="1-n"	Owner="PAPYRUS"	Keyword="PapyrusComments"			Name="Papyrus Comments"
+(0041,0010) VERS="PA3"	VR="SQ"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="PointerSequence"			Name="Pointer Sequence"
+(0041,0010) VERS="PAP"	VR="US"   VM="1"	Owner="PAPYRUS"	Keyword="FolderType"			Name="Folder Type"
+(0041,0011) VERS="PA3"	VR="UL"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ImagePointer"			Name="Image Pointer"
+(0041,0011) VERS="PAP"	VR="LT"   VM="1"	Owner="PAPYRUS"	Keyword="PatientFolderDataSetID"			Name="Patient Folder Data Set ID"
+(0041,0012) VERS="PA3"	VR="UL"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="PixelOffset"			Name="Pixel Offset"
+(0041,0013) VERS="PA3"	VR="SQ"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ImageIdentifierSequence"			Name="Image Identifier Sequence"
+(0041,0014) VERS="PA3"	VR="SQ"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ExternalFileReferenceSequence"			Name="External File Reference Sequence"
+(0041,0015) VERS="PA3"	VR="US"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="NumberOfImages"			Name="Number of Images"
+(0041,0020) VERS="PAP"	VR="LT"   VM="1"	Owner="PAPYRUS"	Keyword="FolderName"			Name="Folder Name"
+(0041,0021) VERS="PA3"	VR="UI"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ReferencedSOPClassUID"			Name="Referenced SOP Class UID"
+(0041,0022) VERS="PA3"	VR="UI"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ReferencedSOPInstanceUID"			Name="Referenced SOP Instance UID"
+(0041,0030) VERS="PAP"	VR="DA"   VM="1"	Owner="PAPYRUS"	Keyword="CreationDate"			Name="Creation Date"
+(0041,0031) VERS="PA3"  VR="LT"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ReferencedFileName"			Name="Referenced File Name"
+(0041,0032) VERS="PA3"  VR="LT"   VM="1-n"	Owner="PAPYRUS 3.0"	Keyword="ReferencedFilePath"			Name="Referenced File Path"
+(0041,0032) VERS="PAP"	VR="TM"   VM="1"	Owner="PAPYRUS"	Keyword="CreationTime"			Name="Creation Time"
+(0041,0034) VERS="PAP"	VR="DA"   VM="1"	Owner="PAPYRUS"	Keyword="ModifiedDate"			Name="Modified Date"
+(0041,0036) VERS="PAP"	VR="TM"   VM="1"	Owner="PAPYRUS"	Keyword="ModifiedTime"			Name="Modified Time"
+(0041,0040) VERS="PAP"	VR="LT"   VM="1-n"	Owner="PAPYRUS"	Keyword="OwnerName"			Name="Owner Name"
+(0041,0041) VERS="PA3"	VR="UI"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ReferencedImageSOPClassUID"			Name="Referenced Image SOP Class UID"
+(0041,0042) VERS="PA3"	VR="UI"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ReferencedImageSOPInstanceUID"			Name="Referenced Image SOP Instance UID"
+(0041,0050) VERS="PA3"	VR="SQ"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ImageSequence"			Name="Image Sequence"
+(0041,0050) VERS="PAP"	VR="LT"   VM="1"	Owner="PAPYRUS"	Keyword="FolderStatus"			Name="Folder Status"
+(0041,0060) VERS="PAP"	VR="UL"   VM="1"	Owner="PAPYRUS"	Keyword="NumberOfImages"			Name="Number of Images"
+(0041,0062) VERS="PAP"	VR="UL"   VM="1"	Owner="PAPYRUS"	Keyword="NumberOfOther"			Name="Number of Other"
+(0041,00a0) VERS="PAP"	VR="LT"   VM="1-n"	Owner="PAPYRUS"	Keyword="ExternalFolderElementDSID"			Name="External Folder Element DSID"
+(0041,00a1) VERS="PAP"	VR="US"   VM="1-n"	Owner="PAPYRUS"	Keyword="ExternalFolderElementDataSetType"			Name="External Folder Element Data Set Type"
+(0041,00a2) VERS="PAP"	VR="LT"   VM="1-n"	Owner="PAPYRUS"	Keyword="ExternalFolderElementFileLocation"			Name="External Folder Element File Location"
+(0041,00a3) VERS="PAP"	VR="UL"   VM="1-n"	Owner="PAPYRUS"	Keyword="ExternalFolderElementLength"			Name="External Folder Element Length"
+(0041,00b0) VERS="PAP"	VR="LT"   VM="1-n"	Owner="PAPYRUS"	Keyword="InternalFolderElementDSID"			Name="Internal Folder Element DSID"
+(0041,00b1) VERS="PAP"	VR="US"   VM="1-n"	Owner="PAPYRUS"	Keyword="InternalFolderElementDataSetType"			Name="Internal Folder Element Data Set Type"
+(0041,00b2) VERS="PAP"	VR="UL"   VM="1-n"	Owner="PAPYRUS"	Keyword="InternalOffsetToDataSet"			Name="Internal Offset To Data Set"
+(0041,00b3) VERS="PAP"	VR="UL"   VM="1-n"	Owner="PAPYRUS"	Keyword="InternalOffsetToImage"			Name="Internal Offset To Image"
+(60xx,0000) VERS="PA3"	VR="IS"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayID"		Name="Overlay ID"
+(60xx,0001) VERS="PA3"	VR="LT"   VM="1-n"	Owner="PAPYRUS 3.0"	Keyword="LinkedOverlays"	Name="Linked Overlays"
+(60xx,0010) VERS="PA3"	VR="US"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayRows"		Name="Overlay Rows"
+(60xx,0011) VERS="PA3"	VR="US"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayColumns"	Name="Overlay Columns"
+(60xx,0040) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayType"		Name="Overlay Type"
+(60xx,0050) VERS="PA3"	VR="US"   VM="1-n"	Owner="PAPYRUS 3.0"	Keyword="OverlayOrigin"		Name="Overlay Origin"
+(60xx,0060) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="Editable"		Name="Editable"
+(60xx,0070) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayFont"		Name="Overlay Font"
+(60xx,0072) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayStyle"		Name="Overlay Style"
+(60xx,0074) VERS="PA3"	VR="US"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayFontSize"	Name="Overlay Font Size"
+(60xx,0076) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayColor"		Name="Overlay Color"
+(60xx,0078) VERS="PA3"	VR="US"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ShadowSize"		Name="Shadow Size"
+(60xx,0080) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="FillPattern"		Name="Fill Pattern"
+(60xx,0082) VERS="PA3"	VR="US"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="OverlayPenSize"	Name="Overlay Pen Size"
+(60xx,00a0) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="Label"			Name="Label"
+(60xx,00a2) VERS="PA3"	VR="LT"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="PostItText"		Name="Post It Text"
+(60xx,00a4) VERS="PA3"	VR="US"   VM="2"	Owner="PAPYRUS 3.0"	Keyword="AnchorPoint"		Name="Anchor Point"
+(60xx,00b0) VERS="PA3"	VR="LO"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="ROIType"		Name="ROI Type"
+(60xx,00b2) VERS="PA3"	VR="LT"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="AttachedAnnotation"	Name="Attached Annotation"
+(60xx,00ba) VERS="PA3"	VR="US"   VM="1-n"	Owner="PAPYRUS 3.0"	Keyword="ContourPoints"		Name="Contour Points"
+(60xx,00bc) VERS="PA3"	VR="US"   VM="1-n"	Owner="PAPYRUS 3.0"	Keyword="MaskData"		Name="Mask Data"
+(60xx,00c0) VERS="PA3"  VR="SQ"   VM="1"	Owner="PAPYRUS 3.0"	Keyword="UINOverlaySequence"	Name="UIN Overlay Sequence"
diff --git a/libsrc/standard/elmdict/philips.tpl b/libsrc/standard/elmdict/philips.tpl
new file mode 100644
index 0000000..ee23426
--- /dev/null
+++ b/libsrc/standard/elmdict/philips.tpl
@@ -0,0 +1,1991 @@
+(0009,0000) VERS=""		VR="UL"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="FileLocation"				Name="File Location"
+(0009,0000) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="DataObjectRecognitionCode"	Name="Data Object Recognition Code"
+(0009,0000) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0001) VERS=""		VR="UL"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="FileSize"				Name="File Size"
+(0009,0004) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="ImageDataConsistency"		Name="Image Data Consistency"
+(0009,0008) VERS=""		VR="CS"   VM="1"	Owner="SPI Release 1"		Keyword="?"				Name="?"
+(0009,0008) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0010) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR"		Keyword="SPIRelease"			Name="SPI Release"
+(0009,0010) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART 12"		Keyword="?"			Name="?"	PrivateBlock="0021"
+(0009,0010) VERS=""		VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="?"				Name="?"
+(0009,0010) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0010) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0012) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR"		Keyword="?"				Name="?"
+(0009,0012) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0015) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="UniqueIdentifier"		Name="Unique Identifier"
+(0009,0016) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0018) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0020) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0021) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0030) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0031) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="PACSUniqueIdentifier"		Name="PACS Unique Identifier"
+(0009,0034) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="ClusterUniqueIdentifier"	Name="Cluster Unique Identifier"
+(0009,0038) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="SystemUniqueIdentifier"	Name="System Unique Identifier"
+(0009,0039) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,0040) VERS=""		VR="SQ"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="AlternateImageSequence"		Name="Alternate Image Sequence"
+(0009,0040) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0050) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0051) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="StudyUniqueIdentifier"		Name="Study Unique Identifier"
+(0009,0060) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0061) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="SeriesUniqueIdentifier"	Name="Series Unique Identifier"
+(0009,0070) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0075) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0080) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0090) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0009,0091) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,00a0) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,00c0) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="?"				Name="?"
+(0009,00c1) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="?"				Name="?"
+(0009,00f2) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,00f3) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,00f4) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,00f5) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0009,00f7) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0011,0010) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="PatientEntryID"		Name="Patient Entry ID"
+(0011,0018) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 2;1"	Keyword="?"				Name="?"
+(0011,0020) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0011,0021) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0011,0022) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0011,0030) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0011,0031) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0011,0032) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0019,0000) VERS=""		VR="CS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="ImageBlankingShape"			Name="Image Blanking Shape"
+(0019,0000) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR R5.5/PART"	Keyword="FieldOfView"			Name="Field of View"	PrivateBlock="0010"
+(0019,0000) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR R5.6/PART"	Keyword="FieldOfView"			Name="Field of View"	PrivateBlock="0010"
+(0019,0000) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART 7"		Keyword="?"			Name="?"
+(0019,0000) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="FieldOfView"			Name="Field of View"	PrivateBlock="0010"
+(0019,0000) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfStacks"		Name="Number of Stacks"	PrivateBlock="0011"
+(0019,0000) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0019,0000) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="PhysiologicalDataType"		Name="Physiological Data Type"
+(0019,0000) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0000) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-Private-DiDi Release 1"	Keyword="PostModeString"		Name="Post Mode String"
+(0019,0000) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0001) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0001) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0001) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="StackType"			Name="Stack Type"	PrivateBlock="0011"	DefinedTerms="0=Par,1=Rad,2=Vol"
+(0019,0001) VERS=""		VR="LO"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0019,0001) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="PhysiologicalDataChannelAndKind"	Name="Physiological Data Channel And Kind"
+(0019,0001) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-Private-DiDi Release 1"	Keyword="PostData"			Name="Post Data"
+(0019,0002) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="ImageBlankingLeftVerticalEdge"		Name="Image Blanking Left Vertical Edge"
+(0019,0002) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0002) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0011"
+(0019,0002) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0002) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0019,0002) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleBitsAllocated"		Name="Sample Bits Allocated"
+(0019,0002) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0003) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0003) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0003) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleBitsStored"		Name="Sample Bits Stored"
+(0019,0003) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0004) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="ImageBlankingRightVerticalEdge"	Name="Image Blanking Right Vertical Edge"
+(0019,0004) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0004) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleHighBit"			Name="Sample High Bit"
+(0019,0004) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0005) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0005) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="CCAngulation"			Name="CC Angulation"	PrivateBlock="0010"
+(0019,0005) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleRepresentation"		Name="Sample Representation"
+(0019,0005) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0006) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="ImageBlankingUpperHorizontalEdge"	Name="Image Blanking Upper Horizontal Edge"
+(0019,0006) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0006) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="APAngulation"			Name="AP Angulation"	PrivateBlock="0010"
+(0019,0006) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SmallestSampleValue"		Name="Smallest Sample Value"
+(0019,0007) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0007) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="LRAngulation"			Name="LR Angulation"	PrivateBlock="0010"
+(0019,0007) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="LargestSampleValue"		Name="Largest Sample Value"
+(0019,0008) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="ImageBlankingLowerHorizontalEdge"	Name="Image Blanking Lower Horizontal Edge"
+(0019,0008) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0008) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PatientOrientation1"		Name="Patient Orientation 1"	PrivateBlock="0010"	DefinedTerms="1=head first,2=feet first"
+(0019,0008) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PatientPosition"		Name="Patient Position"	PrivateBlock="0010"	DefinedTerms="1=head first,2=feet first"
+(0019,0008) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="NumberOfSamples"		Name="Number Of Samples"
+(0019,0008) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0009) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0009) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="MainMagneticField"		Name="Main Magnetic Field"	Units="Tesla"
+(0019,0009) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PatientOrientation"		Name="Patient Orientation"	PrivateBlock="0010"	DefinedTerms="1=supine,2=prone,3=left lateral decubitus,4=right lateral decubitus"
+(0019,0009) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleData"			Name="Sample Data"
+(0019,0009) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,000a) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SliceOrientation"		Name="Slice Orientation"	PrivateBlock="0010"	DefinedTerms="1=Transverse,2=Sagittal,3=Coronal"
+(0019,000a) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleRate"			Name="Sample Rate"
+(0019,000a) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,000b) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="LROffcenter"			Name="LR Offcenter"	PrivateBlock="0010"
+(0019,000b) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="LROffcenter"			Name="LR Offcenter"	PrivateBlock="0011"
+(0019,000b) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,000c) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="CCOffcenter"			Name="CC Offcenter"	PrivateBlock="0010"
+(0019,000c) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="CCOffcenter"			Name="CC Offcenter"	PrivateBlock="0011"
+(0019,000c) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,000d) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="APOffcenter"			Name="AP Offcenter"	PrivateBlock="0010"
+(0019,000d) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="APOffcenter"			Name="AP Offcenter"	PrivateBlock="0011"
+(0019,000e) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="FlowCompensation"		Name="Flow Compensation"	DefinedTerms="0=No,1=Yes"
+(0019,000e) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,000f) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfSlices"		Name="Number of Slices"	PrivateBlock="0010"
+(0019,0010) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="CenterOfCircularImageBlanking"		Name="Center of Circular Image Blanking"
+(0019,0010) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0010) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART 6"		Keyword="?"			Name="?"
+(0019,0010) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SliceFactor"			Name="Slice Factor"	PrivateBlock="0010"
+(0019,0010) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="MainsFrequency"		Name="Mains Frequency"
+(0019,0010) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="PhysiologicalDataType2"	Name="Physiological Data Type 2"
+(0019,0010) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0010) VERS=""		VR="US"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0010) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataBitsAllocated"	Name="?"
+(0019,0010) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-Private-DiDi Release 1"	Keyword="ImageHeader"			Name="Image Header"
+(0019,0010) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-XSB-DCI Release 1"	Keyword="VideoBeamBoost"		Name="Video Beam Boost"
+(0019,0010) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0011) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="EchoTimes"			Name="Echo Times"	PrivateBlock="0010"
+(0019,0011) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS-MR-1"		Keyword="ChemicalShiftNumber"		Name="Chemical Shift Number"
+(0019,0011) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="PhysiologicalDataChannelAndKind2"	Name="Physiological Data Channel And Kind 2"
+(0019,0011) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataBitsStored"	Name="?"
+(0019,0011) VERS=""		VR="US"   VM="1"	Owner="SPI-P-XSB-DCI Release 1"	Keyword="ChannelGeneratingVideoSync"	Name="Channel Generating Video Sync"
+(0019,0011) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0012) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="RadiusOfCircularImageBlanking"		Name="Radius of Circular Image Blanking"
+(0019,0012) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0012) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS-MR-1"		Keyword="PhaseNumber"			Name="Phase Number"
+(0019,0012) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleBitsAllocated2"		Name="Sample Bits Allocated 2"
+(0019,0012) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataHighBit"	Name="?"
+(0019,0012) VERS=""		VR="US"   VM="1"	Owner="SPI-P-XSB-DCI Release 1"	Keyword="VideoGain"			Name="Video Gain"
+(0019,0012) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0013) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0013) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleBitsStored2"		Name="Sample Bits Stored 2"
+(0019,0013) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataRepresentation"	Name="?"
+(0019,0013) VERS=""		VR="US"   VM="1"	Owner="SPI-P-XSB-DCI Release 1"	Keyword="VideoOffset"			Name="Video Offset"
+(0019,0014) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0014) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0014) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleHighBit2"		Name="Sample High Bit 2"
+(0019,0014) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0014) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataSmallestDataValue"	Name="?"
+(0019,0015) VERS=""		VR="US"   VM="1-n"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0015) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="DynamicStudy"			Name="Dynamic Study"	PrivateBlock="0010"	DefinedTerms="0=No,1=Yes"
+(0019,0015) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleRepresentation2"		Name="Sample Representation 2"
+(0019,0015) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataLargestDataValue"	Name="?"
+(0019,0016) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0016) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SmallestSampleValue2"		Name="Smallest Sample Value 2"
+(0019,0016) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapDataNumberOfDataValues"	Name="?"
+(0019,0017) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0017) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="LargestSampleValue2"		Name="Largest Sample Value 2"
+(0019,0017) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private-DCI Release 1"	Keyword="ECGTimeMapData"	Name="?"
+(0019,0018) VERS=""		VR="UN"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0018) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="HeartbeatInterval"		Name="Heartbeat Interval"	PrivateBlock="0010"
+(0019,0018) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="NumberOfSamples2"		Name="Number Of Samples 2"
+(0019,0018) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,0019) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="RepetitionTimeFFE"		Name="Repetition Time FFE"	PrivateBlock="0010"
+(0019,0019) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleData2"			Name="Sample Data 2"
+(0019,0019) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,001a) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="FFEFlipAngle"			Name="FFE Flip Angle"	PrivateBlock="0010"
+(0019,001a) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="SampleRate2"			Name="Sample Rate 2"
+(0019,001a) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,001b) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfScans"			Name="Number of Scans"	PrivateBlock="0010"
+(0019,001b) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,001c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,001c) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,001d) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,001d) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-CTBE Release 1"	Keyword="?"		Name="?"
+(0019,001e) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0020) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0020) VERS=""		VR="TM"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0020) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0020) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-XSB-DCI Release 1"	Keyword="RTDDataCompressionFactor"	Name="RTD Data Compression Factor"
+(0019,0020) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0021) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0021) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,0021) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0021) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0022) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="RouteAET"			Name="Route AET"
+(0019,0022) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0022) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"	Keyword="DynamicScanTimeBegin"			Name="Dynamic Scan Time Begin"	PrivateBlock="0010"
+(0019,0023) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="PCRPrintScale"			Name="PCR Print Scale"
+(0019,0023) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0023) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0024) VERS=""		VR="ST"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="PCRPrintJobEnd"		Name="PCR Print Job End"
+(0019,0024) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0024) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,0024) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0025) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="PCRNoFilmCopies"		Name="PCR No Film Copies"
+(0019,0025) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0025) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0025) VERS=""		VR="LO"   VM="1-n"	Owner="SPI-P Release 1"		Keyword="OriginalPixelDataQuality"	Name="Original Pixel Data Quality"
+(0019,0026) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="PCRFilmLayoutPosition"		Name="PCR Film Layout Position"
+(0019,0026) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0026) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0027) VERS=""		VR="ST"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="PCRPrintReportName"		Name="PCR Print Report Name"
+(0019,0027) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0027) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0028) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0028) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0029) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0029) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0030) VERS=""		VR="UL"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="MaximumImageFrameSize"			Name="Maximum Image Frame Size"
+(0019,0030) VERS=""		VR="LO"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0030) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECGTriggering"			Name="ECG Triggering"
+(0019,0030) VERS=""		VR="US"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0030) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0019,0031) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0031) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0031) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECG1Offset"			Name="ECG 1 Offset"
+(0019,0031) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0019,0032) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0032) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECG2Offset1"			Name="ECG 2 Offset 1"
+(0019,0033) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECG2Offset2"			Name="ECG 2 Offset 2"
+(0019,0040) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0040) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0040) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0041) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0042) VERS=""		VR="IS"   VM="2"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0043) VERS=""		VR="IS"   VM="2"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0045) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0045) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ReconstructionResolution"	Name="Reconstruction Resolution"	PrivateBlock="0011"
+(0019,0046) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0047) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0048) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0049) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0050) VERS=""		VR="UN"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0050) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0050) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0050) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="VideoScanMode"			Name="Video Scan Mode"
+(0019,0050) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0050) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0019,0051) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0051) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="VideoLineRate"			Name="Video LineRate"
+(0019,0052) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0053) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0054) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0055) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0056) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0057) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0058) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0059) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0060) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0060) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0060) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="XrayTechnique"			Name="Xray Technique"
+(0019,0060) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0060) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0061) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0061) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0061) VERS=""		VR="DS"   VM="1"	Owner="SPI-P Release 1"		Keyword="ImageIdentifierFromat"		Name="Image Identifier Fromat"
+(0019,0061) VERS=""		VR="US"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0062) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0062) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="IrisDiaphragm"			Name="Iris Diaphragm"
+(0019,0063) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0063) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="Filter"			Name="Filter"
+(0019,0063) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0064) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0064) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="RepetitionTimeSE"		Name="Repetition Time SE"	PrivateBlock="0010"
+(0019,0064) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="CineParallel"			Name="Cine Parallel"
+(0019,0064) VERS=""		VR="US"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0065) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="RepetitionTimeIR"		Name="Repetition Time IR"	PrivateBlock="0010"
+(0019,0065) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="CineMaster"			Name="Cine Master"
+(0019,0065) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0066) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0011"
+(0019,0067) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0069) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfPhases"		Name="Number of Phases"	PrivateBlock="0010"
+(0019,006a) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="CardiacFrequency"		Name="Cardiac Frequency"	PrivateBlock="0010"
+(0019,006b) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="InversionDelay"		Name="Inversion Delay"	PrivateBlock="0010"
+(0019,006c) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="GateDelay"			Name="Gate Delay"	PrivateBlock="0010"
+(0019,006d) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="GateWidth"			Name="Gate Width"	PrivateBlock="0010"
+(0019,006e) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="TriggerDelayTime"		Name="Trigger Delay Time"	PrivateBlock="0010"
+(0019,0070) VERS=""		VR="ST"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="RADProtocolPrinter"		Name="RAD Protocol Printer"
+(0019,0070) VERS=""		VR="UN"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0070) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0070) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="ExposureChannel"		Name="Exposure Channel"
+(0019,0070) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0071) VERS=""		VR="ST"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="RADProtocolMedium"		Name="RAD Protocol Medium"
+(0019,0071) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0071) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="ExposureChannelFirstImage"	Name="Exposure Channel First Image"
+(0019,0072) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0072) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="ProcessingChannel"		Name="Processing Channel"
+(0019,0073) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0074) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0076) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0077) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0078) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0079) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0080) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR SPECTRO;1"	Keyword="?"				Name="?"
+(0019,0080) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfChemicalShifts"	Name="Number of Chemical Shifts"	PrivateBlock="0010"
+(0019,0080) VERS=""		VR="DS"   VM="1"	Owner="SPI-P Release 1"		Keyword="AcquisitionDelay"		Name="Acquisition Delay"
+(0019,0080) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0080) VERS=""		VR="US"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0081) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ChemicalShift"			Name="Chemical Shift"	PrivateBlock="0010"
+(0019,0081) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1"		Keyword="RelativeImageTime"		Name="Relative Image Time"
+(0019,0081) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0084) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfRows"			Name="Number of Rows"	PrivateBlock="0010"
+(0019,0085) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfSamples"		Name="Number of Samples"	PrivateBlock="0010"
+(0019,0089) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="ExposureIndex"			Name="Exposure Index"
+(0019,008A) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="CollimatorX"			Name="Collimator X"
+(0019,008A) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,008B) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="CollimatorY"			Name="Collimator Y"
+(0019,008B) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,008C) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="PrintMarker"			Name="Print Marker"
+(0019,008C) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,008D) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="RGDVName"			Name="RGDV Name"
+(0019,008D) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,008E) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="AcqdSensitivity"		Name="Acqd Sensitivity"
+(0019,008E) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,008F) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="ProcessingCategory"		Name="Processing Category"
+(0019,008F) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,0090) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="UnprocessedFlag"		Name="Unprocessed Flag"
+(0019,0090) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="VideoWhiteCompression"		Name="Video White Compression"
+(0019,0090) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,0090) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,0091) VERS=""		VR="DS"   VM="1-n"	Owner="DIDI TO PCR 1.1"			Keyword="KeyValues"			Name="Key Values"
+(0019,0092) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="DestinationPostprocessingFunction"	Name="Destination Postprocessing Function"
+(0019,0094) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="MagnetizationTransferContrast"	Name="Magnetization Transfer Contrast"	PrivateBlock="0010"
+(0019,0095) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SpectralPresaturationWithInversionRecovery"	Name="Spectral Presaturation With Inversion Recovery"	PrivateBlock="0010"
+(0019,0096) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,0097) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00A0) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="Version"			Name="Version"
+(0019,00A1) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="RangingMode"			Name="Ranging Mode"
+(0019,00A2) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="AbdomenBrightness"		Name="Abdomen Brightness"
+(0019,00A3) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="FixedBrightness"		Name="Fixed Brightness"
+(0019,00A4) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="DetailContrast"		Name="Detail Contrast"
+(0019,00A5) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="ContrastBalance"		Name="Contrast Balance"
+(0019,00A6) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="StructureBoost"		Name="Structure Boost"
+(0019,00A7) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="StructurePreference"		Name="Structure Preference"
+(0019,00A8) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="NoiseRobustness"		Name="Noise Robustness"
+(0019,00A9) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="NoiseDoseLimit"		Name="Noise Dose Limit"
+(0019,00AA) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="NoiseDoseStep"			Name="Noise Dose Step"
+(0019,00AB) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="NoiseFrequencyLimit"		Name="Noise Frequency Limit"
+(0019,00AC) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="WeakContrastLimit"		Name="Weak Contrast Limit"
+(0019,00AD) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="StrongContrastLimit"		Name="Strong Contrast Limit"
+(0019,00AE) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="StructureBoostOffset"		Name="Structure Boost Offset"
+(0019,00AF) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="SmoothGain"			Name="Smooth Gain"
+(0019,00B0) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="MeasureField1"			Name="Measure Field 1"
+(0019,00B1) VERS=""		VR="LO"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="MeasureField2"			Name="Measure Field 2"
+(0019,00B2) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="KeyPercentile1"		Name="Key Percentile 1"
+(0019,00B3) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="KeyPercentile2"		Name="Key Percentile 2"
+(0019,00B4) VERS=""		VR="IS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="DensityLUT"			Name="Density LUT"
+(0019,00B4) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00B5) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="Brightness"			Name="Brightness"
+(0019,00B5) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00B6) VERS=""		VR="DS"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="Gamma"				Name="Gamma"
+(0019,00B6) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00B7) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"			Name="?"
+(0019,00D1) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00D3) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00E4) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"			Name="?"
+(0019,00E5) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"			Name="?"
+(0019,00F0) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00F6) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00F7) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00F8) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00F9) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00FA) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00FB) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00FC) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0019,00a0) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00a0) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="Angulation"			Name="Angulation"
+(0019,00a0) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,00a1) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00a1) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="Rotation"			Name="Rotation"
+(0019,00a1) VERS=""		VR="US"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,00a1) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a2) VERS=""		VR="US"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,00a3) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00a3) VERS=""		VR="US"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,00a3) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a4) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00a4) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a5) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a6) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a7) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a8) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00a9) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00aa) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00ab) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00ac) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00ad) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00ae) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00af) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b0) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,00b0) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b1) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="MinimumRRInterval"		Name="Minimum RR Interval"
+(0019,00b1) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0019,00b1) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b2) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="MaximumRRInterval"		Name="Maximum RR Interval"
+(0019,00b2) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b3) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="NumberOfRejections"		Name="Number of Rejections"
+(0019,00b3) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b4) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="NumberOfRRIntervals"		Name="Number of RR Intervals"
+(0019,00b4) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b5) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ArrhythmiaRejection"		Name="Arrhythmia Rejection"
+(0019,00b5) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b6) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b7) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b8) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00b9) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00ba) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-PCR Release 2"	Keyword="?"		Name="?"
+(0019,00c0) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0019,00c0) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="TriggerDelayTimes"		Name="Trigger Delay Times"	PrivateBlock="0012"
+(0019,00c6) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="CycledMultipleSlice"		Name="Cycled Multiple Slice"	DefinedTerms="0=No,1=Yes"
+(0019,00c8) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00c9) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="FoldoverDirectionTransverse"	Name="Foldover Direction Transverse"	PrivateBlock="0010"	DefinedTerms="1=AP,3=LR"
+(0019,00ca) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="FoldoverDirectionSagittal"	Name="Foldover Direction Sagittal"	PrivateBlock="0010"	DefinedTerms="1=AP,2=FH"
+(0019,00cb) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="FoldoverDirectionCoronal"	Name="Foldover Direction Coronal"	PrivateBlock="0010"	DefinedTerms="2=FH,3=LR"
+(0019,00cc) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00cd) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00ce) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="REST"				Name="REST"	DefinedTerms="0=No,1=Yes"
+(0019,00ce) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00cf) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfEchoes"		Name="Number of Echoes"	PrivateBlock="0010"
+(0019,00d0) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ScanResolution"		Name="Scan Resolution"	PrivateBlock="0010"
+(0019,00d2) VERS=""		VR="LO"   VM="2"	Owner="PHILIPS MR/PART"		Keyword="WaterFatShift"			Name="Water Fat Shift"	PrivateBlock="0010"	DefinedTerms="0=Default"
+(0019,00d4) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ArtifactReduction"		Name="Artifact Reduction"	PrivateBlock="0010"	DefinedTerms="1=No,2=CT,3=RG,4=CT+RG"
+(0019,00d5) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0019,00d5) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00d6) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="FourierInterpolation"		Name="Fourier Interpolation"	DefinedTerms="0=No,1=Yes"
+(0019,00d6) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00d7) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ScanPercentage"		Name="Scan Percentage"	PrivateBlock="0010"
+(0019,00d8) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="Halfscan"			Name="Halfscan"	PrivateBlock="0010"	DefinedTerms="0=No,1=Yes"
+(0019,00d9) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0019,00d9) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="EPIFactor"			Name="EPI Factor"	PrivateBlock="0010"
+(0019,00da) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="TurboFactor"			Name="Turbo Factor"	PrivateBlock="0010"
+(0019,00db) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00e0) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="Prepulse"			Name="Prepulse"	DefinedTerms="0=No,1=Inversion,2=Saturation,3=Echo"
+(0019,00e0) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PercentageOfScanCompleted"	Name="Percentage of Scan Completed"	PrivateBlock="0010"
+(0019,00e0) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PrepulseType"			Name="Prepulse Type"	PrivateBlock="0012"
+(0019,00e1) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="PrepulseDelay"			Name="Prepulse Delay"
+(0019,00e1) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0019,00e1) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PrepulseDelay"			Name="Prepulse Delay"	PrivateBlock="0012"
+(0019,00e2) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0019,00e3) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0019,00e3) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PhaseContrastVelocity"		Name="Phase Contrast Velocity"	PrivateBlock="0012"
+(0019,00f0) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="WSProtocolString1"		Name="WS Protocol String 1"
+(0019,00f1) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="WSProtocolString2"		Name="WS Protocol String 2"
+(0019,00f2) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="WSProtocolString3"		Name="WS Protocol String 3"
+(0019,00f3) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="WSProtocolString4"		Name="WS Protocol String 4"
+(0019,00fc) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ResonanceFrequency"		Name="Resonance Frequency"	Units="Hertz"	PrivateBlock="0011"
+(0021,0000) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0021,0000) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ReconstructionNumber"		Name="Reconstruction Number"	PrivateBlock="0010"
+(0021,0000) VERS=""		VR="DA"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ScanDate"			Name="Scan Date"	PrivateBlock="0011"
+(0021,0000) VERS=""		VR="DA"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SeriesDate"			Name="Series Date"	PrivateBlock="0011"
+(0021,0000) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-CTBE-Private Release 1"	Keyword="?"		Name="?"
+(0021,0000) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-Private-CWS Release 1"	Keyword="WindowOfImagesID"	Name="Window Of Images ID"
+(0021,0001) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS-MR-1"		Keyword="ReconstructionNumber"		Name="Reconstruction Number"
+(0021,0001) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-Private-CWS Release 1"	Keyword="WindowOfImagesType"	Name="Window Of Images Type"
+(0021,0002) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS-MR-1"		Keyword="SliceNumber"			Name="Slice Number"
+(0021,0002) VERS=""		VR="IS"   VM="1-n"	Owner="SPI-P-Private-CWS Release 1"	Keyword="WindowOfImagesScope"	Name="WindowOfImagesScope"
+(0021,0006) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,0008) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,0009) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,000a) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,000f) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,0010) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0021,0010) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ImageType"			Name="Image Type"	PrivateBlock="0010"
+(0021,0010) VERS=""		VR="TM"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ScanTime"			Name="Scan Time"	PrivateBlock="0011"
+(0021,0012) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="SeriesUniqueIdentifier"	Name="Series Unique Identifier"
+(0021,0013) VERS=""		VR="IS"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="ImageSequenceNumber"			Name="Image Sequence Number"
+(0021,0013) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,0014) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0021,0015) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0021,0020) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0021,0020) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SliceNumber"			Name="Slice Number"	PrivateBlock="0010"
+(0021,0020) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0021) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="SliceGap"			Name="Slice Gap"
+(0021,0021) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SliceGap"			Name="Slice Gap"	PrivateBlock="0012"
+(0021,0022) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="StackRadialAngle"		Name="Stack Radial Angle"
+(0021,0030) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="EchoNumber"			Name="Echo Number"	PrivateBlock="0010"
+(0021,0030) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0031) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PatientReferenceID"		Name="Patient Reference ID"	PrivateBlock="0010"
+(0021,0035) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ChemicalShiftNumber"		Name="Chemical Shift Number"	PrivateBlock="0010"
+(0021,0040) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="PhaseNumber"			Name="Phase Number"	PrivateBlock="0010"
+(0021,0040) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0040) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-Private_CDS Release 1"	Keyword="?"			Name="?"
+(0021,0050) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="DynamicScanNumber"		Name="Dynamic Scan Number"	PrivateBlock="0010"
+(0021,0050) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0060) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="NumberOfRowsInObject"		Name="Number of Rows In Object"	PrivateBlock="0010"
+(0021,0060) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0061) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="RowNumber"			Name="Row Number"	PrivateBlock="0010"
+(0021,0062) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"	PrivateBlock="0010"
+(0021,0070) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0080) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,0090) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00a0) VERS=""		VR="US"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00a1) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00a2) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00a3) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00a4) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00b0) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0021,00c0) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0023,000d) VERS=""		VR="UI"   VM="1"	Owner="SPI-P Release 2;1"	Keyword="?"				Name="?"
+(0023,000e) VERS=""		VR="UI"   VM="1"	Owner="SPI-P Release 2;1"	Keyword="?"				Name="?"
+(0027,0000) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0027,0011) VERS=""		VR="US"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0027,0012) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0027,0013) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0027,0014) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0027,0015) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0027,0016) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0029,0000) VERS=""		VR="SQ"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="EdgeEnhancementSequence"		Name="Edge Enhancement Sequence"
+(0029,0000) VERS=""		VR="DS"   VM="2"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0000) VERS=""		VR="DS"   VM="4"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0000) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="ZoomID"			Name="Zoom ID"
+(0029,0000) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;2"	Keyword="SubtractionMaskID"		Name="Subtraction Mask ID"
+(0029,0000) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ImageEnhancementID"		Name="Image Enhancement ID"
+(0029,0000) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private_CDS Release 1"	Keyword="?"			Name="?"
+(0029,0000) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1" 	Keyword="?"			Name="?"
+(0029,0000) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"	Keyword="?"			Name="?"
+(0029,0000) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-Private_ICS Release 1;3"	Keyword="?"		Name="?"
+(0029,0000) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0001) VERS=""		VR="US"   VM="2"	Owner="CARDIO-D.R. 1.0"		Keyword="ConvolutionKernelSize"			Name="Convolution Kernel Size"
+(0029,0001) VERS=""		VR="DS"   VM="1-n"	Owner="SPI-P Release 1;1"	Keyword="ZoomRectangle"			Name="Zoom Rectangle"
+(0029,0001) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ImageEnhancement"		Name="Image Enhancement"
+(0029,0001) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"	Keyword="?"			Name="?"
+(0029,0001) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-Private_ICS Release 1;3"	Keyword="?"		Name="?"
+(0029,0001) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0002) VERS=""		VR="US"   VM="1-n"	Owner="CARDIO-D.R. 1.0"		Keyword="ConvolutionKernelCoefficients"		Name="Convolution Kernel Coefficients"
+(0029,0002) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ConvolutionID"			Name="Convolution ID"
+(0029,0002) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"	Keyword="?"			Name="?"
+(0029,0002) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0003) VERS=""		VR="FL"   VM="1"	Owner="CARDIO-D.R. 1.0"		Keyword="EdgeEnhancementGain"			Name="Edge Enhancement Gain"
+(0029,0003) VERS=""		VR="DS"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="ZoomFactor"			Name="Zoom Factor"
+(0029,0003) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ConvolutionType"		Name="Convolution Type"
+(0029,0003) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"	Keyword="?"			Name="?"
+(0029,0004) VERS=""		VR="US"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0004) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="ZoomFunction"			Name="Zoom Function"
+(0029,0004) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;2"	Keyword="MaskingFunction"		Name="Masking Function"
+(0029,0004) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ConvolutionKernelSizeID"	Name="Convolution Kernel Size ID"
+(0029,0004) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"	Keyword="?"			Name="?"
+(0029,0005) VERS=""		VR="US"   VM="2"	Owner="SPI-P Release 1;3"	Keyword="ConvolutionKernelSize"		Name="Convolution Kernel Size"
+(0029,0005) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,0005) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"	Keyword="?"			Name="?"
+(0029,0006) VERS=""		VR="US"   VM="1-n"	Owner="SPI-P Release 1;3"	Keyword="ConvolutionKernel"		Name="Convolution Kernel"
+(0029,0006) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,000c) VERS=""		VR="UN"   VM="1"	Owner="SPI-P Release 1;2"	Keyword="ProprietaryMaskingParameters"	Name="Proprietary Masking Parameters"
+(0029,000c) VERS=""		VR="DS"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="EnhancementGain"		Name="Enhancement Gain"
+(0029,000d) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,000e) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="ZoomEnableStatus"		Name="Zoom Enable Status"
+(0029,000e) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,000f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="ZoomSelectStatus"		Name="Zoom Select Status"
+(0029,000f) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,000f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0010) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="FPMin"				Name="FP Min"
+(0029,0010) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0010) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0010) VERS=""		VR="OB"   VM="1"	Owner="SPI-P-Private_CDS Release 1"	Keyword="?"			Name="?"
+(0029,0010) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0010) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0011) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0011) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0012) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0012) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,001b) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,001c) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,001d) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,001e) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;2"	Keyword="SubtractionMaskEnableStatus"	Name="Subtraction Mask Enable Status"
+(0029,001e) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ImageEnhancementEnableStatus"	Name="Image Enhancement Enable Status"
+(0029,001e) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,001f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;2"	Keyword="SubtractionMaskSelectStatus"	Name="Subtraction Mask Select Status"
+(0029,001f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;3"	Keyword="ImageEnhancementSelectStatus"	Name="Image Enhancement Select Status"
+(0029,001f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0020) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="FPMax"				Name="FP Max"
+(0029,0020) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0020) VERS=""		VR="DS"   VM="1"	Owner="SPI-P Release 1"		Keyword="PixelAspectRatio"		Name="Pixel Aspect Ratio"
+(0029,0020) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0020) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,0020) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0021) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0021) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,0021) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0022) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0025) VERS=""		VR="LO"   VM="1-n"	Owner="SPI-P Release 1"		Keyword="ProcessedPixelDataQuality"	Name="Processed Pixel Data Quality"
+(0029,002f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0030) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ScaledMinimum"			Name="Scaled Minimum"
+(0029,0030) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0030) VERS=""		VR="UL"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0030) VERS=""		VR="LT"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,0030) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0031) VERS=""		VR="DS"   VM="2"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0031) VERS=""		VR="UL"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0031) VERS=""		VR="DS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0032) VERS=""		VR="DS"   VM="2"	Owner="PHILIPS MR/PART"		Keyword="?"				Name="?"
+(0029,0032) VERS=""		VR="UL"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0032) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0033) VERS=""		VR="UL"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0038) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,003f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-XSB-VISUB Release 1"	Keyword="?"			Name="?"
+(0029,0040) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ScaledMaximum"			Name="Scaled Maximum"
+(0029,0040) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="MagnifyingGlassID"		Name="Magnifying Glass ID"
+(0029,0041) VERS=""		VR="DS"   VM="1-n"	Owner="SPI-P Release 1;1"	Keyword="MagnifyingGlassRectangle"	Name="Magnifying Glass Rectangle"
+(0029,0043) VERS=""		VR="DS"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="MagnifyingGlassFactor"		Name="Magnifying Glass Factor"
+(0029,0044) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="MagnifyingGlassFunction"	Name="Magnifying Glass Function"
+(0029,004c) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,004d) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,004e) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="MagnifyingGlassEnableStatus"	Name="Magnifying Glass Enable Status"
+(0029,004e) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1"		Keyword="?"		Name="?"
+(0029,004f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1;1"	Keyword="MagnifyingGlassSelectStatus"	Name="Magnifying Glass Select Status"
+(0029,004f) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1"		Keyword="?"		Name="?"
+(0029,0050) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="WindowMinimum"			Name="Window Minimum"
+(0029,0050) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0029,0050) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1"		Keyword="?"		Name="?"
+(0029,0050) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-Private_ICS Release 1;5"	Keyword="?"			Name="?"
+(0029,0051) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0029,0051) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1"		Keyword="?"		Name="?"
+(0029,0052) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0029,0053) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="?"			Name="?"	PrivateBlock="0010"
+(0029,0055) VERS=""		VR="CS"   VM="1"	Owner="SPI-P-Private_ICS Release 1;5"	Keyword="?"			Name="?"
+(0029,0060) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="WindowMaximum"			Name="Window Maximum"
+(0029,0060) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0061) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0029,0061) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0062) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"			Name="?"
+(0029,0067) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0067) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0068) VERS=""		VR="US"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,006A) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,006B) VERS=""		VR="US"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0070) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0029,0070) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="WindowID"			Name="Window ID"
+(0029,0071) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0029,0071) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="VideoInvertSubtracted"		Name="Video Invert Subtracted"
+(0029,0072) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(0029,0072) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="VideoInvertNonsubtracted"	Name="Video Invert Nonsubtracted"
+(0029,0072) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,0077) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="WindowSelectStatus"		Name="Window Select Status"
+(0029,0078) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECGDisplayPrintingID"		Name="ECG Display Printing ID"
+(0029,0079) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECGDisplayPrinting"		Name="ECG Display Printing"
+(0029,007e) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECGDisplayPrintingEnableStatus"	Name="ECG Display Printing Enable Status"
+(0029,007f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="ECGDisplayPrintingSelectStatus"	Name="ECG Display Printing Select Status"
+(0029,0080) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ViewCenter"			Name="View Center"
+(0029,0080) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="PhysiologicalDisplayID"	Name="Physiological Display ID"
+(0029,0080) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0081) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ViewSize"			Name="View Size"
+(0029,0081) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="PreferredPhysiologicalChannelDisplay"	Name="Preferred Physiological Channel Display"
+(0029,0082) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ViewZoom"			Name="View Zoom"
+(0029,0083) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="ViewTransform"			Name="View Transform"
+(0029,008e) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="PhysiologicalDisplayEnableStatus"	Name="Physiological Display Enable Status"
+(0029,008f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="PhysiologicalDisplaySelectStatus"	Name="Physiological Display Select Status"
+(0029,0090) VERS=""		VR="DS"   VM="1-n"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0090) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,0091) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,0091) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-Private_ICS Release 1"	Keyword="?"			Name="?"
+(0029,009f) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00a0) VERS=""		VR="DS"   VM="1-n"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00a0) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00a1) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00a1) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00a2) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00a3) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00a5) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00a6) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00af) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00b0) VERS=""		VR="DS"   VM="1-n"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00b1) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00bf) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="?"				Name="?"
+(0029,00c0) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="FunctionalShutterID"		Name="Functional Shutter ID"
+(0029,00c0) VERS=""		VR="SL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00c1) VERS=""		VR="US"   VM="1"	Owner="SPI-P Release 1"		Keyword="FieldOfShutter"		Name="Field Of Shutter"
+(0029,00c1) VERS=""		VR="US"   VM="1" 	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,00c3) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="ScanResolution"		Name="Scan Resolution"
+(0029,00c4) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="FieldOfView"			Name="Field of View"
+(0029,00c5) VERS=""		VR="LT"   VM="1"	Owner="SPI-P Release 1"		Keyword="FieldOfShutterRectangle"	Name="Field Of Shutter Rectangle"
+(0029,00cb) VERS=""		VR="FD"   VM="1" 	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,00cc) VERS=""		VR="FD"   VM="1" 	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,00cd) VERS=""		VR="SQ"   VM="1" 	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"			Name="?"
+(0029,00ce) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="ShutterEnableStatus"		Name="Shutter Enable Status"
+(0029,00cf) VERS=""		VR="CS"   VM="1"	Owner="SPI-P Release 1"		Keyword="ShutterSelectStatus"		Name="Shutter Select Status"
+(0029,00d0) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,00d0) VERS=""		VR="UN"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d1) VERS=""		VR="IS"   VM="1"	Owner="SPI-P-GV-CT Release 1"	Keyword="?"				Name="?"
+(0029,00d1) VERS=""		VR="LO"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d2) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d3) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d4) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d5) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR/PART"		Keyword="SliceThickness"		Name="Slice Thickness"
+(0029,00d5) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d6) VERS=""		VR="ST"   VM="1"	Owner="SPI-P-Private_ICS Release 1;1"	Keyword="?"		Name="?"
+(0029,00d6) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00d7) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00d8) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00d9) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1;2"		Keyword="?"		Name="?"
+(0029,00d9) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00da) VERS=""		VR="FL"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00dc) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00dd) VERS=""		VR="FD"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"		Keyword="?"		Name="?"
+(0029,00e0) VERS=""		VR="SQ"   VM="1"	Owner="SPI-P-Private_ICS Release 1;4"	Keyword="?"			Name="?"
+(0041,0007) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"			Name="?"
+(0041,0009) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"			Name="?"
+(0089,0010) VERS=""		VR="SQ"   VM="1"	Owner="DIDI TO PCR 1.1"			Keyword="StampImageSequence"	Name="Stamp Image Sequence"
+(0089,0020) VERS=""		VR="SQ"   VM="1"	Owner="PMS-THORA-5.1"		Keyword="?"				Name="?"
+(0511,0000) VERS=""		VR="US"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(0511,0001) VERS=""		VR="US"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(0511,0002) VERS=""		VR="OB"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(0511,0003) VERS=""		VR="OB"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(0511,0032) VERS=""		VR="DS"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(0511,0050) VERS=""		VR="DS"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(1001,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 124"		Keyword="?"				Name="?"
+(2001,0000) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 129"		Keyword="PresentationStateSequence"		Name="Presentation State Sequence"
+(2001,0001) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ChemicalShift"				Name="Chemical Shift"
+(2001,0001) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ChemicalShift"				Name="Chemical Shift"
+(2001,0001) VERS=""		VR="US"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"		Name="?"
+(2001,0001) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 129"		Keyword="PresentationStateSequence"		Name="PresentationStateSequence"
+(2001,0002) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ChemicalShiftNumberMR"				Name="Chemical Shift Number MR"
+(2001,0002) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ChemicalShiftNumberMR"				Name="Chemical Shift Number MR"
+(2001,0002) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"		Name="?"
+(2001,0003) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DiffusionBFactor"				Name="Diffusion B-Factor"
+(2001,0003) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DiffusionBFactor"				Name="Diffusion B-Factor"
+(2001,0004) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DiffusionDirection"				Name="Diffusion Direction"
+(2001,0004) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DiffusionDirection"				Name="Diffusion Direction"
+(2001,0005) VERS=""	    VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicAnnotationParentID"	Name="Graphic Annotation ParentID"
+(2001,0005) VERS=""	    VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicAnnotationParentID"	Name="Graphic Annotation ParentID"
+(2001,0006) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImageEnhanced"				Name="Image Enhanced"
+(2001,0006) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ImageEnhanced"				Name="Image Enhanced"
+(2001,0007) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImageTypeEDES"				Name="Image Type End Diastole or End Systole"
+(2001,0007) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ImageTypeEDES"				Name="Image Type End Diastole or End Systole"
+(2001,0008) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PhaseNumber"				Name="Phase Number"
+(2001,0008) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PhaseNumber"				Name="Phase Number"
+(2001,0009) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImagePrepulseDelay"		Name="Image Prepulse Delay"
+(2001,0009) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ImagePrepulseDelay"		Name="Image Prepulse Delay"
+(2001,000a) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImagePlaneNumber"			Name="Image Plane Number"
+(2001,000a) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SliceNumber"				Name="Slice Number"
+(2001,000b) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImageOrientation"			Name="Image Orientation"
+(2001,000b) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SliceOrientation"			Name="Slice Orientation"
+(2001,000c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ArrhythmiaRejection"	Name="Arrhythmia Rejection"
+(2001,000c) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ArrhythmiaRejection"	Name="Arrhythmia Rejection"
+(2001,000e) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="CardiacCycled"		Name="Cardiac Cycled"
+(2001,000e) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="CardiacCycled"		Name="Cardiac Cycled"
+(2001,000f) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="CardiacGateWidth"	Name="Cardiac Gate Width"
+(2001,000f) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="CardiacGateWidth"	Name="Cardiac Gate Width"
+(2001,0010) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="CardiacSync"			Name="Cardiac Sync"
+(2001,0010) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="CardiacSync"			Name="Cardiac Sync"
+(2001,0011) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DiffusionEchoTime"	Name="Diffusion Echo Time"
+(2001,0011) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DiffusionEchoTime"	Name="Diffusion Echo Time"
+(2001,0012) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DynamicSeries"		Name="Dynamic Series"
+(2001,0012) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DynamicSeries"		Name="Dynamic Series"
+(2001,0013) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="EPIFactor"			Name="EPI Factor"
+(2001,0013) VERS=""		VR="SL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="EPIFactor"			Name="EPI Factor"
+(2001,0013) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"							Name="?"
+(2001,0014) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfEchoes"		Name="Number of Echoes"
+(2001,0014) VERS=""		VR="SL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfEchoes"		Name="Number of Echoes"
+(2001,0014) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"							Name="?"
+(2001,0015) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfLocations"	Name="Number of Locations"
+(2001,0015) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfLocations"	Name="Number of Locations"
+(2001,0015) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"							Name="?"
+(2001,0016) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfPCDirections"	Name="Number of PC Directions"
+(2001,0016) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfPCDirections"	Name="Number of PC Directions"
+(2001,0016) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"							Name="?"
+(2001,0017) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfPhases"		Name="Number of Phases"
+(2001,0017) VERS=""		VR="SL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfPhases"		Name="Number of Phases"
+(2001,0017) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"		Keyword="?"							Name="?"
+(2001,0018) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfSlices"		Name="Number of Slices"
+(2001,0018) VERS=""		VR="SL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfSlices"		Name="Number of Slices"
+(2001,0018) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0019) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PartialMatrixScanned"	Name="Partial Matrix Scanned"
+(2001,0019) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PartialMatrixScanned"	Name="Partial Matrix Scanned"
+(2001,0019) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,001a) VERS=""		VR="FL"   VM="3"	Owner="PHILIPS IMAGING DD 001"		Keyword="PCVelocity"			Name="PC Velocity"
+(2001,001a) VERS=""		VR="FL"   VM="3"	Owner="Philips Imaging DD 001"		Keyword="PCVelocity"			Name="PC Velocity"
+(2001,001a) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,001b) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PrepulseDelay"		Name="Prepulse Delay"
+(2001,001b) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PrepulseDelay"		Name="Prepulse Delay"
+(2001,001b) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,001c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PrepulseType"		Name="Prepulse Type"
+(2001,001c) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PrepulseType"		Name="Prepulse Type"
+(2001,001c) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,001d) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ReconstructionNumber"	Name="Reconstruction Number"
+(2001,001d) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ReconstructionNumber"	Name="Reconstruction Number"
+(2001,001d) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,001e) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ReformatAccuracy"	Name="Reformat Accuracy"
+(2001,001e) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ReformatAccuracy"	Name="Reformat Accuracy"
+(2001,001e) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,001f) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="RespirationSync"		Name="Respiration Sync"
+(2001,001f) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="RespirationSync"		Name="Respiration Sync"
+(2001,001f) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0020) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ScanningTechnique"		Name="Scanning Technique"
+(2001,0020) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ScanningTechnique"		Name="Scanning Technique"
+(2001,0020) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0021) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SPIR"				Name="SPIR"
+(2001,0021) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SPIR"				Name="SPIR"
+(2001,0021) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0022) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="WaterFatShift"		Name="Water-Fat Shift"
+(2001,0022) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="WaterFatShift"		Name="Water-Fat Shift"
+(2001,0022) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0023) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="FlipAngle"			Name="Flip Angle"
+(2001,0023) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="FlipAngle"			Name="Flip Angle"
+(2001,0023) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0024) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SeriesIsInteractive"		Name="Series is Interactive"
+(2001,0024) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SeriesIsInteractive"		Name="Series is Interactive"
+(2001,0024) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0025) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="EchoTimeDisplay"		Name="Echo Time Display"
+(2001,0025) VERS=""		VR="SH"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="EchoTimeDisplay"		Name="Echo Time Display"
+(2001,0025) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0026) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PresentationStateSubtractionActive"	Name="Presentation State Subtraction Active"
+(2001,0026) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PresentationStateSubtractionActive"	Name="Presentation State Subtraction Active"
+(2001,0026) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0027) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0028) VERS=""		VR="US"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0029) VERS=""	    VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"							Name="?"
+(2001,0029) VERS=""	    VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"							Name="?"
+(2001,0029) VERS=""		VR="US"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,002a) VERS=""		VR="US"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,002b) VERS=""	    VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"							Name="?"
+(2001,002b) VERS=""	    VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"							Name="?"
+(2001,002b) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,002c) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,002d) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfSlicesInStack"		Name="Number of Slices in Stack"
+(2001,002d) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfSlicesInStack"		Name="Number of Slices in Stack"
+(2001,002d) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,002e) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,002f) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0030) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0031) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0032) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="StackRadialAngle"			Name="Stack Radial Angle"
+(2001,0032) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="StackRadialAngle"			Name="Stack Radial Angle"
+(2001,0032) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0033) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="StackRadialAxis"			Name="Stack Radial Axis"
+(2001,0033) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="StackRadialAxis"			Name="Stack Radial Axis"
+(2001,0033) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0034) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0035) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="StackSliceNumber"			Name="Stack Slice Number"
+(2001,0035) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="StackSliceNumber"			Name="Stack Slice Number"
+(2001,0035) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0036) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="StackType"					Name="Stack Type"
+(2001,0036) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="StackType"					Name="Stack Type"
+(2001,0036) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0037) VERS=""		VR="FD"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0039) VERS=""	    VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"				Name="?"
+(2001,0039) VERS=""	    VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"				Name="?"
+(2001,0039) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,003a) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,003b) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,003c) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,003d) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ContourFillColor"			Name="Contour Fill Color"
+(2001,003d) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ContourFillColor"			Name="Contour Fill Color"
+(2001,003d) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,003e) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,003f) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DisplayedAreaZoomInterpolationMeth"	Name="Displayed Area Zoom Interpolation Method"
+(2001,003f) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DisplayedAreaZoomInterpolationMeth"	Name="Displayed Area Zoom Interpolation Method"
+(2001,003f) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0040) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 002"	Keyword="?"		Name="?"
+(2001,0043) VERS=""		VR="IS"   VM="2"	Owner="PHILIPS IMAGING DD 001"		Keyword="EllipsDisplShutMajorAxFrstEndPnt"		Name="Ellipse Display Shutter Major Axis First End Point"
+(2001,0043) VERS=""		VR="IS"   VM="2"	Owner="Philips Imaging DD 001"		Keyword="EllipsDisplShutMajorAxFrstEndPnt"		Name="Ellipse Display Shutter Major Axis First End Point"
+(2001,0044) VERS=""		VR="IS"   VM="2"	Owner="PHILIPS IMAGING DD 001"		Keyword="EllipsDisplShutMajorAxScndEndPnt"		Name="Ellipse Display Shutter Major Axis Second End Point"
+(2001,0044) VERS=""		VR="IS"   VM="2"	Owner="Philips Imaging DD 001"		Keyword="EllipsDisplShutMajorAxScndEndPnt"		Name="Ellipse Display Shutter Major Axis Second End Point"
+(2001,0045) VERS=""		VR="IS"   VM="2"	Owner="PHILIPS IMAGING DD 001"		Keyword="EllipsDisplShutOtherAxFrstEndPnt"		Name="Ellipse Display Shutter Other Axis First End Point"
+(2001,0045) VERS=""		VR="IS"   VM="2"	Owner="Philips Imaging DD 001"		Keyword="EllipsDisplShutOtherAxFrstEndPnt"		Name="Ellipse Display Shutter Other Axis First End Point"
+(2001,0046) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicLineStyle"				Name="Graphic Line Style"
+(2001,0046) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicLineStyle"				Name="Graphic Line Style"
+(2001,0047) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicLineWidth"				Name="Graphic Line Width"
+(2001,0047) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicLineWidth"				Name="Graphic Line Width"
+(2001,0048) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicAnnotationID"			Name="Graphic Annotation ID"
+(2001,0048) VERS=""		VR="SS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicAnnotationID"			Name="Graphic Annotation ID"
+(2001,004b) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="InterpolationMethod"			Name="Interpolation Method"
+(2001,004b) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="InterpolationMethod"			Name="Interpolation Method"
+(2001,004c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PolyLineBeginPointStyle"		Name="Poly Line Begin Point Style"
+(2001,004c) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PolyLineBeginPointStyle"		Name="Poly Line Begin Point Style"
+(2001,004d) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PolyLineEndPointStyle"			Name="Poly Line End Point Style"
+(2001,004d) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PolyLineEndPointStyle"			Name="Poly Line End Point Style"
+(2001,004e) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="WindowSmoothingTaste"			Name="Window Smoothing Taste"
+(2001,004e) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="WindowSmoothingTaste"			Name="Window Smoothing Taste"
+(2001,0050) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicMarkerType"				Name="Graphic Marker Type"
+(2001,0050) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicMarkerType"				Name="Graphic Marker Type"
+(2001,0051) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="OverlayPlaneID"				Name="Overlay Plane ID"
+(2001,0051) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="OverlayPlaneID"				Name="Overlay Plane ID"
+(2001,0052) VERS=""		VR="UI"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImagePresentationStateUID"		Name="Image Presentation State UID"
+(2001,0052) VERS=""		VR="UI"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ImagePresentationStateUID"		Name="Image Presentation State UID"
+(2001,0053) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PresentationGLTrafoInvert"		Name="Presentation GL Transform Invert"
+(2001,0053) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PresentationGLTrafoInvert"		Name="Presentation GL Transform Invert"
+(2001,0054) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ContourFillTransparency"		Name="Contour Fill Transparency"
+(2001,0054) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ContourFillTransparency"		Name="Contour Fill Transparency"
+(2001,0055) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicLineColor"				Name="Graphic Line Color"
+(2001,0055) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicLineColor"				Name="Graphic Line Color"
+(2001,0056) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicType"					Name="Graphic Type"
+(2001,0056) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicType"					Name="Graphic Type"
+(2001,0058) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ContrastTransferTaste"			Name="Contrast Transfer Taste"
+(2001,0058) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ContrastTransferTaste"			Name="Contrast Transfer Taste"
+(2001,005a) VERS=""	    VR="ST"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicAnnotationModel"		Name="Graphic Annotation Model"
+(2001,005a) VERS=""	    VR="ST"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicAnnotationModel"		Name="Graphic Annotation Model"
+(2001,005d) VERS=""	    VR="ST"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="MeasurementTextUnits"			Name="Measurement Text Units"
+(2001,005d) VERS=""	    VR="ST"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="MeasurementTextUnits"			Name="Measurement Text Units"
+(2001,005e) VERS=""	    VR="ST"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="MeasurementTextType"			Name="Measurement Text Type"
+(2001,005e) VERS=""	    VR="ST"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="MeasurementTextType"			Name="Measurement Text Type"
+(2001,005f) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="StackSequence"					Name="Stack Sequence"
+(2001,005f) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="StackSequence"					Name="Stack Sequence"
+(2001,0060) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfStacks"				Name="Number of Stacks"
+(2001,0060) VERS=""		VR="SL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfStacks"				Name="Number of Stacks"
+(2001,0061) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SeriesTransmitted"				Name="Series Transmitted"
+(2001,0061) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SeriesTransmitted"				Name="Series Transmitted"
+(2001,0062) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SeriesCommitted"				Name="Series Committed"
+(2001,0062) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SeriesCommitted"				Name="Series Committed"
+(2001,0063) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ExaminationSource"				Name="Examination Source"
+(2001,0063) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ExaminationSource"				Name="Examination Source"
+(2001,0064) VERS=""	    VR="SH"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextType"						Name="Text Type"
+(2001,0064) VERS=""	    VR="SH"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextType"						Name="Text Type"
+(2001,0065) VERS=""	    VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicOverlayPlane"			Name="Graphic Overlay Plane"
+(2001,0065) VERS=""	    VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicOverlayPlane"			Name="Graphic Overlay Plane"
+(2001,0067) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="LinearPresentationGLTrafoShapeSub"	Name="Linear Presentation GL Transform Shape Sub"
+(2001,0067) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="LinearPresentationGLTrafoShapeSub"	Name="Linear Presentation GL Transform Shape Sub"
+(2001,0068) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="LinearModalityGLTrafo"			Name="Linear Modality GL Transform"
+(2001,0068) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="LinearModalityGLTrafo"			Name="Linear Modality GL Transform"
+(2001,0069) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DisplayShutter"				Name="Display Shutter"
+(2001,0069) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DisplayShutter"				Name="Display Shutter"
+(2001,006a) VERS=""	    VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SpatialTransformation"			Name="Spatial Transformation"
+(2001,006a) VERS=""	    VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SpatialTransformation"			Name="Spatial Transformation"
+(2001,006b) VERS=""	    VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"								Name="?"
+(2001,006b) VERS=""	    VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"								Name="?"
+(2001,006d) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextFont"						Name="Text Font"
+(2001,006d) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextFont"						Name="Text Font"
+(2001,006e) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SeriesType"					Name="Series Type"
+(2001,006e) VERS=""		VR="SH"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SeriesType"					Name="Series Type"
+(2001,0071) VERS=""	    VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicConstraint"				Name="Graphic Constraint"
+(2001,0071) VERS=""	    VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicConstraint"				Name="Graphic Constraint"
+(2001,0072) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="EllipsDisplShutOtherAxScndEndPnt"	Name="Ellipse Display Shutter Other Axis Second End Point"
+(2001,0072) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="EllipsDisplShutOtherAxScndEndPnt"	Name="Ellipse Display Shutter Other Axis Second End Point"
+(2001,0072) VERS=""		VR="FL"   VM="2"	Owner="Philips Imaging DD 002"		Keyword="?"								Name="?"
+(2001,0073) VERS=""		VR="FL"   VM="2"	Owner="Philips Imaging DD 002"		Keyword="?"								Name="?"
+(2001,0074) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"								Name="?"
+(2001,0074) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"								Name="?"
+(2001,0075) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"								Name="?"
+(2001,0075) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"								Name="?"
+(2001,0076) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfFrames"				Name="Number of Frames"
+(2001,0076) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfFrames"				Name="Number of Frames"
+(2001,0077) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GLTrafoType"					Name="GL Transform Type"
+(2001,0077) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GLTrafoType"					Name="GL Transform Type"
+(2001,007a) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="WindowRoundingFactor"			Name="Window Rounding Factor"
+(2001,007a) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="WindowRoundingFactor"			Name="Window Rounding Factor"
+(2001,007b) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="AcquisitionNumber"		Name="Acquisition Number"
+(2001,007b) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="AcquisitionNumber"		Name="Acquisition Number"
+(2001,007c) VERS=""		VR="US"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="FrameNumber"					Name="Frame Number"
+(2001,007c) VERS=""		VR="US"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="FrameNumber"					Name="Frame Number"
+(2001,0080) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"								Name="?"
+(2001,0080) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"								Name="?"
+(2001,0081) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfDynamicScans"	Name="Number of Dynamic Scans"
+(2001,0081) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfDynamicScans"	Name="Number of Dynamic Scans"
+(2001,0082) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="EchoTrainLength"			Name="Echo Train Length"
+(2001,0082) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="EchoTrainLength"			Name="Echo Train Length"
+(2001,0083) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImagingFrequency"		Name="Imaging Frequency"
+(2001,0083) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ImagingFrequency"		Name="Imaging Frequency"
+(2001,0084) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="InversionTime"			Name="Inversion Time"
+(2001,0084) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="InversionTime"			Name="Inversion Time"
+(2001,0085) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="MagneticFieldStrength"	Name="Magnetic Field Strength"
+(2001,0085) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="MagneticFieldStrength"	Name="Magnetic Field Strength"
+(2001,0086) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NrOfPhaseEncodingSteps"	Name="Number of Phase Encoding Steps"
+(2001,0086) VERS=""		VR="IS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NrOfPhaseEncodingSteps"	Name="Number of Phase Encoding Steps"
+(2001,0087) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ImagedNucleus"			Name="Imaged Nucleus"
+(2001,0087) VERS=""		VR="SH"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ImagedNucleus"			Name="Imaged Nucleus"
+(2001,0088) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="NumberOfAverages"		Name="Number of Averages"
+(2001,0088) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="NumberOfAverages"		Name="Number of Averages"
+(2001,0089) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="PhaseFOVPercent"			Name="Phase FOV Percent"
+(2001,0089) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="PhaseFOVPercent"			Name="Phase FOV Percent"
+(2001,008a) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="SamplingPercent"			Name="Sampling Percent"
+(2001,008a) VERS=""		VR="DS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="SamplingPercent"			Name="Sampling Percent"
+(2001,008b) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TransmittingCoil"				Name="Transmitting Coil"
+(2001,008b) VERS=""		VR="SH"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TransmittingCoil"				Name="Transmitting Coil"
+(2001,0090) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextForegroundColor"			Name="Text Foreground Color"
+(2001,0090) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextForegroundColor"			Name="Text Foreground Color"
+(2001,0091) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextBackgroundColor"			Name="Text Background Color"
+(2001,0091) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextBackgroundColor"			Name="Text Background Color"
+(2001,0092) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextShadowColor"				Name="Text Shadow Color"
+(2001,0092) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextShadowColor"				Name="Text Shadow Color"
+(2001,0093) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextStyle"						Name="Text Style"
+(2001,0093) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextStyle"						Name="Text Style"
+(2001,009a) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"								Name="?"
+(2001,009a) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"								Name="?"
+(2001,009b) VERS=""	    VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicNumber"					Name="Graphic Number"
+(2001,009b) VERS=""	    VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicNumber"					Name="Graphic Number"
+(2001,009c) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="GraphicAnnotationLabel"		Name="Graphic Annotation Label"
+(2001,009c) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="GraphicAnnotationLabel"		Name="Graphic Annotation Label"
+(2001,009f) VERS=""		VR="US"   VM="2"	Owner="PHILIPS IMAGING DD 001"		Keyword="PixelProcessingKernelSize"		Name="Pixel Processing Kernel Size"
+(2001,009f) VERS=""		VR="US"   VM="2"	Owner="Philips Imaging DD 001"		Keyword="PixelProcessingKernelSize"		Name="Pixel Processing Kernel Size"
+(2001,00a1) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="IsRawImage"					Name="Is Raw Image"
+(2001,00a1) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="IsRawImage"					Name="Is Raw Image"
+(2001,00a3) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextColorForeground"			Name="Text Color Foreground"
+(2001,00a3) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextColorForeground"			Name="Text Color Foreground"
+(2001,00a4) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextColorBackground"			Name="Text Color Background"
+(2001,00a4) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextColorBackground"			Name="Text Color Background"
+(2001,00a5) VERS=""		VR="UL"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="TextColorShadow"				Name="Text Color Shadow"
+(2001,00a5) VERS=""		VR="UL"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="TextColorShadow"				Name="Text Color Shadow"
+(2001,00c1) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="LinearModalityGLTrafo"			Name="Linear Modality GL Transform"
+(2001,00c1) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="LinearModalityGLTrafo"			Name="Linear Modality GL Transform"
+(2001,00c8) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="ExamCardName"					Name="Exam Card Name"
+(2001,00c8) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="ExamCardName"					Name="Exam Card Name"
+(2001,00cc) VERS=""		VR="ST"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="DerivationDescription"	Name="Derivation Description"
+(2001,00cc) VERS=""		VR="ST"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="DerivationDescription"	Name="Derivation Description"
+(2001,00da) VERS=""	    VR="CS"   VM="1"	Owner="PHILIPS IMAGING DD 001"		Keyword="?"								Name="?"
+(2001,00da) VERS=""	    VR="CS"   VM="1"	Owner="Philips Imaging DD 001"		Keyword="?"								Name="?"
+(2001,00f1) VERS=""	    VR="FL"   VM="1-n"	Owner="PHILIPS IMAGING DD 001"		Keyword="ProspectiveMotionCorrection"	Name="Prospective Motion Correction"
+(2001,00f1) VERS=""	    VR="FL"   VM="6"	Owner="Philips Imaging DD 001"		Keyword="ProspectiveMotionCorrection"	Name="Prospective Motion Correction"
+(2001,00f2) VERS=""	    VR="FL"   VM="1-n"	Owner="PHILIPS IMAGING DD 001"		Keyword="RetrospectiveMotionCorrection"	Name="Retrospective Motion Correction"
+(2001,00f2) VERS=""	    VR="FL"   VM="6"	Owner="Philips Imaging DD 001"		Keyword="RetrospectiveMotionCorrection"	Name="Retrospective Motion Correction"
+(2003,0000) VERS=""		VR="CS"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0002) VERS=""		VR="FD"   VM="3"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0006) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0009) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0010) VERS=""		VR="LO"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0011) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0012) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0013) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0014) VERS=""		VR="FD"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0015) VERS=""		VR="FD"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0016) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0017) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0018) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0019) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0022) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0024) VERS=""		VR="FD"   VM="4"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0025) VERS=""		VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0026) VERS=""	    VR="SL"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0027) VERS=""		VR="SH"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0028) VERS=""		VR="SH"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0029) VERS=""		VR="FD"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,002a) VERS=""		VR="LO"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,002b) VERS=""		VR="FD"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,002c) VERS=""		VR="SH"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,002d) VERS=""		VR="SL"   VM="1-n"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,002e) VERS=""		VR="SQ"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0030) VERS=""		VR="CS"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0031) VERS=""		VR="CS"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2003,0032) VERS=""		VR="UI"   VM="1"	Owner="Philips X-ray Imaging DD 001"	Keyword="?"				Name="?"
+(2005,0000) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageAngulationAP"			Name="Image Angulation AP"
+(2005,0000) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageAngulationAP"			Name="Image Angulation AP"
+(2005,0000) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NumberOfSOPCommon"			Name="Number of SOP Common"
+(2005,0000) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumExtraNumber"		Name="Spectrum Extra Number"
+(2005,0000) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="VolumeViewEnabled"			Name="Volume View Enabled"
+(2005,0001) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageAngulationFH"			Name="Image Angulation FH"
+(2005,0001) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageAngulationFH"			Name="Image Angulation FH"
+(2005,0001) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NoOfFilmConsumption"		Name="Number of Film Consumption"
+(2005,0001) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumKxCoordinate"		Name="Spectrum Kx Coordinate"
+(2005,0001) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfStudyReference"	Name="Number of Study Reference"
+(2005,0002) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageAngulationRL"			Name="Image Angulation RL"
+(2005,0002) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageAngulationRL"			Name="Image Angulation RL"
+(2005,0002) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumKyCoordinate"		Name="Spectrum Ky Coordinate"
+(2005,0002) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="SPSCode"					Name="SPS Code"
+(2005,0003) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageAnnotationCount"		Name="Image Annotation Count"
+(2005,0003) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumLocationNumber"	Name="Spectrum Location Number"
+(2005,0003) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfSPSCodes"			Name="Number of SPS Codes"
+(2005,0004) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageDisplayOrientation"	Name="Image Display Orientation"
+(2005,0004) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageDisplayOrientation"	Name="Image Display Orientation"
+(2005,0004) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumMixNumber"			Name="Spectrum Mix Number"
+(2005,0004) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="?"							Name="?"
+(2005,0005) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SynergyReconstructionType"	Name="Synergy Reconstruction Type"
+(2005,0005) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SynergyReconstructionType"	Name="Synergy Reconstruction Type"
+(2005,0005) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumXCoordinate"		Name="Spectrum X Coordinate"
+(2005,0006) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumYCoordinate"		Name="Spectrum Y Coordinate"
+(2005,0006) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfPSSpecificCharacterSets"	Name="Number of PS Specific Character Sets"
+(2005,0007) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageLineCount"			Name="Image Line Count"
+(2005,0007) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumDCLevel"			Name="Spectrum DC Level"
+(2005,0007) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfSpecificCharacterSet"	Name="Number of Specific Character Set"
+(2005,0008) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageOffcenterAP"			Name="Image Offcenter AP"
+(2005,0008) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageOffcenterAP"			Name="Image Offcenter AP"
+(2005,0008) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumNoiseLevel"		Name="Spectrum Noise Level"
+(2005,0009) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageOffcenterFH"			Name="Image Offcenter FH"
+(2005,0009) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageOffcenterFH"			Name="Image Offcenter FH"
+(2005,0009) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumBeginTime"			Name="Spectrum Begin Time"
+(2005,0009) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="RescaleInterceptOriginal"	Name="Rescale Intercept Original"
+(2005,000a) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageOffCentreRL"			Name="Image OffCentre RL"
+(2005,000a) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ImageOffCentreRL"			Name="Image OffCentre RL"
+(2005,000a) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="RescaleSlopeOriginal"		Name="Rescale Slope Original"
+(2005,000b) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MaxFP"						Name="Max FP"
+(2005,000b) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MaxFP"						Name="Max FP"
+(2005,000b) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="RescaleTypeOriginal"		Name="Rescale Type Original"
+(2005,000c) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MinFP"						Name="Min FP"
+(2005,000c) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MinFP"						Name="Min FP"
+(2005,000d) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ScaleIntercept"			Name="Scale Intercept"
+(2005,000d) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ScaleIntercept"			Name="Scale Intercept"
+(2005,000e) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ScaleSlope"				Name="Scale Slope"
+(2005,000e) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ScaleSlope"				Name="Scale Slope"
+(2005,000e) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="PrivateSharedSequence"		Name="Private Shared Sequence"
+(2005,000f) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="WindowCenter"				Name="Window Center"
+(2005,000f) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="WindowCenter"				Name="Window Center"
+(2005,000f) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="PrivatePerFrameSequence"	Name="Private Per-Frame Sequence"
+(2005,0010) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="WindowWidth"				Name="Window Width"
+(2005,0010) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="WindowWidth"				Name="Window Width"
+(2005,0010) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumEchoTime"			Name="Spectrum Echo Time"
+(2005,0010) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="MFConvTreatSpectroMixNumber"	Name="MF Conv Treat Spectro Mix Number"
+(2005,0011) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ImageType"					Name="Image Type"
+(2005,0011) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ImageType"					Name="Image Type"
+(2005,0011) VERS=""		VR="UI"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="MFPrivateReferencedSOPInstanceUID"	Name="MF Private Referenced SOP Instance UID"
+(2005,0012) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="CardiacGating"				Name="Cardiac Gating"
+(2005,0012) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="CardiacGating"				Name="Cardiac Gating"
+(2005,0012) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumInversionTime"		Name="Spectrum Inversion Time"
+(2005,0012) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="DiffusionBValueNumber"		Name="Diffusion B Value Number"
+(2005,0013) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="DevelopmentMode"			Name="Development Mode"
+(2005,0013) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="DevelopmentMode"			Name="Development Mode"
+(2005,0013) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NumberOfCodes"				Name="Number of Codes"
+(2005,0013) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumNumber"			Name="Spectrum Number"
+(2005,0013) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="GradientOrientationNumber"	Name="Gradient Orientation Number"
+(2005,0014) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="Diffusion"					Name="Diffusion"
+(2005,0014) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="Diffusion"					Name="Diffusion"
+(2005,0014) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumNumberOfAverages"	Name="Spectrum Number of Averages"
+(2005,0014) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfDiffusionBValues"	Name="Number of Diffusion B Values"
+(2005,0015) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="FatSaturation"				Name="Fat Saturation"
+(2005,0015) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="FatSaturation"				Name="Fat Saturation"
+(2005,0015) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="UserName"					Name="User Name"
+(2005,0015) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumNumberOfSamples"	Name="Spectrum Number of Samples"
+(2005,0015) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfDiffusionGradientOrientations"	Name="Number of Diffusion Gradient Orientations"
+(2005,0016) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="FlowCompensation"			Name="Flow Compensation"
+(2005,0016) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="FlowCompensation"			Name="Flow Compensation"
+(2005,0016) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="PassWord"					Name="Pass Word"
+(2005,0016) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumScanSequenceNumber"	Name="Spectrum Scan Sequence Number"
+(2005,0016) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="PlanMode"					Name="Plan Mode"
+(2005,0017) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="FourierInterpolation"		Name="Fourier Interpolation"
+(2005,0017) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="FourierInterpolation"		Name="Fourier Interpolation"
+(2005,0017) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="ServerName"				Name="Server Name"
+(2005,0017) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumNumberOfPeaks"		Name="Spectrum Number of Peaks"
+(2005,0017) VERS=""		VR="FD"   VM="3"	Owner="Philips MR Imaging DD 005"		Keyword="DiffusionBMatrix"			Name="Diffusion B Matrix"
+(2005,0018) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="HardcopyProtocol"			Name="Hardcopy Protocol"
+(2005,0018) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="HardcopyProtocol"			Name="Hardcopy Protocol"
+(2005,0018) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="DataBaseName"				Name="Data Base Name"
+(2005,0018) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeak"				Name="Spectrum Peak"
+(2005,0018) VERS=""		VR="CS"   VM="3"	Owner="Philips MR Imaging DD 005"		Keyword="OperatingModeType"			Name="Operating Mode Type"
+(2005,0019) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="InverseReconstructed"		Name="Inverse Reconstructed"
+(2005,0019) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="InverseReconstructed"		Name="Inverse Reconstructed"
+(2005,0019) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="RootName"					Name="RootName"
+(2005,0019) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeakIntensity"		Name="Spectrum Peak Intensity"
+(2005,0019) VERS=""		VR="CS"   VM="3"	Owner="Philips MR Imaging DD 005"		Keyword="OperatingMode"				Name="Operating Mode"
+(2005,001a) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="LabelSyntax"				Name="Label Syntax"
+(2005,001a) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="LabelSyntax"				Name="Label Syntax"
+(2005,001a) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="FatSaturationTechnique"	Name="Fat Saturation Technique"
+(2005,001b) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MagnetizationPrepared"		Name="Magnetization Prepared"
+(2005,001b) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MagnetizationPrepared"		Name="Magnetization Prepared"
+(2005,001b) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="VersionNumberDeletedImages"	Name="Version Number Deleted Images"
+(2005,001c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MagnetizationTransferContrast"	Name="Magnetization Transfer Contrast"
+(2005,001c) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MagnetizationTransferContrast"	Name="Magnetization Transfer Contrast"
+(2005,001c) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="VersionNumberDeletedSpectra"	Name="Version Number Deleted Spectra"
+(2005,001d) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MeasurementScanResolution"		Name="Measurement Scan Resolution"
+(2005,001d) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MeasurementScanResolution"		Name="Measurement Scan Resolution"
+(2005,001d) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="VersionNumberDeletedBlobsets"	Name="Version Number Deleted Blobsets"
+(2005,001e) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MIPProtocol"				Name="MIP Protocol"
+(2005,001e) VERS=""		VR="SH"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MIPProtocol"				Name="MIP Protocol"
+(2005,001e) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT1Offset"				Name="LUT1 Offset"
+(2005,001f) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="MPRProtocol"				Name="MPR Protocol"
+(2005,001f) VERS=""		VR="SH"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="MPRProtocol"				Name="MPR Protocol"
+(2005,001f) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT1Range"					Name="LUT1 Range"
+(2005,0020) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfChemicalShift"		Name="Number of Chemical Shift"
+(2005,0020) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfChemicalShifts"	Name="Number of Chemical Shifts"
+(2005,0020) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="DMIApplicationName"		Name="DMI Application Name"
+(2005,0020) VERS=""		VR="LO"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeakLabel"			Name="Spectrum Peak Label"
+(2005,0020) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT1BeginColor"			Name="LUT1 Begin Color"
+(2005,0021) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfMixes"				Name="Number of Mixes"
+(2005,0021) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfMixes"				Name="Number of Mixes"
+(2005,0021) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeakPhase"			Name="Spectrum Peak Phase"
+(2005,0021) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT1EndColor"				Name="LUT1 End Color"
+(2005,0022) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfReferences"		Name="Number of References"
+(2005,0022) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfReferences"		Name="Number of References"
+(2005,0022) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeakPosition"		Name="Spectrum Peak Position"
+(2005,0022) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT2Offset"				Name="LUT2 Offset"
+(2005,0023) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfSlabs"				Name="Number of Slabs"
+(2005,0023) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfSlabs"				Name="Number of Slabs"
+(2005,0023) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeakType"			Name="Spectrum Peak Type"
+(2005,0023) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT2Range"					Name="LUT2 Range"
+(2005,0024) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPeakWidth"			Name="Spectrum Peak Width"
+(2005,0024) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT2BeginColor"			Name="LUT2 Begin Color"
+(2005,0025) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfVolumes"			Name="Number of Volumes"
+(2005,0025) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfVolumes"			Name="Number of Volumes"
+(2005,0025) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroSIB0Correction"		Name="Spectro SI B0 Correction"
+(2005,0025) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUT2EndColor"				Name="LUT2 End Color"
+(2005,0026) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="OverSamplingPhase"			Name="Over Sampling Phase"
+(2005,0026) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="OverSamplingPhase"			Name="Over Sampling Phase"
+(2005,0026) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroB0EchoTopPosition"	Name="Spectro B0 Echo Top Position"
+(2005,0026) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ViewingHardcopyOnly"		Name="Viewing Hardcopy Only"
+(2005,0027) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		KKeyword="PackageMode"				Name="Package Mode"
+(2005,0027) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PackageMode"				Name="Package Mode"
+(2005,0027) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroComplexComponent"	Name="Spectro Complex Component"
+(2005,0027) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="?"							Name="?"							# not SQ <Private EMR> after all :(
+(2005,0028) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PartialFourierFrequency"	Name="Partial Fourier Frequency"
+(2005,0028) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PartialFourierFrequency"	Name="Partial Fourier Frequency"
+(2005,0028) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroDataOrigin"			Name="Spectro Data Origin"
+(2005,0028) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfLabelTypes"		Name="Number of Label Types"
+(2005,0029) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PartialFourierPhase"		Name="PartialFourierPhase"
+(2005,0029) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PartialFourierPhase"		Name="PartialFourierPhase"
+(2005,0029) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroEchoTopPosition"	Name="Spectro Echo Top Position"
+(2005,0029) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LabelType"					Name="Label Type"
+(2005,002D) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="RootId"					Name="Root Id"
+(2005,002a) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PatientReferenceID"		Name="Patient Reference ID"
+(2005,002a) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PatientReferenceID"		Name="Patient Reference ID"
+(2005,002a) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ExamPrintStatus"			Name="Exam Print Status"
+(2005,002b) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PercentScanComplete"		Name="Percent Scan Complete"
+(2005,002b) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PercentScanComplete"		Name="Percent Scan Complete"
+(2005,002b) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ExamExportStatus"			Name="Exam Export Status"
+(2005,002c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PhaseEncodeReordering"		Name="Phase Encode Reordering"
+(2005,002c) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PhaseEncodeReordering"		Name="Phase Encode Reordering"
+(2005,002c) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ExamStorageCommitStatus"	Name="Exam Storage Commit Status"
+(2005,002d) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PlanScanSurveyNumberOfImages"	Name="PlanScan Survey Number of Images"
+(2005,002d) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyNumberOfImages"	Name="PlanScan Survey Number of Images"
+(2005,002d) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ExamMediaWriteStatus"		Name="Exam Media Write Status"
+(2005,002e) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PPGPPUGating"				Name="PPG PPU Gating"
+(2005,002e) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PPGPPUGating"				Name="PPG PPU Gating"
+(2005,002e) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="DBdt"				Name="dBdt"
+(2005,002f) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SpatialPresaturation"		Name="Spatial Presaturation"
+(2005,002f) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SpatialPresaturation"		Name="Spatial Presaturation"
+(2005,002f) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ProtonSAR"			Name="Proton SAR"
+(2005,0030) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="RepetitionTime"			Name="Repetition Time"
+(2005,0030) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="RepetitionTime"		Name="Repetition Time"
+(2005,0030) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="InPlaneTransforms"			Name="InPlane Transforms"
+(2005,0030) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NonProtonSAR"		Name="Non Proton SAR"
+(2005,0031) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="RespiratoryGating"			Name="Respiratory Gating"
+(2005,0031) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="RespiratoryGating"			Name="Respiratory Gating"
+(2005,0031) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="NumberOfSpectraAcquired"	Name="Number of Spectra Acquired"
+(2005,0031) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LocalSAR"			Name="Local SAR"
+(2005,0032) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SampleRepresentation"		Name="Sample Representation"
+(2005,0032) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SampleRepresentation"		Name="Sample Representation"
+(2005,0032) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobDataObjectArray"		Name="Blob Data Object Array"
+(2005,0032) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="SafetyOverrideMode"	Name="Safety Override Mode"
+(2005,0033) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="AcquisitionDuration"		Name="Acquisition Duration"
+(2005,0033) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="AcquisitionDuration"		Name="Acquisition Duration"
+(2005,0033) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="PhaseEncodingEchoTopPositions"	Name="Phase Encoding Echo Top Positions"
+(2005,0033) VERS=""		VR="DT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="EVDVDJobInParamsDatetime"	Name="EV DVD Job In Params Datetime"
+(2005,0034) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SegmentedKSpace"			Name="Segmented KSpace"
+(2005,0034) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SegmentedKSpace"			Name="Segmented KSpace"
+(2005,0034) VERS=""		VR="LT"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="SeriesTransactionUID"		Name="Series Transaction UID"
+(2005,0034) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NumberOfImagePerSeriesRef"		Name="Number of Image Per Series Ref"
+(2005,0034) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="PhysicalQuantityForChemicalShift"	Name="Physical Quantity for Chemical Shift"
+(2005,0034) VERS=""		VR="DT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="DVDJobInParamsVolumeLabel"	Name="DVD Job In Params Volume Label"
+(2005,0035) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="DataType"					Name="Data Type"
+(2005,0035) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="DataType"					Name="Data Type"
+(2005,0035) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="ParentID"						Name="Parent ID"
+(2005,0035) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="PhysicalQuantitySpatial"	Name="Physical Quantity Spatial"
+(2005,0035) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="SpectroExamcard"			Name="Spectro Examcard"
+(2005,0036) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="IsCardiac"					Name="Is Cardiac"
+(2005,0036) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="IsCardiac"					Name="Is Cardiac"
+(2005,0036) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="ParentType"				Name="Parent Type"
+(2005,0036) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="ReferenceFrequency"		Name="Reference Frequency"
+(2005,0036) VERS=""		VR="UI"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ReferencedSeriesInstanceUID"		Name="Referenced Series Instance UID"
+(2005,0037) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="IsSpectro"					Name="Is Spectro"
+(2005,0037) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="IsSpectro"					Name="Is Spectro"
+(2005,0037) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobName"					Name="Blob Name"
+(2005,0037) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SampleOffset"				Name="Sample Offset"
+(2005,0037) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ColorLUTType"				Name="Color LUT Type"
+(2005,0038) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="Spoiled"					Name="Spoiled"
+(2005,0038) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="Spoiled"					Name="Spoiled"
+(2005,0038) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="ApplicationName"			Name="Application Name"
+(2005,0038) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SamplePitch"				Name="Sample Pitch"
+(2005,0038) VERS=""		VR="LT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="?"							Name="?"
+(2005,0039) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SteadyState"				Name="Steady State"
+(2005,0039) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SteadyState"				Name="Steady State"
+(2005,0039) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="TypeName"					Name="Type Name"
+(2005,0039) VERS=""		VR="SS"   VM="2"	Owner="Philips MR Imaging DD 004"		Keyword="SearchIntervalForPeaks"	Name="Search Interval for Peaks"
+(2005,0039) VERS=""		VR="LT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="?"							Name="?"
+(2005,003a) VERS=""		VR="SH"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SubAnatomy"				Name="Sub Anatomy"
+(2005,003a) VERS=""		VR="SH"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SubAnatomy"				Name="Sub Anatomy"
+(2005,003a) VERS=""		VR="LT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="DataDictionaryContentsVersion"			Name="Data Dictionary Contents Version"
+(2005,003b) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="TimeReversedSteadyState"	Name="Time Reversed Steady State"
+(2005,003b) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="TimeReversedSteadyState"	Name="Time Reversed Steady State"
+(2005,003b) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="IsCoilSurvey"							Name="Is Coil Survey"
+(2005,003c) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="TiltOptimizedNonsaturatedExcitation"	Name="Tilt Optimized Nonsaturated Excitation"
+(2005,003c) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="TiltOptimizedNonsaturatedExcitation"	Name="Tilt Optimized Nonsaturated Excitation"
+(2005,003c) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="StackTablePosLong"						Name="Stack Table Position Longitudinal"
+(2005,003d) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfRRIntervalRanges"				Name="Number of RR Interval Ranges"
+(2005,003d) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfRRIntervalRanges"				Name="Number of RR Interval Ranges"
+(2005,003d) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="StackTablePosLat"						Name="Stack Table Position Lateral"
+(2005,003e) VERS=""		VR="SL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="RRIntervalsDistribution"				Name="RR Intervals Distribution"
+(2005,003e) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="RRIntervalsDistribution"				Name="RR Intervals Distribution"
+(2005,003e) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="StackPosteriorCoilPos"					Name="Stack Posterior Coil Position"
+(2005,003f) VERS=""		VR="SL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PlanScanAcquisitionNumber"				Name="PlanScan Acquisition Number"
+(2005,003f) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanAcquisitionNumber"				Name="PlanScan Acquisition Number"
+(2005,003f) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="AIMDLimitsApplied"						Name="Active Implantable Medical Device Limits Applied"
+(2005,0040) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyChemicalShiftNumber"		Name="PlanScan Survey Chemical Shift Number"
+(2005,0040) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="VersionStr"							Name="Version String"
+(2005,0040) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SignalDomainForChemicalShift"			Name="Signal Domain for Chemical Shift"
+(2005,0040) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="AIMDHeadSARLimit"						Name="Active Implantable Medical Device Head SAR Limit"
+(2005,0041) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyDynamicScanNumber"		Name="PlanScan Survey Dynamic Scan Number"
+(2005,0041) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="CommentStr"							Name="Comment String"
+(2005,0041) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SignalDomainSpatial"					Name="Signal Domain Spatial"
+(2005,0041) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="AIMDWholeBodySARLimit"					Name="Active Implantable Medical Device Whole Body SAR Limit"
+(2005,0042) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyEchoNumber"				Name="PlanScan Survey Echo Number"
+(2005,0042) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobInFile"							Name="Blob In File"
+(2005,0042) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SignalType"							Name="Signal Type"
+(2005,0042) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="AIMDB1RMSLimit"						Name="Active Implantable Medical Device B1 RMS Limit"
+(2005,0043) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyImageType"				Name="PlanScan Survey Image Type"
+(2005,0043) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="ActualBlobSize"						Name="Actual Blob Size"
+(2005,0043) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NoDateOfLastCalibration"				Name="No Date of Last Calibration"
+(2005,0043) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroAdditionalRotations"			Name="Spectro Additional Rotations"
+(2005,0043) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="AIMDdbDtLimit"							Name="Active Implantable Medical Device dbDt Limit"
+(2005,0044) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyPhaseNumber"				Name="PlanScan Survey Phase Number"
+(2005,0044) VERS=""		VR="OW"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobData"								Name="Blob Data"
+(2005,0044) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NoTimeOfLastCalibration"				Name="No Time of Last Calibration"
+(2005,0044) VERS=""		VR="SS"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroDisplayRanges"					Name="Spectro Display Ranges"
+(2005,0044) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="TFEFactor"								Name="TFE Factor"
+(2005,0045) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyReconstructionNumber"	Name="PlanScan Survey Reconstruction Number"
+(2005,0045) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobFilename"							Name="Blob Filename"
+(2005,0045) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfSoftwareVersion"					Name="Number of Software Version"
+(2005,0045) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroEchoAcquisition"				Name="Spectro Echo Acquisition"
+(2005,0045) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="AttenuationCorrection"					Name="Attenuation Correction"
+(2005,0046) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyScanningSequence"		Name="PlanScan Survey Scanning Sequence"
+(2005,0046) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobOffset"							Name="Blob Offset"
+(2005,0046) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroFrequencyUnit"					Name="Spectro Frequency Unit"
+(2005,0046) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="FWHMShim"								Name="FWHM Shim"
+(2005,0047) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="PlanScanSurveyCSliceNumber"			Name="PlanScan Survey Slice Number"
+(2005,0047) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="BlobFlag"								Name="Blob Flag"
+(2005,0047) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfPatientOtherNames"					Name="Number of Patient Other Names"
+(2005,0047) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroGamma"							Name="Spectro Gamma"
+(2005,0047) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="PowerOptimization"						Name="Power Optimization"
+(2005,0048) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferencedAcquisitionNumber"			Name="Referenced Acquisition Number"
+(2005,0048) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferencedAcquisitionNumber"			Name="Referenced Acquisition Number"
+(2005,0048) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfReqRecipeOfResults"				Name="Number of Req Recipe of Results"
+(2005,0048) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroHiddenLineRemoval"				Name="Spectro Hidden Line Removal"
+(2005,0048) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="CoilQ"									Name="Coil Q"
+(2005,0049) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferencedChemicalShiftNumber"			Name="Referenced Chemical Shift Number"
+(2005,0049) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferencedChemicalShiftNumber"			Name="Referenced Chemical Shift Number"
+(2005,0049) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfSeriesOperatorsName"				Name="Number of Series Operators Name"
+(2005,0049) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroHorizontalShift"				Name="Spectro Horizontal Shift"
+(2005,0049) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ReceiverGain"							Name="Receiver Gain"
+(2005,004a) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferenceDynamicScanNumber"			Name="Referenced Dynamic Scan Number"
+(2005,004a) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferenceDynamicScanNumber"			Name="Referenced Dynamic Scan Number"
+(2005,004a) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="DataWindowDuration"					Name="Data Window Duration"
+(2005,004b) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferencedEchoNumber"					Name="Referenced Echo Number"
+(2005,004b) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferencedEchoNumber"					Name="Referenced Echo Number"
+(2005,004b) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="MixingTime"							Name="Mixing Time"
+(2005,004c) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferencedEntity"						Name="Referenced Entity"
+(2005,004c) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferencedEntity"						Name="Referenced Entity"
+(2005,004c) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="FirstEchoTime"							Name="First Echo Time"
+(2005,004d) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferencedImageType"					Name="Referenced Image Type"
+(2005,004d) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferencedImageType"					Name="Referenced Image Type"
+(2005,004d) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="IsB0Series"							Name="Is B0 Series"
+(2005,004e) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabFOVRL"								Name="Slab FOV RL"
+(2005,004e) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabFOVRL"								Name="Slab FOV RL"
+(2005,004e) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="IsB1Series"							Name="Is B1 Series"
+(2005,004f) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabOffcentreAP"						Name="Slab Offcentre AP"
+(2005,004f) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabOffcentreAP"						Name="Slab Offcentre AP"
+(2005,004f) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="VolumeSelect"							Name="Volume Select"
+(2005,0050) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabOffcentreFH"						Name="Slab Offcentre FH"
+(2005,0050) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabOffcentreFH"						Name="Slab Offcentre FH"
+(2005,0050) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfSeriesPerfPhysiName"				Name="Number of Series Performing Physicians Name"
+(2005,0050) VERS=""		VR="FL"   VM="2"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroHorizontalWindow"				Name="Spectro Horizontal Window"
+(2005,0050) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="NumberOfPatientOtherIDs"				Name="Number of Patient Other IDs"
+(2005,0051) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabOffcentreRL"						Name="Slab Offcentre RL"
+(2005,0051) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabOffcentreRL"						Name="Slab Offcentre RL"
+(2005,0051) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfStudyAdmittingDiagnosticDescr"		Name="Number of Study Admitting Diagnostic Description"
+(2005,0051) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroNumberOfDisplayRanges"			Name="Spectro Number of Display Ranges"
+(2005,0051) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="OriginalSeriesNumber"					Name="Original Series Number"
+(2005,0052) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabType"								Name="Slab Type"
+(2005,0052) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabType"								Name="Slab Type"
+(2005,0052) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfStudyPatientContrastAllergies"		Name="Number of Study Patient Contrast Allergies"
+(2005,0052) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroNumberOfEchoPulses"				Name="Spectro Number of Echo Pulses"
+(2005,0052) VERS=""		VR="UI"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="OriginalSeriesInstanceUID"				Name="Original Series Instance UID"
+(2005,0053) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabViewAxis"							Name="Slab View Axis"
+(2005,0053) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabViewAxis"							Name="Slab View Axis"
+(2005,0053) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfStudyPatientMedicalAlerts"			Name="Number of Study Patient Medical Alerts"
+(2005,0053) VERS=""		VR="LO"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroProcessingHistory"				Name="Spectro Processing History"
+(2005,0053) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="SplitSeriesJobParams"					Name="Split Series Job Params"
+(2005,0054) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeAngulationAP"					Name="Volume Angulation AP"
+(2005,0054) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeAngulationAP"					Name="Volume Angulation AP"
+(2005,0054) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfStudyPhysiciansOfRecord"			Name="Number of Study Physicians of Record"
+(2005,0054) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroScanType"						Name="Spectro Scan Type"
+(2005,0054) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="PreferredDimensionForSplitting"		Name="Preferred Dimension for Splitting"
+(2005,0055) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeAngulationFH"					Name="Volume Angulation FH"
+(2005,0055) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeAngulationFH"					Name="Volume Angulation FH"
+(2005,0055) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrOfStudyPhysiReadingStudy"			Name="Number of Study Physicians Reading Study"
+(2005,0055) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroSICSIntervals"					Name="Spectro SI CS Intervals"
+(2005,0055) VERS=""		VR="FD"   VM="3"	Owner="Philips MR Imaging DD 005"		Keyword="VelocityEncodingDirection"				Name="Velocity Encoding Direction"
+(2005,0056) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeAngulationRL"					Name="Volume Angulation RL"
+(2005,0056) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeAngulationRL"					Name="Volume Angulation RL"
+(2005,0056) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrSCSoftwareVersions"					Name="Number of SC Software Versions"
+(2005,0056) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroSIMode"							Name="Spectro SI Mode"
+(2005,0056) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusNumberOfInjections"		Name="Contrast/Bolus Number of Injections"
+(2005,0057) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeFOVAP"							Name="Volume FOV AP"
+(2005,0057) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeFOVAP"							Name="Volume FOV AP"
+(2005,0057) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="NrRunningAttributes"					Name="Number of Running Attributes"
+(2005,0057) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroSpectralBW"						Name="Spectro Spectral BW"
+(2005,0057) VERS=""		VR="LT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusAgentCode"				Name="Contrast/Bolus Agent Code"
+(2005,0058) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeFOVFH"							Name="Volume FOV FH"
+(2005,0058) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeFOVFH"							Name="Volume FOV FH"
+(2005,0058) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroTitleLine"						Name="Spectro Title Line"
+(2005,0058) VERS=""		VR="LT"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusAdminRouteCode"			Name="Contrast/Bolus Administration Route Code"
+(2005,0059) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeFOVRL"							Name="Volume FOV RL"
+(2005,0059) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeFOVRL"							Name="Volume FOV RL"
+(2005,0059) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroTurboEchoSpacing"				Name="Spectro Turbo Echo Spacing"
+(2005,0059) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusVolume"					Name="Contrast/Bolus Volume"
+(2005,005a) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeOffcentreAP"						Name="Volume Offcentre AP"
+(2005,005a) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeOffcentreAP"						Name="Volume Offcentre AP"
+(2005,005a) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusIngredientConcentration"	Name="Contrast/Bolus Ingredient Concentration"
+(2005,005b) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeOffcentreFH"						Name="Volume Offcentre FH"
+(2005,005b) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeOffcentreFH"						Name="Volume Offcentre FH"
+(2005,005b) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusDynamicNumber"			Name="Contrast/Bolus Dynamic Number"
+(2005,005c) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeOffcentreRL"						Name="Volume Offcentre RL"
+(2005,005c) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeOffcentreRL"						Name="Volume Offcentre RL"
+(2005,005c) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusSequence"					Name="Contrast/Bolus Sequence"
+(2005,005d) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeType"							Name="Volume Type"
+(2005,005d) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeType"							Name="Volume Type"
+(2005,005d) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="ContrastBolusID"						Name="Contrast/Bolus ID"
+(2005,005e) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="VolumeViewAxis"						Name="Volume View Axis"
+(2005,005e) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="VolumeViewAxis"						Name="Volume View Axis"
+(2005,005f) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StudyOrigin"							Name="Study Origin"
+(2005,005f) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StudyOrigin"							Name="Study Origin"
+(2005,0060) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StudySequenceNumber"					Name="Study Sequence Number"
+(2005,0060) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StudySequenceNumber"					Name="Study Sequence Number"
+(2005,0060) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroVerticalShift"					Name="Spectro Vertical Shift"
+(2005,0060) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="LUTToRGBJobParams"						Name="LUT to RGB Job Params"
+(2005,0061) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="PrepulseType"							Name="Prepulse Type"
+(2005,0061) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="PrepulseType"							Name="Prepulse Type"
+(2005,0061) VERS=""		VR="FL"   VM="2"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroVerticalWindow"					Name="Spectro Vertical Window"
+(2005,0062) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectroOffset"							Name="Spectro Offset"
+(2005,0063) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="fMRIStatusIndication"					Name="fMRI Status Indication"
+(2005,0063) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="fMRIStatusIndication"					Name="fMRI Status Indication"
+(2005,0063) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SpectrumPitch"							Name="Spectrum Pitch"
+(2005,0064) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferencePhaseNumber"					Name="Reference Phase Number"
+(2005,0064) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferencePhaseNumber"					Name="Reference Phase Number"
+(2005,0064) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="VolumeSelection"						Name="Volume Selection"
+(2005,0065) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferenceReconstructionNumber"			Name="Reference Reconstruction Number"
+(2005,0065) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferenceReconstructionNumber"			Name="Reference Reconstruction Number"
+(2005,0066) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferenceScanningSequence"				Name="Reference Scanning Sequence"
+(2005,0066) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferenceScanningSequence"				Name="Reference Scanning Sequence"
+(2005,0067) VERS=""		VR="IS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferenceSliceNumber"					Name="Reference Slice Number"
+(2005,0067) VERS=""		VR="IS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferenceSliceNumber"					Name="Reference Slice Number"
+(2005,0068) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ReferenceType"							Name="Reference Type"
+(2005,0068) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ReferenceType"							Name="Reference Type"
+(2005,0069) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabAngulationAP"						Name="Slab Angulation AP"
+(2005,0069) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabAngulationAP"						Name="Slab Angulation AP"
+(2005,006a) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabAngulationFH"						Name="Slab Angulation FH"
+(2005,006a) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabAngulationFH"						Name="Slab Angulation FH"
+(2005,006b) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabAngulationRL"						Name="Slab Angulation RL"
+(2005,006b) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabAngulationRL"						Name="Slab Angulation RL"
+(2005,006c) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabFOVAP"								Name="Slab FOV AP"
+(2005,006c) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabFOVAP"								Name="Slab FOV AP"
+(2005,006d) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SlabFOVFH"								Name="Slab FOV FH"
+(2005,006d) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="SlabFOVFH"								Name="Slab FOV FH"
+(2005,006e) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ScanningSequence"						Name="Scanning Sequence"
+(2005,006e) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="ScanningSequence"						Name="Scanning Sequence"
+(2005,006f) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="AcquisitionType"						Name="Acquisition Type"
+(2005,006f) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="AcquisitionType"						Name="Acquisition Type"
+(2005,0070) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="HardcopyProtocolEV"					Name="Hardcopy Protocol EasyVision"
+(2005,0070) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="HardcopyProtocolEV"					Name="Hardcopy Protocol EasyVision"
+(2005,0070) VERS=""		VR="OW"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="SpectrumPixelData"						Name="Spectrum Pixel Data"
+(2005,0070) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="NumberMixesSpectro"					Name="Number Mixes Spectro"
+(2005,0071) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackAngulationAP"						Name="Stack Angulation AP"
+(2005,0071) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackAngulationAP"						Name="Stack Angulation AP"
+(2005,0071) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="SeriesSPMix"							Name="Series SP Mix"
+(2005,0072) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackAngulationFH"						Name="Stack Angulation FH"
+(2005,0072) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackAngulationFH"						Name="Stack Angulation FH"
+(2005,0072) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixTResolution"						Name="SP Mix T Resolution"
+(2005,0073) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackAngulationRL"						Name="Stack Angulation RL"
+(2005,0073) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackAngulationRL"						Name="Stack Angulation RL"
+(2005,0073) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixKXResolution"						Name="SP Mix KX Resolution"
+(2005,0074) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackFOVAP"							Name="Stack FOV AP"
+(2005,0074) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackFOVAP"							Name="Stack FOV AP"
+(2005,0074) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixKYResolution"						Name="SP Mix KY Resolution"
+(2005,0075) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackFOVFH"							Name="Stack FOV FH"
+(2005,0075) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackFOVFH"							Name="Stack FOV FH"
+(2005,0075) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixFResolution"						Name="SP Mix F Resolution"
+(2005,0076) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackFOVRL"							Name="Stack FOV RL"
+(2005,0076) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackFOVRL"							Name="Stack FOV RL"
+(2005,0076) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixXResolution"						Name="SP Mix X Resolution"
+(2005,0077) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixYResolution"						Name="SP Mix Y Resolution"
+(2005,0078) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackOffcentreAP"						Name="Stack Offcentre AP"
+(2005,0078) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackOffcentreAP"						Name="Stack Offcentre AP"
+(2005,0078) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixNumberOfSpectraIntended"			Name="SP Mix Number of Spectra Intended"
+(2005,0079) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackOffcentreFH"						Name="Stack Offcentre FH"
+(2005,0079) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackOffcentreFH"						Name="Stack Offcentre FH"
+(2005,0079) VERS=""		VR="SS"   VM="1-2"	Owner="Philips MR Imaging DD 004"		Keyword="SPMixNumberOfAverages"					Name="SP Mix Number of Averages"
+(2005,007a) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackOffcentreRL"						Name="Stack Offcentre RL"
+(2005,007a) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackOffcentreRL"						Name="Stack Offcentre RL"
+(2005,007b) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackPreparationDirection"				Name="Stack Preparation Direction"
+(2005,007b) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackPreparationDirection"				Name="Stack Preparation Direction"
+(2005,007e) VERS=""		VR="FL"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackSliceDistance"					Name="Stack Slice Distance"
+(2005,007e) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackSliceDistance"					Name="Stack Slice Distance"
+(2005,0080) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SeriesPlanScan"						Name="Series PlanScan"
+(2005,0080) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SeriesPlanScan"						Name="Series PlanScan"
+(2005,0080) VERS=""		VR="SL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="NumberOfMFImageObjects"				Name="Number of MF Image Objects"
+(2005,0081) VERS=""		VR="CS"   VM="1-n"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackViewAxis"							Name="Stack View Axis"
+(2005,0081) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="StackViewAxis"							Name="Stack View Axis"
+(2005,0081) VERS=""		VR="UI"   VM="1"	Owner="Philips MR Imaging DD 003"		Keyword="DefaultImageUID"						Name="Default Image UID"
+(2005,0081) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="ScanoGramSurveyNumberOfImages"			Name="ScanoGram Survey Number of Images"
+(2005,0082) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 003"		Keyword="RunningAttributes"						Name="Running Attributes"
+(2005,0082) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="NumberOfProcedureCodes"				Name="Number of Procedure Codes"
+(2005,0083) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SeriesSlab"							Name="Series Slab"
+(2005,0083) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SeriesSlab"							Name="Series Slab"
+(2005,0083) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="Sort Attributes"						Name="Sort Attributes"
+(2005,0084) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SeriesReference"						Name="Series Reference"
+(2005,0084) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SeriesReference"						Name="Series Reference"
+(2005,0084) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="NumberOfSortAttributes"				Name="Number of Sort Attributes"
+(2005,0085) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SeriesVolume"							Name="Series Volume"
+(2005,0085) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SeriesVolume"							Name="Series Volume"
+(2005,0085) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="ImageDisplayDirection"					Name="Image Display Direction"
+(2005,0086) VERS=""		VR="SS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="NumberOfGeometry"						Name="Number of Geometry"
+(2005,0086) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfGeometry"						Name="Number of Geometry"
+(2005,0086) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="Inset Scanogram"						Name="Inset Scanogram"
+(2005,0087) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="NumberOfGeometrySlices"				Name="Number of Geometry Slices"
+(2005,0087) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="DisplayLayoutNumberOfColumns"			Name="Display Layout Number of Columns"
+(2005,0088) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomAngulationAP"						Name="Geom Angulation AP"
+(2005,0088) VERS=""		VR="SS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="DisplayLayoutNumberOfRows"				Name="Display Layout Number of Rows"
+(2005,0089) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomAngulationFH"						Name="Geom Angulation FH"
+(2005,0089) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="ViewingProtocol"						Name="Viewing Protocol"
+(2005,008A) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomAngulationRL"						Name="Geom Angulation RL"
+(2005,008B) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomFOVAP"								Name="Geom FOV AP"
+(2005,008C) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomFOVFH"								Name="Geom FOV FH"
+(2005,008D) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomFOVRL"								Name="Geom FOV RL"
+(2005,008E) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomOffCentreAP"						Name="Geom OffCentre AP"
+(2005,008F) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomOffCentreFH"						Name="Geom OffCentre FH"
+(2005,0090) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomOffCentreRL"						Name="Geom OffCentre RL"
+(2005,0090) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="StackCoilFunction"						Name="Stack Coil Function"
+(2005,0090) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="OriginalVOILUTSequence"				Name="Original VOI LUT Sequence"
+(2005,0091) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomPreparationDirect"					Name="Geom Preparation Direct"
+(2005,0091) VERS=""		VR="PN"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="PatientNameJobInParams"				Name="Patient Name Job In Params"
+(2005,0091) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 005"		Keyword="OriginalModalityLUTSequence"			Name="Original Modality LUT Sequence"
+(2005,0092) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomRadialAngle"						Name="Geom Radial Angle"
+(2005,0092) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="GeolinkID"								Name="Geolink ID"
+(2005,0093) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomRadialAxis"						Name="Geom Radial Axis"
+(2005,0093) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="StationNumber"							Name="Station Number"
+(2005,0094) VERS=""		VR="FL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomSliceDistance"						Name="Geom Slice Distance"
+(2005,0094) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 004"		Keyword="ProcessingHistory"						Name="Processing History"
+(2005,0095) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomSliceNumber"						Name="Geom Slice Number"
+(2005,0095) VERS=""		VR="UI"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="ViewProcedureString"					Name="View Procedure String"
+(2005,0096) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomType"								Name="Geom Type"
+(2005,0096) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="FlowImagesPresent"						Name="Flow Images Present"
+(2005,0097) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomViewAxis"							Name="Geom ViewA xis"
+(2005,0097) VERS=""		VR="LO"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="AnatomicRegionCodeValue"				Name="Anatomic Region Code Value"
+(2005,0098) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomColour"							Name="Geom Colour"
+(2005,0098) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="MobiviewEnabled"						Name="Mobiview Enabled"
+(2005,0099) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomApplicationType"					Name="Geom Application Type"
+(2005,0099) VERS=""		VR="UL"   VM="1"	Owner="Philips MR Imaging DD 002"		Keyword="NumberOfRequestExcerpts"				Name="Number of Request Excerpts"
+(2005,0099) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 004"		Keyword="IViewBoldEnabled"						Name="IViewBold Enabled"
+(2005,009a) VERS=""		VR="SL"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomId"								Name="Geom Id"
+(2005,009b) VERS=""		VR="SH"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomApplicationName"					Name="Geom Application Name"
+(2005,009c) VERS=""		VR="SH"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomLabelName"							Name="Geom Label Name"
+(2005,009d) VERS=""		VR="CS"   VM="1-n"	Owner="Philips MR Imaging DD 001"		Keyword="GeomLineStyle"							Name="Geom Line Style"
+(2005,009e) VERS=""		VR="SQ"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SeriesGeometry"						Name="Series Geometry"
+(2005,009e) VERS=""		VR="SQ"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SeriesGeometry"						Name="Series Geometry"
+(2005,009f) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SpectralSelectiveExcitationPulse"		Name="Spectral Selective Excitation Pulse"
+(2005,009f) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SpectralSelectiveExcitationPulse"	Name="SeriesSpectral Selective Excitation Pulse"
+(2005,00a0) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="DynamicScanBeginTime"					Name="Dynamic Scan Begin Time"
+(2005,00a0) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="DynamicScanBeginTime"					Name="Dynamic Scan Begin Time"
+(2005,00a1) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="SyncraScanType"						Name="Syncra Scan Type"
+(2005,00a1) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="SyncraScanType"						Name="Syncra Scan Type"
+(2005,00a2) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="IsCOCA"								Name="Is COCA"
+(2005,00a2) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="IsCOCA"								Name="Is COCA"
+(2005,00a3) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackCoilID"							Name="Stack Coil ID"
+(2005,00a3) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StackCoilID"							Name="Stack Coil ID"
+(2005,00a4) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackCBBCoil1"							Name="Stack CBB Coil 1"
+(2005,00a4) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StackCBBCoil1"							Name="Stack CBB Coil 1"
+(2005,00a5) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackCBBCoil2"							Name="Stack CBB Coil 2"
+(2005,00a5) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StackCBBCoil2"							Name="Stack CBB Coil 2"
+(2005,00a6) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackChannelCombi"						Name="Stack Channel Combination Bitmask"
+(2005,00a6) VERS=""		VR="IS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StackChannelCombi"						Name="Stack Channel Combination Bitmask"
+(2005,00a7) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="StackCoilConnection"					Name="Stack Coil Connection"
+(2005,00a7) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="StackCoilConnection"					Name="Stack Coil Connection"
+(2005,00a8) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="InversionTime"							Name="Inversion Time"
+(2005,00a8) VERS=""		VR="DS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="InversionTime"							Name="Inversion Time"
+(2005,00a9) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="GeometryCorrection"				Name="Geometry Correction"
+(2005,00a9) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="GeometryCorrection"				Name="Geometry Correction"
+(2005,00b0) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="DiffusionDirectionRL"					Name="Diffusion Direction RL"
+(2005,00b0) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="DiffusionDirectionRL"					Name="Diffusion Direction RL"
+(2005,00b1) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="DiffusionDirectionAP"					Name="Diffusion Direction AP"
+(2005,00b1) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="DiffusionDirectionAP"					Name="Diffusion Direction AP"
+(2005,00b2) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="DiffusionDirectionFH"					Name="Diffusion Direction FH"
+(2005,00b2) VERS=""		VR="FL"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="DiffusionDirectionFH"					Name="Diffusion Direction FH"
+(2005,00c0) VERS=""		VR="CS"   VM="1"	Owner="PHILIPS MR IMAGING DD 001"		Keyword="ScanSequence"					Name="Scan Sequence"
+(2005,00c0) VERS=""		VR="CS"   VM="1"	Owner="Philips MR Imaging DD 001"		Keyword="ScanSequence"					Name="Scan Sequence"
+(2007,0000) VERS=""	    VR="ST"   VM="1"	Owner="Philips EV Imaging DD 022"		Keyword="?"				Name="?"
+(200b,0000) VERS=""		VR="PN"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0000) VERS=""		VR="ST"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0001) VERS=""		VR="US"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0001) VERS=""		VR="CS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0002) VERS=""		VR="US"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0002) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0005) VERS=""		VR="IS"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0011) VERS=""		VR="LO"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0027) VERS=""		VR="DT"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0028) VERS=""		VR="DS"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0029) VERS=""		VR="DS"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,002a) VERS=""		VR="UL"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,002b) VERS=""		VR="DA"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,002c) VERS=""		VR="TM"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,002d) VERS=""		VR="LO"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,003b) VERS=""		VR="LO"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0040) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0041) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0042) VERS=""		VR="UI"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0043) VERS=""		VR="UI"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0047) VERS=""		VR="DA"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0048) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,004c) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,004d) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,004f) VERS=""		VR="DT"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0050) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0051) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0052) VERS=""		VR="CS"   VM="1"	Owner="Philips RAD Imaging DD 001"	Keyword="?"		Name="?"
+(200b,0052) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0053) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0054) VERS=""		VR="ST"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0060) VERS=""		VR="LT"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0063) VERS=""		VR="LT"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0065) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,006e) VERS=""		VR="US"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0072) VERS=""		VR="FD"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0073) VERS=""		VR="SS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0074) VERS=""		VR="IS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0075) VERS=""		VR="CS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0076) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0078) VERS=""		VR="IS"   VM="1-n"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0079) VERS=""		VR="IS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,007a) VERS=""		VR="IS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,007b) VERS=""		VR="US"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,007c) VERS=""		VR="US"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,007d) VERS=""		VR="IS"   VM="1-n"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,007e) VERS=""		VR="UI"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0081) VERS=""		VR="LO"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0082) VERS=""		VR="LO"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0085) VERS=""		VR="IS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0086) VERS=""		VR="CS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0088) VERS=""		VR="CS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0089) VERS=""		VR="LT"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0090) VERS=""		VR="DS"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0096) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,0099) VERS=""		VR="SH"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,009a) VERS=""		VR="FD"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,009b) VERS=""		VR="FD"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200b,00a0) VERS=""		VR="LT"   VM="1"	Owner="Philips RAD Imaging DD 097"	Keyword="?"		Name="?"
+(200d,0000) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0000) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 066"	Keyword="?"		Name="?"
+(200d,0000) VERS=""		VR="US"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 038"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 048"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 066"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0001) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 038"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 066"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="ST"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0002) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 038"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 066"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0003) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 038"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 066"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="SL"   VM="4"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0004) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 017"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="SH"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="UL"   VM="3"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0005) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="UL"   VM="3"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0006) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 021"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 065"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0007) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0008) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0009) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,000a) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,000b) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,000b) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,000b) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,000b) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,000b) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,000b) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,000c) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="PrivateNativeDataType"		Name="Private Native Data Type"
+(200d,000d) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 035"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,000d) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,000e) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,000e) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,000e) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,000e) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,000e) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,000f) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,000f) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,000f) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 037"	Keyword="?"		Name="?"
+(200d,000f) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,000f) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,000f) VERS=""		VR="DS"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0010) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="PrivateNativeTotalNumSample"		Name="Private Native Total Num Sample"
+(200d,0010) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0010) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0010) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0010) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0010) VERS=""		VR="SL"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0010) VERS=""		VR="DS"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0011) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="NativeDataSampleSize"		Name="Native Data Sample Size"
+(200d,0011) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0011) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0011) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0011) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0011) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0011) VERS=""		VR="SL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0012) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0012) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0012) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0012) VERS=""		VR="SL"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0012) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0013) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0013) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0013) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0013) VERS=""		VR="US"   VM="1-n"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0013) VERS=""		VR="FL"   VM="1-n"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0014) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0014) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0014) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0014) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0014) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 109"	Keyword="?"		Name="?"
+(200d,0014) VERS=""		VR="SS"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0015) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="?"		Name="?"
+(200d,0015) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 036"	Keyword="?"		Name="?"
+(200d,0015) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0015) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0015) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0015) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0016) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 036"	Keyword="?"		Name="?"
+(200d,0016) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0016) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0017) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0017) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 036"	Keyword="?"		Name="?"
+(200d,0017) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0017) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0017) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 046"	Keyword="?"		Name="?"
+(200d,0017) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0018) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0018) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 036"	Keyword="?"		Name="?"
+(200d,0018) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0018) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0019) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 036"	Keyword="?"		Name="?"
+(200d,0019) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0019) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 046"	Keyword="?"		Name="?"
+(200d,0019) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,001a) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,001a) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,001a) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,001b) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,001b) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,001b) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,001b) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,001c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,001c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,001c) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,001d) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,001d) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,001e) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,001e) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,001e) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,001f) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,001f) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,001f) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0020) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0020) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 036"	Keyword="?"		Name="?"
+(200d,0020) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 040"	Keyword="?"		Name="?"
+(200d,0020) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0020) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0021) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 033"	Keyword="PrivateNativeDataInstanceNum"		Name="Private Native Data Instance Num"
+(200d,0021) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0021) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0021) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0022) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0022) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0023) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0023) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0023) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0024) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0024) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0024) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0024) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0025) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0025) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0025) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0025) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0026) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0026) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0026) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0026) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0027) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0027) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0027) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0027) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0028) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 034"	Keyword="?"		Name="?"
+(200d,0028) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0028) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0028) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0029) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0029) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,002a) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,002b) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,002c) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,002d) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,002e) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,002f) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0030) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 041"	Keyword="?"		Name="?"
+(200d,0030) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0030) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0031) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0031) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0031) VERS=""		VR="UL"   VM="1"	Owner="Philips US Imaging DD 113"	Keyword="?"		Name="?"
+(200d,0032) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0033) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0034) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0035) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0036) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0037) VERS=""		VR="DA"   VM="1"	Owner="Philips US Imaging DD 023"	Keyword="?"		Name="?"
+(200d,0037) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0038) VERS=""		VR="TM"   VM="1"	Owner="Philips US Imaging DD 023"	Keyword="?"		Name="?"
+(200d,0038) VERS=""		VR="FD"   VM="1-n"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0039) VERS=""		VR="FD"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0040) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0040) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0041) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0042) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 043"	Keyword="?"		Name="?"
+(200d,0045) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 023"	Keyword="?"		Name="?"
+(200d,0050) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0050) VERS=""		VR="LO"   VM="1-n"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0051) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0051) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0052) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0052) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0053) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0053) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0054) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0054) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0055) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0055) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0056) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0056) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0057) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0057) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0058) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0058) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0059) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0059) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,005a) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,005b) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,005c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,005d) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,005e) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,005f) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0060) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0060) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0061) VERS=""		VR="IS"   VM="1"	Owner="Philips US Imaging DD 039"	Keyword="?"		Name="?"
+(200d,0070) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0071) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0072) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0073) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0074) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0075) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0076) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0077) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,0078) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,008c) VERS=""		VR="LO"   VM="1"	Owner="Philips US Imaging DD 042"	Keyword="?"		Name="?"
+(200d,00f1) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00f3) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00f4) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00f5) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00f6) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00f8) VERS=""		VR="SQ"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00fa) VERS=""		VR="CS"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(200d,00fb) VERS=""		VR="OB"   VM="1"	Owner="Philips US Imaging DD 045"	Keyword="?"		Name="?"
+(4001,0000) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 067"	Keyword="?"		Name="?" 
+(4001,0001) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 067"	Keyword="?"		Name="?"
+(4001,0008) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 067"	Keyword="?"		Name="?"
+(4001,0009) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 067"	Keyword="?"		Name="?"
+(4001,0010) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,0011) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,0012) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,0013) VERS=""		VR="ST"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,0016) VERS=""		VR="ST"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,0017) VERS=""		VR="ST"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,0018) VERS=""		VR="ST"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4001,001c) VERS=""		VR="SQ"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?" 
+(4001,001d) VERS=""		VR="LT"   VM="1"	Owner="Philips Imaging DD 070"	Keyword="?"		Name="?"
+(4007,0000) VERS=""		VR="CS"   VM="1"	Owner="Philips Imaging DD 065"	Keyword="?"		Name="?"
+(4007,0048) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 073"	Keyword="?"		Name="?"
+(4007,004b) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 073"	Keyword="?"		Name="?"
+(4007,004c) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 073"	Keyword="?"		Name="?"
+(4007,004d) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 073"	Keyword="?"		Name="?"
+(4007,004e) VERS=""		VR="FL"   VM="1"	Owner="Philips Imaging DD 073"	Keyword="?"		Name="?"
+(4007,004f) VERS=""		VR="LO"   VM="1"	Owner="Philips Imaging DD 073"	Keyword="?"		Name="?"
+(6001,0000) VERS=""		VR="LT"   VM="1"	Owner="PHILIPS MR/LAST"		Keyword="?"				Name="?"
+(7043,0000) VERS=""		VR="SH"   VM="1"	Owner="Philips NM Private Group"		Keyword="?"										Name="?"
+(7051,0000) VERS=""		VR="US"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="CurrentSegment"				Name="Current Segment"
+(7051,0001) VERS=""		VR="US"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="NumberOfSegments"				Name="Number of Segments"
+(7051,0001) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS XCT -Private"			Keyword="AttenuationThreshold"			Name="Attenuation Threshold"
+(7051,0002) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="SegmentStartPosition"			Name="Segment Start Position"
+(7051,0002) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS XCT -Private"			Keyword="DLPEstimate"					Name="DLPEstimate"
+(7051,0003) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="SegmentStopPosition"			Name="Segment Stop Position"
+(7051,0004) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="RelativeCOROffsetXDirection"	Name="Relative COR offset - X direction"
+(7051,0005) VERS=""		VR="FL"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="RelativeCOROffsetZDirection"	Name="Relative COR offset - Z direction"
+(7051,0006) VERS=""		VR="US"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="CurrentRotationNumber"			Name="Current Rotation Number"
+(7051,0007) VERS=""		VR="US"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="NumberOfRotations"				Name="Number of Rotations"
+(7051,0010) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS NM -Private"				Keyword="AlignmentTranslations"			Name="Alignment Translations"
+(7051,0011) VERS=""		VR="DS"   VM="1-n"	Owner="PHILIPS NM -Private"				Keyword="AlignmentRotations"			Name="Alignment Rotations"
+(7051,0012) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="AlignmentTimestamp"			Name="Alignment Timestamp"
+(7051,0015) VERS=""		VR="UI"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="RelatedXraySeriesInstanceUID"	Name="Related Xray Series Instance UID"
+(7051,0025) VERS=""		VR="LO"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="?"								Name="?"
+(7051,0026) VERS=""		VR="DS"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="?"								Name="?"
+(7051,0027) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="?"								Name="?"
+(7051,0028) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="?"								Name="?"
+(7051,0029) VERS=""		VR="IS"   VM="1"	Owner="PHILIPS NM -Private"				Keyword="?"								Name="?"
+(7053,0000) VERS=""		VR="DS"   VM="1"	Owner="Philips PET Private Group"	Keyword="SUVFactor"		Name="SUV Factor"
+(7053,0001) VERS=""		VR="OB"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(7053,0002) VERS=""		VR="OB"   VM="1"	Owner="Philips PET Private Group"	Keyword="PrivateData"		Name="Private Data"
+(7053,0003) VERS=""		VR="ST"   VM="1"	Owner="Philips PET Private Group"	Keyword="OriginalFileName"	Name="Original File Name"
+(7053,0004) VERS=""		VR="OB"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0005) VERS=""		VR="LO"   VM="1"	Owner="Philips PET Private Group"	Keyword="WorklistInfoFileName"		Name="Worklist Info File Name"
+(7053,0006) VERS=""		VR="OB"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0007) VERS=""		VR="SQ"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0008) VERS=""		VR="SQ"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0009) VERS=""		VR="DS"   VM="1"	Owner="Philips PET Private Group"	Keyword="ActivityConcentrationScaleFactor"		Name="Activity Concentration Scale Factor"
+(7053,000f) VERS=""		VR="UL"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0010) VERS=""		VR="US"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0011) VERS=""		VR="US"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0012) VERS=""		VR="SQ"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0013) VERS=""		VR="SS"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0014) VERS=""		VR="SS"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0015) VERS=""		VR="SS"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0016) VERS=""		VR="SS"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0017) VERS=""		VR="SS"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,0018) VERS=""		VR="SS"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7053,00c2) VERS=""		VR="UI"   VM="1"	Owner="Philips PET Private Group"	Keyword="?"		Name="?"
+(7FE1,0010) VERS=""		VR="OW/OB"   VM="1"	Owner="SPI-P Release 1"		Keyword="PixelData"			Name="Pixel Data"
diff --git a/libsrc/standard/elmdict/picker.tpl b/libsrc/standard/elmdict/picker.tpl
new file mode 100755
index 0000000..9eb3f8e
--- /dev/null
+++ b/libsrc/standard/elmdict/picker.tpl
@@ -0,0 +1,24 @@
+(7001,0001) VERS="PCK"	VR="UI"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0002) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0003) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0004) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0005) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0006) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0007) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0008) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0009) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0010) VERS="PCK"	VR="SQ"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0011) VERS="PCK"	VR="LO"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0012) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0013) VERS="PCK"	VR="US"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0014) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0016) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7001,0017) VERS="PCK"	VR="LO"   VM="1"	Owner="Picker NM Private Group"	Keyword="?"		Name="?"
+(7101,0000) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0001) VERS="PCK"	VR="SL"   VM="1"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0002) VERS="PCK"	VR="OB"   VM="1"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0003) VERS="PCK"	VR="SL"   VM="1"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0004) VERS="PCK"	VR="SH"   VM="1"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0005) VERS="PCK"	VR="SH"   VM="2"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0006) VERS="PCK"	VR="SH"   VM="4"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
+(7101,0010) VERS="PCK"	VR="DS"   VM="1"	Owner="Picker MR Private Group"	Keyword="?"		Name="?"
diff --git a/libsrc/standard/elmdict/siemens.tpl b/libsrc/standard/elmdict/siemens.tpl
new file mode 100755
index 0000000..fdf43f3
--- /dev/null
+++ b/libsrc/standard/elmdict/siemens.tpl
@@ -0,0 +1,3374 @@
+(0003,0008) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS ISI"		Keyword="ISICommandField"			Name="ISI Command Field"
+(0003,0011) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS ISI"		Keyword="AttachIDApplicationCode"		Name="Attach ID Application Code"
+(0003,0012) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS ISI"		Keyword="AttachIDMessageCount"			Name="Attach ID Message Count"
+(0003,0013) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS ISI"		Keyword="AttachIDDate"				Name="Attach ID Date"
+(0003,0014) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="AttachIDTime"				Name="Attach ID Time"
+(0003,0020) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS ISI"		Keyword="MessageType"				Name="Message Type"
+(0003,0030) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS ISI"		Keyword="MaxWaitingDate"			Name="Max Waiting Date"
+(0003,0031) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="MaxWaitingTime"			Name="Max Waiting Time"
+
+(0009,0000) VERS="SSPI"	VR="SQ"   VM="1"	Owner="SIEMENS SYNGO INSTANCE MANIFEST"	Keyword="TemporaryOriginalHeaderSequence"	Name="Temporary Original Header Sequence"
+(0009,0000) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="NumberOfMeasurements"			Name="Number of Measurements"
+(0009,0001) VERS="SSPI"	VR="UN"   VM="1"	Owner="FFP DATA"		Keyword="CRHeaderInformation"			Name="CR Header Information"
+(0009,0001) VERS="SSPI"	VR="UN"   VM="1"	Owner="ISI"			Keyword="SIENETGeneralPurposeIMGEF"		Name="SIENET General Purpose IMGEF"
+(0009,0001) VERS="SSPI"	VR="UN"   VM="1"	Owner="SIEMENS ISI"		Keyword="RISPatientInfoIMGEF"			Name="RIS Patient Info IMGEF"
+(0009,0001) VERS="SSPI"	VR="US"   VM="1"	Owner="SIENET"			Keyword="SIENETCommandField"			Name="SIENET Command Field"
+(0009,0010) VERS="SSPI" VR="AE"   VM="1"	Owner="SIEMENS SYNGO INSTANCE MANIFEST"	Keyword="syngoIndexSourceAETitle"	Name="syngo Index Source AE Title"
+(0009,0010) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="StorageMode"				Name="Storage Mode"
+(0009,0010) VERS="SSPI"	VR="UN"   VM="1"	Owner="SIEMENS DICOM"		Keyword="?"					Name="?"
+(0009,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="GeneratorIdentificationLabel"		Name="Generator Identification Label"
+(0009,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="RecognitionCode"			Name="Recognition Code"
+(0009,0011) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="GantryIdentificationLabel"		Name="Gantry Identification Label"
+(0009,0012) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="EvaluationMaskImage"			Name="Evaluation Mask - Image"
+(0009,0012) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="XRayTubeIdentificationLabel"		Name="X-Ray Tube Identification Label"
+(0009,0012) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DICOM"		Keyword="?"					Name="?"
+(0009,0013) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="DetectorIdentificationLabel"		Name="Detector Identification Label"
+(0009,0014) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIENET"			Keyword="ReceiverPLA"				Name="Receiver PLA"
+(0009,0014) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="DASIdentificationLabel"		Name="DAS Identification Label"
+(0009,0015) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="SMIIdentificationLabel"		Name="SMI Identification Label"
+(0009,0016) VERS="SSPI"	VR="US"   VM="1"	Owner="SIENET"			Keyword="TransferPriority"			Name="Transfer Priority"
+(0009,0016) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="CPUIdentificationLabel"		Name="CPU Identification Label"
+(0009,0020) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS CM VA0  LAB"	Keyword="HeaderVersion"				Name="Header Version"
+(0009,0020) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  ORI"	Keyword="?"					Name="?"
+(0009,0026) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="LastMoveDate"				Name="Last Move Date"
+(0009,0027) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="LastMoveTime"				Name="Last Move Time"
+(0009,0029) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIENET"			Keyword="ActualUser"				Name="Actual User"
+(0009,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED"		Keyword="ByteOffsetOfOriginalHeader"		Name="Byte Offset of Original Header"
+(0009,0030) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  ORI"	Keyword="?"					Name="?"
+(0009,0031) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MED"		Keyword="LengthOfOriginalHeader"		Name="Length of Original Header"
+(0009,0031) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0032) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0034) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0040) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED"		Keyword="ByteOffsetOfPixelmatrix"		Name="Byte Offset of Pixelmatrix"
+(0009,0040) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0041) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MED"		Keyword="LengthOfPixelmatrixInBytes"		Name="Length of Pixelmatrix In Bytes"
+(0009,0042) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0050) VERS="SSPI" VR="DA"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="?"					Name="?"
+(0009,0051) VERS="SSPI" VR="TM"   VM="1"	Owner="SIEMENS CT VA0  IDE"	Keyword="?"					Name="?"
+(0009,0051) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="?"					Name="?"
+(0009,0070) VERS="SSPI" VR="DS"   VM="1"	Owner="SIENET"			Keyword="?"					Name="?"
+(0009,0071) VERS="SSPI" VR="DS"   VM="1"	Owner="SIENET"			Keyword="?"					Name="?"
+(0009,0072) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"					Name="?"
+(0009,0073) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"					Name="?"
+(0009,0074) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"					Name="?"
+(0009,0075) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"					Name="?"
+(0009,0080) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0009,00f5) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="PDMEFIDPlaceholder"			Name="PDM EFID Placeholder"
+(0009,00f6) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="PDMDataObjectTypeExtension"		Name="PDM Data Object Type Extension"
+
+(0009,0020) VERS="SSPI" VR="DA"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="ObjectInsertionDate"			Name="Object Insertion Date"
+(0009,00A0) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="SenderSystemDeviceName"		Name="Sender System Device Name"
+(0009,0040) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="LastAccessTime"				Name="Last Access Time"
+(0009,0041) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="DeleteProtectedStatus"			Name="Delete Protected Status"
+(0009,0042) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="ReceivedfromArchiveStatus"		Name="Received from Archive Status"
+(0009,0043) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="ArchiveStatus"					Name="Archive Status"
+(0009,0044) VERS="SSPI" VR="AE"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="Location"						Name="Location"
+(0009,0045) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="LogicalDeletedStatus"			Name="Logical Deleted Status"
+(0009,0046) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="InsertTime"					Name="Insert Time"
+(0009,0047) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="VisibleInstancesonSeriesLevel"	Name="Visible Instances on Series Level"
+(0009,0048) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="UnarchivedInstances"			Name="Unarchived Instances"
+(0009,0049) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="VisibleInstancesonStudyLevel"	Name="Visible Instances on Study Level"
+(0009,0031) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="SeriesObjectStates"			Name="Series Object States"
+(0009,0030) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="InstanceObjectStates"			Name="Instance Object States"
+(0009,0050) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO INDEX SERVICE"	Keyword="HiddenInstance"				Name="Hidden Instance"
+
+(0009,0050) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS AX INSPACE_EP"				Keyword="?"				Name="?"
+(0009,0051) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS AX INSPACE_EP"				Keyword="?"				Name="?"
+
+(0011,0020) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0011,0025) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0011,0026) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0011,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0011,0035) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0011,0040) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+
+(0011,0028) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"				Keyword="?"				Name="?"
+(0011,0029) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"				Keyword="?"				Name="?"
+(0011,002a) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"				Keyword="?"				Name="?"
+(0011,002b) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"				Keyword="?"				Name="?"
+(0011,002c) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"				Keyword="?"				Name="?"
+
+(0011,0028) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"				Keyword="?"				Name="?"
+(0011,0029) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"				Keyword="?"				Name="?"
+(0011,002a) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"				Keyword="?"				Name="?"
+(0011,002b) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"				Keyword="?"				Name="?"
+(0011,002c) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"				Keyword="?"				Name="?"
+
+(0011,0003) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientUID"				Name="Patient UID"
+(0011,0004) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientID"				Name="Patient ID"
+(0011,000a) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0011,000a) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="CaseID"				Name="Case ID"
+(0011,0010) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="RegistrationDate"			Name="Registration Date"
+(0011,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientUID"				Name="Patient UID"
+(0011,0010) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0011,0011) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="RegistrationTime"			Name="Registration Time"
+(0011,0011) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientID"				Name="Patient ID"
+(0011,0020) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientRegistrationDate"		Name="Patient Registration Date"
+(0011,0021) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientRegistrationTime"		Name="Patient Registration Time"
+(0011,0022) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0011,0022) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="RequestID"				Name="Request ID"
+(0011,0023) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="UsedPatientWeight"			Name="Used Patient Weight"
+(0011,0023) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ExaminationUID"			Name="Examination UID"
+(0011,0030) VERS="SSPI" VR="PN"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientnameRIS"			Name="Patientname RIS"
+(0011,0031) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientprenameRIS"			Name="Patientprename RIS"
+(0011,0040) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="OrganCode"				Name="Organ Code"
+(0011,0040) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientHospitalStatus"			Name="Patient Hospital Status"
+(0011,0041) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="MedicalAlerts"				Name="Medical Alerts"
+(0011,0042) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="ContrastAllergies"			Name="Contrast Allergies"
+(0011,00a1) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientRegistrationDate"		Name="Patient Registration Date"
+(0011,00a2) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientRegistrationTime"		Name="Patient Registration Time"
+(0011,00b0) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientLastName"			Name="Patient Last Name"
+(0011,00b2) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientFirstName"			Name="Patient First Name"
+(0011,00b4) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientHospitalStatus"			Name="Patient Hospital Status"
+(0011,00bc) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="CurrentLocationTime"			Name="Current Location Time"
+(0011,00c0) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientInsuranceStatus"		Name="Patient Insurance Status"
+(0011,00d0) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientBillingType"			Name="Patient Billing Type"
+(0011,00d2) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="PatientBillingAddress"			Name="Patient Billing Address"
+
+(0011,0001) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="ReprocessingInfo"		Name="Reprocessing Info"
+(0011,0002) VERS="SSPI" VR="CS"   VM="1-n"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="DataRoleType"			Name="Data Role Type"
+(0011,0003) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="DataRoleName"			Name="Data Role Name"
+(0011,0004) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="RescanName"			Name="Rescan Name"
+(0011,0005) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="?"						Name="?"
+(0011,0006) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="CardiacTypeName"		Name="Cardiac Type Name"
+(0011,0007) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="CardiacTypeNameL2"		Name="Cardiac Type Name L2"
+(0011,0008) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="MiscIndicator"			Name="Misc Indicator"
+(0011,0009) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="?"						Name="?"
+(0011,000A) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="?"						Name="?"
+(0011,000B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="?"						Name="?"
+(0011,000C) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="SplitBaggingName"		Name="Split Bagging Name"
+(0011,000D) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="SplitSubBaggingName"	Name="Split Sub Bagging Name"
+(0011,000E) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="StageSubBaggingName"	Name="Stage Sub Bagging Name"
+(0011,000F) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR DATAMAPPING ATTRIBUTES"	Keyword="IsInternalDataRole"	Name="Is Internal Data Role"
+
+(0013,0000) VERS="SSPI" VR="PN"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ModifyingPhysician"			Name="Modifying Physician"
+(0013,0010) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ModificationDate"			Name="Modification Date"
+(0013,0012) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ModificationTime"			Name="Modification Time"
+(0013,0020) VERS="SSPI" VR="PN"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientName"				Name="Patient Name"
+(0013,0022) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientId"				Name="Patient Id"
+(0013,0030) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientBirthdate"			Name="Patient Birthdate"
+(0013,0031) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientWeight"				Name="Patient Weight"
+(0013,0032) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientsMaidenName"			Name="Patients Maiden Name"
+(0013,0033) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ReferringPhysician"			Name="Referring Physician"
+(0013,0034) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="AdmittingDiagnosis"			Name="Admitting Diagnosis"
+(0013,0035) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientSex"				Name="Patient Sex"
+(0013,0040) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ProcedureDescription"			Name="Procedure Description"
+(0013,0042) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientRestDirection"			Name="Patient Rest Direction"
+(0013,0044) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientPosition"			Name="Patient Position"
+(0013,0046) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ViewDirection"				Name="View Direction"
+(0013,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0013,0051) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0013,0052) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0013,0053) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0013,0054) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0013,0055) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0013,0056) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+
+(0015,0000) VERS="SSPI" VR="OB"   VM="1"	Owner="ESOFT_DICOM_ECAT_OWNERCODE"	Keyword="?"					Name="?"
+
+(0017,0000) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0017,0000) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Version"	Keyword="?"			Name="?"
+(0017,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Version"	Keyword="?"			Name="?"
+(0017,0020) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0017,0070) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0017,0080) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+
+(0017,000a) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,000b) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,000c) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,000d) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,000e) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,000f) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0010) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0011) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0014) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0016) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0017) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0018) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0019) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,001a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,001b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,001c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,001e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,001f) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0020) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0021) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0022) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0023) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0024) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0025) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0026) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0028) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0029) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0048) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0049) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,004d) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,004e) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,004f) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0050) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0051) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0052) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0053) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0054) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0055) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,005c) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0064) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0066) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0067) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0068) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0085) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0086) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0087) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0088) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,0089) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,008a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,008b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,008c) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,008d) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,008e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,008f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a2) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a3) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a4) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a5) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00a6) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00aa) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00b0) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+(0017,00c0) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS_FLCOMPACT_VA01A_PROC"		Keyword="?"					Name="?"
+
+(0017,0011) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0012) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0014) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0015) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0016) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0018) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0021) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0022) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0023) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0024) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0025) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0026) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0027) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,002a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0030) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0031) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0032) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0033) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0037) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0038) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0041) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0043) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0044) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0045) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0046) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0047) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0048) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0049) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,004a) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0051) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0052) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0061) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0062) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0071) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0072) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0073) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0074) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0079) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,007a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,007b) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,00a0) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,00c1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,00c2) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DFR.01 ORIGINAL"		Keyword="?"		Name="?"
+(0017,0011) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0012) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0014) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0015) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0025) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0027) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0029) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="EdgeEnhancement"		Name="Edge Enhancement %" 
+(0017,0030) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="Harmonization"		Name="Harmonization %"
+(0017,0031) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0032) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0033) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0035) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0037) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0038) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0071) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="Landmark"		Name="Landmark"
+(0017,0072) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0073) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0074) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0077) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="PixelShiftHorizontal"		Name="Pixel Shift horizontal" 
+(0017,0078) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="PixelShiftVertical"		Name="Pixel Shift vertical"
+(0017,0079) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,007a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0080) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,0083) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="LeftMarker"		Name="Left Marker"
+(0017,0084) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="RightMarker"		Name="Right Marker"
+(0017,00a1) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="?"		Name="?"
+(0017,00a2) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="ImageNameExtension1"		Name="Image Name Extension 1"
+(0017,00a3) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS DFR.01 MANIPULATED"		Keyword="ImageNameExtension2"		Name="Image Name Extension 2"
+(0019,0001) VERS="SSPI" VR="UL"   VM="1-n"	Owner="SIEMENS MED SP DXMG WH AWS 1"		Keyword="AECCoordinates"					Name="AEC Coordinates"
+(0019,0002) VERS="SSPI" VR="US"   VM="2"	Owner="SIEMENS MED SP DXMG WH AWS 1"		Keyword="AECCoordinatesSize"					Name="AEC Coordinates Size"
+(0019,0010) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"		Keyword="DerivationDescription"					Name="Derivation Description"
+
+(0019,0008) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"													Name="?"
+(0019,000F) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="SiemensICONDataType"								Name="Siemens ICON Data Type"
+(0019,0016) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"													Name="?"
+(0019,00A5) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="NumberOfRepeatsPerPhase"							Name="Number of Repeats per Phase"
+(0019,00A6) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="CyclesPerRepeat"									Name="Cycles per Repeat"
+(0019,00A7) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="RepeatStartTime"									Name="Repeat Start Time"
+(0019,00A8) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="RepeatStopTime"									Name="Repeat Stop Time"
+(0019,00A9) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="EffectiveRepeatTime"								Name="Effective Repeat Time"
+(0019,00AA) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="AcquiredCyclesPerRepeat"							Name="Acquired Cycles per Repeat"
+
+(0019,0015) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0015) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0018) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0018) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0019) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0019) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,001a) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,001a) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,001b) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,001b) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,001c) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,001c) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,001d) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,001d) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,001e) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,001e) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,001f) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,001f) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0020) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0020) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0022) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0022) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0024) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0024) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0026) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0026) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0028) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0028) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,002a) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,002a) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,002c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,002c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,002e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,002e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0032) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0032) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0034) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0034) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0036) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0036) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0038) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0038) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,003a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,003a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,003c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,003c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,003e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,003e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0040) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0040) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0042) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0042) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0044) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0044) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0046) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0046) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0048) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0048) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,004a) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,004a) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,004c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,004c) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,004e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,004e) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0050) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0050) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0052) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0052) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0054) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0054) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0056) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0056) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0058) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0058) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,005a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,005a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,005c) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,005c) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,005e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,005e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0060) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0060) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0062) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0062) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0064) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0064) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0066) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0066) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0068) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0068) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,006a) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,006a) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,006c) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,006c) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,006e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,006e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0070) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0070) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0072) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0072) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0074) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0074) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0076) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0076) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0078) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0078) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,007a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,007a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,007c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,007c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,007e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,007e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0080) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0080) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0082) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0082) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0084) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0084) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0086) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0086) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0088) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0088) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,008a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,008a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,008c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,008c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,008e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,008e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0090) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0090) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0092) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0092) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0094) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0094) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0096) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0096) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,0098) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,0098) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,009a) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,009a) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,009c) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,009c) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,009e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,009e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00a0) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00a0) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00a2) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00a2) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00a4) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00a4) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00a6) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00a6) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00a8) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00a8) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00aa) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00aa) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00ac) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00ac) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00ae) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00ae) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b3) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b3) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b4) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b4) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b5) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b5) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b6) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b6) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b7) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b7) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b8) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b8) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00b9) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00b9) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00bb) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00bb) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00bc) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00bc) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00bd) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00bd) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00be) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00be) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00bf) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00bf) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c0) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c0) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c1) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c1) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c2) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c2) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c3) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c3) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c4) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c4) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c5) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c5) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c6) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c6) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c7) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c7) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c8) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c8) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00c9) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00c9) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00ca) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00ca) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00cb) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00cb) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00cc) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00cc) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00cd) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00cd) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00ce) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00ce) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00cf) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00cf) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d2) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d2) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d3) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d3) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d4) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d4) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d5) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d5) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d6) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d6) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d7) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d7) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d8) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d8) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00d9) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00d9) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00da) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00da) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00db) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00db) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00dc) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00dc) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00dd) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00dd) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00de) VERS="SSPI" VR="UL"   VM="1-n"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00de) VERS="SSPI" VR="UL"   VM="1-n"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00df) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00df) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+(0019,00e0) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE A"	Keyword="?"					Name="?"
+(0019,00e0) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA PLANE B"	Keyword="?"					Name="?"
+
+(0019,0015) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,001f) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0020) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0022) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0024) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0026) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0028) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,002c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,002a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,002e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0034) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0036) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0038) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,003a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,003c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,003e) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0032) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0040) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0042) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0044) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0046) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0048) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,004a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,004c) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0050) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0052) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0054) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0056) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0058) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,005a) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,005c) VERS="SSPI"	VR="UN"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,005e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0060) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0062) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0064) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0066) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0068) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,006a) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0070) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0072) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0074) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0076) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0078) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,007a) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,007c) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,007e) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0080) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0082) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0084) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0086) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0088) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,008a) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,008c) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,008e) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0092) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0096) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0098) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,009a) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,009c) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,009e) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,0094) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a2) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a4) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a5) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a6) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a7) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a8) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00a9) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00aa) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00ab) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00ac) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00ad) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0019,00ff) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+
+(0019,0010) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="NetFrequency"				Name="Net Frequency"
+(0019,0010) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="DistanceSourceToSourceSideCollimator"	Name="Distance Source To Source Side Collimator"
+(0019,0010) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="SourceSideCollimatorAperture"		Name="Source Side Collimator Aperture"
+(0019,0010) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="TotalMeasurementTimeNominal"		Name="Total Measurement Time Nominal"
+(0019,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  ACQU"	Keyword="ParameterFileName"			Name="Parameter File Name"
+(0019,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="MeasurementMode"			Name="Measurement Mode"
+(0019,0011) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="DistanceSourceToDetectorSideCollimator"	Name="Distance Source To Detector Side Collimator"
+(0019,0011) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="DetectorSideCollimatorAperture"	Name="Detector Side Collimator Aperture"
+(0019,0011) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="TotalMeasurementTimeCurrent"		Name="Total Measurement Time Current"
+(0019,0011) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  ACQU"	Keyword="SequenceFileName"			Name="Sequence File Name"
+(0019,0011) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="ImageType"				Name="Image Type"
+(0019,0012) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="MagneticFieldStrength"			Name="Magnetic Field Strength"
+(0019,0012) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="StartDelayTime"			Name="Start Delay Time"
+(0019,0012) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  ACQU"	Keyword="SequenceFileOwner"			Name="Sequence File Owner"
+(0019,0013) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="DwellTime"				Name="Dwell Time"
+(0019,0013) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  ACQU"	Keyword="SequenceDescription"			Name="Sequence Description"
+(0019,0014) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ADCVoltage"				Name="ADC Voltage"
+(0019,0014) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfPhases"			Name="Number of Phases"
+(0019,0014) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  ACQU"	Keyword="EPIFileName"				Name="EPI File Name"
+(0019,0015) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="SoftwareVersion"			Name="Software Version"
+(0019,0016) VERS="SSPI"	VR="DS"   VM="2"	Owner="SIEMENS MR VA0  COAD"	Keyword="ADCOffset"				Name="ADC Offset"
+(0019,0016) VERS="SSPI"	VR="UL"   VM="2"	Owner="SIEMENS MR VA0  GEN"	Keyword="SequenceControlMask"			Name="Sequence Control Mask"
+(0019,0018) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MeasurementStatusMask"			Name="Measurement Status Mask"
+(0019,0020) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="ExposureTime"				Name="Exposure Time"
+(0019,0020) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="TransmitterAmplitude"			Name="Transmitter Amplitude"
+(0019,0020) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="NumberOfPossibleChannels"		Name="Number of Possible Channels"
+(0019,0020) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfFourierLinesNominal"		Name="Number of Fourier Lines Nominal"
+(0019,0020) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="MeasurementMode"			Name="Measurement Mode"
+(0019,0020) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="MPMCode"				Name="MPM Code"
+(0019,0021) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="ExposureCurrent"			Name="Exposure Current"
+(0019,0021) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="MeanChannelNumber"			Name="Mean Channel Number"
+(0019,0021) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="NumberOfTransmitterAmplitudes"		Name="Number of Transmitter Amplitudes"
+(0019,0021) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfFourierLinesCurrent"		Name="Number of Fourier Lines Current"
+(0019,0021) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="Latitude"				Name="Latitude"
+(0019,0022) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="DetectorSpacing"			Name="Detector Spacing"
+(0019,0022) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="TransmitterAttenuator"			Name="Transmitter Attenuator"
+(0019,0022) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="Sensitivity"				Name="Sensitivity"
+(0019,0023) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="DetectorCenter"			Name="Detector Center"
+(0019,0023) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="EDR"					Name="EDR"
+(0019,0024) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="ReadingIntegrationTime"		Name="Reading Integration Time"
+(0019,0024) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="TransmitterCalibration"		Name="Transmitter Calibration"
+(0019,0024) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="LFix"					Name="L Fix"
+(0019,0025) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="KVPGeneratorPowerCurrent"		Name="KVP Generator Power Current"
+(0019,0025) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="SFix"					Name="S Fix"
+(0019,0026) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="GeneratorVoltage"			Name="Generator Voltage"
+(0019,0026) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="TransmitterReference"			Name="Transmitter Reference"
+(0019,0026) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfFourierLinesAfterZero"		Name="Number of Fourier Lines after Zero"
+(0019,0026) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="PresetMode"				Name="Preset Mode"
+(0019,0027) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="Region"				Name="Region"
+(0019,0028) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="FirstMeasuredFourierLine"		Name="First Measured Fourier Line"
+(0019,0028) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="Subregion"				Name="Subregion"
+(0019,0030) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="AcquisitionColumns"			Name="Acquisition Columns"
+(0019,0030) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="CalculationMode"			Name="Calculation Mode"
+(0019,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="Orientation"				Name="Orientation"
+(0019,0031) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ReconstructionColumns"			Name="Reconstruction Columns"
+(0019,0031) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="MarkOnFilm"				Name="Mark On Film"
+(0019,0032) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="RotationOnDRC"				Name="Rotation On DRC"
+(0019,0040) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilElementNumber"		Name="Array Coil Element Number"
+(0019,0040) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="MasterControlMask"			Name="Master Control Mask"
+(0019,0040) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="ReaderType"				Name="Reader Type"
+(0019,0041) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilElementSelectMask"		Name="Array Coil Element Select Mask"
+(0019,0041) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="SubModality"				Name="Sub Modality"
+(0019,0042) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilElementDataMask"		Name="Array Coil Element Data Mask"
+(0019,0042) VERS="SSPI"	VR="US"   VM="5"	Owner="SIEMENS CT VA0  GEN"	Keyword="ProcessingMask"			Name="Processing Mask"
+(0019,0042) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="ReaderSerialNumber"			Name="Reader Serial Number"
+(0019,0043) VERS="SSPI"	VR="IS"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilElementToADCConnect"		Name="Array Coil Element To ADC Connect"
+(0019,0044) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilElementNoiseLevel"		Name="Array Coil Element Noise Level"
+(0019,0044) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0019,0045) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilADCPairNumber"		Name="Array Coil ADC Pair Number"
+(0019,0045) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0019,0046) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ArrayCoilCombinationMask"		Name="Array Coil Combination Mask"
+(0019,0050) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="DetectorAlignment"			Name="Detector Alignment"
+(0019,0050) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReceiverTotalGain"			Name="Receiver Total Gain"
+(0019,0050) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="NoiseLevel"				Name="Noise Level"
+(0019,0050) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfAveragesCurrent"		Name="Number of Averages Current"
+(0019,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="CassetteScale"				Name="Cassette Scale"
+(0019,0051) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReceiverAmplifierGain"			Name="Receiver Amplifier Gain"
+(0019,0051) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="CassetteMatrix"			Name="Cassette Matrix"
+(0019,0052) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="? "
+(0019,0052) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReceiverPreamplifierGain"		Name="Receiver Preamplifier Gain"
+(0019,0052) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="CassetteSubmatrix"			Name="Cassette Submatrix"
+(0019,0053) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="Barcode"				Name="Barcode"
+(0019,0054) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="? "
+(0019,0054) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReceiverCableAttenuation"		Name="Receiver Cable Attenuation"
+(0019,0055) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReceiverReferenceGain"			Name="Receiver Reference Gain"
+(0019,0056) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReceiverFilterFrequency"		Name="Receiver Filter Frequency"
+(0019,0060) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="FocusAlignment"			Name="Focus Alignment"
+(0019,0060) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReconstructionScaleFactor"		Name="Reconstruction Scale Factor"
+(0019,0060) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="FlipAngle"				Name="Flip Angle"
+(0019,0060) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="NumberOfDataBytes"			Name="Number of Data Bytes"
+(0019,0060) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="ContrastType"				Name="GT - Contrast Type"
+(0019,0061) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="RotationAmount"			Name="GA - Rotation Amount"
+(0019,0062) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReferenceScaleFactor"			Name="Reference Scale Factor"
+(0019,0062) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="NumberOfVirtuellChannels"		Name="Number of Virtuell Channels"
+(0019,0062) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="RotationCenter"			Name="GC - Rotation Center"
+(0019,0063) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="DensityShift"				Name="GS - Density Shift"
+(0019,0064) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="FrequencyRank"				Name="RN - Frequency Rank"
+(0019,0065) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="FocalSpotDeflectionAmplitude"		Name="Focal Spot Deflection Amplitude"
+(0019,0065) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="FrequencyEnhancement"			Name="RE - Frequency Enhancement"
+(0019,0066) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="FocalSpotDeflectionPhase"		Name="Focal Spot Deflection Phase"
+(0019,0066) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="FrequencyType"				Name="RT - Frequency Type"
+(0019,0067) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="FocalSpotDeflectionOffset"		Name="Focal Spot Deflection Offset"
+(0019,0067) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="KernelLength"				Name="Kernel Length"
+(0019,0068) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="KernelMode"				Name="Kernel Mode"
+(0019,0069) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="ConvolutionMode"			Name="Convolution Mode"
+(0019,0070) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0019,0070) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="WaterScalingFactor"			Name="Water Scaling Factor"
+(0019,0070) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="PhaseGradientAmplitude"		Name="Phase Gradient Amplitude"
+(0019,0070) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="NumberOfReadings"			Name="Number of Readings"
+(0019,0070) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfPrescans"			Name="Number of Prescans"
+(0019,0070) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="PLASource"				Name="PLA Source"
+(0019,0071) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="InterpolationFactor"			Name="Interpolation Factor"
+(0019,0071) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ReadoutGradientAmplitude"		Name="Readout Gradient Amplitude"
+(0019,0071) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0019,0071) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="PLADestination"			Name="PLA Destination"
+(0019,0072) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="SelectionGradientAmplitude"		Name="Selection Gradient Amplitude"
+(0019,0074) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="NumberOfProjections"			Name="Number of Projections"
+(0019,0075) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="NumberOfBytes"				Name="Number of Bytes"
+(0019,0075) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="UIDOriginalImage"			Name="UID Original Image"
+(0019,0076) VERS="SPI"   VR="LO"   VM="1"	Owner="SIEMENS DLR.01" 		Keyword="?"					Name="?"
+(0019,0080) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0019,0080) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  COAD"	Keyword="GradientDelayTime"			Name="Gradient Delay Time"
+(0019,0080) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="ReconstructionAlgorithmSet"		Name="Reconstruction Algorithm Set"
+(0019,0080) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PatientRegion"				Name="Patient Region"
+(0019,0080) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="ReaderHeader"				Name="Reader Header"
+(0019,0081) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="ReconstructionAlgorithmIndex"		Name="Reconstruction Algorithm Index"
+(0019,0081) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="FilterTypeForRawData"			Name="Filter Type for Raw Data"
+(0019,0082) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="TotalGradientDelayTime"		Name="Total Gradient Delay Time"
+(0019,0082) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="FilterParameterForRawData"		Name="Filter Parameter for Raw Data"
+(0019,0082) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PatientPhaseOfLife"			Name="Patient Phase of Life"
+(0019,0082) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="RegenerationSoftwareVersion"		Name="Regeneration Software Version"
+(0019,0083) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="FilterTypeForImageData"		Name="Filter Type for Image Data"
+(0019,0084) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="FilterParameterForImageData"		Name="Filter Parameter for Image Data"
+(0019,0085) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="FilterTypeForPhaseCorrection"		Name="Filter Type for Phase Correction"
+(0019,0086) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="FilterParameterForPhaseCorrection"	Name="Filter Parameter for Phase Correction"
+(0019,0087) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NormalizationFilterTypeForImageData"	Name="Normalization Filter Type for Image Data"
+(0019,0088) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0019,0088) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="NormalizationFilterParameterForImageData"	Name="Normalization Filter Parameter for Image Data"
+(0019,0090) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="OsteoOffset"				Name="Osteo Offset"
+(0019,0090) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfSaturationRegions"		Name="Number of Saturation Regions"
+(0019,0090) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="PLAOfSecondaryDestination"		Name="PLA of Secondary Destination"
+(0019,0090) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="SensitivityCorrectionLabel"		Name="Sensitivity Correction Label"
+(0019,0091) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  COAD"	Keyword="SaturationPhaseEncodingVectorCoronalComponent"	Name="Saturation Phase Encoding Vector Coronal Component"
+(0019,0091) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  GEN"	Keyword="SaturationPhaseEncodingVectorSagittalComponent"	Name="Saturation Phase Encoding Vector Sagittal Component"
+(0019,0092) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  COAD"	Keyword="SaturationReadoutVectorCoronalComponent"	Name="Saturation Readout Vector Coronal Component"
+(0019,0092) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  GEN"	Keyword="SaturationReadoutVectorSagittalComponent"	Name="Saturation Readout Vector Sagittal Component"
+(0019,0092) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="OsteoRegressionLineSlope"		Name="Osteo Regression Line Slope"
+(0019,0093) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="OsteoRegressionLineIntercept"		Name="Osteo Regression Line Intercept"
+(0019,0093) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIStimulationMonitorMode"		Name="EPI Stimulation Monitor Mode"
+(0019,0093) VERS="SSPI" VR="SL"   VM="2"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0019,0094) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="OsteoStandardizationCode"		Name="Osteo Standardization Code"
+(0019,0094) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="ImageRotationAngle"			Name="Image Rotation Angle"
+(0019,0096) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="OsteoPhantomNumber"			Name="Osteo Phantom Number"
+(0019,0096) VERS="SSPI"	VR="UL"   VM="3"	Owner="SIEMENS MR VA0  GEN"	Keyword="CoilIDMask"				Name="Coil ID Mask"
+(0019,0097) VERS="SSPI"	VR="UL"   VM="2"	Owner="SIEMENS MR VA0  GEN"	Keyword="CoilClassMask"				Name="Coil Class Mask"
+(0019,0098) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  GEN"	Keyword="CoilPosition"				Name="Coil Position"
+(0019,00a0) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="?"					Name="?"
+(0019,00a0) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIReconstructionPhase"		Name="EPI Reconstruction Phase"
+(0019,00a0) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="RFWatchdogMask"			Name="RF Watchdog Mask"
+(0019,00a0) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a1) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a1) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="?"					Name="?"
+(0019,00a1) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="EPIReconstructionSlope"		Name="EPI Reconstruction Slope"
+(0019,00a1) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIReconstructionSlope"		Name="EPI Reconstruction Slope"
+(0019,00a1) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0019,00a2) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a2) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="RFPowerErrorIndicator"			Name="RF Power Error Indicator"
+(0019,00a3) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a3) VERS="SSPI" VR="SL"   VM="2"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0019,00a4) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a5) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a5) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  COAD"	Keyword="SpecificAbsorptionRateWholeBody"	Name="Specific Absorption Rate Whole Body"
+(0019,00a6) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  COAD"	Keyword="SpecificEnergyDose"			Name="Specific Energy Dose"
+(0019,00a6) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a7) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a8) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00a9) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00aa) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00ab) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00ac) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00ad) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00ae) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00af) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00b0) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="FeedPerRotation"			Name="Feed per Rotation"
+(0019,00b0) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="AdjustmentStatusMask"			Name="Adjustment Status Mask"
+(0019,00bd) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PulmoTriggerLevel"			Name="Pulmo Trigger Level"
+(0019,00be) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="ExpiratoricReserveVolume"		Name="Expiratoric Reserve Volume"
+(0019,00bf) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="VitalCapacity"				Name="Vital Capacity"
+(0019,00c0) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PulmoWater"				Name="Pulmo Water"
+(0019,00c1) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PulmoAir"				Name="Pulmo Air"
+(0019,00c1) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  COAD"	Keyword="EPICapacity"				Name="EPI Capacity"
+(0019,00c2) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  COAD"	Keyword="EPIInductance"				Name="EPI Inductance"
+(0019,00c2) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PulmoDate"				Name="Pulmo Date"
+(0019,00c3) VERS="SSPI"	VR="IS"   VM="1-n"	Owner="SIEMENS MR VA0  COAD"	Keyword="EPISwitchConfigurationCode"		Name="EPI Switch Configuration Code"
+(0019,00c3) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="PulmoTime"				Name="Pulmo Time"
+(0019,00c3) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0019,00c4) VERS="SSPI"	VR="IS"   VM="1-n"	Owner="SIEMENS MR VA0  COAD"	Keyword="EPISwitchHardwareCode"			Name="EPI Switch Hardware Code"
+(0019,00c4) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00c5) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS MR VA0  COAD"	Keyword="EPISwitchDelayTime"			Name="EPI Switch Delay Time"
+(0019,00c5) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  COAD"	Keyword="?"					Name="?"
+(0019,00d1) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="FlowSensitivity"			Name="Flow Sensitivity"
+(0019,00d2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="CalculationSubmode"			Name="Calculation Submode"
+(0019,00d3) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="FieldOfViewRatio"			Name="Field of View Ratio"
+(0019,00d4) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="BaseRawMatrixSize"			Name="Base Raw Matrix Size"
+(0019,00d5) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="2DOversamplingLines"			Name="2D Oversampling Lines"
+(0019,00d6) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="ThreeDPhaseOversamplingPartitions"		Name="3D Phase Oversampling Partitions"
+(0019,00d7) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="EchoLinePosition"			Name="Echo Line Position"
+(0019,00d8) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="EchoColumnPosition"			Name="Echo Column Position"
+(0019,00d9) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="LinesPerSegment"			Name="Lines Per Segment"
+(0019,00da) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  COAD"	Keyword="PhaseCodingDirection"			Name="Phase Coding Direction"
+(0019,0006) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0007) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0008) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0026) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0029) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0030) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0031) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0032) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0033) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0034) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+(0019,0035) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Selma"	Keyword="?"			Name="?"
+
+(0019,0000) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="ReviewMode"								Name="Review Mode"
+(0019,0001) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="AnatomicalBackgroundPercent"				Name="Anatomical Background Percent"
+(0019,0002) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="NumberOfPhases"							Name="Number of Phases"
+(0019,0003) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="ApplyAnatomicalBackground"					Name="Apply Anatomical Background"
+(0019,0004) VERS="SSPI"	VR="SS"   VM="4-4n"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="PixelShiftArray"							Name="Pixel Shift Array"
+(0019,0005) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="Brightness"								Name="Brightness"
+(0019,0006) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="Contrast"									Name="Contrast"
+(0019,0007) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="EnabledShutters"							Name="Enabled Shutters"
+(0019,0008) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="NativeEdgeEnhancementPercentGain"			Name="Native Edge Enhancement Percent Gain"
+(0019,0009) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="NativeEdgeEnhancementLUTIndex"				Name="Native Edge Enhancement LUT Index"
+(0019,000A) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="NativeEdgeEnhancementKernelSize"			Name="Native Edge Enhancement Kernel Size"
+(0019,000B) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="SubtractedEdgeEnhancementPercentGain"		Name="Subtracted Edge Enhancement Percent Gain"
+(0019,000C) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="SubtractedEdgeEnhancementLUTIndex"			Name="Subtracted Edge Enhancement LUT Index"
+(0019,000D) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="SubtractedEdgeEnhancementKernelSize"		Name="Subtracted Edge Enhancement Kernel Size"
+(0019,000E) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="FadePercent"								Name="Fade Percent"
+(0019,000F) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="FlippedBeforeLateralityApplied"			Name="Flipped Before Laterality Applied"
+(0019,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="ApplyFade"									Name="Apply Fade"
+(0019,0011) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="ReferenceImagesTakenFlag"					Name="Reference Images Taken Flag"
+(0019,0012) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="Zoom"										Name="Zoom"
+(0019,0013) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="PanX"										Name="Pan X"
+(0019,0014) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="PanY"										Name="Pan Y"
+(0019,0015) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="NativeEdgeEnhancementAdvPercentGain"		Name="Native Edge Enhancement Adv Percent Gain"
+(0019,0016) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="SubtractedEdgeEnhancementAdvPercentGain"	Name="Subtracted Edge Enhancement Adv Percent Gain"
+(0019,0017) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="InvertFlag"								Name="Invert Flag"
+(0019,001A) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="Quant1KOverlay"							Name="Quant 1K Overlay"
+(0019,001B) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="OriginalResolution"						Name="Original Resolution"
+(0019,001C) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="AutoWindowCenter"							Name="Auto Window Center"
+(0019,001D) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="AutoWindowWidth"							Name="Auto Window Width"
+(0019,001E) VERS="SSPI"	VR="IS"   VM="2"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="AutoWindowCorrectValue"					Name="Auto Window Correct Value"
+(0019,001F) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="SigmoidWindowParameter"					Name="Sigmoid Window Parameter"
+(0019,0041) VERS="SSPI" VR="SL"   VM="2"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="DispayedAreaTopLeftHandCorner"				Name="Dispayed Area Top Left Hand Corner"
+(0019,0042) VERS="SSPI" VR="SL"   VM="2"	Owner="SIEMENS SMS-AX  VIEW 1.0"	Keyword="DispayedAreaBottomRightHandCorner"			Name="Dispayed Area Bottom Right Hand Corner"
+
+(0019,0001) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SIENET"				Keyword="?"									Name="?"
+
+(0019,0000) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0003) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,000c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,000d) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,000e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0095) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0020) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0021) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0022) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0023) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0024) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0025) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0026) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0028) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0029) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,002a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,002d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,002e) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0031) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?" 
+(0019,003a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,003b) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0040) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0041) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0042) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0043) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0044) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0046) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0047) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0048) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0049) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0054) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0060) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0061) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0062) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0063) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0065) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0066) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0067) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0069) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,006a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,006c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0072) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0080) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0081) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0082) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0083) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0086) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0087) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0088) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,00a0) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES"	Keyword="?"			Name="?"
+(0019,0020) VERS="SSPI" VR="SH"   VM="1"	Owner="Siemens Ultrasound Miscellaneous"	Keyword="?"			Name="?"
+
+(0019,0000) VERS="SSPI"	VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="?"							Name="?"
+(0019,0001) VERS="SSPI"	VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="?"							Name="?"
+(0019,0002) VERS="SSPI"	VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="TotalDoseAreaProduct"		Name="Total Dose Area Product uGy*cm*cm"
+(0019,0003) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="?"							Name="?"
+(0019,0004) VERS="SSPI"	VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="?"							Name="?"
+(0019,0005) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="?"							Name="?"
+(0019,0006) VERS="SSPI"	VR="FD"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="TableObjectDistance"		Name="Table Object Distance"
+(0019,0007) VERS="SSPI"	VR="FD"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="TableDetectorDistance"		Name="Table Detector Distance"
+(0019,0008) VERS="SSPI"	VR="US"   VM="1-n"	Owner="Siemens: Thorax/Multix FD Lab Settings"	Keyword="OrthoStepDistance"			Name="Ortho Step Distance"
+
+(0019,0000) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="PrivateCreatorVersion"			Name="Private Creator Version"
+(0019,0003) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="FrameRate"						Name="Frame Rate"
+(0019,000C) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BurnedInGraphics"				Name="Burned in Graphics"
+(0019,000D) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="SieClearIndex"					Name="SieClear Index"
+(0019,000E) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,0020) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeSubmode"					Name="B-Mode Submode"
+(0019,0021) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeDynamicRange"				Name="B-Mode Dynamic Range"
+(0019,0022) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeOverallGain"				Name="B-Mode Overall Gain"
+(0019,0023) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeResolutionSpeedIndex"		Name="B-Mode Resolution/Speed Index"
+(0019,0024) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeEdgeEnhanceIndex"			Name="B-Mode Edge Enhance Index"
+(0019,0025) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModePersistenceIndex"			Name="B-Mode Persistence Index"
+(0019,0026) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeMapIndex"					Name="B-Mode Map Index"
+(0019,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,0028) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,0029) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,002A) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeTintType"					Name="B-Mode Tint Type"
+(0019,002D) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="BModeTintIndex"				Name="B-Mode Tint Index"
+(0019,002E) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ClarifyVEIndex"				Name="ClarifyVE Index"
+(0019,0030) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,0031) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,003A) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ImageFlag"						Name="Image Flag"
+(0019,003B) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,0040) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowState"				Name="Color Flow State"
+(0019,0041) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowWallFilterIndex"		Name="Color Flow Wall Filter Index"
+(0019,0042) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowSubmode"				Name="Color Flow Submode"
+(0019,0043) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowOverallGain"			Name="Color Flow Overall Gain"
+(0019,0044) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowResolutionSpeedIndex"	Name="Color Flow Resolution/Speed Index"
+(0019,0046) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowSmoothIndex"			Name="Color Flow Smooth Index"
+(0019,0047) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowPersistenceIndex"		Name="Color Flow Persistence Index"
+(0019,0048) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowMapIndex"				Name="Color Flow Map Index"
+(0019,0049) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowPriorityIndex"		Name="Color Flow Priority Index"
+(0019,0054) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="ColorFlowMaximumVelocity"		Name="Color Flow Maximum Velocity"
+(0019,0060) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerDynamicRange"	Name="Doppler Dynamic Range"
+(0019,0061) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerOverallGain"			Name="Doppler Overall Gain"
+(0019,0062) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerWallFilter"				Name="Doppler Wall Filter"
+(0019,0063) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerGateSize"				Name="Doppler Gate Size"
+(0019,0065) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerMapIndex"				Name="Doppler Map Index"
+(0019,0066) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerSubmode"				Name="Doppler Submode"
+(0019,0067) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+(0019,0069) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerTimeFreqResIndex"		Name="Doppler Time/Freq Res Index"
+(0019,006A) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerTraceInverted"			Name="Doppler Trace Inverted"
+(0019,006C) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerTintType"				Name="Doppler Tint Type"
+(0019,0072) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="DopplerTintIndex"				Name="Doppler Tint Index"
+(0019,0080) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeDynamicRange"				Name="M-Mode Dynamic Range"
+(0019,0081) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeOverallGain"				Name="M-Mode Overall Gain"
+(0019,0082) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeEdgeEnhanceIndex"			Name="M-Mode Edge Enhance Index"
+(0019,0083) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeMapIndex"					Name="M-Mode Map Index"
+(0019,0086) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeTintType"					Name="M-Mode Tint Type"
+(0019,0087) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeSubmode"					Name="M-Mode Submode"
+(0019,0088) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="MModeTintIndex"				Name="M-Mode Tint Index"
+(0019,0095) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000"	Keyword="?"								Name="?"
+
+(0021,0000) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED NM"				Keyword="ECATMainHeader"				Name="ECAT_Main_Header"
+(0021,0001) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED NM"				Keyword="ECATImageSubheader"			Name="ECAT_Image_Subheader"
+(0021,0000) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED ECAT FILE INFO"	Keyword="ECATMainHeader"				Name="ECAT_Main_Header"
+(0021,0001) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED ECAT FILE INFO"	Keyword="ECATImageSubheader"			Name="ECAT_Image_Subheader"
+
+(0021,0000) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="AcquisitionType"						Name="Acquisition Type"
+(0021,0001) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="AcquisitionMode"						Name="Acquisition Mode"
+(0021,0002) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="FootswitchIndex"						Name="Footswitch Index"
+(0021,0003) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="AcquisitionRoom"						Name="Acquisition Room"
+(0021,0004) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="CurrentTimeProduct"					Name="Current Time Product"
+(0021,0005) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ImagerReceptorDose"					Name="Imager Receptor Dose"
+(0021,0006) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SkinDosePercent"						Name="Skin Dose Percent"
+(0021,0007) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SkinDoseAccumulation"					Name="Skin Dose Accumulation"
+(0021,0008) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SkinDoseRate"							Name="Skin Dose Rate"
+(0021,0009) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ImpacFilename"							Name="Impac Filename"
+(0021,000A) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="CopperFilter"							Name="Copper Filter"
+(0021,000B) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="MeasuringField"						Name="Measuring Field"
+(0021,000C) VERS="SSPI"	VR="SS"   VM="3"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="PostBlankingCircle"					Name="Post Blanking Circle"
+(0021,000D) VERS="SSPI"	VR="SS"   VM="2-2n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DynaAngles"							Name="Dyna Angles"
+(0021,000E) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TotalSteps"							Name="Total Steps"
+(0021,000F) VERS="SSPI"	VR="SL"   VM="4-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DynaXRayInfo"							Name="Dyna X-Ray Info"
+(0021,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ModalityLUTInputGamma"					Name="Modality LUT Input Gamma"
+(0021,0011) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ModalityLUTOutputGamma"				Name="Modality LUT Output Gamma"
+(0021,0012) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SHSTPAR"								Name="SH_STPAR"
+(0021,0013) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="AcquisitionZoom"						Name="Acquisition Zoom"
+(0021,0014) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DynaAngulationStep"					Name="Dyna Angulation Step"
+(0021,0015) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DDOValue"								Name="DDO Value"
+(0021,0016) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DRSingleFlag"							Name="DR Single Flag"
+(0021,0017) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SourcetoIsocenter"						Name="Source to Isocenter" 
+(0021,0018) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="PressureData"							Name="Pressure Data"
+(0021,0019) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ECGIndexArray"							Name="ECG Index Array"
+(0021,001A) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="FDFlag"								Name="FD Flag"
+(0021,001B) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SHZOOM"								Name="SH_ZOOM"
+(0021,001C) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="SHCOLPAR"								Name="SH_COLPAR"
+(0021,001D) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="KFactor"								Name="K-Factor"
+(0021,001E) VERS="SSPI"	VR="US"   VM="8"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="EVE"									Name="EVE"
+(0021,001F) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TotalSceneTime"						Name="Total Scene Time"
+(0021,0020) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="RestoreFlag"							Name="Restore Flag"
+(0021,0021) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="StandMovementFlag"						Name="Stand Movement Flag"
+(0021,0022) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="FDRows"								Name="FD Rows"
+(0021,0023) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="FDColumns"								Name="FD Columns"
+(0021,0024) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableMovementFlag"						Name="Table Movement Flag"
+(0021,0026) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="CrispyXPIFilterValue"					Name="Crispy XPI Filter Value"
+(0021,0027) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ICStentFlag"							Name="IC Stent Flag"
+(0021,0028) VERS="SSPI"	VR="SQ"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="GammaLUTSequence"						Name="Gamma LUT Sequence"
+(0021,0029) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="AcquisitionSceneTime"					Name="Acquisition Scene Time"
+(0021,002A) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDCardiacPhaseCenter"				Name="3D Cardiac Phase Center"
+(0021,002B) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDCardiacPhaseWidth"				Name="3D Cardiac Phase Width"
+(0021,0030) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="OrganProgramInfo"						Name="Organ Program Info"
+(0021,003A) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DDOKernelsize"							Name="DDO Kernel size"
+(0021,003B) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="mAsModulation"							Name="mAs Modulation"
+(0021,003C) VERS="SSPI"	VR="DT"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDRPeakReferenceTime"				Name="3D R-Peak Reference Time"
+(0021,003D) VERS="SSPI"	VR="SL"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ECGFrameTimeVector"					Name="ECG Frame Time Vector"
+(0021,003E) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ECGStartTimeOfRun"						Name="ECG Start Time of Run"
+(0021,0040) VERS="SSPI"	VR="US"   VM="3"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="GammaLUTDescriptor"					Name="Gamma LUT Descriptor"
+(0021,0041) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="GammaLUTType"							Name="Gamma LUT Type"
+(0021,0042) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="GammaLUTData"							Name="Gamma LUT Data"
+(0021,0043) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="GlobalGain"							Name="Global Gain"
+(0021,0044) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="GlobalOffset"							Name="Global Offset"
+(0021,0045) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DIPPMode"								Name="DIPP Mode"
+(0021,0046) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ArtisSystemType"						Name="Artis System Type"
+(0021,0047) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ArtisTableType"						Name="Artis Table Type"
+(0021,0048) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ArtisTableTopType"						Name="Artis Table Top Type"
+(0021,0049) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="WaterValue"							Name="Water Value"
+(0021,0051) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDPositionerPrimaryStartAngle"		Name="3D Positioner Primary Start Angle"
+(0021,0052) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDPositionerSecondaryStartAngle"	Name="3D Positioner Secondary Start Angle"
+(0021,0053) VERS="SSPI"	VR="SS"   VM="3"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="StandPosition"							Name="Stand Position"
+(0021,0054) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="RotationAngle"							Name="Rotation Angle"
+(0021,0055) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ImageRotation"							Name="Image Rotation"
+(0021,0056) VERS="SSPI"	VR="SS"   VM="3"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableCoordinates"						Name="Table Coordinates"
+(0021,0057) VERS="SSPI"	VR="SS"   VM="3"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="IsocenterTablePosition"				Name="Isocenter Table Position"
+(0021,0058) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableObjectDistance"					Name="Table Object Distance"
+(0021,0059) VERS="SSPI" VR="FL"   VM="12-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="CarmCoordinateSystem"					Name="Carm Coordinate System"
+(0021,005A) VERS="SSPI" VR="FL"   VM="6-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="RobotAxes"								Name="Robot Axes"
+(0021,005B) VERS="SSPI" VR="FL"   VM="12"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableCoordinateSystem"					Name="Table Coordinate System"
+(0021,005C) VERS="SSPI" VR="FL"   VM="12"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="PatientCoordinateSystem"				Name="Patient Coordinate System"
+(0021,005D) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="Angulation"							Name="Angulation"
+(0021,005E) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="Orbital"								Name="Orbital"
+(0021,0061) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="LargeVolumeOverlap"					Name="Large Volume Overlap"
+(0021,0062) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ReconstructionPreset"					Name="Reconstruction Preset"
+(0021,0063) VERS="SSPI"	VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDStartAngle"						Name="3D Start Angle"
+(0021,0064) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDPlannedAngle"					Name="3D Planned Angle"
+(0021,0065) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDRotationPlaneAlpha"				Name="3D Rotation Plane Alpha"
+(0021,0066) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDRotationPlaneBeta"				Name="3D Rotation Plane Beta"
+(0021,0067) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDFirstImageAngle"					Name="3D First Image Angle"
+(0021,0068) VERS="SSPI"	VR="SS"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDTriggerAngle"					Name="3D Trigger Angle"
+(0021,0071) VERS="SSPI"	VR="DS"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="DetectorRotation"						Name="Detector Rotation"
+(0021,0072) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="PhysicalDetectorRotation"				Name="Physical Detector Rotation"
+(0021,0081) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableTilt"								Name="Table Tilt"
+(0021,0082) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableRotation"							Name="Table Rotation"
+(0021,0083) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="TableCradleTilt"						Name="Table Cradle Tilt"
+(0021,00A0) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="Crispy1Container"						Name="Crispy1 Container"
+(0021,00A3) VERS="SSPI"	VR="SQ"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDCardiacTriggerSequence"			Name="3D Cardiac Trigger Sequence"
+(0021,00A4) VERS="SSPI"	VR="DT"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDFrameReferenceDateTime"			Name="3D Frame Reference Date Time"
+(0021,00A5) VERS="SSPI"	VR="FD"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDCardiacTriggerDelayTime"			Name="3D Cardiac Trigger Delay Time"
+(0021,00A6) VERS="SSPI"	VR="FD"   VM="1"	Owner="SIEMENS SMS-AX  ACQ 1.0"		Keyword="ThreeDRRIntervalTimeMeasured"			Name="3D R-R Interval Time Measured" 
+
+(0021,0000) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0001) VERS="SSPI"	VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0002) VERS="SSPI"	VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0003) VERS="SSPI"	VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0004) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0005) VERS="SSPI"	VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0006) VERS="SSPI"	VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0007) VERS="SSPI"	VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0008) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AutoWindowFlag"			Name="Auto Window Flag"
+(0021,0009) VERS="SSPI"	VR="SL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AutoWindowCenter"			Name="Auto Window Center"
+(0021,000a) VERS="SSPI"	VR="SL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AutoWindowWidth"			Name="Auto Window Width"
+(0021,000b) VERS="SSPI"	VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="FilterID"					Name="Filter ID"
+(0021,000c) VERS="SSPI"	VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,000d) VERS="SSPI"	VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,000e) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="DoseControlValue"			Name="Dose Control Value"
+(0021,000f) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0011) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0012) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0013) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="?"		Name="?"
+(0021,0014) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AnatomicCorrectView"		Name="Anatomic Correct View"
+(0021,0015) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AutoWindowShift"			Name="Auto Window Shift"
+(0021,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AutoWindowExpansion"		Name="Auto Window Expansion"
+(0021,0017) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="SystemType"				Name="System Type"
+(0021,0018) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="DetectorType"				Name="Detector Type"
+(0021,0030) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AnatomicSortNumber"		Name="Anatomic Sort Number"
+(0021,0031) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Post Processing"	Keyword="AcquisitionSortNumber"		Name="Acquisition Sort Number"
+
+(0021,0015) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0021,0020) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0021,0025) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0021,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0021,0028) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0021,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+(0021,0040) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS RA GEN"		Keyword="?"					Name="?"
+
+(0021,0000) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="SequenceType"				Name="Sequence Type"
+(0021,0001) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="VectorSizeOriginal"			Name="Vector Size Original"
+(0021,0002) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="VectorSizeExtended"			Name="Vector Size Extended"
+(0021,0003) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="AcquiredSpectralRange"			Name="Acquired Spectral Range"
+(0021,0004) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="VOIPosition"				Name="VOI Position"
+(0021,0005) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="VOISize"				Name="VOI Size"
+(0021,0006) VERS="SSPI"	VR="IS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="CSIMatrixSizeOriginal"			Name="CSI Matrix Size Original"
+(0021,0007) VERS="SSPI"	VR="IS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="CSIMatrixSizeExtended"			Name="CSI Matrix Size Extended"
+(0021,0008) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="SpatialGridShift"			Name="Spatial Grid Shift"
+(0021,0009) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="SignalLimitsMinimum"			Name="Signal Limits Minimum"
+(0021,0010) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MED"		Keyword="Zoom"					Name="Zoom"
+(0021,0010) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="SignalLimitsMaximum"			Name="Signal Limits Maximum"
+(0021,0010) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="RotationAngle"				Name="Rotation Angle"
+(0021,0010) VERS="SSPI"	VR="UL"   VM="2"	Owner="SIEMENS CT VA0  RAW"	Keyword="CreationMask"				Name="Creation Mask"
+(0021,0010) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0021,0011) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="SpecInfoMask"				Name="Spec Info Mask"
+(0021,0011) VERS="SSPI"	VR="DS"   VM="2"	Owner="SIEMENS MED"		Keyword="Target"				Name="Target"
+(0021,0011) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="StartAngle"				Name="Start Angle"
+(0021,0012) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPITimeRateOfChangeOfMagnitude"	Name="EPI Time Rate of Change of Magnitude"
+(0021,0012) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MED"		Keyword="TubeAngle"				Name="Tube Angle"
+(0021,0013) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPITimeRateOfChangeOfXComponent"	Name="EPI Time Rate of Change of X Component"
+(0021,0014) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPITimeRateOfChangeOfYComponent"	Name="EPI Time Rate of Change of Y Component"
+(0021,0015) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPITimeRateOfChangeOfZComponent"	Name="EPI Time Rate of Change of Z Component"
+(0021,0016) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPITimeRateOfChangeLegalLimit1"	Name="EPI Time Rate of Change Legal Limit 1"
+(0021,0017) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPIOperationModeFlag"			Name="EPI Operation Mode Flag"
+(0021,0018) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPIFieldCalculationSafetyFactor"	Name="EPI Field Calculation Safety Factor"
+(0021,0019) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPILegalLimit1OfChangeValue"		Name="EPI Legal Limit 1 of Change Value"
+(0021,0020) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPILegalLimit2OfChangeValue"		Name="EPI Legal Limit 2 of Change Value"
+(0021,0020) VERS="SSPI"	VR="DS"   VM="2"	Owner="SIEMENS CM VA0  CMS"	Keyword="FoV"					Name="FoV"
+(0021,0020) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="PhaseCorrectionRowsSequence"		Name="Phase Correction Rows Sequence"
+(0021,0020) VERS="SSPI"	VR="UL"   VM="2"	Owner="SIEMENS CT VA0  RAW"	Keyword="EvaluationMask"			Name="Evaluation Mask"
+(0021,0020) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED"		Keyword="ROIMask"				Name="ROI Mask"
+(0021,0020) VERS="SSPI"	VR="IS"   VM="1-n"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0021,0021) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="EPIRiseTime"				Name="EPI Rise Time"
+(0021,0021) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="PhaseCorrectionColumnsSequence"	Name="Phase Correction Columns Sequence"
+(0021,0022) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageMagnificationFactor"		Name="Image Magnification Factor"
+(0021,0022) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="PhaseCorrectionRowsReconstruction"	Name="Phase Correction Rows Reconstruction"
+(0021,0024) VERS="SSPI"	VR="DS"   VM="2"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageScrollOffset"			Name="Image Scroll Offset"
+(0021,0024) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="PhaseCorrectionColumnsReconstruction"	Name="Phase Correction Columns Reconstruction"
+(0021,0026) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImagePixelOffset"			Name="Image Pixel Offset"
+(0021,0030) VERS="SSPI"	VR="DS"   VM="16"	Owner="SIEMENS MR VA0  RAW"	Keyword="ArrayCoilADCOffset"			Name="Array Coil ADC Offset"
+(0021,0030) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="TopogramTubePosition"			Name="Topogram Tube Position"
+(0021,0030) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOf3DRawPartitionsNominal"	Name="Number of 3D Raw Partitions Nominal"
+(0021,0030) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ViewDirection"				Name="View Direction"
+(0021,0030) VERS="SSPI"	VR="US"   VM="7"	Owner="SIEMENS CT VA0  RAW"	Keyword="ExtendedProcessingMask"		Name="Extended Processing Mask"
+(0021,0031) VERS="SSPI"	VR="DS"   VM="16"	Owner="SIEMENS MR VA0  RAW"	Keyword="ArrayCoilPreamplifierGain"		Name="Array Coil Preamplifier Gain"
+(0021,0031) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOf3DRawPartitionsCurrent"	Name="Number of 3D Raw Partitions Current"
+(0021,0032) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientRestDirection"			Name="Patient Rest Direction"
+(0021,0032) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="LengthOfTopogram"			Name="Length of Topogram"
+(0021,0034) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="TopogramCorrectionFactor"		Name="Topogram Correction Factor"
+(0021,0034) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOf3DImagePartitions"		Name="Number of 3D Image Partitions"
+(0021,0036) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="MaximumTablePosition"			Name="Maximum Table Position"
+(0021,0036) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="Actual3DImagePartitionNumber"		Name="Actual 3D Image Partition Number"
+(0021,0039) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="SlabThickness"				Name="Slab Thickness"
+(0021,0040) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="TableMoveDirectionCode"		Name="Table Move Direction Code"
+(0021,0040) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfSlicesNominal"			Name="Number of Slices Nominal"
+(0021,0040) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  RAW"	Keyword="?"					Name="?"
+(0021,0041) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfSlicesCurrent"			Name="Number of Slices Current"
+(0021,0041) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  RAW"	Keyword="?"					Name="?"
+(0021,0042) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="CurrentSliceNumber"			Name="Current Slice Number"
+(0021,0042) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  RAW"	Keyword="?"					Name="?"
+(0021,0043) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="CurrentGroupNumber"			Name="Current Group Number"
+(0021,0043) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  RAW"	Keyword="?"					Name="?"
+(0021,0044) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="CurrentSliceDistanceFactor"		Name="Current Slice Distance Factor"
+(0021,0044) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS CT VA0  RAW"	Keyword="?"					Name="?"
+(0021,0045) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VOIStartRow"				Name="VOI Start Row"
+(0021,0045) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MIPStartRow"				Name="MIP Start Row"
+(0021,0046) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VOIStopRow"				Name="VOI Stop Row"
+(0021,0046) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MIPStopRow"				Name="MIP Stop Row"
+(0021,0047) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VOIStartColumn"			Name="VOI Start Column"
+(0021,0047) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MIPStartColumn"			Name="MIP Start Column"
+(0021,0048) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VOIStopColumn"				Name="VOI Stop Column"
+(0021,0048) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MIPStartColumn"			Name="MIP Stop Column"
+(0021,0049) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VOIStartSlice"				Name="VOI Start Slice"
+(0021,0049) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MIPStartSlice"				Name="MIP Start Slice"
+(0021,004a) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VOIStopSlice"				Name="VOI Stop Slice"
+(0021,004a) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="MIPStartSlice"				Name="MIP Stop Slice"
+(0021,004f) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="OrderofSlices"				Name="Order of Slices"
+(0021,0050) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VectorStartRow"			Name="Vector Start Row"
+(0021,0050) VERS="SSPI"	VR="UL"   VM="1-n"	Owner="SIEMENS MR VA0  GEN"	Keyword="SignalMask"				Name="Signal Mask"
+(0021,0050) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT VA0  RAW"	Keyword="?"					Name="?"
+(0021,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR VA0  RAW"	Keyword="SaturationType"			Name="Saturation Type"
+(0021,0051) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="SaturationNormalVector"		Name="Saturation Normal Vector"
+(0021,0051) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VectorRowStep"				Name="Vector Row Step"
+(0021,0052) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="DelayAfterTrigger"			Name="Delay After Trigger"
+(0021,0052) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS MR VA0  RAW"	Keyword="SaturationPositionVector"		Name="Saturation Position Vector"
+(0021,0052) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VectorStartColumn"			Name="Vector Start Column"
+(0021,0053) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  RAW"	Keyword="SaturationThickness"			Name="Saturation Thickness"
+(0021,0053) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="VectorColumnStep"			Name="Vector Column Step"
+(0021,0053) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="RRInterval"				Name="RR Interval"
+(0021,0054) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfTriggerPulses"			Name="Number of Trigger Pulses"
+(0021,0054) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  RAW"	Keyword="SaturationWidth"			Name="Saturation Width"
+(0021,0055) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  RAW"	Keyword="SaturationDistance"			Name="Saturation Distance"
+(0021,0056) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="RepetitionTimeEffective"		Name="Repetition Time Effective"
+(0021,0057) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="GatePhase"				Name="Gate Phase"
+(0021,0058) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="GateThreshold"				Name="Gate Threshold"
+(0021,0059) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="GatedRatio"				Name="Gated Ratio"
+(0021,0060) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImagePosition"				Name="Image Position"
+(0021,0060) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="RangeTypeCode"				Name="Range Type Code"
+(0021,0060) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfInterpolatedImages"		Name="Number of Interpolated Images"
+(0021,0061) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageNormal"				Name="Image Normal"
+(0021,0062) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="ReferenceTypeCode"			Name="Reference Type Code"
+(0021,0063) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageDistance"				Name="Image Distance"
+(0021,0065) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImagePositioningHistoryMask"		Name="Image Positioning History Mask"
+(0021,006a) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageRow"				Name="Image Row"
+(0021,006b) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageColumn"				Name="Image Column"
+(0021,0070) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS CT VA0  GEN"	Keyword="ObjectOrientation"			Name="Object Orientation"
+(0021,0070) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="NumberOfEchoes"			Name="Number of Echoes"
+(0021,0070) VERS="SSPI"	VR="CS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientOrientationSet1"		Name="Patient Orientation Set1"
+(0021,0071) VERS="SSPI"	VR="CS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="PatientOrientationSet2"		Name="Patient Orientation Set2"
+(0021,0072) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="SecondEchoTime"			Name="Second Echo Time"
+(0021,0072) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="SecondRepetitionTime"			Name="Second Repetition Time"
+(0021,0072) VERS="SSPI"	VR="DS"   VM="3"	Owner="SIEMENS CT VA0  GEN"	Keyword="LightOrientation"			Name="Light Orientation"
+(0021,0073) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="SecondRepetitionTime"			Name="Second Repetition Time"
+(0021,0075) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="LightBrightness"			Name="Light Brightness"
+(0021,0076) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="LightContrast"				Name="Light Contrast"
+(0021,007a) VERS="SSPI"	VR="IS"   VM="2"	Owner="SIEMENS CT VA0  GEN"	Keyword="OverlayThreshold"			Name="Overlay Threshold"
+(0021,007b) VERS="SSPI"	VR="IS"   VM="2"	Owner="SIEMENS CT VA0  GEN"	Keyword="SurfaceThreshold"			Name="Surface Threshold"
+(0021,007c) VERS="SSPI"	VR="IS"   VM="2"	Owner="SIEMENS CT VA0  GEN"	Keyword="GreyScaleThreshold"			Name="Grey Scale Threshold"
+(0021,0080) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="CardiacCode"				Name="Cardiac Code"
+(0021,0080) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="StudyName"				Name="Study Name"
+(0021,0082) VERS="SSPI" VR="SH"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="StudyType"				Name="Study Type"
+(0021,0091) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  GEN"	Keyword="SaturationPhaseEncodingVectorTransverseComponent"	Name="Saturation Phase Encoding Vector Transverse Component"
+(0021,0092) VERS="SSPI"	VR="DS"   VM="6"	Owner="SIEMENS MR VA0  GEN"	Keyword="SaturationReadoutVectorTransverseComponent"	Name="Saturation Readout Vector Transverse Component"
+(0021,0093) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIChangeValueOfMagnitude"		Name="EPI Change Value of Magnitude"
+(0021,0094) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIChangeValueOfXComponent"		Name="EPI Change Value of X Component"
+(0021,0095) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIChangeValueOfYComponent"		Name="EPI Change Value of Y Component"
+(0021,0096) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS MR VA0  GEN"	Keyword="EPIChangeValueOfZComponent"		Name="EPI Change Value of Z Component"
+(0021,00a0) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0021,00a2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+(0021,00a7) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  GEN"	Keyword="?"					Name="?"
+
+(0021,0008) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AutoWindowFlag"			Name="Auto Window Flag"
+(0021,0009) VERS="SSPI" VR="SL"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AutoWindowCenter"			Name="Auto Window Center"
+(0021,000A) VERS="SSPI" VR="SL"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AutoWindowWidth"			Name="Auto Window Width"
+(0021,000B) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="FilterID"					Name="Filter ID"
+(0021,0014) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AnatomicCorrectView"		Name="Anatomic Correct View"
+(0021,0015) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AutoWindowShift"			Name="Auto Window Shift"
+(0021,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AutoWindowExpansion"		Name="Auto Window Expansion"
+(0021,0017) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="SystemType"				Name="System Type"
+(0021,0030) VERS="SSPI" VR="SH"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AnatomicSortNumber"		Name="Anatomic Sort Number"
+(0021,0031) VERS="SSPI" VR="SH"   VM="1"	Owner="Siemens: Thorax/Multix FD Lab Settings"			Keyword="AcquisitionSortNumber"		Name="AcquisitionSortNumber"
+
+(0021,00a4) VERS="KDX"  VR="OB"   VM="1"	Owner="KINETDX_GRAPHICS"	Keyword="?"					Name="?"	RenderAsString="true"
+
+(0021,00a6) VERS="KDX"  VR="OB"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"	RenderAsString="true"
+(0021,00a5) VERS="KDX"  VR="US"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"
+(0021,00a8) VERS="KDX"  VR="LO"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"
+(0021,00aa) VERS="KDX"  VR="OB"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"	RenderAsString="true"
+(0021,00ab) VERS="KDX"  VR="LO"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"
+(0021,00ac) VERS="KDX"  VR="LO"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"
+(0021,00b4) VERS="KDX"  VR="LO"   VM="1"	Owner="KINETDX"				Keyword="?"					Name="?"
+
+(0021,00ae) VERS="SSPI" VR="OB"   VM="1"	Owner="syngoDynamics"		Keyword="?"					Name="?"
+(0021,00b0) VERS="SSPI" VR="LO"   VM="1"	Owner="syngoDynamics"		Keyword="?"					Name="?"
+(0021,00b1) VERS="SSPI" VR="LO"   VM="1"	Owner="syngoDynamics"		Keyword="?"					Name="?"
+
+(0023,0001) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED NM"		Keyword="DICOMReaderFlag"									Name="DICOM Reader flag"
+
+(0023,0000) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Image Stamp"	Keyword="?"			Name="?"
+(0023,0001) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Image Stamp"	Keyword="?"			Name="?"
+(0023,0002) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Image Stamp"	Keyword="?"			Name="?"
+(0023,0003) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Image Stamp"	Keyword="?"			Name="?"
+(0023,0004) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Image Stamp"	Keyword="?"			Name="?"
+
+(0023,0000) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="HorizontalCalibrationPixelSize"	Name="Horizontal Calibration Pixel Size"
+(0023,0001) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="VerticalCalibrationPixelSize"		Name="Vertical Calibration Pixel Size"
+(0023,0002) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="CalibrationObject"					Name="Calibration Object"
+(0023,0003) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="CalibrationObjectSize"				Name="Calibration Object Size"
+(0023,0004) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="CalibrationMethod"					Name="Calibration Method"
+(0023,0005) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="Filename"							Name="Filename"
+(0023,0006) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="FrameNumber"						Name="Frame Number"
+(0023,0007) VERS="SSPI" VR="IS"   VM="2"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="CalibrationFactorMultiplicity"		Name="Calibration Factor Multiplicity"
+(0023,0008) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  QUANT 1.0"		Keyword="CalibrationTableObjectDistance"	Name="Calibration Table Object Distance"
+
+(0025,0000) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="ViewNative"				Name="View Native"
+(0025,0001) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalSeriesNumber"		Name="Original Series Number"
+(0025,0002) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalImageNumber"		Name="Original Image Number"
+(0025,0003) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="WinCenter"					Name="Win Center"
+(0025,0004) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="WinWidth"					Name="Win Width"
+(0025,0005) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="WinBrightness"				Name="Win Brightness"
+(0025,0006) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="WinContrast"				Name="Win Contrast"
+(0025,0007) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalFrameNumber"		Name="Original Frame Number"
+(0025,0008) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalMaskFrameNumber"	Name="Original Mask Frame Number"
+(0025,0009) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="Opac"						Name="Opac"
+(0025,000a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalNumberofFrames"	Name="Original Number of Frames"
+(0025,000b) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalSceneDuration"		Name="Original Scene Duration"
+(0025,000c) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="IdentifierLOID"			Name="Identifier LOID"
+(0025,000d) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalSceneVFRInfo"		Name="Original Scene VFR Info"
+(0025,000e) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalFrameECGPosition"	Name="Original Frame ECG Position"
+(0025,000f) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="OriginalECG1stFrameOffset"	Name="Original ECG 1st Frame Offset"
+(0025,0010) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="ZoomFlag"					Name="Zoom Flag"
+(0025,0011) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="FlexiblePixelShift"		Name="Flexible Pixel Shift"
+(0025,0012) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="NumberOfMaskFrames"		Name="Number of Mask Frames"
+(0025,0013) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="NumberOfFillFrames"		Name="Number of Fill Frames"
+(0025,0014) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="SeriesNumber"				Name="Series Number"
+(0025,0015) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="ImageNumber"				Name="Image Number"
+(0025,0016) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SMS-AX  ORIGINAL IMAGE INFO 1.0"		Keyword="ReadyProcessingStatus"		Name="Ready Processing Status"
+
+(0025,0000) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="RawImageAmplification"		Name="Raw Image Amplification"
+(0025,0001) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="GammaLUT"					Name="Gamma LUT"
+(0025,0002) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0003) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0004) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0005) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0006) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0007) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0008) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0009) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,000a) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,000b) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,000C) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="HarmonizationKernel"		Name="Harmonization Kernel"
+(0025,000D) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="HarmonizationGain"			Name="Harmonization Gain"
+(0025,000E) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="EdgeEnhancementKernel"		Name="Edge Enhancement Kernel"
+(0025,000F) VERS="SSPI" VR="FL"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="EdgeEnhancementGain"		Name="Edge Enhancement Gain"
+(0025,0010) VERS="SSPI" VR="LT"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="InternalValue"				Name="Internal Value"
+(0025,0011) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0012) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0013) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0014) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0015) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0016) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0017) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"		Name="?"
+(0025,0018) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="AutoGain"					Name="Auto Gain"
+(0025,0019) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="OrthoSubsampling"			Name="Ortho Subsampling"
+(0025,001A) VERS="SSPI" VR="US"   VM="2"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="ImageCropUpperLeft"		Name="Image Crop Upper Left"
+(0025,001B) VERS="SSPI" VR="US"   VM="2"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="ImageCropUpperRight"		Name="Image Crop Upper Right"
+(0025,001C) VERS="SSPI" VR="US"   VM="2"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="ImageCropLowerLeft"		Name="Image Crop Lower Left"
+(0025,001D) VERS="SSPI" VR="US"   VM="2"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="ImageCropLowerRight"		Name="Image Crop Lower Right"
+(0025,0030) VERS="SSPI" VR="US"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="ManualCropping"			Name="Manual Cropping"
+(0025,0031) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="GammaLUTParameter1"		Name="Gamma LUT Parameter 1"
+(0025,0032) VERS="SSPI" VR="DS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="GammaLUTParameter2"		Name="Gamma LUT Parameter 2"
+(0025,0033) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="GammaLUTParameter3"		Name="Gamma LUT Parameter 3"
+(0025,0034) VERS="SSPI" VR="SS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="GammaLUTParameter4"		Name="Gamma LUT Parameter 4"
+(0025,0035) VERS="SSPI" VR="LO"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="GammaLUTName"				Name="Gamma LUT Name"
+(0025,0036) VERS="SSPI" VR="DS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"				Name="?"
+(0025,0037) VERS="SSPI" VR="DS"   VM="1"	Owner="Siemens: Thorax/Multix FD Raw Image Settings"	Keyword="?"				Name="?"
+
+(0027,0001) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ENHANCED IDATASET API"				Keyword="BusinessUnitCode"					Name="Business Unit Code"
+(0027,0002) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ENHANCED IDATASET API"				Keyword="ApplicationType"					Name="Application Type"
+(0027,0003) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ENHANCED IDATASET API"				Keyword="ApplicationAttributesSequence"		Name="Application Attributes Sequence" 
+
+(0029,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO FUNCTION ASSIGNMENT"				Keyword="DataReference"						Name="Data Reference"
+
+(0029,0002) VERS="SSPI" VR="FD"   VM="1"	Owner="SHS MagicView 300"	Keyword="?"					Name="?"
+(0029,0003) VERS="SSPI" VR="FD"   VM="1"	Owner="SHS MagicView 300"	Keyword="?"					Name="?"
+(0029,0004) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="PhotometricInterpretation"		Name="Photometric Interpretation"
+(0029,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CSA NON-IMAGE"	Keyword="CSADataType"				Name="CSA Data Type"
+(0029,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CSA HEADER"	Keyword="CSAImageHeaderType"			Name="CSA Image Header Type"
+(0029,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="MedComHeaderType"			Name="MedCom Header Type"
+(0029,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM OOG"	Keyword="MedComOOGType"				Name="MedCom OOG Type"
+(0029,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CSA NON-IMAGE"	Keyword="CSADataVersion"			Name="CSA Data Version"
+(0029,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CSA HEADER"	Keyword="CSAImageHeaderVersion"			Name="CSA Image Header Version"
+(0029,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MEDCOM OOG"	Keyword="MedComOOGVersion"			Name="MedCom OOG Version"
+(0029,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="RowsOfSubmatrix"			Name="Rows of Submatrix"
+(0029,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED HG"		Keyword="ListOfGroupNumbers"			Name="List of Group Numbers"
+(0029,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED MG"		Keyword="ListOfGroupNumbers"			Name="List of Group Numbers"
+(0029,0010) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="WindowStyle"				Name="Window Style"
+(0029,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CSA NON-IMAGE"	Keyword="CSADataInfo"				Name="CSA Data Info"
+(0029,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CSA HEADER"	Keyword="CSAImageHeaderInfo"			Name="CSA Image Header Info"
+(0029,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MEDCOM OOG"	Keyword="MedComOOGInfo"				Name="MedCom OOG Info"
+(0029,0011) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="ColumnsOfSubmatrix"			Name="Columns of Submatrix"
+(0029,0011) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0029,0013) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0029,0015) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED HG"		Keyword="ListOfShadowOwnerCodes"		Name="List of Shadow Owner Codes"
+(0029,0015) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED MG"		Keyword="ListOfShadowOwnerCodes"		Name="List of Shadow Owner Codes"
+(0029,0018) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CSA HEADER"	Keyword="CSASeriesHeaderType"			Name="CSA Series Header Type"
+(0029,0019) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CSA HEADER"	Keyword="CSASeriesHeaderVersion"		Name="CSA Series Header Version"
+(0029,0020) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED HG"		Keyword="ListOfElementNumbers"			Name="List of Element Numbers"
+(0029,0020) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED MG"		Keyword="ListOfElementNumbers"			Name="List of Element Numbers"
+(0029,0020) VERS="SSPI" VR="CS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="PixelQualityCode"			Name="Pixel Quality Code"
+(0029,0020) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY" 	Keyword="?" 					Name="?"
+(0029,0020) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CSA HEADER"	Keyword="CSASeriesHeaderInfo"			Name="CSA Series Header Info"
+(0029,0021) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY" 	Keyword="?" 					Name="?"
+(0029,0022) VERS="SSPI"	VR="IS"   VM="3"	Owner="SIEMENS CM VA0  CMS"	Keyword="PixelQualityValue"			Name="Pixel Quality Value"
+(0029,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED HG"		Keyword="ListOfTotalDisplayLength"		Name="List of Total Display Length"
+(0029,0030) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED MG"		Keyword="ListOfTotalDisplayLength"		Name="List of Total Display Length"
+(0029,0031) VERS="SSPI"	VR="US"   VM="1-n"	Owner="DIGISCAN IMAGE"		Keyword="?"					Name="?"
+(0029,0032) VERS="SSPI"	VR="US"   VM="1-n"	Owner="DIGISCAN IMAGE"		Keyword="?"					Name="?"
+(0029,0033) VERS="SSPI" VR="LO"   VM="1"	Owner="DIGISCAN IMAGE"		Keyword="?"					Name="?"
+(0029,0034) VERS="SSPI" VR="LO"   VM="1"	Owner="DIGISCAN IMAGE"		Keyword="?"					Name="?"
+(0029,0040) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED HG"		Keyword="ListOfDisplayPrefix"			Name="List of Display Prefix"
+(0029,0040) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED MG"		Keyword="ListOfDisplayPrefix"			Name="List of Display Prefix"
+(0029,0050) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="OriginOfSubmatrix"			Name="Origin of Submatrix"
+(0029,0050) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ArchiveCode"				Name="Archive Code"
+(0029,0050) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED HG"		Keyword="ListOfDisplayPostfix"			Name="List of Display Postfix"
+(0029,0050) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED MG"		Keyword="ListOfDisplayPostfix"			Name="List of Display Postfix"
+(0029,0051) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ExposureCode"				Name="Exposure Code"
+(0029,0052) VERS="SSPI"	VR="IS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="SortCode"				Name="Sort Code"
+(0029,0053) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="?"					Name="?"
+(0029,0060) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="Splash"				Name="Splash"
+(0029,0060) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED HG"		Keyword="ListOfTextPosition"			Name="List of Text Position"
+(0029,0060) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED MG"		Keyword="ListOfTextPosition"			Name="List of Text Position"
+(0029,0060) VERS="SSPI" VR="LO"   VM="1"	Owner="SPI"			Keyword="CompressionAlgorithm"			Name="Compression Algorithm"
+(0029,0070) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED HG"		Keyword="ListOfTextConcatenation"		Name="List of Text Concatenation"
+(0029,0070) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED MG"		Keyword="ListOfTextConcatenation"		Name="List of Text Concatenation"
+(0029,0080) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="?"				Name="?"
+(0029,0099) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="ShutterType"				Name="Shutter Type"
+(0029,00a0) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="RowsOfRectangularShutter"		Name="Rows of Rectangular Shutter"
+(0029,00a1) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="ColumnsOfRectangularShutter"		Name="Columns of Rectangular Shutter"
+(0029,00a2) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="OriginOfRectangularShutter"		Name="Origin of Rectangular Shutter"
+(0029,00b0) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="RadiusOfCircularShutter"		Name="Radius of Circular Shutter"
+(0029,00b2) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="OriginOfCircularShutter"		Name="Origin of Circular Shutter"
+(0029,00c1) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY"	Keyword="ContourOfIrregularShutter"		Name="Contour of Irregular Shutter"
+(0029,005a) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED MAMMO"		Keyword="?"					Name="?"
+
+(0029,0099) VERS="SSPI"	VR="CS"   VM="1"	Owner="SIEMENS MED DISPLAY 0000"	Keyword="?"					Name="?"
+(0029,00c1) VERS="SSPI"	VR="US"   VM="1-n"	Owner="SIEMENS MED DISPLAY 0000"	Keyword="?"					Name="?"
+(0029,00b0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY 0000"	Keyword="?"					Name="?"
+(0029,00b2) VERS="SSPI" VR="US"   VM="1-n"	Owner="SIEMENS MED DISPLAY 0000"	Keyword="?"					Name="?"
+
+(0029,0099) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED DISPLAY 0001"	Keyword="?"					Name="?"
+(0029,00a0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY 0001"	Keyword="?"					Name="?"
+(0029,00a1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED DISPLAY 0001"	Keyword="?"					Name="?"
+(0029,00a2) VERS="SSPI" VR="US"   VM="1-n"	Owner="SIEMENS MED DISPLAY 0001"	Keyword="?"					Name="?"
+
+(0029,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="MedComHeaderVersion"			Name="MedCom Header Version"
+(0029,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="MedComHeaderInfo"			Name="MedCom Header Info"
+(0029,0020) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="MedComHistoryInformation"		Name="MedCom History Information"
+(0029,0031) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="PMTFInformation1"			Name="PMTF Information 1"
+(0029,0032) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="PMTFInformation2"			Name="PMTF Information 2"
+(0029,0033) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="PMTFInformation3"			Name="PMTF Information 3"
+(0029,0034) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="PMTFInformation4"			Name="PMTF Information 4"
+(0029,0035) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="PMTFInformation5"			Name="PMTF Information 5"
+(0029,0040) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ApplicationHeaderSequence"		Name="Application Header Sequence"
+(0029,0041) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ApplicationHeaderType"			Name="Application Header Type"
+(0029,0042) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ApplicationHeaderID"			Name="Application Header ID"
+(0029,0043) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ApplicationHeaderVersion"		Name="Application Header Version"
+(0029,0044) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ApplicationHeaderInfo"			Name="Application Header Info"
+(0029,0050) VERS="SSPI" VR="LO"   VM="8"	Owner="SIEMENS MEDCOM HEADER"	Keyword="WorkflowControlFlags"			Name="Workflow Control Flags"
+(0029,0051) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ArchiveManagementFlagKeepOnline"	Name="Archive Management Flag Keep Online"
+(0029,0052) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ArchiveManagementFlagDoNotArchive"	Name="Archive Management Flag Do Not Archive"
+(0029,0053) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="ImageLocationStatus"			Name="Image Location Status"
+(0029,0054) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="EstimatedRetrieveTime"			Name="Estimated Retrieve Time"
+(0029,0055) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"	Keyword="DataSizeOfRetrievedImages"		Name="Data Size of Retrieved Images"
+(0029,0070) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="SiemensLinkSequence"				Name="Siemens Link Sequence"  
+(0029,0071) VERS="SSPI" VR="AT"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedTag"						Name="Referenced Tag"  
+(0029,0072) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedTagType"					Name="Referenced Tag Type"  
+(0029,0073) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedValueLength"				Name="Referenced Value Length"  
+(0029,0074) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedObjectDeviceType"		Name="Referenced Object Device Type"  
+(0029,0075) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedObjectDeviceLocation"	Name="Referenced Object Device Location"  
+(0029,0076) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedObjectID"				Name="Referenced Object ID"  
+(0029,0077) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MEDCOM HEADER"		Keyword="ReferencedObjectOffset"			Name="Referenced Object Offset"  
+
+(0029,0060) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MEDCOM HEADER2"	Keyword="SeriesWorkFlowStatus"		Name="Series Work Flow Status" 
+
+(0029,0012) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="Slices"									Name="Slices"
+(0029,0014) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="VolumeHistogram"							Name="Volume Histogram"
+(0029,0018) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="VolumeLevel"								Name="Volume Level"
+(0029,0030) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO VOLUME"					Keyword="VoxelSpacing"								Name="Voxel Spacing"
+(0029,0032) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO VOLUME"					Keyword="VolumePositionPatient"						Name="Volume Position (Patient)"
+(0029,0037) VERS="SSPI" VR="DS"   VM="9"	Owner="SIEMENS SYNGO VOLUME"					Keyword="VolumeOrientationPatient"					Name="Volume Orientation (Patient)"
+(0029,0040) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="ResamplingFlag"							Name="Resampling Flag"
+(0029,0042) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="NormalizationFlag"							Name="Normalization Flag"
+(0029,0044) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="SubVolumeSequence"							Name="SubVolume Sequence"
+(0029,0046) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="HistogramNumberOfBins"						Name="Histogram Number Of Bins"
+(0029,0047) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO VOLUME"					Keyword="VolumeHistogramData"						Name="Volume Histogram Data"
+
+(0029,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO TIME POINT SERVICE"		Keyword="TimePointID"								Name="Time Point ID" 
+(0029,0002) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO TIME POINT SERVICE"		Keyword="TimePointInformation"						Name="Time Point Information"
+(0029,0050) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO TIME POINT SERVICE"		Keyword="StudiesinTimePointSequence"				Name="Studies in Time Point Sequence"
+
+(0029,0000) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationName"							Name="Presentation Name"  
+(0029,0001) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationType"							Name="Presentation Type"  
+(0029,0002) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AdvancedPresentationSequence"				Name="Advanced Presentation Sequence"  
+(0029,0003) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TimePointSequence"							Name="Time Point Sequence"  
+(0029,0004) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="BaseImageSequence"							Name="Base Image Sequence"  
+(0029,0005) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="OverlayImageSequence"						Name="Overlay Image Sequence"  
+(0029,0006) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RegistrationInstanceSequence"				Name="Registration Instance Sequence"  
+(0029,0007) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RealWorldValueMappingInstanceSequence"		Name="Real World Value Mapping Instance Sequence"  
+(0029,0008) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementSequence"						Name="Measurement Sequence"  
+(0029,0009) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementUID"							Name="Measurement UID"  
+(0029,0010) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationSequence"						Name="Segmentation Sequence"
+(0029,0011) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationUID"							Name="Segmentation UID" 
+(0029,0012) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="NavigationSequence"						Name="Navigation Sequence"  
+(0029,0013) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="NavigationName"							Name="Navigation Name"  
+(0029,0014) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AutoNavigationDirection"					Name="Auto Navigation Direction"  
+(0029,0015) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AutoNavigationFrameRate"					Name="Auto Navigation Frame Rate"  
+(0029,0016) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AutoNavigationMode"						Name="Auto Navigation Mode"  
+(0029,0017) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AutoNavigationRealtimeSpeed"				Name="Auto Navigation Realtime Speed"  
+(0029,0018) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AutoNavigationStrategy"					Name="Auto Navigation Strategy"  
+(0029,0019) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="AutoNavigationRealtimeFlag"				Name="Auto Navigation Realtime Flag"  
+(0029,0020) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="IndexNavigationCurrentIndex"				Name="Index Navigation Current Index"  
+(0029,0021) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="IndexAutoNavigationSkippingDegree"			Name="Index Auto Navigation Skipping Degree"  
+(0029,0022) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="VolumeNavigationMinimumPixelSpacing"		Name="Volume Navigation Minimum Pixel Spacing"  
+(0029,0023) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="VolumeNavigationScrollUnit"				Name="Volume Navigation Scroll Unit"  
+(0029,0024) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="VolumeNavigationStepSize"					Name="Volume Navigation Step Size"  
+(0029,0025) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="VolumeNavigationJumpSize"					Name="Volume Navigation Jump Size"  
+(0029,0026) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ReferencedRegistrationNumber"				Name="Referenced Registration Number"  
+(0029,0027) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RealWorldValueMappingUID"					Name="Real World Value Mapping UID"  
+(0029,0028) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ChannelAlphaValue"							Name="Channel Alpha Value"
+(0029,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementApplicationName"				Name="Measurement Application Name"
+(0029,0031) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDataSequence"					Name="Measurement Data Sequence"  
+(0029,0032) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementType"							Name="Measurement Type"  
+(0029,0033) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementFrameOfReferenceUID"			Name="Measurement Frame of Reference UID"  
+(0029,0034) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementUid"							Name="Measurement UID"
+(0029,0035) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementApplicationNumber"				Name="Measurement Application Number"  
+(0029,0036) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementApplicationNumberPrefixText"	Name="Measurement Application Number Prefix Text"  
+(0029,0037) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementGraphicIsVisibleFlag"			Name="Measurement Graphic Is Visible Flag"
+(0029,0038) VERS="SSPI" VR="UI"   VM="4"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ReferencedSyngoUID"						Name="Referenced Syngo UID"
+(0029,0039) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClinicalFindingUID"						Name="Clinical Finding UID"
+(0029,003A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationStringValue"			Name="Measurement Evaluation String Value"
+(0029,003B) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationIntegerValue"			Name="Measurement Evaluation Integer Value"
+(0029,003C) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationDecimalValue"			Name="Measurement Evaluation Decimal Value"
+(0029,003D) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementLineShowCenterFlag"				Name="Measurement Line Show Center Flag"
+(0029,003E) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementAngleShowArrowTipFlag"			Name="Measurement Angle Show ArrowTip Flag"
+(0029,003F) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraHomeSettingsSequence"				Name="Camera Home Settings Sequence"
+(0029,0040) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraZoom"								Name="Camera Zoom"
+(0029,0041) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraPosition"							Name="Camera Position"  
+(0029,0042) VERS="SSPI" VR="DS"   VM="4"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraOrientation"							Name="Camera Orientation"  
+(0029,0043) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraFarClipPlane"						Name="Camera Far Clip Plane"  
+(0029,0044) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraNearClipPlane"						Name="Camera Near Clip Plane"  
+(0029,0045) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraThickness"							Name="Camera Thickness"  
+(0029,0046) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraViewPortSize"						Name="Camera ViewPort Size"  
+(0029,0047) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraAspectRatio"							Name="Camera Aspect Ratio"  
+(0029,0048) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraProjectionType"						Name="Camera Projection Type" 
+(0029,0049) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraFieldOfView"							Name="Camera Field of View"  
+(0029,004A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraImagePlaneDistance"					Name="Camera Image Plane Distance"  
+(0029,004B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraImageMaximumHeight"					Name="Camera Image Maximum Height"  
+(0029,004C) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraImageMinimumHeight"					Name="Camera Image Minimum Height"  
+(0029,004D) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ParallelShiftIntervalMM"					Name="Parallel Shift Interval MM"  
+(0029,004E) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ParallelShiftBoundingBoxMinimum"			Name="Parallel Shift BoundingBox Minimum"  
+(0029,004F) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ParallelShiftBoundingBoxMaximum"			Name="Parallel Shift BoundingBox Maximum"  
+(0029,0050) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererVertexIsCharacteristicFlag"		Name="Renderer Vertex Is Characteristic Flag"
+(0029,0051) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererThicknessUsageFlag"				Name="Renderer Thickness Usage Flag"  
+(0029,0052) VERS="SSPI" VR="DS"   VM="4"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererThreshold"							Name="Renderer Threshold"  
+(0029,0053) VERS="SSPI" VR="DS"   VM="4"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererMaterial"							Name="Renderer Material"  
+(0029,0054) VERS="SSPI" VR="DS"   VM="4"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererDirectionalLightColor"				Name="Renderer DirectionalLight Color"  
+(0029,0055) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererDirectionalLightDirection"			Name="Renderer DirectionalLight Direction"  
+(0029,0056) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererDirectionalLightTwoSideUsageFlag"	Name="Renderer DirectionalLight TwoSide Usage Flag"  
+(0029,0057) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererPWLTransferFunctionSequence"		Name="Renderer PWL TransferFunction Sequence"  
+(0029,0058) VERS="SSPI" VR="IS"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererPWLVertexIndex"					Name="Renderer PWL Vertex Index"  
+(0029,0059) VERS="SSPI" VR="DS"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererPWLVertexColor"					Name="Renderer PWL Vertex Color"  
+(0029,005A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererIsCameraRequiredFlag"				Name="Renderer Is Camera Required Flag"  
+(0029,005B) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererDoDepthTestFlag"					Name="Renderer Do Depth Test Flag "  
+(0029,005C) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererDirectionalLightUsageFlag"			Name="Renderer Directional Light Usage Flag"  
+(0029,005D) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererThicknessSequence"					Name="Renderer Thickness Sequence"  
+(0029,005E) VERS="SSPI" VR="SQ"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererSliceSpacingSequence"				Name="Renderer Slice Spacing Sequence"
+(0029,005F) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererSamplingDistance"					Name="Renderer Sampling Distance"
+(0029,0060) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RendererInitialSamplingDistance"			Name="Renderer Initial Sampling Distance"
+(0029,0061) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayDataSequence"			Name="Segmentation Display Data Sequence"  
+(0029,0062) VERS="SSPI" VR="UI"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayDataUID"				Name="Segmentation Display Data UID"  
+(0029,0063) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayParameterSequence"		Name="Segmentation Display Parameter Sequence"  
+(0029,0064) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayParameterType"			Name="Segmentation Display Parameter Type"  
+(0029,0065) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayVisibility"				Name="Segmentation Display Visibility"  
+(0029,0066) VERS="SSPI" VR="DS"   VM="4"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayColor"					Name="Segmentation Display Color"  
+(0029,0067) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationDisplayIsSelectedFlag"			Name="Segmentation Display is Selected Flag "  
+(0029,0068) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationAdditionalInformationBlob"		Name="Segmentation Additional Information Blob"
+(0029,0069) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="HashCodeValue"								Name="Hash Code Value"
+(0029,006A) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationVersionIdentifier"				Name="Segmentation Version Identifier"
+(0029,0070) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationVolumeSize"					Name="Segmentation Volume Size"
+(0029,0071) VERS="SSPI" VR="UI"   VM="1-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RegistrationReferencedFrames"				Name="Registration Referenced Frames"  
+(0029,0072) VERS="SSPI" VR="UI"   VM="1-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RegistrationReferencedRegistrations"		Name="Registration Referenced Registrations"
+(0029,0073) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="RegistrationCreationAlgorithmName"			Name="Registration Creation Algorithm Name"
+(0029,0074) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ECGGraphicType"							Name="ECG Graphic Type"
+(0029,007A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationVolumeStorageDataType"			Name="Segmentation Volume Storage Data Type"
+(0029,007B) VERS="SSPI" VR="FL"   VM="16"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SegmentationVolumeModelMatrix"				Name="Segmentation Volume Model Matrix"
+(0029,0080) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraRotationAxis"						Name="Camera Rotation Axis"
+(0029,0081) VERS="SSPI" VR="SL"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="OverlayHiddenDisplayAttributes"			Name="Overlay Hidden Display Attributes"
+(0029,0082) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationStateGroupIdentifier"			Name="Presentation State Group Identifier"
+(0029,0083) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TemporarySmallestImagePixelValue"			Name="Temporary Smallest Image Pixel Value"
+(0029,0084) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraRotationCenter"						Name="Camera Rotation Center"  
+(0029,0085) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraRotationCenterUsageFlag"				Name="Camera Rotation Center Usage Flag"  
+(0029,0086) VERS="SSPI" VR="DS"   VM="12"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraParallelEpiped"						Name="Camera Parallel Epiped"  
+(0029,0087) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraMaxZoomInFactor"						Name="Camera Max Zoom In Factor"
+(0029,0088) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraMinZoomInFactor"						Name="Camera Min Zoom In Factor"
+(0029,0089) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TemporaryLargestImagePixelValue"			Name="Temporary Largest Image Pixel Value"
+(0029,008A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CameraRotationAxisUsageFlag"				Name="Camera Rotation Axis Usage Flag"
+(0029,008B) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementSurfaceNormal"					Name="Measurement Surface Normal"
+(0029,008C) VERS="SSPI" VR="FL"   VM="16"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEllipsoidModelMatrix"			Name="Measurement Ellipsoid Model Matrix"
+(0029,008D) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationDataRoleID"			Name="Measurement Evaluation DataRole ID"
+(0029,008E) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementAlgorithmType"					Name="Measurement Algorithm Type"
+(0029,0091) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationDataRoleSequence"		Name="Measurement Evaluation DataRole Sequence"  
+(0029,0092) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationDataRoleItem"			Name="Measurement Evaluation DataRole Item"  
+(0029,0093) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationSequence"				Name="Measurement Evaluation Sequence"  
+(0029,0094) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationValue"				Name="Measurement Evaluation Value"  
+(0029,0095) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationID"					Name="Measurement Evaluation ID"  
+(0029,0096) VERS="SSPI" VR="FL"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDataPoints"						Name="Measurement Data Points"  
+(0029,0097) VERS="SSPI" VR="FL"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDataAngles"						Name="Measurement Data Angles"  
+(0029,0098) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDataSlice"						Name="Measurement Data Slice"  
+(0029,0099) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDataSliceThickness"				Name="Measurement Data Slice Thickness"  
+(0029,009A) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementReferencedFramesSequence"		Name="Measurement Referenced Frames Sequence"  
+(0029,009B) VERS="SSPI" VR="DS"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationLongestDistance"		Name="Measurement Evaluation Longest Distance"  
+(0029,009C) VERS="SSPI" VR="DS"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationCentroid"				Name="Measurement Evaluation Centroid"  
+(0029,009D) VERS="SSPI" VR="FL"   VM="6"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDataBoundingBox"				Name="Measurement Data Bounding Box "  
+(0029,009E) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementText"							Name="Measurement Text"
+(0029,009F) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementDiameter"						Name="Measurement Diameter"
+(0029,00A0) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageRotationFractional"					Name="Image Rotation Fractional"  
+(0029,00A1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresetName"								Name="Preset Name"
+(0029,00A2) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="FusionLUTSequence"							Name="Fusion LUT Sequence"
+(0029,00A3) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="FusionLUTIsActiveFlag"						Name="Fusion LUT Is Active Flag"
+(0029,00A5) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SyngoUID"									Name="Syngo UID"
+(0029,00A6) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationVersionIdentifier"				Name="Presentation Version Identifier"  
+(0029,00A7) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationModuleSequence"				Name="Presentation Module Sequence"  
+(0029,00A8) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationModuleType"					Name="Presentation Module Type"  
+(0029,00A9) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="PresentationStateSequence"					Name="Presentation State Sequence" 
+(0029,00AA) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="LUTInvertedFlag"							Name="LUT Inverted Flag"
+(0029,00AB) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="SoftcopyVOILUTViewingIndex"				Name="Softcopy VOI LUT Viewing Index"
+(0029,00AC) VERS="SSPI" VR="FD"   VM="2"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="DisplayedAreaBottomRightHandCornerFractional"	Name="Displayed Area Bottom Right Hand Corner Fractional"
+(0029,00AD) VERS="SSPI" VR="FD"   VM="2"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="DisplayedAreaTopLeftHandCornerFractional"	Name="Displayed Area Top Left Hand Corner Fractional"
+(0029,00AE) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementAlpha"							Name="Measurement Alpha"
+(0029,00AF) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementBitmap"							Name="Measurement Bitmap"
+(0029,00B0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurrentFrameNumber"						Name="Current Frame Number"
+(0029,00B1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageTextViewName"							Name="Image Text View Name"
+(0029,00B2) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageTextViewContentSequence"				Name="Image Text View Content Sequence"
+(0029,00B3) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageTextLineNames"						Name="Image Text Line Names"
+(0029,00B4) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageTextLineValues"						Name="ImageText Line Values"
+(0029,00B5) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationTextPositionSequence"	Name="Measurement Evaluation Text Position Sequence"
+(0029,00B6) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementLinkEvaluationTextFlag"			Name="Measurement Link Evaluation Text Flag"
+(0029,00B7) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementEvaluationTextPositionVector"	Name="Measurement Evaluation Text Position Vector"
+(0029,00B8) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageTextAlphaBlendingLineValue"			Name="Image Text Alpha Blending Line Value"
+(0029,00C1) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TaskDataSequence"							Name="Task Data Sequence"
+(0029,00C2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TaskDataType"								Name="Task Data Type"
+(0029,00C3) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TaskDataVersion"							Name="Task Data Version"
+(0029,00C4) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TaskDataDescription"						Name="Task Data Description"
+(0029,00C5) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TaskData"									Name="Task Data"
+(0029,00C6) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="TaskDataSize"								Name="Task Data Size"
+(0029,00C9) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneSequence"							Name="Clip Plane Sequence"
+(0029,00CA) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneCenter"							Name="Clip Plane Center"
+(0029,00CB) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneNormal"							Name="Clip Plane Normal"
+(0029,00CC) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneScale"							Name="Clip Plane Scale"
+(0029,00CD) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneUseThicknessFlag"					Name="Clip Plane Use Thickness Flag"
+(0029,00CE) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneThickness"						Name="Clip Plane Thickness"
+(0029,00CF) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ImageSequence"								Name="Image Sequence"
+(0029,00D0) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneEnableClip"						Name="Clip Plane Enable Clip"
+(0029,00D1) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneHandleRatio"						Name="Clip Plane Handle Ratio"
+(0029,00D2) VERS="SSPI" VR="DS"   VM="24"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneBoundingPoints"					Name="Clip Plane Bounding Points"
+(0029,00D3) VERS="SSPI" VR="DS"   VM="16"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneMotionMatrix"						Name="Clip Plane Motion Matrix"
+(0029,00D4) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneShiftVelocity"					Name="Clip Plane Shift Velocity"
+(0029,00D5) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneEnabledFlag"						Name="Clip Plane Enabled Flag"
+(0029,00D6) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneRotateVelocity"					Name="Clip Plane Rotate Velocity"
+(0029,00D7) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClipPlaneShowGraphicsFlag"					Name="Clip Plane Show Graphics Flag"
+(0029,00E0) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CropBoxSize"								Name="Crop Box Size"
+(0029,00E1) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CropBoxEnabledFlag"						Name="Crop Box Enabled Flag"
+(0029,00E2) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CropBoxAbsoluteOrigin"						Name="Crop Box Absolute Origin"
+(0029,00E3) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CropBoxShowGraphicsFlag"					Name="Crop Box Show Graphics Flag"
+(0029,00F1) VERS="SSPI" VR="DS"   VM="0-n"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraCoordinates"					Name="Curved Camera Coordinates"
+(0029,00F2) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraPointOfInterest"				Name="Curved Camera Point of Interest"
+(0029,00F3) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraPointOfInterestUsageFlag"		Name="Curved Camera Point of Interest Usage Flag"
+(0029,00F4) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraThickness"						Name="Curved Camera Thickness"
+(0029,00F5) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraExtrusionLength"				Name="Curved Camera Extrusion Length"
+(0029,00F6) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraRotationAxisMode"				Name="Curved Camera Rotation Axis Mode"
+(0029,00F7) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraRollRotationAxis"				Name="Curved Camera Roll Rotation Axis"
+(0029,00F8) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraViewPortHeight"				Name="Curved Camera View Port Height"
+(0029,00F9) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraCutDirection"					Name="Curved Camera Cut Direction"
+(0029,00FA) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="CurvedCameraPanVector"						Name="Curved Camera Pan Vector"
+(0029,00FB) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="ClinicalFindingID"							Name="Clinical Finding ID"
+(0029,00FC) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementIsCircleFlag"					Name="Measurement Is Circle Flag"
+(0029,00FD) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ADVANCED PRESENTATION"		Keyword="MeasurementApplicationTypeID"				Name="Measurement Application Type ID"
+
+(0029,0010) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO FRAME SET"					Keyword="ImageFrameSequence"						Name="Image Frame Sequence"
+(0029,0012) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO FRAME SET"					Keyword="TypeOfProgression"							Name="Type of Progression"
+(0029,0014) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO FRAME SET"					Keyword="RepresentationLevel"						Name="Representation Level"
+(0029,0016) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO FRAME SET"					Keyword="RepresentationInformationSequence"			Name="Representation Information Sequence"  
+(0029,0018) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO FRAME SET"					Keyword="NumberOfRepresentations"					Name="Number of Representations"
+(0029,0020) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO FRAME SET"					Keyword="RepresentationPixelOffset"					Name="Representation Pixel Offset"  
+
+(0029,0010) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO PRINT SERVICE"				Keyword="SheetNumber"					Name="Sheet Number" 
+
+(0029,0001) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS IKM CKS LUNGCAD BMK"				Keyword="?"				Name="?"
+
+(0029,0001) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS IKM CKS CXRCAD FINDINGS"			Keyword="?"				Name="?"
+
+(0029,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CSA REPORT"						Keyword="ReportType"						Name="Report Type"
+(0029,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CSA REPORT"						Keyword="ReportVersion"						Name="Report Version"
+(0029,0015) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CSA REPORT"						Keyword="SRVariant"							Name="SR Variant"
+(0029,0017) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS CSA REPORT"						Keyword="SCSOP InstanceUID"					Name="SC SOP Instance UID"
+
+(0029,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CSA ENVELOPE"	Keyword="syngoReportData"			Name="syngo Report Data"
+(0029,0011) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CSA ENVELOPE"	Keyword="syngoReportPresentation"	Name="syngo Report Presentation"
+
+(0029,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ModalityImageHeaderType"							Name="Modality Image Header Type"
+(0029,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ModalityImageHeaderVersion"						Name="Modality Image Header Version"
+(0029,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ModalityImageHeaderInfo"							Name="Modality Image Header Info"
+
+(0031,0001) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,000c) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,000f) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="RequestUID"				Name="Request UID"
+(0031,0010) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0012) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ExaminationReason"			Name="Examination Reason"
+(0031,0012) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0013) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0014) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0015) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0016) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0017) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0020) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0021) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0031,0030) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS ISI"		Keyword="RequestedDate"				Name="Requested Date"
+(0031,0032) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="WorklistRequestStartTime"		Name="Worklist Request Start Time"
+(0031,0033) VERS="SSPI"	VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="WorklistRequestEndTime"		Name="Worklist Request End Time"
+(0031,0045) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="RequestingPhysician"			Name="Requesting Physician"
+(0031,004a) VERS="SSPI" VR="TM"   VM="1"	Owner="SIEMENS ISI"		Keyword="RequestedTime"				Name="Requested Time"
+(0031,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="RequestedPhysician"			Name="Requested Physician"
+(0031,0080) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="RequestedLocation"			Name="Requested Location"
+
+(0031,0010) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="SOPClassPackingSequence"			Name="SOP Class Packing Sequence"
+(0031,0020) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="PackingVersion"					Name="Packing Version"
+(0031,0021) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="PackingOriginator"					Name="Packing Originator"
+(0031,0030) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalSOPClassUID"				Name="Original SOP Class UID"
+(0031,0031) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalStudyInstanceUID"			Name="Original Study Instance UID"
+(0031,0032) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalSeriesInstanceUID"			Name="Original Series Instance UID"
+(0031,0033) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalSOPInstanceUID"			Name="Original SOP Instance UID"
+(0031,0034) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalTransferSyntaxUID"			Name="Original Transfer Syntax UID"
+(0031,0040) VERS="SSPI" VR="AT"   VM="1-n"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="AttributesToSetToZeroLength"		Name="Attributes to Set to Zero Length"
+(0031,0041) VERS="SSPI" VR="AT"   VM="1-n"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="AttributesToRemove"				Name="Attributes to Remove"
+(0031,0050) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalRows"						Name="Original Rows"
+(0031,0051) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalColumns"					Name="Original Columns"
+(0031,0058) VERS="SSPI" VR="CS"   VM="2-n"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalImageType"					Name="Original Image Type"
+(0031,0060) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="OriginalModality"					Name="Original Modality"
+(0031,0070) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="SequenceOfOriginalStreamChunks"	Name="Sequence of Original StreamCchunks"
+(0031,0071) VERS="SSPI" VR="AT"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="StartTagOfAStreamChunk"			Name="Start Tag of a Stream Chunk"
+(0031,0072) VERS="SSPI" VR="AT"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="EndTagOfAStreamChunk"				Name="End Tag of a Stream Chunk"
+(0031,0073) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="StreamChunkIsAPayload"				Name="Stream Chunk is a Payload"
+(0031,0080) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO SOP CLASS PACKING"	Keyword="StreamChunk"						Name="Stream Chunk"
+
+(0031,0010) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="InternalPatientUID"		Name="Internal Patient UID"
+(0031,0011) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="PatientsDeathIndicator"	Name="Patients Death Indicator"
+(0031,0012) VERS="SSPI" VR="DA"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="PatientsDeathDate"			Name="Patients Death Date"
+(0031,0013) VERS="SSPI" VR="TM"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="PatientsDeathTime"			Name="Patients Death Time"
+(0031,0014) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="VIPIndicator"				Name="VIP Indicator"
+(0031,0015) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="EmergencyFlag"				Name="Emergency Flag"
+(0031,0020) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="InternalVisitUID"			Name="Internal Visit UID"
+(0031,0025) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="InternalISRUID"			Name="Internal ISR UID"
+(0031,0032) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="ControlState"				Name="Control State"
+(0031,0034) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="LocalFlag"					Name="Local Flag"
+(0031,0036) VERS="SSPI" VR="UI"   VM="1-n"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="ReferencedStudies"			Name="Referenced Studies"
+(0031,0040) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkflowID"				Name="Workflow ID"
+(0031,0041) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkflowDescription"		Name="Workflow Description"
+(0031,0042) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkflowControlState"		Name="Workflow Control State"
+(0031,0043) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkflowAdHocFlag"			Name="Workflow Ad Hoc Flag"
+(0031,0044) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="HybridFlag"				Name="Hybrid Flag"
+(0031,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemID"				Name="Workitem ID"
+(0031,0051) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemName"				Name="Workitem Name"
+(0031,0052) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemType"				Name="Workitem Type"
+(0031,0053) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemRoles"				Name="Workitem Roles"
+(0031,0054) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemDescription"		Name="Workitem Description"
+(0031,0055) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemControlState"		Name="Workitem Control State"
+(0031,0056) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="ClaimingUser"				Name="Claiming User"
+(0031,0057) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="ClaimingHost"				Name="Claiming Host"
+(0031,0058) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="TaskflowID"				Name="Taskflow ID"
+(0031,0059) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="TaskflowName"				Name="Taskflow Name"
+(0031,005A) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="FailedFlag"				Name="Failed Flag"
+(0031,005B) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="ScheduledTime"				Name="Scheduled Time"
+(0031,005C) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="WorkitemAdHocFlag"			Name="Workitem Ad Hoc Flag"
+(0031,005D) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="PatientUpdatePendingFlag"	Name="Patient Update Pending Flag"
+(0031,005E) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="PatientMixupFlag"			Name="Patient Mixup Flag"
+(0031,0060) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="ClientID"					Name="Client ID"
+(0031,0061) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="TemplateID"				Name="Template ID"
+(0031,0081) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="InstitutionName"			Name="Institution Name"
+(0031,0082) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="InstitutionAddress"		Name="Institution Address"
+(0031,0083) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO WORKFLOW"	Keyword="InstitutionCodeSequence"	Name="Institution Code Sequence"
+
+(0033,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS RIS"		Keyword="PatientStudyUID"			Name="Patient Study UID"
+
+(0033,0000) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="FloodCorrectionMatrixDetector1"		Name="Flood Correction Matrix Detector 1"
+(0033,0001) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="FloodCorrectionMatrixDetector2"		Name="Flood Correction Matrix Detector 2"
+(0033,0010) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="CORDataForDetector1"					Name="COR Data for Detector 1"
+(0033,0011) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="CORDataForDetector2"					Name="COR Data for Detector 2"
+(0033,0014) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="MHRDataForDetector1"					Name="MHR ( Y-Shift) data for detector 1"
+(0033,0015) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="MHRDataForDetector2"					Name="MHR ( Y-Shift) data for detector 2"
+(0033,0018) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="NCODataForDetector1"					Name="NCO Data for detector 1"
+(0033,0019) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="NCODataForDetector2"					Name="NCO Data for detector 2"
+(0033,001A) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="?"										Name="?"
+(0033,0020) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="BedCorrectionAngle"					Name="Bed correction angle"
+(0033,0021) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="GantryCorrectionAngle"					Name="Gantry correction angle"
+(0033,0022) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="BedUDCorrectionData"					Name="Bed U/D correction data"
+(0033,0023) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="GantryLRCorrectionData"				Name="Gantry L/R Correction Data"
+(0033,0024) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="BackProjectionCorrectionAngleHead1"	Name="BackProjection Correction angle head 1"
+(0033,0025) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="BackProjectionCorrectionAngleHead2"	Name="BackProjection Correction angle head 2"
+(0033,0028) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="MHRCalibrations"						Name="MHR calibrations"
+(0033,0029) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="CrystalThickness"						Name="Crystal thickness"
+(0033,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="PresetNameUsedForAcquisition"			Name="Preset name used for acquisition"
+(0033,0031) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="CameraConfigAngle"						Name="Camera Config Angle"
+(0033,0032) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="CrystalType"							Name="Crystal Type"
+(0033,0033) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="CoinGantryStep"						Name="Coin Gantry Step"
+(0033,0034) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="WholebodyBedStep"						Name="Wholebody bed step"
+(0033,0035) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="WeightFactorTableForCoincidenceAcquisitions"		Name="Weight Factor Table For Coincidence Acquisitions"
+(0033,0036) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="CoincidenceWeightFactorTable"			Name="Coincidence weight factor table"
+(0033,0037) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="StarburstFlagsAtImageAcqTime"			Name="Starburst flags at image acq time"
+(0033,0038) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="PixelScaleFactor"						Name="Pixel Scale factor"
+
+(0035,0000) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="SpecializedTomoType"								Name="Specialized Tomo Type"
+(0035,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="EnergyWindowType"									Name="Energy Window Type"
+(0035,0002) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="StartandEndRowIlluminatedByWindPosition"			Name="Start and End Row Illuminated By Wind Position"
+(0035,0003) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="BlankScanImageForProfile"							Name="Blank Scan Image For Profile"
+(0035,0004) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="RepeatNumberOfTheOriginalDynamicSPECT"				Name="Repeat Number of the Original Dynamic SPECT"
+(0035,0005) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="PhaseNumberOfTheOriginalDynamicSPECT"				Name="Phase Number of the Original Dynamic SPECT"
+(0035,0006) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="SiemensProfile2ImageSubtype"						Name="Siemens Profile 2 Image Subtype"
+
+(0037,0000) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="FloodCorrectionMatrixDetector1"		Name="Flood correction matrix Detector 1"
+(0037,0080) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="FloodCorrectionMatrixDetector2"		Name="Flood correction matrix Detector 2"
+
+(0039,0000) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ToshibaCBFActivityResults"							Name="Toshiba CBF Activity Results"
+(0039,0001) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED NM"		Keyword="RelatedCTSeriesInstanceUID"						Name="Related CT Series Instance UID"
+
+(0041,0002) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"		Keyword="ReasonForTheRequestedProcedure"	Name="Reason for the Requested Procedure"
+
+(0041,0001) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="WholeBodyTomoPositionIndex"						Name="Whole Body Tomo Position Index"
+(0041,0002) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="WholeBodyTomoNumberOfPositions"					Name="Whole Body Tomo Number of Positions"
+(0041,0003) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="HorizontalTablePositionOfCTScan"					Name="Horizontal Table Position of CT scan"
+(0041,0004) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="EffectiveEnergyOfCTScan"							Name="Effective Energy fo CT Scan"
+(0041,0005) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="LongLinearDriveInformationForDetector1"			Name="Long Linear Drive Information for Detector 1"
+(0041,0006) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="LongLinearDriveInformationForDetector2"			Name="Long Linear Drive Information for Detector 2"
+(0041,0007) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="TrunnionInformationForDetector1"					Name="Trunnion Information for Detector 1"
+(0041,0008) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="TrunnionInformationForDetector2"					Name="Trunnion Information for Detector 2"
+(0041,0009) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="BroadBeamFactor"									Name="Broad Beam Factor"
+(0041,000A) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED NM"		Keyword="OriginalWholebodyPosition"							Name="Original Wholebody Position"
+(0041,000B) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED NM"		Keyword="WholebodyScanRange"								Name="Wholebody Scan Range"
+(0041,0010) VERS="SSPI" VR="FL"   VM="1-3"	Owner="SIEMENS MED NM"		Keyword="EffectiveEmissionEnergy"							Name="Effective Emission Energy"
+(0041,0011) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="GatedFrameDuration"								Name="Gated Frame Duration"
+(0041,0030) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"													Name="?"
+(0041,0032) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"													Name="?"
+
+(0041,0010) VERS="SSPI"	VR="US"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="NumberOfHardcopies"								Name="Number of Hardcopies"
+(0041,0020) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="FilmFormat"										Name="Film Format"
+(0041,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="FilmSize"											Name="Film Size"
+(0041,0031) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS DLR.01"		Keyword="FullFilmFormat"									Name="Full Film Format"
+
+(0041,0001) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MI RWVM SUV"	Keyword="SUVDecayCorrectionMethod"							Name="SUV Decay Correction Method"
+
+(0043,0001) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="DetectorViewAngle"									Name="Detector View Angle"
+(0043,0002) VERS="SSPI" VR="FD"   VM="1-16"	Owner="SIEMENS MED NM"		Keyword="TransformationMatrix"								Name="Transformation Matrix"
+(0043,0003) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ViewDependentYShiftMHRForDetector1"				Name="View Dependent Y Shift MHR For Detector 1"
+(0043,0004) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ViewDependentYShiftMHRForDetector2"				Name="View Dependent Y Shift MHR For Detector 2"
+
+(0045,0001) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="PlanarProcessingString"							Name="Planar Processing String"
+
+(0051,0010) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageText"				Name="Image Text"
+
+(0051,0010) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="?"									Name="?"
+(0051,0037) VERS="SSPI" VR="DS"   VM="6"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="?"									Name="?"
+(0051,0050) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="?"									Name="?"
+(0051,0060) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="PrimaryPositionerScanArc"			Name="Primary Positioner Scan Arc"
+(0051,0061) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="SecondaryPositionerScanArc"		Name="Secondary Positioner Scan Arc"
+(0051,0062) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="PrimaryPositionerScanStartAngle"	Name="Primary Positioner Scan Start Angle"
+(0051,0063) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="SecondaryPositionerScanStartAngle"	Name="Secondary Positioner Scan Start Angle"
+(0051,0064) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="PrimaryPositionerIncrement"		Name="Primary Positioner Increment"
+(0051,0065) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="SecondaryPositionerIncrement"		Name="Secondary Positioner Increment"
+
+(0055,0004) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="PromptWindowWidth"									Name="Prompt Window Width"
+(0055,0005) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="RandomWindowWidth"									Name="Random Window Width"
+(0055,0020) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0022) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0024) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0030) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0032) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0034) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0040) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0042) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0044) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,004c) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,004d) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0051) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0052) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0053) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,0055) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,005c) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,006d) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,007e) VERS="SSPI" VR="FL"   VM="2"	Owner="SIEMENS MED NM"		Keyword="CollimatorThickness"								Name="Collimator Thickness mm"
+(0055,007f) VERS="SSPI" VR="FL"   VM="2"	Owner="SIEMENS MED NM"		Keyword="CollimatorAngularResolution"						Name="Collimator Angular Resolution radians"
+(0055,00a8) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,00C0) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="UsefulFieldOfView"									Name="Useful Field of View"
+(0055,00c2) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,00c3) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,00c4) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(0055,00d0) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+
+(0055,0046) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="CurrentWard"				Name="Current Ward"
+(0055,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SP DXMG WH AWS 1"	Keyword="ProjectionViewDisplayString"	Name="Projection View Display String"
+
+(0057,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="SyngoMIDICOMOriginalImageType"						Name="Syngo MI DICOM Original Image Type"
+(0057,0002) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="DoseCalibrationFactor"								Name="Dose Calibration Factor"
+(0057,0003) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="Units"												Name="Units"
+(0057,0004) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="DecayCorrection"									Name="Decay Correction"
+(0057,0005) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="RadionuclideHalfLife"								Name="Radionuclide Half Life"
+(0057,0006) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="RescaleIntercept"									Name="Rescale Intercept"
+(0057,0007) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="RescaleSlope"										Name="Rescale Slope"
+(0057,0008) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="FrameReferenceTime"								Name="Frame Reference Time"
+(0057,0009) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="NumberofRadiopharmaceuticalInformationSequence"	Name="Number of Radiopharmaceutical Information Sequence"
+(0057,000A) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="DecayFactor"										Name="Decay Factor"
+(0057,000B) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="CountsSource"										Name="Counts Source"
+(0057,000C) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="RadionuclidePositronFraction"						Name="Radionuclide Positron Fraction"
+(0057,000E) VERS="SSPI" VR="US"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="TriggerTimeOfCTSlice"								Name="Trigger Time of CT Slice"
+
+(0061,0001) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="XPrincipalRayOffset"								Name="X Principal Ray Offset"
+(0061,0005) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="YPrincipalRayOffset"								Name="Y Principal Ray Offset"
+(0061,0009) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="XPrincipalRayAngle"								Name="X Principal Ray Angle"
+(0061,000A) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="YPrincipalRayAngle"								Name="Y Principal Ray Angle"
+(0061,000B) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="XShortFocalLength"									Name="X Short Focal Length"
+(0061,000C) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="YShortFocalLength"									Name="Y Short Focal Length"
+(0061,000D) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="XLongFocalLength"									Name="X Long Focal Length"
+(0061,000E) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="YLongFocalLength"									Name="Y Long Focal Length"
+(0061,000F) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="XFocalScaling"										Name="X Focal Scaling"
+(0061,0010) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="YFocalScaling"										Name="Y Focal Scaling"
+(0061,0011) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="XMotionCorrectionShift"							Name="X Motion Correction Shift"
+(0061,0015) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="YMotionCorrectionShift"							Name="Y Motion Correction Shift"
+(0061,0019) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="XHeartCenter"										Name="X Heart Center"
+(0061,001A) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="YHeartCenter"										Name="Y Heart Center"
+(0061,001B) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ZHeartCenter"										Name="Z Heart Center"
+(0061,001C) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ImagePixelContentType"								Name="Image Pixel Content Type"
+(0061,001D) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED NM"		Keyword="AutoSaveCorrectedSeries"							Name="Auto Save Corrected Series"
+(0061,001E) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED NM"		Keyword="DistortedSeriesInstanceUID"						Name="Distorted Series Instance UID"
+(0061,0021) VERS="SSPI" VR="SS"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ReconRange"										Name="Recon Range"
+(0061,0022) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconOrientation"									Name="Recon Orientation"
+(0061,0023) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ReconSelectedAngularRange"							Name="Recon Selected Angular Range"
+(0061,0024) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconTransverseAngle"								Name="Recon Transverse Angle"
+(0061,0025) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconSagittalAngle"								Name="Recon Sagittal Angle"
+(0061,0026) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconXMaskSize"									Name="Recon X Mask Size"
+(0061,0027) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconYMaskSize"									Name="Recon Y Mask Size"
+(0061,0028) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconXImageCenter"									Name="Recon X Image Center"
+(0061,0029) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconYImageCenter"									Name="Recon Y Image Center"
+(0061,002A) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconZImageCenter"									Name="Recon Z Image Center"
+(0061,002B) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconXZoom"										Name="Recon X Zoom"
+(0061,002C) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconYZoom"										Name="Recon Y Zoom"
+(0061,002D) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconThreshold"									Name="Recon Threshold"
+(0061,002E) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconOutputPixelSize"								Name="Recon Output Pixel Size"
+(0061,002F) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ScatterEstimationMethod"							Name="Scatter Estimation Method"
+(0061,0030) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ScatterEstimationMethodMode"						Name="Scatter Estimation Method Mode"
+(0061,0031) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ScatterEstimationLowerWindowWeights"				Name="Scatter Estimation Lower Window Weights"
+(0061,0032) VERS="SSPI" VR="FL"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ScatterEstimationUpperWindowWeights"				Name="Scatter Estimation Upper Window Weights"
+(0061,0033) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ScatterEstimationWindowMode"						Name="Scatter Estimation Window Mode"
+(0061,0034) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MED NM"		Keyword="ScatterEstimationFilter"							Name="Scatter Estimation Filter"
+(0061,0035) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconRawTomoInputUID"								Name="Recon RawTomo Input UID"
+(0061,0036) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconCTInputUID"									Name="Recon CT Input UID"
+(0061,0037) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconZMaskSize"									Name="Recon Z Mask Size"
+(0061,0038) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconXMaskCenter"									Name="Recon X Mask Center"
+(0061,0039) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconYMaskCenter"									Name="Recon Y Mask Center"
+(0061,003A) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MED NM"		Keyword="ReconZMaskCenter"									Name="Recon Z Mask Center"
+(0061,0051) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED NM"		Keyword="RawTomoSeriesUID"									Name="Raw Tomo Series UID"
+(0061,0052) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED NM"		Keyword="LowResCTSeriesUID"									Name="LowRes CT Series UID"
+(0061,0053) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED NM"		Keyword="HighResCTSeriesUID"								Name="HighRes CT Series UID"
+
+(0071,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS WH SR 1.0"	Keyword="?"					Name="?"
+(0071,0002) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS WH SR 1.0"	Keyword="?"					Name="?"
+
+(0071,0021) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS MED PT"				Keyword="RegistrationMatrixUID"						Name="Registration Matrix UID"
+(0071,0022) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS MED PT"				Keyword="DecayCorrectionDateTime"					Name="Decay Correction DateTime"
+(0071,0023) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED PT"				Keyword="VolumeIndex"								Name="Volume Index"
+(0071,0024) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED PT"				Keyword="TimeSliceDuration"							Name="Time Slice Duration"
+
+(0071,0046) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED PT WAVEFORM"		Keyword="StartingRespiratoryAmplitude"				Name="Starting Respiratory Amplitude"
+(0071,0047) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED PT WAVEFORM"		Keyword="StartingRespiratoryPhase"					Name="Starting Respiratory Phase"
+(0071,0048) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED PT WAVEFORM"		Keyword="EndingRespiratoryAmplitude"				Name="Ending Respiratory Amplitude"
+(0071,0049) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED PT WAVEFORM"		Keyword="EndingRespiratoryPhase"					Name="Ending Respiratory Phase"
+(0071,0050) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED PT WAVEFORM"		Keyword="RespiratoryTriggerType"					Name="Respiratory Trigger Type"
+
+(0071,0020) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO REGISTRATION"						Keyword="RegisteredImageSequence"			Name="Registered Image Sequence"
+(0071,0021) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO REGISTRATION"						Keyword="RegistrationIsValidatedFlag"		Name="Registration Is Validated Flag"
+
+(0071,0000) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicObjectSequence"			Name="Graphic Object Sequence"
+(0071,0001) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="FillStyleVersion"				Name="Fill Style Version"
+(0071,0002) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="FillBackgroundColor"			Name="Fill Background Color"
+(0071,0003) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="FillForegroundColor"			Name="Fill Foreground Color"
+(0071,0004) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="FillMode"						Name="Fill Mode"
+(0071,0005) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="FillPattern"					Name="Fill Pattern"
+(0071,0006) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineStyleVersion"				Name="Line Style Version"
+(0071,0007) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineBackgroundColor"			Name="Line Background Color"
+(0071,0008) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineForegroundColor"			Name="Line Foreground Color"
+(0071,0009) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineType"						Name="Line Type"
+(0071,0010) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineThickness"					Name="Line Thickness"
+(0071,0011) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineShadowXOffset"				Name="Line Shadow X Offset"
+(0071,0012) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineShadowYOffset"				Name="Line Shadow Y Offset"
+(0071,0013) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="ShadowStyle"					Name="Shadow Style"
+(0071,0014) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="ShadowColor"					Name="Shadow Color"
+(0071,0015) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="StipplePattern"				Name="Stipple Pattern"
+(0071,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineAntiAliasing"				Name="Line Anti Aliasing"
+(0071,0017) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="Line-Z-BlendFlag"				Name="Line-Z-Blend Flag"
+(0071,0018) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextStyleVersion"				Name="Text Style Version"
+(0071,0019) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextColor"						Name="Text Color"
+(0071,0020) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextHorizontalAlign"			Name="Text Horizontal Align"
+(0071,0021) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextVerticalAlign"				Name="Text Vertical Align"
+(0071,0022) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextShadowXOffset"				Name="Text Shadow X Offset"
+(0071,0023) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextShadowYOffset"				Name="Text Shadow Y Offset"
+(0071,0024) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextShadowStyle"				Name="Text Shadow Style"
+(0071,0025) VERS="SSPI" VR="FL"   VM="4"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextShadowColor"				Name="Text Shadow Color"
+(0071,0026) VERS="SSPI" VR="CS"   VM="1-n"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextLogFont"					Name="Text Log Font"
+(0071,0027) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="Text-Z-BlendFlag"				Name="Text-Z-Blend Flag"
+(0071,0028) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicBitMask"				Name="Graphic Bit Mask"
+(0071,0029) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="VisiblilityFlag"				Name="Visiblility Flag"
+(0071,0030) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicSensitivity"			Name="Graphic Sensitivity"
+(0071,0031) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicPickModeType"			Name="Graphic Pick Mode Type"
+(0071,0032) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicLayer"					Name="Graphic Layer"
+(0071,0033) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicObjectVersion"			Name="Graphic Object Version"
+(0071,0034) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicCoordinateSystem"		Name="Graphic Coordinate System"
+(0071,0035) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicCustomAttributes"		Name="Graphic Custom Attributes"
+(0071,0036) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicCustomAttributesKey"	Name="Graphic Custom Attributes Key"
+(0071,0037) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicCustomAttributesValue"	Name="Graphic Custom Attributes Value"
+(0071,0038) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicViewName"				Name="Graphic View Name"
+(0071,0039) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicData"					Name="Graphic Data"
+(0071,0040) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicType"					Name="Graphic Type"
+(0071,0041) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="NumberOfGraphicPoints"			Name="Number of Graphic Points"
+(0071,0042) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisMainTickLength"			Name="Axis Main Tick Length"
+(0071,0043) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisDetailTickLength"			Name="Axis Detail Tick Length"
+(0071,0044) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisMainTickSpacing"			Name="Axis Main Tick Spacing"
+(0071,0045) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisDetailTickSpacing"			Name="Axis Detail Tick Spacing"
+(0071,0046) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisMainTickCount"				Name="Axis Main Tick Count"
+(0071,0047) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisDetailTickCount"			Name="Axis Detail Tick Count"
+(0071,0048) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisTickBehavior"				Name="Axis Tick Behavior"
+(0071,0049) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisTickAligment"				Name="Axis Tick Aligment"
+(0071,0050) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisStep"						Name="Axis Step"
+(0071,0051) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisStepIndex"					Name="Axis Step Index"
+(0071,0052) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisTextFormat"				Name="Axis Text Format"
+(0071,0053) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisShowCenterTextFlag"		Name="Axis Show Center Text Flag"
+(0071,0054) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisShowTickTextFlag"			Name="Axis Show Tick Text Flag"
+(0071,0055) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="BitmapXOrientation"			Name="Bitmap X Orientation"
+(0071,0056) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="BitmapYOrientation"			Name="Bitmap Y Orientation"
+(0071,0057) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicBlob"					Name="Graphic Blob"
+(0071,0058) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicInterpolation"			Name="Graphic Interpolation"
+(0071,0059) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicAngle"					Name="Graphic Angle"
+(0071,0060) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicSize"					Name="Graphic Size"
+(0071,0061) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CutLineSide"					Name="Cut Line Side"
+(0071,0062) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicTipLength"				Name="Graphic Tip Length"
+(0071,0063) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CutLineArrowLength"			Name="Cut Line Arrow Length"
+(0071,0064) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineGapLength"					Name="Line Gap Length"
+(0071,0065) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicCircleRadius"			Name="Graphic Circle Radius"
+(0071,0066) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineDistanceMove"				Name="Line Distance Move"
+(0071,0067) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LineMarkerLength"				Name="Line Marker Length"
+(0071,0068) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicCenter"					Name="Graphic Center"
+(0071,0069) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeCenterAreaTopLeft"		Name="Range Center Area Top Left"
+(0071,0070) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeCenterAreaBottomRight"	Name="Range Center Area Bottom Right"
+(0071,0071) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeTilt"						Name="Range Tilt"
+(0071,0072) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeMinimumTilt"				Name="Range Minimum Tilt"
+(0071,0073) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeMaximumTilt"				Name="Range Maximum Tilt"
+(0071,0074) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicWidth"					Name="Graphic Width"
+(0071,0075) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeMinimumWidth"				Name="Range Minimum Width"
+(0071,0076) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeMaximumWidth"				Name="Range Maximum Width"
+(0071,0077) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicHeight"					Name="Graphic Height"
+(0071,0078) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeFeed"						Name="Range Feed"
+(0071,0079) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeDirection"				Name="Range Direction"
+(0071,0080) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeShowScans"				Name="Range Show Scans"
+(0071,0081) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeMinimumScanDistance"		Name="Range Minimum Scan Distance"
+(0071,0082) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeOrthogonalHeight"			Name="Range Orthogonal Height"
+(0071,0083) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicPosition"				Name="Graphic Position"
+(0071,0084) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicClosedFlag"				Name="Graphic Closed Flag"
+(0071,0085) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RangeLineTipMode"				Name="Range Line Tip Mode"
+(0071,0086) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicListCount"				Name="Graphic List Count"
+(0071,0087) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisFlipTextFlag"				Name="Axis Flip Text Flag"
+(0071,0088) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CurveDiagramType"				Name="Curve Diagram Type"
+(0071,0089) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicStartAngle"				Name="Graphic Start Angle"
+(0071,0090) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicEndAngle"				Name="Graphic End Angle"
+(0071,0091) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LiveWireSmoothness"			Name="Live Wire Smoothness"
+(0071,0092) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="LiveWireSplineFlag"			Name="Live Wire Spline Flag"
+(0071,0093) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="EllipseCircleFlag"				Name="Ellipse Circle Flag"
+(0071,0094) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicSquareFlag"				Name="Graphic Square Flag"
+(0071,0095) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CurveSectionStartIndex"		Name="Curve Section Start Index"
+(0071,0096) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CurveSectionEndIndex"			Name="Curve Section End Index"
+(0071,0097) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="MarkerAlpha"					Name="Marker Alpha"
+(0071,0098) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TableRowCount"					Name="Table Row Count"
+(0071,0099) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TableColumnCount"				Name="Table Column Count"
+(0071,009A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TableRowHeight"				Name="Table Row Height"
+(0071,009B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TableColumnWidth"				Name="Table Column Width"
+(0071,009C) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="RectangleSelectionSegmentOffset"	Name="Rectangle Selection Segment Offset"
+(0071,009D) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicText"					Name="Graphic Text"
+(0071,00A0) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisTickSpacingCoordinateSystem"	Name="Axis Tick Spacing Coordinate System"
+(0071,00A1) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisDiagramGridType"			Name="Axis Diagram Grid Type"
+(0071,00A2) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="PolarPlotCircleCount"			Name="Polar Plot Circle Count"
+(0071,00A3) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="PolarPlotLines-per-Circle"		Name="Polar Plot Lines-per-Circle"
+(0071,00A4) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="PolarPlotCompartmentCount"		Name="Polar Plot Compartment Count"
+(0071,00A5) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="PolarPlotRadiusWeight"			Name="Polar Plot Radius Weight"
+(0071,00A6) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CircleSegmentOuterRadius"		Name="Circle Segment Outer Radius"
+(0071,00A7) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="CircleSegmentClockwiseFlag"	Name="Circle Segment Clockwise Flag"
+(0071,00A8) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisDiagramAutoResizeFlag"		Name="Axis Diagram Auto Resize Flag"
+(0071,00A9) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="AxisDiagramStepStart"			Name="Axis Diagram Step Start"
+(0071,00B0) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GroupRoot"						Name="Group Root"
+(0071,00B1) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GroupName"						Name="Group Name"
+(0071,00B2) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicAnnotationSequence"		Name="Graphic Annotation Sequence"
+(0071,00B3) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextMinimumHeight"				Name="Text Minimum Height"
+(0071,00B4) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextFontScalingFactor"			Name="Text Font Scaling Factor"
+(0071,00B5) VERS="SSPI" VR="SL"   VM="2"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextMaximumExtensions"			Name="Text Maximum Extensions"
+(0071,00B6) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="TextSegmentSize"				Name="Text Segment Size"
+(0071,00B7) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS SYNGO OBJECT GRAPHICS"	Keyword="GraphicObjectReferenceLabel"	Name="Graphic Object Reference Label"
+
+(0073,0002) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="HangingProtocolExcellenceRank"		Name="Hanging Protocol Excellence Rank"
+(0073,0004) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TemplateDataRoleID"				Name="Template Data Role ID"
+(0073,0006) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataSharingFlag"					Name="Data Sharing Flag"
+(0073,0008) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="BaggingOperationsSequence"			Name="Bagging Operations Sequence"
+(0073,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SynchronizationType"				Name="Synchronization Type"
+(0073,0012) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomFilterType"					Name="Custom Filter Type"
+(0073,0014) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomSorterType"					Name="Custom Sorter Type"
+(0073,0016) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferenceTemplateDataRoleID"		Name="Reference Template Data Role ID"
+(0073,0018) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ModelTemplateDataRoleID"			Name="Model Template Data Role ID"
+(0073,0020) VERS="SSPI" VR="DT"   VM="1-n"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorDTValue"					Name="Selector DT Value"
+(0073,0022) VERS="SSPI" VR="DA"   VM="1-n"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorDAValue"					Name="Selector DA Value"
+(0073,0024) VERS="SSPI" VR="TM"   VM="1-n"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorTMValue"					Name="Selector TM Value"
+(0073,0026) VERS="SSPI" VR="UI"   VM="1-n"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorUIValue"					Name="Selector UI Value"
+(0073,0028) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferencedTemplateDataRole"		Name="Referenced Template Data Role"
+(0073,0030) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomPropertySequence"			Name="Custom Property Sequence"
+(0073,0032) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomPropertyType"				Name="Custom Property Type"
+(0073,0034) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomPropertyName"				Name="Custom Property Name"
+(0073,0036) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomPropertyValue"				Name="Custom Property Value"
+(0073,0038) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="LayoutPropertySequence"			Name="Layout Property Sequence"
+(0073,0040) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SynchronizationSequence"			Name="Synchronization Sequence"
+(0073,0042) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="PresentationCreatorType"			Name="Presentation Creator Type"
+(0073,0044) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CineNavigationType"				Name="Cine Navigation Type"
+(0073,0048) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SemanticNamingStrategy"			Name="Semantic Naming Strategy"
+(0073,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ParameterString"					Name="Parameter String"
+(0073,0052) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SortingOrder"						Name="Sorting Order"
+(0073,0054) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="syngoTemplateType"					Name="syngo Template Type"
+(0073,0056) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SorterType"						Name="Sorter Type"
+(0073,0058) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataDisplayProtocolVersion"		Name="Data Display Protocol Version"
+(0073,005A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TimepointValue"					Name="Timepoint Value"
+(0073,005B) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SharingGroupSequence"				Name="Sharing Group Sequence"
+(0073,005C) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TemplateSelectorOperator"			Name="Template Selector Operator"
+(0073,005D) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SharingType"						Name="Sharing Type"
+(0073,0060) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ViewportDefinitionsSequence"		Name="Viewport Definitions Sequence" 
+(0073,0062) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ProtocolType"						Name="Protocol Type"
+(0073,0064) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TemplateSelectorSequence"			Name="Template Selector Sequence"
+(0073,0066) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DefaultTemplate"					Name="Default Template"
+(0073,0068) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="IsPreferred"						Name="Is Preferred"
+(0073,006A) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TimepointInitialValueSequence"		Name="Timepoint Initial Value Sequence"
+(0073,006C) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TimepointVariable"					Name="Timepoint Variable"
+(0073,0070) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DisplayProtocolName"				Name="Display Protocol Name"
+(0073,0072) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DisplayProtocolDescription"		Name="Display Protocol Description"
+(0073,0074) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DisplayProtocolLevel"				Name="Display Protocol Level"
+(0073,0076) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DisplayProtocolCreator"			Name="Display Protocol Creator"
+(0073,0078) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DisplayProtocolCreationDatetime"	Name="Display Protocol Creation Datetime"
+(0073,007A) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferencedDataProtocol"			Name="Referenced Data Protocol"
+(0073,007C) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DisplayProtocolExcellenceRank"		Name="Display Protocol Excellence Rank"
+(0073,007E) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="LayoutSequence"					Name="Layout Sequence"
+(0073,0080) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="LayoutNumber"						Name="Layout Number"
+(0073,0082) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="LayoutDescription"					Name="Layout Description"
+(0073,0084) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentSequence"					Name="Segment Sequence"
+(0073,0086) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentNumber"						Name="Segment Number"
+(0073,0088) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentDescription"				Name="Segment Description"
+(0073,008A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentType"						Name="Segment Type"
+(0073,008C) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TileHorizontalDimension"			Name="Tile Horizontal Dimension"
+(0073,008E) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TileVerticalDimension"				Name="Tile Vertical Dimension"
+(0073,0090) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="FillOrder"							Name="Fill Order"
+(0073,0092) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentSmallScrollType"			Name="Segment Small Scroll Type"
+(0073,0094) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentSmallScrollAmount"			Name="Segment Small Scroll Amount"
+(0073,0096) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentLargeScrollType"			Name="Segment Large Scroll Type"
+(0073,0098) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentLargeScrollAmount"			Name="Segment Large Scroll Amount"
+(0073,009A) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SegmentOverlapPriority"			Name="Segment Overlap Priority"
+(0073,009C) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataRoleViewSequence"				Name="Data Role View Sequence"
+(0073,009E) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataRoleViewNumber"				Name="Data Role View Number"
+(0073,00A2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferencedDataRole"				Name="Referenced Data Role"
+(0073,00A4) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SharingEnabled"					Name="Sharing Enabled"
+(0073,00A8) VERS="SSPI" VR="US"   VM="2-n"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferencedDataRoleViews"			Name="Referenced Data Role Views"
+(0073,00B0) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolName"					Name="Data Protocol Name" 
+(0073,00B2) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolDescription"			Name="Data Protocol Description"
+(0073,00B4) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolLevel"					Name="Data Protocol Level"
+(0073,00B6) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolCreator"				Name="Data Protocol Creator"
+(0073,00B8) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolCreationDatetime"		Name="Data Protocol Creation Datetime"
+(0073,00BA) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolExcellenceRank"		Name="Data Protocol Excellence Rank"
+(0073,00BC) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProtocolDefinitionSequence"	Name="Data Protocol Definition Sequence"
+(0073,00BE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataRoleSequence"					Name="Data Role Sequence"
+(0073,00C0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataRoleNumber"					Name="Data Role Number"
+(0073,00C2) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataRoleName"						Name="Data Role Name"
+(0073,00C6) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorOperationsSequence"		Name="Selector Operations Sequence"
+(0073,00C8) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorUsageFlag"					Name="Selector Usage Flag"
+(0073,00CA) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectByAttributePresence"			Name="Select by Attribute Presence"
+(0073,00CC) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectByCategory"					Name="Select by Category"
+(0073,00CE) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectByOperator"					Name="Select by Operator"
+(0073,00D0) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomSelectorType"				Name="Custom Selector Type"
+(0073,00D2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="SelectorOperator"					Name="Selector Operator"
+(0073,00D4) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReformattingRequired"				Name="Reformatting Required"  
+(0073,00D6) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="RegistrationDataSequence"			Name="Registration Data Sequence"
+(0073,00D8) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferenceDataRoleNumber"			Name="Reference Data Role Number"
+(0073,00DA) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ModelDataSequence"					Name="Model Data Sequence"
+(0073,00DC) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ModelDataRoleNumber"				Name="Model Data Role Number"
+(0073,00DE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="FusionDisplaySequence"				Name="Fusion Display Sequence"
+(0073,00E0) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="Transparency"						Name="Transparency"
+(0073,00E2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TimePoint"							Name="Time Point"
+(0073,00E4) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="FirstTimePointToken"				Name="First Time Point Token"
+(0073,00E6) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="LastTimePointToken"				Name="Last Time Point Token"
+(0073,00E8) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="IntermediateTimePointToken"		Name="Intermediate Time Point Token"
+(0073,00EA) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProcessorSequence"				Name="Data Processor Sequence"
+(0073,00EC) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataProcessorType"					Name="Data Processor Type"
+(0073,00EE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="TemplateDataRoleSequence"			Name="Template Data Role Sequence"
+(0073,00F0) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ViewSequence"						Name="View Sequence"
+(0073,00F4) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ViewType"							Name="View Type"
+(0073,00F6) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="CustomBaggingType"					Name="Custom Bagging Type"
+(0073,00F8) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="ReferencedDisplaySegmentNumber"	Name="Referenced Display Segment Number"
+(0073,00FA) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="DataRoleType"						Name="Data Role Type"
+(0073,0046) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="InternalFlag"						Name="Internal Flag"
+(0073,00FC) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="UnassignedFlag"					Name="Unassigned Flag"
+(0073,00FE) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="InitialDisplayScrollPosition"		Name="Initial Display Scroll Position"
+(0073,00FF) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO LAYOUT PROTOCOL"		Keyword="VRTPreset"							Name="VRT Preset"
+
+(0091,0020) VERS="SSPI" VR="PN"   VM="1"	Owner="SIENET"			Keyword="RISPatientName"				Name="RIS Patient Name"
+(0093,0002) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"								Name="?"
+(0095,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="ExaminationFolderID"			Name="Examination Folder ID"
+(0095,0004) VERS="SSPI"	VR="UL"   VM="1"	Owner="SIENET"			Keyword="FolderReportedStatus"			Name="Folder Reported Status"
+(0095,0005) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="FolderReportingRadiologist"	Name="Folder Reporting Radiologist"
+(0095,0007) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="SIENETISAPLA"					Name="SIENET ISA PLA"
+(0095,000c) VERS="SSPI" VR="SL"   VM="1"	Owner="SIENET"			Keyword="?"								Name="?"
+(0095,0020) VERS="SSPI" VR="PN"   VM="1"	Owner="SIENET"			Keyword="RISPatientName"				Name="RIS Patient Name"
+(0097,0003) VERS="SSPI" VR="SL"   VM="1"	Owner="SIENET"			Keyword="?"								Name="?"
+(0097,0005) VERS="SSPI" VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"								Name="?"
+(0099,0002) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIENET"			Keyword="DataObjectAttributes"			Name="Data Object Attributes"
+(0099,0005) VERS="SSPI"	VR="SL"   VM="1"	Owner="SIENET"			Keyword="?"								Name="?"
+(00A5,0005) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIENET"			Keyword="?"								Name="?"
+
+(0193,0002) VERS="SSPI"	VR="DS"   VM="1"	Owner="SIEMENS ISI"		Keyword="RISKey"				Name="RIS Key"
+(0307,0001) VERS="SSPI"	VR="UN"   VM="1"	Owner="SIEMENS ISI"		Keyword="RISWorklistIMGEF"			Name="RIS Worklist IMGEF"
+(0309,0001) VERS="SSPI"	VR="UN"   VM="1"	Owner="SIEMENS ISI"		Keyword="RISReportIMGEF"			Name="RIS Report IMGEF"
+(4009,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportID"				Name="Report ID"
+(4009,0020) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportStatus"				Name="Report Status"
+(4009,0030) VERS="SSPI"	VR="DA"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportCreationDate"			Name="Report Creation Date"
+(4009,0070) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportApprovingPhysician"		Name="Report Approving Physician"
+(4009,00e0) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportText"				Name="Report Text"
+(4009,00e1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportAuthor"				Name="Report Author"
+(4009,00e3) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS ISI"		Keyword="ReportingRadiologist"			Name="Reporting Radiologist"
+(6021,0000) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageGraphicsFormatCode"		Name="Image Graphics Format Code"
+(6021,0000) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS CT VA0  OST"	Keyword="OsteoContourComment"			Name="Osteo Contour Comment"
+(6021,0010) VERS="SSPI"	VR="LO"   VM="1"	Owner="SIEMENS CM VA0  CMS"	Keyword="ImageGraphics"				Name="Image Graphics"
+(6021,0010) VERS="SSPI"	VR="US"   VM="256"	Owner="SIEMENS CT VA0  OST"	Keyword="OsteoContourBuffer"			Name="Osteo Contour Buffer"
+(7001,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="Dummy"					Name="Dummy"
+(7003,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="Header"				Name="Header"
+(7005,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED"		Keyword="Dummy"					Name="Dummy"
+(7fe1,0000) VERS="SSPI"	VR="OB"   VM="1-n"	Owner="SIEMENS CM VA0  CMS"	Keyword="BinaryData"				Name="Binary Data"
+(7fe1,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CSA NON-IMAGE"	Keyword="CSAData"				Name="CSA Data"
+(7fe3,0000) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS NUMARIS II"	Keyword="ImageGraphicsFormatCode"		Name="Image Graphics Format Code"
+(7fe3,0010) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS NUMARIS II"	Keyword="ImageGraphics"				Name="Image Graphics"
+(7fe3,0020) VERS="SSPI"	VR="OB"   VM="1"	Owner="SIEMENS NUMARIS II"	Keyword="ImageGraphicsDummy"			Name="Image Graphics Dummy"
+
+(7FE3,0014) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="MinimumPixelInFrame"								Name="Minimum Pixel in Frame"
+(7FE3,0015) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="MaximumPixelInFrame"								Name="Maximum Pixel in Frame"
+(7fe3,0016) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7fe3,001b) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7fe3,001c) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7fe3,001e) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7fe3,0026) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7fe3,0027) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7fe3,0028) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="?"					Name="?"
+(7FE3,0029) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED NM"		Keyword="NumberOfRWavesInFrame"								Name="Number of R-Waves in Frame"
+
+(0077,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="EvidenceDocumentTemplateName"		Name="Evidence Document Template Name"
+(0077,0011) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="EvidenceDocumentTemplateVersion"	Name="Evidence Document Template Version"
+(0077,0020) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="ClinicalFindingData"		Name="Clinical Finding Data"
+(0077,0021) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="Metadata"					Name="Metadata"
+(0077,0030) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="ImplementationVersion"		Name="Implementation Version"
+(0077,0040) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="Predecessor"				Name="Predecessor"
+(0077,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="LogicalID"					Name="Logical ID"
+(0077,0060) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="ApplicationData"			Name="Application Data"
+(0077,0070) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="OwnerClinicalTaskName"		Name="Owner Clinical Task Name"
+(0077,0071) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="OwnerTaskName"				Name="Owner Task Name"
+(0077,0072) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="OwnerSupportedTemplates"	Name="Owner Supported Templates"
+(0077,0080) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO EVIDENCE DOCUMENT DATA"	Keyword="VolumeCatalog"				Name="Volume Catalog"
+
+(0021,00AD) VERS="SSPI" VR="OB"   VM="1"	Owner="syngoDynamics_Reporting"					Keyword="Data"								Name="Data"
+
+(0087,0020) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ENCAPSULATED DOCUMENT DATA"	Keyword="StudyModel"					Name="Study Model"
+(0087,0030) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ENCAPSULATED DOCUMENT DATA"	Keyword="ReportXMLSchema"				Name="Report XML Schema"
+(0087,0040) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ENCAPSULATED DOCUMENT DATA"	Keyword="ReportIdentifier"				Name="Report Identifier"
+
+(0029,0008) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO 3D FUSION MATRIX"	Keyword="ObjectSeriesInstanceUID"			Name="Object Series Instance UID"
+(0029,0009) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO 3D FUSION MATRIX"	Keyword="ModelSeriesInstanceUID"			Name="Model Series Instance UID"
+(0029,0010) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS SYNGO 3D FUSION MATRIX"	Keyword="MatrixReferencedSeriesInstanceUID"	Name="Matrix Referenced Series Instance UID"
+
+(0019,002D) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				 Keyword="BModeTintIndex"				Name="B-mode Tint Index"
+(0019,0072) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				 Keyword="DopplerTintIndex"				Name="Doppler Tint Index"
+(0019,0088) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				 Keyword="MModeTintIndex"				Name="M-mode Tint Index"
+(0019,0089) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				 Keyword="?"							Name="?"
+
+(0119,0000) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticMetaInformationVersion"			Name="Acoustic Meta Information Version"
+(0119,0001) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="CommonAcousticMetaInformation"				Name="Common Acoustic Meta Information"
+(0119,0002) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="MultiStreamSequence"						Name="Multi Stream Sequence"
+(0119,0003) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticDataSequence"						Name="Acoustic Data Sequence"
+(0119,0004) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="PerTransactionAcousticControlInformation"	Name="Per Transaction Acoustic Control Information"
+(0119,0005) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticDataOffset"						Name="Acoustic Data Offset"
+(0119,0006) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticDataLength"						Name="Acoustic Data Length"
+(0119,0007) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="FooterOffset"								Name="Footer Offset"
+(0119,0008) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="FooterLength"								Name="Footer Length"
+(0119,0009) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticStreamNumber"						Name="Acoustic Stream Number"
+(0119,0010) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticStreamType"						Name="Acoustic Stream Type"
+(0119,0011) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="StageTimerTime"							Name="Stage Timer Time"
+(0119,0012) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="StopWatchTime"								Name="Stop Watch Time"
+(0119,0013) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="VolumeRate"								Name="Volume Rate"
+
+(0129,0000) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="MPRViewSequence"							Name="MPR View Sequence"
+(0129,0002) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="BookmarkUID"								Name="Bookmark UID"
+(0129,0003) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="PlaneOriginVector"							Name="Plane Origin Vector"
+(0129,0004) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="RowVector"									Name="Row Vector"
+(0129,0005) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="ColumnVector"								Name="Column Vector"
+(0129,0006) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="VisualizationSequence"						Name="Visualization Sequence"
+(0129,0007) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="BookmarkUID"								Name="Bookmark UID"
+(0129,0008) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="VisualizationInformation"					Name="Visualization Information"
+(0129,0009) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="ApplicationStateSequence"					Name="Application State Sequence"
+(0129,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="ApplicationStateInformation"				Name="Application State Information"
+(0129,0011) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="ReferencedBookmarkSequence"				Name="Referenced Bookmark Sequence"
+(0129,0012) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="ReferencedBookmarkUID"						Name="Referenced Bookmark UID"
+(0129,0020) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="CineParametersSequence"					Name="Cine Parameters Sequence"
+(0129,0021) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="CineParametersSchema"						Name="Cine Parameters Schema"
+(0129,0022) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="ValuesOfCineParameters"					Name="Values of Cine Parameters"
+(0129,0030) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="RawDataObjectType"							Name="Raw Data Object Type"
+
+(0139,0001) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="PhysioCaptureROI"							Name="Physio Capture ROI"
+
+(0149,0001) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS Ultrasound SC2000"				Keyword="VectorOfBROIPoints"						Name="Vector of BROI Points"
+(0149,0002) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS Ultrasound SC2000"				Keyword="StartEndTimestampsOfStripStream"			Name="Start/End Timestamps of Strip Stream"
+(0149,0003) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS Ultrasound SC2000"				Keyword="TimestampsOfVisibleRWaves"					Name="Timestamps of Visible R-waves"
+
+(7FD1,0001) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AcousticImageAndFooterData"				Name="Acoustic Image and Footer Data"
+(7FD1,0009) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="VolumeVersionID"							Name="Volume Version ID"
+(7FD1,0010) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="VolumePayload"								Name="Volume Payload"
+(7FD1,0011) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS Ultrasound SC2000"				Keyword="AfterPayload"								Name="After Payload"
+
+(7FDF,00FC) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO DATA PADDING"				Keyword="PixelDataLeadingPadding"					Name="Pixel Data Leading Padding"
+
+(0019,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"								Name="?"
+(0019,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"								Name="?"
+(0019,000A) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="NumberOfImagesInMosaic"		Name="Number of Images in Mosaic"
+(0019,000B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="SliceMeasurementDuration"		Name="Slice Measurement Duration"
+(0019,000C) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="BValue"						Name="B Value"
+(0019,000D) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="DiffusionDirectionality"		Name="Diffusion Directionality"
+(0019,000E) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR HEADER"				Keyword="DiffusionGradientDirection"	Name="Diffusion Gradient Direction"
+(0019,000f) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="GradientMode"					Name="Gradient Mode"
+(0019,0011) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="FlowCompensation"				Name="Flow Compensation"
+(0019,0012) VERS="SSPI" VR="SL"   VM="3"	Owner="SIEMENS MR HEADER"				Keyword="TablePositionOrigin"			Name="Table Position Origin"
+(0019,0013) VERS="SSPI" VR="SL"   VM="3"	Owner="SIEMENS MR HEADER"				Keyword="ImaAbsTablePosition"			Name="Ima Abs Table Position"
+(0019,0014) VERS="SSPI" VR="IS"   VM="3"	Owner="SIEMENS MR HEADER"				Keyword="ImaRelTablePosition"			Name="Ima Rel Table Position"
+(0019,0015) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR HEADER"				Keyword="SlicePosition_PCS"				Name="Slice Position PCS"
+(0019,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="TimeAfterStart"				Name="Time After Start"
+(0019,0017) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="SliceResolution"				Name="Slice Resolution"
+(0019,0018) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="RealDwellTime"					Name="Real Dwell Time"
+(0019,0023) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"								Name="?"
+(0019,0025) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MR HEADER"				Keyword="?"								Name="?"
+(0019,0026) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MR HEADER"				Keyword="?"								Name="?"
+(0019,0027) VERS="SSPI" VR="FD"   VM="6"	Owner="SIEMENS MR HEADER"				Keyword="BMatrix"						Name="B Matrix"
+(0019,0028) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="BandwidthPerPixelPhaseEncode"	Name="Bandwidth per Pixel Phase Encode"
+(0019,0029) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MR HEADER"				Keyword="MosaicRefAcqTimes"				Name="Mosaic Ref Acq Times"
+
+(0021,0001) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0002) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0003) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0004) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0005) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0006) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0007) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0008) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,000a) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,000c) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,000d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,000f) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0010) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0011) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0012) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0013) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0014) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0017) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0018) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0019) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001a) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001b) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001c) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001d) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001f) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0022) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0023) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0025) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0026) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002a) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002b) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002c) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002d) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002e) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002f) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0030) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0031) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0032) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0033) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0034) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0035) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0036) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0038) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,003b) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS SERIES SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+
+(0021,0001) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0002) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0003) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0004) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0005) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0006) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001a) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001c) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,001f) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0020) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0022) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0024) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0025) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0026) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0027) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002a) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002b) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002c) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002d) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,002e) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0033) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0034) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0035) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0037) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,003a) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,003b) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,003c) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,003d) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,003f) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0040) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0041) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0042) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0043) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0044) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0045) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0046) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0047) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0048) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0049) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,004b) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,004e) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,004f) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0051) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0052) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0053) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0054) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0056) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0058) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,0059) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,005a) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,005b) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+(0021,005e) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS IMAGE SHADOW ATTRIBUTES"				Keyword="?"				Name="?"
+
+(0021,0001) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR IMA"					Keyword="MRImageSequence"					Name="MR Image Sequence"
+
+(0021,0030) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="BackgroundColorDRSequence"			Name="Background Color DR Sequence"
+(0021,0031) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="BackgroundColor"					Name="Background Color"
+(0021,0036) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FieldMapDRSequence"				Name="Field Map DR Sequence"
+(0021,0037) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="Visible"							Name="Visible"
+(0021,0038) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="TintingColor"						Name="Tinting Color"
+(0021,0039) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="TintingEnabled"					Name="Tinting Enabled"
+(0021,003A) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VolumeID"							Name="Volume ID"
+(0021,003B) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VolumeIDAsBound"					Name="Volume ID As Bound"
+(0021,0041) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FloatingMPRColorLUTDRSequence"		Name="Floating MPR Color LUT DR Sequence"
+(0021,0042) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="RGBALUT"							Name="RGBA LUT"
+(0021,0043) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="BlendFactor"						Name="Blend Factor"
+(0021,0044) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="RGBALUTDataSequence"				Name="RGBA LUT Data Sequence"
+(0021,0045) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ColorLUT"							Name="Color LUT"
+(0021,004A) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="OrthoMPRColorLUTDRSequence"		Name="Ortho MPR ColorLUT DR Sequence"
+(0021,004B) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VRTColorLUTDRSequence"				Name="VRT Color LUT DR Sequence"
+(0021,004D) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PwlTransferFunctionDataSequence"	Name="Pwl Transfer Function Data Sequence"
+(0021,004C) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PwlTransferFunctionSequence"		Name="Pwl Transfer Function Sequence"
+(0021,004E) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PwlVertexIndex"					Name="Pwl Vertex Index"
+(0021,0050) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PwlVertexSequence"					Name="Pwl Vertex Sequence"
+(0021,0051) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FloatingMPRRenderDRSequence"		Name="Floating MPR Render DR Sequence"
+(0021,0052) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PrimaryShowHide"					Name="Primary Show Hide"
+(0021,0056) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="AlphaDependentFieldmap"			Name="Alpha Dependent Fieldmap"
+(0021,0057) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VolumeFilter"						Name="Volume Filter"
+(0021,005A) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="OrthoMPRRenderDRSequence"			Name="Ortho MPR Render DR Sequence"
+(0021,005B) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VRTRenderDRSequence"				Name="VRT Render DR Sequence"
+(0021,0053) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="SecondaryShowHide"					Name="Secondary Show Hide"
+(0021,0054) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PrimaryShadingIndex"				Name="Primary Shading Index"
+(0021,0055) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="SecondaryShadingIndex"				Name="Secondary Shading Index"
+(0021,0058) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="BoundingBoxColor"					Name="Bounding Box Color"
+(0021,0059) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="SceneInteractionOn"				Name="Scene Interaction On"
+(0021,0060) VERS="SSPI" VR="SQ"   VM="6"	Owner="SIEMENS MR N3D"	Keyword="ClipPlaneDRSequence"				Name="Clip Plane DR Sequence"
+(0021,0061) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="PlaneCenter"						Name="Plane Center"
+(0021,0062) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="PlaneNormal"						Name="Plane Normal"
+(0021,0063) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MR N3D"	Keyword="PlaneScale"						Name="Plane Scale"
+(0021,0064) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneEnableGLClip"					Name="Plane Enable GL Clip"
+(0021,0065) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneHandleRatio"					Name="Plane Handle Ratio"
+(0021,0066) VERS="SSPI" VR="DS"   VM="24"	Owner="SIEMENS MR N3D"	Keyword="PlaneBoundingPoints"				Name="Plane Bounding Points"
+(0021,0067) VERS="SSPI" VR="DS"   VM="16"	Owner="SIEMENS MR N3D"	Keyword="PlaneMotionMatrix"					Name="Plane Motion Matrix"
+(0021,0068) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneShiftVelocity"				Name="Plane Shift Velocity"
+(0021,0069) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneEnabled"						Name="Plane Enabled"
+(0021,006A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneRotateVelocity"				Name="Plane Rotate Velocity"
+(0021,006B) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneShowGraphics"					Name="Plane Show Graphics"
+(0021,0073) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneSingleSelectionMode"			Name="Plane Single Selection Mode"
+(0021,0074) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneAlignment"					Name="Plane Alignment"
+(0021,0075) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneSelected"						Name="Plane Selected"
+(0021,0070) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="SplitPlaneDRSequence"				Name="Split Plane DR Sequence"
+(0021,0071) VERS="SSPI" VR="SQ"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="FloatingMPRDRSequence"				Name="Floating MPR DR Sequence"
+(0021,006E) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneMPRLocked"					Name="Plane MPR Locked"
+(0021,006F) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlaneScalingDisabled"				Name="Plane Scaling Disabled"
+(0021,0072) VERS="SSPI" VR="SQ"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="OrthoMPRDRSequence"				Name="Ortho MPR DR Sequence"
+(0021,006C) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="Offset"							Name="Offset"
+(0021,006D) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="OrthoMPRAtBoundingBox"				Name="Ortho MPR At Bounding Box"
+(0021,0076) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ClusteringDRSequence"				Name="Clustering DR Sequence"
+(0021,0077) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ClusterSize"						Name="Cluster Size"
+(0021,0078) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ClusteringEnabled"					Name="Clustering Enabled"
+(0021,0079) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ClusterMaskVolID"					Name="Cluster Mask Vol ID"
+(0021,0080) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="HeadMaskingDRSequence"				Name="Head Masking DR Sequence"
+(0021,0081) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MR N3D"	Keyword="MaskingRange"						Name="Masking Range"
+(0021,0082) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="MaskEnabled"						Name="Mask Enabled"
+(0021,0083) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="BrainMaskingDRSequence"			Name="Brain Masking DR Sequence"
+(0021,0084) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="MaskingStatusDRSequence"			Name="Masking Status DR Sequence"
+(0021,0085) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VRTMaskingDRSequence"				Name="VRT Masking DR Sequence"
+(0021,0086) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="OrthoMPRMaskingDRSequence"			Name="Ortho MPR Masking DR Sequence"
+(0021,0087) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FloatingMPRMaskingDRSequence"		Name="Floating MPR Masking DR Sequence"
+(0021,0088) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="AlignDRSequence"					Name="Align DR Sequence"
+(0021,0089) VERS="SSPI" VR="DS"   VM="16"	Owner="SIEMENS MR N3D"	Keyword="RegistrationMatrix"				Name="Registration Matrix"
+(0021,0090) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FunctionalEvaluationDRSequence"	Name="Functional Evaluation DR Sequence"
+(0021,0091) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR N3D"	Keyword="FrameAcquitionNumbers"				Name="Frame Acquition Numbers"
+(0021,0092) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ShowCursor"						Name="Show Cursor"
+(0021,0093) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="CurrentFrame"						Name="Current Frame"
+(0021,0094) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR N3D"	Keyword="PlotArea"							Name="Plot Area"
+(0021,0095) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MR N3D"	Keyword="PlotTextPosition"					Name="Plot Text Position"
+(0021,0096) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR N3D"	Keyword="BaseLinePoints"					Name="Base Line Points"
+(0021,0097) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR N3D"	Keyword="ActivePoints"						Name="Active Points"
+(0021,0098) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ShowLabel"							Name="Show Label"
+(0021,0099) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="MeanPlot"							Name="Mean Plot"
+(0021,009A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="MotionPlot"						Name="Motion Plot"
+(0021,009B) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ActivateNormallizedCurve"			Name="Activate Normallized Curve"
+(0021,009C) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlotSize"							Name="Plot Size"
+(0021,00A0) VERS="SSPI" VR="SQ"   VM="4"	Owner="SIEMENS MR N3D"	Keyword="PlotDRSequence"					Name="PlotDR Sequence"
+(0021,00A1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="Title"								Name="Title"
+(0021,00A2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="AutoScale"							Name="Auto Scale"
+(0021,00A3) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FixedScale"						Name="Fixed Scale"
+(0021,00A4) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="BackgroundColor"					Name="Background Color"
+(0021,00A5) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="LabelX"							Name="Label X"
+(0021,00A6) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="LabelY"							Name="Label Y"
+(0021,00A7) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="Legend"							Name="Legend"
+(0021,00A8) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ScrollBarX"						Name="Scroll Bar X"
+(0021,00A9) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ScrollBarY"						Name="Scroll Bar Y"
+(0021,00AA) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ConnectScrollX"					Name="Connect Scroll X"
+(0021,00AB) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlotID"							Name="Plot ID"
+(0021,00AC) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlotPosition"						Name="Plot Position"
+(0021,00B0) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="CurveDRSequence"					Name="Curve DR Sequence"
+(0021,00B1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="CurveID"							Name="Curve ID"
+(0021,00B2) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="PlotType"							Name="Plot Type"
+(0021,00B3) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR N3D"	Keyword="CurveValues"						Name="Curve Values"
+(0021,00B4) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="LineColor"							Name="Line Color"
+(0021,00B5) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR N3D"	Keyword="MarkerColor"						Name="Marker Color"
+(0021,00B6) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="LineFilled"						Name="Line Filled"
+(0021,00B7) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="Label"								Name="Label"
+(0021,00B8) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="ShowMarker"						Name="Show Marker"
+(0021,00B9) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="MarkerShape"						Name="Marker Shape"
+(0021,00BA) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="SmoothingAlgo"						Name="Smoothing Algo"
+(0021,00BB) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="MarkerSize"						Name="Marker Size"
+(0021,00BC) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="LineStyle"							Name="Line Style"
+(0021,00BD) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="LinePattern"						Name="Line Pattern"
+(0021,00BE) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="LineWidth"							Name="Line Width"
+(0021,00C0) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="VRTFilterDRSequence"				Name="VRT Filter DR Sequence"
+(0021,00C1) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="FilterType"						Name="Filter Type"
+(0021,00C2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR N3D"	Keyword="CurrentActivePlane"				Name="Current Active Plane"
+
+(0021,0001) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MR PHOENIX ATTRIBUTES"	Keyword="MdsModeMask"				Name="Mds Mode Mask"
+(0021,0002) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR PHOENIX ATTRIBUTES"	Keyword="Dixon"						Name="Dixon"
+(0021,0003) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MR PHOENIX ATTRIBUTES"	Keyword="SequenceFileName"			Name="Sequence File Name"
+(0021,00F1) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MR PHOENIX ATTRIBUTES"	Keyword="CountOfPseudoAttributes"	Name="Count of Pseudo Attributes"
+
+(0021,00FE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SiemensMRSDSSequence"			Name="Siemens MR SDS Sequence"
+(0021,0001) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="UsedPatientWeight"				Name="Used Patient Weight"
+(0021,0002) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="SARWholeBody"					Name="SAR Whole Body"
+(0021,0003) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="MRProtocol"					Name="MR Protocol"
+(0021,0004) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SliceArrayConcatenations"		Name="Slice Array Concatenations"
+(0021,0005) VERS="SSPI" VR="IS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="RelTablePosition"				Name="Rel Table Position"
+(0021,0006) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="CoilForGradient"				Name="Coil For Gradient"
+(0021,0007) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="LongModelName"					Name="Long Model Name"
+(0021,0008) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="GradientMode"					Name="Gradient Mode"
+(0021,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="PATModeText"					Name="PAT Mode Text"
+(0021,000A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SWCorrectionFactor"			Name="SW Correction Factor"
+(0021,000B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="RFPowerErrorIndicator"			Name="RF Power Error Indicator"
+(0021,000C) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="PositivePCSDirections"			Name="Positive PCS Directions"
+(0021,000D) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="ProtocolChangeHistory"			Name="Protocol Change History"
+(0021,000E) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="DataFileName"					Name="Data File Name"
+(0021,000F) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="Stimlim"						Name="Stimlim"
+(0021,0010) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="MRProtocolVersion"				Name="MR Protocol Version"
+(0021,0011) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="PhaseGradientAmplitude"		Name="Phase Gradient Amplitude"
+(0021,0012) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="ReadoutOS"						Name="Readout OS"
+(0021,0013) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="tpulsmax"						Name="tpuls max"
+(0021,0014) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="NumberOfPrescans"				Name="Number of Prescans"
+(0021,0015) VERS="SSPI" VR="FL"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="MeasurementIndex"				Name="Measurement Index"
+(0021,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="dBdtThreshold"					Name="dBdt Threshold"
+(0021,0017) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SelectionGradientAmplitude"	Name="Selection Gradient Amplitude"
+(0021,0018) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="RFSWDMostCriticalAspect"		Name="RF SWD Most Critical Aspect"
+(0021,0019) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="MRPhoenixProtocol"				Name="MR Phoenix Protocol"
+(0021,001A) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="CoilString"					Name="Coil String"
+(0021,001B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SliceResolution"				Name="Slice Resolution"
+(0021,001C) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="Stimmaxonline"					Name="Stim max online"
+(0021,001D) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="OperationModeFlag"				Name="Operation Mode Flag"
+(0021,001E) VERS="SSPI" VR="FL"   VM="16"	Owner="SIEMENS MR SDS 01"	Keyword="AutoAlignMatrix"				Name="Auto Align Matrix"
+(0021,001F) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MR SDS 01"	Keyword="CoilTuningReflection"			Name="Coil Tuning Reflection"
+(0021,0020) VERS="SSPI" VR="UI"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="RepresentativeImage"			Name="Representative Image"
+(0021,0022) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SequenceFileOwner"				Name="Sequence File Owner"
+(0021,0023) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="RFWatchdogMask"				Name="RF Watchdog Mask"
+(0021,0024) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="PostProcProtocol"				Name="Post Proc Protocol"
+(0021,0025) VERS="SSPI" VR="SL"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="TablePositionOrigin"			Name="Table Position Origin"
+(0021,0026) VERS="SSPI" VR="IS"   VM="32"	Owner="SIEMENS MR SDS 01"	Keyword="MiscSequenceParam"				Name="Misc Sequence Param"
+(0021,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="Isocentered"					Name="Isocentered"
+(0021,002A) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS MR SDS 01"	Keyword="CoilID"						Name="Coil ID"
+(0021,002B) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="PatReinPattern"				Name="Pat Rein Pattern"
+(0021,002C) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="SED"							Name="SED"
+(0021,002D) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="SARMostCriticalAspect"			Name="SAR Most Critical Aspect"
+(0021,002E) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="StimmOnMode"					Name="Stimm on mode"
+(0021,002F) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDS 01"	Keyword="GradientDelayTime"				Name="Gradient Delay Time"
+(0021,0030) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="ReadoutGradientAmplitude"		Name="Readout Gradient Amplitude"
+(0021,0031) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="AbsTablePosition"				Name="Abs Table Position"
+(0021,0032) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="RFSWDOperationMode"			Name="RF SWD Operation Mode"
+(0021,0033) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="CoilForGradient2"				Name="Coil for Gradient2"
+(0021,0034) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="StimFactor"					Name="Stim Factor"
+(0021,0035) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="Stimmaxgesnormonline"			Name="Stim max ges norm online"
+(0021,0036) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="dBdtmax"						Name="dBdt max"
+(0021,0038) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="TransmitterCalibration"		Name="Transmitter Calibration"
+(0021,0039) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="MREVAProtocol"					Name="MR EVA Protocol"
+(0021,003B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="dBdtLimit"						Name="dBdt Limit"
+(0021,003C) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="VFModelInfo"					Name="VF Model Info"
+(0021,003D) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="PhaseSliceOversampling"		Name="Phase Slice Oversampling"
+(0021,003E) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="VFSettings"					Name="VF Settings"
+(0021,003F) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="AutoAlignData"					Name="Auto Align Data"
+(0021,0040) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="FMRIModelParameters"			Name="FMRI Model Parameters"
+(0021,0041) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="FMRIModelInfo"					Name="FMRI Model Info"
+(0021,0042) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="FMRIExternalParameters"		Name="FMRI External Parameters"
+(0021,0043) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="FMRIExternalInfo"				Name="FMRI External Info"
+(0021,0044) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MR SDS 01"	Keyword="B1RMS"							Name="B1 RMS"
+(0021,0045) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="B1RMSSupervision"				Name="B1 RMS Supervision"
+(0021,0046) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="TalesReferencePower"			Name="Tales Reference Power"
+(0021,0047) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="SafetyStandard"				Name="Safety Standard"
+(0021,0048) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="DICOMImageFlavor"				Name="DICOM Image Flavor"
+(0021,0049) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="DICOMAcquisitionContrast"		Name="DICOM Acquisition Contrast"
+(0021,0050) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="RFEchoTrainLength4MF"			Name="RF Echo Train Length 4MF"
+(0021,0051) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="GradientEchoTrainLength4MF"	Name="Gradient Echo Train Length 4MF"
+(0021,0052) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="VersionInfo"					Name="Version Info"
+(0021,0053) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"	Keyword="Laterality4MF"					Name="Laterality 4MF"
+
+(0021,0001) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="TransmitterReferenceAmplitude"		Name="Transmitter Reference Amplitude"
+(0021,0002) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="HammingFilterWidth"				Name="Hamming Filter Width"
+(0021,0003) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR MRS 05"	Keyword="CSIGridshiftVector"				Name="CSI Gridshift Vector"
+(0021,0004) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="MixingTime"						Name="Mixing Time"
+(0021,0040) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SeriesProtocolInstance"			Name="Series Protocol Instance"
+(0021,0041) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SpectroResultType"					Name="Spectro Result Type"
+(0021,0042) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SpectroResultExtendType"			Name="Spectro Result Extend Type"
+(0021,0043) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="PostProcProtocol"					Name="Post Proc Protocol"
+(0021,0044) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="RescanLevel"						Name="Rescan Level"
+(0021,0045) VERS="SSPI" VR="OF"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SpectroAlgoResult"					Name="Spectro Algo Result"
+(0021,0046) VERS="SSPI" VR="OF"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SpectroDisplayParams"				Name="Spectro Display Params"
+(0021,0047) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="VoxelNumber"						Name="Voxel Number"
+(0021,0048) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="APRSequence"						Name="APR Sequence"
+(0021,0049) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SyncData"							Name="Sync Data"
+(0021,004A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="PostProcDetailedProtocol"			Name="Post Proc Detailed Protocol"
+(0021,004B) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR MRS 05"	Keyword="SpectroResultExtendTypeDetailed"	Name="Spectro Result Extend Type Detailed"
+
+(0025,0001) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR EXTRACTED CSA HEADER"	Keyword="ExtractedMRHeaderInformationSequence"			Name="Extracted MR Header Information Sequence"
+(0025,0002) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR EXTRACTED CSA HEADER"	Keyword="ExtractedMRHeaderCreatorIdentificationCode"	Name="Extracted MR Header Creator Identification Code"
+(0025,0003) VERS="SSPI" VR="AT"   VM="1"	Owner="SIEMENS MR EXTRACTED CSA HEADER"	Keyword="ExtractedMRHeaderTag"							Name="Extracted MR Header Tag"
+
+(0051,0008) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="CSAImageHeaderType"				Name="CSA Image Header Type"
+(0051,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="CSAImageHeaderVersion"				Name="CSA Image Header Version"
+(0051,000a) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,000b) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="AcquisitionMatrixText"				Name="Acquisition Matrix Text"
+(0051,000c) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,000d) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,000e) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,000f) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="CoilString"						Name="Coil String"
+(0051,0011) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,0012) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,0013) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="PositivePCSDirections"				Name="Positive PCS Directions"
+(0051,0015) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,0016) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,0017) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,0018) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+(0051,0019) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR HEADER"				Keyword="?"									Name="?"
+
+(0021,0001) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0002) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0003) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0004) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0005) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0006) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0007) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0008) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0009) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,000a) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,000c) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,000d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,000f) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0010) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0011) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0012) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0013) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0014) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0016) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0017) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0018) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0019) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,001a) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,001b) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,001c) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,001d) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,001f) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0022) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0023) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0025) VERS="SSPI" VR="SL"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0026) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0027) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,002a) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,002b) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,002c) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,002d) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,002e) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,002f) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0030) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0031) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0032) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0033) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0034) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0035) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0036) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0038) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0039) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,003b) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0044) VERS="SSPI" VR="DS"   VM="1-n"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0045) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,0046) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+(0021,00fe) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR SDS 01"				Keyword="?"				Name="?"
+
+(0021,0001) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="NumberOfImagesInMosaic"			Name="Number of Images in Mosaic"
+(0021,0002) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="SliceNormalVector"					Name="Slice Normal Vector"
+(0021,0003) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="SliceMeasurementDuration"			Name="Slice Measurement Duration"
+(0021,0004) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="TimeAfterStart"					Name="Time After Start"
+(0021,0005) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="BValue"							Name="B Value"
+(0021,0006) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ICEDims"							Name="ICE Dims"
+(0021,001A) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="RFSWDDataType"						Name="RF SWD Data Type"
+(0021,001B) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="MoCoQMeasure"						Name="MoCoQ Measure"
+(0021,001C) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="PhaseEncodingDirectionPositive"	Name="Phase Encoding Direction Positive"
+(0021,001D) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="PixelFile"							Name="Pixel File"
+(0021,001F) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="FMRIStimulInfo"					Name="FMRI Stimul Info"
+(0021,0020) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelInPlaneRot"					Name="Voxel in Plane Rot"
+(0021,0021) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="DiffusionDirectionality4MF"		Name="Diffusion Directionality 4MF"
+(0021,0022) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelThickness"					Name="Voxel Thickness"
+(0021,0023) VERS="SSPI" VR="FD"   VM="6"	Owner="SIEMENS MR SDI 02"	Keyword="BMatrix"							Name="B Matrix"
+(0021,0024) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="MultistepIndex"					Name="Multistep Index"
+(0021,0025) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CompAdjustedParam"					Name="Comp Adjusted Param"
+(0021,0026) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CompAlgorithm"						Name="Comp Algorithm"
+(0021,0027) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelNormalCor"					Name="Voxel NormalC or"
+(0021,0029) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="FlowEncodingDirectionString"		Name="Flow Encoding Direction String"
+(0021,002A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelNormalSag"					Name="Voxel Normal Sag"
+(0021,002B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelPositionSag"					Name="Voxel Position Sag"
+(0021,002C) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelNormalTra"					Name="Voxel Normal Tra"
+(0021,002D) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelPositionTra"					Name="Voxel Position Tra"
+(0021,002E) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="UsedChannelMask"					Name="Used Channel Mask"
+(0021,002F) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="RepetitionTimeEffective"			Name="Repetition Time Effective"
+(0021,0030) VERS="SSPI" VR="DS"   VM="6"	Owner="SIEMENS MR SDI 02"	Keyword="CSIImageOrientationPatient"		Name="CSI Image Orientation Patient"
+(0021,0032) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CSISliceLocation"					Name="CSI Slice Location"
+(0021,0033) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="EchoColumnPosition"				Name="Echo Column Position"
+(0021,0034) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="FlowVENC"							Name="Flow VENC"
+(0021,0035) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="MeasuredFourierLines"				Name="Measured Fourier Lines"
+(0021,0036) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="LQAlgorithm"						Name="LQ Algorithm"
+(0021,0037) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelPositionCor"					Name="Voxel Position Cor"
+(0021,0038) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="Filter2"							Name="Filter2"
+(0021,0039) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="FMRIStimulLevel"					Name="FMRI Stimul Level"
+(0021,003A) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelReadoutFOV"					Name="Voxel Readout FOV"
+(0021,003B) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="NormalizeManipulated"				Name="Normalize Manipulated"
+(0021,003C) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="RBMoCoRot"							Name="RBMoCoRot"
+(0021,003D) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CompManualAdjusted"				Name="Comp Manual Adjusted"
+(0021,003F) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="SpectrumTextRegionLabel"			Name="Spectrum Text Region Label"
+(0021,0040) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="VoxelPhaseFOV"						Name="Voxel Phase FOV"
+(0021,0041) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="GSWDDataType"						Name="GSWD Data Type"
+(0021,0042) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="RealDwellTime"						Name="Real Dwell Time"
+(0021,0043) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CompJobID"							Name="Comp Job ID"
+(0021,0044) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CompBlended"						Name="Comp Blended"
+(0021,0045) VERS="SSPI" VR="SL"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="ImaAbsTablePosition"				Name="Ima Abs Table Position"
+(0021,0046) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="DiffusionGradientDirection"		Name="Diffusion Gradient Direction"
+(0021,0047) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="FlowEncodingDirection"				Name="Flow Encoding Direction"
+(0021,0048) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="EchoPartitionPosition"				Name="Echo Partition Position"
+(0021,0049) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="EchoLinePosition"					Name="Echo Line Position"
+(0021,004B) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CompAutoParam"						Name="Comp Auto Param"
+(0021,004C) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="OriginalImageNumber"				Name="Original Image Number"
+(0021,004D) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="OriginalSeriesNumber"				Name="Original Series Number"
+(0021,004E) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="Actual3DImaPartNumber"				Name="Actual 3D Ima Part Number"
+(0021,004F) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ImaCoilString"						Name="Ima Coil String"
+(0021,0050) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MR SDI 02"	Keyword="CSIPixelSpacing"					Name="CSI Pixel Spacing"
+(0021,0051) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="SequenceMask"						Name="Sequence Mask"
+(0021,0052) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ImageGroup"						Name="Image Group"
+(0021,0053) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="BandwidthPerPixelPhaseEncode"		Name="Bandwidth Per Pixel Phase Encode"
+(0021,0054) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="NonPlanarImage"					Name="Non Planar Image"
+(0021,0055) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="PixelFileName"						Name="Pixel File Name"
+(0021,0056) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ImaPATModeText"					Name="Ima PAT Mode Text"
+(0021,0057) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="CSIImagePositionPatient"			Name="CSI Image Position Patient"
+(0021,0058) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="AcquisitionMatrixText"				Name="Acquisition Matrix Text"
+(0021,0059) VERS="SSPI" VR="IS"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="ImaRelTablePosition"				Name="Ima Rel Table Position"
+(0021,005A) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="RBMoCoTrans"						Name="RBMoCoTrans"
+(0021,005B) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="SlicePositionPCS"					Name="Slice Position PCS"
+(0021,005C) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="CSISliceThickness"					Name="CSI Slice Thickness"
+(0021,005E) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ProtocolSliceNumber"				Name="Protocol Slice Number"
+(0021,005F) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="Filter1"							Name="Filter1"
+(0021,0060) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="TransmittingCoil"					Name="Transmitting Coil"
+(0021,0061) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="NumberOfAveragesN4"				Name="Number of Averages N4"
+(0021,0062) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MR SDI 02"	Keyword="MosaicRefAcqTimes"					Name="Mosaic Ref Acq Times"
+(0021,0063) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="AutoInlineImageFilterEnabled"		Name="Auto Inline Image Filter Enabled"
+(0021,0065) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MR SDI 02"	Keyword="QCData"							Name="QC Data"
+(0021,0066) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ExamLandmarks"						Name="Exam Landmarks"
+(0021,0067) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ExamDataRole"						Name="Exam Data Role"
+(0021,0068) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="MRDiffusion"						Name="MR Diffusion"
+(0021,0069) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="RealWorldValueMapping"				Name="Real World Value Mapping"
+(0021,0070) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="DataSetInfo"						Name="Data Set Info"
+(0021,0071) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="UsedChannelString"					Name="Used Channel String"
+(0021,0072) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="PhaseContrastN4"					Name="Phase ContrastN4"
+(0021,0073) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="MRVelocityEncoding"				Name="MR Velocity Encoding"
+(0021,0074) VERS="SSPI" VR="FD"   VM="3"	Owner="SIEMENS MR SDI 02"	Keyword="VelocityEncodingDirectionN4"		Name="Velocity Encoding Direction N4"
+(0021,0075) VERS="SSPI" VR="CS"   VM="1-n"	Owner="SIEMENS MR SDI 02"	Keyword="ImageType4MF"						Name="Image Type 4MF"
+(0021,0076) VERS="SSPI" VR="LO"   VM="1-n"	Owner="SIEMENS MR SDI 02"	Keyword="ImageHistory"						Name="Image History"
+(0021,0077) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="SequenceInfo"						Name="SequenceI nfo"
+(0021,0078) VERS="SSPI" VR="CS"   VM="1-n"	Owner="SIEMENS MR SDI 02"	Keyword="ImageTypeVisible"					Name="Image Type Visible"
+(0021,0079) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="DistortionCorrectionType"			Name="Distortion Correction Type"
+(0021,0080) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="ImageFilterType"					Name="Image Filter Type"
+(0021,00FE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MR SDI 02"	Keyword="SiemensMRSDISequence"				Name="Siemens MR SDI Sequence"
+
+(0021,0001) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MR CM 03"				Keyword="?"				Name="?"
+(0021,0002) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MR CM 03"				Keyword="?"				Name="?"
+
+(0021,0001) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MR PS 04"				Keyword="?"				Name="?"
+
+(0021,0001) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MR FOR 06"				Keyword="?"				Name="?"
+
+(0029,0000) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="DualEnergyAlgorithmParameters"				Name="Dual Energy Algorithm Parameters"
+(0029,0001) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ValidCTVolumeMBoxTasks"					Name="Valid CT Volume MBox Tasks"
+(0029,0002) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ScanOptions"								Name="Scan Options"
+(0029,0003) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="AcquisitionDateandTime"					Name="Acquisition Date and Time"
+(0029,0004) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="AcquisitionNumber"							Name="Acquisition Number"
+(0029,0005) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="DynamicData"								Name="Dynamic Data"
+(0029,0006) VERS="SSPI" VR="DS"   VM="6"	Owner="SIEMENS CT APPL DATASET"	Keyword="ImageOrientationPatient"					Name="Image Orientation Patient"
+(0029,0007) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="FrameOfReferenceUid"						Name="Frame Of Reference Uid"
+(0029,0008) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="PatientPosition"							Name="Patient Position"
+(0029,0009) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ConvolutionKernel"							Name="Convolution Kernel"
+(0029,0010) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="Kvp"										Name="Kvp"
+(0029,0011) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ReconstructionDiameter"					Name="Reconstruction Diameter"
+(0029,0012) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="RescaleIntercept"							Name="Rescale Intercept"
+(0029,0013) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="RescaleSlope"								Name="Rescale Slope"
+(0029,0014) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="SliceThickness"							Name="Slice Thickness"
+(0029,0015) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="TableHeight"								Name="Table Height"
+(0029,0016) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="GantryDetectorTilt"						Name="Gantry Detector Tilt"
+(0029,0017) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="PixelSpacing"								Name="Pixel Spacing"
+(0029,0018) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumePatientPositionNotEqual"				Name="Volume PatientPosition Not Equal"
+(0029,0019) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeLossyImageCompressionNotEqual"		Name="Volume LossyImageCompression Not Equal"
+(0029,0020) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeConvolutionKernelNotEqual"			Name="Volume ConvolutionKernel Not Equal"
+(0029,0021) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumePixelSpacingNotEqual"				Name="Volume PixelSpacing Not Equal"
+(0029,0022) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeKvpNotEqual"							Name="Volume Kvp Not Equal"
+(0029,0023) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeReconstructionDiameterNotEqual"		Name="Volume ReconstructionDiameter Not Equal"
+(0029,0024) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeTableHeightNotEqual"					Name="Volume TableHeight Not Equal"
+(0029,0025) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeHasGaps"								Name="Volume Has Gaps"
+(0029,0026) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeNumberOfMissingImages"				Name="Volume Number Of Missing Images"
+(0029,0027) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeMaxGap"								Name="Volume Max Gap"
+(0029,0028) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumePositionOfGaps"						Name="Volume Position Of Gaps"
+(0029,0029) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="CalibrationFactor"							Name="Calibration Factor"
+(0029,002A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="FlashMode"									Name="Flash Mode"
+(0029,002B) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="Warnings"									Name="Warnings"
+(0029,002C) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeHighBitNotEqual"						Name="Volume HighBit Not Equal"
+(0029,002D) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeImageTypeNotEqual"					Name="Volume ImageType Not Equal"
+(0029,002E) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ImageType0"								Name="ImageType 0"
+(0029,002F) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ImageType1"								Name="ImageType 1"
+(0029,0030) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ImageType2"								Name="ImageType 2"
+(0029,0031) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ImageType3"								Name="ImageType 3"
+(0029,0032) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="PhotometricInterpretationNotMONOCHROME2"	Name="PhotometricInterpretation not MONOCHROME2"
+(0029,0033) VERS="SSPI" VR="DA"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="FirstAcquisitionDate"						Name="First Acquisition Date"
+(0029,0034) VERS="SSPI" VR="DA"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="LastAcquisitionDate"						Name="Last Acquisition Date"
+(0029,0035) VERS="SSPI" VR="TM"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="FirstAcquisitionTime"						Name="First Acquisition Time"
+(0029,0036) VERS="SSPI" VR="TM"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="LastAcquisitionTime"						Name="Last Acquisition Time"
+(0029,0037) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="InternalData"								Name="Internal Data"
+(0029,0038) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="RangesSOM7"								Name="Ranges SOM7"
+(0029,0039) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="CalculatedGantryDetectorTilt"				Name="Calculated Gantry Detector Tilt"
+(0029,0040) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="VolumeSliceDistance"						Name="Volume Slice Distance"
+(0029,0041) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="FirstSliceZCoordinate"						Name="First Slice Z Coordinate "
+(0029,0042) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="LastSliceZCoordinate"						Name="Last Slice Z Coordinate "
+(0029,0043) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="ContentDateTime"							Name="Content DateTime"
+(0029,0044) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="DeltaTime"									Name="Delta Time"
+(0029,0045) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS CT APPL DATASET"	Keyword="FrameCount"								Name="Frame Count"
+
+(0029,0000) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS CT APPL EVIDENCEDOCUMENT"	Keyword="PrivateTaskDatamodel"			Name="Private Task Datamodel"
+
+(0029,0000) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS CT APPL MEASUREMENT"	Keyword="OncologySegmentationMeasurementValues"	Name="Oncology Segmentation Measurement Values"
+(0029,0001) VERS="SSPI" VR="ST"   VM="1"	Owner="SIEMENS CT APPL MEASUREMENT"	Keyword="OncologyMeasurementRecistStandard"		Name="Oncology Measurement Recist Standard"
+(0029,0010) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS CT APPL MEASUREMENT"	Keyword="DualEnergyROIAnnotationMode"			Name="DualEnergy ROI Annotation Mode"
+
+(0029,0000) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="TranslucentMode"			Name="Translucent Mode"
+(0029,0001) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="TranslucentWindowSize"		Name="Translucent Window Size"
+(0029,0002) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="PanoramicMode"				Name="Panoramic Mode"
+(0029,0003) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="PanoramicInnerWidth"		Name="Panoramic Inner Width"
+(0029,0004) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="DisplayUnseenAreas"		Name="Display Unseen Areas"
+(0029,0005) VERS="SSPI" VR="US"   VM="4"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="UnseenAreasColor"			Name="Unseen Areas Color"
+(0029,0006) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="DisplayTaggedData"			Name="Display Tagged Data"
+(0029,0007) VERS="SSPI" VR="US"   VM="4"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="TaggedColor"				Name="Tagged Color"
+(0029,0008) VERS="SSPI" VR="UL"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="TaggedSampleThickness"		Name="Tagged Sample Thickness"
+(0029,0009) VERS="SSPI" VR="SL"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="TaggedThreshold"			Name="Tagged Threshold"
+(0029,0010) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS CT APPL PRESENTATION"	Keyword="KernelFilter"				Name="Kernel Filter"
+
+(0029,0000) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS CT APPL TMP DATAMODEL"	Keyword="CTTaskCommonDataModel"		Name="CT Task Common DataModel"
+
+(0039,0000) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ReleaseVersion"					Name="Release Version"
+(0039,0003) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VolumeAcquisitionDuration"			Name="Volume Acquisition Duration"
+(0039,0004) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VolumeRawDataType"					Name="Volume Raw Data Type"
+(0039,0005) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ScanType"							Name="Scan Type"
+(0039,0006) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ZlateralMin"						Name="Z Lateral Min"
+(0039,0007) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ZlateralSpan"						Name="Z Lateral Span"
+(0039,0008) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ZRadiusOfCurvature"				Name="Z Radius of Curvature"
+(0039,0009) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="WobbleCorrection"					Name="Wobble Correction"
+(0039,0010) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ScaleAlongWidth"					Name="Scale Along Width"
+(0039,0011) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ScaleAlongHeight"					Name="Scale Along Height"
+(0039,0012) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ScaleAlongDepth"					Name="Scale Along Depth"
+(0039,0013) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BufferSize"						Name="Buffer Size"
+(0039,0014) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="AcquisitionRate"					Name="Acquisition Rate"
+(0039,0015) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DepthMinCm"						Name="Depth Min cm"
+(0039,0016) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="IsLeftRightFlippedEn"				Name="Is Left Right Flipped Enabled"
+(0039,0017) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="IsUpDownFlippedEn"					Name="Is Up Down Flipped Enabled"
+(0039,0018) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="IsVolumeGeomAccurate"				Name="Is Volume Geom Accurate"
+(0039,0019) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BByteMaskOffset"					Name="BByte Mask Offset"
+(0039,0020) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BByteMaskSize"						Name="BByte Mask Size"
+(0039,0022) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="AcqPlaneRotationDeg"				Name="Acq Plane Rotation Deg"
+(0039,0023) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BeamAxialSpan"						Name="Beam Axial Span"
+(0039,0024) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BeamLateralMin"					Name="Beam Lateral Min"
+(0039,0025) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BeamLateralSpan"					Name="Beam Lateral Span"
+(0039,0026) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BeamAxialMin"						Name="Beam Axial Min"
+(0039,0027) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="NumDisplaySamples"					Name="Num Display Samples"
+(0039,0028) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DVolumeWidth"						Name="DVolume Width"
+(0039,0029) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DVolumeDepth"						Name="DVolume Depth"
+(0039,0030) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DVolumeHeight"						Name="DVolume Height"
+(0039,0031) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DVolumePosX"						Name="DVolume Pos X"
+(0039,0032) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DVolumePosY"						Name="DVolume Pos Y"
+(0039,0033) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DVolumePosZ"						Name="DVolume Pos Z"
+(0039,0034) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DBeamAxialMin"						Name="DBeam Axial Min"
+(0039,0035) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DBeamAxialSpan"					Name="DBeam Axial Span"
+(0039,0037) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DBeamLateralSpan"					Name="DBeam Lateral Span"
+(0039,0038) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="NumOfVolumesInSequence"			Name="Number of Volumes in Sequence"
+(0039,0039) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DByteMaskOffset"					Name="DByte Mask Offset"
+(0039,0040) VERS="SSPI" VR="UN"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="DByteMaskSize"						Name="DByte Mask Size"
+
+(0039,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="PrivateCreatorVersionOfBookmark"	Name="Private Creator Version of Bookmark"
+(0039,0051) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BCutPlaneEnable"					Name="BCut Plane Enable"
+(0039,0052) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BMprColorMapIndex"					Name="BMpr Color Map Index"
+(0039,0053) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BMprDynamicRangeDb"				Name="BMpr Dynamic Range Db"
+(0039,0054) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BMprGrayMapIndex"					Name="BMpr Gray Map Index"
+(0039,0055) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVolumeRenderMode"					Name="BVolume Render Mode"
+(0039,0056) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrBrightness"						Name="BVr Brightness"
+(0039,0057) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrContrast"						Name="BVr Contrast"
+(0039,0058) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrColorMapIndex"					Name="BVr Color Map Index"
+(0039,0059) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrDynamicRangeDb"					Name="BVr Dynamic Range Db"
+(0039,005a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrGrayMapIndex"					Name="BVr Gray Map Index"
+(0039,005b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrGrayMapIndex"					Name="BVr Gray Map Index"
+(0039,005c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrThresholdHigh"					Name="BVr Threshold High"
+(0039,005d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BVrThresholdLow"					Name="BVr Threshold Low"
+(0039,005e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BPreProcessFilterMix"				Name="BPre Process Filter Mix"
+(0039,005f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CCutPlaneEnable"					Name="CCut Plane Enable"
+(0039,0060) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CFrontClipMode"					Name="CFront Clip Mode"
+(0039,0061) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CMprColorMapIndex"					Name="CMpr Color Map Index"
+(0039,0062) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CMprColorFlowPriorityIndex"		Name="CMpr Color Flow Priority Index"
+(0039,0063) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVolumeRenderMode"					Name="CVolume Render Mode"
+(0039,0064) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVrColorMapIndex"					Name="CVr Color Map Index"
+(0039,0065) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVrColorFlowPriorityIndex"			Name="CVr Color Flow Priority Index"
+(0039,0066) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVrOpacity"						Name="CVr Opacity"
+(0039,0067) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVrThresholdHigh"					Name="CVr Threshold High"
+(0039,0068) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVrThresholdLow"					Name="CVr Threshold Low"
+(0039,0069) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiMode"							Name="Voi Mode"
+(0039,006a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiRotationOffsetDeg"				Name="Voi Rotation Offset Deg"
+(0039,006b) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiSizeRatioX"						Name="Voi Size Ratio X"
+(0039,006c) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiSizeRatioY"						Name="Voi Size Ratio Y"
+(0039,006d) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiSizeRatioZ"						Name="Voi Size Ratio Z"
+(0039,006e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiSyncPlane"						Name="Voi Sync Plane"
+(0039,006f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiViewMode"						Name="Voi View Mode"
+(0039,0070) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VrOrientationA"					Name="Vr Orientation A"
+(0039,0071) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="MprOrientationA"					Name="Mpr Orientation A"
+(0039,0072) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VrOffsetVector"					Name="Vr Offset Vector"
+(0039,0073) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BlendingRatio"						Name="Blending Ratio"
+(0039,0074) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="FusionBlendMode"					Name="Fusion Blend Mode"
+(0039,0075) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="QualityFactor"						Name="Quality Factor"
+(0039,0076) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="RendererType"						Name="Renderer Type"
+(0039,0077) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SliceMode"							Name="Slice Mode"
+(0039,0078) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ActiveQuad"						Name="Active Quad"
+(0039,0079) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ScreenMode"						Name="Screen Mode"
+(0039,007a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CutPlaneSide"						Name="Cut Plane Side"
+(0039,007b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="WireframeMode"						Name="Wireframe Mode"
+(0039,007c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CrossmarkMode"						Name="Crossmark Mode"
+(0039,007d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="MprDisplayType"					Name="Mpr Display Type"
+(0039,007e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VolumeDisplayType"					Name="Volume Display Type"
+(0039,007f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="LastReset"							Name="Last Reset"
+(0039,0080) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="LastNonFullScreenMode"				Name="Last Non Full Screen Mode"
+(0039,0081) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="MprToolIndex"						Name="Mpr Tool Index"
+(0039,0082) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiToolIndex"						Name="Voi Tool Index"
+(0039,0083) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ToolLoopMode"						Name="Tool Loop Mode"
+(0039,0084) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VolumeArbMode"						Name="Volume Arb Mode"
+(0039,0085) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="MprZoomEn"							Name="Mpr Zoom Enabled"
+(0039,0086) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="IsVolumeZoomEn"					Name="Is Volume Zoom Enabled"
+(0039,0087) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ZoomLevelMpr"						Name="Zoom Level Mpr"
+(0039,0088) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ZoomLevelVolume"					Name="Zoom Level Volume"
+(0039,0089) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="IsAutoRotateEn"					Name="Is Auto Rotate Enabled"
+(0039,008a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="AutoRotateAxis"					Name="Auto Rotate Axis"
+(0039,008b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="AutoRotateRangeIndex"				Name="Auto Rotate Range Index"
+(0039,008c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="AutoRotateSpeedIndex"				Name="Auto Rotate Speed Index"
+(0039,008d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CVrBrightness"						Name="CVr Brightness"
+(0039,008e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CFlowStateIndex"					Name="CFlow State Index"
+(0039,008f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BSubmodeIndex"						Name="BSubmode Index"
+(0039,0090) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CSubmodeIndex"						Name="CSubmode Index"
+(0039,0091) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CutPlane"							Name="Cut Plane"
+(0039,0092) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="BookmarkChunkId"					Name="Bookmark Chunk Id"
+(0039,0093) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SequenceMinChunkId"				Name="Sequence Min Chunk Id"
+(0039,0094) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SequenceMaxChunkId"				Name="Sequence Max Chunk Id"
+(0039,0095) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VolumeRateHz"						Name="Volume Rate Hz"
+(0039,009a) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiPositionOffsetX"				Name="Voi Position Offset X"
+(0039,009b) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiPositionOffsetY"				Name="Voi Position Offset Y"
+(0039,009c) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiPositionOffsetZ"				Name="Voi Position Offset Z"
+(0039,009d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VrToolIndex"						Name="Vr Tool Index"
+(0039,009e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ShadingPercent"					Name="Shading Percent"
+(0039,009f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VolumeType"						Name="Volume Type"
+(0039,00a0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VrQuadDisplayType"					Name="Vr Quad Display Type"
+(0039,00a1) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="MprCenterLocation"					Name="Mpr Center Location"
+(0039,00e0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SliceRangeType"					Name="Slice Range Type"
+(0039,00e1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SliceMPRPlane"						Name="Slice MPR Plane"
+(0039,00e2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SliceLayout"						Name="Slice Layout"
+(0039,00e3) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="SliceSpacing"						Name="Slice Spacing"
+(0039,00e4) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ThinVrMode"						Name="Thin Vr Mode"
+(0039,00e5) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="ThinVrThickness"					Name="Thin Vr Thickness"
+(0039,00e6) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiPivotX"							Name="Curved TOP VOI Pivot X"
+(0039,00e7) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiPivotY"							Name="Curved TOP VOI Pivot Y"
+(0039,00e8) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="VoiPivotZ"							Name="Curved TOP VOI Pivot Z"
+(0039,00e9) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="CTopVoiQuad"						Name="Curved TOP VOI Quadrant"
+(0039,00ea) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00ed) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00ee) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00ef) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f0) VERS="SSPI" VR="US"   VM="1-n"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f3) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f4) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f5) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+(0039,00f6) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SMS USG ANTARES 3D VOLUME"				Keyword="?"									Name="?"
+
+(0039,0050) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="PrivateCreatorVersionOfBookmark"	Name="Private Creator Version of Bookmark"
+(0039,0051) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BCutPlaneEnable"					Name="BCut Plane Enable"
+(0039,0052) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BMprColorMapIndex"					Name="BMpr Color Map Index"
+(0039,0053) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BMprDynamicRangeDb"				Name="BMpr Dynamic Range Db"
+(0039,0054) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BMprGrayMapIndex"					Name="BMpr Gray Map Index"
+(0039,0055) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVolumeRenderMode"					Name="BVolume Render Mode"
+(0039,0056) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrBrightness"						Name="BVr Brightness"
+(0039,0057) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrContrast"						Name="BVr Contrast"
+(0039,0058) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrColorMapIndex"					Name="BVr Color Map Index"
+(0039,0059) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrDynamicRangeDb"					Name="BVr Dynamic Range Db"
+(0039,005a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrGrayMapIndex"					Name="BVr Gray Map Index"
+(0039,005b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrGrayMapIndex"					Name="BVr Gray Map Index"
+(0039,005c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrThresholdHigh"					Name="BVr Threshold High"
+(0039,005d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BVrThresholdLow"					Name="BVr Threshold Low"
+(0039,005e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BPreProcessFilterMix"				Name="BPre Process Filter Mix"
+(0039,005f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CCutPlaneEnable"					Name="CCut Plane Enable"
+(0039,0060) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CFrontClipMode"					Name="CFront Clip Mode"
+(0039,0061) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CMprColorMapIndex"					Name="CMpr Color Map Index"
+(0039,0062) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CMprColorFlowPriorityIndex"		Name="CMpr Color Flow Priority Index"
+(0039,0063) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVolumeRenderMode"					Name="CVolume Render Mode"
+(0039,0064) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVrColorMapIndex"					Name="CVr Color Map Index"
+(0039,0065) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVrColorFlowPriorityIndex"			Name="CVr Color Flow Priority Index"
+(0039,0066) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVrOpacity"						Name="CVr Opacity"
+(0039,0067) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVrThresholdHigh"					Name="CVr Threshold High"
+(0039,0068) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVrThresholdLow"					Name="CVr Threshold Low"
+(0039,0069) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiMode"							Name="Voi Mode"
+(0039,006a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiRotationOffsetDeg"				Name="Voi Rotation Offset Deg"
+(0039,006b) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiSizeRatioX"						Name="Voi Size Ratio X"
+(0039,006c) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiSizeRatioY"						Name="Voi Size Ratio Y"
+(0039,006d) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiSizeRatioZ"						Name="Voi Size Ratio Z"
+(0039,006e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiSyncPlane"						Name="Voi Sync Plane"
+(0039,006f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiViewMode"						Name="Voi View Mode"
+(0039,0070) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VrOrientationA"					Name="Vr Orientation A"
+(0039,0071) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="MprOrientationA"					Name="Mpr Orientation A"
+(0039,0072) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VrOffsetVector"					Name="Vr Offset Vector"
+(0039,0073) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BlendingRatio"						Name="Blending Ratio"
+(0039,0074) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="FusionBlendMode"					Name="Fusion Blend Mode"
+(0039,0075) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="QualityFactor"						Name="Quality Factor"
+(0039,0076) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="RendererType"						Name="Renderer Type"
+(0039,0077) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SliceMode"							Name="Slice Mode"
+(0039,0078) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ActiveQuad"						Name="Active Quad"
+(0039,0079) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ScreenMode"						Name="Screen Mode"
+(0039,007a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CutPlaneSide"						Name="Cut Plane Side"
+(0039,007b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="WireframeMode"						Name="Wireframe Mode"
+(0039,007c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CrossmarkMode"						Name="Crossmark Mode"
+(0039,007d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="MprDisplayType"					Name="Mpr Display Type"
+(0039,007e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VolumeDisplayType"					Name="Volume Display Type"
+(0039,007f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="LastReset"							Name="Last Reset"
+(0039,0080) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="LastNonFullScreenMode"				Name="Last Non Full Screen Mode"
+(0039,0081) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="MprToolIndex"						Name="Mpr Tool Index"
+(0039,0082) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiToolIndex"						Name="Voi Tool Index"
+(0039,0083) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ToolLoopMode"						Name="Tool Loop Mode"
+(0039,0084) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VolumeArbMode"						Name="Volume Arb Mode"
+(0039,0085) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="MprZoomEn"							Name="Mpr Zoom Enabled"
+(0039,0086) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="IsVolumeZoomEn"					Name="Is Volume Zoom Enabled"
+(0039,0087) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ZoomLevelMpr"						Name="Zoom Level Mpr"
+(0039,0088) VERS="SSPI" VR="SS"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ZoomLevelVolume"					Name="Zoom Level Volume"
+(0039,0089) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="IsAutoRotateEn"					Name="Is Auto Rotate Enabled"
+(0039,008a) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="AutoRotateAxis"					Name="Auto Rotate Axis"
+(0039,008b) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="AutoRotateRangeIndex"				Name="Auto Rotate Range Index"
+(0039,008c) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="AutoRotateSpeedIndex"				Name="Auto Rotate Speed Index"
+(0039,008d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CVrBrightness"						Name="CVr Brightness"
+(0039,008e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CFlowStateIndex"					Name="CFlow State Index"
+(0039,008f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BSubmodeIndex"						Name="BSubmode Index"
+(0039,0090) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CSubmodeIndex"						Name="CSubmode Index"
+(0039,0091) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CutPlane"							Name="Cut Plane"
+(0039,0092) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="BookmarkChunkId"					Name="Bookmark Chunk Id"
+(0039,0093) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SequenceMinChunkId"				Name="Sequence Min Chunk Id"
+(0039,0094) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SequenceMaxChunkId"				Name="Sequence Max Chunk Id"
+(0039,0095) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VolumeRateHz"						Name="Volume Rate Hz"
+(0039,009a) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiPositionOffsetX"				Name="Voi Position Offset X"
+(0039,009b) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiPositionOffsetY"				Name="Voi Position Offset Y"
+(0039,009c) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiPositionOffsetZ"				Name="Voi Position Offset Z"
+(0039,009d) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VrToolIndex"						Name="Vr Tool Index"
+(0039,009e) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ShadingPercent"					Name="Shading Percent"
+(0039,009f) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VolumeType"						Name="Volume Type"
+(0039,00a0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VrQuadDisplayType"					Name="Vr Quad Display Type"
+(0039,00a1) VERS="SSPI" VR="FD"   VM="1-n"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="MprCenterLocation"					Name="Mpr Center Location"
+(0039,00e0) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SliceRangeType"					Name="Slice Range Type"
+(0039,00e1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SliceMPRPlane"						Name="Slice MPR Plane"
+(0039,00e2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SliceLayout"						Name="Slice Layout"
+(0039,00e3) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="SliceSpacing"						Name="Slice Spacing"
+(0039,00e4) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ThinVrMode"						Name="Thin Vr Mode"
+(0039,00e5) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="ThinVrThickness"					Name="Thin Vr Thickness"
+(0039,00e6) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiPivotX"							Name="Curved TOP VOI Pivot X"
+(0039,00e7) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiPivotY"							Name="Curved TOP VOI Pivot Y"
+(0039,00e8) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="VoiPivotZ"							Name="Curved TOP VOI Pivot Z"
+(0039,00e9) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="CTopVoiQuad"						Name="Curved TOP VOI Quadrant"
+(0039,00ea) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00ed) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00ee) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00ef) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f0) VERS="SSPI" VR="US"   VM="1-n"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f1) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f2) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f3) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f4) VERS="SSPI" VR="FD"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f5) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+(0039,00f6) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SMS USG S2000 3D VOLUME"					Keyword="?"									Name="?"
+
+(0039,0076) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED OCS BEAM DISPLAY INFO"					Keyword="BeamDisplayProperties"				Name="Beam Display Properties"
+
+(0039,0001) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MED OCS PUBLIC RT PLAN ATTRIBUTES"			Keyword="ExternalAttributes"				Name="External Attributes"
+
+(0039,0076) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED OCS SS VERSION INFO"						Keyword="StructureSetPredecessor"			Name="Structure Set Predecessor"
+
+(0011,0020) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,0024) VERS="SSPI" VR="DS"   VM="1-n"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,0031) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,0032) VERS="SSPI" VR="SL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,0039) VERS="SSPI" VR="CS"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,003a) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00d0) VERS="SSPI" VR="OB"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00e0) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00e1) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00e2) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00e3) VERS="SSPI" VR="US"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00e4) VERS="SSPI" VR="US"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0011,00e5) VERS="SSPI" VR="CS"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+
+(0063,000c) VERS="SSPI" VR="DS"   VM="1-n"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0063,0035) VERS="SSPI" VR="SQ"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0063,0020) VERS="SSPI" VR="US"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+(0063,0021) VERS="SSPI" VR="UL"   VM="1"	Owner="BioPri3D"				Keyword="?"				Name="?"
+
+(2121,0001) VERS="" VR="ST"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationMethod"					Name="Calibration Method"
+(2121,0002) VERS="" VR="ST"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationMethodInfo"				Name="Calibration Method Info"
+(2121,0003) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationObjectSize"				Name="Calibration Object Size"
+(2121,0004) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationObjectSDev"				Name="Calibration Object S Dev"
+(2121,0005) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationHorizontalPixelSpacing"	Name="Calibration Horizontal Pixel Spacing"
+(2121,0006) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationVerticalPixelSpacing"	Name="Calibration Vertical Pixel Spacing"
+(2121,0008) VERS="" VR="ST"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationFileName"				Name="Calibration File Name"
+(2121,0009) VERS="" VR="IS"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationFrameNumber"			Name="Calibration Frame Number"
+(2121,000a) VERS="" VR="SH"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="CalibrationObjectUnit"				Name="Calibration Object Unit"
+(2121,000b) VERS="" VR="SS"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="AveragedCalibrationsPerformed"		Name="Averaged Calibrations Performed"
+(2121,000c) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="AutoMagnifyFactor"					Name="Auto Magnify Factor"
+(2121,000d) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="HorizontalPixelSDev"				Name="Horizontal Pixel S Dev"
+(2121,000e) VERS="" VR="FL"   VM="1"	Owner="PMI Private Calibration Module Version 2.0"				Keyword="VerticalPixelSDev"					Name="Vertical Pixel S Dev"
+
+(0029,0000) VERS="SSPI" VR="SQ"   VM="1"	Owner="CARDIO-D.R. 1.0"				Keyword="EdgeEnhancementSequence"						Name="Edge Enhancement Sequence"
+(0029,0001) VERS="SSPI" VR="US"   VM="2"	Owner="CARDIO-D.R. 1.0"				Keyword="ConvolutionKernelSize"							Name="Convolution Kernel Size"
+(0029,0002) VERS="SSPI" VR="US"   VM="1-n"	Owner="CARDIO-D.R. 1.0"				Keyword="ConvolutionKernelCoefficients"					Name="Convolution Kernel Coefficients"
+(0029,0003) VERS="SSPI" VR="FL"   VM="1"	Owner="CARDIO-D.R. 1.0"				Keyword="EdgeEnhancementGain"							Name="Edge Enhancement Gain"
+(0029,00AC) VERS="SSPI" VR="FL"   VM="1"	Owner="CARDIO-D.R. 1.0"				Keyword="DisplayedAreaBottomRightHandCornerFractional"	Name="Displayed Area Bottom Right Hand Corner Fractional"
+(0029,00AD) VERS="SSPI" VR="FL"   VM="1"	Owner="CARDIO-D.R. 1.0"				Keyword="DisplayedAreaTopLeftHandCornerFractional"		Name="Displayed Area Top Left Hand Corner Fractional"
+
+(0009,0002) VERS="SSPI" VR="OB"   VM="1"	Owner="POLYTRON-SMS 2.5"				Keyword="?"				Name="?"
+(0009,0004) VERS="SSPI" VR="OB"   VM="1"	Owner="POLYTRON-SMS 2.5"				Keyword="?"				Name="?"
+(0009,0006) VERS="SSPI" VR="OB"   VM="1"	Owner="POLYTRON-SMS 2.5"				Keyword="?"				Name="?"
+
+(0089,0010) VERS="SSPI" VR="OB"   VM="1"	Owner="POLYTRON-SMS 2.5"				Keyword="?"				Name="?"
+
+(300B,0010) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="PlanType"									Name="Plan Type"
+(300B,0011) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DeliveryWarningDoseComment"				Name="Delivery Warning Dose Comment"
+(300B,0012) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerOrganProgram"						Name="Imager Organ Program"
+(300B,0013) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="XAImageSID"								Name="XA Image SID"
+(300B,0014) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="XAImageReceptorAngle"						Name="XA Image Receptor Angle"
+(300B,0015) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetPrescriptionDoseType"				Name="Target Prescription Dose Type"
+(300B,0016) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ReferencedTargetROINumber"					Name="Referenced Target ROI Number"
+(300B,0017) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="RTPrivateData"								Name="RT Private Data"
+(300B,0018) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ReferencedSiemensNonImageSequence"			Name="Referenced Siemens Non Image Sequence"
+(300B,0019) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="VerificationMethod"						Name="Verification Method"
+(300B,0020) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="AlternativeTreatmentMachineNameSequence"	Name="Alternative Treatment Machine Name Sequence"
+(300B,0024) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerAngularAngle"						Name="Imager Angular Angle"
+(300B,0025) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerIsocentricAngle"						Name="Imager Isocentric Angle"
+(300B,0026) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerVerticalPosition"					Name="Imager Vertical Position"
+(300B,0027) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerLongitudinalPosition"				Name="Imager Longitudinal Position"
+(300B,0028) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerLateralPosition"						Name="Imager Lateral Position"
+(300B,0029) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerAngularRotationDirection"			Name="Imager Angular Rotation Direction"
+(300B,002A) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerIsocentricRotationDirection"			Name="Imager Isocentric Rotation Direction"
+(300B,002B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="RequestedScanningSpotSize"					Name="Requested Scanning Spot Size"
+(300B,002C) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerOrbitalAngle"						Name="Imager Orbital Angle"
+(300B,002E) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagingTechnique"							Name="Imaging Technique"
+(300B,002F) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerOrbitalRotationDirection"			Name="Imager Orbital Rotation Direction"
+(300B,0030) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="PatientBarcode"							Name="Patient Barcode"
+(300B,0031) VERS="SSPI" VR="SH"   VM="3"	Owner="SIEMENS MED SYNGO RT"	Keyword="BeamModifierType"							Name="Beam Modifier Type"
+(300B,0032) VERS="SSPI" VR="FL"   VM="3"	Owner="SIEMENS MED SYNGO RT"	Keyword="SourceToRangeShifterDistance"				Name="Source to Range Shifter Distance"
+(300B,0033) VERS="SSPI" VR="SH"   VM="3"	Owner="SIEMENS MED SYNGO RT"	Keyword="TreatmentRoomName"							Name="Treatment Room Name"
+(300B,0060) VERS="SSPI" VR="IS"   VM="1-n"	Owner="SIEMENS MED SYNGO RT"	Keyword="OrderedReferencedBeamNumbers"				Name="Ordered Referenced Beam Numbers"
+(300B,0066) VERS="SSPI" VR="LT"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="FractionDeliveryNotes"						Name="Fraction Delivery Notes"
+(300B,0067) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="RecordID"									Name="Record ID"
+(300B,0076) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="FractionGroupCode"							Name="Fraction Group Code"
+(300B,0077) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ReferencedTreatmentBeamNumber"				Name="Referenced Treatment Beam Number"
+(300B,0078) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="FractionDoseToDoseReference"				Name="Fraction Dose to Dose Reference"
+(300B,0080) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ReferencedTargetROISequence"				Name="Referenced Target ROI Sequence"
+(300B,0082) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetROILateralExpansionMargin"			Name="Target ROI Lateral Expansion Margin"
+(300B,0083) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetROIDistalExpansionMargin"			Name="Target ROI Distal Expansion Margin"
+(300B,0084) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetROIProximalExpansionMargin"			Name="Target ROI Proximal Expansion Margin"
+(300B,0085) VERS="SSPI" VR="DS"   VM="2"	Owner="SIEMENS MED SYNGO RT"	Keyword="ScanGridLateralDistance"					Name="Scan Grid Lateral Distance"
+(300B,0086) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ScanGridLongitudinalDistance"				Name="Scan Grid Longitudinal Distance"
+(300B,0087) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="BeamWeight"								Name="Beam Weight"
+(300B,0089) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MED SYNGO RT"	Keyword="PointOnPlane"								Name="Point on Plane"
+(300B,008A) VERS="SSPI" VR="DS"   VM="3"	Owner="SIEMENS MED SYNGO RT"	Keyword="NormVectorOfPlane"							Name="Norm Vector of Plane"
+(300B,008B) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="PlaneThickness"							Name="Plane Thickness"
+(300B,0090) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TreatmentApprovalSequence"					Name="Treatment Approval Sequence"
+(300B,0098) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TreatmentRoomTemperature"					Name="Treatment Room Temperature"
+(300B,0099) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TreatmentRoomAirPressure"					Name="Treatment Room Air Pressure"
+(300B,009B) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="Split[laneSequence"						Name="Split Plane Sequence"
+(300B,009C) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DisplayColor"								Name="Display Color"
+(300B,009D) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="BeamGroupName"								Name="Beam Group Name"
+(300B,00A0) VERS="SSPI" VR="DT"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ExpireDateTime"							Name="Expire DateTime"
+(300B,00A1) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ChecksumEncryptionCode"					Name="Checksum Encryption Code"
+(300B,00A2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="SetupType"									Name="Setup Type"
+(300B,00A3) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="NumberofTherapyDetectors"					Name="Number of Therapy Detectors"
+(300B,00A4) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TherapyDetectorSequence"					Name="Therapy Detector Sequence"
+(300B,00A5) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TherapyDetectorNumber"						Name="Therapy Detector Number"
+(300B,00A6) VERS="SSPI" VR="SH"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TherapyDetectorSetupID"					Name="Therapy Detector Setup ID"
+(300B,00A7) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TherapyDetectorSettingsSequence"			Name="Therapy Detector Settings Sequence"
+(300B,00A8) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ReferencedTherapyDetectorNumber"			Name="Referenced Therapy Detector Number"
+(300B,00A9) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TherapyDetectorPosition"					Name="Therapy Detector Position"
+(300B,00B0) VERS="SSPI" VR="IS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ScanSpotResumptionIndex"					Name="Scan Spot Resumption Index"
+(300B,00B1) VERS="SSPI" VR="OW"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="PhantomDetectorMeasurements"				Name="Phantom Detector Measurements"
+(300B,00B2) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TreatmentEvents"							Name="Treatment Events"
+(300B,00C0) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DoseOptimizationConstraintSequence"		Name="Dose Optimization Constraint Sequence"
+(300B,00C8) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetMaximumDoseConstraint"				Name="Target Maximum Dose Constraint"
+(300B,00C9) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetMaximumDoseConstraintWeight"			Name="Target Maximum Dose Constraint Weight"
+(300B,00CA) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetMinimumDoseConstraint"				Name="Target Minimum Dose Constraint"
+(300B,00CB) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="TargetMinimumDoseConstraintWeight"			Name="Target Minimum Dose Constraint Weight"
+(300B,00CC) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="OrganAtRiskMaximumDoseConstraint"			Name="Organ At Risk Maximum Dose Constraint"
+(300B,00CD) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="OrganAtRiskMaximumDoseConstraintWeight"	Name="Organ At Risk Maximum Dose Constraint Weight"
+(300B,00CE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DVHConstraintSequence"						Name="DVH Constraint Sequence"
+(300B,00CF) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DVHConstraintVolumeLimit"					Name="DVH Constraint Volume Limit"
+(300B,00D0) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DVHConstraintVolumeUnits"					Name="DVH Constraint Volume Units"
+(300B,00D1) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DVHConstraintDoseLimit"					Name="DVH Constraint Dose Limit"
+(300B,00D3) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DVHConstraintDirection"					Name="DVH Constraint Direction"
+(300B,00D4) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DVHConstraintWeight"						Name="DVH Constraint Weight"
+(300B,00D5) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="OptimizedDoseType"							Name="Optimized Dose Type"
+(300B,00D6) VERS="SSPI" VR="UT"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DoseCalculationandOptimizationParameters"	Name="Dose Calculation and Optimization Parameters"
+(300B,00D7) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="AppliedRenormalizationFactor"				Name="Applied Renormalization Factor"
+(300B,00D8) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DoseConstraintStatus"						Name="Dose Constraint Status"
+(300B,00D9) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="OrganAtRiskMinimumDoseConstraint"			Name="Organ At Risk Minimum Dose Constraint"
+(300B,00DA) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="OrganAtRiskMinimumDoseConstraintWeight"	Name="Organ At Risk Minimum Dose Constraint Weight"
+(300B,00E0) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="BaseDataGroupSequence"						Name="Base Data Group Sequence"
+(300B,00E1) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="PhysicsBaseDataGroupID"					Name="Physics Base Data Group ID"
+(300B,00E2) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="BiologicalBaseDataGroupID"					Name="Biological Base Data Group ID"
+(300B,00E3) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagingBaseDataGroupID"					Name="Imaging Base Data Group ID"
+(300B,00E4) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DosimetricBaseDataGroupID"					Name="Dosimetric Base Data Group ID"
+(300B,00E5) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ConfigurationBaseline"						Name="Configuration Baseline"
+(300B,00E6) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ConfigurationObjects"						Name="Configuration Objects"
+(300B,00E7) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ConfidenceMeasureUnits"					Name="Confidence Measure Units"
+(300B,00E8) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ConfidenceMeasureValue"					Name="Confidence Measure Value"
+(300B,00E9) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ImagerOrganProgramName"					Name="Imager Organ Program Name"
+(300B,00EB) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="BodyRegion"								Name="Body Region"
+(300B,00EC) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="PrefinalizedStatus"						Name="Prefinalized Status"
+(300B,00ED) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DosimetricChecksumEncryptionCode"			Name="Dosimetric Checksum Encryption Code"
+(300B,00EE) VERS="SSPI" VR="SQ"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="ReferencedReportSequence"					Name="Referenced Report Sequence"
+(300B,00EF) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="MaintainChecksumCompatibility"				Name="Maintain Checksum Compatibility"
+(300B,00F0) VERS="SSPI" VR="DS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="DoseStatisticalUncertainty"				Name="Dose Statistical Uncertainty"
+(300B,00F1) VERS="SSPI" VR="CS"   VM="1"	Owner="SIEMENS MED SYNGO RT"	Keyword="InterpretedRadiationType"					Name="Interpreted Radiation Type"
+
+(7FD1,0001) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ULTRA-SOUND TOYON DATA STREAMING"	Keyword="Padding"			Name="Padding"
+(7FD1,0009) VERS="SSPI" VR="OB"   VM="1"	Owner="SIEMENS SYNGO ULTRA-SOUND TOYON DATA STREAMING"	Keyword="VersionID"			Name="Version ID"
+(7FD1,0010) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ULTRA-SOUND TOYON DATA STREAMING"	Keyword="Payload"			Name="Payload"
+(7FD1,0011) VERS="SSPI" VR="LO"   VM="1"	Owner="SIEMENS SYNGO ULTRA-SOUND TOYON DATA STREAMING"	Keyword="AfterPayload"		Name="After Payload"
+
+(0021,0000) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Ultrasound S2000"	Keyword="NipplePosition"						Name="Nipple Position"
+(0021,0001) VERS="SSPI" VR="US"   VM="1"	Owner="SIEMENS Ultrasound S2000"	Keyword="ABVSClipDerivedFromVolume"				Name="ABVS Clip Derived From Volume"
+
+(0079,0000) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="Analgesia"					Name="Analgesia"
+(0079,0001) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="Anesthesia"				Name="Anesthesia"
+(0079,0002) VERS="SMIL" VR="IS"   VM="1"	Owner="SMIL_PB79"	Keyword="BedMotion"					Name="Bed Motion"
+(0079,0003) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="FoodAccess"				Name="Food Access"
+(0079,0004) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="HistogramVersion"			Name="Histogram Version"
+(0079,0006) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="InjectionDecayCorrection"	Name="Injection Decay Correction"
+(0079,0007) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="Isotope"					Name="Isotope"
+(0079,0008) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="OtherDrugs"				Name="Other Drugs"
+(0079,0009) VERS="SMIL" VR="IS"   VM="1"	Owner="SMIL_PB79"	Keyword="RebinningType"				Name="RebinningType"
+(0079,000A) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="RebinningVersion"			Name="Rebinning Version"
+(0079,000B) VERS="SMIL" VR="IS"   VM="1"	Owner="SMIL_PB79"	Keyword="Reconstruction"			Name="Reconstruction"
+(0079,000C) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="ReconstructionVersion"		Name="ReconstructionVersion"
+(0079,000D) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="InjectedCompound"			Name="Injected Compounds"
+(0079,000E) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="StudyModel"				Name="Study Model"
+(0079,000F) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="SubjectGenus"				Name="Subject Genus"
+(0079,0010) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="SubjectPhenotype"			Name="Subject Phenotype"
+(0079,0011) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="Version"					Name="Version"
+(0079,0012) VERS="SMIL" VR="LO"   VM="1"	Owner="SMIL_PB79"	Keyword="WaterAccess"				Name="Water Access"
+(0079,0013) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="XOffset"					Name="X Offset"
+(0079,0014) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="YOffset"					Name="Y Offset"
+(0079,0015) VERS="SMIL" VR="DS"   VM="1"	Owner="SMIL_PB79"	Keyword="Zoom"						Name="Zoom"
+(0079,0017) VERS="SMIL" VR="IS"   VM="1"	Owner="SMIL_PB79"	Keyword="SubjectOrientation"		Name="Subject Orientation"
+
+(007B,0000) VERS="SMIO" VR="LO"   VM="1"	Owner="SMIO_PB7B"	Keyword="Units"						Name="Units"
+
+(007D,0001) VERS="SMIO" VR="UL"   VM="1"	Owner="SMIO_PB7D"	Keyword="Geometry"					Name="Geometry"
+(007D,0002) VERS="SMIO" VR="FL"   VM="1"	Owner="SMIO_PB7D"	Keyword="Spacing"					Name="Spacing"
+(007D,0003) VERS="SMIO" VR="FL"   VM="1"	Owner="SMIO_PB7D"	Keyword="Origin"					Name="Origin"
+
+
diff --git a/libsrc/standard/elmdict/spi.tpl b/libsrc/standard/elmdict/spi.tpl
new file mode 100755
index 0000000..cc5652c
--- /dev/null
+++ b/libsrc/standard/elmdict/spi.tpl
@@ -0,0 +1,23 @@
+(0009,0010) VERS="SPI" VR="LO"   VM="1"	Owner="SPI"			Keyword="Comments"				Name="Comments"
+(0009,0010) VERS="SPI" VR="LO"   VM="1"	Owner="SPI RELEASE 1"		Keyword="Comments"				Name="Comments"
+(0009,0010) VERS="SPI" VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="Comments"				Name="Comments"
+(0009,0015) VERS="SPI" VR="LO"   VM="1"	Owner="SPI"			Keyword="UID"					Name="UID"
+(0009,0015) VERS="SPI" VR="LO"   VM="1"	Owner="SPI RELEASE 1"		Keyword="UID"					Name="UID"
+(0009,0015) VERS="SPI" VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="UID"					Name="UID"
+(0009,0040) VERS="SPI" VR="US"   VM="1"	Owner="SPI"			Keyword="DataObjectType"			Name="Data Object Type"
+(0009,0040) VERS="SPI" VR="US"   VM="1"	Owner="SPI RELEASE 1"		Keyword="DataObjectType"			Name="Data Object Type"
+(0009,0040) VERS="SPI" VR="US"   VM="1"	Owner="SPI Release 1"		Keyword="DataObjectType"			Name="Data Object Type"
+(0009,0041) VERS="SPI" VR="SH"   VM="1"	Owner="SPI"			Keyword="DataObjectSubtype"			Name="Data Object Subtype"
+(0009,0041) VERS="SPI" VR="SH"   VM="1"	Owner="SPI RELEASE 1"		Keyword="DataObjectSubtype"			Name="Data Object Subtype"
+(0009,0041) VERS="SPI" VR="SH"   VM="1"	Owner="SPI Release 1"		Keyword="DataObjectSubtype"			Name="Data Object Subtype"
+(0011,0010) VERS="SPI" VR="LO"   VM="1"	Owner="SPI"			Keyword="Organ"					Name="Organ"
+(0011,0010) VERS="SPI" VR="LO"   VM="1"	Owner="SPI RELEASE 1"		Keyword="Organ"					Name="Organ"
+(0011,0010) VERS="SPI" VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="Organ"					Name="Organ"
+(0011,0015) VERS="SPI" VR="LO"   VM="1"	Owner="SPI"			Keyword="AllergyIndication"			Name="Allergy Indication"
+(0011,0015) VERS="SPI" VR="LO"   VM="1"	Owner="SPI RELEASE 1"		Keyword="AllergyIndication"			Name="Allergy Indication"
+(0011,0015) VERS="SPI" VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="AllergyIndication"			Name="Allergy Indication"
+(0011,0020) VERS="SPI" VR="LO"   VM="1"	Owner="SPI"			Keyword="Pregnancy"				Name="Pregnancy"
+(0011,0020) VERS="SPI" VR="LO"   VM="1"	Owner="SPI RELEASE 1"		Keyword="Pregnancy"				Name="Pregnancy"
+(0011,0020) VERS="SPI" VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="Pregnancy"				Name="Pregnancy"
+(0029,0060) VERS="SPI" VR="LO"   VM="1"	Owner="SPI RELEASE 1"		Keyword="CompressionAlgorithm"			Name="Compression Algorithm"
+(0029,0060) VERS="SPI" VR="LO"   VM="1"	Owner="SPI Release 1"		Keyword="CompressionAlgorithm"			Name="Compression Algorithm"
diff --git a/libsrc/standard/elmdict/toshiba.tpl b/libsrc/standard/elmdict/toshiba.tpl
new file mode 100755
index 0000000..d95bd84
--- /dev/null
+++ b/libsrc/standard/elmdict/toshiba.tpl
@@ -0,0 +1,240 @@
+(0009,0000) VERS="TSH"  VR="LO"   VM="1"	Owner="TOSHIBA_MEC_OT3"	Keyword="HISRISStudyID"			Name="HIS/RIS Study ID"
+(0009,0001) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0009,0002) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0009,0003) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0009,0004) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0011,0001) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_1.0"		Keyword="?"				Name="?"
+(0011,0002) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"		Keyword="?"				Name="?"
+(0019,0001) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0001) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0019,0002) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0002) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0019,0003) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0004) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0005) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0006) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0007) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0019,0008) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="OrientationHeadFeet"			Name="Orientation Head Feet"
+(0019,0009) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="ViewDirection"					Name="View Direction"
+(0019,000a) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="OrientationSupineProne"		Name="Orientation Supine Prone"
+(0019,000b) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="Location"						Name="Location"
+(0019,000c) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="ScanViewDirection"				Name="Scan View Direction"
+(0019,000d) VERS="TSH"	VR="TM"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="Time"							Name="Time"
+(0019,000e) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"			Name="?"
+(0021,0001) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0021,0002) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0021,0003) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"	Keyword="?"			Name="?"
+(0029,0008) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA MDW NON-IMAGE"	Keyword="NonImageHeaderType"		Name="Non-Image Header Type"
+(0029,0009) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA MDW NON-IMAGE"	Keyword="NonImageHeaderVersion"		Name="Non-Image Header Version"
+(0029,0020) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA MDW NON-IMAGE"	Keyword="?"							Name="?"
+(0029,0008) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA MDW HEADER"	Keyword="ImageHeaderType"				Name="Image Header Type"
+(0029,0009) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA MDW HEADER"	Keyword="ImageHeaderVersion"			Name="Image Header Version"
+(0029,0010) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA MDW HEADER"	Keyword="ImageHeaderInfo"				Name="Image Header Info"
+(0029,0018) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA MDW HEADER"	Keyword="SeriesHeaderType"				Name="Series Header Type"
+(0029,0019) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA MDW HEADER"	Keyword="SeriesHeaderVersion"			Name="Series Header Version"
+(0029,0020) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA MDW HEADER"	Keyword="SeriesHeaderInfo"				Name="Series Header Info"
+(0029,0008) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA COMAPL HEADER"	Keyword="COMAPLHeaderType"			Name="COMAPL Header Type"
+(0029,0009) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA COMAPL HEADER"	Keyword="COMAPLHeaderVersion"		Name="COMAPL Header Version"
+(0029,0010) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA COMAPL HEADER"	Keyword="COMAPLHeaderInfo"			Name="COMAPL Header Info"
+(0029,0020) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA COMAPL HEADER"	Keyword="COMAPLHistoryInformation"	Name="COMAPL History Information"
+(0029,0031) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA COMAPL HEADER"	Keyword="?"	Name="?"
+(0029,0034) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA COMAPL HEADER"	Keyword="?"	Name="?"
+(0029,0008) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA COMAPL OOG"	Keyword="COMAPLOOGType"					Name="COMAPL OOG Type"
+(0029,0009) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA COMAPL OOG"	Keyword="COMAPLOOGVersion"				Name="COMAPL OOG Version"
+(0029,0010) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA COMAPL OOG"	Keyword="COMAPLOOGInfo"					Name="COMAPL OOG Info"
+(0029,0001) VERS="TSH"	VR="SQ"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="?"							Name="?"
+(0029,0031) VERS="TSH"	VR="LO"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="PMTFInformation1"			Name="PMTF Information 1"
+(0029,0032) VERS="TSH"	VR="UL"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="PMTFInformation2"			Name="PMTF Information 2"
+(0029,0033) VERS="TSH"	VR="UL"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="PMTFInformation3"			Name="PMTF Information 3"
+(0029,0034) VERS="TSH"	VR="CS"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="PMTFInformation4"			Name="PMTF Information 4"
+(0029,0089) VERS="TSH"	VR="LO"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="?"							Name="?"
+(0029,0090) VERS="TSH"	VR="OB"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="?"							Name="?"
+
+(7005,0000) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CTPrivateData1"								Name="CT Private Data 1"
+(7005,0003) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CardiacRRMeanTime"								Name="Cardiac R-R Mean Time"
+(7005,0004) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CardiacReconstructionGettingPhaseInPercent"	Name="Cardiac Reconstruction Getting Phase in Percent"
+(7005,0005) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CardiacReconstructionGettingPhaseInMS"			Name="Cardiac Reconstruction Getting Phase in ms"
+(7005,0006) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CardiacReconstructionMode"						Name="Cardiac Reconstruction Mode"
+(7005,0007) VERS="TSH"	VR="DS"   VM="1-n"	Owner="TOSHIBA_MEC_CT3"	Keyword="ReconstructionCenter"							Name="Reconstruction Center"
+(7005,0008) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="DetectorSliceThickness"						Name="Detector Slice Thickness in mm"
+(7005,0009) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="NumberOfDetectorRowsToReconstruct"				Name="Number of Detector rows to Reconstruct"
+(7005,000a) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="TableSpeed"									Name="Table Speed in mm/rot"
+(7005,000b) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="Filter"										Name="Filter"
+(7005,000c) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ReconstructionCorrectionType"					Name="Reconstruction Correction Type"
+(7005,000d) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="Organ"											Name="Organ"
+(7005,000e) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="FileTypeRemarks"								Name="File Type Remarks"
+(7005,000f) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="Direction"										Name="Direction (head or feet first)"
+(7005,0010) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CTPrivateData2"								Name="CT Private Data 2"
+(7005,0011) VERS="TSH"	VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="SeriesComment"									Name="Series Comment"
+(7005,0012) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="Position"										Name="Position (supine or prone)"
+(7005,0013) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ExpertPlanNumber"								Name="Expert Plan Number"
+(7005,0014) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ReconstructionROINumber"						Name="Reconstruction ROI Number"
+(7005,0015) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="SpecialHelicalAcquisitionNumber"				Name="Special Helical Acquisition Number"
+(7005,0016) VERS="TSH"	VR="UI"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="VolumeUID"										Name="Volume UID"
+(7005,0017) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="TotalFrameCountInTheVolume"					Name="Total Frame Count in the Volume"
+(7005,0018) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="FrameNumber"									Name="Frame Number"
+(7005,0019) VERS="TSH"	VR="UL"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="FrameSortKey"									Name="Frame Sort Key"
+(7005,001a) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="FrameSortOrder"								Name="Frame Sort Order"
+(7005,001b) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ConvolutionKernelForSeriesRecord"				Name="Convolution Kernel for Series Record"
+(7005,001c) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ContrastBolusAgentForSeriesRecord"				Name="Contrast/Bolus Agent for Series Record"
+(7005,001d) VERS="TSH"	VR="UL"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ReconstructionNumber"							Name="Reconstruction Number"
+(7005,001e) VERS="TSH"	VR="UL"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="RawDataNumber"									Name="Raw Data Number"
+(7005,001f) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="VolumeNumber"									Name="Volume Number"
+(7005,0020) VERS="TSH"	VR="UL"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="LocalSeriesNumber"								Name="Local Series Number"
+(7005,0021) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="DecreaseInArtifactFilter"						Name="Decrease in Artifact Filter"
+(7005,0022) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ReconstructionInterval"						Name="Reconstruction Interval"
+(7005,0023) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="PitchFactor"									Name="Pitch Factor"
+(7005,0024) VERS="TSH"	VR="DA"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="AcquisitionDateOfNRA"							Name="AcquisitionDateOfNRA"
+(7005,0025) VERS="TSH"	VR="UL"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="LargeDataFileAttribute"						Name="Large Data File Attribute"
+(7005,0026) VERS="TSH"	VR="CS"   VM="1-8"	Owner="TOSHIBA_MEC_CT3"	Keyword="LargeDataFileName"								Name="Large Data File Name"
+(7005,0028) VERS="TSH"	VR="SQ"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="EnhancedCTPrivateSequence"						Name="Enhanced CT Private Sequence"
+(7005,0029) VERS="TSH"	VR="UI"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="FrameUID"										Name="Frame UID"
+(7005,0030) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="MainModalityInStudy"							Name="Main Modality in Study"
+(7005,0035) VERS="TSH"	VR="DS"   VM="2"	Owner="TOSHIBA_MEC_CT3"	Keyword="ScanRange"										Name="Scan Range"
+(7005,0036) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CTPrivateData3"								Name="CT Private Data 3"
+(7005,0037) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="TotalFrames"									Name="Total Frames"
+(7005,0038) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="StartFrame"									Name="Start Frame"
+(7005,0039) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="EndFrame"										Name="End Frame"
+(7005,0040) VERS="TSH"	VR="FD"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="DLP"											Name="DLP"
+(7005,0041) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="RowSliceInformation"							Name="Row Slice Information"
+(7005,0042) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="LocalFrameNumber"								Name="Local Frame Number"
+(7005,0043) VERS="TSH"	VR="DS"   VM="3"	Owner="TOSHIBA_MEC_CT3"	Keyword="VolumeVector"									Name="Volume Vector"
+(7005,0044) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="VolumeType"									Name="Volume Type"
+(7005,0045) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="RelativeTablePositionOf4DVolume"				Name="Relative Table Position of 4D Volume"
+(7005,0046) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="AbsoluteTablePositionOf4DVolume"				Name="Absolute Table Position of 4D Volume"
+(7005,0047) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="SlicePitchOf4DVolume"							Name="Slice Pitch of 4D Volume"
+(7005,0048) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="RespiratoryGatingInformation"					Name="Respiratory Gating Information"
+(7005,0049) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="RespiratoryPhase"								Name="Respiratory Phase"
+(7005,0061) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="SynchronizedSignalInformation"					Name="Synchronized Signal Information"
+(7005,0062) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="TotalRawDataSize"								Name="Total Raw Data Size"
+(7005,0063) VERS="TSH"	VR="FD"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="CTDIw"											Name="CTDIw"
+(7005,0067) VERS="TSH"	VR="UI"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="VolumeUIDOf4DVolume"							Name="Volume UID of 4D-Volume"
+(7005,0068) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="TotalFrameCountIn4DVolume"						Name="Total Frame Count in 4D-Volume"
+(7005,0069) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="FrameNumberIn4DVolume"							Name="Frame Number in 4D-Volume"
+(7005,006a) VERS="TSH"	VR="DS"   VM="3"	Owner="TOSHIBA_MEC_CT3"	Keyword="ImagePositionOf4DVolumeTop"					Name="Image Position of 4D-Volume Top"
+(7005,006b) VERS="TSH"	VR="DS"   VM="3"	Owner="TOSHIBA_MEC_CT3"	Keyword="ImagePositionOf4DVolumeTopEquipment"			Name="Image Position of 4D-Volume Top (Equipment)"
+(7005,006c) VERS="TSH"	VR="UI"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="SOPInstanceUIDOf4DVolume"						Name="SOP Instance UID of 4D-Volume"
+(7005,006d) VERS="TSH"	VR="UI"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="SeriesInstanceUIDOf4DVolume"					Name="Series Instance UID of 4D-Volume" 
+(7005,00F1) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ProtectMarkForImageCurveOrPrivateRecord"		Name="Protect Mark for Image, Curve or Private Record" 
+(7005,00F1) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ProtectMarkForSeriesRecord"					Name="Protect Mark for Series Record" 
+(7005,00F1) VERS="TSH"	VR="CS"   VM="1"	Owner="TOSHIBA_MEC_CT3"	Keyword="ProtectMarkForStudyRecord"						Name="Protect Mark for Study Record" 
+
+(700d,0000) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="ScaleFactor"			Name="Scale Factor"
+(700d,0001) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="AcquisitionOrder"		Name="Acquisition Order"
+(700d,0002) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="OrientationVector"		Name="Orientation Vector"
+(700d,0003) VERS="TSH"	VR="SS"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="FlipFlag"				Name="Flip Flag"
+(700d,0004) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="RotateInformation"		Name="Rotate Information"
+(700d,0005) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="FOV"					Name="FOV"
+(700d,0006) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="ImageMatrix"			Name="Image Matrix"
+(700d,0007) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="ImageInformation"		Name="Image Information"
+(700d,0008) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="OriginalData"			Name="Original Data"
+(700d,0009) VERS="TSH"	VR="SS"   VM="1"	Owner="TOSHIBA_MEC_MR3"	Keyword="OriginalDataFlag"		Name="Original Data Flag"
+(7015,0000) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA ENCRYPTED SR DATA"	Keyword="?"			Name="?"
+(7015,0010) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_SR"	Keyword="?"			Name="?"
+(7015,0060) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_SR"	Keyword="?"							Name="?"
+(7015,0073) VERS="TSH"	VR="SQ"   VM="1"	Owner="PMTF INFORMATION DATA"	Keyword="?"							Name="?"
+(7079,0021) VERS="TSH"	VR="SH"   VM="5"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0022) VERS="TSH"	VR="IS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0023) VERS="TSH"	VR="IS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0024) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0025) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0026) VERS="TSH"	VR="DS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0027) VERS="TSH"	VR="US"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0028) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,002a) VERS="TSH"	VR="US"   VM="5"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,002c) VERS="TSH"	VR="SH"   VM="3"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,002d) VERS="TSH"	VR="SS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,002e) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,002f) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0030) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0031) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0032) VERS="TSH"	VR="SH"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0033) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0034) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0035) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0036) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0037) VERS="TSH"	VR="US"   VM="4"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0038) VERS="TSH"	VR="SS"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0039) VERS="TSH"	VR="SS"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,003a) VERS="TSH"	VR="US"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,003b) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,003c) VERS="TSH"	VR="DS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,003d) VERS="TSH"	VR="SS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,003e) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,003f) VERS="TSH"	VR="US"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0040) VERS="TSH"	VR="SH"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0041) VERS="TSH"	VR="SS"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0042) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0043) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0044) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0045) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0046) VERS="TSH"	VR="SS"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0047) VERS="TSH"	VR="SS"   VM="18"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0048) VERS="TSH"	VR="US"   VM="12"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0049) VERS="TSH"	VR="US"   VM="3"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,004a) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,004b) VERS="TSH"	VR="LO"   VM="3"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,004c) VERS="TSH"	VR="OB"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,004d) VERS="TSH"	VR="SH"   VM="3"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,004e) VERS="TSH"	VR="SL"   VM="35"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,004f) VERS="TSH"	VR="SH"   VM="3"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0050) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0051) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0052) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0053) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0054) VERS="TSH"	VR="US"   VM="5"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0055) VERS="TSH"	VR="UL"   VM="47-47n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0056) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0057) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0058) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0059) VERS="TSH"	VR="US"   VM="2-2n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,005a) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,005b) VERS="TSH"	VR="US"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,005c) VERS="TSH"	VR="US"   VM="2-2n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,005d) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,005e) VERS="TSH"	VR="US"   VM="2"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,005f) VERS="TSH"	VR="SS"   VM="4-4n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0060) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0061) VERS="TSH"	VR="SS"   VM="30-30n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0062) VERS="TSH"	VR="US"   VM="4"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0063) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0064) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0065) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0066) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0067) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0068) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0069) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,006a) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,006b) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,006c) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,006d) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,006e) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,006f) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0070) VERS="TSH"	VR="DS"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0071) VERS="TSH"	VR="DS"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0072) VERS="TSH"	VR="DS"   VM="1-n"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0073) VERS="TSH"	VR="SL"   VM="4"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0074) VERS="TSH"	VR="SL"   VM="28"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0075) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?" 
+(7079,0076) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?" 
+(7079,0077) VERS="TSH"	VR="SL"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0078) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0079) VERS="TSH"	VR="US"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,007b) VERS="TSH"	VR="SH"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7079,0080) VERS="TSH"	VR="LO"   VM="1"	Owner="TOSHIBA_MEC_XA3"	Keyword="?"		Name="?"
+(7ff1,0001) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"		Keyword="?"		Name="?"
+(7ff1,0001) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0002) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"		Keyword="?"		Name="?"
+(7ff1,0002) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0003) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0003) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"		Keyword="?"		Name="?"
+(7ff1,0004) VERS="TSH"	VR="IS"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0005) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0007) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0008) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0009) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,000a) VERS="TSH"  VR="LT"   VM="1"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,000b) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,000c) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,000d) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_CT_1.0"	Keyword="?"		Name="?"
+(7ff1,0010) VERS="TSH"	VR="US"   VM="1-n"	Owner="TOSHIBA_MEC_1.0"		Keyword="?"		Name="?"
diff --git a/libsrc/standard/elmdict/wordpart6tabletotpl.awk b/libsrc/standard/elmdict/wordpart6tabletotpl.awk
new file mode 100644
index 0000000..c86afaa
--- /dev/null
+++ b/libsrc/standard/elmdict/wordpart6tabletotpl.awk
@@ -0,0 +1,2 @@
+#  wordpart6tabletotpl.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+{FS="|"; keyword=$4; gsub("[ -]*","",keyword); print $1 " VERS=\"3MR\"  VR=\"" $2 "\"   VM=\"" $3 "\"	Keyword=\"" keyword "\"	Name=\"" $5 "\"";}
diff --git a/libsrc/standard/iodandmodulerelationshipsbytag.head b/libsrc/standard/iodandmodulerelationshipsbytag.head
new file mode 100644
index 0000000..a5b611b
--- /dev/null
+++ b/libsrc/standard/iodandmodulerelationshipsbytag.head
@@ -0,0 +1 @@
+Data Element Tag,Data Element Name,Composite IOD Name,Module Name,Module Requirement,Macro Invocation Path,Data Element Requirement,Value Multiplicity or Number of Items
diff --git a/libsrc/standard/iodcomp/Imakefile b/libsrc/standard/iodcomp/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/standard/iodcomp/base.tpl b/libsrc/standard/iodcomp/base.tpl
new file mode 100755
index 0000000..0db812c
--- /dev/null
+++ b/libsrc/standard/iodcomp/base.tpl
@@ -0,0 +1,922 @@
+CompositeIOD="CRImage"			Condition="CRImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="CRSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="CRImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="ModalityLUT"				Usage="U"	Condition="NeedModuleModalityLUT"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="CTImage"			Condition="CTImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePlane"					Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="CTImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MRImage"			Condition="MRImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePlane"					Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="MRImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="NMImage"			Condition="NMImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="NMPETPatientOrientation"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="U"	Condition="NeedModuleAcquisitionContext"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="NMImagePixel"				Usage="M"
+		Module="MultiFrame"					Usage="M"
+		Module="NMMultiFrame"				Usage="M"
+		Module="NMImage"					Usage="M"
+		Module="NMIsotope"					Usage="M"
+		Module="NMDetector"					Usage="M"
+		Module="NMTomoAcquisition"			Usage="C"	Condition="NeedModuleNMTomoAcquisition"
+		Module="NMMultiGatedAcquisition"	Usage="C"	Condition="NeedModuleNMMultiGatedAcquisition"
+		Module="NMPhase"					Usage="C"	Condition="NeedModuleNMPhase"
+		Module="NMReconstruction"			Usage="C"	Condition="NeedModuleNMReconstruction"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="MultiFrameOverlay"			Usage="U"	Condition="NeedModuleMultiFrameOverlay"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="USImage"			Condition="USImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="PaletteColorLookupTable"	Usage="C"	Condition="PhotometricInterpretationIsPaletteColor"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="USRegionCalibration"		Usage="U"	Condition="NeedModuleUSRegionCalibration"
+		Module="USImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="USMultiFrameImage"	Condition="USMultiFrameImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="NeedModuleSynchronizationForIVUS"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="Cine"						Usage="M"
+		Module="MultiFrame"					Usage="M"
+		Module="FramePointers"				Usage="U"	Condition="NeedModuleFramePointers"
+		Module="PaletteColorLookupTable"	Usage="C"	Condition="PhotometricInterpretationIsPaletteColor"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="USRegionCalibration"		Usage="U"	Condition="NeedModuleUSRegionCalibration"
+		Module="USImage"					Usage="M"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="SCImage"			Condition="SCImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="U"	Condition="NeedModuleGeneralEquipment"
+		Module="SCEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SCImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="ModalityLUT"				Usage="U"	Condition="NeedModuleModalityLUT"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MultiframeSingleBitSCImage"			Condition="MultiframeSingleBitSCImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"				Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"							Usage="M"
+		Module="ClinicalTrialSubject"				Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"						Usage="M"
+		Module="PatientStudy"						Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"					Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"						Usage="M"
+		Module="ClinicalTrialSeries"				Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"					Usage="U"	Condition="NeedModuleGeneralEquipment"
+		Module="SCEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"						Usage="M"
+		Module="ImagePixel"							Usage="M"
+		Module="Cine"								Usage="C"	Condition="NeedModuleCineForSC"
+		Module="MultiFrame"							Usage="M"
+		Module="FramePointers"						Usage="U"	Condition="NeedModuleFramePointers"
+		Module="Device"								Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"							Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SCImage"							Usage="U"
+		Module="SCMultiFrameImage"					Usage="M"
+		Module="SCMultiFrameVector"					Usage="C"	Condition="NumberOfFramesGreaterThanOne"
+		Module="SOPCommon"							Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"						Usage="C"	Condition="NeedModuleFrameExtraction"
+		Module="MultiframeSingleBitSCImagePseudo"	Usage="M"
+		# how to forbid presence of VOI LUT Module and Overlay Module :( ?
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MultiframeGrayscaleByteSCImage"			Condition="MultiframeGrayscaleByteSCImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="C"	Condition="PixelMeasuresOrPlanePositionOrPlaneOrientationSequenceIsPresent"
+		Module="Synchronization"						Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="U"	Condition="NeedModuleGeneralEquipment"
+		Module="SCEquipment"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"							Usage="M"
+		Module="ImagePixel"								Usage="M"
+		Module="Cine"									Usage="C"	Condition="NeedModuleCineForSC"
+		Module="MultiFrame"								Usage="M"
+		Module="FramePointers"							Usage="U"	Condition="NeedModuleFramePointers"
+		Module="Device"									Usage="U"	Condition="NeedModuleDevice"
+		Module="MultiFrameFunctionalGroupsCommon"		Usage="U"	Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+		Module="MultiFrameFunctionalGroupsForMFSC"		Usage="U"	Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+		Module="MultiFrameDimension"					Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="Specimen"								Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SCImage"								Usage="U"
+		Module="SCMultiFrameImage"						Usage="M"
+		Module="SCMultiFrameVector"						Usage="C"	Condition="NumberOfFramesGreaterThanOne"
+		Module="VOILUT"									Usage="C"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"								Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"						Usage="C"	Condition="NeedModuleFrameExtraction"
+		Module="MultiframeGrayscaleByteSCImagePseudo"	Usage="M"
+		# how to forbid presence of Overlay Module :( ?
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MultiframeGrayscaleWordSCImage"			Condition="MultiframeGrayscaleWordSCImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="C"	Condition="PixelMeasuresOrPlanePositionOrPlaneOrientationSequenceIsPresent"
+		Module="Synchronization"						Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="U"	Condition="NeedModuleGeneralEquipment"
+		Module="SCEquipment"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"							Usage="M"
+		Module="ImagePixel"								Usage="M"
+		Module="Cine"									Usage="C"	Condition="NeedModuleCineForSC"
+		Module="MultiFrame"								Usage="M"
+		Module="FramePointers"							Usage="U"
+		Module="Device"									Usage="U"	Condition="NeedModuleDevice"
+		Module="MultiFrameFunctionalGroupsCommon"		Usage="U"	Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+		Module="MultiFrameFunctionalGroupsForMFSC"		Usage="U"	Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+		Module="MultiFrameDimension"					Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="Specimen"								Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SCImage"								Usage="U"
+		Module="SCMultiFrameImage"						Usage="M"
+		Module="SCMultiFrameVector"						Usage="C"	Condition="NumberOfFramesGreaterThanOne"
+		Module="VOILUT"									Usage="C"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"								Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"						Usage="C"	Condition="NeedModuleFrameExtraction"
+		Module="MultiframeGrayscaleWordSCImagePseudo"	Usage="M"
+		# how to forbid presence of Overlay Module :( ?
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MultiframeTrueColorSCImage"				Condition="MultiframeTrueColorSCImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="C"	Condition="PixelMeasuresOrPlanePositionOrPlaneOrientationSequenceIsPresent"
+		Module="Synchronization"						Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="U"	Condition="NeedModuleGeneralEquipment"
+		Module="SCEquipment"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"							Usage="M"
+		Module="ImagePixel"								Usage="M"
+		Module="Cine"									Usage="C"	Condition="NeedModuleCineForSC"
+		Module="MultiFrame"								Usage="M"
+		Module="FramePointers"							Usage="U"
+		Module="Device"									Usage="U"	Condition="NeedModuleDevice"
+		Module="MultiFrameFunctionalGroupsCommon"		Usage="U"	Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+		Module="MultiFrameFunctionalGroupsForMFSC"		Usage="U"	Condition="MultiFrameFunctionalGroupsModuleIsPresent"
+		Module="MultiFrameDimension"					Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="Specimen"								Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SCImage"								Usage="U"
+		Module="SCMultiFrameImage"						Usage="M"
+		Module="SCMultiFrameVector"						Usage="C"	Condition="NumberOfFramesGreaterThanOne"
+		Module="ICCProfile"								Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"								Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"						Usage="C"	Condition="NeedModuleFrameExtraction"
+		Module="MultiframeTrueColorSCImagePseudo"		Usage="M"
+		# how to forbid presence of VOI LUT Module and Overlay Module :( ?
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="StandaloneOverlay"		Condition="StandaloneOverlayInstance"	Retired="true"
+	InformationEntity="File"
+		Module="FileMetaInformation"	Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"				Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"			Usage="M"
+		Module="PatientStudy"			Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"		Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"			Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="Overlay"
+		Module="OverlayIdentification"	Usage="M"
+		Module="OverlayPlane"			Usage="M"
+		Module="SOPCommon"				Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="StandaloneCurve"			Condition="StandaloneCurveInstance"	Retired="true"
+	InformationEntity="File"
+		Module="FileMetaInformation"	Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"				Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"			Usage="M"
+		Module="PatientStudy"			Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"		Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"			Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="Curve"
+		Module="CurveIdentification"	Usage="M"
+		Module="Curve"					Usage="M"
+		Module="SOPCommon"				Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+
+CompositeIOD="StandaloneModalityLUT"	Condition="StandaloneModalityLUTInstance"	Retired="true"
+	InformationEntity="File"
+		Module="FileMetaInformation"	Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"				Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"			Usage="M"
+		Module="PatientStudy"			Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"		Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"			Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="ModalityLUT"
+		Module="ModalityLUT"			Usage="M"
+		Module="LUTIdentification"		Usage="M"
+		Module="SOPCommon"				Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="StandaloneVOILUT"			Condition="StandaloneVOILUTInstance"	Retired="true"
+	InformationEntity="File"
+		Module="FileMetaInformation"	Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"				Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"			Usage="M"
+		Module="PatientStudy"			Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"		Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"			Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="VOILUT"
+		Module="VOILUT"					Usage="M"
+		Module="LUTIdentification"		Usage="M"
+		Module="SOPCommon"				Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="Segmentation"				Condition="SegmentationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="SegmentationSeries"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="C"	Condition="DerivationImageFunctionalGroupNotPresentOrFrameOfReferenceUIDPresent"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="M"
+		Module="EnhancedGeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"									Usage="M"
+		Module="ImagePixel"										Usage="M"
+		Module="SegmentationImage"								Usage="M"
+		Module="CommonInstanceReference"						Usage="C"	Condition="DerivationImageFunctionalGroupPresent"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForSegmentation"		Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SOPCommon"										Usage="M"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+		# how to forbid presence of VOI LUT Module and Overlay Module :( ?
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="SurfaceSegmentation"				Condition="SurfaceSegmentationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="SegmentationSeries"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="M"
+		Module="EnhancedGeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="Surface"
+		Module="SurfaceSegmentation"					Usage="M"
+		Module="SurfaceMesh"							Usage="M"
+		Module="CommonInstanceReference"				Usage="C"	Condition="NeedModuleCommonInstanceReference"
+		Module="SOPCommon"								Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="SpatialRegistration"			Condition="SpatialRegistrationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="SpatialRegistrationSeries"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="SpatialRegistration"
+		Module="SpatialRegistration"		Usage="M"
+		Module="CommonInstanceReference"	Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="DeformableSpatialRegistration"			Condition="DeformableSpatialRegistrationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="SpatialRegistrationSeries"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="SpatialRegistration"
+		Module="DeformableSpatialRegistration"	Usage="M"
+		Module="CommonInstanceReference"		Usage="M"
+		Module="SOPCommon"						Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="SpatialFiducials"				Condition="SpatialFiducialsInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="SpatialFiducialsSeries"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="SpatialFiducials"
+		Module="SpatialFiducials"			Usage="M"
+		Module="CommonInstanceReference"	Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EncapsulatedPDF"				Condition="EncapsulatedPDFInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"						Usage="M"
+		Module="ClinicalTrialSubject"			Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"					Usage="M"
+		Module="PatientStudy"					Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"				Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="EncapsulatedDocumentSeries"		Usage="M"
+		Module="ClinicalTrialSeries"			Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"				Usage="M"
+		Module="SCEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="EncapsulatedDocument"
+		Module="EncapsulatedDocument"			Usage="M"
+		Module="EncapsulatedDocumentPDFPseudo"	Usage="M"
+		Module="SOPCommon"						Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EncapsulatedCDA"					Condition="EncapsulatedCDAInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"						Usage="M"
+		Module="ClinicalTrialSubject"			Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"					Usage="M"
+		Module="PatientStudy"					Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"				Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="EncapsulatedDocumentSeries"		Usage="M"
+		Module="ClinicalTrialSeries"			Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"				Usage="M"
+		Module="SCEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="EncapsulatedDocument"
+		Module="EncapsulatedDocument"			Usage="M"
+		Module="EncapsulatedDocumentCDAPseudo"	Usage="M"
+		Module="SOPCommon"						Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RealWorldValueMapping"				Condition="RealWorldValueMappingInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"						Usage="M"
+		Module="ClinicalTrialSubject"			Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"					Usage="M"
+		Module="PatientStudy"					Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"				Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"					Usage="M"
+		Module="ClinicalTrialSeries"			Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="RealWorldValueMappingSeries"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="RealWorldValueMapping"
+		Module="RealWorldValueMapping"			Usage="M"
+		Module="CommonInstanceReference"		Usage="M"
+		Module="SOPCommon"						Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="IVOCTImage"			Condition="IVOCTImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"									Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"												Usage="M"
+		Module="ClinicalTrialSubject"									Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"											Usage="M"
+		Module="PatientStudy"											Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"										Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"											Usage="M"
+		Module="ClinicalTrialSeries"									Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="IntravascularOCTSeries"									Usage="M"	
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"										Usage="M"
+		Module="Synchronization"										Usage="M"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"										Usage="M"
+		Module="EnhancedGeneralEquipment"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"												Usage="M"
+		Module="SupplementalPaletteColorLUT"							Usage="C"	Condition="NeedModuleSupplementalPaletteColorLUT"
+		Module="EnhancedContrastBolus"									Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"						Usage="M"
+		Module="MultiFrameFunctionalGroupsForIVOCTImageForPresentation"	Usage="C"	Condition="PresentationIntentTypeIsForPresentation"
+		Module="MultiFrameFunctionalGroupsForIVOCTImageForProcessing"	Usage="C"	Condition="PresentationIntentTypeIsForProcessing"
+		Module="MultiFrameDimension"									Usage="M"
+		Module="AcquisitionContext"										Usage="M"
+		Module="CardiacSynchronization"									Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="IntravascularOCTImage"									Usage="M"
+		Module="IntravascularOCTAcquisitionParameters"					Usage="M"
+		Module="IntravascularOCTProcessingParameters"					Usage="C"	Condition="PresentationIntentTypeIsForProcessing"
+		Module="IntravascularImageAcquisitionParameters"				Usage="M"
+		Module="Device"													Usage="U"	Condition="NeedModuleDevice"
+		Module="SOPCommon"												Usage="M"
+		Module="CommonInstanceReference"								Usage="M"
+		Module="FrameExtraction"										Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="ParametricMap" Condition="ParametricMapInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"									Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"												Usage="M"
+		Module="ClinicalTrialSubject"									Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"											Usage="M"
+		Module="PatientStudy"											Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"										Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"											Usage="M"
+		Module="ParametricMapSeries"									Usage="M"
+		Module="ClinicalTrialSeries"									Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"										Usage="M"
+		Module="EnhancedGeneralEquipment"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"											Usage="M"
+		Module="ImagePixel"												Usage="C"	Condition="PixelDataPresent"
+		Module="FloatingPointImagePixel"								Usage="C"	Condition="FloatPixelDataPresent"
+		Module="DoubleFloatingPointImagePixel"							Usage="C"	Condition="DoubleFloatPixelDataPresent"
+		Module="ParametricMapImage"										Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"						Usage="M"
+		Module="MultiFrameFunctionalGroupsForParametricMap"				Usage="M"
+		Module="MultiFrameDimension"									Usage="M"
+		Module="CardiacSynchronization"									Usage="U"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"								Usage="U"	Condition="NeedModuleRespiratorySynchronization"
+		Module="BulkMotionSynchronization"								Usage="U"	Condition="NeedModuleBulkMotion"
+		Module="AcquisitionContext"										Usage="M"
+		Module="Device"													Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"												Usage="U"	Condition="NeedModuleSpecimen"
+		Module="CommonInstanceReference"								Usage="C"	Condition="NeedModuleCommonInstanceReference"	# really should check if contained references are present :(
+		Module="SOPCommon"												Usage="M"
+		Module="FrameExtraction"										Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
diff --git a/libsrc/standard/iodcomp/ct.tpl b/libsrc/standard/iodcomp/ct.tpl
new file mode 100644
index 0000000..64b3297
--- /dev/null
+++ b/libsrc/standard/iodcomp/ct.tpl
@@ -0,0 +1,134 @@
+CompositeIOD="EnhancedCTImage"			Condition="EnhancedCTImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="CTSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="EnhancedContrastBolus"							Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedCTImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="SupplementalPaletteColorLUT"					Usage="C"	Condition="NeedModuleSupplementalPaletteColorLUT"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedCTImage"								Usage="M"
+		Module="ICCProfile"										Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="LegacyConvertedEnhancedCTImage"	Condition="LegacyConvertedEnhancedCTImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="CTSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="ContrastBolus"									Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="EnhancedContrastBolus"							Usage="U"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForLegacyConvertedEnhancedCTImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"							Usage="U"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="U"	Condition="NeedModuleRespiratorySynchronization"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedCTImage"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="PrivatePixelMedLegacyConvertedEnhancedCTImage"	Condition="PrivatePixelMedLegacyConvertedEnhancedCTImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="CTSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="ContrastBolus"									Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForPrivatePixelMedLegacyConvertedEnhancedCTImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="C"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedCTImage"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
diff --git a/libsrc/standard/iodcomp/dx.tpl b/libsrc/standard/iodcomp/dx.tpl
new file mode 100755
index 0000000..7fa6850
--- /dev/null
+++ b/libsrc/standard/iodcomp/dx.tpl
@@ -0,0 +1,796 @@
+CompositeIOD="DXImageForProcessing"			Condition="DXImageForProcessingInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="DXImageForPresentation"			Condition="DXImageForPresentationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyImageForProcessing"			Condition="MammographyImageForProcessingInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="MammographySeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="MammographyImage"			Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyImageForPresentation"			Condition="MammographyImageForPresentationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="MammographySeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="MammographyImage"			Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyImageForProcessingIHEMammo"			Condition="MammographyImageForProcessingInstance"	Profile="IHEMammo"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="MammographySeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="MammographyImage"			Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="IHEMammoProfile"			Usage="M"
+		Module="IHEMammoProfileWithoutPartialViewOption"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyImageForProcessingIHEMammoPartialViewOption"			Condition="MammographyImageForProcessingInstance"	Profile="IHEMammoPartialViewOption"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="MammographySeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="MammographyImage"			Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="IHEMammoProfile"			Usage="M"
+		Module="IHEMammoProfileWithPartialViewOption"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyImageForPresentationIHEMammo"			Condition="MammographyImageForPresentationInstance"	Profile="IHEMammo"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="MammographySeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="MammographyImage"			Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="IHEMammoProfile"			Usage="M"
+		Module="IHEMammoProfileWithoutPartialViewOption"		Usage="M"
+		Module="IHEMammoProfileForPresentationOnly"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyImageForPresentationIHEMammoPartialViewOption"			Condition="MammographyImageForPresentationInstance"	Profile="IHEMammoPartialViewOption"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="MammographySeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="MammographyImage"			Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="IHEMammoProfile"			Usage="M"
+		Module="IHEMammoProfileWithPartialViewOption"		Usage="M"
+		Module="IHEMammoProfileForPresentationOnly"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="IntraoralImageForProcessing"			Condition="IntraoralImageForProcessingInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="IntraoralSeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="IntraoralImage"				Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="IntraoralImageForPresentation"			Condition="IntraoralImageForPresentationInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="IntraoralSeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="IntraoralImage"				Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="IntraoralImageForPresentationDentalMedia"			Condition="IntraoralImageForPresentationInstance"	Profile="Dental"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+		Module="IntraoralSeries"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="IntraoralImage"				Usage="M"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="DentalImageOnMediaProfile"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="DXImageForPresentationDentalMedia"			Condition="DXImageForPresentationInstance"	Profile="Dental"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="DXAnatomyImaged"			Usage="M"
+		Module="DXImage"					Usage="M"
+		Module="DXDetector"					Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DXPositioning"				Usage="U"	Condition="NeedModuleDXPositioning"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayAcquisitionDose"		Usage="U"	Condition="NeedModuleXRayAcquisitionDose"
+		Module="XRayGeneration"				Usage="U"	Condition="NeedModuleXRayGeneration"
+		Module="XRayFiltration"				Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"					Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="OverlayPlane"				Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="C"	Condition="DXNeedModuleVOILUT"
+		Module="ImageHistogram"				Usage="U"	Condition="NeedModuleImageHistogram"
+		Module="AcquisitionContext"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="DentalImageOnMediaProfile"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="BreastTomosynthesisImage"					Condition="BreastTomosynthesisInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedMammographySeries"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="U"	Condition="NeedModuleFrameOfReference"
+		Module="Synchronization"						Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="M"
+		Module="EnhancedGeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"												Usage="M"
+		Module="EnhancedContrastBolus"									Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Device"													Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"											Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"										Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"						Usage="M"
+		Module="MultiFrameFunctionalGroupsForBreastTomosynthesisImage"	Usage="M"
+		Module="MultiFrameDimension"									Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="ImageEquipmentCoordinateRelationship"					Usage="U"	Condition="NeedModuleImageEquipmentCoordinateRelationship"
+		Module="Specimen"												Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRay3DImage"											Usage="M"
+		Module="BreastTomosynthesisContributingSources"					Usage="U"	Condition="NeedModuleBreastTomosynthesisContributingSources"
+		Module="BreastTomosynthesisAcquisition"							Usage="U"	Condition="NeedModuleBreastTomosynthesisAcquisition"
+		Module="XRay3DReconstruction"									Usage="U"	Condition="NeedModuleXRay3DReconstruction"
+		Module="BreastView"												Usage="M"
+		Module="SOPCommon"												Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"										Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="BreastTomosynthesisImageIHEDBT"				Condition="BreastTomosynthesisInstance"	Profile="IHEDBT"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedMammographySeries"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="U"	Condition="NeedModuleFrameOfReference"
+		Module="Synchronization"						Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="M"
+		Module="EnhancedGeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"												Usage="M"
+		Module="EnhancedContrastBolus"									Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Device"													Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"											Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"										Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"						Usage="M"
+		Module="MultiFrameFunctionalGroupsForBreastTomosynthesisImage"	Usage="M"
+		Module="MultiFrameDimension"									Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="ImageEquipmentCoordinateRelationship"					Usage="U"	Condition="NeedModuleImageEquipmentCoordinateRelationship"
+		Module="Specimen"												Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRay3DImage"											Usage="M"
+		Module="BreastTomosynthesisContributingSources"					Usage="U"	Condition="NeedModuleBreastTomosynthesisContributingSources"
+		Module="BreastTomosynthesisAcquisition"							Usage="U"	Condition="NeedModuleBreastTomosynthesisAcquisition"
+		Module="XRay3DReconstruction"									Usage="U"	Condition="NeedModuleXRay3DReconstruction"
+		Module="BreastView"												Usage="M"
+		Module="SOPCommon"												Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"										Usage="C"	Condition="NeedModuleFrameExtraction"
+		Module="IHEDBTProfile"			Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="BreastProjectionXRayImage"	Condition="BreastProjectionXRayImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"					Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"								Usage="M"
+		Module="ClinicalTrialSubject"					Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"							Usage="M"
+		Module="PatientStudy"							Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"						Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"							Usage="M"
+		Module="ClinicalTrialSeries"					Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="DXSeries"								Usage="M"
+		Module="EnhancedMammographySeries"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"						Usage="M"
+		Module="Synchronization"						Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"						Usage="M"
+		Module="EnhancedGeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="EnhancedMammographyImage"				Usage="M"
+		Module="BreastView"								Usage="M"
+		Module="ImagePixel"								Usage="M"
+		Module="EnhancedContrastBolus"					Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Device"									Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"							Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"						Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"		Usage="M"
+		Module="MultiFrameFunctionalGroupsForBreastProjectionXRayImage"	Usage="M"
+		Module="MultiFrameDimension"					Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="PatientOrientation"						Usage="M"
+		Module="Specimen"								Usage="U"	Condition="NeedModuleSpecimen"
+		Module="SOPCommon"								Usage="M"
+		Module="CommonInstanceReference"				Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"						Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
diff --git a/libsrc/standard/iodcomp/file.tpl b/libsrc/standard/iodcomp/file.tpl
new file mode 100755
index 0000000..02d68d4
--- /dev/null
+++ b/libsrc/standard/iodcomp/file.tpl
@@ -0,0 +1,21 @@
+CompositeIOD="BasicDirectory"					Condition="MediaStorageDirectoryInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="M"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Directory"
+		Module="FileSetIdentification"			Usage="M"
+		Module="DirectoryInformation"			Usage="U"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="BasicDirectoryDental"				Condition="MediaStorageDirectoryInstance"	Profile="Dental"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="M"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Directory"
+		Module="FileSetIdentification"			Usage="M"
+		Module="DirectoryInformation"			Usage="U"
+		Module="DirectoryInformationDental"		Usage="U"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/mr.tpl b/libsrc/standard/iodcomp/mr.tpl
new file mode 100755
index 0000000..4527b23
--- /dev/null
+++ b/libsrc/standard/iodcomp/mr.tpl
@@ -0,0 +1,263 @@
+CompositeIOD="EnhancedMRImage"			Condition="EnhancedMRImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="MRSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="EnhancedContrastBolus"							Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedMRImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="BulkMotionSynchronization"						Usage="C"	Condition="NeedModuleBulkMotion"
+		Module="SupplementalPaletteColorLUT"					Usage="C"	Condition="NeedModuleSupplementalPaletteColorLUT"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedMRImage"								Usage="M"
+		Module="MRPulseSequence"								Usage="C"	Condition="NeedModuleMRPulseSequence"
+		Module="ICCProfile"										Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EnhancedMRColorImage"			Condition="EnhancedMRColorImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="MRSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="EnhancedContrastBolus"							Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedMRImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="BulkMotionSynchronization"						Usage="C"	Condition="NeedModuleBulkMotion"
+		Module="SupplementalPaletteColorLUT"					Usage="C"	Condition="NeedModuleSupplementalPaletteColorLUT"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="C"	Condition="NeedModuleSpecimen"
+		Module="EnhancedMRImage"								Usage="M"
+		Module="MRPulseSequence"								Usage="C"	Condition="NeedModuleMRPulseSequence"
+		Module="ICCProfile"										Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MRSpectroscopy"			Condition="MRSpectroscopyInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="MRSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="MRSpectroscopy"
+		Module="EnhancedContrastBolus"							Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForMRSpectroscopy"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="BulkMotionSynchronization"						Usage="C"	Condition="NeedModuleBulkMotion"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="MRSpectroscopy"									Usage="M"
+		Module="MRSpectroscopyPulseSequence"					Usage="C"	Condition="NeedModuleMRSpectroscopyPulseSequence"
+		Module="MRSpectroscopyData"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RawData"			Condition="RawDataInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+		Module="Synchronization"			Usage="C"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="RawData"
+		Module="AcquisitionContext"			Usage="M"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="RawData"					Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="LegacyConvertedEnhancedMRImage"	Condition="LegacyConvertedEnhancedMRImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="MRSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="ContrastBolus"									Usage="U"	Condition="NeedModuleContrastBolus"
+		Module="EnhancedContrastBolus"							Usage="U"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForLegacyConvertedEnhancedMRImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"							Usage="U"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="U"	Condition="NeedModuleRespiratorySynchronization"
+		Module="BulkMotionSynchronization"						Usage="U"	Condition="NeedModuleBulkMotion"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedMRImage"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="PrivatePixelMedLegacyConvertedEnhancedMRImage"	Condition="PrivatePixelMedLegacyConvertedEnhancedMRImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="MRSeries"										Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="ContrastBolus"									Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForPrivatePixelMedLegacyConvertedEnhancedMRImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="C"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="BulkMotionSynchronization"						Usage="C"	Condition="NeedModuleBulkMotion"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedMRImage"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/pet.tpl b/libsrc/standard/iodcomp/pet.tpl
new file mode 100755
index 0000000..118c7d3
--- /dev/null
+++ b/libsrc/standard/iodcomp/pet.tpl
@@ -0,0 +1,175 @@
+CompositeIOD="PETImage"		Condition="PETImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="PETSeries"					Usage="M"
+		Module="PETIsotope"					Usage="M"
+		Module="PETMultigatedAcquisition"	Usage="C"	Condition="NeedModulePETMultigatedAcquisition"
+		Module="NMPETPatientOrientation"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePlane"					Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="PETImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="AcquisitionContext"			Usage="U"	Condition="NeedModuleAcquisitionContext"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="CheckSingleFramePseudo"		Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EnhancedPETImage"			Condition="EnhancedPETImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedPETSeries"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="Intervention"									Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"								Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedPETImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedPETIsotope"								Usage="M"
+		Module="EnhancedPETAcquisition"							Usage="M"
+		Module="EnhancedPETImage"								Usage="M"
+		Module="EnhancedPETCorrections"							Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="LegacyConvertedEnhancedPETImage"	Condition="LegacyConvertedEnhancedPETImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedPETSeries"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="Intervention"									Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"								Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForLegacyConvertedEnhancedPETImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="C"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedPETImage"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="PrivatePixelMedLegacyConvertedEnhancedPETImage"	Condition="PrivatePixelMedLegacyConvertedEnhancedPETImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedPETSeries"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="Synchronization"								Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"										Usage="M"
+		Module="ContrastBolus"									Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForPrivatePixelMedLegacyConvertedEnhancedPETImage"	Usage="M"
+		Module="MultiFrameDimension"							Usage="C"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedPETImage"								Usage="M"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
diff --git a/libsrc/standard/iodcomp/rt.tpl b/libsrc/standard/iodcomp/rt.tpl
new file mode 100755
index 0000000..5f268c7
--- /dev/null
+++ b/libsrc/standard/iodcomp/rt.tpl
@@ -0,0 +1,311 @@
+CompositeIOD="RTImage"		Condition="RTImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="Cine"						Usage="C"	Condition="NeedModuleCine"
+		Module="MultiFrame"					Usage="C"	Condition="NeedModuleMultiFrame"
+		Module="RTImage"					Usage="M"
+		Module="ModalityLUT"				Usage="U"	Condition="NeedModuleModalityLUT"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="Approval"					Usage="U"	Condition="NeedModuleApproval"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTDose"		Condition="RTDoseInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="C"	Condition="DoseDataGridbased"
+		Module="ImagePlane"					Usage="C"	Condition="DoseDataGridbased"
+		Module="ImagePixel"					Usage="C"	Condition="DoseDataGridbased"
+		Module="MultiFrame"					Usage="C"	Condition="DoseDataGridbasedAndNeedModuleMultiFrame"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="MultiFrameOverlay"			Usage="U"	Condition="NeedModuleMultiFrameOverlay"
+		Module="ModalityLUT"				Usage="U"	Condition="NeedModuleModalityLUT"
+		Module="RTDose"						Usage="M"
+		Module="RTDVH"						Usage="U"	Condition="NeedModuleRTDVH"
+		Module="StructureSet"				Usage="C"	Condition="DoseDataPointsOrCurves"
+		Module="ROIContour"					Usage="C"	Condition="DoseDataPointsOrCurves"
+		Module="RTDoseROI"					Usage="C"	Condition="DoseDataPointsOrCurves"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTStructureSet"		Condition="RTStructureSetInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="StructureSet"
+		Module="StructureSet"				Usage="M"
+		Module="ROIContour"					Usage="M"
+		Module="RTROIObservations"			Usage="M"
+		Module="Approval"					Usage="U"	Condition="NeedModuleApproval"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTPlan"			Condition="RTPlanInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Plan"
+		Module="RTGeneralPlan"				Usage="M"
+		Module="RTPrescription"				Usage="U"	Condition="NeedModuleRTPrescription"
+		Module="RTToleranceTables"			Usage="U"	Condition="NeedModuleRTToleranceTables"
+		Module="RTPatientSetup"				Usage="U"	Condition="NeedModuleRTPatientSetup"
+		Module="RTFractionScheme"			Usage="U"	Condition="NeedModuleRTFractionScheme"
+		Module="RTBeams"					Usage="C"	Condition="NeedRTBeams"
+		Module="RTBrachyApplicationSetups"	Usage="C"	Condition="NeedRTBrachyApplicationSetups"
+		Module="Approval"					Usage="U"	Condition="NeedModuleApproval"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTBeamsTreatmentRecord"			Condition="RTBeamsTreatmentRecordInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"						Usage="M"
+		Module="ClinicalTrialSubject"			Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"					Usage="M"
+		Module="PatientStudy"					Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"				Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"						Usage="M"
+		Module="ClinicalTrialSeries"			Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="TreatmentRecord"
+		Module="RTGeneralTreatmentRecord"		Usage="M"
+		Module="RTPatientSetup"					Usage="U"	Condition="NeedModuleRTPatientSetup"
+		Module="RTTreatmentMachineRecord"		Usage="M"
+		Module="MeasuredDoseReferenceRecord"	Usage="U"	Condition="NeedModuleMeasuredDoseReferenceRecord"
+		Module="CalculatedDoseReferenceRecord"	Usage="U"	Condition="NeedModuleCalculatedDoseReferenceRecord"
+		Module="RTBeamsSessionRecord"			Usage="M"
+		Module="RTTreatmentSummaryRecord"		Usage="U"	Condition="NeedModuleRTTreatmentSummaryRecord"
+		Module="SOPCommon"						Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTBrachyTreatmentRecord"			Condition="RTBrachyTreatmentRecordInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"						Usage="M"
+		Module="ClinicalTrialSubject"			Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"					Usage="M"
+		Module="PatientStudy"					Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"				Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"						Usage="M"
+		Module="ClinicalTrialSeries"			Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="TreatmentRecord"
+		Module="RTGeneralTreatmentRecord"		Usage="M"
+		Module="RTPatientSetup"					Usage="U"	Condition="NeedModuleRTPatientSetup"
+		Module="RTTreatmentMachineRecord"		Usage="M"
+		Module="MeasuredDoseReferenceRecord"	Usage="U"	Condition="NeedModuleMeasuredDoseReferenceRecord"
+		Module="CalculatedDoseReferenceRecord"	Usage="U"	Condition="NeedModuleCalculatedDoseReferenceRecord"
+		Module="RTBrachySessionRecord"			Usage="M"
+		Module="RTTreatmentSummaryRecord"		Usage="U"	Condition="NeedModuleRTTreatmentSummaryRecord"
+		Module="SOPCommon"						Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTTreatmentSummaryRecord"			Condition="RTTreatmentSummaryRecordInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="TreatmentRecord"
+		Module="RTGeneralTreatmentRecord"	Usage="M"
+		Module="RTTreatmentSummaryRecord"	Usage="U"	Condition="NeedModuleRTTreatmentSummaryRecord"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTIonPlan"			Condition="RTIonPlanInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"					Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Plan"
+		Module="RTGeneralPlan"				Usage="M"
+		Module="RTPrescription"				Usage="U"	Condition="NeedModuleRTPrescription"
+		Module="RTIonToleranceTables"		Usage="U"	Condition="NeedModuleRTIonToleranceTables"
+		Module="RTPatientSetup"				Usage="U"	Condition="NeedModuleRTPatientSetup"
+		Module="RTFractionScheme"			Usage="U"	Condition="NeedModuleRTFractionScheme"
+		Module="RTIonBeams"					Usage="C"	Condition="NeedRTIonBeams"
+		Module="Approval"					Usage="U"	Condition="NeedModuleApproval"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RTIonBeamsTreatmentRecord"			Condition="RTIonBeamsTreatmentRecordInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"			Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"						Usage="M"
+		Module="ClinicalTrialSubject"			Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"					Usage="M"
+		Module="PatientStudy"					Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"				Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="RTSeries"						Usage="M"
+		Module="ClinicalTrialSeries"			Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="TreatmentRecord"
+		Module="RTGeneralTreatmentRecord"		Usage="M"
+		Module="RTPatientSetup"					Usage="U"	Condition="NeedModuleRTPatientSetup"
+		Module="RTTreatmentMachineRecord"		Usage="M"
+		Module="MeasuredDoseReferenceRecord"	Usage="U"	Condition="NeedModuleMeasuredDoseReferenceRecord"
+		Module="CalculatedDoseReferenceRecord"	Usage="U"	Condition="NeedModuleCalculatedDoseReferenceRecord"
+		Module="RTIonBeamsSessionRecord"		Usage="M"
+		Module="RTTreatmentSummaryRecord"		Usage="U"	Condition="NeedModuleRTTreatmentSummaryRecord"
+		Module="SOPCommon"						Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/softcopy.tpl b/libsrc/standard/iodcomp/softcopy.tpl
new file mode 100755
index 0000000..03bb9ff
--- /dev/null
+++ b/libsrc/standard/iodcomp/softcopy.tpl
@@ -0,0 +1,212 @@
+CompositeIOD="GrayscaleSoftcopyPresentationState"	Condition="GrayscaleSoftcopyPresentationStateInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"				Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"							Usage="M"
+		Module="ClinicalTrialSubject"				Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"						Usage="M"
+		Module="PatientStudy"						Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"					Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"						Usage="M"
+		Module="ClinicalTrialSeries"				Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="PresentationSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Presentation"
+		Module="PresentationStateIdentification"	Usage="M"
+		Module="PresentationStateRelationship"		Usage="M"
+		Module="PresentationStateShutter"			Usage="M"
+		Module="PresentationStateMask"				Usage="M"
+		Module="Mask"								Usage="C"	Condition="NeedModuleMask"
+		Module="DisplayShutter"						Usage="C"	Condition="NeedModuleDisplayShutter"
+		Module="BitmapDisplayShutter"				Usage="C"	Condition="NeedModuleBitmapDisplayShutter"
+		Module="OverlayPlane"						Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="OverlayActivation"					Usage="C"	Condition="NeedModuleOverlayActivation"
+		Module="DisplayedArea"						Usage="M"
+		Module="GraphicAnnotation"					Usage="C"	Condition="NeedModuleGraphicAnnotation"
+		Module="SpatialTransformation"				Usage="C"	Condition="NeedModuleSpatialTransformation"
+		Module="GraphicLayer"						Usage="C"	Condition="NeedModuleGraphicLayer"
+		Module="ModalityLUT"						Usage="C"	Condition="NeedModuleModalityLUT"
+		Module="SoftcopyVOILUT"						Usage="C"	Condition="NeedModuleSoftcopyVOILUT"
+		Module="SoftcopyPresentationLUT"			Usage="M"
+		Module="SOPCommon"							Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="ColorSoftcopyPresentationState"	Condition="ColorSoftcopyPresentationStateInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"				Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"							Usage="M"
+		Module="ClinicalTrialSubject"				Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"						Usage="M"
+		Module="PatientStudy"						Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"					Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"						Usage="M"
+		Module="ClinicalTrialSeries"				Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="PresentationSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Presentation"
+		Module="PresentationStateIdentification"	Usage="M"
+		Module="PresentationStateRelationship"		Usage="M"
+		Module="PresentationStateShutter"			Usage="M"
+		Module="DisplayShutter"						Usage="C"	Condition="NeedModuleDisplayShutter"
+		Module="BitmapDisplayShutter"				Usage="C"	Condition="NeedModuleBitmapDisplayShutter"
+		Module="OverlayPlane"						Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="OverlayActivation"					Usage="C"	Condition="NeedModuleOverlayActivation"
+		Module="DisplayedArea"						Usage="M"
+		Module="GraphicAnnotation"					Usage="C"	Condition="NeedModuleGraphicAnnotation"
+		Module="SpatialTransformation"				Usage="C"	Condition="NeedModuleSpatialTransformation"
+		Module="GraphicLayer"						Usage="C"	Condition="NeedModuleGraphicLayer"
+		Module="ICCProfile"							Usage="M"
+		Module="SOPCommon"							Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="PseudoColorSoftcopyPresentationState"	Condition="PseudoColorSoftcopyPresentationStateInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"				Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"							Usage="M"
+		Module="ClinicalTrialSubject"				Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"						Usage="M"
+		Module="PatientStudy"						Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"					Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"						Usage="M"
+		Module="ClinicalTrialSeries"				Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="PresentationSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Presentation"
+		Module="PresentationStateIdentification"	Usage="M"
+		Module="PresentationStateRelationship"		Usage="M"
+		Module="PresentationStateShutter"			Usage="M"
+		Module="PresentationStateMask"				Usage="M"
+		Module="Mask"								Usage="C"	Condition="NeedModuleMask"
+		Module="DisplayShutter"						Usage="C"	Condition="NeedModuleDisplayShutter"
+		Module="BitmapDisplayShutter"				Usage="C"	Condition="NeedModuleBitmapDisplayShutter"
+		Module="OverlayPlane"						Usage="C"	Condition="NeedModuleOverlayPlane"
+		Module="OverlayActivation"					Usage="C"	Condition="NeedModuleOverlayActivation"
+		Module="DisplayedArea"						Usage="M"
+		Module="GraphicAnnotation"					Usage="C"	Condition="NeedModuleGraphicAnnotation"
+		Module="SpatialTransformation"				Usage="C"	Condition="NeedModuleSpatialTransformation"
+		Module="GraphicLayer"						Usage="C"	Condition="NeedModuleGraphicLayer"
+		Module="ModalityLUT"						Usage="C"	Condition="NeedModuleModalityLUT"
+		Module="SoftcopyVOILUT"						Usage="C"	Condition="NeedModuleSoftcopyVOILUT"
+		Module="PaletteColorLookupTable"			Usage="M"
+		Module="ICCProfile"							Usage="M"
+		Module="SOPCommon"							Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="BlendingSoftcopyPresentationState"	Condition="BlendingSoftcopyPresentationStateInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"				Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"							Usage="M"
+		Module="ClinicalTrialSubject"				Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"						Usage="M"
+		Module="PatientStudy"						Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"					Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"						Usage="M"
+		Module="ClinicalTrialSeries"				Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="PresentationSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Presentation"
+		Module="PresentationStateIdentification"	Usage="M"
+		Module="PresentationStateBlending"			Usage="M"
+		Module="DisplayedArea"						Usage="M"
+		Module="GraphicAnnotation"					Usage="C"	Condition="NeedModuleGraphicAnnotation"
+		Module="SpatialTransformation"				Usage="C"	Condition="NeedModuleSpatialTransformation"
+		Module="GraphicLayer"						Usage="C"	Condition="NeedModuleGraphicLayer"
+		Module="PaletteColorLookupTable"			Usage="M"
+		Module="ICCProfile"							Usage="M"
+		Module="SOPCommon"							Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="HangingProtocol"	Condition="HangingProtocolInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="HangingProtocol"
+		Module="HangingProtocolDefinition"	Usage="M"
+		Module="HangingProtocolEnvironment"	Usage="M"
+		Module="HangingProtocolDisplay"		Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="ColorPalette"	Condition="ColorPaletteInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="ColorPalette"
+		Module="ColorPaletteDefinition"		Usage="M"
+		Module="PaletteColorLookupTable"	Usage="M"
+		Module="ICCProfile"					Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="BasicStructuredDisplay"	Condition="BasicStructuredDisplayInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"				Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"							Usage="M"
+		Module="ClinicalTrialSubject"				Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"						Usage="M"
+		Module="PatientStudy"						Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"					Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"						Usage="M"
+		Module="ClinicalTrialSeries"				Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="PresentationSeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"					Usage="M"
+		Module="EnhancedGeneralEquipment"			Usage="U"	Condition="EnhancedGeneralEquipmentIsPresent"
+	InformationEntityEnd
+	InformationEntity="Presentation"
+		Module="StructuredDisplay"					Usage="M"
+		Module="StructuredDisplayImageBox"			Usage="M"
+		Module="StructuredDisplayAnnotation"		Usage="U"	Condition="NeedModuleStructuredDisplayAnnotation"
+		Module="CommonInstanceReference"			Usage="M"
+		Module="SOPCommon"							Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/sr.tpl b/libsrc/standard/iodcomp/sr.tpl
new file mode 100755
index 0000000..ffd682a
--- /dev/null
+++ b/libsrc/standard/iodcomp/sr.tpl
@@ -0,0 +1,364 @@
+CompositeIOD="BasicTextSR"				Condition="BasicTextSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EnhancedSR"				Condition="EnhancedSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="ComprehensiveSR"				Condition="ComprehensiveSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="Comprehensive3DSR"				Condition="Comprehensive3DSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="KeyObjectSelectionDocument"		Condition="KeyObjectSelectionDocumentStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="KeyObjectDocumentSeries"	Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="KeyObjectDocument"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="MammographyCADSR"				Condition="MammographyCADSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="ChestCADSR"				Condition="ChestCADSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="ProcedureLog"				Condition="ProcedureLogStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="XRayRadiationDoseSR"				Condition="XRayRadiationDoseSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="XRayRadiationDoseSRIHEREM"				Condition="XRayRadiationDoseSRStorageInstance"	Profile="IHEREM"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="IHEREMProfile"				Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="RadiopharmaceuticalRadiationDoseSR"	Condition="RadiopharmaceuticalRadiationDoseSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="SpectaclePrescriptionReport" Condition="SpectaclePrescriptionReportInstance"
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="AcquisitionContextSR"	Condition="AcquisitionContextSRStorageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="SRDocumentSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Document"
+		Module="SRDocumentGeneral"			Usage="M"
+		Module="SRDocumentContent"			Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/us.tpl b/libsrc/standard/iodcomp/us.tpl
new file mode 100644
index 0000000..4ffa30d
--- /dev/null
+++ b/libsrc/standard/iodcomp/us.tpl
@@ -0,0 +1,105 @@
+CompositeIOD="EnhancedUltrasoundVolume"			Condition="EnhancedUltrasoundVolumeInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedUSSeries"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="UltrasoundFrameOfReference"						Usage="M"
+		Module="Synchronization"								Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"									Usage="M"
+		Module="ImagePixel"										Usage="M"
+		Module="EnhancedContrastBolus"							Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedUSVolume"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedPaletteColorLookupTable"				Usage="U"	Condition="NeedModuleEnhancedPaletteColorLookupTable"
+		Module="EnhancedUSImage"								Usage="M"
+		Module="IVUSImage"										Usage="C"	Condition="ModalityIsIVUS"
+		Module="ExcludedIntervals"								Usage="U"	Condition="NeedModuleExcludedIntervals"
+		Module="ICCProfile"										Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EnhancedUltrasoundVolumeQTUS"			Condition="EnhancedUltrasoundVolumeInstance"	Profile="QTUS"
+	InformationEntity="File"
+		Module="FileMetaInformation"							Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"										Usage="M"
+		Module="ClinicalTrialSubject"							Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"									Usage="M"
+		Module="PatientStudy"									Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"								Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+		Module="QTUSEnhancedUltrasoundVolumeProfileStudy"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"									Usage="M"
+		Module="ClinicalTrialSeries"							Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedUSSeries"								Usage="M"
+		Module="QTUSEnhancedUltrasoundVolumeProfileSeries"		Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"								Usage="M"
+		Module="UltrasoundFrameOfReference"						Usage="M"
+		Module="Synchronization"								Usage="M"
+		Module="QTUSEnhancedUltrasoundVolumeProfileFrameOfReference"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"								Usage="M"
+		Module="EnhancedGeneralEquipment"						Usage="M"
+		Module="QTUSEnhancedUltrasoundVolumeProfileEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"									Usage="M"
+		Module="ImagePixel"										Usage="M"
+		Module="EnhancedContrastBolus"							Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedUSVolume"	Usage="M"
+		Module="MultiFrameDimension"							Usage="M"
+		Module="CardiacSynchronization"							Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"						Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="Device"											Usage="U"	Condition="NeedModuleDevice"
+		Module="AcquisitionContext"								Usage="M"
+		Module="Specimen"										Usage="U"	Condition="NeedModuleSpecimen"
+		Module="EnhancedPaletteColorLookupTable"				Usage="U"	Condition="NeedModuleEnhancedPaletteColorLookupTable"
+		Module="EnhancedUSImage"								Usage="M"
+		Module="IVUSImage"										Usage="C"	Condition="ModalityIsIVUS"
+		Module="ExcludedIntervals"								Usage="U"	Condition="NeedModuleExcludedIntervals"
+		Module="ICCProfile"										Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"										Usage="M"
+		Module="CommonInstanceReference"						Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"								Usage="C"	Condition="NeedModuleFrameExtraction"
+		Module="QTUSEnhancedUltrasoundVolumeProfileInstance"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/vl.tpl b/libsrc/standard/iodcomp/vl.tpl
new file mode 100755
index 0000000..1271929
--- /dev/null
+++ b/libsrc/standard/iodcomp/vl.tpl
@@ -0,0 +1,645 @@
+CompositeIOD="VLEndoscopicImage"		Condition="VisibleLightEndoscopicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLEndoscopicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# not check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="VLImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VLMicroscopicImage"		Condition="VisibleLightMicroscopicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLMicroscopicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# not check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="C"	Condition="NeedModuleSpecimen"	# real-world "is a specimen"
+		Module="VLImage"					Usage="M"
+		Module="OpticalPath"				Usage="U"	Condition="NeedModuleOpticalPath"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VLSlideCoordinatesMicroscopicImage"		Condition="VisibleLightSlideCoordinatesMicroscopicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLSlideCoordinatesMicroscopicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# not check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="M"
+		Module="VLImage"					Usage="M"
+		Module="SlideCoordinates"			Usage="M"
+		Module="OpticalPath"				Usage="U"	Condition="NeedModuleOpticalPath"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VLPhotographicImage"		Condition="VisibleLightPhotographicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLPhotographicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# not check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="C"	Condition="NeedModuleSpecimen"	# real-world "is a specimen"
+		Module="VLImage"					Usage="M"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="CheckSingleFramePseudo"		Usage="M"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VideoEndoscopicImage"			Condition="VideoEndoscopicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLEndoscopicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="Cine"						Usage="M"
+		Module="MultiFrame"					Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# no check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="C"	Condition="NeedModuleSpecimen"	# real-world "is a specimen"
+		Module="VLImage"					Usage="M"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VideoMicroscopicImage"		Condition="VideoMicroscopicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLMicroscopicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="Cine"						Usage="M"
+		Module="MultiFrame"					Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# not check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="C"	Condition="NeedModuleSpecimen"	# real-world "is a specimen"
+		Module="VLImage"					Usage="M"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VideoPhotographicImage"		Condition="VideoPhotographicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="VLPhotographicSeriesPseudo"	Usage="M"	# not in standard ... use to check conditions
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="Cine"						Usage="M"
+		Module="MultiFrame"					Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"	# not check for baseline CIDs yet
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Specimen"					Usage="C"	Condition="NeedModuleSpecimen"	# real-world "is a specimen"
+		Module="VLImage"					Usage="M"
+		Module="ICCProfile"					Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="OphthalmicPhotography8BitImage"		Condition="OphthalmicPhotography8BitImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"						Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"									Usage="M"
+		Module="ClinicalTrialSubject"						Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"								Usage="M"
+		Module="PatientStudy"								Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"							Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"								Usage="M"
+		Module="OphthalmicPhotographySeries"				Usage="M"
+		Module="ClinicalTrialSeries"						Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"								Usage="M"
+		Module="ImagePixel"									Usage="M"
+		Module="EnhancedContrastBolus"						Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Cine"										Usage="C"	Condition="NeedModuleCine"
+		Module="MultiFrame"									Usage="M"
+		Module="AcquisitionContext"							Usage="U"	Condition="NeedModuleAcquisitionContext"
+		Module="OphthalmicPhotographyImage"					Usage="M"
+		Module="OphthalmicPhotography8BitImagePseudo"		Usage="M"	# not in standard ... use to check bit depths
+		Module="OcularRegionImaged"							Usage="M"
+		Module="OphthalmicPhotographyAcquisitionParameters"	Usage="M"
+		Module="OphthalmicPhotographicParameters"			Usage="M"
+		Module="ICCProfile"									Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"									Usage="M"
+		Module="CommonInstanceReference"					Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"							Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="OphthalmicPhotography16BitImage"		Condition="OphthalmicPhotography16BitImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"						Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"									Usage="M"
+		Module="ClinicalTrialSubject"						Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"								Usage="M"
+		Module="PatientStudy"								Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"							Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"								Usage="M"
+		Module="OphthalmicPhotographySeries"					Usage="M"
+		Module="ClinicalTrialSeries"						Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"							Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"								Usage="M"
+		Module="ImagePixel"									Usage="M"
+		Module="EnhancedContrastBolus"						Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Cine"										Usage="C"	Condition="NeedModuleCine"
+		Module="MultiFrame"									Usage="M"
+		Module="AcquisitionContext"							Usage="U"	Condition="NeedModuleAcquisitionContext"
+		Module="OphthalmicPhotographyImage"					Usage="M"
+		Module="OphthalmicPhotography16BitImagePseudo"		Usage="M"	# not in standard ... use to check bit depths
+		Module="OcularRegionImaged"							Usage="M"
+		Module="OphthalmicPhotographyAcquisitionParameters"	Usage="M"
+		Module="OphthalmicPhotographicParameters"			Usage="M"
+		Module="ICCProfile"									Usage="U"	Condition="NeedModuleICCProfile"
+		Module="SOPCommon"									Usage="M"
+		Module="CommonInstanceReference"					Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"							Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+
+CompositeIOD="StereometricRelationship"			Condition="StereometricRelationshipInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="StereometricSeries"			Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="StereometricRelationship"	Usage="M"
+		Module="CommonInstanceReference"	Usage="M"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="OphthalmicTomographyImage"		Condition="OphthalmicTomographyImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"						Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"									Usage="M"
+		Module="ClinicalTrialSubject"						Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"								Usage="M"
+		Module="PatientStudy"								Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"							Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"								Usage="M"
+		Module="ClinicalTrialSeries"						Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="OphthalmicTomographySeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"							Usage="C"	Condition="NeedModuleFrameOfReference"			# condition is real-world (Ophthalmic Photography Reference Image available) ... just check if present
+		Module="Synchronization"							Usage="C"	Condition="NeedToCheckModuleSynchronization"	# condition is real-world (Ophthalmic Photography Reference Image available) ... just check if present
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"							Usage="M"
+		Module="EnhancedGeneralEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"									Usage="M"
+		Module="EnhancedContrastBolus"						Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="MultiFrameFunctionalGroupsCommon"			Usage="M"
+		Module="MultiFrameFunctionalGroupsForOphthalmicTomography"	Usage="M"
+		Module="MultiFrameDimension"						Usage="M"
+		Module="AcquisitionContext"							Usage="M"
+		Module="CardiacSynchronization"						Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="OphthalmicTomographyImage"					Usage="M"
+		Module="OphthalmicTomographyAcquisitionParameters"	Usage="M"
+		Module="OphthalmicTomographyParameters"				Usage="M"
+		Module="OcularRegionImaged"							Usage="M"
+		Module="SOPCommon"									Usage="M"
+		Module="CommonInstanceReference"					Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"							Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VLWholeSlideMicroscopyImage"		Condition="VLWholeSlideMicroscopyImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"						Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"									Usage="M"
+		Module="ClinicalTrialSubject"						Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"								Usage="M"
+		Module="PatientStudy"								Usage="U"	# no condition ... all attributes type 3
+		Module="ClinicalTrialStudy"							Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"								Usage="M"
+		Module="ClinicalTrialSeries"						Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="WholeSlideMicroscopySeries"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"							Usage="C"	Condition="NeedModuleFrameOfReference"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"							Usage="M"
+		Module="EnhancedGeneralEquipment"					Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"								Usage="M"
+		Module="ImagePixel"									Usage="M"
+		Module="AcquisitionContext"							Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"			Usage="M"
+		Module="MultiFrameFunctionalGroupsForWholeSlideMicroscopy"	Usage="M"
+		Module="MultiFrameDimension"						Usage="M"
+		Module="Specimen"									Usage="M"
+		Module="WholeSlideMicroscopyImage"					Usage="M"
+		Module="OpticalPath"								Usage="M"
+		Module="MultiResolutionNavigation"					Usage="C"	Condition="ImageTypeValue3Localizer"
+		Module="SlideLabel"									Usage="C"	Condition="ImageTypeValue3Label"
+		Module="SOPCommon"									Usage="M"
+		Module="CommonInstanceReference"					Usage="M"
+		Module="FrameExtraction"							Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="LensometryMeasurements" Condition="LensometryMeasurementsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="LensometryMeasurementsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="LensometryMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="AutorefractionMeasurements" Condition="AutorefractionMeasurementsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="AutorefractionMeasurementsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="AutorefractionMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="KeratometryMeasurements" Condition="KeratometryMeasurementsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="KeratometryMeasurementsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="KeratometryMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="SubjectiveRefractionMeasurements" Condition="SubjectiveRefractionMeasurementsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="SubjectiveRefractionMeasurementsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="SubjectiveRefractionMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="VisualAcuityMeasurements" Condition="VisualAcuityMeasurementsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="VisualAcuityMeasurementsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="VisualAcuityMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="OphthalmicAxialMeasurements" Condition="OphthalmicAxialMeasurementsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="OphthalmicAxialMeasurementsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="OphthalmicAxialMeasurements"	Usage="M"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="IntraocularLensCalculations" Condition="IntraocularLensCalculationsInstance"
+	InformationEntity="Patient"
+		Module="Patient"	Usage="M"
+		Module="ClinicalTrialSubject"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"	Usage="M"
+		Module="PatientStudy"	Usage="U"
+		Module="ClinicalTrialStudy"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"	Usage="M"
+		Module="IntraocularLensCalculationsSeries"	Usage="M"
+		Module="ClinicalTrialSeries"	Usage="U"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"	Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Measurements"
+		Module="IntraocularLensCalculations"	Usage="M"
+		Module="GeneralOphthalmicRefractiveMeasurements"	Usage="M"
+		Module="SOPCommon"	Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/waveform.tpl b/libsrc/standard/iodcomp/waveform.tpl
new file mode 100755
index 0000000..ef66b89
--- /dev/null
+++ b/libsrc/standard/iodcomp/waveform.tpl
@@ -0,0 +1,192 @@
+CompositeIOD="BasicVoice"		Condition="BasicVoiceInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Waveform"
+		Module="WaveformIdentification"		Usage="M"
+		Module="Waveform"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"
+		Module="WaveformAnnotation"			Usage="U"	Condition="NeedModuleWaveformAnnotation"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="TwelveLeadECG"				Condition="TwelveLeadECGInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Waveform"
+		Module="WaveformIdentification"		Usage="M"
+		Module="Waveform"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"
+		Module="WaveformAnnotation"			Usage="C"	Condition="NeedModuleWaveformAnnotation"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="GeneralECG"				Condition="GeneralECGInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Waveform"
+		Module="WaveformIdentification"		Usage="M"
+		Module="Waveform"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"
+		Module="WaveformAnnotation"			Usage="C"	Condition="NeedModuleWaveformAnnotation"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="AmbulatoryECG"				Condition="AmbulatoryECGInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Waveform"
+		Module="WaveformIdentification"		Usage="M"
+		Module="Waveform"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"
+		Module="WaveformAnnotation"			Usage="C"	Condition="NeedModuleWaveformAnnotation"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="HemodynamicWaveform"			Condition="HemodynamicWaveformInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="ReallyNeedModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Waveform"
+		Module="WaveformIdentification"		Usage="M"
+		Module="Waveform"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"
+		Module="WaveformAnnotation"			Usage="C"	Condition="NeedModuleWaveformAnnotation"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="CardiacElectrophysiologyWaveform"		Condition="CardiacElectrophysiologyWaveformInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd	
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="C"	Condition="ReallyNeedModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Waveform"
+		Module="WaveformIdentification"		Usage="M"
+		Module="Waveform"					Usage="M"
+		Module="AcquisitionContext"			Usage="M"
+		Module="WaveformAnnotation"			Usage="C"	Condition="NeedModuleWaveformAnnotation"
+		Module="SOPCommon"					Usage="M"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/iodcomp/xaxrf.tpl b/libsrc/standard/iodcomp/xaxrf.tpl
new file mode 100755
index 0000000..1960351
--- /dev/null
+++ b/libsrc/standard/iodcomp/xaxrf.tpl
@@ -0,0 +1,304 @@
+CompositeIOD="XAImage"		Condition="XAImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="Cine"						Usage="C"	Condition="NeedModuleCine"
+		Module="MultiFrame"					Usage="C" 	Condition="NeedModuleMultiFrame"
+		Module="FramePointers"				Usage="U"	Condition="NeedModuleFramePointers"
+		Module="Mask"						Usage="C" 	Condition="NeedModuleMask"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRayImage"					Usage="M"
+		Module="XRayAcquisition"			Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="XRayTable"					Usage="C"	Condition="NeedModuleXRayTable"
+		Module="XAPositioner"				Usage="M"
+		Module="DXDetector"					Usage="U"	Condition="NeedModuleDXDetector"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="MultiFrameOverlay"			Usage="C" 	Condition="NeedModuleMultiFrameOverlay"
+		Module="ModalityLUT"				Usage="C"	Condition="XRayNeedModuleModalityLUT"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="XRFImage"		Condition="XRFImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="GeneralImage"				Usage="M"
+		Module="ImagePixel"					Usage="M"
+		Module="ContrastBolus"				Usage="C"	Condition="NeedModuleContrastBolus"
+		Module="Cine"						Usage="C"	Condition="NeedModuleCine"
+		Module="MultiFrame"					Usage="C" 	Condition="NeedModuleMultiFrame"
+		Module="FramePointers"				Usage="U"	Condition="NeedModuleFramePointers"
+		Module="Mask"						Usage="C" 	Condition="NeedModuleMask"
+		Module="XRayImage"					Usage="M"
+		Module="XRayAcquisition"			Usage="M"
+		Module="XRayCollimator"				Usage="U"	Condition="NeedModuleXRayCollimator"
+		Module="DisplayShutter"				Usage="U"	Condition="NeedModuleDisplayShutter"
+		Module="Device"						Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"				Usage="U"	Condition="NeedModuleIntervention"
+		Module="Specimen"					Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRayTable"					Usage="C"	Condition="NeedModuleXRayTable"
+		Module="XRFPositioner"				Usage="U"
+		Module="XRayTomographyAcquisition"	Usage="U"	Condition="NeedModuleXRayTomographyAcquisitionBasedOnScanOptions"
+		Module="DXDetector"					Usage="U"	Condition="NeedModuleDXDetector"
+		Module="OverlayPlane"				Usage="U"	Condition="NeedModuleOverlayPlane"
+		Module="MultiFrameOverlay"			Usage="C" 	Condition="NeedModuleMultiFrameOverlay"
+		Module="ModalityLUT"				Usage="C"	Condition="XRayNeedModuleModalityLUT"
+		Module="VOILUT"						Usage="U"	Condition="NeedModuleVOILUT"
+		Module="SOPCommon"					Usage="M"
+		Module="CommonInstanceReference"	Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"			Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EnhancedXAImage"		Condition="EnhancedXAImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="XAXRFSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="C"	Condition="CArmPositionerTabletopRelationshipIsYes"
+		Module="Synchronization"			Usage="C"	Condition="CArmPositionerTabletopRelationshipIsYes"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"							Usage="M"
+		Module="EnhancedContrastBolus"				Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Mask"								Usage="U" 	Condition="NeedModuleMask"
+		Module="Device"								Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"						Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"					Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedXAImage"	Usage="M"
+		Module="MultiFrameDimension"				Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"				Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"			Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="Specimen"							Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRayFiltration"						Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"							Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="EnhancedXAXRFImage"					Usage="M"
+		Module="XAXRFAcquisition"					Usage="C"	Condition="ImageTypeValue1Original"
+		Module="XRayImageIntensifier"				Usage="C"	Condition="XRayReceptorTypeIsImageIntensifier"
+		Module="XRayDetector"						Usage="C"	Condition="XRayReceptorTypeIsDigitalDetector"
+		Module="XAXRFMultiFramePresentation"		Usage="U"	Condition="NeedModuleXAXRFMultiFramePresentation"
+		Module="SOPCommon"							Usage="M"
+		Module="CommonInstanceReference"			Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"					Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="EnhancedXRFImage"		Condition="EnhancedXRFImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="XAXRFSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="U"	Condition="NeedModuleFrameOfReference"
+		Module="Synchronization"			Usage="U"	Condition="NeedToCheckModuleSynchronization"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"							Usage="M"
+		Module="EnhancedContrastBolus"				Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Mask"								Usage="U" 	Condition="NeedModuleMask"
+		Module="Device"								Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"						Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"					Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"				Usage="M"
+		Module="MultiFrameFunctionalGroupsForEnhancedXRFImage"	Usage="M"
+		Module="MultiFrameDimension"				Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"				Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"			Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="Specimen"							Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRayTomographyAcquisition"			Usage="U"	Condition="NeedToCheckModuleXRayTomographyAcquisition"
+		Module="XRayFiltration"						Usage="U"	Condition="NeedModuleXRayFiltration"
+		Module="XRayGrid"							Usage="U"	Condition="NeedModuleXRayGrid"
+		Module="EnhancedXAXRFImage"					Usage="M"
+		Module="XAXRFAcquisition"					Usage="C"	Condition="ImageTypeValue1Original"
+		Module="XRayImageIntensifier"				Usage="C"	Condition="XRayReceptorTypeIsImageIntensifier"
+		Module="XRayDetector"						Usage="C"	Condition="XRayReceptorTypeIsDigitalDetector"
+		Module="XAXRFMultiFramePresentation"		Usage="U"	Condition="NeedModuleXAXRFMultiFramePresentation"
+		Module="SOPCommon"							Usage="M"
+		Module="CommonInstanceReference"			Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"					Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="XRay3DAngiographicImage"		Condition="XRay3DAngiographicImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedSeries"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"												Usage="M"
+		Module="EnhancedContrastBolus"									Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Device"													Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"											Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"										Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"						Usage="M"
+		Module="MultiFrameFunctionalGroupsForXRay3DAngiographicImage"	Usage="M"
+		Module="MultiFrameDimension"									Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="CardiacSynchronization"									Usage="C"	Condition="NeedModuleCardiacSynchronization"
+		Module="RespiratorySynchronization"								Usage="C"	Condition="NeedModuleRespiratorySynchronization"
+		Module="PatientOrientation"										Usage="U"	Condition="NeedModulePatientOrientation"
+		Module="ImageEquipmentCoordinateRelationship"					Usage="U"	Condition="NeedModuleImageEquipmentCoordinateRelationship"
+		Module="Specimen"												Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRay3DImage"											Usage="M"
+		Module="XRay3DAngiographicImageContributingSources"				Usage="U"	Condition="NeedModuleXRay3DAngiographicImageContributingSources"
+		Module="XRay3DAngiographicAcquisition"							Usage="U"	Condition="NeedModuleXRay3DAngiographicAcquisition"
+		Module="XRay3DReconstruction"									Usage="U"	Condition="NeedModuleXRay3DReconstruction"
+		Module="SOPCommon"												Usage="M"
+		Module="CommonInstanceReference"								Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"										Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
+CompositeIOD="XRay3DCraniofacialImage"		Condition="XRay3DCraniofacialImageInstance"
+	InformationEntity="File"
+		Module="FileMetaInformation"		Usage="C"	Condition="NeedModuleFileMetaInformation"
+	InformationEntityEnd
+	InformationEntity="Patient"
+		Module="Patient"					Usage="M"
+		Module="ClinicalTrialSubject"		Usage="U"	Condition="NeedModuleClinicalTrialSubject"
+	InformationEntityEnd
+	InformationEntity="Study"
+		Module="GeneralStudy"				Usage="M"
+		Module="PatientStudy"				Usage="U"
+		Module="ClinicalTrialStudy"			Usage="U"	Condition="NeedModuleClinicalTrialStudy"
+	InformationEntityEnd
+	InformationEntity="Series"
+		Module="GeneralSeries"				Usage="M"
+		Module="ClinicalTrialSeries"		Usage="U"	Condition="NeedModuleClinicalTrialSeries"
+		Module="EnhancedSeries"				Usage="M"
+	InformationEntityEnd
+	InformationEntity="FrameOfReference"
+		Module="FrameOfReference"			Usage="M"
+	InformationEntityEnd
+	InformationEntity="Equipment"
+		Module="GeneralEquipment"			Usage="M"
+		Module="EnhancedGeneralEquipment"	Usage="M"
+	InformationEntityEnd
+	InformationEntity="Image"
+		Module="ImagePixel"												Usage="M"
+		Module="EnhancedContrastBolus"									Usage="C"	Condition="NeedModuleEnhancedContrastBolus"
+		Module="Device"													Usage="U"	Condition="NeedModuleDevice"
+		Module="Intervention"											Usage="U"	Condition="NeedModuleIntervention"
+		Module="AcquisitionContext"										Usage="M"
+		Module="MultiFrameFunctionalGroupsCommon"						Usage="M"
+		Module="MultiFrameFunctionalGroupsForXRay3DCraniofacialImage"	Usage="M"
+		Module="MultiFrameDimension"									Usage="U"	Condition="NeedModuleMultiFrameDimension"
+		Module="PatientOrientation"										Usage="U"	Condition="NeedModulePatientOrientation"
+		Module="ImageEquipmentCoordinateRelationship"					Usage="U"	Condition="NeedModuleImageEquipmentCoordinateRelationship"
+		Module="Specimen"												Usage="U"	Condition="NeedModuleSpecimen"
+		Module="XRay3DImage"											Usage="M"
+		Module="XRay3DCraniofacialImageContributingSources"				Usage="U"	Condition="NeedModuleXRay3DCraniofacialImageContributingSources"
+		Module="XRay3DCraniofacialAcquisition"							Usage="U"	Condition="NeedModuleXRay3DCraniofacialAcquisition"
+		Module="XRay3DReconstruction"									Usage="U"	Condition="NeedModuleXRay3DReconstruction"
+		Module="SOPCommon"												Usage="M"
+		Module="CommonInstanceReference"								Usage="U"	Condition="NeedModuleCommonInstanceReference"
+		Module="FrameExtraction"										Usage="C"	Condition="NeedModuleFrameExtraction"
+	InformationEntityEnd
+CompositeIODEnd
+
diff --git a/libsrc/standard/module/Imakefile b/libsrc/standard/module/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/standard/module/acqctx.tpl b/libsrc/standard/module/acqctx.tpl
new file mode 100755
index 0000000..332869e
--- /dev/null
+++ b/libsrc/standard/module/acqctx.tpl
@@ -0,0 +1,29 @@
+Module="AcquisitionContext"
+	Sequence="AcquisitionContextSequence"			Type="2"	VM="0-n"
+		Name="ValueType"							Type="3"	StringDefinedTerms="AcquisitionContextValueTypes"
+		Sequence="ConceptNameCodeSequence"			Type="1"	VM="1"	# should check for 1 and only 1 item present
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="ReferencedFrameNumbers"				Type="1C"	NoCondition=""	NotZeroError=""
+		Name="NumericValue"							Type="1C"	VM="1-n" Condition="AcquisitionContextItemIsNumeric"
+		Name="FloatingPointValue"					Type="1C"	VM="1-n" NoCondition=""																# should check that VM is same as NumericValue :(
+		Verify="FloatingPointValue"								Condition="FloatingPointValuePresentButAcquisitionContextItemIsNotNumeric"			ThenErrorMessage="May not be present when NumericValue is absent"
+		Name="RationalNumeratorValue"				Type="1C"	VM="1-n" NoCondition=""																# should check that VM is same as NumericValue :(
+		Verify="RationalNumeratorValue"							Condition="RationalNumeratorValuePresentButAcquisitionContextItemIsNotNumeric"		ThenErrorMessage="May not be present when NumericValue is absent"
+		Name="RationalDenominatorValue"				Type="1C"	VM="1-n" Condition="RationalNumeratorValueIsPresent" NotZeroError=""				# should check that VM is same as NumericValue :(
+		Verify="RationalDenominatorValue"						Condition="RationalDenominatorValuePresentButAcquisitionContextItemIsNotNumeric"	ThenErrorMessage="May not be present when NumericValue is absent"
+		Sequence="MeasurementUnitsCodeSequence"		Type="1C"	VM="1"	Condition="NeedMeasurementUnitsCodeSequence"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Verify="MeasurementUnitsCodeSequence"					Condition="MeasurementUnitsCodeSequencePresentAndNumericValueAbsent"	ThenErrorMessage="May not be present when NumericValue is absent"
+		Name="Date"									Type="1C"	Condition="AcquisitionContextItemIsDate"
+		Name="Time"									Type="1C"	Condition="AcquisitionContextItemIsTime"
+		Name="PersonName"							Type="1C"	Condition="AcquisitionContextItemIsPersonName"
+		Name="TextValue"							Type="1C"	Condition="AcquisitionContextItemIsTextValue"
+		Sequence="ConceptCodeSequence"				Type="1C"	VM="1"	Condition="AcquisitionContextItemIsConceptCodeSequence"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="AcquisitionContextDescription"			Type="3"
+ModuleEnd
+
diff --git a/libsrc/standard/module/base.tpl b/libsrc/standard/module/base.tpl
new file mode 100755
index 0000000..e98fd82
--- /dev/null
+++ b/libsrc/standard/module/base.tpl
@@ -0,0 +1,2704 @@
+DefineMacro="IconImageSequenceMacro"
+	#InvokeMacro="ImagePixelMacro" # would be nice to do this, but can't then insert verify statements (undeclared variables)
+	Name="SamplesPerPixel"							Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="IconImagePhotometricInterpretation"
+	Name="Rows"										Type="1"	NotZeroError=""
+	Name="Columns"									Type="1"	NotZeroError=""
+	Name="BitsAllocated"							Type="1"	BinaryEnumValues="BitsAre1Or8"
+	Name="BitsStored"								Type="1"	BinaryEnumValues="BitsAre1Or8"
+	Name="HighBit"									Type="1"	BinaryEnumValues="BitsAre0Or7"
+	Name="PixelRepresentation"						Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="PixelData"								Type="1"
+	Name="PlanarConfiguration"						Type="1C"	BinaryEnumValues="PlanarConfiguration"	Condition="Never"
+	Name="PixelAspectRatio"							Type="3"	BinaryEnumValues="One"
+	Name="SmallestImagePixelValue"					Type="3"
+	Name="LargestImagePixelValue"					Type="3"
+	Name="RedPaletteColorLookupTableDescriptor"		Type="1C"	Condition="PhotometricInterpretationNeedsPalette"
+	Verify="RedPaletteColorLookupTableDescriptor"				ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+	Name="GreenPaletteColorLookupTableDescriptor"	Type="1C"	Condition="PhotometricInterpretationNeedsPalette"
+	Verify="GreenPaletteColorLookupTableDescriptor"				ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+	Name="BluePaletteColorLookupTableDescriptor"	Type="1C"	Condition="PhotometricInterpretationNeedsPalette"
+	Verify="BluePaletteColorLookupTableDescriptor"				ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+	Name="RedPaletteColorLookupTableData"			Type="1C"	Condition="PhotometricInterpretationNeedsPalette"
+	Name="GreenPaletteColorLookupTableData"			Type="1C"	Condition="PhotometricInterpretationNeedsPalette"
+	Name="BluePaletteColorLookupTableData"			Type="1C"	Condition="PhotometricInterpretationNeedsPalette"
+	Name="ICCProfile"								Type="3"
+MacroEnd
+
+DefineMacro="BasicCodeSequenceMacro"
+	Name="CodeValue"						Type="1C"	Condition="LongCodeValueAndURNCodeValueAbsent"
+	Verify="CodeValue"									Condition="CodeValueIllegalOrDeprecated"	ThenErrorMessage="Code Value is illegal or deprecated" ShowValueWithMessage="true"
+	Name="CodingSchemeDesignator"			Type="1C"	Condition="CodeValueOrLongCodeValuePresent"	StringDefinedTerms="MiscellaneousCodingSchemeDesignators"	mbpo="true"
+	Verify="CodingSchemeDesignator"						Condition="CodingSchemeDesignatorDeprecated"	ThenWarningMessage="Coding Scheme Designator is deprecated" ShowValueWithMessage="true"
+	Name="CodingSchemeVersion"				Type="1C"	Condition="CodingSchemeVersionRequired" mbpo="true"
+	Name="CodeMeaning"						Type="1"
+	Verify="CodeMeaning"								Condition="CodeMeaningIllegalOrDeprecated"	ThenErrorMessage="Code Meaning is illegal or deprecated" ShowValueWithMessage="true"
+	Name="LongCodeValue"					Type="1C"	Condition="CodeValueAndURNCodeValueAbsent"
+	Name="URNCodeValue"						Type="1C"	Condition="CodeValueAndLongCodeValueAbsent"
+MacroEnd
+
+DefineMacro="CodeSequenceMacro"
+	InvokeMacro="BasicCodeSequenceMacro"
+	Sequence="EquivalentCodeSequence"		Type="3"	VM="1-n"
+		InvokeMacro="BasicCodeSequenceMacro"
+	SequenceEnd
+	Name="ContextIdentifier"				Type="3"
+	Name="ContextUID"						Type="3"
+	Name="MappingResource"					Type="1C"	Condition="ContextIdentifierIsPresent"
+	Name="MappingResourceUID"				Type="3"	StringDefinedTerms="MappingResourceUIDs"
+	Name="ContextGroupVersion"				Type="1C"	Condition="ContextIdentifierIsPresent"
+	Name="ContextGroupExtensionFlag"		Type="3"	StringEnumValues="YesNoLetter"
+	Name="ContextGroupLocalVersion"			Type="1C"	Condition="ExtendedCodingScheme"
+	Name="ContextGroupExtensionCreatorUID"	Type="1C"	Condition="ExtendedCodingScheme"
+MacroEnd
+
+DefineMacro="CodeSequenceMeaningOptionalMacro"
+	Name="CodeValue"						Type="1"
+	Verify="CodeValue"									Condition="CodeValueIllegalOrDeprecated"	ThenErrorMessage="Code Value is illegal or deprecated" ShowValueWithMessage="true"
+	Name="CodingSchemeDesignator"			Type="1"	StringDefinedTerms="MiscellaneousCodingSchemeDesignators"
+	Verify="CodingSchemeDesignator"						Condition="CodingSchemeDesignatorDeprecated"	ThenWarningMessage="Coding Scheme Designator is deprecated" ShowValueWithMessage="true"
+	Name="CodingSchemeVersion"				Type="1C"	Condition="CodingSchemeVersionRequired"
+	Name="CodeMeaning"						Type="3"
+	Verify="CodeMeaning"								Condition="CodeMeaningEmptyOrNotPresent"	ThenWarningMessage="Code Meaning is missing or empty, which is legal but undesirable"
+	Name="ContextIdentifier"				Type="3"
+	Name="ContextUID"						Type="3"
+	Name="MappingResource"					Type="1C"	Condition="ContextIdentifierIsPresent"
+	Name="ContextGroupVersion"				Type="1C"	Condition="ContextIdentifierIsPresent"
+	Name="ContextGroupExtensionFlag"		Type="3"	StringEnumValues="YesNoLetter"
+	Name="ContextGroupLocalVersion"			Type="1C"	Condition="ExtendedCodingScheme"
+	Name="ContextGroupExtensionCreatorUID"	Type="1C"	Condition="ExtendedCodingScheme"
+MacroEnd
+
+DefineMacro="CodeSequence99SDMMacro"
+	Name="CodeValue"						Type="1"
+	Verify="CodeValue"									Condition="CodeValueIllegalOrDeprecated"	ThenErrorMessage="Code Value is illegal or deprecated" ShowValueWithMessage="true"
+	Name="CodingSchemeDesignator"			Type="1"	StringEnumValues="CodingSchemeDesignatorForSNOMEDDICOMMicroglossary"
+	Name="CodingSchemeVersion"				Type="1C"	Condition="CodingSchemeVersionRequired"
+	Name="CodeMeaning"						Type="3"
+	Verify="CodeMeaning"								Condition="CodeMeaningEmptyOrNotPresent"	ThenWarningMessage="Code Meaning is missing or empty, which is legal but undesirable"
+	Name="ContextIdentifier"				Type="3"
+	Name="ContextUID"						Type="3"
+	Name="MappingResource"					Type="1C"	Condition="ContextIdentifierIsPresent"
+	Name="ContextGroupVersion"				Type="1C"	Condition="ContextIdentifierIsPresent"
+	Name="ContextGroupExtensionFlag"		Type="3"	StringEnumValues="YesNoLetter"
+	Name="ContextGroupLocalVersion"			Type="1C"	Condition="ExtendedCodingScheme"
+	Name="ContextGroupExtensionCreatorUID"	Type="1C"	Condition="ExtendedCodingScheme"
+MacroEnd
+
+DefineMacro="PersonIdentificationMacro"
+	Sequence="PersonIdentificationCodeSequence"	Type="1"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="PersonAddress"						Type="3"
+	Name="PersonTelephoneNumbers"				Type="3"
+	Name="InstitutionName"						Type="1C"	Condition="InstitutionCodeSequenceNotPresent"
+	Name="InstitutionAddress"					Type="3"
+	Sequence="InstitutionCodeSequence"			Type="1C"	VM="1"	Condition="InstitutionNameNotPresent"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="ContentItemMacro"
+	Name="ValueType"						Type="1"	StringDefinedTerms="ContentItemValueTypes"
+	Sequence="ConceptNameCodeSequence"		Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="DateTime"							Type="1C"	Condition="ValueTypeIsDateTime"
+	Name="Date"								Type="1C"	Condition="ValueTypeIsDate"
+	Name="Time"								Type="1C"	Condition="ValueTypeIsTime"
+	Name="PersonName"						Type="1C"	Condition="ValueTypeIsPersonName"
+	Name="UID"								Type="1C"	Condition="ValueTypeIsUID"
+	Name="TextValue"						Type="1C"	Condition="ValueTypeIsText"
+	Sequence="ConceptCodeSequence"			Type="1C"	VM="1"	Condition="ValueTypeIsCode"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="NumericValue"						Type="1C"	Condition="ValueTypeIsNumeric"
+	Name="FloatingPointValue"				Type="1C"	NoCondition=""
+	Verify="FloatingPointValue"							Condition="FloatingPointValuePresentButValueTypeIsNotNumeric"	ThenErrorMessage="May only be present for NUMERIC ValueType"
+	Name="RationalNumeratorValue"			Type="1C"	NoCondition=""
+	Verify="RationalNumeratorValue"						Condition="RationalNumeratorValuePresentButValueTypeIsNotNumeric"	ThenErrorMessage="May only be present for NUMERIC ValueType"
+	Name="RationalDenominatorValue"			Type="1C"	Condition="RationalNumeratorValueIsPresent" NotZeroError=""
+	Verify="RationalDenominatorValue"					Condition="RationalDenominatorValueButValueTypeIsNotNumeric"	ThenErrorMessage="May only be present for NUMERIC ValueType"
+	Sequence="MeasurementUnitsCodeSequence"	Type="1C"	VM="1"	Condition="ValueTypeIsNumeric"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="ReferencedSOPSequence"		Type="1C"	VM="1"	Condition="ValueTypeIsCompositeOrImage"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Name="ReferencedFrameNumber"		Type="1C"	NoCondition=""	NotZeroError=""	# cannot just check SOP Class and mbpo false, since may be absent for multi-frame if applies to all frames (including multi-frame SOP Class with only 1 frame) :(
+		Verify="ReferencedFrameNumber"					Condition="ReferencedFrameNumberPresentAndReferencedSOPClassUIDIsNotMultiFrame"	ThenErrorMessage="May not be present for Referenced SOP Class that is not multi-frame"
+		Name="ReferencedSegmentNumber"		Type="1C"	NoCondition=""	NotZeroError=""	# cannot just check SOP Class and mbpo false, since may be absent for segmentation if applies to all segments :(
+		Verify="ReferencedSegmentNumber"				Condition="ReferencedSegmentNumberPresentAndReferencedSOPClassUIDIsNotSegmentationOrSurfaceSegmentation"	ThenErrorMessage="May not be present for Referenced SOP Class that is not segmentation"
+		Verify="ReferencedSegmentNumber"				Condition="ReferencedFrameNumberAndReferencedSegmentNumberPresent"	ThenErrorMessage="May not be present when ReferencedFrameNumber is present"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="ImageSOPInstanceReferenceMacro" InformationEntity="Image"
+	InvokeMacro="SOPInstanceReferenceMacro"
+	Name="ReferencedFrameNumber"					Type="1C"	NoCondition=""	NotZeroError=""	# cannot just check SOP Class and mbpo false, since may be absent for multi-frame if applies to all frames (including multi-frame SOP Class with only 1 frame) :(
+	Verify="ReferencedFrameNumber"								Condition="ReferencedFrameNumberPresentAndReferencedSOPClassUIDIsNotMultiFrame"	ThenErrorMessage="May not be present for Referenced SOP Class that is not multi-frame"
+	Name="ReferencedSegmentNumber"					Type="1C"	NoCondition=""	NotZeroError=""	# cannot just check SOP Class and mbpo false, since may be absent for segmentation if applies to all segments :(
+	Verify="ReferencedSegmentNumber"							Condition="ReferencedSegmentNumberPresentAndReferencedSOPClassUIDIsNotSegmentationOrSurfaceSegmentation"	ThenErrorMessage="May not be present for Referenced SOP Class that is not segmentation"
+	Verify="ReferencedSegmentNumber"							Condition="ReferencedFrameNumberAndReferencedSegmentNumberPresent"	ThenErrorMessage="May not be present when ReferencedFrameNumber is present"
+MacroEnd
+
+DefineMacro="SeriesAndInstanceReferenceMacro" InformationEntity="Image"
+	Sequence="ReferencedSeriesSequence"				Type="1"	VM="1-n"
+		Name="SeriesInstanceUID"					Type="1"
+		Sequence="ReferencedInstanceSequence"		Type="1"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PrimaryAnatomicStructureMacro" InformationEntity="Frame"
+	Sequence="PrimaryAnatomicStructureSequence"				Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="PrimaryAnatomicStructureModifierSequence"	Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"	BaselineContextID="2"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="GeneralAnatomyMandatoryMacro" InformationEntity="Frame"
+	Sequence="AnatomicRegionSequence"						Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="AnatomicRegionModifierSequence"			Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"	BaselineContextID="2"
+		SequenceEnd
+	SequenceEnd
+	InvokeMacro="PrimaryAnatomicStructureMacro"
+	Sequence="AnatomicRegionModifierSequence"				Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+	Sequence="PrimaryAnatomicStructureModifierSequence"		Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="GeneralAnatomyRequiredMacro" InformationEntity="Frame"
+	Sequence="AnatomicRegionSequence"						Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="AnatomicRegionModifierSequence"			Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"	BaselineContextID="2"
+		SequenceEnd
+	SequenceEnd
+	Verify="AnatomicRegionSequence"													Condition="AnatomicRegionSequencePresentAndEmptyButBodyPartExaminedHasValue"	ThenErrorMessage="AnatomicRegionSequence is only permitted to be empty when actually unknown, but BodyPartExamined has a value, therefore it is known"
+	InvokeMacro="PrimaryAnatomicStructureMacro"
+	Sequence="AnatomicRegionModifierSequence"				Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+	Sequence="PrimaryAnatomicStructureModifierSequence"		Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="GeneralAnatomyOptionalMacro" InformationEntity="Frame"
+	Sequence="AnatomicRegionSequence"						Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="AnatomicRegionModifierSequence"			Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"	BaselineContextID="2"
+		SequenceEnd
+	SequenceEnd
+	InvokeMacro="PrimaryAnatomicStructureMacro"
+	Sequence="AnatomicRegionModifierSequence"				Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+	Sequence="PrimaryAnatomicStructureModifierSequence"		Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="RequestAttributesMacro" InformationEntity="Series"
+	Name="RequestedProcedureID"							Type="1C"	NoCondition="" mbpo="true"
+	Name="AccessionNumber"								Type="3"
+	Sequence="IssuerOfAccessionNumberSequence"			Type="3"	VM="1"
+		InvokeMacro="HL7v2HierarchicDesignatorMacro"
+	SequenceEnd
+	Name="StudyInstanceUID"								Type="3"
+	Sequence="ReferencedStudySequence"					Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="RequestedProcedureDescription"				Type="3"
+	Sequence="RequestedProcedureCodeSequence"			Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="ReasonForTheRequestedProcedure"				Type="3"
+	Sequence="ReasonForRequestedProcedureCodeSequence"	Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="ScheduledProcedureStepID"						Type="1C"	NoCondition="" mbpo="true"
+	Name="ScheduledProcedureStepDescription"			Type="3"
+	Sequence="ScheduledProtocolCodeSequence"			Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="ProtocolContextSequence"				Type="3"	VM="1-n"
+			InvokeMacro="ContentItemMacro"
+			Sequence="ContentItemModifierSequence"		Type="3"	VM="1-n"
+				InvokeMacro="ContentItemMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="BasicPixelSpacingCalibrationMacro" InformationEntity="Frame"
+	Name="PixelSpacing"							Type="1C"	NoCondition=""	NotZeroError=""
+	Name="PixelSpacingCalibrationType"			Type="3"
+	Name="PixelSpacingCalibrationDescription"	Type="1C"	Condition="PixelSpacingCalibrationTypeIsPresent"
+MacroEnd
+
+DefineMacro="SOPInstanceReferenceMacro"
+	Name="ReferencedSOPClassUID"				Type="1"
+	Name="ReferencedSOPInstanceUID"				Type="1"
+MacroEnd
+
+DefineMacro="DisplayShutterMacro" InformationEntity="Frame"
+	Name="ShutterShape"							Type="1"	StringEnumValues="ShutterShape"
+	Name="ShutterLeftVerticalEdge"				Type="1C"	Condition="ShutterShapeIsRectangular"
+	Name="ShutterRightVerticalEdge"				Type="1C"	Condition="ShutterShapeIsRectangular"
+	Name="ShutterUpperHorizontalEdge"			Type="1C"	Condition="ShutterShapeIsRectangular"
+	Name="ShutterLowerHorizontalEdge"			Type="1C"	Condition="ShutterShapeIsRectangular"
+	Name="CenterOfCircularShutter"				Type="1C"	Condition="ShutterShapeIsCircular"
+	Name="RadiusOfCircularShutter"				Type="1C"	Condition="ShutterShapeIsCircular"
+	Name="VerticesOfThePolygonalShutter"		Type="1C"	Condition="ShutterShapeIsPolygonal"
+	Name="ShutterPresentationValue"				Type="3"
+	Name="ShutterPresentationColorCIELabValue"	Type="3"
+MacroEnd
+
+DefineMacro="ContentIdentificationMacro" InformationEntity="Instance"
+	Name="InstanceNumber"										Type="1"
+	Name="ContentLabel"											Type="1"
+	Name="ContentDescription"									Type="2"
+	Sequence="AlternateContentDescriptionSequence"				Type="3"	VM="1-n"
+		Name="ContentDescription"								Type="1"
+		Sequence="LanguageCodeSequence"							Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"									DefinedContextID="5000"
+		SequenceEnd
+	SequenceEnd
+	Name="ContentCreatorName"									Type="2"
+	Sequence="ContentCreatorIdentificationCodeSequence"		Type="3"	VM="1"
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="HL7v2HierarchicDesignatorMacro"
+	Name="LocalNamespaceEntityID"								Type="1C"	Condition="UniversalEntityIDNotPresent" mbpo="true"
+	Name="UniversalEntityID"									Type="1C"	Condition="LocalNamespaceEntityIDNotPresent" mbpo="true"
+	Name="UniversalEntityIDType"								Type="1C"	Condition="UniversalEntityIDPresent" StringDefinedTerms="UniversalEntityIDType"
+MacroEnd
+
+DefineMacro="IssuerOfPatientIDMacro"
+	Name="IssuerOfPatientID"									Type="3"
+	Sequence="IssuerOfPatientIDQualifiersSequence"				Type="3"	VM="1"
+		Name="UniversalEntityID"								Type="3"
+		Name="UniversalEntityIDType"							Type="3"	StringDefinedTerms="UniversalEntityIDType"
+		Name="IdentifierTypeCode"								Type="3"	StringDefinedTerms="HL7Table0203IdentifierType"
+		Sequence="AssigningFacilitySequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Sequence="AssigningJurisdictionCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"									BaselineContextID="5001"
+		SequenceEnd
+		Sequence="AssigningAgencyOrDepartmentCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="AlgorithmIdentificationMacro"
+	Sequence="AlgorithmFamilyCodeSequence"						Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="AlgorithmNameCodeSequence"						Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="AlgorithmName"										Type="1"
+	Name="AlgorithmVersion"										Type="1"
+	Name="AlgorithmParameters"									Type="3"
+	Name="AlgorithmSource"										Type="3"
+MacroEnd
+
+# no information entity specified for this macro, else screws up attributes that are otherwise at the Series entity level
+DefineMacro="GeneralContributingSourcesMacro"
+	Sequence="ContributingSOPInstancesReferenceSequence"	Type="1C"	VM="1-n"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		Name="StudyInstanceUID"								Type="3"
+		Sequence="ReferencedSeriesSequence"					Type="1"	VM="1-n"
+			Name="SeriesInstanceUID"						Type="1"
+			Name="SeriesNumber"								Type="2"
+			Sequence="ReferencedInstanceSequence"			Type="1"	VM="1-n"
+				InvokeMacro="SOPInstanceReferenceMacro"
+				Name="InstanceNumber"						Type="2"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	Name="Manufacturer"										Type="2"
+	Name="ManufacturerModelName"							Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="DeviceSerialNumber"								Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="SoftwareVersions"									Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="AcquisitionDateTime"								Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="StationName"										Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="OperatorsName"									Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Sequence="OperatorIdentificationSequence"				Type="1C"	VM="1-n"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+	Name="ProtocolName"										Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	Sequence="PerformedProtocolCodeSequence"				Type="1C"	VM="1-n"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="AcquisitionProtocolName"							Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+MacroEnd
+
+DefineMacro="ContributingImageSourcesMacro" InformationEntity="Instance"
+	Name="Rows"												Type="1"	NotZeroError=""
+	Name="Columns"											Type="1"	NotZeroError=""
+	Name="BitsStored"										Type="1"	NotZeroError=""
+	Name="LossyImageCompression"							Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"						Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+MacroEnd
+
+DefineMacro="PatientOrientationMacro" InformationEntity="Instance"
+	Sequence="PatientOrientationCodeSequence"				Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"									BaselineContextID="19"
+		Sequence="PatientOrientationModifierCodeSequence"   Type="1C"	VM="1"	NoCondition=""	# real-world - orientation wrt. gravity
+ 			InvokeMacro="CodeSequenceMacro"								BaselineContextID="20"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PatientGantryRelationshipCodeSequence"		Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"									BaselineContextID="21"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PerformedProcedureStepSummaryMacro" InformationEntity="Series"
+	Name="PerformedProcedureStepID"							Type="3"
+	Name="PerformedProcedureStepStartDate"					Type="3"
+	Name="PerformedProcedureStepStartTime"					Type="3"
+	Name="PerformedProcedureStepDescription"				Type="3"
+	Sequence="PerformedProtocolCodeSequence"				Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="ProtocolContextSequence"					Type="3"	VM="1-n"
+			InvokeMacro="ContentItemMacro"
+			Sequence="ContentItemModifierSequence"			Type="3"	VM="1-n"
+				InvokeMacro="ContentItemMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	Name="CommentsOnThePerformedProcedureStep"				Type="3"
+MacroEnd
+
+DefineMacro="ExposureIndexMacro" InformationEntity="Frame"
+	Name="ExposureIndex"									Type="3"	NotZeroWarning=""
+	Name="TargetExposureIndex"								Type="3"	NotZeroWarning=""
+	Name="DeviationIndex"									Type="3"	NotZeroWarning=""
+MacroEnd
+
+DefineMacro="MandatoryViewAndSliceProgressionDirectionMacro" InformationEntity="Frame"
+	Sequence="ViewCodeSequence"								Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"						BaselineContextID="26"
+		Sequence="ViewModifierCodeSequence"					Type="2C"	VM="0-n"	NoCondition=""	# real-world - if needed to fully specify the view
+			InvokeMacro="ContentItemMacro"					BaselineContextID="23"
+		SequenceEnd
+	SequenceEnd
+	Name="SliceProgressionDirection"						Type="1C"	StringEnumValues="CardiacSliceProgressionDirection"	Condition="ViewIsCardiacShortOrLongAxis"	mbpo="true"
+MacroEnd
+
+DefineMacro="OptionalViewAndSliceProgressionDirectionMacro" InformationEntity="Frame"
+	Sequence="ViewCodeSequence"								Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"						BaselineContextID="26"
+		Sequence="ViewModifierCodeSequence"					Type="3"	VM="1-n"
+			InvokeMacro="ContentItemMacro"					BaselineContextID="23"
+		SequenceEnd
+	SequenceEnd
+	Name="SliceProgressionDirection"						Type="3"	StringEnumValues="CardiacSliceProgressionDirection"
+MacroEnd
+
+DefineMacro="RTEquipmentCorrelationMacro" InformationEntity="Image"
+	Name="PatientSupportAngle"								Type="3"
+	Name="TableTopPitchAngle"								Type="3"
+	Name="TableTopRollAngle"								Type="3"
+	Name="TableTopLongitudinalPosition"						Type="3"
+	Name="TableTopLateralPosition"							Type="3"
+MacroEnd
+
+DefineMacro="PatientGroupMacro" InformationEntity="Patient"
+	Sequence="SourcePatientGroupIdentificationSequence"		Type="3"	VM="1"
+		Name="PatientID"									Type="1"
+		InvokeMacro="IssuerOfPatientIDMacro"
+	SequenceEnd
+	Sequence="GroupOfPatientsIdentificationSequence"		Type="3"	VM="1-n"
+		Name="PatientID"									Type="1"
+		InvokeMacro="IssuerOfPatientIDMacro"
+		Name="SubjectRelativePositionInImage"				Type="3"
+		Name="PatientPosition"								Type="3"
+	SequenceEnd
+MacroEnd
+
+Module="Patient"
+	Name="PatientName"						Type="2"
+	Name="PatientID"						Type="2"
+	InvokeMacro="IssuerOfPatientIDMacro"
+	Name="PatientBirthDate"					Type="2"
+	Name="PatientSex"						Type="2"	StringEnumValues="Sex"
+	Name="QualityControlSubject"			Type="3"	StringEnumValues="YesNoFull"
+	Sequence="ReferencedPatientSequence"	Type="3"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="PatientBirthTime"					Type="3"
+	Name="OtherPatientIDs"					Type="3"
+	Sequence="OtherPatientIDsSequence"		Type="3"	VM="1-n"
+		Name="PatientID"					Type="1"
+		InvokeMacro="IssuerOfPatientIDMacro"
+		Name="TypeOfPatientID"				Type="1"	StringDefinedTerms="TypeOfPatientID"
+	SequenceEnd
+	Name="OtherPatientNames"				Type="3"
+	Name="EthnicGroup"						Type="3"
+	Name="PatientComments"					Type="3"
+	Name="PatientSpeciesDescription"		Type="1C"	Condition="IsAnimalAndPatientSpeciesCodeSequenceAbsent" mbpo="true"
+	Sequence="PatientSpeciesCodeSequence"	Type="1C"	VM="1"	Condition="IsAnimalAndPatientSpeciesDescriptionAbsent" mbpo="true"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="PatientBreedDescription"			Type="2C"	Condition="IsAnimalAndPatientBreedCodeSequenceEmpty" mbpo="true"
+	Sequence="PatientBreedCodeSequence"		Type="2C"	VM="0-1"	Condition="IsAnimal"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="BreedRegistrationSequence"	Type="2C"	VM="0-n"	Condition="IsAnimal"
+		Name="BreedRegistrationNumber"		Type="1"
+		Sequence="BreedRegistryCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="StrainDescription"						Type="3"
+	Name="StrainNomenclature"						Type="3"
+	Sequence="StrainCodeSequence"					Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="StrainAdditionalInformation"				Type="3"
+	Sequence="StrainStockSequence"					Type="3"	VM="1"
+		Name="StrainStockNumber"					Type="1"
+		Name="StrainSource"							Type="1"
+		Sequence="StrainSourceRegistryCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="ResponsiblePerson"				Type="2C"	Condition="IsAnimal" mbpo="true"
+	Name="ResponsiblePersonRole"			Type="1C"	Condition="ResponsiblePersonIsPresentWithValue"	StringDefinedTerms="ResponsiblePersonRole"
+	Name="ResponsibleOrganization"			Type="2C"	Condition="IsAnimal" mbpo="true"
+	Name="PatientIdentityRemoved"			Type="3"	StringEnumValues="YesNoFull"
+	Name="DeidentificationMethod"					Type="1C"	Condition="PatientIdentityRemovedAndNotDeidentificationMethodCodeSequence" mbpo="true"
+	Sequence="DeidentificationMethodCodeSequence"	Type="1C"	VM="1-n"	Condition="PatientIdentityRemovedAndNotDeidentificationMethod" mbpo="true"
+		InvokeMacro="CodeSequenceMacro"					DefinedContextID="7050"
+	SequenceEnd
+	InvokeMacro="PatientGroupMacro"
+ModuleEnd
+
+Module="ClinicalTrialSubject"
+	Name="ClinicalTrialSponsorName"			Type="1"
+	Name="ClinicalTrialProtocolID"			Type="1"
+	Name="ClinicalTrialProtocolName"		Type="2"
+	Name="ClinicalTrialSiteID"				Type="2"
+	Name="ClinicalTrialSiteName"			Type="2"
+	Name="ClinicalTrialSubjectID"			Type="1C"	Condition="ClinicalTrialSubjectReadingIDAbsent" mbpo="true"
+	Name="ClinicalTrialSubjectReadingID"	Type="1C"	Condition="ClinicalTrialSubjectIDAbsent" mbpo="true"
+	Name="ClinicalTrialProtocolEthicsCommitteeName"	Type="1C"	Condition="ClinicalTrialProtocolEthicsCommitteeApprovalNumberIsPresent"
+	Name="ClinicalTrialProtocolEthicsCommitteeApprovalNumber"	Type="3"
+
+ModuleEnd
+
+Module="GeneralStudy"
+	Name="StudyInstanceUID"									Type="1"
+	Name="StudyDate"										Type="2"
+	Name="StudyTime"										Type="2"
+	Name="ReferringPhysicianName"							Type="2"
+	Sequence="ReferringPhysicianIdentificationSequence"		Type="3"	VM="1"
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+	Name="StudyID"											Type="2"
+	Name="AccessionNumber"									Type="2"
+	Sequence="IssuerOfAccessionNumberSequence"				Type="3"	VM="1"
+		InvokeMacro="HL7v2HierarchicDesignatorMacro"
+	SequenceEnd
+	Name="StudyDescription"									Type="3"
+	Name="PhysiciansOfRecord"								Type="3"
+	Sequence="PhysiciansOfRecordIdentificationSequence"		Type="3"	VM="1-n"
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+	Name="NameOfPhysiciansReadingStudy"						Type="3"
+	Sequence="PhysiciansReadingStudyIdentificationSequence"	Type="3"	VM="1-n"
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+	Sequence="RequestingServiceCodeSequence"				Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"						DefinedContextID="7030"
+	SequenceEnd
+	Sequence="ReferencedStudySequence"						Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ProcedureCodeSequence"						Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="ReasonForPerformedProcedureCodeSequence"		Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="PatientStudy"
+	Name="AdmittingDiagnosesDescription"		Type="3"
+	Sequence="AdmittingDiagnosesCodeSequence"	Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="PatientAge"							Type="3"
+	Name="PatientSize"							Type="3"	NotZeroWarning=""
+	Name="PatientWeight"						Type="3"	NotZeroWarning=""
+	Sequence="PatientSizeCodeSequence"			Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="Occupation"							Type="3"
+	Name="AdditionalPatientHistory"				Type="3"
+	Name="AdmissionID"							Type="3"
+	Name="IssuerOfAdmissionID"					Type="3"
+	Sequence="IssuerOfAdmissionIDSequence"		Type="3"	VM="1"
+		InvokeMacro="HL7v2HierarchicDesignatorMacro"
+	SequenceEnd
+	Name="ServiceEpisodeID"						Type="3"
+	Sequence="IssuerOfServiceEpisodeIDSequence"	Type="3"	VM="1"
+		InvokeMacro="HL7v2HierarchicDesignatorMacro"
+	SequenceEnd
+	Name="ServiceEpisodeDescription"			Type="3"
+	Name="PatientSexNeutered"					Type="2C"	Condition="IsAnimal"	StringEnumValues="PatientSexNeutered" mbpo="true"
+ModuleEnd
+
+Module="ClinicalTrialStudy"
+	Name="ClinicalTrialTimePointID"					Type="2"
+	Name="ClinicalTrialTimePointDescription"		Type="3"
+	Sequence="ConsentForClinicalTrialUseSequence"	Type="3"	VM="1-n"
+		Name="DistributionType"						Type="1C"	Condition="ConsentForDistributionFlagIsYesOrWithdrawn"	StringEnumValues="DistributionType"
+		Name="ClinicalTrialProtocolID"				Type="1C"	NoCondition=""
+		Verify="ClinicalTrialProtocolID"						Condition="DistributionTypeIsNotNamedProtocol"		ThenErrorMessage="Only permitted when DistributionType is NAMED_PROTOCOL"
+		Name="ConsentForDistributionFlag"			Type="1"	StringEnumValues="ConsentForDistributionFlag"
+	SequenceEnd
+ModuleEnd
+
+Module="GeneralSeries"
+	Name="Modality"											Type="1C"	Condition="NotSecondaryCaptureSOPClass" mbpo="true"
+	Verify="Modality"													StringDefinedTerms="Modality"
+	Name="SeriesInstanceUID"								Type="1"
+	Name="SeriesNumber"										Type="2"
+	Name="Laterality"										Type="2C"	Condition="LateralityRequired"	StringEnumValues="Laterality"
+	Verify="Laterality"													Condition="LateralityHasNoValue"	ThenWarningMessage="is only permitted to be empty when actually unknown; should be absent (not empty) if an unpaired body part, and have a value if a paired body part"
+	Name="SeriesDate"										Type="3"
+	Name="SeriesTime"										Type="3"
+	Name="PerformingPhysicianName"							Type="3"
+	Sequence="PerformingPhysicianIdentificationSequence"	Type="3"	VM="1-n"
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+	Name="ProtocolName"										Type="3"
+	Name="SeriesDescription"								Type="3"
+	Sequence="SeriesDescriptionCodeSequence"				Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="OperatorsName"									Type="3"
+	Sequence="OperatorIdentificationSequence"				Type="3"	VM="1-n"
+		InvokeMacro="PersonIdentificationMacro"
+	SequenceEnd
+	Sequence="ReferencedPerformedProcedureStepSequence"		Type="3"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="RelatedSeriesSequence"						Type="3"	VM="1-n"
+		Name="StudyInstanceUID"								Type="1"
+		Name="SeriesInstanceUID"							Type="1"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="BodyPartExamined"									Type="3"
+	Verify="BodyPartExamined"											Condition="IsHuman"		StringDefinedTerms="BodyPartExaminedHuman"
+	Verify="BodyPartExamined"											Condition="IsAnimal"	StringDefinedTerms="BodyPartExaminedAnimal"
+	Name="PatientPosition"									Type="2C"	StringDefinedTerms="PatientPosition"	Condition="SOPClassIsCTOrMR" mbpo="true"
+	Verify="PatientPosition"											Condition="PatientPositionAndPatientOrientationCodeSequencePresent"	ThenErrorMessage="May not be present when PatientOrientationCodeSequence is present"
+	Name="SmallestPixelValueInSeries"						Type="3"
+	Name="LargestPixelValueInSeries"						Type="3"
+	Sequence="RequestAttributesSequence"					Type="3"	VM="1-n"
+		InvokeMacro="RequestAttributesMacro"
+	SequenceEnd
+	InvokeMacro="PerformedProcedureStepSummaryMacro"
+	Name="AnatomicalOrientationType"						Type="1C"	NoCondition=""	StringEnumValues="AnatomicalOrientationType"
+ModuleEnd
+
+Module="ClinicalTrialSeries"
+	Name="ClinicalTrialCoordinatingCenterName"				Type="2"
+	Name="ClinicalTrialSeriesID"							Type="3"
+	Name="ClinicalTrialSeriesDescription"					Type="3"
+ModuleEnd
+
+Module="EnhancedSeries"
+	Name="SeriesNumber"										Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"		Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="FrameOfReference"
+	Name="FrameOfReferenceUID"								Type="1"
+	Name="PositionReferenceIndicator"						Type="2"
+ModuleEnd
+
+Module="GeneralEquipment"
+	Name="Manufacturer"										Type="2"
+	Name="InstitutionName"									Type="3"
+	Name="InstitutionAddress"								Type="3"
+	Name="StationName"										Type="3"
+	Name="InstitutionalDepartmentName"						Type="3"
+	Name="ManufacturerModelName"							Type="3"
+	Name="DeviceSerialNumber"								Type="3"
+	Name="SoftwareVersions"									Type="3"
+	Name="GantryID"											Type="3"
+	Name="SpatialResolution"								Type="3"
+	Name="DateOfLastCalibration"							Type="3"
+	Name="TimeOfLastCalibration"							Type="3"
+	Name="PixelPaddingValue"								Type="1C"	Condition="PixelPaddingRangeLimitIsPresent" mbpo="true"
+	Verify="PixelPaddingValue"											Condition="PixelPaddingValueIsPresentAndInstanceIsNotAnImage"	ThenErrorMessage="May not be present when not an integer pixel data image"
+ModuleEnd
+
+Module="EnhancedGeneralEquipment"
+	Name="Manufacturer"										Type="1"
+	Name="ManufacturerModelName"							Type="1"
+	Name="DeviceSerialNumber"								Type="1"
+	Name="SoftwareVersions"									Type="1"
+ModuleEnd
+
+Module="GeneralImage"
+	Name="InstanceNumber"									Type="2"
+	Name="PatientOrientation"								Type="2C"	Condition="PatientOrientationRequired" mbpo="true"
+	# ImageDate and ImageTime real-world condition "images are temporally related"
+	Name="ContentDate"										Type="2C"	NoCondition=""	# "if temporally related" ... real world
+	Name="ContentTime"										Type="2C"	NoCondition=""	# "if temporally related" ... real world
+	Name="ImageType"										Type="3"	ValueSelector="0"	StringEnumValues="ImageType1"
+	Verify="ImageType"										Type="3"	ValueSelector="1"	StringEnumValues="ImageType2"
+	Name="AcquisitionNumber"								Type="3"
+	Name="AcquisitionDate"									Type="3"
+	Name="AcquisitionTime"									Type="3"
+	Name="AcquisitionDateTime"								Type="3"
+	Sequence="ReferencedImageSequence"						Type="3"	VM="1-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="DerivationDescription"							Type="3"
+	Sequence="DerivationCodeSequence"						Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="SourceImageSequence"							Type="3"	VM="1-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="SpatialLocationsPreserved"					Type="3"	StringEnumValues="YesNoReorientedOnly"
+		Name="PatientOrientation"							Type="1C"	Condition="SpatialLocationsPreservedReorientedOnly"
+	SequenceEnd
+	Sequence="ReferencedInstanceSequence"					Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="1"	VM="1"
+ 			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="ImagesInAcquisition"								Type="3"
+	Name="ImageComments"									Type="3"
+	Name="QualityControlImage"								Type="3"	StringEnumValues="YesNoFull"
+	Name="BurnedInAnnotation"								Type="3"	StringEnumValues="YesNoFull"
+	Name="RecognizableVisualFeatures"						Type="3"	StringEnumValues="YesNoFull"
+	Name="LossyImageCompression"							Type="3"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="3"
+	Name="LossyImageCompressionMethod"						Type="3"	StringDefinedTerms="LossyImageCompressionMethod"
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Sequence="IconImageSequence"							Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	Name="PresentationLUTShape"								Type="3"	StringEnumValues="SoftcopyPresentationLUTShape"
+	Verify="PresentationLUTShape"							Condition="PhotometricInterpretationIsMonochrome1"			StringEnumValues="InversePresentationLUTShape"
+	Verify="PresentationLUTShape"							Condition="PhotometricInterpretationIsMonochrome2"			StringEnumValues="IdentityPresentationLUTShape"
+	Verify="PresentationLUTShape"							Condition="PhotometricInterpretationIsColor"				StringEnumValues="IdentityPresentationLUTShape"
+	Name="IrradiationEventUID"								Type="3"
+	Sequence="RealWorldValueMappingSequence"				Type="3"	VM="1-n"
+		InvokeMacro="RealWorldValueMappingItemMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="ImagePlane"
+	Name="PixelSpacing"										Type="1"	NotZeroError=""
+	Name="ImageOrientationPatient"							Type="1"
+	Name="ImagePositionPatient"								Type="1"
+	Name="SliceThickness"									Type="2"	NotZeroError=""
+	Name="SliceLocation"									Type="3"
+ModuleEnd
+
+DefineMacro="ImagePixelMacro" InformationEntity="Instance"
+	Name="SamplesPerPixel"							Type="1"
+	Verify="SamplesPerPixel"						Condition="PhotometricInterpretationNeedsOneSample"	BinaryEnumValues="One"
+	Verify="SamplesPerPixel"						Condition="PhotometricInterpretationNeedsThreeSamples"	BinaryEnumValues="Three"
+	Verify="SamplesPerPixel"						Condition="MPEG2TransferSyntaxAndNotThreeSamples"		ThenErrorMessage="May only be 3 for MPEG Transfer Syntax"
+	
+	Name="PhotometricInterpretation"				Type="1"	StringDefinedTerms="PhotometricInterpretation"
+	Verify="PhotometricInterpretation"				Condition="JPEGLossyTransferSyntaxAndThreeSamples"			StringEnumValues="PhotometricInterpretationYBRFull422"
+	Verify="PhotometricInterpretation"				Condition="JPEGLosslessTransferSyntaxAndThreeSamples"		StringEnumValues="PhotometricInterpretationRGBorYBR_RCT"
+	Verify="PhotometricInterpretation"				Condition="JPEG2000LosslessTransferSyntaxAndThreeSamples"	StringEnumValues="PhotometricInterpretationYBRRCT"
+	Verify="PhotometricInterpretation"				Condition="JPEG2000TransferSyntaxAndThreeSamples"			StringEnumValues="PhotometricInterpretationYBRRCTOrICT"
+	Verify="PhotometricInterpretation"				Condition="MPEG2TransferSyntax"								StringEnumValues="PhotometricInterpretationYBRPartial420"	# regardless of number of samples (required to be 3 by PS 3.5)
+	Verify="PhotometricInterpretation"				Condition="RLETransferSyntaxAndThreeSamples"				StringEnumValues="PhotometricInterpretationYBRFullOrRGBorYBR_RCTorYBR_ICT"
+	Verify="PhotometricInterpretation"				Condition="UncompressedTransferSyntaxAndThreeSamples"		StringEnumValues="PhotometricInterpretationYBRFullOrRGBorYBR_RCTorYBR_ICT"
+	
+	Name="Rows"										Type="1"	NotZeroError=""
+	Verify="Rows"									Condition="MPEG2MPMLTransferSyntaxAndRowsGreaterThan480NTSCOr576PAL"	ThenErrorMessage="Must be <= 480 (NTSC) or 576 (PAL) for MPEG MP at MLTransfer Syntax"
+	Verify="Rows"									Condition="MPEG2MPHLTransferSyntaxAndRowsNot720Or1080"					ThenErrorMessage="Must be 720 or 1080 for MPEG MP at HLTransfer Syntax"
+	
+	Name="Columns"									Type="1"	NotZeroError=""
+	Verify="Columns"								Condition="MPEG2MPMLTransferSyntaxAndColumnsGreaterThan720"				ThenErrorMessage="Must be <= 720 for MPEG MP at MLTransfer Syntax"
+	Verify="Columns"								Condition="MPEG2MPHLTransferSyntaxAndColumnsNot1280Or1920"				ThenErrorMessage="Must be 1280 or 1920 for MPEG MP at HLTransfer Syntax"
+	Verify="Columns"								Condition="MPEG2MPHLTransferSyntaxAndColumnsInconsistentWithRows"		ThenErrorMessage="Must be 1280 when 720 Rows, or 1920 when 1080 Rows, for MPEG MP at HLTransfer Syntax"
+	
+	Name="BitsAllocated"							Type="1"	NotZeroError=""
+	Verify="BitsAllocated"							Condition="MPEG2TransferSyntaxAndNotBitsAllocated8"		ThenErrorMessage="May only be 8 for MPEG Transfer Syntax"
+	
+	Name="BitsStored"								Type="1"	NotZeroError=""
+	Verify="BitsStored"								Condition="MPEG2TransferSyntaxAndNotBitsStored8"		ThenErrorMessage="May only be 8 for MPEG Transfer Syntax"
+	
+	Name="HighBit"									Type="1"
+	Verify="HighBit"								Condition="MPEG2TransferSyntaxAndNotHighBit7"		ThenErrorMessage="May only be 7 for MPEG Transfer Syntax"
+	
+	Name="PixelRepresentation"						Type="1"	BinaryEnumValues="PixelRepresentation"
+	Verify="PixelRepresentation"					Condition="MPEG2TransferSyntaxAndNotPixelRepresentation0"		ThenErrorMessage="May only be 0 for MPEG Transfer Syntax"
+	
+	Name="PixelData"								Type="1C"	Condition="PixelDataProviderURLIsAbsent"
+
+	Name="PlanarConfiguration"						Type="1C"	BinaryEnumValues="PlanarConfiguration"	Condition="SamplesPerPixelGreaterThanOne"
+	Verify="PlanarConfiguration"					Condition="MPEG2TransferSyntaxAndNotPlanarConfiguration0"		ThenErrorMessage="May only be 0 for MPEG Transfer Syntax"
+	
+	# PixelAspectRatio required if the image plane module not applicable and the aspect ratio is not 1:1
+	Name="PixelAspectRatio"							Type="1C"	NoCondition=""	# "if ! image plane module present && not 1:1" ... too hard for now :(
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenPixelSpacingPresent"					ThenErrorMessage="May not be present when Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenImagerPixelSpacingPresent"			ThenErrorMessage="May not be present when Imager Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenNominalScannedPixelSpacingPresent"	ThenErrorMessage="May not be present when Nominal Scanned Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenSharedPixelMeasuresMacro"			ThenErrorMessage="May not be present when Pixel Measures Macro is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenPerFramePixelMeasuresMacro"			ThenErrorMessage="May not be present when Pixel Measures Macro is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenMPEG2MPHLTransferSyntax"				ThenErrorMessage="May not be present for MPEG MP at HLTransfer Syntax"
+	Name="SmallestImagePixelValue"					Type="3"
+	Name="LargestImagePixelValue"					Type="3"
+	Name="RedPaletteColorLookupTableDescriptor"	Type="1C"	Condition="ImagePixelMacroNeedsPaletteDescriptor"
+	Verify="RedPaletteColorLookupTableDescriptor"			ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+	Name="GreenPaletteColorLookupTableDescriptor"	Type="1C"	Condition="ImagePixelMacroNeedsPaletteDescriptor"
+	Verify="GreenPaletteColorLookupTableDescriptor"			ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+	Name="BluePaletteColorLookupTableDescriptor"	Type="1C"	Condition="ImagePixelMacroNeedsPaletteDescriptor"
+	Verify="BluePaletteColorLookupTableDescriptor"			ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+	Name="RedPaletteColorLookupTableData"			Type="1C"	Condition="ImagePixelMacroNeedsPaletteDescriptorAndNotSegmentedLegallyPresentInPaletteColorModule"
+	Name="GreenPaletteColorLookupTableData"			Type="1C"	Condition="ImagePixelMacroNeedsPaletteDescriptorAndNotSegmentedLegallyPresentInPaletteColorModule"
+	Name="BluePaletteColorLookupTableData"			Type="1C"	Condition="ImagePixelMacroNeedsPaletteDescriptorAndNotSegmentedLegallyPresentInPaletteColorModule"
+	Name="ICCProfile"								Type="3"
+MacroEnd
+
+Module="FloatingPointImagePixel"
+	Name="SamplesPerPixel"							Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="Rows"										Type="1"	NotZeroError=""
+	Name="Columns"									Type="1"	NotZeroError=""
+	Name="BitsAllocated"							Type="1"	BinaryEnumValues="BitsAre32"
+	Verify="BitsStored"								Condition="BitsStoredPresent"			ThenErrorMessage="May not be present for Float Pixel Data"
+	Verify="HighBit"								Condition="HighBitPresent"				ThenErrorMessage="May not be present for Float Pixel Data"
+	Verify="PixelRepresentation"					Condition="PixelRepresentationPresent"	ThenErrorMessage="May not be present for Float Pixel Data"
+	Verify="PlanarConfiguration"					Condition="PlanarConfigurationPresent"	ThenErrorMessage="May not be present for Float Pixel Data"
+
+	Name="FloatPixelData"							Type="1"
+
+	# PixelAspectRatio required if the image plane module not applicable and the aspect ratio is not 1:1
+	Name="PixelAspectRatio"							Type="1C"	NoCondition=""	# "if ! image plane module present && not 1:1" ... too hard for now :(
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenPixelSpacingPresent"					ThenErrorMessage="May not be present when Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenImagerPixelSpacingPresent"			ThenErrorMessage="May not be present when Imager Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenNominalScannedPixelSpacingPresent"	ThenErrorMessage="May not be present when Nominal Scanned Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenSharedPixelMeasuresMacro"			ThenErrorMessage="May not be present when Pixel Measures Macro is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenPerFramePixelMeasuresMacro"			ThenErrorMessage="May not be present when Pixel Measures Macro is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenMPEG2MPHLTransferSyntax"				ThenErrorMessage="May not be present for MPEG MP at HLTransfer Syntax"
+
+	Name="FloatPixelPaddingValue"					Type="3"
+	Name="FloatPixelPaddingRangeLimit"				Type="1C"	Condition="FloatPixelPaddingValuePresent"
+ModuleEnd
+
+Module="DoubleFloatingPointImagePixel"
+	Name="SamplesPerPixel"							Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="Rows"										Type="1"	NotZeroError=""
+	Name="Columns"									Type="1"	NotZeroError=""
+	Name="BitsAllocated"							Type="1"	BinaryEnumValues="BitsAre64"
+	Verify="BitsStored"								Condition="BitsStoredPresent"			ThenErrorMessage="May not be present for Float Pixel Data"
+	Verify="HighBit"								Condition="HighBitPresent"				ThenErrorMessage="May not be present for Float Pixel Data"
+	Verify="PixelRepresentation"					Condition="PixelRepresentationPresent"	ThenErrorMessage="May not be present for Float Pixel Data"
+	Verify="PlanarConfiguration"					Condition="PlanarConfigurationPresent"	ThenErrorMessage="May not be present for Float Pixel Data"
+
+	Name="DoubleFloatPixelData"						Type="1"
+
+	# PixelAspectRatio required if the image plane module not applicable and the aspect ratio is not 1:1
+	Name="PixelAspectRatio"							Type="1C"	NoCondition=""	# "if ! image plane module present && not 1:1" ... too hard for now :(
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenPixelSpacingPresent"					ThenErrorMessage="May not be present when Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenImagerPixelSpacingPresent"			ThenErrorMessage="May not be present when Imager Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenNominalScannedPixelSpacingPresent"	ThenErrorMessage="May not be present when Nominal Scanned Pixel Spacing is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenSharedPixelMeasuresMacro"			ThenErrorMessage="May not be present when Pixel Measures Macro is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenPerFramePixelMeasuresMacro"			ThenErrorMessage="May not be present when Pixel Measures Macro is present"
+	Verify="PixelAspectRatio"									Condition="UnwantedPixelAspectRatioWhenMPEG2MPHLTransferSyntax"				ThenErrorMessage="May not be present for MPEG MP at HLTransfer Syntax"
+
+	Name="DoubleFloatPixelPaddingValue"				Type="3"
+	Name="DoubleFloatPixelPaddingRangeLimit"		Type="1C"	Condition="DoubleFloatPixelPaddingValuePresent"
+ModuleEnd
+
+Module="ImagePixel"
+	InvokeMacro="ImagePixelMacro"
+	Name="PixelDataProviderURL"								Type="1C"	Condition="TransferSyntaxIsReferencedPixelData"
+	Name="PixelPaddingRangeLimit"							Type="1C"	NoCondition=""		# real world
+ModuleEnd
+
+Module="ContrastBolus"
+	Name="ContrastBolusAgent"							Type="2"
+	Sequence="ContrastBolusAgentSequence"				Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="ContrastBolusRoute"							Type="3"
+	Sequence="ContrastBolusAdministrationRouteSequence"	Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="AdditionalDrugSequence"				Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="ContrastBolusVolume"							Type="3"
+	Name="ContrastBolusStartTime"						Type="3"
+	Name="ContrastBolusStopTime"						Type="3"
+	Name="ContrastBolusTotalDose"						Type="3"
+	Name="ContrastFlowRate"								Type="3"
+	Name="ContrastFlowDuration"							Type="3"
+	Name="ContrastBolusIngredient"						Type="3"
+	Name="ContrastBolusIngredientConcentration"			Type="3"
+ModuleEnd
+
+Module="EnhancedContrastBolus"
+	Sequence="ContrastBolusAgentSequence"					Type="1"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+		Name="ContrastBolusAgentNumber"						Type="1"
+		Sequence="ContrastBolusAdministrationRouteSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ContrastBolusIngredientCodeSequence"		Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="ContrastBolusVolume"							Type="2"
+		Name="ContrastBolusIngredientConcentration"			Type="2"
+		Name="ContrastBolusIngredientPercentByVolume"		Type="3"
+		Name="ContrastBolusIngredientOpaque"				Type="3"	StringEnumValues="YesNoFull"
+		Sequence="ContrastAdministrationProfileSequence"	Type="3"	VM="1-n"
+			Name="ContrastBolusVolume"						Type="2"
+			Name="ContrastBolusStartTime"					Type="3"
+			Name="ContrastBolusStopTime"					Type="3"
+			Name="ContrastFlowRate"							Type="3"
+			Name="ContrastFlowDuration"						Type="3"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="Cine"
+	Name="PreferredPlaybackSequencing"		Type="3"	BinaryEnumValues="PreferredPlaybackSequencing"
+	
+	Name="FrameTime"						Type="1C"	Condition="FrameIncrementPointerContainsFrameTime"
+	Verify="FrameTime"						Condition="MPEG2MPMLTransferSyntaxAndFrameTimeNotNTSCOrPAL"	ThenErrorMessage="Must be 33.3 (NTSC) or 40 (PAL) for MPEG MP at MLTransfer Syntax"
+	Verify="FrameTime"						Condition="MPEG2MPHLTransferSyntaxAndFrameTimeNotValid"	ThenErrorMessage="Must be 16.17, 20, 33.33, or 40 (PAL) for MPEG MP at HLTransfer Syntax"
+	
+	Name="FrameTimeVector"					Type="1C"	Condition="FrameIncrementPointerContainsFrameTimeVector"
+	Name="StartTrim"						Type="3"
+	Name="StopTrim"							Type="3"
+	Name="RecommendedDisplayFrameRate"		Type="3"
+	
+	Name="CineRate"							Type="3"
+	Verify="CineRate"						Condition="MPEG2MPMLTransferSyntaxAndCineRateNotNTSCOrPAL"	ThenErrorMessage="Must be 30 (NTSC) or 25 (PAL) for MPEG MP at MLTransfer Syntax"
+	Verify="CineRate"						Condition="MPEG2MPHLTransferSyntaxAndCineRateNotValid"	ThenErrorMessage="Must be 25, 30, 50 or 60 for MPEG MP at HLTransfer Syntax"
+	Verify="CineRate"						Condition="MPEG2MPMLTransferSyntaxAndCineRateInconsistentWithFrameTime"	ThenErrorMessage="Must be 30 when FrameTime is 33.3 (NTSC) or 25 when FrameTime is 40 (PAL) for MPEG MP at MLTransfer Syntax"
+	Verify="CineRate"						Condition="MPEG2MPHLTransferSyntaxAndCineRateInconsistentWithFrameTime"	ThenErrorMessage="Must be 30 when FrameTime is 33.3, 25 when FrameTime is 40, 60 when FrameTime is 16.17, or 50 when FrameTime is 20 for MPEG MP at HLTransfer Syntax"
+	
+	Name="FrameDelay"						Type="3"
+	Name="ImageTriggerDelay"				Type="3"
+	Name="EffectiveDuration"				Type="3"
+	Name="ActualFrameDuration"				Type="3"
+	Sequence="MultiplexedAudioChannelsDescriptionCodeSequence"	Type="3"	VM="1-n"
+		Name="ChannelIdentificationCode"	Type="1"
+		Name="ChannelMode"					Type="1"
+		Sequence="ChannelSourceSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrame"
+	Name="NumberOfFrames"					Type="1"	NotZeroError=""
+	Name="FrameIncrementPointer"			Type="1C"	Condition="NotSCMultiFrameOrNumberOfFramesGreaterThanOne"
+	Name="StereoPairsPresent"				Type="3"	StringEnumValues="YesNoFull"
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsCommon"
+	# the Type 2 Shared Functional Groups Sequence and Type 1 Per-frame Functional Groups Sequence are included in the IOD-specific pseudo-modules
+	Name="InstanceNumber"						Type="1"
+	Name="ContentDate"							Type="1"
+	Name="ContentTime"							Type="1"
+	Name="NumberOfFrames"						Type="1"	NotZeroError=""
+	Name="StereoPairsPresent"					Type="3"	StringEnumValues="YesNoFull"
+	Name="ConcatenationFrameOffsetNumber"		Type="1C"	Condition="ConcatenationUIDIsPresent"
+	Name="RepresentativeFrameNumber"			Type="3"	NotZeroError=""
+	Name="ConcatenationUID"						Type="1C"	NoCondition=""	# real world
+	Name="SOPInstanceUIDOfConcatenationSource"	Type="1C"	Condition="ConcatenationUIDIsPresent"
+	Name="InConcatenationNumber"				Type="1C"	Condition="ConcatenationUIDIsPresent"
+	Name="InConcatenationTotalNumber"			Type="3"
+ModuleEnd
+
+DefineMacro="PixelMeasuresMacro" InformationEntity="FunctionalGroup"
+	Sequence="PixelMeasuresSequence"		Type="1"	VM="1"
+		Name="PixelSpacing"					Type="1C"	NotZeroError=""	Condition="PixelSpacingNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndVolumetricPropertiesIsNotDistortedSampledOrSegmentationWithFrameOfReference" mbpo="true"
+		Name="SliceThickness"				Type="1C"	NotZeroError=""	Condition="SliceThicknessNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndVolumetricPropertiesIsVolumeOrSampledOrSegmentationWithFrameOfReference" mbpo="true"
+		Name="SpacingBetweenSlices"			Type="3"	NotZeroError=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="FrameContentMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameContentSequence"				Type="1"	VM="1"
+		Name="FrameAcquisitionNumber"			Type="3"
+		Name="FrameReferenceDateTime"			Type="1C"	NoCondition="" mbpo="true" # (../../[SharedFunctionalGroupsSequence or PerFrameFunctionalGroupsSequence item for this frame]MRImageFrameTypeMacro/FrameType is ORIGINAL) and not legacy CT, MR or PET ... too hard :(
+		Name="FrameAcquisitionDateTime"			Type="1C"	NoCondition="" mbpo="true" # (../../[SharedFunctionalGroupsSequence or PerFrameFunctionalGroupsSequence item for this frame]MRImageFrameTypeMacro/FrameType is ORIGINAL) and not legacy CT, MR or PET ... too hard :(
+		Name="FrameAcquisitionDuration"			Type="1C"	NoCondition="" mbpo="true" # (../../[SharedFunctionalGroupsSequence or PerFrameFunctionalGroupsSequence item for this frame]MRImageFrameTypeMacro/FrameType is ORIGINAL) and not legacy CT, MR or PET ... too hard :(
+		Name="CardiacCyclePosition"				Type="3"	StringDefinedTerms="CardiacCyclePosition"
+		Name="RespiratoryCyclePosition"			Type="3"	StringDefinedTerms="RespiratoryCyclePosition"
+		Name="DimensionIndexValues"				Type="1C"	Condition="DimensionIndexSequencePresent"
+		Verify="DimensionIndexValues"						Condition="DimensionIndexValuesContainsZero"	ThenErrorMessage="Must start from one, not zero"
+		Name="TemporalPositionIndex"			Type="1C"	Condition="EnhancedPETImageInstance" mbpo="true"
+		Verify="TemporalPositionIndex"						Condition="TemporalPositionIndexIsZero"	ThenErrorMessage="Must start from one, not zero"
+		Name="StackID"							Type="1C"	Condition="EnhancedPETImageInstance" mbpo="true"
+		Name="InStackPositionNumber"			Type="1C"	Condition="StackIDIsPresent"
+		Verify="InStackPositionNumber"						Condition="InStackPositionNumberIsZero"	ThenErrorMessage="Must start from one, not zero"
+		Name="FrameComments"					Type="3"
+		Name="FrameLabel"						Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PlanePositionMacro" InformationEntity="FunctionalGroup"
+	Sequence="PlanePositionSequence"			Type="1"	VM="1"
+		Name="ImagePositionPatient"				Type="1C"	Condition="ImagePositionPatientNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndEitherFrameTypeIsOriginalAndVolumetricPropertiesIsNotDistortedOrSegmentationWithFrameOfReference" mbpo="true"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PlaneOrientationMacro" InformationEntity="FunctionalGroup"
+	Sequence="PlaneOrientationSequence"			Type="1"	VM="1"
+		Name="ImageOrientationPatient"			Type="1C"		Condition="ImageOrientationPatientNotPresentInEitherSharedOrPerFrameFunctionalGroupsAndEitherFrameTypeIsOriginalAndVolumetricPropertiesIsNotDistortedOrSegmentationWithFrameOfReference" mbpo="true"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="ReferencedImageMacro" InformationEntity="FunctionalGroup"
+	Sequence="ReferencedImageSequence"				Type="2"	VM="0-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="DerivationImageMacro" InformationEntity="FunctionalGroup"
+	Sequence="DerivationImageSequence"					Type="2"	VM="0-n"
+		Name="DerivationDescription"					Type="3" 
+		Sequence="DerivationCodeSequence"				Type="1"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="SourceImageSequence"					Type="2"	VM="0-n"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+			Sequence="PurposeOfReferenceCodeSequence"	Type="1"	VM="1"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CardiacSynchronizationMacro" InformationEntity="FunctionalGroup"
+	Sequence="CardiacSynchronizationSequence"	Type="1"	VM="1"
+		Name="NominalPercentageOfCardiacPhase"	Type="1C"  	NoCondition="" mbpo="true"	# too hard
+		Name="NominalCardiacTriggerDelayTime"	Type="1"
+		Name="ActualCardiacTriggerDelayTime"	Type="1C"	Condition="SingleCardiacIntervalAcquired" mbpo="true"
+		Name="IntervalsAcquired"				Type="3"
+		Name="IntervalsRejected"				Type="3"
+		Name="HeartRate"						Type="3"
+		Name="RRIntervalTimeNominal"			Type="1C"	Condition="CardiacSynchronizationTechniqueOtherThanNoneOrRealTime" mbpo="true"
+		Name="LowRRValue"						Type="3"
+		Name="HighRRValue"						Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="FrameAnatomyMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameAnatomySequence"						Type="1"	VM="1"
+		Name="FrameLaterality"							Type="1"	StringEnumValues="ImageLaterality"
+		InvokeMacro="GeneralAnatomyMandatoryMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PixelValueTransformationMacro" InformationEntity="FunctionalGroup"
+	Sequence="PixelValueTransformationSequence"		Type="1"	VM="1"
+		Name="RescaleIntercept"						Type="1" 
+		Name="RescaleSlope"							Type="1"	NotZeroError=""
+		Name="RescaleType"							Type="1"
+		Verify="RescaleType"						Type="1C"	StringDefinedTerms="RescaleTypeUnspecified"	Condition="ModalityIsMROrPET"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="FrameVOILUTMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameVOILUTSequence"				Type="1"	VM="1"
+		Name="WindowCenter"						Type="1"
+		Name="WindowWidth"						Type="1"	NotZeroError=""
+		Verify="WindowWidth"								Condition="WindowWidthIsNegative"	ThenErrorMessage="Not permitted to be negative" ShowValueWithMessage="true"
+		Name="WindowCenterWidthExplanation"		Type="3"
+		Verify="WindowCenterWidthExplanation"	Type="1C"	StringDefinedTerms="EnhancedCTWindowCenterWidthExplanation"	Condition="ModalityIsCT"
+		Name="VOILUTFunction"					Type="3"	StringDefinedTerms="VOILUTFunction"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="RealWorldValueMappingMacro" InformationEntity="FunctionalGroup"
+	Sequence="RealWorldValueMappingSequence"		Type="1"	VM="1-n"
+		InvokeMacro="RealWorldValueMappingItemMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="RealWorldValueMappingItemMacro" InformationEntity="FunctionalGroup"
+	Name="RealWorldValueFirstValueMapped"		Type="1" 
+	Name="RealWorldValueLastValueMapped"		Type="1" 
+	Name="RealWorldValueIntercept"				Type="1C" 	Condition="RealWorldValueLUTDataNotPresent"
+	Name="RealWorldValueSlope"					Type="1C" 	Condition="RealWorldValueLUTDataNotPresent"
+	Name="RealWorldValueLUTData"				Type="1C" 	Condition="RealWorldValueInterceptNotPresent"
+	Name="LUTExplanation"						Type="1" 
+	Name="LUTLabel"								Type="1" 
+	Sequence="MeasurementUnitsCodeSequence"		Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"						DefinedContextID="7181"
+	SequenceEnd
+	Sequence="QuantityDefinitionSequence"		Type="3"	VM="1-n"
+		InvokeMacro="ContentItemMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="ContrastBolusUsageMacro" InformationEntity="FunctionalGroup"
+	Sequence="ContrastBolusUsageSequence"			Type="1"	VM="1-n"
+		Name="ContrastBolusAgentNumber"				Type="1" 
+		Name="ContrastBolusAgentAdministered"		Type="1"	StringEnumValues="YesNoFull"
+		Name="ContrastBolusAgentDetected"			Type="2"	StringEnumValues="YesNoFull"
+		Name="ContrastBolusAgentPhase"				Type="2C"	NoCondition="" StringDefinedTerms="ContrastBolusAgentPhase"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PixelIntensityRelationshipLUTMacro" InformationEntity="FunctionalGroup"
+	Sequence="PixelIntensityRelationshipLUTSequence"	Type="1"	VM="1-n"
+		Name="LUTDescriptor"							Type="1" 
+		Name="LUTData"									Type="1" 
+		Name="LUTFunction"								Type="1" 	StringEnumValues="PixelIntensityRelationshipLUTFunction"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="FramePixelShiftMacro" InformationEntity="FunctionalGroup"
+	Sequence="FramePixelShiftSequence"		Type="1"	VM="1-n"
+		Name="SubtractionItemID"			Type="1" 
+		Name="MaskSubPixelShift"			Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PatientOrientationInFrameMacro" InformationEntity="FunctionalGroup"
+	Sequence="PatientOrientationInFrameSequence"		Type="1"	VM="1"
+		Name="PatientOrientation"						Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="FrameDisplayShutterMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameDisplayShutterSequence"		Type="1"	VM="1"
+		InvokeMacro="DisplayShutterMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="RespiratorySynchronizationMacro" InformationEntity="FunctionalGroup"
+	Sequence="RespiratorySynchronizationSequence"		Type="1"	VM="1"
+		Name="RespiratoryIntervalTime"					Type="1C"	Condition="NeedRespiratoryIntervalTime"
+		Name="NominalPercentageOfRespiratoryPhase"		Type="1C"  	NoCondition="" mbpo="true"	# too hard
+		Name="NominalRespiratoryTriggerDelayTime"		Type="1"
+		Name="ActualRespiratoryTriggerDelayTime"		Type="1C"	Condition="RespiratoryTriggerTypeTimeOrBoth"
+		Name="StartingRespiratoryAmplitude"				Type="1C"	Condition="RespiratoryTriggerTypeAmplitudeOrBoth"
+		Name="StartingRespiratoryPhase"					Type="1C"	Condition="StartingRespiratoryAmplitudeIsPresent"	StringEnumValues="RespiratoryPhase"
+		Name="EndingRespiratoryAmplitude"				Type="1C"	Condition="RespiratoryTriggerTypeAmplitudeOrBoth"
+		Name="EndingRespiratoryPhase"					Type="1C"	Condition="EndingRespiratoryAmplitudeIsPresent"		StringEnumValues="RespiratoryPhase"
+		
+	SequenceEnd
+MacroEnd
+
+DefineMacro="IrradiationEventIdentificationMacro" InformationEntity="FunctionalGroup"
+	Sequence="IrradiationEventIdentificationSequence"	Type="1"	VM="1"
+		Name="IrradiationEventUID"						Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="RadiopharmaceuticalUsageMacro" InformationEntity="FunctionalGroup"
+	Sequence="RadiopharmaceuticalUsageSequence"	Type="1"	VM="1"
+		Name="RadiopharmaceuticalAgentNumber"	Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PatientPhysiologicalStateMacro" InformationEntity="FunctionalGroup"
+	Sequence="PatientPhysiologicalStateSequence"			Type="1"	VM="1"
+		Sequence="PatientPhysiologicalStateCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"					DefinedContextID="3101"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameDimension"
+	Sequence="DimensionOrganizationSequence"	Type="1"	VM="1-n"
+		Name="DimensionOrganizationUID"			Type="1" 
+	SequenceEnd
+	Name="DimensionOrganizationType"			Type="3"	StringDefinedTerms="DimensionOrganizationType"
+	Sequence="DimensionIndexSequence"			Type="1"	VM="1-n"
+		Name="DimensionIndexPointer"			Type="1"
+		Name="DimensionIndexPrivateCreator"		Type="1C"	NoCondition="" # too hard to check
+		Name="FunctionalGroupPointer"			Type="1C"	Condition="DimensionIndexPointerIsNotFunctionalGroup"
+		Name="FunctionalGroupPrivateCreator"	Type="1C"	NoCondition="" # too hard to check
+		Name="DimensionOrganizationUID"			Type="1C" 	NoCondition="" # too hard to check number of items
+		Name="DimensionDescriptionLabel"		Type="3" 
+	SequenceEnd
+ModuleEnd
+
+Module="CardiacSynchronization"	
+	Name="CardiacSynchronizationTechnique"		Type="1C" 	StringEnumValues="CardiacSynchronizationTechnique"	Condition="ImageTypeValue1OriginalOrMixed" mbpo="true"
+	Name="CardiacSignalSource"					Type="1C" 	StringDefinedTerms="CardiacSignalSource"		Condition="CardiacSynchronizationTechniqueNotNoneAndOriginalOrMixed" mbpo="true"
+	Verify="CardiacSignalSource"							Condition="CardiacSignalSourcePresentAndCardiacSynchronizationTechniqueIsNone"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is NONE"
+	Name="CardiacRRIntervalSpecified"			Type="1C" 	Condition="CardiacSynchronizationTechniqueNotNoneAndOriginalOrMixed"
+	Verify="CardiacRRIntervalSpecified"						Condition="CardiacRRIntervalSpecifiedPresentAndCardiacSynchronizationTechniqueIsNone"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is NONE"
+	Name="CardiacBeatRejectionTechnique"		Type="1C" 	StringDefinedTerms="CardiacBeatRejectionTechnique"	Condition="CardiacSynchronizationTechniqueProspectiveOrRetrospective"
+	Verify="CardiacBeatRejectionTechnique"					Condition="CardiacBeatRejectionTechniquePresentAndCardiacSynchronizationTechniqueIsNotProspectiveOrRetrospective"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is not PROSPECTIVE or RETROSPECTIVE"
+	Name="LowRRValue"							Type="2C" 	Condition="CardiacSynchronizationTechniqueProspectiveOrRetrospective"
+	Verify="LowRRValue"										Condition="LowRRValuePresentAndCardiacSynchronizationTechniqueIsNotProspectiveOrRetrospective"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is not PROSPECTIVE or RETROSPECTIVE"
+	Name="HighRRValue"							Type="2C" 	Condition="CardiacSynchronizationTechniqueProspectiveOrRetrospective"
+	Verify="HighRRValue"									Condition="HighRRValuePresentAndCardiacSynchronizationTechniqueIsNotProspectiveOrRetrospective"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is not PROSPECTIVE or RETROSPECTIVE"
+	Name="IntervalsAcquired"					Type="2C" 	Condition="CardiacSynchronizationTechniqueNotNoneAndOriginalOrMixed"
+	Verify="IntervalsAcquired"								Condition="IntervalsAcquiredPresentAndCardiacSynchronizationTechniqueIsNone"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is NONE"
+	Name="IntervalsRejected"					Type="2C" 	Condition="CardiacSynchronizationTechniqueNotNoneAndOriginalOrMixed"
+	Verify="IntervalsRejected"								Condition="IntervalsRejectedPresentAndCardiacSynchronizationTechniqueIsNone"	ThenErrorMessage="May not be present when CardiacSynchronizationTechnique is NONE"
+	Name="SkipBeats"							Type="3" 
+	Name="CardiacFramingType"					Type="1C"	NoCondition="" 	StringDefinedTerms="CardiacFramingType"
+ModuleEnd
+
+Module="RespiratorySynchronization"
+	Name="RespiratoryMotionCompensationTechnique"	Type="1C" 	StringDefinedTerms="RespiratoryMotionCompensationTechnique"	Condition="ImageTypeValue1OriginalOrMixed" mbpo="true"
+	Name="RespiratorySignalSource"					Type="1C" 	StringDefinedTerms="RespiratorySignalSource"			Condition="RespiratoryMotionCompensationTechniqueNotNone"
+	Verify="RespiratorySignalSource"							Condition="RespiratorySignalSourcePresentAndRespiratoryMotionCompensationTechniqueIsNone"	ThenErrorMessage="May not be present when RespiratoryMotionCompensationTechnique is NONE"
+	Name="RespiratoryTriggerDelayThreshold"			Type="1C" 	Condition="RespiratoryMotionCompensationTechniqueNotNoneOrRealTimeOrBreathHoldAndOriginalOrMixed" mbpo="true"
+	Name="RespiratoryTriggerType"					Type="1C"	NoCondition="" 	StringDefinedTerms="RespiratoryTriggerType"
+ModuleEnd
+
+Module="BulkMotionSynchronization"
+	Name="BulkMotionCompensationTechnique"		Type="1C" 	StringDefinedTerms="BulkMotionCompensationTechnique"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="BulkMotionSignalSource"				Type="1C" 	StringDefinedTerms="BulkMotionSignalSource"		Condition="BulkMotionCompensationTechniqueNotNoneAndOriginalOrMixed"
+	Verify="BulkMotionSignalSource"							Condition="BulkMotionSignalSourcePresentAndBulkMotionCompensationTechniqueIsNone"	ThenErrorMessage="May not be present when BulkMotionCompensationTechnique is NONE"
+ModuleEnd
+
+Module="SupplementalPaletteColorLUT"
+	Name="RedPaletteColorLookupTableDescriptor"		Type="1"
+	Verify="RedPaletteColorLookupTableDescriptor"	Type="1"	ValueSelector="2"	BinaryEnumValues="BitsAre16"
+	Name="GreenPaletteColorLookupTableDescriptor"	Type="1"
+	Verify="GreenPaletteColorLookupTableDescriptor"	Type="1"	ValueSelector="2"	BinaryEnumValues="BitsAre16"
+	Name="BluePaletteColorLookupTableDescriptor"	Type="1"
+	Verify="BluePaletteColorLookupTableDescriptor"	Type="1"	ValueSelector="2"	BinaryEnumValues="BitsAre16"
+	Name="RedPaletteColorLookupTableData"			Type="1"
+	Name="GreenPaletteColorLookupTableData"			Type="1"
+	Name="BluePaletteColorLookupTableData"			Type="1"
+ModuleEnd
+
+DefineMacro="PaletteColorLookupTableMacro"
+	Name="RedPaletteColorLookupTableDescriptor"			Type="1"
+	Verify="RedPaletteColorLookupTableDescriptor"					Condition="NotColorPaletteInstance"	ValueSelector="2"	BinaryEnumValues="BitsAre16"
+	Verify="RedPaletteColorLookupTableDescriptor"					Condition="ColorPaletteInstance"	ValueSelector="2"	BinaryEnumValues="BitsAre8"
+	Name="GreenPaletteColorLookupTableDescriptor"		Type="1"
+	Verify="GreenPaletteColorLookupTableDescriptor"					Condition="NotColorPaletteInstance"	ValueSelector="2"	BinaryEnumValues="BitsAre16"
+	Verify="GreenPaletteColorLookupTableDescriptor"					Condition="ColorPaletteInstance"	ValueSelector="2"	BinaryEnumValues="BitsAre8"
+	Name="BluePaletteColorLookupTableDescriptor"		Type="1"
+	Verify="BluePaletteColorLookupTableDescriptor"					Condition="NotColorPaletteInstance"	ValueSelector="2"	BinaryEnumValues="BitsAre16"
+	Verify="BluePaletteColorLookupTableDescriptor"					Condition="ColorPaletteInstance"	ValueSelector="2"	BinaryEnumValues="BitsAre8"
+	Name="PaletteColorLookupTableUID"					Type="3"	# should check matches SOPInstanceUID if is ColorPaletteInstance :(
+	Name="RedPaletteColorLookupTableData"				Type="1C"	Condition="NeedsNonSegmentedLookupTableData"
+	Name="GreenPaletteColorLookupTableData"				Type="1C"	Condition="NeedsNonSegmentedLookupTableData"
+	Name="BluePaletteColorLookupTableData"				Type="1C"	Condition="NeedsNonSegmentedLookupTableData"
+	Name="SegmentedRedPaletteColorLookupTableData"		Type="1C"	Condition="NeedsSegmentedLookupTableData"
+	Name="SegmentedGreenPaletteColorLookupTableData"	Type="1C"	Condition="NeedsSegmentedLookupTableData"
+	Name="SegmentedBluePaletteColorLookupTableData"		Type="1C"	Condition="NeedsSegmentedLookupTableData"
+MacroEnd
+
+Module="PaletteColorLookupTable"
+	InvokeMacro="PaletteColorLookupTableMacro"
+ModuleEnd
+
+Module="PatientOrientation"
+	InvokeMacro="PatientOrientationMacro"
+ModuleEnd
+
+Module="ImageEquipmentCoordinateRelationship"
+	Name="ImageToEquipmentMappingMatrix"				Type="1"
+	Name="EquipmentCoordinateSystemIdentification"		Type="1"	StringEnumValues="EquipmentCoordinateSystemIdentification"
+ModuleEnd
+
+Module="CRSeries"
+	Name="BodyPartExamined"				Type="2"
+	Verify="BodyPartExamined"						Condition="IsHuman"		StringDefinedTerms="BodyPartExaminedHuman"
+	Verify="BodyPartExamined"						Condition="IsAnimal"	StringDefinedTerms="BodyPartExaminedAnimal"
+	Name="ViewPosition"					Type="2"
+	Verify="ViewPosition"							Condition="IsHuman"		StringDefinedTerms="ViewPositionHuman"
+	Verify="ViewPosition"							Condition="IsAnimal"	StringDefinedTerms="ViewPositionAnimal"
+	Name="FilterType"					Type="3"
+	Name="CollimatorGridName"			Type="3"
+	Name="FocalSpots"					Type="3"
+	Name="PlateType"					Type="3"
+	Name="PhosphorType"					Type="3"
+ModuleEnd
+
+Module="CRImage"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="PhotometricInterpretationMonochrome"
+	Name="KVP"										Type="3"	NotZeroWarning=""
+	Name="PlateID"									Type="3"
+	Name="DistanceSourceToDetector"					Type="3"
+	Name="DistanceSourceToPatient"					Type="3"
+	Name="ExposureTime"								Type="3"	NotZeroWarning=""
+	Verify="ExposureTimeInms"									Condition="ExposureTimeInmsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <CRImage> - use ExposureTime instead of"
+
+	Name="XRayTubeCurrent"							Type="3"	NotZeroWarning=""
+	Verify="XRayTubeCurrentInmA"								Condition="XRayTubeCurrentInmAIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <CRImage> - use XRayTubeCurrent instead of"
+
+	Name="Exposure"									Type="3"	NotZeroWarning=""
+	Name="ExposureInuAs"							Type="3"	NotZeroWarning=""
+	Verify="ExposureInmAs"										Condition="ExposureInmAsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <CRImage> - use Exposure and/or ExposureInuAs instead of"
+
+	Name="ImagerPixelSpacing"						Type="3"	NotZeroError=""
+	InvokeMacro="BasicPixelSpacingCalibrationMacro"
+	Name="GeneratorPower"							Type="3"	NotZeroWarning=""
+	Name="AcquisitionDeviceProcessingDescription"	Type="3"
+	Name="AcquisitionDeviceProcessingCode"			Type="3"
+	Name="CassetteOrientation"						Type="3"	StringEnumValues="Orientation"
+	Name="CassetteSize"								Type="3"	StringDefinedTerms="CassetteSize"
+	Name="ExposuresOnPlate"							Type="3"	NotZeroWarning=""
+	Name="RelativeXRayExposure"						Type="3"	NotZeroWarning=""
+	Name="Sensitivity"								Type="3"	NotZeroWarning=""
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	InvokeMacro="ExposureIndexMacro"
+ModuleEnd
+
+Module="CTImage"
+	Name="ImageType"					Type="1"	ValueSelector="2"	StringDefinedTerms="CTImageType3"
+	Verify="ImageType"								Condition="ImageTypeValue3MissingOrEmpty"	ThenErrorMessage="A value is required for value 3 in CT Images"
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"	Type="1"	StringEnumValues="PhotometricInterpretationMonochrome"
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"					Type="1"	BinaryEnumValues="BitsAre12To16"
+	Name="HighBit"						Type="1"	BinaryEnumValues="BitsAre11To15"
+	Name="RescaleIntercept"				Type="1"
+	Name="RescaleSlope"					Type="1"	NotZeroError=""
+	Name="RescaleType"					Type="1C"	Condition="RescaleTypeIsPresentAndNotHU"	StringDefinedTerms="RescaleTypeHounsfieldUnits" mbpo="true"
+	Verify="RescaleType"							Condition="RescaleTypeIsPresentAndNotHUAndImageIsOriginalNotLocalizer" ThenErrorMessage="If RescaleType is present, must be HU for ORIGINAL non-LOCALIZER images"
+	Verify="RescaleType"							Condition="RescaleTypeIsPresentAndIsHUAndImageIsOriginalLocalizer"   ThenWarningMessage="If RescaleType is present, should not be HU for ORIGINAL LOCALIZER images"
+	Name="KVP"							Type="2"	NotZeroWarning=""
+	Name="AcquisitionNumber"			Type="2"
+	Name="ScanOptions"					Type="3"
+	Name="DataCollectionDiameter"		Type="3"	NotZeroWarning=""
+	Name="DataCollectionCenterPatient"	Type="3"
+	Name="ReconstructionDiameter"		Type="3"	NotZeroWarning=""
+	Name="ReconstructionTargetCenterPatient"	Type="3"
+	Name="DistanceSourceToDetector"		Type="3"	NotZeroWarning=""
+	Name="DistanceSourceToPatient"		Type="3"	NotZeroWarning=""
+	Name="GantryDetectorTilt"			Type="3"
+	Name="TableHeight"					Type="3"
+	Name="RotationDirection"			Type="3"	StringEnumValues="RotationDirection"
+	Name="ExposureTime"					Type="3"	NotZeroWarning=""
+	Verify="ExposureTimeInms"						Condition="ExposureTimeInmsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <CTImage> - use ExposureTime instead of"
+	
+	Name="XRayTubeCurrent"				Type="3"	NotZeroWarning=""
+	Verify="XRayTubeCurrentInmA"					Condition="XRayTubeCurrentInmAIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <CTImage> - use XRayTubeCurrent instead of"
+	
+	Name="Exposure"						Type="3"	NotZeroWarning=""
+	Name="ExposureInuAs"				Type="3"	NotZeroWarning=""
+	Verify="ExposureInmAs"							Condition="ExposureInmAsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <CTImage> - use Exposure and/or ExposureInuAs instead of"
+	
+	Name="FilterType"					Type="3"
+	Name="GeneratorPower"				Type="3"	NotZeroWarning=""
+	Name="FocalSpots"					Type="3"
+	Name="ConvolutionKernel"			Type="3"
+	Name="RevolutionTime"				Type="3"	NotZeroWarning=""
+	Name="SingleCollimationWidth"		Type="3"	NotZeroWarning=""
+	Name="TotalCollimationWidth"		Type="3"	NotZeroWarning=""
+	Name="TableSpeed"					Type="3"	NotZeroWarning=""
+	Name="TableFeedPerRotation"			Type="3"	NotZeroWarning=""
+	Name="SpiralPitchFactor"			Type="3"	NotZeroWarning=""
+	Name="ExposureModulationType"		Type="3"
+	Name="EstimatedDoseSaving"			Type="3"
+	Name="CTDIvol"						Type="3"	NotZeroWarning=""
+	Sequence="CTDIPhantomTypeCodeSequence"	Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"				DefinedContextID="4052"
+	SequenceEnd
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+	Name="CalciumScoringMassFactorPatient"		Type="3"	NotZeroWarning=""
+	Name="CalciumScoringMassFactorDevice"		Type="3"	NotZeroWarning=""
+	Name="EnergyWeightingFactor"				Type="1C"	Condition="MultiEnergyProportionalWeighting" mbpo="true"
+	Sequence="CTAdditionalXRaySourceSequence"	Type="3"	VM="1-n"
+		Name="KVP"								Type="1"	NotZeroWarning=""
+		Name="XRayTubeCurrentInmA"				Type="1"	NotZeroWarning=""
+		Name="DataCollectionDiameter"			Type="1"	NotZeroWarning=""
+		Name="FocalSpots"						Type="1"
+		Name="FilterType"						Type="1"
+		Name="FilterMaterial"					Type="1"
+		Name="ExposureInmAs"					Type="3"	NotZeroWarning=""
+		Name="EnergyWeightingFactor"			Type="1C"	NotZeroWarning=""	Condition="EnergyWeightingFactorPresentInRoot" mbpo="true"	# delegate condition since hard otherwise; same result
+	SequenceEnd
+	Name="IsocenterPosition"					Type="3"
+	InvokeMacro="RTEquipmentCorrelationMacro"
+ModuleEnd
+
+Module="MRImage"
+	Name="ImageType"					Type="1"	ValueSelector="2"	StringDefinedTerms="MRImageType3"
+	Verify="ImageType"								Condition="ImageTypeValue3MissingOrEmpty"	ThenErrorMessage="A value is required for value 3 in MR Images"
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"	Type="1"	StringEnumValues="PhotometricInterpretationMonochrome"
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="BitsAre16"
+	Name="ScanningSequence"				Type="1"	StringEnumValues="ScanningSequence"
+	Name="SequenceVariant"				Type="1"	StringDefinedTerms="SequenceVariant"
+	Name="ScanOptions"					Type="2"	StringDefinedTerms="ScanOptions"
+	Name="MRAcquisitionType"			Type="2"	StringEnumValues="MRAcquisitionType"
+	Name="RepetitionTime"				Type="2C"	Condition="MRIsNotEchoPlanarNotSegmentedKSpace"
+	Name="EchoTime"						Type="2"	NotZeroWarning=""
+	Name="EchoTrainLength"				Type="2"	NotZeroWarning=""
+	Name="InversionTime"				Type="2C"	Condition="MRIsInversionRecovery"	NotZeroWarning=""
+	Name="TriggerTime"					Type="2C"	Condition="MRIsCardiacOrPulseGated"
+	Name="SequenceName"					Type="3"
+	Name="AngioFlag"					Type="3"	StringEnumValues="AngioFlag"
+	Name="NumberOfAverages"				Type="3"	NotZeroWarning=""
+	Name="ImagingFrequency"				Type="3"	NotZeroWarning=""
+	Name="ImagedNucleus"				Type="3"
+	Name="EchoNumbers"					Type="3"
+	Name="MagneticFieldStrength"		Type="3"	NotZeroWarning=""
+	Name="SpacingBetweenSlices"			Type="3"
+	Name="NumberOfPhaseEncodingSteps"	Type="3"
+	Name="PercentSampling"				Type="3"
+	Name="PercentPhaseFieldOfView"		Type="3"
+	Name="PixelBandwidth"				Type="3"
+	Name="NominalInterval"				Type="3"
+	Name="BeatRejectionFlag"			Type="3"	StringEnumValues="YesNoLetter"
+	Name="LowRRValue"					Type="3"
+	Name="HighRRValue"					Type="3"
+	Name="IntervalsAcquired"			Type="3"
+	Name="IntervalsRejected"			Type="3"
+	Name="PVCRejection"					Type="3"
+	Name="SkipBeats"					Type="3"
+	Name="HeartRate"					Type="3"
+	Name="CardiacNumberOfImages"		Type="3"
+	Name="TriggerWindow"				Type="3"
+	Name="ReconstructionDiameter"		Type="3"
+	Name="ReceiveCoilName"				Type="3"
+	Name="TransmitCoilName"				Type="3"
+	Name="AcquisitionMatrix"			Type="3"
+	Name="InPlanePhaseEncodingDirection"	Type="3"	StringEnumValues="PhaseEncodingDirection"
+	Name="FlipAngle"					Type="3"	NotZeroWarning=""
+	Name="SAR"							Type="3"
+	Name="VariableFlipAngleFlag"		Type="3"	StringEnumValues="YesNoLetter"
+	Name="dBdt"							Type="3"
+	Name="TemporalPositionIdentifier"	Type="3"
+	Name="NumberOfTemporalPositions"	Type="3"
+	Name="TemporalResolution"			Type="3"
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+ModuleEnd
+
+Module="NMPETPatientOrientation"
+	Sequence="PatientOrientationCodeSequence"				Type="2"	VM="0-1"
+		InvokeMacro="CodeSequence99SDMMacro"							BaselineContextID="19"
+		Sequence="PatientOrientationModifierCodeSequence"   Type="2C"	VM="0-1"	NoCondition=""	# real-world - orientation wrt. gravity
+ 			InvokeMacro="CodeSequence99SDMMacro"						BaselineContextID="20"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PatientGantryRelationshipCodeSequence"		Type="2"	VM="0-1"
+		InvokeMacro="CodeSequence99SDMMacro"							BaselineContextID="21"
+	SequenceEnd
+ModuleEnd
+
+Module="NMImagePixel"
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"   	Type="1"	StringEnumValues="NMPhotometricInterpretation"
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"					Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="HighBit"						Type="1"	BinaryEnumValues="BitsAre7Or15"
+	Name="PixelSpacing"					Type="2"	NotZeroError=""
+ModuleEnd
+
+Module="NMMultiFrame"
+	Name="FrameIncrementPointer"   		Type="1"	TagEnumValues="NMFrameIncrementPointerValues"
+	
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3WholeBodyOrStatic"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsEnergyWindowVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3WholeBodyOrStatic"	ValueSelector="1"	TagEnumValues="FrameIncrementPointerIsDetectorVector"
+	
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Dynamic"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsEnergyWindowVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Dynamic"	ValueSelector="1"	TagEnumValues="FrameIncrementPointerIsDetectorVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Dynamic"	ValueSelector="2"	TagEnumValues="FrameIncrementPointerIsPhaseVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Dynamic"	ValueSelector="3"	TagEnumValues="FrameIncrementPointerIsTimeSliceVector"
+
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Gated"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsEnergyWindowVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Gated"	ValueSelector="1"	TagEnumValues="FrameIncrementPointerIsDetectorVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Gated"	ValueSelector="2"	TagEnumValues="FrameIncrementPointerIsRRIntervalVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Gated"	ValueSelector="3"	TagEnumValues="FrameIncrementPointerIsTimeSlotVector"
+
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Tomo"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsEnergyWindowVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Tomo"	ValueSelector="1"	TagEnumValues="FrameIncrementPointerIsDetectorVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Tomo"	ValueSelector="2"	TagEnumValues="FrameIncrementPointerIsRotationVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3Tomo"	ValueSelector="3"	TagEnumValues="FrameIncrementPointerIsAngularViewVector"
+
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3GatedTomo"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsEnergyWindowVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3GatedTomo"	ValueSelector="1"	TagEnumValues="FrameIncrementPointerIsDetectorVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3GatedTomo"	ValueSelector="2"	TagEnumValues="FrameIncrementPointerIsRotationVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3GatedTomo"	ValueSelector="3"	TagEnumValues="FrameIncrementPointerIsRRIntervalVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3GatedTomo"	ValueSelector="4"	TagEnumValues="FrameIncrementPointerIsTimeSlotVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3GatedTomo"	ValueSelector="5"	TagEnumValues="FrameIncrementPointerIsAngularViewVector"
+
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3ReconTomo"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsSliceVector"
+
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3ReconGatedTomo"	ValueSelector="0"	TagEnumValues="FrameIncrementPointerIsRRIntervalVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3ReconGatedTomo"	ValueSelector="1"	TagEnumValues="FrameIncrementPointerIsTimeSlotVector"
+	Verify="FrameIncrementPointer"					Condition="ImageTypeValue3ReconGatedTomo"	ValueSelector="2"	TagEnumValues="FrameIncrementPointerIsSliceVector"
+	
+	Name="EnergyWindowVector"   		Type="1C"	Condition="FrameIncrementPointerContainsEnergyWindowVector"
+	Name="NumberOfEnergyWindows"   		Type="1"
+	Name="DetectorVector"				Type="1C"	Condition="FrameIncrementPointerContainsDetectorVector"
+	Name="NumberOfDetectors"			Type="1"
+	Name="PhaseVector"					Type="1C"	Condition="FrameIncrementPointerContainsPhaseVector"
+	Name="NumberOfPhases"				Type="1C"	Condition="FrameIncrementPointerContainsPhaseVector"
+	Name="RotationVector"				Type="1C"	Condition="FrameIncrementPointerContainsRotationVector"
+	Name="NumberOfRotations"			Type="1C"	Condition="ImageTypeValue3TomoFamily"
+	Name="RRIntervalVector"				Type="1C"	Condition="FrameIncrementPointerContainsRRIntervalVector"
+	Name="NumberOfRRIntervals"   		Type="1C"	Condition="FrameIncrementPointerContainsRRIntervalVector"
+	Name="TimeSlotVector"				Type="1C"	Condition="FrameIncrementPointerContainsTimeSlotVector"
+	Name="NumberOfTimeSlots"			Type="1C"	Condition="FrameIncrementPointerContainsTimeSlotVector"
+	Name="SliceVector"					Type="1C"	Condition="FrameIncrementPointerContainsSliceVector"
+	Name="NumberOfSlices"				Type="1C"	Condition="FrameIncrementPointerContainsSliceVector"
+	Name="AngularViewVector"			Type="1C"	Condition="FrameIncrementPointerContainsAngularViewVector"
+	Name="TimeSliceVector"				Type="1C"	Condition="FrameIncrementPointerContainsTimeSliceVector"
+ModuleEnd
+
+Module="NMImage"
+	Name="ImageType"						Type="1"	ValueSelector="1"	StringEnumValues="NMImageTypeValue2"
+	Verify="ImageType"									ValueSelector="2"	StringEnumValues="NMImageTypeValue3"
+	Verify="ImageType"									ValueSelector="3"	StringEnumValues="NMImageTypeValue4"
+	Verify="ImageType"								Condition="ImageTypeValue3MissingOrEmpty"	ThenErrorMessage="A value is required for value 3 in NM Images"
+	Verify="ImageType"								Condition="ImageTypeValue4MissingOrEmpty"	ThenErrorMessage="A value is required for value 4 in NM Images"
+	Name="ImageID"							Type="3"
+	Name="LossyImageCompression"			Type="1C"	NoCondition=""	StringEnumValues="LossyImageCompression"
+	Name="CountsAccumulated"				Type="2"
+	Name="AcquisitionTerminationCondition"	Type="3"	StringDefinedTerms="NMAcquisitionTerminationCondition"
+	Name="TableHeight"						Type="3"
+	Name="TableTraverse"					Type="3"
+	Name="ActualFrameDuration"				Type="1C"	Condition="ImageTypeValue3WholeBodyOrStatic"
+	Name="CountRate"						Type="3"
+	Name="ProcessingFunction"				Type="3"
+	Name="CorrectedImage"					Type="3"	StringDefinedTerms="NMCorrectedImage"
+	Name="WholeBodyTechnique"				Type="3"	StringEnumValues="NMWholeBodyTechnique"
+	Name="ScanVelocity"						Type="2C"	Condition="ImageTypeValue3WholeBody"
+	Name="ScanLength"						Type="2C"	Condition="ImageTypeValue3WholeBody"
+	Name="TriggerSourceOrType"   			Type="3"	StringDefinedTerms="EKG"
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	Sequence="RealWorldValueMappingSequence"		Type="3"	VM="1-n"
+		InvokeMacro="RealWorldValueMappingItemMacro"
+	SequenceEnd
+ModuleEnd
+	
+Module="NMIsotope"
+	Sequence="EnergyWindowInformationSequence"   		Type="2"	VM="0-n"
+            Name="EnergyWindowName"						Type="3"
+            Sequence="EnergyWindowRangeSequence"   		Type="3"	VM="1-n"
+                    Name="EnergyWindowLowerLimit"   	Type="3"
+                    Name="EnergyWindowUpperLimit"   	Type="3"
+	    SequenceEnd
+	SequenceEnd
+	Sequence="RadiopharmaceuticalInformationSequence"  	Type="2"	VM="0-n"
+		Sequence="RadionuclideCodeSequence"				Type="2"	VM="0-1"
+			InvokeMacro="CodeSequence99SDMMacro"		BaselineContextID="18"
+	    SequenceEnd
+		Name="RadiopharmaceuticalRoute"					Type="3"
+		Sequence="AdministrationRouteCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMeaningOptionalMacro"		BaselineContextID="11"
+	    SequenceEnd
+		Name="RadiopharmaceuticalVolume"				Type="3"
+		Name="RadiopharmaceuticalStartTime"				Type="3"
+		Name="RadiopharmaceuticalStopTime"				Type="3"
+		Name="RadionuclideTotalDose"					Type="3"
+		Sequence="CalibrationDataSequence"				Type="3"	VM="1-n"
+			Name="EnergyWindowNumber"					Type="1"
+			Name="SyringeCounts"						Type="3"
+			Name="ResidualSyringeCounts"				Type="3"
+	    SequenceEnd
+		Name="Radiopharmaceutical"						Type="3"
+		Sequence="RadiopharmaceuticalCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMeaningOptionalMacro"		BaselineContextID="25"
+	    SequenceEnd
+	SequenceEnd
+	Sequence="InterventionDrugInformationSequence"   	Type="3"	VM="1-n"
+		Name="InterventionDrugName"						Type="3"
+		Sequence="InterventionDrugCodeSequence"   		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMeaningOptionalMacro"		BaselineContextID="10"
+	    SequenceEnd
+		Sequence="AdministrationRouteCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMeaningOptionalMacro"		BaselineContextID="11"
+	    SequenceEnd
+		Name="InterventionDrugStartTime"				Type="3"
+		Name="InterventionDrugStopTime"					Type="3"
+		Name="InterventionDrugDose"						Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="NMDetector"
+	Sequence="DetectorInformationSequence"   	Type="2"	VM="0-n"
+		Name="CollimatorGridName"   			Type="3"
+		Name="CollimatorType"   				Type="2"	StringDefinedTerms="NMCollimatorType"
+		Name="FieldOfViewShape"   				Type="3"	StringDefinedTerms="NMFieldOfViewShape"
+		Name="FieldOfViewDimensions"   			Type="3"
+		Name="FocalDistance"					Type="3"
+		Name="XFocusCenter"						Type="3"
+		Name="YFocusCenter"						Type="3"
+		Name="ZoomCenter"						Type="3"
+		Name="ZoomFactor"						Type="3"
+		Name="CenterOfRotationOffset"   		Type="3"
+		Name="GantryDetectorTilt"   			Type="3"
+		Name="DistanceSourceToDetector"   		Type="2C"	Condition="ImageTypeValue4TransmissionAndNotTomo"
+		Name="StartAngle"						Type="3"
+		Name="RadialPosition"   				Type="3"
+		Name="ImageOrientationPatient"   		Type="2"
+		Name="ImagePositionPatient"   			Type="2"
+		Sequence="ViewCodeSequence"   			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMeaningOptionalMacro"		BaselineContextID="26"
+			Sequence="ViewModifierCodeSequence" Type="2C"	VM="0-1"	NoCondition=""	# if needed to fully specify the view
+				InvokeMacro="CodeSequenceMeaningOptionalMacro"	BaselineContextID="23"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="NMTomoAcquisition"
+	Sequence="RotationInformationSequence"  Type="2"	VM="0-n"
+		Name="StartAngle"   				Type="1"
+		Name="AngularStep"   				Type="1"
+		Name="RotationDirection"   			Type="1"	StringEnumValues="RotationDirection"
+		Name="ScanArc"   					Type="1"
+		Name="ActualFrameDuration"   		Type="1"
+		Name="RadialPosition"   			Type="3"
+		Name="DistanceSourceToDetector"  	Type="2C"	Condition="ImageTypeValue4Transmission"
+		Name="NumberOfFramesInRotation"   	Type="1"
+		Name="TableTraverse"   				Type="3"
+		Name="TableHeight"   				Type="3"
+	SequenceEnd
+	Name="TypeOfDetectorMotion"   			Type="3"	StringEnumValues="NMTypeOfDetectorMotion"
+ModuleEnd
+
+Module="NMMultiGatedAcquisition"
+	Name="BeatRejectionFlag"						Type="3"	StringEnumValues="YesNoLetter"
+	Name="PVCRejection"								Type="3"
+	Name="SkipBeats"								Type="3"
+	Name="HeartRate"								Type="3"
+	Sequence="GatedInformationSequence"   			Type="2C"	VM="0-n"	Condition="FrameIncrementPointerContainsRRIntervalVector"
+		Name="TriggerTime"							Type="3"
+		Name="CardiacFramingType"					Type="3"
+		Sequence="DataInformationSequence"   		Type="2"	VM="0-n"
+			Name="FrameTime"						Type="1"
+			Name="NominalInterval"					Type="3"
+			Name="LowRRValue"						Type="3"
+			Name="HighRRValue"						Type="3"
+			Name="IntervalsAcquired"				Type="3"
+			Name="IntervalsRejected"				Type="3"
+			Sequence="TimeSlotInformationSequence"  Type="2C"	VM="0-n"	Condition="FrameIncrementPointerContainsTimeSlotVector"
+				Name="TimeSlotTime"					Type="3"
+			SequenceEnd
+	    SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="NMPhase"
+	Sequence="PhaseInformationSequence"   	Type="2C"	VM="0-n"	Condition="FrameIncrementPointerContainsPhaseVector"
+		Name="PhaseDelay"					Type="1"
+		Name="ActualFrameDuration"			Type="1"
+		Name="PauseBetweenFrames"			Type="1"
+		Name="NumberOfFramesInPhase"		Type="1"
+		Name="TriggerVector"				Type="3"
+		Name="NumberOfTriggersInPhase"   	Type="1C"	Condition="TriggerVectorIsPresent"
+		Name="PhaseDescription"				Type="3"	StringDefinedTerms="NMPhaseDescription"
+	SequenceEnd
+ModuleEnd
+
+Module="NMReconstruction"
+	Name="SpacingBetweenSlices"   		Type="2"
+	Name="ReconstructionDiameter"   	Type="3"	NotZeroWarning=""
+	Name="ConvolutionKernel"			Type="3"
+	Name="SliceThickness"				Type="2"	NotZeroWarning=""
+	Name="SliceLocation"				Type="3"
+	Name="SliceProgressionDirection"	Type="3"	StringEnumValues="CardiacSliceProgressionDirection"
+ModuleEnd
+
+Module="USRegionCalibration"
+	Sequence="SequenceOfUltrasoundRegions"			Type="1"	VM="1-n"
+		Name="RegionLocationMinX0"					Type="1"
+		Name="RegionLocationMinY0"					Type="1"
+		Name="RegionLocationMaxX1"					Type="1"
+		Name="RegionLocationMaxY1"					Type="1"
+		Name="PhysicalUnitsXDirection"				Type="1"
+		Name="PhysicalUnitsYDirection"				Type="1"
+		Name="PhysicalDeltaX"						Type="1"
+		Name="PhysicalDeltaY"						Type="1"
+		Name="ReferencePixelX0"						Type="3"
+		Name="ReferencePixelY0"						Type="3"
+		Name="ReferencePixelPhysicalValueX"			Type="3"
+		Name="ReferencePixelPhysicalValueY"			Type="3"
+		Name="RegionSpatialFormat"					Type="1"	BinaryEnumValues="RegionSpatialFormat"
+		Name="RegionDataType"						Type="1"	BinaryEnumValues="RegionDataType"
+		Name="RegionFlags"							Type="1"	BinaryBitMap="RegionFlags"
+		Name="PixelComponentOrganization"			Type="1C"	Condition="NeedPixelComponentOrganization"	BinaryEnumValues="PixelComponentOrganization"
+		Name="PixelComponentMask"					Type="1C"	Condition="PixelComponentOrganizationIs0"
+		Name="PixelComponentRangeStart"				Type="1C"	Condition="PixelComponentOrganizationIs1"
+		Name="PixelComponentRangeStop"				Type="1C"	Condition="PixelComponentOrganizationIs1"
+		Name="PixelComponentPhysicalUnits"			Type="1C"	Condition="PixelComponentOrganizationPresent"	BinaryEnumValues="PixelComponentPhysicalUnits"
+		Name="PixelComponentDataType"				Type="1C"	Condition="PixelComponentOrganizationPresent"	BinaryEnumValues="PixelComponentDataType"
+		Name="NumberOfTableBreakPoints"				Type="1C"	Condition="PixelComponentOrganizationIs0Or1"
+		Name="TableOfXBreakPoints"					Type="1C"	Condition="PixelComponentOrganizationIs0Or1"
+		Name="TableOfYBreakPoints"					Type="1C"	Condition="PixelComponentOrganizationIs0Or1"
+		Name="NumberOfTableEntries"					Type="1C"	Condition="PixelComponentOrganizationIs2Or3"
+		Name="TableOfPixelValues"					Type="1C"	Condition="PixelComponentOrganizationIs2"
+		Name="TableOfParameterValues"				Type="1C"	Condition="PixelComponentOrganizationIs2"
+		Sequence="PixelValueMappingCodeSequence"	Type="1C"	VM="1-n"	Condition="PixelComponentOrganizationIs3"
+			InvokeMacro="CodeSequenceMacro"			BaselineContextID="3497"
+		SequenceEnd
+		Name="TransducerFrequency"					Type="3"
+		Name="PulseRepetitionFrequency"				Type="3"
+		Name="DopplerCorrectionAngle"				Type="3"
+		Name="SteeringAngle"						Type="3"
+		Name="DopplerSampleVolumeXPosition"			Type="3"
+		Name="DopplerSampleVolumeYPosition"			Type="3"
+		Name="TMLinePositionX0"						Type="3"
+		Name="TMLinePositionY0"						Type="3"
+		Name="TMLinePositionX1"						Type="3"
+		Name="TMLinePositionY1"						Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="USImage"
+	Name="SamplesPerPixel"							Type="1"	NotZeroError=""
+	Verify="SamplesPerPixel"									Condition="PhotometricInterpretationNeedsOneSample"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Verify="SamplesPerPixel"									Condition="PhotometricInterpretationNeedsThreeSamples"	BinaryEnumValues="SamplesPerPixelIsThree"
+	Name="PhotometricInterpretation"				Type="1"	StringDefinedTerms="USPhotometricInterpretation"
+	Name="BitsAllocated"							Type="1"	NotZeroError=""
+	Verify="BitsAllocated"										Condition="US8BitSamples"	BinaryEnumValues="BitsAre8"
+	Verify="BitsAllocated"										Condition="US8Or16BitSamples"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"								Type="1"	NotZeroError=""
+	Verify="BitsStored"											Condition="US8BitSamples"	BinaryEnumValues="BitsAre8"
+	Verify="BitsStored"											Condition="US8Or16BitSamples"	BinaryEnumValues="BitsAre8Or16"
+	Name="HighBit"									Type="1"
+	Verify="HighBit"											Condition="US8BitSamples"	BinaryEnumValues="BitsAre7"
+	Verify="HighBit"											Condition="US8Or16BitSamples"	BinaryEnumValues="BitsAre7Or15"
+	Name="PlanarConfiguration"						Type="1C"	Condition="SamplesPerPixelGreaterThanOne"	BinaryEnumValues="USPlanarConfiguration"
+	Verify="PlanarConfiguration"								Condition="USNeedsColorByPlaneOrPixel"	BinaryEnumValues="PlanarConfigurationIsColorByPlaneOrPixel"
+	Verify="PlanarConfiguration"								Condition="USNeedsColorByPixel"		BinaryEnumValues="PlanarConfigurationIsColorByPixel"
+	Verify="PlanarConfiguration"								Condition="USNeedsColorByPlane"		BinaryEnumValues="PlanarConfigurationIsColorByPlane"
+	Name="PixelRepresentation"						Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="FrameIncrementPointer"					Type="1C"	Condition="NumberOfFramesPresent"
+	Name="ImageType"								Type="2"  	ValueSelector="2"	StringDefinedTerms="USImageType3"
+	Verify="ImageType"											ValueSelector="3"	StringDefinedTerms="USImageType4"
+	Name="LossyImageCompression"					Type="1C"	NoCondition=""	StringEnumValues="LossyImageCompression"
+	Name="NumberOfStages"							Type="2C"	Condition="IsUltrasoundStageProtocol"
+	Name="NumberOfViewsInStage"						Type="2C"	Condition="IsUltrasoundStageProtocol"
+	Name="RWaveTimeVector"							Type="3"
+	Name="UltrasoundColorDataPresent"				Type="3"	BinaryEnumValues="UltrasoundColorDataPresent"
+	Name="StageName"								Type="3"	StringDefinedTerms="USStageName"
+	Sequence="StageCodeSequence"					Type="3"	VM="1-n"
+ 		InvokeMacro="CodeSequenceMacro"				BaselineContextID="12002"
+	SequenceEnd
+	Name="StageNumber"								Type="3"
+	Name="ViewName"									Type="3"
+	Name="ViewNumber"								Type="3"
+	Name="NumberOfEventTimers"						Type="3"
+	Name="EventElapsedTimes"						Type="3"
+	Name="EventTimerNames"							Type="3"
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+	Name="AcquisitionDateTime"						Type="1C"	Condition="ModalityIsIVUS" mbpo="true"
+	Name="TriggerTime"								Type="3"
+	Name="NominalInterval"							Type="3"
+	Name="BeatRejectionFlag"						Type="3"	StringEnumValues="YesNoLetter"
+	Name="LowRRValue"								Type="3"
+	Name="HighRRValue"								Type="3"
+	Name="HeartRate"								Type="3"
+	Name="IVUSAcquisition"							Type="1C"	Condition="ModalityIsIVUS"	StringDefinedTerms="IVUSAcquisition"
+	Name="IVUSPullbackRate"							Type="1C"	Condition="IVUSAcquisitionIsMotor"
+	Name="IVUSGatedRate"							Type="1C"	Condition="IVUSAcquisitionIsGated"
+	Name="IVUSPullbackStartFrameNumber"				Type="1C"	Condition="IVUSAcquisitionIsMotorOrGated"	NotZeroError=""
+	Name="IVUSPullbackStopFrameNumber"				Type="1C"	Condition="IVUSAcquisitionIsMotorOrGated"	NotZeroError=""
+	Name="LesionNumber"								Type="3"
+	Name="OutputPower"								Type="3"
+	Name="TransducerData"							Type="3"
+	Name="TransducerType"							Type="3"	StringDefinedTerms="USTransducerType"
+	Name="FocusDepth"								Type="3"
+	Name="ProcessingFunction"						Type="3"
+	Name="MechanicalIndex"							Type="3"
+	Name="BoneThermalIndex"							Type="3"
+	Name="CranialThermalIndex"						Type="3"
+	Name="SoftTissueThermalIndex"					Type="3"
+	Name="SoftTissueFocusThermalIndex"				Type="3"
+	Name="SoftTissueSurfaceThermalIndex"			Type="3"
+	Name="DepthOfScanField"							Type="3"
+	Name="OverlaySubtype"							Type="3"	StringDefinedTerms="OverlaySubtypeUS"
+ModuleEnd
+
+Module="SCEquipment"
+	Name="ConversionType"								Type="1"	StringDefinedTerms="ConversionType"
+	Name="Modality"										Type="3"	StringDefinedTerms="Modality"
+	Name="SecondaryCaptureDeviceID"						Type="3"
+	Name="SecondaryCaptureDeviceManufacturer"			Type="3"
+	Name="SecondaryCaptureDeviceManufacturerModelName"	Type="3"
+	Name="SecondaryCaptureDeviceSoftwareVersions"		Type="3"
+	Name="VideoImageFormatAcquired"						Type="3"
+	Name="DigitalImageFormatAcquired"					Type="3"
+ModuleEnd
+
+Module="SCImage"
+	Name="DateOfSecondaryCapture"						Type="3"
+	Name="TimeOfSecondaryCapture"						Type="3"
+	Name="NominalScannedPixelSpacing"					Type="3"	NotZeroError=""
+	InvokeMacro="BasicPixelSpacingCalibrationMacro"
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+ModuleEnd
+
+Module="SCMultiFrameImage"
+	Name="BurnedInAnnotation"							Type="1"	StringEnumValues="YesNoFull"
+	Name="RecognizableVisualFeatures"					Type="3"	StringEnumValues="YesNoFull"
+	Name="PresentationLUTShape"							Type="1C"	StringEnumValues="SecondaryCapturePresentationLUTShape"	Condition="MonochromeNotBitmapPhotometricInterpretation"
+	Name="Illumination"									Type="3"
+	Name="ReflectedAmbientLight"						Type="3"
+	Name="RescaleIntercept"								Type="1C"	Condition="MonochromeNotBitmapPhotometricInterpretation"
+	Name="RescaleSlope"									Type="1C"	Condition="MonochromeNotBitmapPhotometricInterpretation"
+	Name="RescaleType"									Type="1C"	StringDefinedTerms="RescaleTypeUnspecified"	Condition="MonochromeNotBitmapPhotometricInterpretation"
+	Name="FrameIncrementPointer"						Type="1C"	Condition="NumberOfFramesGreaterThanOne"
+	Name="NominalScannedPixelSpacing"					Type="1C"	Condition="ConversionTypeDigitizedFilm"	mbpo="true" NotZeroError=""
+	Verify="NominalScannedPixelSpacing"								Condition="NominalScannedPixelSpacingPresentAndConversionTypeNotDigitizedFilmScannedDocumentScannedImage" ThenErrorMessage="May not be present unless ConversionType is DF, SD or SI"
+	InvokeMacro="BasicPixelSpacingCalibrationMacro"
+	Name="DigitizingDeviceTransportDirection"			Type="3"	StringEnumValues="TransportDirection"
+	Name="RotationOfScannedFilm"						Type="3"
+ModuleEnd
+
+Module="SCMultiFrameVector"
+	Name="FrameTimeVector"								Type="1C"	Condition="FrameIncrementPointerContainsFrameTimeVector"
+	Name="PageNumberVector"								Type="1C"	Condition="FrameIncrementPointerContainsPageNumberVector"
+	Name="FrameLabelVector"								Type="1C"	Condition="FrameIncrementPointerContainsFrameLabelVector"
+	Name="FramePrimaryAngleVector"						Type="1C"	Condition="FrameIncrementPointerContainsFramePrimaryAngleVector"
+	Name="FrameSecondaryAngleVector"					Type="1C"	Condition="FrameIncrementPointerContainsFrameSecondaryAngleVector"
+	Name="SliceLocationVector"							Type="1C"	Condition="FrameIncrementPointerContainsSliceLocationVector"
+	Name="DisplayWindowLabelVector"						Type="1C"	Condition="FrameIncrementPointerContainsDisplayWindowLabelVector"
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForMFSC"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequenceAndPlanePositionSequenceOrPlaneOrientationSequencePresent"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlaneOrientationSequencePresent"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlanePositionSequencePresent"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequenceAndPlanePositionSequenceOrPlaneOrientationSequencePresent"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlaneOrientationSequencePresent"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequenceAndPixelMeasuresSequenceOrPlanePositionSequencePresent"
+	SequenceEnd
+ModuleEnd
+
+Module="OverlayIdentification"
+	Name="OverlayNumber"								Type="2"
+	Name="OverlayDate"									Type="3"
+	Name="OverlayTime"									Type="3"
+	Sequence="ReferencedImageSequence"					Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="OverlayPlane"
+	Name="OverlayRows"									Type="1"	NotZeroError=""
+	Name="OverlayColumns"								Type="1"	NotZeroError=""
+	Name="OverlayType"									Type="1"	StringEnumValues="OverlayType"
+	Name="OverlayOrigin"								Type="1"
+	Name="OverlayBitsAllocated"							Type="1"	BinaryEnumValues="One"
+	Name="OverlayBitPosition"							Type="1"	BinaryEnumValues="Zero"
+	Name="OverlayData"									Type="1"
+	Name="OverlayDescription"							Type="3"
+	Name="OverlaySubtype"								Type="3"	StringDefinedTerms="OverlaySubtype"
+	Name="OverlayLabel"									Type="3"
+	Name="ROIArea"										Type="3"
+	Name="ROIMean"										Type="3"
+	Name="ROIStandardDeviation"							Type="3"
+ModuleEnd
+
+Module="MultiFrameOverlay"
+	Name="NumberOfFramesInOverlay"						Type="1"
+	Name="ImageFrameOrigin"								Type="3"
+ModuleEnd
+
+Module="CurveIdentification"
+	Name="CurveNumber"									Type="2"
+	Name="CurveDate"									Type="3"
+	Name="CurveTime"									Type="3"
+	Sequence="ReferencedImageSequence"					Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+	SequenceEnd
+	Sequence="ReferencedOverlaySequence"				Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+	SequenceEnd
+	Sequence="ReferencedCurveSequence"					Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="Curve"
+	Name="CurveDimensions"								Type="1"
+	Name="NumberOfPoints"								Type="1"
+	Name="TypeOfData"									Type="1"	StringDefinedTerms="CurveTypeOfData"
+	Name="DataValueRepresentation"						Type="1"	BinaryEnumValues="CurveDataValueRepresentation"
+	Name="CurveData"									Type="1"
+	Name="CurveDescription"								Type="3"
+	Name="AxisUnits"									Type="3"	StringDefinedTerms="CurveAxisUnits"
+	Name="AxisLabels"									Type="3"
+	Name="MinimumCoordinateValue"						Type="3"
+	Name="MaximumCoordinateValue"						Type="3"
+	Name="CurveRange"									Type="3"
+	Name="CurveDataDescriptor"							Type="1C"	BinaryEnumValues="CurveDataDescriptor"	Condition="Never"
+	Name="CoordinateStartValue"							Type="1C"	Condition="CurveDataDescriptorPresent"
+	Name="CoordinateStepValue"							Type="1C"	Condition="CurveDataDescriptorPresent"
+	Name="CurveLabel"									Type="3"
+	Sequence="ReferencedOverlaySequence"				Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+		Name="CurveReferencedOverlayGroup"				Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="Audio"
+	Name="AudioType"									Type="1"	BinaryEnumValues="AudioType"
+	Name="AudioSampleFormat"							Type="1"	BinaryEnumValues="AudioSampleFormat"
+	Name="NumberOfChannels"								Type="1"	BinaryEnumValues="NumberOfChannels"
+	Name="NumberOfSamples"								Type="1"
+	Name="SampleRate"									Type="1"
+	Name="TotalTime"									Type="1"
+	Name="AudioSampleData"								Type="1"
+	Sequence="ReferencedImageSequence"					Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+	SequenceEnd
+	Name="AudioComments"
+ModuleEnd
+
+DefineMacro="ModalityLUTMacro"	InformationEntity="Frame"
+	Sequence="ModalityLUTSequence"						Type="1C"	VM="1"	Condition="RescaleInterceptNotPresent"
+		Name="LUTDescriptor"							Type="1"
+		Verify="LUTDescriptor"										ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+		Name="LUTExplanation"							Type="3"
+		Name="ModalityLUTType"							Type="1"	StringDefinedTerms="ModalityLUTType"
+		Name="LUTData"									Type="1"
+	SequenceEnd
+	Name="RescaleIntercept"								Type="1C"	Condition="ModalityLUTSequenceNotPresent"
+	Name="RescaleSlope"									Type="1C"	Condition="RescaleInterceptPresent"	NotZeroError=""
+	Name="RescaleType"									Type="1C"	Condition="RescaleInterceptPresent"	StringDefinedTerms="ModalityLUTType"
+	Verify="PhotometricInterpretation"					Condition="PhotometricInterpretationIsGrayscaleOrAbsent"	ElseWarningMessage="Modality LUT Module (Rescale Slope and Intercept) not appropriate for non-grayscale images" ShowValueWithMessage="true"
+MacroEnd
+
+Module="ModalityLUT"
+	InvokeMacro="ModalityLUTMacro"
+ModuleEnd
+
+DefineMacro="VOILUTMacro"	InformationEntity="Frame"
+	Sequence="VOILUTSequence"							Type="1C"	VM="1-n"	Condition="MonochromeAndWindowCenterNotPresent" mbpo="true"
+		Name="LUTDescriptor"							Type="1"
+		Verify="LUTDescriptor"										Condition="VOILUTSequenceLUTDescriptorRequiredToBe8Or16"	ValueSelector="2"	BinaryEnumValues="BitsAre8Or16"
+		Name="LUTExplanation"							Type="3"
+		Name="LUTData"									Type="1"
+	SequenceEnd
+	Name="WindowCenter"									Type="1C"	Condition="MonochromeAndVOILUTSequenceNotPresent" mbpo="true"
+	Name="WindowWidth"									Type="1C"	Condition="WindowCenterPresent"	NotZeroError=""
+	Verify="WindowWidth"											Condition="WindowWidthIsNegative"	ThenErrorMessage="Not permitted to be negative" ShowValueWithMessage="true"
+	Name="WindowCenterWidthExplanation"					Type="3"
+	Name="VOILUTFunction"								Type="3"	StringDefinedTerms="VOILUTFunction"
+	Verify="PhotometricInterpretation"					Condition="PhotometricInterpretationIsGrayscaleOrAbsent"	ElseWarningMessage="VOI LUT Module (Window Center and Width) not appropriate for non-grayscale images" ShowValueWithMessage="true"
+ModuleEnd
+
+Module="VOILUT"
+	InvokeMacro="VOILUTMacro"
+ModuleEnd
+
+Module="LUTIdentification"
+	Name="LUTNumber"									Type="2"
+	Sequence="ReferencedImageSequence"					Type="3"	VM="1-n"
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="DigitalSignaturesMacro"	InformationEntity="Instance"
+	Sequence="MACParametersSequence"					Type="3"	VM="1-n"
+		Name="MACIDNumber"								Type="1"
+		Name="MACCalculationTransferSyntaxUID"			Type="1"
+		Name="MACAlgorithm"								Type="1"	StringDefinedTerms="MACAlgorithm"
+		Name="DataElementsSigned"						Type="1"
+	SequenceEnd
+	Sequence="DigitalSignaturesSequence"				Type="3"	VM="1-n"
+		Name="MACIDNumber"								Type="1"
+		Name="DigitalSignatureUID"						Type="1"
+		Name="DigitalSignatureDateTime"					Type="1"
+		Name="CertificateType"							Type="1"	StringDefinedTerms="CertificateType"
+		Name="CertificateOfSigner"						Type="1"
+		Name="Signature"								Type="1"
+		Name="CertifiedTimestampType"					Type="1C"	Condition="CertifiedTimestampIsPresent"	StringDefinedTerms="CertifiedTimestampType"
+		Name="CertifiedTimestamp"						Type="3"
+		Sequence="DigitalSignaturePurposeCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="7007"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+Module="SOPCommon"
+	Name="SOPClassUID"									Type="1"
+	Name="SOPInstanceUID"								Type="1"
+	Name="SpecificCharacterSet"							Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+	Name="InstanceCreationDate"							Type="3"
+	Name="InstanceCreationTime"							Type="3"
+	Name="InstanceCoercionDateTime"						Type="3"
+	Name="InstanceCreatorUID"							Type="3"
+	Name="RelatedGeneralSOPClassUID"					Type="3"
+	Name="OriginalSpecializedSOPClassUID"				Type="3"
+	Sequence="CodingSchemeIdentificationSequence"		Type="3"	VM="1-n"
+		Name="CodingSchemeDesignator"					Type="1"	StringDefinedTerms="MiscellaneousCodingSchemeDesignators"
+		Name="CodingSchemeRegistry"						Type="1C"	NoCondition=""	StringDefinedTerms="CodingSchemeRegistries"
+		Name="CodingSchemeUID"							Type="1C"	NoCondition=""	StringDefinedTerms="MiscellaneousCodingSchemeUIDs"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsACR"				StringEnumValues="CodingSchemeUIDForACR"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsASTMSigpurpose"	StringEnumValues="CodingSchemeUIDForASTMSigpurpose"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsC4"				StringEnumValues="CodingSchemeUIDForC4"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsC5"				StringEnumValues="CodingSchemeUIDForC5"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsCD2"				StringEnumValues="CodingSchemeUIDForCD2"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsCTV3"			StringEnumValues="CodingSchemeUIDForCTV3"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsDCM"				StringEnumValues="CodingSchemeUIDForDCM"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsDCMUID"			StringEnumValues="CodingSchemeUIDForDCMUID"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsHPC"				StringEnumValues="CodingSchemeUIDForHPC"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsI10"				StringEnumValues="CodingSchemeUIDForI10"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsI10P"			StringEnumValues="CodingSchemeUIDForI10P"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsI9"				StringEnumValues="CodingSchemeUIDForI9"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsI9C"				StringEnumValues="CodingSchemeUIDForI9C"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsISO3166_1"		StringEnumValues="CodingSchemeUIDForISO3166_1"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsISO639_1"		StringEnumValues="CodingSchemeUIDForISO639_1"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsISO639_2"		StringEnumValues="CodingSchemeUIDForISO639_2"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsLN"				StringEnumValues="CodingSchemeUIDForLN"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsPOS"				StringEnumValues="CodingSchemeUIDForPOS"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsRFC3066"			StringEnumValues="CodingSchemeUIDForRFC3066"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsSNM3"			StringEnumValues="CodingSchemeUIDForSNM3"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsSCT"				StringEnumValues="CodingSchemeUIDForSCT"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsSRT"				StringEnumValues="CodingSchemeUIDForSRT"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsUCUM"			StringEnumValues="CodingSchemeUIDForUCUM"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsUMLS"			StringEnumValues="CodingSchemeUIDForUMLS"
+		Verify="CodingSchemeUID"						Condition="CodingSchemeDesignatorIsUPC"				StringEnumValues="CodingSchemeUIDForUPC"
+		Name="CodingSchemeExternalID"					Type="2C"	NoCondition=""
+		Name="CodingSchemeName"							Type="3"
+		Name="CodingSchemeVersion"						Type="3"
+		Name="CodingSchemeResponsibleOrganization"		Type="3"
+	SequenceEnd
+	Name="TimezoneOffsetFromUTC"						Type="3"
+	Sequence="ContributingEquipmentSequence"			Type="3"	VM="1-n"
+		Sequence="PurposeOfReferenceCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							DefinedContextID="7005"
+		SequenceEnd
+		Name="Manufacturer"								Type="1"
+		Name="InstitutionName"							Type="3"
+		Name="InstitutionAddress"						Type="3"
+		Name="StationName"								Type="3"
+		Name="InstitutionalDepartmentName"				Type="3"
+		Name="OperatorsName"							Type="3"
+		Sequence="OperatorIdentificationSequence"		Type="3"	VM="1-n"
+			InvokeMacro="PersonIdentificationMacro"
+		SequenceEnd
+		Name="ManufacturerModelName"					Type="3"
+		Name="DeviceSerialNumber"						Type="3"
+		Name="SoftwareVersions"							Type="3"
+		Name="SpatialResolution"						Type="3"
+		Name="DateOfLastCalibration"					Type="3"
+		Name="TimeOfLastCalibration"					Type="3"
+		Name="ContributionDateTime"						Type="3"
+		Name="ContributionDescription"					Type="3"
+	SequenceEnd
+	Name="InstanceNumber"								Type="3"
+	Name="SOPInstanceStatus"							Type="3"
+	Name="SOPAuthorizationDateTime"						Type="3"
+	Name="SOPAuthorizationComment"						Type="3"
+	Name="AuthorizationEquipmentCertificationNumber"	Type="3"
+	InvokeMacro="DigitalSignaturesMacro"
+	Sequence="EncryptedAttributesSequence"				Type="1C"	VM="1-n"	NoCondition=""
+		Name="EncryptedContentTransferSyntaxUID"		Type="1"
+		Name="EncryptedContent"							Type="1"
+	SequenceEnd
+	Sequence="OriginalAttributesSequence"				Type="3"	VM="1-n"
+		Name="SourceOfPreviousValues"					Type="2"
+		Name="AttributeModificationDateTime"			Type="1"
+		Name="ModifyingSystem"							Type="1"
+		Name="ReasonForTheAttributeModification"		Type="1"
+		Sequence="ModifiedAttributesSequence"			Type="1"	VM="1"
+		SequenceEnd
+	SequenceEnd
+	Sequence="HL7StructuredDocumentReferenceSequence"	Type="1C"	VM="1-n"	NoCondition=""
+		Name="ReferencedSOPClassUID"					Type="1"
+		Name="ReferencedSOPInstanceUID"					Type="1"
+		Name="HL7InstanceIdentifier"					Type="1"
+		Name="RetrieveURI"								Type="1"
+	SequenceEnd
+	Name="LongitudinalTemporalInformationModified"		Type="3"	StringEnumValues="LongitudinalTemporalInformationModified"
+	Name="QueryRetrieveView"							Type="1C"	NoCondition=""	StringEnumValues="QueryRetrieveView"
+	Sequence="ConversionSourceAttributesSequence"		Type="1C"	VM="1-n"	NoCondition=""
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="ContentQualification"							Type="3"	StringEnumValues="ContentQualification"
+ModuleEnd
+
+Module="FrameExtraction"
+	Sequence="FrameExtractionSequence"					Type="1"	VM="1-n"
+		Name="MultiFrameSourceSOPInstanceUID"			Type="1"
+		Name="SimpleFrameList"							Type="1C"	Condition="NeedSimpleFrameListInFrameExtractionModule"
+		Name="CalculatedFrameList"						Type="1C"	Condition="NeedCalculatedFrameListInFrameExtractionModule"
+		Name="TimeRange"								Type="1C"	Condition="NeedTimeRangeInFrameExtractionModule"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiframeSingleBitSCImagePseudo"
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"	Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="One"
+	Name="BitsStored"					Type="1"	BinaryEnumValues="One"
+	Name="HighBit"						Type="1"	BinaryEnumValues="Zero"
+	Name="PixelRepresentation"			Type="1"	BinaryEnumValues="Zero"
+	Name="PlanarConfiguration"			Type="1C"	BinaryEnumValues="PlanarConfiguration"	Condition="Never"
+ModuleEnd
+
+Module="MultiframeGrayscaleByteSCImagePseudo"
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"	Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="BitsAre8"
+	Name="BitsStored"					Type="1"	BinaryEnumValues="BitsAre8"
+	Name="HighBit"						Type="1"	BinaryEnumValues="BitsAre7"
+	Name="PixelRepresentation"			Type="1"	BinaryEnumValues="Zero"
+	Name="PlanarConfiguration"			Type="1C"	BinaryEnumValues="PlanarConfiguration"	Condition="Never"
+ 	Name="RescaleIntercept"				Type="1"	BinaryEnumValues="Zero"
+ 	Name="RescaleSlope"					Type="1"	BinaryEnumValues="One"
+ 	Name="RescaleType"					Type="1"	StringEnumValues="RescaleTypeUnspecified"
+ModuleEnd
+
+Module="MultiframeGrayscaleWordSCImagePseudo"
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"	Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"					Type="1"	BinaryEnumValues="BitsAre9To16"
+	Name="HighBit"						Type="1"	BinaryEnumValues="BitsAre8To15"	# :( should be one less than bits stored
+	Name="PixelRepresentation"			Type="1"	BinaryEnumValues="Zero"
+	Name="PlanarConfiguration"			Type="1C"	BinaryEnumValues="PlanarConfiguration"	Condition="Never"
+ModuleEnd
+
+Module="MultiframeTrueColorSCImagePseudo"
+
+	Name="SamplesPerPixel"				Type="1"	BinaryEnumValues="Three"
+	Name="PhotometricInterpretation"	Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2OrRGBorYBR_FULL_422orYBR_RCTorYBR_ICTorYBR_PARTIAL_420"
+	Verify="PhotometricInterpretation"				Condition="JPEGTransferSyntaxButNotYBR_FULL_422"			ThenErrorMessage="JPEG transfer syntax is required to have Photometric Interpretation of YBR_FULL422" ShowValueWithMessage="true"
+	Verify="PhotometricInterpretation"				Condition="JPEG2000LosslessTransferSyntaxButNotYBR_RCT"		ThenErrorMessage="JPEG 2000 reversible transfer syntax is required to have Photometric Interpretation of YBR_RCT" ShowValueWithMessage="true"
+	Verify="PhotometricInterpretation"				Condition="JPEG2000TransferSyntaxButNotYBR_RCTorYBR_ICT"	ThenErrorMessage="JPEG 2000 transfer syntax is required to have Photometric Interpretation of YBR_RCT or YBR_ICT" ShowValueWithMessage="true"
+	# MPEG2TransferSyntaxButNotYBR_PARTIAL_420 is generic too ImagePixelMacro and not repeated here (PS 3.5 requirement)
+	Name="BitsAllocated"				Type="1"	BinaryEnumValues="BitsAre8"
+	Name="BitsStored"					Type="1"	BinaryEnumValues="BitsAre8"
+	Name="HighBit"						Type="1"	BinaryEnumValues="BitsAre7"
+	Name="PixelRepresentation"			Type="1"	BinaryEnumValues="Zero"
+	Name="PlanarConfiguration"			Type="1"	BinaryEnumValues="Zero"		# only needs to be 0 for RGB
+
+ModuleEnd
+
+Module="CommonInstanceReference"
+	# do not use SeriesAndInstanceReferenceMacro, but conditional inclusion instead, per CP 926
+	# cannot actually check whether instances that are referenced are in this study or another study
+	# may be present otherwise because cannot check whether or not both sequences are needed
+	Sequence="ReferencedSeriesSequence"								Type="1C"	VM="1-n"	Condition="InstancesAreReferencedAndStudiesContainingOtherReferencedInstancesSequenceAbsent" mbpo="true"
+		Name="SeriesInstanceUID"									Type="1"
+		Verify="StudyInstanceUID"															Condition="StudyInstanceUIDIsPresent"	ThenErrorMessage="StudyInstanceUID should not be present in ReferencedSeriesSequence in CommonInstanceReference Module - use StudiesContainingOtherReferencedInstancesSequence if not the same Study"
+		Sequence="ReferencedInstanceSequence"						Type="1"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="StudiesContainingOtherReferencedInstancesSequence"	Type="1C"	VM="1-n"	Condition="InstancesAreReferencedAndReferencedSeriesSequenceAbsent" mbpo="true"
+		Name="StudyInstanceUID"										Type="1"
+		InvokeMacro="SeriesAndInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="SegmentationSeries"
+	Name="Modality"												Type="1"	StringEnumValues="SEGModality"
+	Name="SeriesNumber"											Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"			Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="SegmentationImage"
+	Name="ImageType"										Type="1"	VM="2"
+	Verify="ImageType"													ValueSelector="0"	StringEnumValues="ImageType1DerivedOnly"
+	Verify="ImageType"													ValueSelector="1"	StringEnumValues="ImageType2PrimaryOnly"
+	InvokeMacro="ContentIdentificationMacro"
+	Name="SamplesPerPixel"									Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"						Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="PixelRepresentation"								Type="1"	BinaryEnumValues="Zero"
+	Name="BitsAllocated"									Type="1"
+	Verify="BitsAllocated"												Condition="SegmentationTypeIsBinary"	BinaryEnumValues="One"
+	Verify="BitsAllocated"												Condition="SegmentationTypeIsNotBinary"	BinaryEnumValues="BitsAre8"
+	Name="BitsStored"										Type="1"
+	Verify="BitsStored"													Condition="SegmentationTypeIsBinary"	BinaryEnumValues="One"
+	Verify="BitsStored"													Condition="SegmentationTypeIsNotBinary"	BinaryEnumValues="BitsAre8"
+	Name="HighBit"											Type="1"
+	Verify="HighBit"													Condition="SegmentationTypeIsBinary"	BinaryEnumValues="Zero"
+	Verify="HighBit"													Condition="SegmentationTypeIsNotBinary"	BinaryEnumValues="BitsAre7"
+	Name="PlanarConfiguration"								Type="1C"	BinaryEnumValues="PlanarConfiguration"	Condition="Never"
+	Name="LossyImageCompression"							Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="1C"	NoCondition=""
+	Name="LossyImageCompressionMethod"						Type="1C"	NoCondition=""
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="SegmentationType"									Type="1"	StringEnumValues="SegmentationType"
+	Name="SegmentationFractionalType"						Type="1C"	Condition="SegmentationTypeIsFractional"	StringEnumValues="SegmentationFractionalType"
+	Name="MaximumFractionalValue"							Type="1C"	Condition="SegmentationTypeIsFractional"
+	# should verify than 0 < MaximumFractionalValue < 256 :(
+	Sequence="SegmentSequence"								Type="1"	VM="1-n"
+		InvokeMacro="SegmentDescriptionMacro"
+		Name="SegmentAlgorithmName"							Type="1C"	Condition="SegmentAlgorithmTypeIsNotManual"
+		Sequence="SegmentSurfaceGenerationAlgorithmIdentificationSequence"	Type="3"	VM="1"
+			InvokeMacro="AlgorithmIdentificationMacro"									BaselineContextID="7162"
+		SequenceEnd
+		Name="RecommendedDisplayGrayscaleValue"				Type="3"
+		Name="RecommendedDisplayCIELabValue"				Type="3"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="SegmentDescriptionMacro" InformationEntity="Instance"
+	Name="SegmentNumber"										Type="1"	NotZeroError=""
+	Name="SegmentLabel"											Type="1"
+	Name="SegmentDescription"									Type="3"
+	Name="SegmentAlgorithmType"									Type="1"	StringEnumValues="SegmentAlgorithmType"
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	Sequence="SegmentedPropertyCategoryCodeSequence"			Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"										BaselineContextID="7150"
+	SequenceEnd
+	Sequence="SegmentedPropertyTypeCodeSequence"				Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"										BaselineContextID="7151"
+		Sequence="SegmentedPropertyTypeModifierCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"									BaselineContextID="244"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="SegmentationMacro" InformationEntity="FunctionalGroup"
+	Sequence="SegmentIdentificationSequence"				Type="1"	VM="1"
+		Name="ReferencedSegmentNumber"						Type="1"	VM="1"
+	SequenceEnd
+MacroEnd
+
+Module="SurfaceSegmentation"
+	InvokeMacro="ContentIdentificationMacro"
+	Name="ContentDate"															Type="1"
+	Name="ContentTime"															Type="1"
+	Sequence="SegmentSequence"													Type="1"	VM="1-n"
+		InvokeMacro="SegmentDescriptionMacro"
+		Name="SurfaceCount"														Type="1"	NotZeroError="" 
+		Sequence="ReferencedSurfaceSequence"									Type="1"	VM="1-n"				# should check that number of items equals SurfaceCount :(
+			Name="ReferencedSurfaceNumber"										Type="1"	VM="1" 	NotZeroError=""	# should check that SurfaceNumber exists in SurfaceSequence :(
+			Sequence="SegmentSurfaceGenerationAlgorithmIdentificationSequence"	Type="1"	VM="1"
+				InvokeMacro="AlgorithmIdentificationMacro"									BaselineContextID="7162"
+			SequenceEnd
+			Sequence="SegmentSurfaceSourceInstanceSequence"						Type="2"	VM="0-n"
+				InvokeMacro="ImageSOPInstanceReferenceMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="PointsMacro" InformationEntity="Surface"
+	Name="NumberOfSurfacePoints"												Type="1"	NotZeroError=""
+	Name="PointCoordinatesData"													Type="1"
+	Name="PointPositionAccuracy"												Type="3"
+	Name="MeanPointDistance"													Type="3"
+	Name="MaximumPointDistance"													Type="3"
+	Name="PointsBoundingBoxCoordinates"											Type="3"
+	Name="AxisOfRotation"														Type="3"
+	Name="CenterOfRotation"														Type="1C"	Condition="AxisOfRotationIsPresent" mbpo="true"
+MacroEnd
+
+DefineMacro="VectorsMacro" InformationEntity="Surface"
+	Name="NumberOfVectors"														Type="1"	NotZeroError=""
+	Name="VectorDimensionality"													Type="1"	NotZeroError=""
+	Name="VectorAccuracy"														Type="3"
+	Name="VectorCoordinateData"													Type="1"
+MacroEnd
+
+DefineMacro="SurfaceMeshPrimitivesMacro" InformationEntity="Surface"
+	Name="VertexPointIndexList"													Type="2"
+	Name="EdgePointIndexList"													Type="2"						# should check OW has 2n values :(
+	Name="TrianglePointIndexList"												Type="2"						# should check OW has 3n values :(
+	Sequence="TriangleStripSequence"											Type="2"	VM="0-n"
+		Name="PrimitivePointIndexList"											Type="1"
+	SequenceEnd
+	Sequence="TriangleFanSequence"												Type="2"	VM="0-n"
+		Name="PrimitivePointIndexList"											Type="1"
+	SequenceEnd
+	Sequence="LineSequence"														Type="2"	VM="0-n"
+		Name="PrimitivePointIndexList"											Type="1"
+	SequenceEnd
+	Sequence="FacetSequence"													Type="2"	VM="0-n"
+		Name="PrimitivePointIndexList"											Type="1"
+	SequenceEnd
+MacroEnd
+
+Module="SurfaceMesh"
+	Name="NumberOfSurfaces"														Type="1"	NotZeroError=""
+	Sequence="SurfaceSequence"													Type="1"	VM="1-n"				# should check that number of items equals NumberOfSurfaces :(
+		Name="SurfaceNumber"													Type="1"	NotZeroError=""			# should check that starts at a value of 1, and increases monotonically by 1 :(
+		Name="SurfaceComments"													Type="3"
+		Name="SurfaceProcessing"												Type="2"	StringEnumValues="YesNoFull"
+		Name="SurfaceProcessingRatio"											Type="2C"	Condition="SurfaceProcessingIsYes"
+		Name="SurfaceProcessingDescription"										Type="3"
+		Sequence="SurfaceProcessingAlgorithmIdentificationSequence"				Type="2C"	VM="0-n"	Condition="SurfaceProcessingIsYes"
+			InvokeMacro="AlgorithmIdentificationMacro"										BaselineContextID="7162"
+		SequenceEnd
+		Name="RecommendedDisplayGrayscaleValue"									Type="1"
+		Name="RecommendedDisplayCIELabValue"									Type="1"
+		Name="RecommendedPresentationOpacity"									Type="1"
+		Name="RecommendedPresentationType"										Type="1"	StringDefinedTerms="RecommendedPresentationType"
+		Name="RecommendedPointRadius"											Type="3"
+		Name="RecommendedLineThickness"											Type="3"
+		Name="FiniteVolume"														Type="1"	StringEnumValues="YesNoFullUnknown"
+		Name="Manifold"															Type="1"	StringEnumValues="YesNoFullUnknown"
+		Sequence="SurfacePointsSequence"										Type="1"	VM="1"
+			InvokeMacro="PointsMacro"
+		SequenceEnd
+		Sequence="SurfacePointsNormalsSequence"									Type="2"	VM="0-1"
+			InvokeMacro="VectorsMacro"																				# should check that NumberOfVectors equals NumberOfSurfacePoints in SurfacePointsSequence, and VectorDimensionality equals 3 :(
+		SequenceEnd
+		Sequence="SurfaceMeshPrimitivesSequence"								Type="1"	VM="1"
+			InvokeMacro="SurfaceMeshPrimitivesMacro"																# should check that indices do not exceed NumberOfSurfacePoints in SurfacePointsSequence :(
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForSegmentation"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageSequenceNotInPerFrameFunctionalGroupSequenceAndPixelMeasuresPlanePositionPlaneOrientationNotPresentInEitherMBPO"
+		InvokeMacro="SegmentationMacro"			Condition="SegmentIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequenceAndDerivationImageMacroNotPresentInEitherMBPO"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageSequenceNotInSharedFunctionalGroupSequenceAndPixelMeasuresPlanePositionPlaneOrientationNotPresentInEitherMBPO"
+		InvokeMacro="SegmentationMacro"			Condition="SegmentIdentificationSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="SpatialRegistrationSeries"
+	Name="Modality"												Type="1"	StringEnumValues="REGModality"
+ModuleEnd
+
+Module="SpatialRegistration"
+	Name="ContentDate"											Type="1"
+	Name="ContentTime"											Type="1"
+	InvokeMacro="ContentIdentificationMacro"
+	Sequence="RegistrationSequence"								Type="1"	VM="1-n"
+		Name="FrameOfReferenceUID"								Type="1C"	Condition="ReferencedImageSequenceNotPresent" mbpo="true"
+		Sequence="ReferencedImageSequence"						Type="1C"	VM="1-n"	Condition="FrameOfReferenceUIDNotPresent" mbpo="true"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="MatrixRegistrationSequence"					Type="1"	VM="1"
+			Name="FrameOfReferenceTransformationComment"		Type="3"
+			Sequence="RegistrationTypeCodeSequence"				Type="2"	VM="0-1"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+			Sequence="MatrixSequence"							Type="1"	VM="1-n"
+				Name="FrameOfReferenceTransformationMatrix"		Type="1"
+				Name="FrameOfReferenceTransformationMatrixType"	Type="1"	StringEnumValues="FrameOfReferenceTransformationMatrixType"
+			SequenceEnd
+		SequenceEnd
+		Sequence="UsedFiducialsSequence"						Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Name="FiducialUID"									Type="1"
+		SequenceEnd
+		Sequence="UsedSegmentsSequence"							Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Name="ReferencedSegmentNumber"						Type="1"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="DeformableSpatialRegistration"
+	Name="ContentDate"											Type="1"
+	Name="ContentTime"											Type="1"
+	InvokeMacro="ContentIdentificationMacro"
+	Sequence="DeformableRegistrationSequence"					Type="1"	VM="1-n"
+		Name="SourceFrameOfReferenceUID"						Type="1"
+		Sequence="ReferencedImageSequence"						Type="1C"	VM="1-n"	NoCondition=""
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="FrameOfReferenceTransformationComment"			Type="3"
+		Sequence="RegistrationTypeCodeSequence"					Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="PreDeformationMatrixRegistrationSequence"		Type="1C"	VM="1"	NoCondition=""
+			Name="FrameOfReferenceTransformationMatrix"			Type="1"
+			Name="FrameOfReferenceTransformationMatrixType"		Type="1"	StringEnumValues="FrameOfReferenceTransformationMatrixType"
+		SequenceEnd
+		Sequence="PostDeformationMatrixRegistrationSequence"	Type="1C"	VM="1"	NoCondition=""
+			Name="FrameOfReferenceTransformationMatrix"			Type="1"
+			Name="FrameOfReferenceTransformationMatrixType"		Type="1"	StringDefinedTerms="FrameOfReferenceTransformationMatrixType"
+		SequenceEnd
+		Sequence="DeformableRegistrationGridSequence"			Type="1C"	VM="1"	NoCondition=""
+			Name="ImageOrientationPatient"						Type="1"
+			Name="ImagePositionPatient"							Type="1"
+			Name="GridDimensions"								Type="1"
+			Name="GridResolution"								Type="1"
+			Name="VectorGridData"								Type="1"
+		SequenceEnd
+		Sequence="UsedFiducialsSequence"						Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Name="FiducialUID"									Type="1"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="SpatialFiducialsSeries"
+	Name="Modality"												Type="1"	StringEnumValues="FIDModality"
+ModuleEnd
+
+Module="SpatialFiducials"
+	Name="ContentDate"											Type="1"
+	Name="ContentTime"											Type="1"
+	InvokeMacro="ContentIdentificationMacro"
+	Sequence="FiducialSetSequence"								Type="1"	VM="1-n"
+		Name="FrameOfReferenceUID"								Type="1C"	Condition="ReferencedImageSequenceNotPresent"
+		Sequence="ReferencedImageSequence"						Type="1C"	VM="1-n"	Condition="FrameOfReferenceUIDNotPresent"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="FiducialSequence"								Type="1"	VM="1-n"
+			Name="FiducialIdentifier"							Type="1"
+			Sequence="FiducialIdentifierCodeSequence"			Type="1C"	VM="1"	Condition="FiducialIdentifierNotPresent"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+			Name="FiducialUID"									Type="3"
+			Name="FiducialDescription"							Type="3"
+			Name="ShapeType"									Type="1"	StringDefinedTerms="FiducialShapeType"
+			Name="NumberOfContourPoints"						Type="1C"	Condition="ContourDataIsPresent"	NotZeroError=""
+			Name="ContourData"									Type="1C"	Condition="FrameOfReferenceUIDIsPresentInParent"
+			Name="ContourUncertaintyRadius"						Type="3"
+			Sequence="GraphicCoordinatesDataSequence"			Type="1C"	VM="1-n"	Condition="ContourDataNotPresent"
+				Name="GraphicData"								Type="1"
+				Sequence="ReferencedImageSequence"				Type="1"	VM="1"
+					InvokeMacro="ImageSOPInstanceReferenceMacro"
+				SequenceEnd
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="EncapsulatedDocumentSeries"
+	Name="Modality"												Type="1"	StringDefinedTerms="Modality"
+	Name="SeriesInstanceUID"									Type="1"
+	Name="SeriesNumber"											Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"			Type="3"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="ProtocolName"											Type="3"
+	Name="SeriesDescription"									Type="3"
+	Sequence="SeriesDescriptionCodeSequence"					Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="RequestAttributesSequence"						Type="3"	VM="1-n"
+		InvokeMacro="RequestAttributesMacro"
+	SequenceEnd
+	InvokeMacro="PerformedProcedureStepSummaryMacro"
+ModuleEnd
+
+Module="EncapsulatedDocument"
+	Name="InstanceNumber"										Type="1"
+	Name="ContentDate"											Type="2"
+	Name="ContentTime"											Type="2"
+	Name="AcquisitionDateTime"									Type="2"
+	Name="BurnedInAnnotation"									Type="1"	StringEnumValues="YesNoFull"
+	Name="RecognizableVisualFeatures"							Type="3"	StringEnumValues="YesNoFull"
+	Sequence="SourceInstanceSequence"							Type="1C"	VM="1-n"	NoCondition=""
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="DocumentTitle"										Type="2"
+	Sequence="ConceptNameCodeSequence"							Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"										BaselineContextID="7020"
+	SequenceEnd
+	Name="VerificationFlag"										Type="3"	StringEnumValues="VerificationFlag"
+	Name="HL7InstanceIdentifier"								Type="1C"	Condition="EncapsulatedCDAInstance"
+	Name="MIMETypeOfEncapsulatedDocument"						Type="1"
+	Name="ListOfMIMETypes"										Type="1C"	NoCondition=""
+	Name="EncapsulatedDocument"									Type="1"
+ModuleEnd
+
+Module="EncapsulatedDocumentPDFPseudo"
+	Name="MIMETypeOfEncapsulatedDocument"						Type="1"	StringEnumValues="MIMETypeApplicationPDF"
+ModuleEnd
+
+Module="EncapsulatedDocumentCDAPseudo"
+	Name="MIMETypeOfEncapsulatedDocument"						Type="1"	StringEnumValues="MIMETypeApplicationCDA"
+ModuleEnd
+
+Module="CheckSingleFramePseudo"
+	Name="NumberOfFrames"										Type="3"	DoNotSetUsed="" BinaryEnumValues="One"
+ModuleEnd
+
+Module="RealWorldValueMappingSeries"
+	Name="Modality"												Type="1"	StringDefinedTerms="RealWorldValueMappingModality"
+ModuleEnd
+
+Module="RealWorldValueMapping"
+	Name="ContentDate"											Type="1"
+	Name="ContentTime"											Type="1"
+	InvokeMacro="ContentIdentificationMacro"
+	Sequence="ReferencedImageRealWorldValueMappingSequence"		Type="1"	VM="1-n"
+		InvokeMacro="RealWorldValueMappingMacro"
+		Sequence="ReferencedImageSequence"						Type="1"	VM="1-n"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+
+Module="IntravascularOCTSeries"
+	Name="Modality"											Type="1"	StringEnumValues="IVOCTModality"
+	Name="SeriesNumber"										Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"		Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="PresentationIntentType"							Type="1"	StringEnumValues="PresentationIntentType"
+	Verify="PresentationIntentType"										Condition="IsForProcessingSOPClass"		StringEnumValues="ForProcessing"
+	Verify="PresentationIntentType"										Condition="IsForPresentationSOPClass"	StringEnumValues="ForPresentation"
+ModuleEnd
+
+Module="IntravascularOCTImage"
+	Name="ImageType"								Type="1"	VM="4"
+	Verify="ImageType"											ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"											ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"											ValueSelector="2"	StringDefinedTerms="IVOCTImageAndFrameTypeValue3"
+	Verify="ImageType"											ValueSelector="3"	StringDefinedTerms="CommonEnhancedImageType4"
+
+	Name="VolumetricProperties"						Type="1"	StringEnumValues="IVOCTVolumetricProperties"
+	Name="PixelPresentation"						Type="1"	StringEnumValues="IVOCTPixelPresentationImageLevel"
+	Name="SamplesPerPixel"							Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="AcquisitionDateTime"						Type="1"
+	Name="AcquisitionDuration"						Type="1C"	Condition="ImageTypeValue1Original"
+	Name="AcquisitionNumber"						Type="1"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="PixelRepresentation"						Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="BitsAllocated"							Type="1"	BinaryEnumValues="BitsAre8Or12Or16"
+	Name="BitsStored"								Type="1"	BinaryEnumValues="BitsAre8Or12Or16"
+	Name="HighBit"									Type="1"	BinaryEnumValues="BitsAre7Or11Or15"
+	Name="PresentationLUTShape"						Type="1C"	Condition="PresentationIntentTypeIsForPresentation"	StringEnumValues="IdentityPresentationLUTShape"
+	Name="LossyImageCompression"					Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"				Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"				Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Name="BurnedInAnnotation"						Type="1"	StringEnumValues="NoFull"
+	Name="RecognizableVisualFeatures"				Type="1"	StringEnumValues="NoFull"
+	Sequence="ReferencedInstanceSequence"			Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="ImageComments"							Type="3"
+	Name="RecommendedDisplayFrameRate"				Type="3"
+	Name="InterpolationType"						Type="1C"	Condition="PresentationIntentTypeIsForPresentation"	StringEnumValues="IVOCTInterpolationType"
+	Name="ReferencedColorPaletteInstanceUID"		Type="1C"	Condition="PixelPresentationIsColorRef"				StringDefinedTerms="WellKnownColorPaletteInstanceUIDs"
+ModuleEnd
+
+Module="IntravascularOCTAcquisitionParameters"
+	Name="OCTFocalDistance"						Type="2"
+	Name="BeamSpotSize"							Type="2"
+	Name="EffectiveRefractiveIndex"				Type="2C"		Condition="PresentationIntentTypeIsForProcessing"
+	Name="OCTAcquisitionDomain"					Type="1"		StringDefinedTerms="OCTAcquisitionDomain"
+	Name="OCTOpticalCenterWavelength"			Type="2"
+	Name="AxialResolution"						Type="2"
+	Name="RangingDepth"							Type="1"
+	Name="ALineRate"							Type="1"
+	Name="ALinesPerFrame"						Type="1"
+ModuleEnd
+
+Module="IntravascularImageAcquisitionParameters"
+	Name="IVUSAcquisition"						Type="1"	StringEnumValues="IVOCTIVUSAcquisition"
+	Name="IVUSPullbackRate"						Type="1C"	Condition="IVUSAcquisitionIsMotorized"
+	Name="IVUSPullbackStartFrameNumber"			Type="1C"	Condition="IVUSAcquisitionIsMotorized"
+	Name="IVUSPullbackStopFrameNumber"			Type="1C"	Condition="IVUSAcquisitionIsMotorized"
+	Name="CatheterDirectionOfRotation"			Type="1C"	Condition="RotationalCatheterInformationIsPresent"	StringEnumValues="CatheterDirectionOfRotation"
+	Name="CatheterRotationalRate"				Type="1C"	Condition="RotationalCatheterInformationIsPresent"				
+	Sequence="ModeOfPercutaneousAccessSequence"	Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd				
+ModuleEnd
+
+Module="IntravascularOCTProcessingParameters"
+	Name="OCTZOffsetApplied"					Type="1"	StringEnumValues="YesNoFull"
+	Name="RefractiveIndexApplied"				Type="1"	StringEnumValues="YesNoFull"
+	Name="ALinePixelSpacing"					Type="1"
+	Name="PixelIntensityRelationship"			Type="1"	StringEnumValues="IVOCTPixelIntensityRelationship"
+	Name="FirstALineLocation"					Type="1"
+ModuleEnd
+
+DefineMacro="IntravascularOCTFrameTypeMacro"		InformationEntity="FunctionalGroup"
+	Sequence="IntravascularOCTFrameTypeSequence"	Type="1"	VM="1"
+		Name="FrameType"							Type="1"	VM="4"
+		Verify="FrameType"										ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+		Verify="FrameType"										ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"										VaueSelector="2"	StringDefinedTerms="IVOCTImageAndFrameTypeValue3"
+		Verify="FrameType"										ValueSelector="3"	StringDefinedTerms="CommonEnhancedImageType4"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="IntravascularFrameContentMacro"		InformationEntity="FunctionalGroup"
+	Sequence="IntravascularFrameContentSequence"	Type="1"	VM="1"
+		Name="IntravascularLongitudinalDistance"	Type="1C"	Condition="IVUSAcquisitionIsMeasured"
+		Name="SeamLineLocation"						Type="2C"	Condition="PresentationIntentTypeIsForPresentation"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="IntravascularOCTFrameContentMacro"		InformationEntity="FunctionalGroup"
+	Sequence="IntravascularOCTFrameContentSequence"	Type="1"	VM="1"
+		Name="OCTZOffsetCorrection"					Type="1"
+		Name="SeamLineIndex"						Type="1"
+		Name="NumberOfPaddedALines"					Type="1C"	NoCondition=""
+		Verify="NumberOfPaddedALines"							Condition="PresentationIntentTypeIsForPresentation"	ThenErrorMessage="Only permitted for FOR PROCESSING images"
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForIVOCTImageForPresentation"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"	Condition="NeedPixelIntensityRelationshipLUTMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="IntravascularOCTFrameTypeMacro"		Condition="IntravascularOCTFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IntravascularFrameContentMacro"		Condition="IntravascularFrameContentSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"	Condition="NeedPixelIntensityRelationshipLUTMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IntravascularOCTFrameTypeMacro"		Condition="IntravascularOCTFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="IntravascularFrameContentMacro"		Condition="IntravascularFrameContentSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForIVOCTImageForProcessing"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"	Condition="NeedPixelIntensityRelationshipLUTMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="IntravascularOCTFrameTypeMacro"		Condition="IntravascularOCTFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IntravascularFrameContentMacro"		Condition="IntravascularFrameContentSequenceNotInPerFrameFunctionalGroupSequenceAndAcquisitionIsMeasured"
+		InvokeMacro="IntravascularOCTFrameContentMacro"		Condition="IntravascularOCTFrameContentSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"	Condition="NeedPixelIntensityRelationshipLUTMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IntravascularOCTFrameTypeMacro"		Condition="IntravascularOCTFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="IntravascularFrameContentMacro"		Condition="IntravascularFrameContentSequenceNotInSharedFunctionalGroupSequenceAndAcquisitionIsMeasured"
+		InvokeMacro="IntravascularOCTFrameContentMacro"		Condition="IntravascularOCTFrameContentSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="ParametricMapSeries"
+	Name="Modality"												Type="1"
+	Name="SeriesNumber"											Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"			Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="ParametricMapImage"
+	Name="ImageType"										Type="1"	VM="4"
+	Verify="ImageType"										ValueSelector="0"	StringEnumValues="ParametricMapImageAndFrameType1"
+	Verify="ImageType"										ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"										ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3"
+	Verify="ImageType"										ValueSelector="3"	StringDefinedTerms="CommonEnhancedFrameType4"
+	InvokeMacro="ContentIdentificationMacro"
+	Name="SamplesPerPixel"									Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"						Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"									Type="1"
+	Verify="BitsAllocated"												Condition="PixelDataPresent"			BinaryEnumValues="BitsAre16"
+	Verify="BitsAllocated"												Condition="FloatPixelDataPresent"		BinaryEnumValues="BitsAre32"
+	Verify="BitsAllocated"												Condition="DoubleFloatPixelDataPresent"	BinaryEnumValues="BitsAre64"
+	Name="BitsStored"										Type="1C"	Condition="PixelDataPresent"			BinaryEnumValues="BitsAre16"
+	Name="HighBit"											Type="1C"	Condition="PixelDataPresent"			BinaryEnumValues="BitsAre15"
+	Name="PresentationLUTShape"								Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Name="LossyImageCompression"							Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="1C"	NoCondition=""
+	Name="LossyImageCompressionMethod"						Type="1C"	NoCondition=""
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="BurnedInAnnotation"								Type="1"	StringEnumValues="NoFull"
+	Name="RecognizableVisualFeatures"						Type="1"	StringEnumValues="YesNoFull"
+	Name="ContentQualification"								Type="1"	StringEnumValues="ContentQualification"
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForParametricMap"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IdentityPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTWithLUTMacro"				Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ParametricMapFrameTypeMacro"			Condition="ParametricMapFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="IdentityPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTWithLUTMacro"				Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ParametricMapFrameTypeMacro"			Condition="ParametricMapFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="ParametricMapFrameTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="ParametricMapFrameTypeSequence"	Type="1"	VM="1"
+		Name="FrameType"						Type="1"	VM="4"
+		Verify="FrameType"								ValueSelector="0"	StringEnumValues="ParametricMapImageAndFrameType1"
+		Verify="FrameType"								ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"								ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3"
+		Verify="FrameType"								ValueSelector="3"	StringDefinedTerms="CommonEnhancedFrameType4"
+	SequenceEnd
+MacroEnd
+
+
diff --git a/libsrc/standard/module/ct.tpl b/libsrc/standard/module/ct.tpl
new file mode 100644
index 0000000..e519eda
--- /dev/null
+++ b/libsrc/standard/module/ct.tpl
@@ -0,0 +1,326 @@
+DefineMacro="CTFrameVOILUTMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameVOILUTSequence"				Type="1"	VM="1"
+		Name="WindowCenter"						Type="1" 
+		Name="WindowWidth"						Type="1"	NotZeroError=""
+		Verify="WindowWidth"								Condition="WindowWidthIsNegative"	ThenErrorMessage="Not permitted to be negative" ShowValueWithMessage="true"
+		Name="WindowCenterWidthExplanation"		Type="3"	StringDefinedTerms="EnhancedCTWindowCenterWidthExplanation"
+		Name="VOILUTFunction"					Type="3"	StringDefinedTerms="VOILUTFunction"
+	SequenceEnd
+MacroEnd
+
+Module="CTSeries"
+	Name="Modality"										Type="1"	StringEnumValues="CTModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedCTImage"
+	Name="ImageType"										Type="1"	VM="4"
+	Verify="ImageType"													ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"													ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"													ValueSelector="2"	StringDefinedTerms="EnhancedCTImageAndFrameType3"
+	Verify="ImageType"													ValueSelector="3"	StringDefinedTerms="EnhancedCTImageType4"
+	InvokeMacro="CommonCTMRImageDescriptionImageLevelMacro"
+	Name="AcquisitionNumber"								Type="3"
+	Name="AcquisitionDateTime"								Type="1C"	Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedCT" mbpo="true"
+	Name="AcquisitionDuration"								Type="2C"	Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedCT" mbpo="true"
+	Sequence="ReferencedRawDataSequence"					Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedWaveformSequence"					Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedImageEvidenceSequence"				Type="1C"	VM="1-n"	Condition="ReferencedImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="SourceImageEvidenceSequence"					Type="1C"	VM="1-n"	Condition="SourceImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedPresentationStateSequence"	Type="1C"	VM="1-n"	NoCondition=""	# real world
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="SamplesPerPixel"									Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"						Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"									Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"										Type="1"	BinaryEnumValues="BitsAre12Or16"
+	Name="HighBit"											Type="1"	BinaryEnumValues="BitsAre11Or15"
+	Name="ContentQualification"								Type="1C"	StringEnumValues="ContentQualification"		Condition="NotLegacyConvertedCT" mbpo="true"
+	Name="ImageComments"									Type="3"
+	Name="BurnedInAnnotation"								Type="1C"	StringEnumValues="NoFull"					Condition="NotLegacyConvertedCT" mbpo="true"
+	Name="RecognizableVisualFeatures"						Type="3"	StringEnumValues="YesNoFull"
+	Name="LossyImageCompression"							Type="1C"	StringEnumValues="LossyImageCompression"	Condition="NotLegacyConvertedCT" mbpo="true"
+	Name="LossyImageCompressionRatio"						Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"						Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="PresentationLUTShape"								Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Sequence="IconImageSequence"							Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+ModuleEnd
+
+DefineMacro="CTImageFrameTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTImageFrameTypeSequence"		Type="1"	VM="1"
+		Name="FrameType"					Type="1"	VM="4"
+		Verify="FrameType"								ValueSelector="0"	StringEnumValues="CommonEnhancedFrameType1"
+		Verify="FrameType"								ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"								ValueSelector="2"	StringDefinedTerms="EnhancedCTImageAndFrameType3"
+		Verify="FrameType"								ValueSelector="3"	StringDefinedTerms="EnhancedCTFrameType4"
+		InvokeMacro="CommonCTMRImageDescriptionFrameLevelMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTAcquisitionTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTAcquisitionTypeSequence"			Type="1"	VM="1"
+		Name="AcquisitionType"						Type="1C"	StringDefinedTerms ="CTAcquisitionType"		Condition="Always"	# ORIGINAL mbpo
+		Name="TubeAngle"							Type="1C"	Condition="AcquisitionTypeConstantAngle"				# and ORIGINAL mbpo
+		Name="ConstantVolumeFlag"					Type="1C"	StringDefinedTerms ="YesNoFull"			Condition="Always"	# ORIGINAL mbpo
+		Name="FluoroscopyFlag"						Type="1C"	StringDefinedTerms ="YesNoFull"			Condition="Always"	# ORIGINAL mbpo
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTAcquisitionDetailsMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTAcquisitionDetailsSequence"			Type="1"	VM="1"
+		Name="RotationDirection"					Type="1C"	StringEnumValues="RotationDirection"		Condition="AcquisitionTypeNotConstantAngle"				# and ORIGINAL mbpo
+		Name="RevolutionTime"						Type="1C"	Condition="AcquisitionTypeNotConstantAngle"	NotZeroWarning=""				# and ORIGINAL mbpo
+		Name="SingleCollimationWidth"				Type="1C"	Condition="Always"	NotZeroWarning=""		# ORIGINAL mbpo
+		Name="TotalCollimationWidth"				Type="1C"	Condition="Always"	NotZeroWarning=""		# ORIGINAL mbpo
+		Name="TableHeight"							Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="GantryDetectorTilt"					Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="DataCollectionDiameter"				Type="1C"	Condition="Always"	NotZeroWarning=""		# ORIGINAL mbpo
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTTableDynamicsMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTTableDynamicsSequence"			Type="1"	VM="1"
+		Name="TableSpeed"						Type="1C"	Condition="AcquisitionTypeConstantAngleOrSpiral"	NotZeroWarning=""	# and ORIGINAL mbpo
+		Name="TableFeedPerRotation"				Type="1C"	Condition="AcquisitionTypeSpiral"	NotZeroWarning=""					# and ORIGINAL mbpo
+		Name="SpiralPitchFactor"				Type="1C"	Condition="AcquisitionTypeSpiral"	NotZeroWarning=""					# and ORIGINAL mbpo
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTPositionMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTPositionSequence"					Type="1"	VM="1"
+		Name="TablePosition"						Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="DataCollectionCenterPatient"			Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="ReconstructionTargetCenterPatient"	Type="1C"	Condition="Always"							# ORIGINAL mbpo
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTGeometryMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTGeometrySequence"					Type="1"	VM="1"
+		Name="DistanceSourceToDetector"				Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+		Name="DistanceSourceToDataCollectionCenter"	Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTReconstructionMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTReconstructionSequence"			Type="1"	VM="1"
+		Name="ReconstructionAlgorithm"			Type="1C"	StringDefinedTerms ="CTReconstructionAlgorithm"	Condition="Always"	# ORIGINAL mbpo
+		Name="ConvolutionKernel"				Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="ConvolutionKernelGroup"			Type="1C"	StringDefinedTerms ="CTConvolutionKernelGroup"	Condition="ConvolutionKernelIsPresent"
+		Name="ReconstructionDiameter"			Type="1C"	Condition="ReconstructionFieldOfViewAbsent"	NotZeroWarning=""				# ORIGINAL mbpo
+		Name="ReconstructionFieldOfView"		Type="1C"	Condition="ReconstructionDiameterAbsent"	NotZeroWarning=""				# ORIGINAL mbpo
+		Name="ReconstructionPixelSpacing"		Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+		Name="ReconstructionAngle"				Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="ImageFilter"						Type="1C"	Condition="Always"							# ORIGINAL mbpo
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTExposureMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTExposureSequence"				Type="1"	VM="1"
+		Name="ExposureTimeInms"					Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+		Name="XRayTubeCurrentInmA"				Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+		Name="ExposureInmAs"					Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+		Name="ExposureModulationType"			Type="1C"	StringDefinedTerms ="CTExposureModulationType"	Condition="Always"	# ORIGINAL mbpo
+		Name="EstimatedDoseSaving"				Type="2C"	Condition="ExposureModulationTypeIsNotNone"	NotZeroWarning=""				# ORIGINAL mbpo
+		Name="CTDIvol"							Type="2C"	NoCondition=""	NotZeroWarning=""
+		Sequence="CTDIPhantomTypeCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"					DefinedContextID="4052"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTXRayDetailsMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTXRayDetailsSequence"			Type="1"	VM="1"
+		Name="KVP"								Type="1C"	Condition="Always"	NotZeroWarning=""							# ORIGINAL mbpo
+		Name="FocalSpots"						Type="1C"	Condition="Always"							# ORIGINAL mbpo
+		Name="FilterType"						Type="1C"	StringDefinedTerms ="CTFilterType"	Condition="Always"	# ORIGINAL mbpo
+		Name="FilterMaterial"					Type="1C"	StringDefinedTerms ="CTFilterMaterial"	Condition="Always"	# ORIGINAL mbpo
+		Name="CalciumScoringMassFactorPatient"	Type="3"	NotZeroWarning=""
+		Name="CalciumScoringMassFactorDevice"	Type="3"	NotZeroWarning=""
+		Name="EnergyWeightingFactor"			Type="1C"	NotZeroWarning=""	NoCondition="" mbpo="true"	# FrameTypeValue4IsEnergyProportionalWeighting ... too hard :(
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTPixelValueTransformationMacro" InformationEntity="FunctionalGroup"
+	Sequence="PixelValueTransformationSequence"		Type="1"	VM="1"
+		Name="RescaleIntercept"						Type="1" 
+		Name="RescaleSlope"							Type="1"	NotZeroError="" 
+		Name="RescaleType"							Type="1" 	StringEnumValues="RescaleTypeHounsfieldUnits"	#actually only if not localizer :(
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CTAdditionalXRaySourceMacro" InformationEntity="FunctionalGroup"
+	Sequence="CTAdditionalXRaySourceSequence"		Type="1"	VM="1-n"
+		Name="KVP"								Type="1"	NotZeroWarning=""
+		Name="XRayTubeCurrentInmA"				Type="1"	NotZeroWarning=""
+		Name="DataCollectionDiameter"			Type="1"	NotZeroWarning=""
+		Name="FocalSpots"						Type="1"
+		Name="FilterType"						Type="1"	StringDefinedTerms ="CTFilterType"
+		Name="FilterMaterial"					Type="1"	StringDefinedTerms ="CTFilterMaterial"
+		Name="ExposureInmAs"					Type="3"	NotZeroWarning=""
+		Name="EnergyWeightingFactor"			Type="1C"	NotZeroWarning=""	NoCondition="" mbpo="true"	# FrameTypeValue4IsEnergyProportionalWeighting ... too hard :(
+	SequenceEnd
+MacroEnd
+
+DefineMacro="UnassignedSharedConvertedAttributesMacro" InformationEntity="FunctionalGroup"
+	Sequence="UnassignedSharedConvertedAttributesSequence"		Type="2"	VM="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="UnassignedPerFrameConvertedAttributesMacro" InformationEntity="FunctionalGroup"
+	Sequence="UnassignedPerFrameConvertedAttributesSequence"	Type="2"	VM="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="ImageFrameConversionSourceMacro" InformationEntity="FunctionalGroup"
+	Sequence="ConversionSourceAttributesSequence"				Type="1"	VM="1-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForEnhancedCTImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTFrameVOILUTMacro"		Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"		Condition="IrradiationEventIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTImageFrameTypeMacro"		Condition="CTImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTAcquisitionTypeMacro"		Condition="NeedCTAcquisitionTypeMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTAcquisitionDetailsMacro"		Condition="NeedCTAcquisitionDetailsMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTTableDynamicsMacro"		Condition="NeedCTTableDynamicsMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTPositionMacro"			Condition="NeedCTPositionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTGeometryMacro"			Condition="NeedCTGeometryMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTReconstructionMacro"		Condition="NeedCTReconstructionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTExposureMacro"			Condition="NeedCTExposureMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTXRayDetailsMacro"		Condition="NeedCTXRayDetailsMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="CTPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTAdditionalXRaySourceMacro"		Condition="CTAdditionalXRaySourceMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CTFrameVOILUTMacro"		Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"		Condition="IrradiationEventIdentificationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CTImageFrameTypeMacro"		Condition="CTImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CTAcquisitionTypeMacro"		Condition="NeedCTAcquisitionTypeMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTAcquisitionDetailsMacro"		Condition="NeedCTAcquisitionDetailsMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTTableDynamicsMacro"		Condition="NeedCTTableDynamicsMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTPositionMacro"			Condition="NeedCTPositionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTGeometryMacro"			Condition="NeedCTGeometryMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTReconstructionMacro"		Condition="NeedCTReconstructionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTExposureMacro"			Condition="NeedCTExposureMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTXRayDetailsMacro"		Condition="NeedCTXRayDetailsMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CTAdditionalXRaySourceMacro"		Condition="CTAdditionalXRaySourceMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForLegacyConvertedEnhancedCTImage"
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CTImageFrameTypeMacro"					Condition="CTImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTPixelValueTransformationMacro"		Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="UnassignedSharedConvertedAttributesMacro"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTImageFrameTypeMacro"					Condition="CTImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CTPixelValueTransformationMacro"		Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="UnassignedPerFrameConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"
+	SequenceEnd
+ModuleEnd
+
+
+Module="MultiFrameFunctionalGroupsForPrivatePixelMedLegacyConvertedEnhancedCTImage"
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CTFrameVOILUTMacro"					Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CTImageFrameTypeMacro"					Condition="CTImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTPixelValueTransformationMacro"		Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="UnassignedSharedConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTFrameVOILUTMacro"					Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CTImageFrameTypeMacro"					Condition="CTImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CTPixelValueTransformationMacro"		Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="UnassignedPerFrameConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
diff --git a/libsrc/standard/module/dx.tpl b/libsrc/standard/module/dx.tpl
new file mode 100755
index 0000000..8904117
--- /dev/null
+++ b/libsrc/standard/module/dx.tpl
@@ -0,0 +1,675 @@
+Module="XRayAcquisitionDose"
+	Name="KVP"									Type="3"	NotZeroWarning=""
+	
+	Name="XRayTubeCurrent"						Type="3"	NotZeroWarning=""
+	Name="XRayTubeCurrentInuA"					Type="3"	NotZeroWarning=""
+	Verify="XRayTubeCurrentInmA"							Condition="XRayTubeCurrentInmAIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayAcquisitionDose> - use XRayTubeCurrent and/or XRayTubeCurrentInuA instead of"
+	
+	Name="ExposureTime"							Type="3"	NotZeroWarning=""
+	Name="ExposureTimeInuS"						Type="3"	NotZeroWarning=""
+	Verify="ExposureTimeInms"								Condition="ExposureTimeInmsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayAcquisitionDose> - use ExposureTime and/or ExposureTimeInuS instead of"
+	
+	Name="Exposure"								Type="3"	NotZeroWarning=""
+	Name="ExposureInuAs"						Type="3"	NotZeroWarning=""
+	Verify="ExposureInmAs"									Condition="ExposureInmAsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayAcquisitionDose> - use Exposure and/or ExposureInuAs instead of"
+	
+	Name="DistanceSourceToDetector"				Type="3"	NotZeroWarning=""
+	Name="DistanceSourceToPatient"				Type="3"	NotZeroWarning=""
+	Name="ImageAndFluoroscopyAreaDoseProduct"	Type="3"	NotZeroWarning=""
+	Name="BodyPartThickness"					Type="3"	NotZeroWarning=""
+	Name="RelativeXRayExposure"					Type="3"	NotZeroWarning=""
+	Name="EntranceDose"							Type="3"	NotZeroWarning=""
+	Name="EntranceDoseInmGy"					Type="3"	NotZeroWarning=""
+	Name="ExposedArea"							Type="3"
+	Name="DistanceSourceToEntrance"				Type="3"	NotZeroWarning=""
+	Name="CommentsOnRadiationDose"				Type="3"
+	Name="XRayOutput"							Type="3"	NotZeroWarning=""
+	Name="HalfValueLayer"						Type="3"	NotZeroWarning=""
+	Name="OrganDose"							Type="3"	NotZeroWarning=""
+	Name="OrganExposed"							Type="3"	StringDefinedTerms="OrganExposed"
+	Name="AnodeTargetMaterial"					Type="3"	StringDefinedTerms="AnodeTargetMaterial"
+	InvokeMacro="XRayFiltrationMacro"
+	Name="RectificationType"					Type="3"	StringDefinedTerms="RectificationType"
+	InvokeMacro="ExposureIndexMacro"
+ModuleEnd
+
+Module="XRayGeneration"
+	Name="KVP"									Type="3"	NotZeroWarning=""
+	
+	Name="XRayTubeCurrent"						Type="3"	NotZeroWarning=""
+	Name="XRayTubeCurrentInuA"					Type="3"	NotZeroWarning=""
+	Verify="XRayTubeCurrentInmA"							Condition="XRayTubeCurrentInmAIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayGeneration> - use XRayTubeCurrent and/or XRayTubeCurrentInuA instead of"
+	
+	Name="ExposureTime"							Type="3"	NotZeroWarning=""
+	Name="ExposureTimeInuS"						Type="3"	NotZeroWarning=""
+	Verify="ExposureTimeInms"								Condition="ExposureTimeInmsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayGeneration> - use ExposureTime and/or ExposureTimeInuS instead of"
+	
+	Name="Exposure"								Type="3"	NotZeroWarning=""
+	Name="ExposureInuAs"						Type="3"	NotZeroWarning=""
+	Verify="ExposureInmAs"									Condition="ExposureInmAsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayGeneration> - use Exposure and/or ExposureInuAs instead of"
+	
+	Name="ExposureControlMode"					Type="3"	StringDefinedTerms="ExposureControlMode"
+	Name="ExposureControlModeDescription"		Type="3"
+	Name="ExposureStatus"						Type="3"	StringDefinedTerms="ExposureStatus"
+	Name="PhototimerSetting"					Type="3"
+	Name="FocalSpots"							Type="3"
+	Name="AnodeTargetMaterial"					Type="3"	StringDefinedTerms="AnodeTargetMaterial"
+	Name="RectificationType"					Type="3"	StringDefinedTerms="RectificationType"
+	Name="GeneratorID"							Type="3"
+ModuleEnd
+
+DefineMacro="XRayFiltrationMacro"
+	Name="FilterType"							Type="3"	StringDefinedTerms="DXFilterType"
+	Name="FilterMaterial"						Type="3"	StringDefinedTerms="DXFilterMaterial"
+	Name="FilterThicknessMaximum"				Type="3"	NotZeroWarning=""
+	Name="FilterThicknessMinimum"				Type="3"	NotZeroWarning=""
+	Name="FilterBeamPathLengthMinimum"			Type="3"	NotZeroWarning=""
+	Name="FilterBeamPathLengthMaximum"			Type="3"	NotZeroWarning=""
+MacroEnd
+
+Module="XRayFiltration"
+	InvokeMacro="XRayFiltrationMacro"
+ModuleEnd
+
+DefineMacro="XRayGridDescriptionMacro" InformationEntity="Image"
+	Name="GridAbsorbingMaterial"				Type="3"
+	Name="GridSpacingMaterial"					Type="3"
+	Name="GridThickness"						Type="3"	NotZeroWarning=""
+	Name="GridPitch"							Type="3"	NotZeroWarning=""
+	Name="GridAspectRatio"						Type="3"	NotZeroWarning=""
+	Name="GridPeriod"							Type="3"	NotZeroWarning=""
+	Name="GridFocalDistance"					Type="3"	NotZeroWarning=""
+	Name="GridID"								Type="3"
+MacroEnd
+
+Module="XRayGrid"
+	Name="Grid"									Type="3"	StringDefinedTerms="XRayGrid"
+	InvokeMacro="XRayGridDescriptionMacro"
+ModuleEnd
+
+Module="DXSeries"
+	Name="Modality"										Type="1"	StringEnumValues="DXModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="PresentationIntentType"						Type="1"	StringEnumValues="PresentationIntentType"
+	Verify="PresentationIntentType"									Condition="IsForProcessingSOPClass"	StringEnumValues="ForProcessing"
+	Verify="PresentationIntentType"									Condition="IsForPresentationSOPClass"	StringEnumValues="ForPresentation"
+ModuleEnd
+
+Module="DXAnatomyImaged"
+	Name="ImageLaterality"								Type="1"	StringEnumValues="ImageLaterality"
+	InvokeMacro="GeneralAnatomyRequiredMacro"
+ModuleEnd
+
+Module="DXImage"
+	Name="ImageType"									Type="1"	ValueSelector="0"	StringEnumValues="ImageType1"
+	Verify="ImageType"												ValueSelector="1"	StringEnumValues="ImageType2"
+	Verify="ImageType"												ValueSelector="2"	StringEnumValues="DXImageType3"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre6To16"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre5To15"
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="PixelIntensityRelationship"					Type="1"	StringEnumValues="DXPixelIntensityRelationship"
+	Name="PixelIntensityRelationshipSign"				Type="1"	BinaryEnumValues="PixelIntensityRelationshipSign"
+	Name="RescaleIntercept"								Type="1"	BinaryEnumValues="Zero"
+	Name="RescaleSlope"									Type="1"	BinaryEnumValues="One"
+	Name="RescaleType"									Type="1"	StringEnumValues="ModalityLUTTypeUnspecified"
+	Name="PresentationLUTShape"							Type="1"	StringEnumValues="DXPresentationLUTShape"
+	Name="LossyImageCompression"						Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"					Type="1C"	NoCondition=""
+	Name="DerivationDescription"						Type="3"
+	Name="AcquisitionDeviceProcessingDescription"		Type="3"
+	Name="AcquisitionDeviceProcessingCode"				Type="3"
+	Name="PatientOrientation"							Type="1C"	Condition="DXPatientOrientationRequired" mbpo="true"
+	Name="CalibrationImage"								Type="3"	StringEnumValues="YesNoFull"
+	Name="BurnedInAnnotation"							Type="1"	StringEnumValues="YesNoFull"
+	Name="RecognizableVisualFeatures"					Type="3"	StringEnumValues="YesNoFull"
+	Sequence="VOILUTSequence"							Type="1C"	VM="1-n"	Condition="ForPresentationAndWindowCenterNotPresent" mbpo="true"
+		Name="LUTDescriptor"							Type="1"
+		Verify="LUTDescriptor"										ValueSelector="2"	BinaryEnumValues="BitsAre10To16"
+		Name="LUTExplanation"							Type="3"
+		Name="LUTData"									Type="1"
+	SequenceEnd
+	Verify="VOILUTSequence"											Condition="VOILUTSequencePresentAndPresentationIntentTypeIsNotForPresentation" ThenErrorMessage="May only be present in For Presentation images"
+	Name="WindowCenter"									Type="1C"	Condition="ForPresentationAndVOILUTSequenceNotPresent" mbpo="true"
+	Verify="WindowCenter"											Condition="WindowCenterPresentAndPresentationIntentTypeIsNotForPresentation" ThenErrorMessage="May only be present in For Presentation images"
+	Name="WindowWidth"									Type="1C"	Condition="WindowCenterPresent"	NotZeroError=""
+	Verify="WindowWidth"											Condition="WindowWidthIsNegative"	ThenErrorMessage="Not permitted to be negative" ShowValueWithMessage="true"
+	Name="WindowCenterWidthExplanation"					Type="3"
+ModuleEnd
+
+DefineMacro="DigitalXRayDetectorMacro" InformationEntity="Image"
+	Name="DetectorType"									Type="2"	StringDefinedTerms="DetectorType"
+	Name="DetectorConfiguration"						Type="3"	StringDefinedTerms="DetectorConfiguration"
+	Name="DetectorDescription"							Type="3"
+	Name="DetectorMode"									Type="3"
+	Name="DetectorID"									Type="3"
+	Name="DateOfLastDetectorCalibration"				Type="3"
+	Name="TimeOfLastDetectorCalibration"				Type="3"
+	Name="ExposuresOnDetectorSinceLastCalibration"		Type="3"
+	Name="ExposuresOnDetectorSinceManufactured"			Type="3"
+	Name="DetectorTimeSinceLastExposure"				Type="3"
+	Name="DetectorBinning"								Type="3"
+	Name="DetectorManufacturerName"						Type="3"
+	Name="DetectorManufacturerModelName"				Type="3"
+	Name="DetectorConditionsNominalFlag"				Type="3"	StringEnumValues="YesNoFull"
+	Name="DetectorTemperature"							Type="3"
+	Name="Sensitivity"									Type="3"	NotZeroWarning=""
+	Name="DetectorElementPhysicalSize"					Type="3"	NotZeroError=""
+	Name="DetectorElementSpacing"						Type="3"	NotZeroError=""
+	Name="DetectorActiveShape"							Type="3"	StringEnumValues="DXShape"
+	Name="DetectorActiveDimensions"						Type="3"
+	Name="DetectorActiveOrigin"							Type="3"
+	InvokeMacro="ExposureIndexMacro"
+MacroEnd
+
+Module="DXDetector"
+	InvokeMacro="DigitalXRayDetectorMacro"
+	Name="DetectorActiveTime"							Type="3"
+	Name="DetectorActivationOffsetFromExposure"			Type="3"
+	Name="FieldOfViewShape"								Type="3"	StringEnumValues="DXShape"
+	Name="FieldOfViewDimensions"						Type="3"	NotZeroError=""
+	Name="FieldOfViewOrigin"							Type="1C"	Condition="FieldOfViewRotationOrFieldOfViewHorizontalFlipPresent"
+	Name="FieldOfViewRotation"							Type="1C"	Condition="FieldOfViewHorizontalFlipPresent"	StringEnumValues="DXFieldOfViewRotation"
+	Name="FieldOfViewHorizontalFlip"					Type="1C"	Condition="FieldOfViewRotationPresent"		StringEnumValues="YesNoFull"
+	Name="ImagerPixelSpacing"							Type="1"	NotZeroError=""
+	InvokeMacro="BasicPixelSpacingCalibrationMacro"
+	Name="CassetteID"									Type="3"
+	Name="PlateID"										Type="3"
+ModuleEnd
+
+Module="DXPositioning"
+	Sequence="ProjectionEponymousNameCodeSequence"		Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4012"
+	SequenceEnd
+	Name="PatientPosition"								Type="3"	StringDefinedTerms="PatientPosition"
+	Name="ViewPosition"									Type="3"
+	Verify="ViewPosition"											Condition="IsHuman"		StringDefinedTerms="ViewPositionHuman"
+	Verify="ViewPosition"											Condition="IsAnimal"	StringDefinedTerms="ViewPositionAnimal"
+	Sequence="ViewCodeSequence"							Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4010"
+		Sequence="ViewModifierCodeSequence"				Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="4011"
+		SequenceEnd
+	SequenceEnd
+	Verify="ViewCodeSequence"										Condition="ViewCodeSequenceAbsentOrEmptyButViewPositionHasValue"	ThenWarningMessage="ViewCodeSequence is empty or absent, but view is known since ViewPosition has a value"
+	Sequence="ViewModifierCodeSequence"					Type="1C"	VM="1-n"	Condition="Never"
+	SequenceEnd
+	Sequence="PatientOrientationCodeSequence"			Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="19"
+		Sequence="PatientOrientationModifierCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="20"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PatientOrientationModifierCodeSequence"	Type="1C"	VM="1"	Condition="Never"
+	SequenceEnd
+	Sequence="PatientGantryRelationshipCodeSequence"	Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="21"
+	SequenceEnd
+	Name="DistanceSourceToPatient"						Type="3"	NotZeroWarning=""
+	Name="DistanceSourceToDetector"						Type="3"	NotZeroWarning=""
+	Name="EstimatedRadiographicMagnificationFactor"		Type="3"
+	Name="PositionerType"								Type="2"	StringDefinedTerms="DXPositionerType"
+	Name="PositionerPrimaryAngle"						Type="3"
+	Name="PositionerSecondaryAngle"						Type="3"
+	Name="DetectorPrimaryAngle"							Type="3"
+	Name="DetectorSecondaryAngle"						Type="3"
+	Name="ColumnAngulation"								Type="3"
+	Name="TableType"									Type="3"	StringDefinedTerms="DXTableType"
+	Name="TableAngle"									Type="3"
+	Name="BodyPartThickness"							Type="3"	NotZeroWarning=""
+	Name="CompressionForce"								Type="3"
+	Name="PaddleDescription"							Type="3"
+ModuleEnd
+
+Module="MammographySeries"
+	Name="Modality"										Type="1"	StringEnumValues="MammographyModality"
+	Sequence="RequestAttributesSequence"				Type="3"	VM="1-n"
+		InvokeMacro="RequestAttributesMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="MammographyImage"
+	Name="ImageType"									Type="1"	ValueSelector="2"	StringEnumValues="MammoImageType3"
+	Verify="ImageType"												ValueSelector="3"	StringDefinedTerms="MammoImageType4"
+	Verify="ImageType"												ValueSelector="4"	StringDefinedTerms="MammoImageType5"
+	Name="PositionerType"								Type="1"	StringEnumValues="MammographyPositionerType"
+	Name="DistanceSourceToPatient"						Type="3"	NotZeroWarning=""
+	Name="DistanceSourceToDetector"						Type="3"	NotZeroWarning=""
+	Name="PositionerPrimaryAngle"						Type="3"
+	Name="PositionerPrimaryAngleDirection"				Type="3"	StringEnumValues="PositionerPrimaryAngleDirection"
+	Name="PositionerSecondaryAngle"						Type="3"
+	Name="ImageLaterality"								Type="1"	StringEnumValues="MammographyImageLaterality"
+	Name="OrganExposed"									Type="1"	StringDefinedTerms="MammographyOrganExposed"
+	Name="BreastImplantPresent"							Type="3"	StringEnumValues="YesNoFull"
+	Name="PartialView"									Type="3"	StringEnumValues="YesNoFull"
+	Name="PartialViewDescription"						Type="3"
+	Sequence="PartialViewCodeSequence"					Type="3"	VM="1-2"
+		InvokeMacro="CodeSequenceMacro"								DefinedContextID="4005"
+	SequenceEnd
+	InvokeMacro="GeneralAnatomyMandatoryMacro"
+	Sequence="ViewCodeSequence"							Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								EnmeratedContextID="4014"
+		Sequence="ViewModifierCodeSequence"				Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"							EnmeratedContextID="4015"
+		SequenceEnd
+	SequenceEnd
+	Sequence="BiopsyTargetSequence"						Type="3"	VM="1-n"
+		Name="TargetUID"								Type="1"
+		Name="LocalizingCursorPosition"					Type="1"
+		Name="CalculatedTargetPosition"					Type="1"
+		Name="DisplayedZValue"							Type="1"
+		Name="TargetLabel"								Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="IntraoralSeries"
+	Name="Modality"										Type="1"	StringEnumValues="IntraoralModality"
+ModuleEnd
+
+Module="IntraoralImage"
+	Name="PositionerType"								Type="1"	StringEnumValues="IntraoralPositionerType"
+	Name="ImageLaterality"								Type="1"	StringEnumValues="IntraoralImageLaterality"
+	Sequence="AnatomicRegionSequence"					Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								DefinedContextID="4016"
+		Sequence="AnatomicRegionModifierSequence"		Type="1C"	VM="1"	Condition="NoPrimaryAnatomicStructureSequence"
+			InvokeMacro="CodeSequenceMacro"							DefinedContextID="4017"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PrimaryAnatomicStructureSequence"			Type="1C"	VM="1-n"	Condition="NoAnatomicRegionModifierSequence"
+		InvokeMacro="CodeSequenceMacro"								DefinedContextID="4018 or 4019"
+	SequenceEnd
+ModuleEnd
+
+Module="ImageHistogram"
+	Sequence="HistogramSequence"						Type="1"	VM="1-n"
+		Name="HistogramNumberOfBins"					Type="1"
+		Name="HistogramFirstBinValue"					Type="1"
+		Name="HistogramLastBinValue"					Type="1"
+		Name="HistogramBinWidth"						Type="1"
+		Name="HistogramExplanation"						Type="3"
+		Name="HistogramData"							Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="IHEDBTProfile"
+	Name="PatientName"						Type="1"
+	Name="PatientID"						Type="1"
+	Name="PatientBirthDate"					Type="1"
+	Name="PatientAge"						Type="1"
+	Name="OperatorsName"					Type="1"
+	Name="Manufacturer"						Type="1"
+	Name="InstitutionName"					Type="1"
+	Name="InstitutionAddress"				Type="1"
+	Name="ManufacturerModelName"			Type="1"
+	Name="DeviceSerialNumber"				Type="1"
+	Name="StationName"						Type="1"
+	Sequence="ContributingSourcesSequence"	Type="1"	VM="1-n"
+		Name="AcquisitionDateTime"			Type="1"
+	SequenceEnd
+	Sequence="XRay3DAcquisitionSequence"	Type="1"	VM="1-n"
+		Name="OrganDose"					Type="1"
+		Name="EntranceDoseInmGy"			Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="IHEMammoProfile"
+	Name="PatientName"						Type="1"
+	Name="PatientID"						Type="1"
+	Name="PatientBirthDate"					Type="1"
+	Name="PatientAge"						Type="1"
+	Name="AcquisitionDate"					Type="1"
+	Name="AcquisitionTime"					Type="1"
+	Name="OperatorsName"					Type="1"
+	Name="Manufacturer"						Type="1"
+	Name="InstitutionName"					Type="1"
+	Name="InstitutionAddress"				Type="1"
+	Name="ManufacturerModelName"			Type="1"
+	Name="DeviceSerialNumber"				Type="1"
+	Name="DetectorID"						Type="1"
+	Name="SoftwareVersions"					Type="1"
+	Name="StationName"						Type="1"
+	Name="GantryID"							Type="1C"	Condition="DetectorTypeIsStorage" mbpo="true"
+	Name="KVP"								Type="1"	NotZeroWarning=""
+	Name="Exposure"							Type="1"	NotZeroWarning=""
+	Name="ExposureTime"						Type="1"	NotZeroWarning=""
+	Name="FilterMaterial"					Type="1"
+	Name="AnodeTargetMaterial"				Type="1"
+	Name="CompressionForce"					Type="1"
+	Name="BodyPartThickness"				Type="1"	NotZeroWarning=""
+	Name="PositionerPrimaryAngle"			Type="1"
+	Name="RelativeXRayExposure"				Type="1"	NotZeroWarning=""
+	Name="EntranceDoseInmGy"				Type="1"	NotZeroWarning=""
+	Name="OrganDose"						Type="1"	NotZeroWarning=""
+	Name="BurnedInAnnotation"				Type="1"	StringEnumValues="NoFull"
+	Name="BreastImplantPresent"				Type="1"
+	Name="PixelPaddingValue"				Type="1"	# really only required if skin edge detected, but cannot check the real world intent
+	Name="EstimatedRadiographicMagnificationFactor"	Type="1"
+	Name="DateOfLastDetectorCalibration"	Type="1C"	Condition="DetectorTypeIsNotStorage" mbpo="true"
+	Verify="PixelSpacing"								Condition="PixelSpacingIsPresent" ThenWarningMessage="Attribute present but not used in IHE Mammo Profile"
+ModuleEnd
+
+Module="IHEMammoProfileWithoutPartialViewOption"
+	Verify="PartialView"								Condition="PartialViewNotPresent"	ThenWarningMessage="IHE Mammo Profile Partial View Option not supported"
+ModuleEnd
+
+Module="IHEMammoProfileWithPartialViewOption"
+	Name="PartialView"						Type="1"	# really only required for partial view named option
+	Sequence="PartialViewCodeSequence"		Type="1C"	VM="1-2"	Condition="PartialViewIsYes"
+	SequenceEnd
+ModuleEnd
+
+Module="IHEMammoProfileForPresentationOnly"
+	Sequence="SourceImageSequence"			Type="1"	VM="1"
+		Name="SpatialLocationsPreserved"	Type="1"
+	SequenceEnd
+	Sequence="VOILUTSequence"				Type="3"	VM="1-n"
+		Name="LUTExplanation"				Type="1"	# really only required if number of items > 1, but cannot check this
+	SequenceEnd
+	Name="WindowCenterWidthExplanation"		Type="1C"	Condition="WindowCenterPresent"	# really only required if number of values > 1, but cannot check this
+	Name="VOILUTFunction"					Type="1"	# really only required if not linear, but cannot check the real world intent
+ModuleEnd
+
+Module="DentalImageOnMediaProfile"
+	Name="BitsAllocated"					Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Verify="BitsAllocated"								Condition="BitsStoredIs8"			BinaryEnumValues="BitsAre8"
+	Verify="BitsAllocated"								Condition="BitsStoredGreaterThan8"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"						Type="1"	BinaryEnumValues="BitsAre8Or10Or12Or16"
+	Name="InstitutionName"					Type="2"
+	Name="ManufacturerModelName"			Type="2"
+	Name="DetectorID"						Type="2"
+	Name="DetectorManufacturerName"			Type="2"
+	Name="DetectorManufacturerModelName"	Type="2"
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForBreastTomosynthesisImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IdentityPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTWithLUTMacro"				Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="IdentityPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTWithLUTMacro"				Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRay3DFrameTypeMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="IdentityPixelValueTransformationMacro" InformationEntity="FunctionalGroup"
+	Sequence="PixelValueTransformationSequence"		Type="1"	VM="1"
+		Name="RescaleIntercept"						Type="1"	BinaryEnumValues="Zero"
+		Name="RescaleSlope"							Type="1"	BinaryEnumValues="One"
+		Name="RescaleType"							Type="1"	StringEnumValues="ModalityLUTTypeUnspecified"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="FrameVOILUTWithLUTMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameVOILUTSequence"					Type="1"	VM="1"
+		InvokeMacro="VOILUTMacro"
+	SequenceEnd
+MacroEnd
+
+Module="BreastTomosynthesisContributingSources"
+	Sequence="ContributingSourcesSequence"					Type="1"	VM="1-n"
+		InvokeMacro="GeneralContributingSourcesMacro"
+		InvokeMacro="ContributingImageSourcesMacro"
+		Name="DetectorType"									Type="1"	StringDefinedTerms="DetectorTypeExcludingFilm"
+		Name="DetectorID"									Type="1"
+		Name="DateOfLastDetectorCalibration"				Type="1"
+		Name="TimeOfLastDetectorCalibration"				Type="1"
+		Name="DetectorElementSpacing"						Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="BreastTomosynthesisAcquisition"
+	Sequence="XRay3DAcquisitionSequence"					Type="1"	VM="1-n"
+		Name="FieldOfViewShape"								Type="1"	StringEnumValues="BreastTomosynthesisFieldOfViewShape"
+		Name="XRayReceptorType"								Type="1"	StringEnumValues="BreastTomosynthesisXRayReceptorType"
+		InvokeMacro="XRay3DGeneralSharedAcquisitionMacro"
+		InvokeMacro="XRay3DGeneralPositionerMovementMacro"
+		Name="DistanceSourceToDetector"						Type="1"	NotZeroWarning=""
+		Name="DistanceSourceToPatient"						Type="1"	NotZeroWarning=""
+		Name="EstimatedRadiographicMagnificationFactor"		Type="1"
+		Name="AnodeTargetMaterial"							Type="1"	StringDefinedTerms="AnodeTargetMaterial"
+		Name="BodyPartThickness"							Type="1"	NotZeroWarning=""
+		Name="ExposureControlMode"							Type="1"	StringDefinedTerms="ExposureControlMode"
+		Name="ExposureControlModeDescription"				Type="1"
+		Name="HalfValueLayer"								Type="1"	NotZeroWarning=""
+		Name="OrganDose"									Type="3"	NotZeroWarning=""
+		Name="EntranceDoseInmGy"							Type="3"	NotZeroWarning=""
+		Name="FocalSpots"									Type="1"
+		Name="DetectorBinning"								Type="1C"	NoCondition=""	# real world
+		Name="DetectorTemperature"							Type="1"	NotZeroWarning=""
+		Name="FilterType"									Type="1"
+		Name="FilterMaterial"								Type="1"
+		Name="FilterThicknessMinimum"						Type="3"	NotZeroWarning=""
+		Name="FilterThicknessMaximum"						Type="3"	NotZeroWarning=""
+		Name="FilterBeamPathLengthMinimum"					Type="3"	NotZeroWarning=""
+		Name="FilterBeamPathLengthMaximum"					Type="3"	NotZeroWarning=""
+		Name="CompressionForce"								Type="1"	NotZeroWarning=""
+		Name="PaddleDescription"							Type="1"
+		Sequence="PerProjectionAcquisitionSequence"			Type="1"	VM="1-n"
+			InvokeMacro="XRay3DGeneralPerProjectionAcquisitionMacro"
+			Name="PositionerPrimaryAngle"					Type="1"
+			Name="PositionerPrimaryAngleDirection"			Type="3"	StringEnumValues="PositionerPrimaryAngleDirection"
+			Name="PositionerSecondaryAngle"					Type="1C"	NoCondition=""	# real world
+			Name="ExposureTimeInms"							Type="1"	NotZeroWarning=""
+			Name="ExposureInmAs"							Type="1"	NotZeroWarning=""
+			Name="RelativeXRayExposure"						Type="1"	NotZeroWarning=""
+			Name="OrganDose"								Type="3"	NotZeroWarning=""
+			Name="EntranceDoseInmGy"						Type="3"	NotZeroWarning=""
+			InvokeMacro="ExposureIndexMacro"
+			Name="IrradiationEventUID"						Type="3"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="BreastView"
+	Name="ImageType"									Type="1"	ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3AndBreastTomoImageAndFrameType3"
+	Verify="ImageType"												ValueSelector="3"	StringDefinedTerms="BreastTomoImageAndFrameType4"
+	Verify="ImageType"												ValueSelector="4"	StringDefinedTerms="BreastTomoImageAndFrameType5"
+	Sequence="ViewCodeSequence"							Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								EnmeratedContextID="4014"
+		Sequence="ViewModifierCodeSequence"				Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"							EnmeratedContextID="4015"
+		SequenceEnd
+	SequenceEnd
+	Name="BreastImplantPresent"							Type="1C"	Condition="ModalityIsMG"	StringEnumValues="YesNoFull"
+	Name="PartialView"									Type="3"	StringEnumValues="YesNoFull"
+	Verify="PartialView"											Condition="ViewModifierCodeSequenceIsMagnificationOrSpotCompression"	StringEnumValues="NoFull"
+	Sequence="PartialViewCodeSequence"					Type="1C"	Condition="PartialViewIsYes"	VM="1-2"
+		InvokeMacro="CodeSequenceMacro"								DefinedContextID="4005"
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedMammographySeries"
+	Name="Modality"										Type="1"	StringEnumValues="MammographyModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="RequestAttributesSequence"				Type="3"	VM="1-n"
+		InvokeMacro="RequestAttributesMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedMammographyImage"
+	Name="PositionerMotion"								Type="1"	StringDefinedTerms="MammographyPositionerAndDetectorMotion"
+	Name="PositionerType"								Type="1"	StringEnumValues="MammographyPositionerTypeWithoutNone"
+	Name="ContentQualification"							Type="1"	StringEnumValues="ContentQualification"
+	Name="AcquisitionDateTime"							Type="1"
+	Name="AcquisitionDuration"							Type="1"
+	InvokeMacro="DigitalXRayDetectorMacro"
+	Name="KVP"											Type="1"
+	Name="XRayTubeCurrentInmA"							Type="1C"	Condition="ExposureInmAsNotPresent" mbpo="true"
+	Name="ExposureTimeInms"								Type="1C"	Condition="ExposureInmAsNotPresent" mbpo="true"
+	Name="ExposureInmAs"								Type="1C"	Condition="XRayTubeCurrentInmAOrExposureTimeInmsNotPresent" mbpo="true"
+	Name="FocalSpots"									Type="1"
+	Name="AnodeTargetMaterial"							Type="1"	StringDefinedTerms="AnodeTargetMaterial"
+	Name="BodyPartThickness"							Type="1"
+	Name="CompressionForce"								Type="1"
+	Name="PaddleDescription"							Type="1"
+	Name="ExposureControlMode"							Type="1"	StringDefinedTerms="ExposureControlMode"
+	Name="ExposureControlModeDescription"				Type="1"
+	Name="PatientOrientation"							Type="1C"	Condition="ViewIsNotSpecimen" mbpo="true"
+	Name="ImageComments"								Type="3"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="One"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre8To16"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre7To15"
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="QualityControlImage"							Type="3"	StringEnumValues="YesNoFull"
+	Name="BurnedInAnnotation"							Type="1"	StringEnumValues="NoFull"
+	Name="LossyImageCompression"						Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"					Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"					Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"							Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="OrganDose"									Type="1"
+	Name="EntranceDoseInmGy"							Type="1"
+	Name="TypeOfDetectorMotion"							Type="1"	StringDefinedTerms="MammographyPositionerAndDetectorMotion"
+	Sequence="IconImageSequence"						Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	Name="PresentationLUTShape"							Type="1"	StringEnumValues="DXPresentationLUTShape"
+ModuleEnd
+
+DefineMacro="BreastXRayPositionerMacro"
+	Sequence="PositionerPositionSequence"				Type="1"	VM="1"
+		Name="PositionerPrimaryAngle"					Type="1C"	NoCondition=""
+		Name="PositionerPrimaryAngleDirection"			Type="1C"	NoCondition=""	StringEnumValues="PositionerPrimaryAngleDirection"
+		Name="PositionerSecondaryAngle"					Type="1C"	NoCondition=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="BreastXRayDetectorMacro"
+	Sequence="DetectorPositionSequence"					Type="1"	VM="1"
+		Name="DetectorPrimaryAngle"						Type="1C"	NoCondition=""
+		Name="DetectorSecondaryAngle"					Type="1C"	NoCondition=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="BreastXRayGeometryMacro"
+	Sequence="XRayGeometrySequence"						Type="1"	VM="1"
+		Name="DistanceSourceToDetector"					Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DistanceSourceToPatient"					Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DistanceSourceToIsocenter"				Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DistanceSourceToEntrance"					Type="3"
+		Name="EstimatedRadiographicMagnificationFactor"	Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="BreastXRayAcquisitionDoseMacro"
+	Sequence="XRayAcquisitionDoseSequence"				Type="1"	VM="1"
+		Name="ExposureTimeInms"							Type="1"
+		Name="ExposureInmAs"							Type="1"
+		Name="RelativeXRayExposure"						Type="3"
+		Name="HalfValueLayer"							Type="3"
+		Name="OrganDose"								Type="1"
+		Name="EntranceDoseInmGy"						Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="BreastXRayIsocenterReferenceSystemMacro"
+	Sequence="IsocenterReferenceSystemSequence"			Type="1"	VM="1"
+		Name="XRaySourceIsocenterPrimaryAngle"			Type="1"
+		Name="XRaySourceIsocenterSecondaryAngle"		Type="1"
+		Name="BreastSupportIsocenterPrimaryAngle"		Type="1"
+		Name="BreastSupportIsocenterSecondaryAngle"		Type="1"
+		Name="BreastSupportXPositionToIsocenter"		Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="BreastSupportYPositionToIsocenter"		Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="BreastSupportZPositionToIsocenter"		Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DetectorIsocenterPrimaryAngle"			Type="1"
+		Name="DetectorIsocenterSecondaryAngle"			Type="1"
+		Name="DetectorXPositionToIsocenter"				Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DetectorYPositionToIsocenter"				Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DetectorZPositionToIsocenter"				Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DetectorActiveAreaTLHCPosition"			Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+		Name="DetectorActiveAreaOrientation"			Type="1C"	Condition="PresentationIntentTypeIsForProcessing"	mbpo="true"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayGridMacro"
+	Sequence="XRayGridSequence"							Type="1"	VM="1"	StringDefinedTerms="XRayGrid"
+		Name="Grid"										Type="1"
+		InvokeMacro="XRayGridDescriptionMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayFilterMacro"
+	Sequence="XRayFilterSequence"						Type="1"	VM="1"
+		InvokeMacro="XRayFiltrationMacro"
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForBreastProjectionXRayImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="NeedDerivationImageMacroInSharedFunctionalGroupSequenceForBreastProjection"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IdentityPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTWithLUTMacro"				Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"				Condition="FrameDisplayShutterMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameCharacteristicsMacro"			Condition="XRayFrameCharacteristicsMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFieldOfViewMacro"					Condition="FieldOfViewSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFramePixelDataPropertiesMacro"		Condition="FramePixelDataPropertiesSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameDetectorParametersMacro"		Condition="XRayFrameDetectorParametersMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayCalibrationDeviceUsageMacro"		Condition="XRayCalibrationDeviceUsageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameAcquisitionMacro"				Condition="XRayFrameAcquisitionMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayCollimatorMacro"					Condition="CollimatorShapeSequenceSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="BreastXRayPositionerMacro"				Condition="NeedBreastXRayPositionerMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="BreastXRayDetectorMacro"				Condition="NeedBreastXRayDetectorMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="BreastXRayGeometryMacro"				Condition="XRayGeometrySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="BreastXRayAcquisitionDoseMacro"		Condition="XRayAcquisitionDoseSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="BreastXRayIsocenterReferenceSystemMacro"	Condition="IsocenterReferenceSystemSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayGridMacro"							Condition="XRayGridMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFilterMacro"						Condition="XRayFilterMacroOKInSharedFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="NeedDerivationImageMacroInPerFrameFunctionalGroupSequenceForBreastProjection"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="IdentityPixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTWithLUTMacro"				Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"				Condition="FrameDisplayShutterMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameCharacteristicsMacro"			Condition="XRayFrameCharacteristicsMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFieldOfViewMacro"					Condition="FieldOfViewSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFramePixelDataPropertiesMacro"		Condition="FramePixelDataPropertiesSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameDetectorParametersMacro"		Condition="XRayFrameDetectorParametersMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayCalibrationDeviceUsageMacro"		Condition="XRayCalibrationDeviceUsageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameAcquisitionMacro"				Condition="XRayFrameAcquisitionMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayCollimatorMacro"					Condition="CollimatorShapeSequenceSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="BreastXRayPositionerMacro"				Condition="NeedBreastXRayPositionerMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="BreastXRayDetectorMacro"				Condition="NeedBreastXRayDetectorMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="BreastXRayGeometryMacro"				Condition="XRayGeometrySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="BreastXRayAcquisitionDoseMacro"		Condition="XRayAcquisitionDoseSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="BreastXRayIsocenterReferenceSystemMacro"	Condition="IsocenterReferenceSystemSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayGridMacro"							Condition="XRayGridMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFilterMacro"						Condition="XRayFilterMacroOKInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
diff --git a/libsrc/standard/module/file.tpl b/libsrc/standard/module/file.tpl
new file mode 100755
index 0000000..5673d4d
--- /dev/null
+++ b/libsrc/standard/module/file.tpl
@@ -0,0 +1,310 @@
+Module="FileMetaInformation"
+
+	Name="FileMetaInformationGroupLength"	Type="1"
+	Name="FileMetaInformationVersion"	Type="1"
+	Name="MediaStorageSOPClassUID"	Type="1"
+	Name="MediaStorageSOPInstanceUID"	Type="1"
+	Name="TransferSyntaxUID"		Type="1"
+	Name="ImplementationClassUID"		Type="1"
+	Name="ImplementationVersionName"	Type="3"
+	Name="SourceApplicationEntityTitle"	Type="3"
+	Name="SendingApplicationEntityTitle"	Type="3"
+	Name="ReceivingApplicationEntityTitle"	Type="3"
+	Name="PrivateInformationCreatorUID"	Type="3"
+	Name="PrivateInformation"		Type="1C"	Condition="PrivateInformationCreatorUIDPresent"
+
+ModuleEnd
+
+Module="FileSetIdentification"
+
+	Name="FileSetID"			Type="2"
+	Name="FileSetDescriptorFileID"		Type="3"
+	Name="SpecificCharacterSetOfFileSetDescriptorFile"		Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+
+ModuleEnd
+
+Module="DirectoryInformation"
+
+	Name="OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity"					Type="1"
+	Name="OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity"					Type="1"
+	Name="FileSetConsistencyFlag"					Type="1"	BinaryEnumValues="FileSetConsistencyFlag"
+	Sequence="DirectoryRecordSequence"				Type="2"	VM="0-n"
+		Name="OffsetOfTheNextDirectoryRecord"			Type="1"
+		Name="RecordInUseFlag"						Type="1"	BinaryEnumValues="RecordInUseFlag"
+		Name="OffsetOfReferencedLowerLevelDirectoryEntity"			Type="1"
+		Name="DirectoryRecordType"					Type="1"	StringEnumValues="DirectoryRecordType"
+		Name="PrivateRecordUID"						Type="1C"	Condition="DirectoryRecordTypeIsPrivate"
+		Name="ReferencedFileID"						Type="1C"	Condition="DirectorySOPInstance" mbpo="true"	# mbpo since may be (optional) Detached Patient instance reference, for example
+		Name="ReferencedSOPClassUIDInFile"			Type="1C"	Condition="DirectorySOPInstance" mbpo="true"
+		Name="ReferencedSOPInstanceUIDInFile"		Type="1C"	Condition="DirectorySOPInstance" mbpo="true"
+		Name="ReferencedTransferSyntaxUIDInFile"	Type="1C"	Condition="DirectorySOPInstance" mbpo="true"
+		
+		InvokeMacro="PatientDirectoryRecord"					Condition="DirectoryRecordTypeIsPatient"
+		InvokeMacro="StudyDirectoryRecord"						Condition="DirectoryRecordTypeIsStudy"
+		InvokeMacro="SeriesDirectoryRecord"						Condition="DirectoryRecordTypeIsSeries"
+		InvokeMacro="ImageDirectoryRecord"						Condition="DirectoryRecordTypeIsImage"
+		InvokeMacro="RTDoseDirectoryRecord"						Condition="DirectoryRecordTypeIsRTDose"
+		InvokeMacro="RTStructureSetDirectoryRecord"				Condition="DirectoryRecordTypeIsRTStructureSet"
+		InvokeMacro="RTPlanDirectoryRecord"						Condition="DirectoryRecordTypeIsRTPlan"
+		InvokeMacro="RTTreatmentRecordDirectoryRecord"			Condition="DirectoryRecordTypeIsRTTreatmentRecord"
+		InvokeMacro="PresentationDirectoryRecord"				Condition="DirectoryRecordTypeIsPresentation"
+		InvokeMacro="WaveformDirectoryRecord"					Condition="DirectoryRecordTypeIsWaveform"
+		InvokeMacro="SRDocumentDirectoryRecord"					Condition="DirectoryRecordTypeIsSRDocument"
+		InvokeMacro="KeyObjectDocumentDirectoryRecord"			Condition="DirectoryRecordTypeIsKeyObjectDocument"
+		InvokeMacro="SpectroscopyDirectoryRecord"				Condition="DirectoryRecordTypeIsSpectroscopy"
+		InvokeMacro="RawDataDirectoryRecord"					Condition="DirectoryRecordTypeIsRawData"
+		InvokeMacro="RegistrationDirectoryRecord"				Condition="DirectoryRecordTypeIsRegistration"
+		InvokeMacro="FiducialDirectoryRecord"					Condition="DirectoryRecordTypeIsFiducial"
+		InvokeMacro="HangingProtocolDirectoryRecord"			Condition="DirectoryRecordTypeIsHangingProtocol"
+		InvokeMacro="EncapsulatedDocumentDirectoryRecord"		Condition="DirectoryRecordTypeIsEncapsulatedDocument"
+		InvokeMacro="HL7StructuredDocumentDirectoryRecord"		Condition="DirectoryRecordTypeIsHL7StructuredDocument"
+		InvokeMacro="RealWorldValueMappingDirectoryRecord"		Condition="DirectoryRecordTypeIsRealWorldValueMapping"
+		InvokeMacro="StereometricRelationshipDirectoryRecord"	Condition="DirectoryRecordTypeIsStereometricRelationship"
+		InvokeMacro="SurfaceDirectoryRecord"					Condition="DirectoryRecordTypeIsSurface"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="PatientDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="PatientName"							Type="2"
+		Name="PatientID"							Type="1"
+MacroEnd
+
+DefineMacro="StudyDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="StudyDate"							Type="1"
+		Name="StudyTime"							Type="1"
+		Name="StudyDescription"						Type="2"
+		Name="StudyInstanceUID"						Type="1C"	Condition="ReferencedSOPInstanceUIDInFileIsNotPresent"
+		Name="StudyID"								Type="1"
+		Name="AccessionNumber"						Type="2"
+MacroEnd
+		
+DefineMacro="SeriesDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="Modality"								Type="1"
+		Name="SeriesInstanceUID"					Type="1"
+		Name="SeriesNumber"							Type="1"
+		Sequence="IconImageSequence"				Type="3"	VM="1"
+			InvokeMacro="IconImageSequenceMacro"
+		SequenceEnd
+MacroEnd
+		
+DefineMacro="ImageDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Sequence="IconImageSequence"				Type="3"	VM="1"
+			InvokeMacro="IconImageSequenceMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="RTDoseDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="DoseSummationType"					Type="1"
+		Name="DoseComment"							Type="3"
+		Sequence="IconImageSequence"				Type="3"	VM="1"
+			InvokeMacro="IconImageSequenceMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="RTStructureSetDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="StructureSetLabel"					Type="1"
+		Name="StructureSetDate"						Type="2"
+		Name="StructureSetTime"						Type="2"
+MacroEnd
+
+DefineMacro="RTPlanDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="RTPlanLabel"							Type="1"
+		Name="RTPlanDate"							Type="2"
+		Name="RTPlanTime"							Type="2"
+MacroEnd
+
+DefineMacro="RTTreatmentRecordDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="TreatmentDate"						Type="2"
+		Name="TreatmentTime"						Type="2"
+MacroEnd
+
+DefineMacro="PresentationDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="PresentationCreationDate"				Type="1C"	Condition="DirectoryRecordTypeIsPresentation"
+		Name="PresentationCreationTime"				Type="1C"	Condition="DirectoryRecordTypeIsPresentation"
+		InvokeMacro="ContentIdentificationMacro"
+		Sequence="ReferencedSeriesSequence"			Type="1C"	VM="1-n"	Condition="BlendingSequenceIsNotPresent"				# condition is actually whether or not present in instance, but this is equivalent based on SOP Classes known
+			Name="SeriesInstanceUID"				Type="1"
+			Sequence="ReferencedImageSequence"		Type="1"	VM="1-n"
+				InvokeMacro="SOPInstanceReferenceMacro"
+			SequenceEnd
+		SequenceEnd
+		Sequence="BlendingSequence"					Type="1C"	VM="2"		Condition="ReferencedSeriesSequenceIsNotPresent"		# condition is actually whether or not present in instance, but this is equivalent based on SOP Classes known
+			Name="StudyInstanceUID"					Type="1"
+			Sequence="ReferencedSeriesSequence"		Type="1"	VM="1-n"
+				Name="SeriesInstanceUID"			Type="1"
+				Sequence="ReferencedImageSequence"	Type="1"	VM="1-n"
+					InvokeMacro="SOPInstanceReferenceMacro"
+				SequenceEnd
+			SequenceEnd
+		SequenceEnd
+MacroEnd
+
+DefineMacro="WaveformDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+MacroEnd
+
+DefineMacro="SRDocumentDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="CompletionFlag"						Type="1"
+		Name="VerificationFlag"						Type="1"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		Name="VerificationDateTime"					Type="1C"	Condition="VerificationFlagIsVerified"
+		Sequence="ConceptNameCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ContentSequence"					Type="1C"	VM="1-n"	NoCondition=""
+			Name="RelationshipType"					Type="1"	StringEnumValues="SRRelationshipTypeHasConceptModifier"
+			InvokeMacro="DocumentContentMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="KeyObjectDocumentDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="InstanceNumber"						Type="1"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		Sequence="ConceptNameCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ContentSequence"					Type="1C"	VM="1-n"	NoCondition=""
+			Name="RelationshipType"					Type="1"	StringEnumValues="SRRelationshipTypeHasConceptModifier"
+			InvokeMacro="DocumentContentMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="SpectroscopyDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ImageType"							Type="1"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		Name="InstanceNumber"						Type="1"
+		Sequence="ReferencedImageEvidenceSequence"	Type="1"	VM="1-n"	NoCondition=""
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="NumberOfFrames"						Type="1"
+		Name="Rows"									Type="1"
+		Name="Columns"								Type="1"
+		Name="DataPointRows"						Type="1"
+		Name="DataPointColumns"						Type="1"
+		Sequence="IconImageSequence"				Type="3"	VM="1"
+			InvokeMacro="IconImageSequenceMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="RawDataDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		Name="InstanceNumber"						Type="2"
+		Sequence="IconImageSequence"				Type="3"	VM="1"
+			InvokeMacro="IconImageSequenceMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="RegistrationDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		InvokeMacro="ContentIdentificationMacro"
+MacroEnd
+
+DefineMacro="FiducialDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		InvokeMacro="ContentIdentificationMacro"
+MacroEnd
+
+DefineMacro="HangingProtocolDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="HangingProtocolName"									Type="1"
+		Name="HangingProtocolDescription"							Type="1"
+		Name="HangingProtocolLevel"									Type="1"
+		Name="HangingProtocolCreator"								Type="1"
+		Name="HangingProtocolCreationDateTime"						Type="1"
+		Sequence="HangingProtocolDefinitionSequence"				Type="1"	VM="1-n"
+			Name="Modality"											Type="1C"	Condition="AnatomicRegionSequenceIsNotPresent" mbpo="true"
+			Sequence="AnatomicRegionSequence"						Type="1C"	VM="1-n"	Condition="ModalityIsNotPresent" mbpo="true"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+			Name="Laterality"										Type="2C"	Condition="AnatomicRegionSequenceIsPresent" mbpo="true"
+			Sequence="ProcedureCodeSequence"						Type="2"	VM="1-n"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+			Sequence="ReasonForRequestedProcedureCodeSequence"		Type="2"	VM="1-n"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+		SequenceEnd
+		Name="NumberOfPriorsReferenced"								Type="1"
+		Sequence="HangingProtocolUserIdentificationCodeSequence"	Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="EncapsulatedDocumentDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ContentDate"							Type="2"
+		Name="ContentTime"							Type="2"
+		Name="InstanceNumber"						Type="1"
+		Name="DocumentTitle"						Type="2"
+		Name="HL7InstanceIdentifier"				Type="1C"	Condition="ReferencedSOPClassUIDInFileIsEncapsulatedCDADocument"
+		Sequence="ConceptNameCodeSequence"			Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="MIMETypeOfEncapsulatedDocument"		Type="1"
+MacroEnd
+
+DefineMacro="HL7StructuredDocumentDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="HL7InstanceIdentifier"				Type="1"
+		Name="HL7DocumentEffectiveTime"				Type="1"
+		Sequence="HL7DocumentTypeCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+MacroEnd
+
+DefineMacro="RealWorldValueMappingDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		InvokeMacro="ContentIdentificationMacro"
+MacroEnd
+
+DefineMacro="StereometricRelationshipDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		InvokeMacro="ContentIdentificationMacro"
+MacroEnd
+
+DefineMacro="SurfaceDirectoryRecord"
+		Name="SpecificCharacterSet"					Type="1C"	NoCondition=""	StringDefinedTerms="SpecificCharacterSet"
+		Name="ContentDate"							Type="1"
+		Name="ContentTime"							Type="1"
+		InvokeMacro="ContentIdentificationMacro"
+MacroEnd
+
+Module="DirectoryInformationDental"
+	Sequence="DirectoryRecordSequence"				Type="2"	VM="0-n"
+		Name="ReferencedSOPClassUIDInFile"			Type="1C"	Condition="DirectorySOPInstance"	StringEnumValues="DentalMediaProfileSOPClasses"
+		Name="ReferencedTransferSyntaxUIDInFile"	Type="1C"	Condition="DirectorySOPInstance"	StringEnumValues="DentalMediaProfileTransferSyntaxes"
+	SequenceEnd
+ModuleEnd
+
diff --git a/libsrc/standard/module/mr.tpl b/libsrc/standard/module/mr.tpl
new file mode 100755
index 0000000..6196837
--- /dev/null
+++ b/libsrc/standard/module/mr.tpl
@@ -0,0 +1,610 @@
+DefineMacro="CommonCTMRImageDescriptionImageLevelMacro" InformationEntity="Image"
+	Name="PixelPresentation"						Type="1"	StringEnumValues="CommonCTMRPixelPresentationImageLevel"
+	Verify="PixelPresentation"									Condition="EnhancedMRColorImageInstance"	StringEnumValues="PixelPresentationTrueColor"
+	Name="VolumetricProperties"						Type="1"	StringEnumValues="CommonCTMRVolumetricPropertiesImageLevel"
+	Name="VolumeBasedCalculationTechnique"			Type="1"	StringDefinedTerms="CommonCTMRVolumeBasedCalculationTechniqueImageLevel"
+MacroEnd
+
+DefineMacro="CommonCTMRImageDescriptionFrameLevelMacro" InformationEntity="Image"
+	Name="PixelPresentation"						Type="1"	StringEnumValues="CommonCTMRPixelPresentationFrameLevel"
+	Name="VolumetricProperties"						Type="1"	StringEnumValues="CommonCTMRVolumetricPropertiesFrameLevel"
+	Name="VolumeBasedCalculationTechnique"			Type="1"	StringDefinedTerms="CommonCTMRVolumeBasedCalculationTechniqueFrameLevel"
+MacroEnd
+
+DefineMacro="MRImageDescriptionImageLevelMacro" InformationEntity="Image"
+	Name="ComplexImageComponent"			Type="1C"	StringEnumValues="EnhancedMRComplexImageComponentImageLevel"	Condition="NotLegacyConvertedMR" mbpo="true"
+	Name="AcquisitionContrast"				Type="1C"	StringEnumValues="EnhancedMRAcquisitionContrastImageLevel"		Condition="NotLegacyConvertedMR" mbpo="true"
+MacroEnd
+
+DefineMacro="MRImageDescriptionFrameLevelMacro" InformationEntity="Image"
+	Name="ComplexImageComponent"			Type="1C"	StringEnumValues="EnhancedMRComplexImageComponentFrameLevel"	Condition="NotLegacyConvertedMR" mbpo="true"
+	Name="AcquisitionContrast"				Type="1C"	StringEnumValues="EnhancedMRAcquisitionContrastFrameLevel"		Condition="NotLegacyConvertedMR" mbpo="true"
+MacroEnd
+
+DefineMacro="MRSpectroscopyDescriptionImageLevelMacro" InformationEntity="Image"
+	Name="VolumetricProperties"					Type="1"	StringEnumValues="CommonCTMRVolumetricPropertiesImageLevel"
+	Name="VolumeBasedCalculationTechnique"		Type="1"	StringDefinedTerms="MRSpectroscopyVolumeBasedCalculationTechniqueImageLevel"
+	Name="ComplexImageComponent"				Type="1"	StringEnumValues="MRSpectroscopyComplexImageComponentImageLevel"
+	Name="AcquisitionContrast"					Type="1"	StringEnumValues="MRSpectroscopyAcquisitionContrastImageLevel"
+MacroEnd
+
+DefineMacro="MRSpectroscopyDescriptionFrameLevelMacro" InformationEntity="Image"
+	Name="VolumetricProperties"					Type="1"	StringEnumValues="CommonCTMRVolumetricPropertiesFrameLevel"
+	Name="VolumeBasedCalculationTechnique"		Type="1"	StringDefinedTerms="MRSpectroscopyVolumeBasedCalculationTechniqueFrameLevel"
+	Name="ComplexImageComponent"				Type="1"	StringEnumValues="MRSpectroscopyComplexImageComponentFrameLevel"
+	Name="AcquisitionContrast"					Type="1"	StringEnumValues="MRSpectroscopyAcquisitionContrastFrameLevel"
+MacroEnd
+
+DefineMacro="MRImageFrameTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRImageFrameTypeSequence"			Type="1"	VM="1"
+		Name="FrameType"						Type="1"	VM="4"
+		Verify="FrameType"									ValueSelector="0"	StringEnumValues="CommonEnhancedFrameType1"
+		Verify="FrameType"									ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"									ValueSelector="2"	StringDefinedTerms="EnhancedMRImageAndFrameType3"
+		Verify="FrameType"									ValueSelector="3"	StringDefinedTerms="EnhancedMRFrameType4"
+		InvokeMacro="CommonCTMRImageDescriptionFrameLevelMacro"
+		InvokeMacro="MRImageDescriptionFrameLevelMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRTimingAndRelatedParametersMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRTimingAndRelatedParametersSequence"		Type="1"	VM="1"
+		Name="RepetitionTime"							Type="1C"	Condition="Always"	NotZeroWarning=""	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="FlipAngle"								Type="1C"	Condition="Always"	NotZeroWarning=""	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="EchoTrainLength"							Type="1C"	Condition="Always"	NotZeroWarning=""	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="RFEchoTrainLength"						Type="1C"	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="GradientEchoTrainLength"					Type="1C"	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Sequence="SpecificAbsorptionRateSequence"		Type="1C"	VM="1-n"	Condition="Always"	# real world
+			Name="SpecificAbsorptionRateDefinition"		Type="1"	StringDefinedTerms="SpecificAbsorptionRateDefinition"
+			Name="SpecificAbsorptionRateValue"			Type="1"
+		SequenceEnd
+		Name="GradientOutputType"						Type="1C"	StringDefinedTerms="GradientOutputType"	Condition="GradientOutputIsPresent"	# real world, but interconnect
+		Name="GradientOutput"							Type="1C"	Condition="GradientOutputTypeIsPresent"	# real world, but interconnect
+		Sequence="OperatingModeSequence"				Type="1C"	VM="1-n"	Condition="Always"	# real world
+			Name="OperatingModeType"					Type="1"	StringDefinedTerms="OperatingModeType"
+			Name="OperatingMode"						Type="1"	StringDefinedTerms="OperatingMode"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRFOVGeometryMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRFOVGeometrySequence"						Type="1"	VM="1"
+		Name="InPlanePhaseEncodingDirection"				Type="1C"	StringEnumValues="InplanePhaseEncodingDirection"	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="MRAcquisitionFrequencyEncodingSteps"			Type="1C"	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="MRAcquisitionPhaseEncodingStepsInPlane"		Type="1C"	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="MRAcquisitionPhaseEncodingStepsOutOfPlane"	Type="1C"	NoCondition=""		# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL and /MRAcquisitionType == 3D
+		Name="PercentSampling"								Type="1C"	Condition="Always"	NotZeroWarning=""	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="PercentPhaseFieldOfView"						Type="1C"	Condition="Always"	NotZeroWarning=""	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MREchoMacro" InformationEntity="FunctionalGroup"
+	Sequence="MREchoSequence"				Type="1"	VM="1"
+		Name="EffectiveEchoTime"			Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRModifierMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRModifierSequence"					Type="1"	VM="1"
+		Name="InversionRecovery"					Type="1C"	StringEnumValues="YesNoFull"			Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="InversionTimes"						Type="1C"							Condition="InversionRecoveryIsYes"	# also should check FrameType[0] :(
+		Name="FlowCompensation"						Type="1C"	StringDefinedTerms="FlowCompensation"		Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="FlowCompensationDirection"			Type="1C"	StringEnumValues="FlowCompensationDirection"	Condition="FlowCompensationNotNone"	# also should check FrameType[0] etc. :(
+		Name="Spoiling"								Type="1C"	StringEnumValues="Spoiling"			NoCondition=""	# EchoPulseSequenceGradientOrBoth (macro can't access root list), also should check FrameType[0] etc. :(
+		Name="T2Preparation"						Type="1C"	StringEnumValues="YesNoFull"			Condition="Always"	# should check FrameType[0] etc. :(
+		Name="SpectrallySelectedExcitation"			Type="1C"	StringEnumValues="SpectrallySelectedExcitation"	Condition="Always"	# should check FrameType[0] etc. :(
+		Name="SpatialPresaturation"					Type="1C"	StringEnumValues="SpatialPresaturation"		Condition="Always"	# should check FrameType[0] etc. :(
+		Name="PartialFourier"						Type="1C"	StringEnumValues="YesNoFull"			Condition="Always"	# should check FrameType[0] etc. :(
+		Name="PartialFourierDirection"				Type="1C"	StringEnumValues="PartialFourierDirection"	Condition="PartialFourierIsYes"	# should check FrameType[0] etc. :(
+		Name="ParallelAcquisition"					Type="1C"	StringEnumValues="YesNoFull"			Condition="Always"	# should check FrameType[0] etc. :(
+		Name="ParallelAcquisitionTechnique"			Type="1C"	StringEnumValues="ParallelAcquisitionTechnique"	Condition="ParallelAcquisitionIsYes"	# should check FrameType[0] etc. :(
+		Name="ParallelReductionFactorInPlane"		Type="1C"							Condition="ParallelAcquisitionIsYes"	# should check FrameType[0] etc. :(
+		Name="ParallelReductionFactorOutOfPlane"	Type="1C"							Condition="ParallelAcquisitionIsYes"	# should check FrameType[0] etc. :(
+		Name="ParallelReductionFactorSecondInPlane"	Type="1C"							Condition="ParallelAcquisitionIsYes"	# should check is spectroscopy instance and FrameType[0] etc. :(
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRImagingModifierMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRImagingModifierSequence"			Type="1"	VM="1"
+		Name="MagnetizationTransfer"				Type="1C"	StringEnumValues="MagnetizationTransfer"	Condition="Always"	# should check FrameType[0] etc. :(
+		Name="BloodSignalNulling"					Type="1C"	StringEnumValues="YesNoFull"			Condition="Always"	# should check FrameType[0] etc. :(
+		Name="Tagging"								Type="1C"	StringEnumValues="Tagging"			Condition="Always"	# should check FrameType[0] etc. :(
+		Name="TagSpacingFirstDimension"				Type="1C"	NotZeroWarning=""							Condition="TaggingIsGridOrLine"	# should check FrameType[0] etc. :(
+		Name="TagSpacingSecondDimension"			Type="1C"	NotZeroWarning=""							Condition="TaggingIsGrid"	# should check FrameType[0] etc. :(
+		Name="TagAngleFirstAxis"					Type="1C"							Condition="TaggingIsGridOrLine"	# should check FrameType[0] etc. :(
+		Name="TagAngleSecondAxis"					Type="1C"							Condition="TaggingIsGrid"	# should check FrameType[0] etc. :(
+		Name="TagThickness"							Type="1C"	NotZeroWarning=""							Condition="TaggingIsGridOrLine"	# should check FrameType[0] etc. :(
+		Name="TaggingDelay"							Type="3"
+		Name="TransmitterFrequency"					Type="1C"	NotZeroWarning=""							Condition="Always"	# should check FrameType[0] etc. :(
+		Name="PixelBandwidth"						Type="1C"	NotZeroWarning=""							Condition="Always"	# should check FrameType[0] etc. :(
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRReceiveCoilMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRReceiveCoilSequence"			Type="1"	VM="1"
+		Name="ReceiveCoilName"					Type="1"
+		Name="ReceiveCoilManufacturerName"		Type="2"
+		Name="ReceiveCoilType"					Type="1"	StringDefinedTerms="ReceiveCoilType"
+		Name="QuadratureReceiveCoil"			Type="1"	StringEnumValues="YesNoFull"
+		Sequence="MultiCoilDefinitionSequence"	Type="1C"	VM="1-n"					Condition="ReceiveCoilTypeIsMultiCoil"	# should check FrameType[0] etc. :(
+			Name="MultiCoilElementName"			Type="1"
+			Name="MultiCoilElementUsed"			Type="1"	StringEnumValues="YesNoFull"
+		SequenceEnd
+		Name="MultiCoilConfiguration"			Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRTransmitCoilMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRTransmitCoilSequence"			Type="1"	VM="1"
+		Name="TransmitCoilName"					Type="1"
+		Name="TransmitCoilManufacturerName"		Type="2"
+		Name="TransmitCoilType"					Type="1"	StringDefinedTerms="TransmitCoilType"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRDiffusionMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRDiffusionSequence"						Type="1"	VM="1"
+		Name="DiffusionBValue"							Type="1C"	NoCondition=""	# should check FrameType[0] etc. :(
+		Name="DiffusionDirectionality"					Type="1C"	StringDefinedTerms="DiffusionDirectionality"	Condition="Always"	# should check FrameType[0] etc. :(
+		Sequence="DiffusionGradientDirectionSequence"	Type="1C"	VM="1"				Condition="DiffusionDirectionalityIsDirectional" mbpo="true" # really should check if DiffusionDirectionality is BMATRIX
+			Name="DiffusionGradientOrientation"			Type="1"
+		SequenceEnd
+		Sequence="DiffusionBMatrixSequence"				Type="1C"	VM="1"				Condition="DiffusionDirectionalityIsBMatrix"
+			Name="DiffusionBValueXX"					Type="1"
+			Name="DiffusionBValueXY"					Type="1"
+			Name="DiffusionBValueXZ"					Type="1"
+			Name="DiffusionBValueYY"					Type="1"
+			Name="DiffusionBValueYZ"					Type="1"
+			Name="DiffusionBValueZZ"					Type="1"
+		SequenceEnd
+		Name="DiffusionAnisotropyType"					Type="1C"	Condition="NeedDiffusionAnisotropyType"	StringDefinedTerms="DiffusionAnisotropyType" mbpo="true" # really shouldn't have mbpo, but account for inadequate condition using ImageType rather than 9current) FraneType
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRAveragesMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRAveragesSequence"				Type="1"	VM="1"
+		Name="NumberOfAverages"					Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRSpatialSaturationMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRSpatialSaturationSequence"			Type="2"	VM="0-n"
+		Name="SlabThickness"						Type="1"	NotZeroWarning=""
+		Name="SlabOrientation"						Type="1"
+		Name="MidSlabPosition"						Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRMetaboliteMapMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRMetaboliteMapSequence"							Type="1"	VM="1"
+		Name="MetaboliteMapDescription"							Type="1"
+		Sequence="MetaboliteMapCodeSequence"					Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ChemicalShiftSequence"						Type="3"	VM="1-n"
+			Name="ChemicalShiftMinimumIntegrationLimitInppm"	Type="1"
+			Name="ChemicalShiftMaximumIntegrationLimitInppm"	Type="1"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRVelocityEncodingMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRVelocityEncodingSequence"		Type="1"	VM="1-n"
+		Name="VelocityEncodingDirection"		Type="1"
+		Name="VelocityEncodingMinimumValue"		Type="1"
+		Name="VelocityEncodingMaximumValue"		Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRArterialSpinLabelingMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRArterialSpinLabelingSequence"	Type="1"	VM="1-n"
+		Name="ASLTechniqueDescription"			Type="2"
+		Name="ASLContext"						Type="1C"	NoCondition="" mbpo="true" StringEnumValues="ASLContext"	# FrameType is ORIGINAL too hard :(
+		Sequence="ASLSlabSequence"				Type="1C"	VM="1-n" Condition="ASLContextIsControlLOrLabel" mbpo="true"
+			Name="ASLSlabNumber"				Type="1"
+			InvokeMacro="GeneralAnatomyOptionalMacro"
+			Name="ASLSlabThickness"				Type="1"
+			Name="ASLSlabOrientation"			Type="1"
+			Name="ASLMidSlabPosition"			Type="1"
+			Name="ASLPulseTrainDuration"		Type="1"
+		SequenceEnd
+		Name="ASLCrusherFlag"					Type="1"	StringEnumValues="YesNoFull"
+		Name="ASLCrusherFlowLimit"				Type="1C"	Condition="ASLCrusherFlagIsYes"
+		Name="ASLCrusherDescription"			Type="1C"	Condition="ASLCrusherFlagIsYes"
+		Name="ASLBolusCutoffFlag"				Type="1"	StringEnumValues="YesNoFull"
+		Sequence="ASLBolusCutoffTimingSequence"	Type="1C"	VM="1" Condition="ASLBolusCutoffFlagIsYes"
+			Name="ASLBolusCutoffDelayTime"		Type="1"
+			Name="ASLBolusCutoffTechnique"		Type="2"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRImageAndSpectroscopyInstanceMacro" InformationEntity="Image"
+	Name="AcquisitionNumber"						Type="3"
+	Name="AcquisitionDateTime"						Type="1C"	Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedMR" mbpo="true"
+	Name="AcquisitionDuration"						Type="1C"	Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedMR" mbpo="true"
+	Sequence="ReferencedRawDataSequence"			Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedWaveformSequence"			Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedImageEvidenceSequence"		Type="1C"	VM="1-n"	Condition="ReferencedImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="SourceImageEvidenceSequence"			Type="1C"	VM="1-n"	Condition="SourceImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedPresentationStateSequence"	Type="1C"	VM="1-n"	NoCondition=""	# real world
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="ContentQualification"						Type="1C"	StringEnumValues="ContentQualification"	Condition="NotLegacyConvertedMR" mbpo="true"
+	Name="ResonantNucleus"							Type="1C"	StringDefinedTerms="ResonantNucleus"	Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedMR" mbpo="true"
+	Name="KSpaceFiltering"							Type="1C"	StringDefinedTerms="KSpaceFiltering"	Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedMR" mbpo="true"
+	Name="MagneticFieldStrength"					Type="1C"	NotZeroWarning=""						Condition="ImageTypeValue1OriginalOrMixedAndNotLegacyConvertedMR" mbpo="true"
+	Name="ApplicableSafetyStandardAgency"			Type="1C"	StringDefinedTerms="ApplicableSafetyStandardAgency"	Condition="NotLegacyConvertedMR" mbpo="true"
+	Name="ApplicableSafetyStandardDescription"		Type="3"
+	Name="ImageComments"				Type="3"
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForEnhancedMRImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRImageFrameTypeMacro"		Condition="MRImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRTimingAndRelatedParametersMacro"	Condition="NeedMRTimingAndRelatedParametersMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRFOVGeometryMacro"		Condition="NeedMRFOVGeometryMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MREchoMacro"			Condition="NeedMREchoMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRModifierMacro"			Condition="NeedMRModifierMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRImagingModifierMacro"		Condition="NeedMRImagingModifierMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRReceiveCoilMacro"		Condition="NeedMRReceiveCoilMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRTransmitCoilMacro"		Condition="NeedMRTransmitCoilMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRDiffusionMacro"			Condition="NeedMRDiffusionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRAveragesMacro"			Condition="NeedMRAveragesMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRSpatialSaturationMacro"		Condition="NeedMRSpatialSaturationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRMetaboliteMapMacro"		Condition="NeedMRMetaboliteMapMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRVelocityEncodingMacro"		Condition="NeedMRVelocityEncodingMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRArterialSpinLabelingMacro"		Condition="NeedMRArterialSpinLabelingMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequenceAndPhotometricInterpretationIsMonochrome2"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRImageFrameTypeMacro"		Condition="MRImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="MRTimingAndRelatedParametersMacro"	Condition="NeedMRTimingAndRelatedParametersMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRFOVGeometryMacro"		Condition="NeedMRFOVGeometryMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MREchoMacro"			Condition="NeedMREchoMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRModifierMacro"			Condition="NeedMRModifierMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRImagingModifierMacro"		Condition="NeedMRImagingModifierMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRReceiveCoilMacro"		Condition="NeedMRReceiveCoilMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRTransmitCoilMacro"		Condition="NeedMRTransmitCoilMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRDiffusionMacro"			Condition="NeedMRDiffusionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRAveragesMacro"			Condition="NeedMRAveragesMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRSpatialSaturationMacro"		Condition="NeedMRSpatialSaturationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRMetaboliteMapMacro"		Condition="NeedMRMetaboliteMapMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRVelocityEncodingMacro"		Condition="NeedMRVelocityEncodingMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRArterialSpinLabelingMacro"		Condition="NeedMRArterialSpinLabelingMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="MRSpectroscopyFrameTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRSpectroscopyFrameTypeSequence"	Type="1"	VM="1"
+		Name="FrameType"						Type="1"	VM="4"
+		Verify="FrameType"								ValueSelector="0"	StringEnumValues="CommonEnhancedFrameType1"
+		Verify="FrameType"								ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"								ValueSelector="2"	StringDefinedTerms="EnhancedMRSpectroscopyImageAndFrameType3"
+		Verify="FrameType"								ValueSelector="3"	StringDefinedTerms="EnhancedMRSpectroscopyFrameType4"
+		InvokeMacro="MRSpectroscopyDescriptionFrameLevelMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="MRSpectroscopyFOVGeometryMacro" InformationEntity="FunctionalGroup"
+	Sequence="MRSpectroscopyFOVGeometrySequence"			Type="1"	VM="1"
+		Name="SpectroscopyAcquisitionDataColumns"			Type="1C"	NotZeroWarning=""	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="SpectroscopyAcquisitionPhaseRows"				Type="1C"	NotZeroWarning=""	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="SpectroscopyAcquisitionPhaseColumns"			Type="1C"	NotZeroWarning=""	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="SpectroscopyAcquisitionOutOfPlanePhaseSteps"	Type="1C"	NotZeroWarning=""	NoCondition=""		# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL and /MRSpectroscopyAcquisitionType == PLANE
+		Name="PercentSampling"								Type="1C"	NotZeroWarning=""	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="PercentPhaseFieldOfView"						Type="1C"	NotZeroWarning=""	Condition="Always"	# ../MRImageFrameTypeMacro/FrameType[0] == ORIGINAL
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForMRSpectroscopy"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRSpectroscopyFrameTypeMacro"	Condition="MRSpectroscopyFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRTimingAndRelatedParametersMacro"	Condition="NeedMRTimingAndRelatedParametersMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRSpectroscopyFOVGeometryMacro"	Condition="NeedMRSpectroscopyFOVGeometryMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MREchoMacro"			Condition="NeedMREchoMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRModifierMacro"			Condition="NeedMRModifierMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRReceiveCoilMacro"		Condition="NeedMRReceiveCoilMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRTransmitCoilMacro"		Condition="NeedMRTransmitCoilMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRDiffusionMacro"			Condition="NeedMRDiffusionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRAveragesMacro"			Condition="NeedMRAveragesMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRSpatialSaturationMacro"		Condition="NeedMRSpatialSaturationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="MRVelocityEncodingMacro"		Condition="NeedMRVelocityEncodingMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRSpectroscopyFrameTypeMacro"	Condition="MRSpectroscopyFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="MRTimingAndRelatedParametersMacro"	Condition="NeedMRTimingAndRelatedParametersMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRSpectroscopyFOVGeometryMacro"	Condition="NeedMRSpectroscopyFOVGeometryMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MREchoMacro"			Condition="NeedMREchoMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRModifierMacro"			Condition="NeedMRModifierMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRReceiveCoilMacro"		Condition="NeedMRReceiveCoilMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRTransmitCoilMacro"		Condition="NeedMRTransmitCoilMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRDiffusionMacro"			Condition="NeedMRDiffusionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRAveragesMacro"			Condition="NeedMRAveragesMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRSpatialSaturationMacro"		Condition="NeedMRSpatialSaturationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRVelocityEncodingMacro"		Condition="NeedMRVelocityEncodingMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedMRImage"
+	InvokeMacro="MRImageAndSpectroscopyInstanceMacro"
+	Name="ImageType"								Type="1"	VM="4"
+	Verify="ImageType"											ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"											ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"											ValueSelector="2"	StringDefinedTerms="EnhancedMRImageAndFrameType3"
+	Verify="ImageType"											ValueSelector="3"	StringDefinedTerms="EnhancedMRImageType4"
+	InvokeMacro="CommonCTMRImageDescriptionImageLevelMacro"
+	InvokeMacro="MRImageDescriptionImageLevelMacro"
+
+	Name="SamplesPerPixel"							Type="1"
+	Verify="SamplesPerPixel"									Condition="PhotometricInterpretationIsMonochrome"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Verify="SamplesPerPixel"									Condition="PhotometricInterpretationIsColor"		BinaryEnumValues="SamplesPerPixelIsThree"
+
+	Name="PhotometricInterpretation"				Type="1"
+	Verify="PhotometricInterpretation"							Condition="EnhancedMRImageInstance"      StringEnumValues="PhotometricInterpretationMonochrome2"
+	Verify="PhotometricInterpretation"							Condition="EnhancedMRColorImageInstance" StringEnumValues="PhotometricInterpretationRGBorYBR_FULL_422orYBR_RCTorYBR_ICTorYBR_PARTIAL_420"
+
+	Name="BitsAllocated"							Type="1"	
+	Verify="BitsAllocated"										Condition="PhotometricInterpretationIsMonochrome"	BinaryEnumValues="BitsAre8Or16"
+	Verify="BitsAllocated"										Condition="PhotometricInterpretationIsColor"		BinaryEnumValues="BitsAre8"
+
+	Name="BitsStored"								Type="1"
+	Verify="BitsStored"											Condition="PhotometricInterpretationIsMonochrome"	BinaryEnumValues="BitsAre8Or12Or16"
+	Verify="BitsStored"											Condition="PhotometricInterpretationIsColor"		BinaryEnumValues="BitsAre8"
+
+	Name="HighBit"									Type="1"
+	Verify="HighBit"											Condition="PhotometricInterpretationIsMonochrome"	BinaryEnumValues="BitsAre7Or11Or15"
+	Verify="HighBit"											Condition="PhotometricInterpretationIsColor"		BinaryEnumValues="BitsAre7"
+
+	Name="PixelRepresentation"						Type="1"
+	Verify="PixelRepresentation"								Condition="PhotometricInterpretationIsMonochrome"	BinaryEnumValues="PixelRepresentation"
+	Verify="PixelRepresentation"								Condition="PhotometricInterpretationIsColor"		BinaryEnumValues="PixelRepresentationUnsigned"
+
+	Name="PlanarConfiguration"						Type="1C"	Condition="SamplesPerPixelGreaterThanOne"	BinaryEnumValues="PlanarConfigurationIsColorByPixel"
+	
+	Name="BurnedInAnnotation"						Type="1C"	Condition="NotLegacyConvertedMR"	StringEnumValues="NoFull"	mbpo="true"
+	Name="RecognizableVisualFeatures"				Type="3"	StringEnumValues="YesNoFull"
+	Name="LossyImageCompression"					Type="1C"	Condition="NotLegacyConvertedMR"	StringEnumValues="LossyImageCompression"	mbpo="true"
+	Name="LossyImageCompressionRatio"				Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"				Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="PresentationLUTShape"						Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Sequence="IconImageSequence"					Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+ModuleEnd
+
+Module="MRPulseSequence"
+	Name="PulseSequenceName"				Type="1C"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="MRAcquisitionType"				Type="1C"	StringDefinedTerms="EnhancedMRAcquisitionType"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="EchoPulseSequence"				Type="1C"	StringEnumValues="EchoPulseSequence"			Condition="ImageTypeValue1OriginalOrMixed"
+	Name="MultipleSpinEcho"					Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixedAndEchoPulseSequenceNotGradient"
+	Name="MultiPlanarExcitation"			Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="PhaseContrast"					Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Sequence="VelocityEncodingAcquisitionSequence"		Type="1C"	VM="1-n"	Condition="PhaseContrastIsYes"
+		Name="VelocityEncodingDirection"				Type="1"
+	SequenceEnd
+	Name="TimeOfFlightContrast"				Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="ArterialSpinLabelingContrast"		Type="1C"	StringEnumValues="ArterialSpinLabelingContrast"				Condition="ImageTypeValue3ASL"
+	Name="SteadyStatePulseSequence"			Type="1C"	StringDefinedTerms="SteadyStatePulseSequence"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="EchoPlanarPulseSequence"			Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="SaturationRecovery"				Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="SpectrallySelectedSuppression"	Type="1C"	StringDefinedTerms="SpectrallySelectedSuppression"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="OversamplingPhase"				Type="1C"	StringEnumValues="OversamplingPhase"			Condition="ImageTypeValue1OriginalOrMixed"
+	Name="GeometryOfKSpaceTraversal"		Type="1C"	StringDefinedTerms="GeometryOfKSpaceTraversal"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="RectilinearPhaseEncodeReordering"	Type="1C"	StringDefinedTerms="RectilinearPhaseEncodeReordering"	Condition="ImageTypeValue1OriginalOrMixedAndRectilinear"
+	Name="SegmentedKSpaceTraversal"			Type="1C"	StringEnumValues="SegmentedKSpaceTraversal"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="CoverageOfKSpace"					Type="1C"	StringDefinedTerms="CoverageOfKSpace"			Condition="ImageTypeValue1OriginalOrMixedAnd3D"
+	Name="NumberOfKSpaceTrajectories"		Type="1C"	Condition="ImageTypeValue1OriginalOrMixed"
+ModuleEnd
+
+Module="MRSpectroscopy"
+	InvokeMacro="MRImageAndSpectroscopyInstanceMacro"
+	Name="ImageType"						Type="1"	VM="4"
+	Verify="ImageType"									ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"									ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"									ValueSelector="2"	StringDefinedTerms="EnhancedMRSpectroscopyImageAndFrameType3"
+	Verify="ImageType"									ValueSelector="3"	StringDefinedTerms="EnhancedMRSpectroscopyImageType4"
+	InvokeMacro="MRSpectroscopyDescriptionImageLevelMacro"
+	Name="TransmitterFrequency"				Type="1C"	Condition="ImageTypeValue1Original"
+	Name="SpectralWidth"					Type="1C"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="ChemicalShiftReference"			Type="1C"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="VolumeLocalizationTechnique"		Type="1C"	StringDefinedTerms="VolumeLocalizationTechnique"	Condition="ImageTypeValue1OriginalOrMixed"
+	Sequence="VolumeLocalizationSequence"	Type="1C"	VM="1-n"	Condition="VolumeLocalizationTechniqueNotNone"
+		Name="SlabThickness"				Type="1"
+		Name="SlabOrientation"				Type="1"
+		Name="MidSlabPosition"				Type="1"
+	SequenceEnd
+	Name="Decoupling"						Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="DecoupledNucleus"					Type="1C"	StringDefinedTerms="DecoupledNucleus"			Condition="DecouplingIsYes"
+	Name="DecouplingFrequency"				Type="1C"								Condition="DecouplingIsYes"
+	Name="DecouplingMethod"					Type="1C"	StringDefinedTerms="DecouplingMethod"			Condition="DecouplingIsYes"
+	Name="DecouplingChemicalShiftReference"	Type="1C"								Condition="DecouplingIsYes"
+	Name="TimeDomainFiltering"				Type="1C"	StringDefinedTerms="TimeDomainFiltering"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="NumberOfZeroFills"				Type="1C"								Condition="ImageTypeValue1OriginalOrMixed"
+	Name="BaselineCorrection"				Type="1C"	StringDefinedTerms="BaselineCorrection"			Condition="ImageTypeValue1OriginalOrMixed"
+	Name="FrequencyCorrection"				Type="1C"	StringDefinedTerms="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="FirstOrderPhaseCorrection"		Type="1C"	StringDefinedTerms="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="WaterReferencedPhaseCorrection"	Type="1C"	StringDefinedTerms="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+ModuleEnd
+
+Module="MRSpectroscopyPulseSequence"
+	Name="PulseSequenceName"				Type="1C"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="MRSpectroscopyAcquisitionType"	Type="1C"	StringDefinedTerms="MRSpectroscopyAcquisitionType"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="EchoPulseSequence"				Type="1C"	StringEnumValues="EchoPulseSequence"			Condition="ImageTypeValue1OriginalOrMixed"
+	Name="MultipleSpinEcho"					Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixedAndEchoPulseSequenceNotGradient"
+	Name="MultiPlanarExcitation"			Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="SteadyStatePulseSequence"			Type="1C"	StringDefinedTerms="SteadyStatePulseSequence"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="EchoPlanarPulseSequence"			Type="1C"	StringEnumValues="YesNoFull"				Condition="ImageTypeValue1OriginalOrMixed"
+	Name="SpectrallySelectedSuppression"	Type="1C"	StringDefinedTerms="SpectrallySelectedSuppression"	Condition="ImageTypeValue1OriginalOrMixed"
+	Name="GeometryOfKSpaceTraversal"		Type="1C"	StringDefinedTerms="GeometryOfKSpaceTraversal"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="RectilinearPhaseEncodeReordering"	Type="1C"	StringDefinedTerms="RectilinearPhaseEncodeReordering"	Condition="ImageTypeValue1OriginalOrMixedAndRectilinear"
+	Name="SegmentedKSpaceTraversal"			Type="1C"	StringEnumValues="SegmentedKSpaceTraversal"		Condition="ImageTypeValue1OriginalOrMixed"
+	Name="CoverageOfKSpace"					Type="1C"	StringDefinedTerms="CoverageOfKSpace"	Condition="ImageTypeValue1OriginalOrMixedAndSpectroscopyVolume"
+	Name="NumberOfKSpaceTrajectories"		Type="1C"	Condition="ImageTypeValue1OriginalOrMixed"
+ModuleEnd
+
+Module="MRSpectroscopyData"
+	Name="Rows"								Type="1"	NotZeroError=""
+	Name="Columns"							Type="1"	NotZeroError=""
+	Name="DataPointRows"					Type="1"	NotZeroError=""
+	Name="DataPointColumns"					Type="1"	NotZeroError=""
+	Name="DataRepresentation"				Type="1"	StringEnumValues="MRSpectroscopyDataRepresentation"
+	Name="SignalDomainColumns"				Type="1"	StringEnumValues="SpectroscopySignalDomain"
+	Name="SignalDomainRows"					Type="1C"	StringEnumValues="SpectroscopySignalDomain"	Condition="DataPointRowsGreaterThanOne"
+	Name="FirstOrderPhaseCorrectionAngle"	Type="1C"							Condition="FirstOrderPhaseCorrectionIsYes"
+	Name="SpectroscopyData"					Type="1"
+ModuleEnd
+
+Module="RawData"
+	Name="InstanceNumber"							Type="2"
+	Name="ContentDate"								Type="1"
+	Name="ContentTime"								Type="1"
+	Name="AcquisitionDateTime"						Type="3"
+	Name="CreatorVersionUID"						Type="1"
+	Sequence="ReferencedInstanceSequence"			Type="3"	VM="1-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="MRSeries"
+	Name="Modality"										Type="1"	StringEnumValues="MRModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+
+Module="MultiFrameFunctionalGroupsForLegacyConvertedEnhancedMRImage"
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="MRImageFrameTypeMacro"					Condition="MRImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="UnassignedSharedConvertedAttributesMacro"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRImageFrameTypeMacro"					Condition="MRImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="UnassignedPerFrameConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"
+	SequenceEnd
+ModuleEnd
+
+
+Module="MultiFrameFunctionalGroupsForPrivatePixelMedLegacyConvertedEnhancedMRImage"
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="MRImageFrameTypeMacro"					Condition="MRImageFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="UnassignedSharedConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"				Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="MRImageFrameTypeMacro"					Condition="MRImageFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="UnassignedPerFrameConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+
+
diff --git a/libsrc/standard/module/pet.tpl b/libsrc/standard/module/pet.tpl
new file mode 100755
index 0000000..a478288
--- /dev/null
+++ b/libsrc/standard/module/pet.tpl
@@ -0,0 +1,437 @@
+Module="PETSeries"
+	Name="SeriesDate"									Type="1"
+	Name="SeriesTime"									Type="1"
+	Name="Units"										Type="1"	StringDefinedTerms="PETUnits"
+	Name="SUVType"										Type="3"	StringEnumValues="SUVType"
+	Name="CountsSource"									Type="1"	StringEnumValues="CountsSource"
+	Name="SeriesType"									Type="1"	ValueSelector="0"	StringEnumValues="PETSeriesType1"
+	Verify="SeriesType"									Type="1"	ValueSelector="1"	StringEnumValues="PETSeriesType2"
+	Name="ReprojectionMethod"							Type="2C"	Condition="PETSeriesType2Reprojection"	StringDefinedTerms="ReprojectionMethod"
+	Name="NumberOfRRIntervals"							Type="1C"	Condition="PETSeriesType1Gated"
+	Name="NumberOfTimeSlots"							Type="1C"	Condition="PETSeriesType1Gated"
+	Name="NumberOfTimeSlices"							Type="1C"	Condition="PETSeriesType1Dynamic"
+	Name="NumberOfSlices"								Type="1"
+	Name="CorrectedImage"								Type="2"	StringDefinedTerms="CorrectedImage"
+	Name="RandomsCorrectionMethod"						Type="3"	StringDefinedTerms="RandomsCorrectionMethod"
+	Name="AttenuationCorrectionMethod"					Type="3"
+	Name="ScatterCorrectionMethod"						Type="3"
+	Name="DecayCorrection"								Type="1"	StringDefinedTerms="DecayCorrection"
+	Name="ReconstructionDiameter"						Type="3"	NotZeroWarning=""
+	Name="ConvolutionKernel"							Type="3"
+	Name="ReconstructionMethod"							Type="3"
+	Name="DetectorLinesOfResponseUsed"					Type="3"
+	Name="AcquisitionStartCondition"					Type="3"	StringDefinedTerms="AcquisitionStartCondition"
+	Name="AcquisitionStartConditionData"				Type="3"
+	Name="AcquisitionTerminationCondition"				Type="3"	StringDefinedTerms="PETAcquisitionTerminationCondition"
+	Name="AcquisitionTerminationConditionData"			Type="3"
+	Name="FieldOfViewShape"								Type="3"	StringDefinedTerms="PETFieldOfViewShape"
+	Name="FieldOfViewDimensions"						Type="3"	NotZeroWarning=""
+	Name="GantryDetectorTilt"							Type="3"
+	Name="GantryDetectorSlew"							Type="3"
+	Name="TypeOfDetectorMotion"							Type="3"	StringDefinedTerms="TypeOfDetectorMotion"
+	Name="CollimatorType"								Type="2"	StringDefinedTerms="PETCollimatorType"
+	Name="CollimatorGridName"							Type="3"
+	Name="AxialAcceptance"								Type="3"
+	Name="AxialMash"									Type="3"
+	Name="TransverseMash"								Type="3"
+	Name="DetectorElementSize"							Type="3"	NotZeroError=""
+	Name="CoincidenceWindowWidth"						Type="3"
+	Sequence="EnergyWindowRangeSequence"				Type="3"	VM="1-n"
+		Name="EnergyWindowLowerLimit"					Type="3"
+		Name="EnergyWindowUpperLimit"					Type="3"
+	SequenceEnd
+	Name="SecondaryCountsType"							Type="3"	StringDefinedTerms="SecondaryCountsType"
+ModuleEnd
+
+Module="PETIsotope"
+	Sequence="RadiopharmaceuticalInformationSequence"	Type="2"	VM="0-n"
+		Sequence="RadionuclideCodeSequence"				Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="4020"
+		SequenceEnd
+		Name="RadiopharmaceuticalRoute"					Type="3"
+		Sequence="AdministrationRouteCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="11"
+		SequenceEnd
+		Name="RadiopharmaceuticalVolume"				Type="3"
+		Name="RadiopharmaceuticalStartTime"				Type="3"
+		Name="RadiopharmaceuticalStartDateTime"			Type="3"
+		Name="RadiopharmaceuticalStopTime"				Type="3"
+		Name="RadiopharmaceuticalStopDateTime"			Type="3"
+		Name="RadionuclideTotalDose"					Type="3"
+		Name="RadionuclideHalfLife"						Type="3"
+		Name="RadionuclidePositronFraction"				Type="3"
+		Name="RadiopharmaceuticalSpecificActivity"		Type="3"
+		Name="Radiopharmaceutical"						Type="3"
+		Sequence="RadiopharmaceuticalCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="4021"
+		SequenceEnd
+	SequenceEnd
+	Sequence="InterventionDrugInformationSequence"		Type="3"	VM="1-n"
+		Name="InterventionDrugName"						Type="3"
+		Sequence="InterventionDrugCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="10"
+		SequenceEnd
+		Name="InterventionDrugStartTime"				Type="3"
+		Name="InterventionDrugStopTime"					Type="3"
+		Name="InterventionDrugDose"						Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="PETMultigatedAcquisition"
+	Name="BeatRejectionFlag"							Type="2"	StringEnumValues="YesNoLetter"
+	Name="TriggerSourceOrType"							Type="3"	StringDefinedTerms="EKG"
+	Name="PVCRejection"									Type="3"
+	Name="SkipBeats"									Type="3"
+	Name="HeartRate"									Type="3"
+	Name="CardiacFramingType"							Type="3"	StringDefinedTerms="CardiacFramingType"
+ModuleEnd
+
+Module="PETImage"
+	Name="ImageType"									Type="1"	ValueSelector="0"	StringEnumValues="ImageType1"
+	Verify="ImageType"									Type="1"	ValueSelector="1"	StringEnumValues="PETImageTypeValue2"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre16"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre15"
+	Name="RescaleIntercept"								Type="1"	BinaryEnumValues="Zero"
+	Name="RescaleSlope"									Type="1"	NotZeroError=""
+	Name="FrameReferenceTime"							Type="1"
+	Name="TriggerTime"									Type="1C"	Condition="PETSeriesType1Gated"
+	Name="FrameTime"									Type="1C"	Condition="PETSeriesType1Gated"
+	Name="LowRRValue"									Type="1C"	Condition="PETSeriesType1GatedAndBeatRejection"
+	Name="HighRRValue"									Type="1C"	Condition="PETSeriesType1GatedAndBeatRejection"
+	Name="LossyImageCompression"						Type="1C"	NoCondition=""	StringEnumValues="LossyImageCompression"
+	Name="ImageIndex"									Type="1"
+	Name="AcquisitionDate"								Type="2"
+	Name="AcquisitionTime"								Type="2"
+	Name="ActualFrameDuration"							Type="2"
+	Name="NominalInterval"								Type="3"
+	Name="IntervalsAcquired"							Type="3"
+	Name="IntervalsRejected"							Type="3"
+	Name="PrimaryPromptsCountsAccumulated"				Type="3"
+	Name="SecondaryCountsAccumulated"					Type="3"
+	Name="SliceSensitivityFactor"						Type="3"
+	Name="DecayFactor"									Type="1C"	Condition="DecayCorrectionNotNone"
+	Name="DoseCalibrationFactor"						Type="3"
+	Name="ScatterFractionFactor"						Type="3"
+	Name="DeadTimeFactor"								Type="3"
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	InvokeMacro="OptionalViewAndSliceProgressionDirectionMacro"
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForEnhancedPETImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RadiopharmaceuticalUsageMacro"		Condition="RadiopharmaceuticalUsageSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PatientPhysiologicalStateMacro"	Condition="NeedPatientPhysiologicalStateMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PETFrameTypeMacro"		Condition="PETFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETFrameAcquisitionMacro"	Condition="NeedPETFrameAcquisitionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PETDetectorMotionDetailsMacro"	Condition="NeedPETDetectorMotionDetailsMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PETPositionMacro"	Condition="NeedPETPositionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PETFrameCorrectionFactorsMacro"	Condition="NeedPETFrameCorrectionFactorsMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PETReconstructionMacro"	Condition="NeedPETReconstructionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PETTableDynamicsMacro"	Condition="NeedPETTableDynamicsMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RadiopharmaceuticalUsageMacro"		Condition="RadiopharmaceuticalUsageSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PatientPhysiologicalStateMacro"	Condition="NeedPatientPhysiologicalStateMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETFrameTypeMacro"		Condition="PETFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PETFrameAcquisitionMacro"	Condition="NeedPETFrameAcquisitionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETDetectorMotionDetailsMacro"	Condition="NeedPETDetectorMotionDetailsMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETPositionMacro"	Condition="NeedPETPositionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETFrameCorrectionFactorsMacro"	Condition="NeedPETFrameCorrectionFactorsMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETReconstructionMacro"	Condition="NeedPETReconstructionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETTableDynamicsMacro"	Condition="NeedPETTableDynamicsMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForLegacyConvertedEnhancedPETImage"
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PETFrameTypeMacro"						Condition="PETFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="UnassignedSharedConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETFrameTypeMacro"						Condition="PETFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="UnassignedPerFrameConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForPrivatePixelMedLegacyConvertedEnhancedPETImage"
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PETFrameTypeMacro"						Condition="PETFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="UnassignedSharedConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"					Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"					Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"					Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"					Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"					Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"			Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"						Condition="FrameAnatomyMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"			Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"						Condition="FrameVOILUTMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"			Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"	Condition="IrradiationEventIdentificationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PETFrameTypeMacro"						Condition="PETFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="UnassignedPerFrameConvertedAttributesMacro"
+		InvokeMacro="ImageFrameConversionSourceMacro"		Condition="ConversionSourceAttributesSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="PETFrameTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETFrameTypeSequence"	Type="1"	VM="1"
+		Name="FrameType"						Type="1"	VM="4"
+		Verify="FrameType"									ValueSelector="0"	StringEnumValues="CommonEnhancedFrameType1"
+		Verify="FrameType"									ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"									ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3"
+		Verify="FrameType"									ValueSelector="3"	StringDefinedTerms="CommonEnhancedFrameType4"
+		InvokeMacro="CommonCTMRImageDescriptionFrameLevelMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PETFrameAcquisitionMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETFrameAcquisitionSequence"		Type="1"	VM="1"
+		Name="TableHeight"						Type="1"	NotZeroWarning=""
+		Name="GantryDetectorTilt"				Type="1"
+		Name="GantryDetectorSlew"				Type="1"
+		Name="DataCollectionDiameter"			Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PETDetectorMotionDetailsMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETDetectorMotionDetailsSequence"	Type="1"	VM="1"
+		Name="RotationDirection"				Type="1"	StringEnumValues="RotationDirection"
+		Name="RevolutionTime"					Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PETPositionMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETPositionSequence"					Type="1"	VM="1"
+		Name="TablePosition"						Type="1C"	Condition="Always"	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="DataCollectionCenterPatient"			Type="1C"	Condition="Always"	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="ReconstructionTargetCenterPatient"	Type="1C"	Condition="Always"	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PETFrameCorrectionFactorsMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETFrameCorrectionFactorsSequence"	Type="1"	VM="1"
+		Name="PrimaryPromptsCountsAccumulated"		Type="1C"	Condition="Always"				NotZeroWarning=""	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="SliceSensitivityFactor"				Type="1C"	Condition="Always"				NotZeroWarning=""	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="DecayFactor"							Type="1C"	Condition="IsDecayCorrected"	NotZeroWarning=""	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="ScatterFractionFactor"				Type="1C"	Condition="Always"									# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="DeadTimeFactor"						Type="1C"	Condition="Always"				NotZeroWarning=""	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PETReconstructionMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETReconstructionSequence"			Type="1"	VM="1"
+		Name="ReconstructionType"					Type="1C"	Condition="Always"	StringDefinedTerms="PETReconstructionType"		# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="ReconstructionAlgorithm"				Type="1C"	Condition="Always"	StringDefinedTerms="PETReconstructionAlgorithm"	# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="IterativeReconstructionMethod"		Type="1"						StringEnumValues="YesNoFull"
+		Name="NumberOfIterations"					Type="1C"	Condition="IsIterativeReconstruction"		NotZeroWarning=""		# && ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="NumberOfSubsets"						Type="1C"	Condition="IsIterativeReconstruction"		NotZeroWarning=""		# && ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="ReconstructionDiameter"				Type="1C"	Condition="ReconstructionFieldOfViewAbsent"	NotZeroWarning=""		# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+		Name="ReconstructionFieldOfView"			Type="1C"	Condition="ReconstructionDiameterAbsent"	NotZeroWarning=""		# ../PETFrameTypeMacro/FrameType[0] == ORIGINAL
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PETTableDynamicsMacro" InformationEntity="FunctionalGroup"
+	Sequence="PETTableDynamicsSequence"				Type="1"	VM="1"
+		Name="TableSpeed"							Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+Module="EnhancedPETSeries"
+	Name="Modality"										Type="1"	StringEnumValues="PETModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="RelatedSeriesSequence"					Type="1C"	VM="1-n"	NoCondition=""
+		Name="StudyInstanceUID"							Type="1"
+		Name="SeriesInstanceUID"						Type="1"
+		Sequence="PurposeOfReferenceCodeSequence"		Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"				BaselineContextID="7210"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedPETIsotope"
+	Sequence="RadiopharmaceuticalInformationSequence"	Type="1"	VM="1-n"
+		Name="RadiopharmaceuticalAgentNumber"			Type="1"
+		Sequence="RadionuclideCodeSequence"				Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="4020"
+		SequenceEnd
+		Sequence="AdministrationRouteCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="11"
+		SequenceEnd
+		Name="RadiopharmaceuticalVolume"				Type="3"	NotZeroWarning=""
+		Name="RadiopharmaceuticalStartDateTime"			Type="1"
+		Name="RadiopharmaceuticalStopDateTime"			Type="3"
+		Name="RadionuclideTotalDose"					Type="2"	NotZeroWarning=""
+		Name="RadionuclideHalfLife"						Type="1"	NotZeroWarning=""
+		Name="RadionuclidePositronFraction"				Type="1"	NotZeroWarning=""
+		Name="RadiopharmaceuticalSpecificActivity"		Type="3"	NotZeroWarning=""
+		Sequence="RadiopharmaceuticalCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="4021"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedPETAcquisition"
+	Name="AcquisitionStartCondition"					Type="1C"	Condition="ImageTypeValue1Original" mbpo="true" StringDefinedTerms="EnhancedPETAcquisitionStartCondition"
+	Name="StartDensityThreshold"						Type="1C"	Condition="AcquisitionStartConditionDENS"
+	Name="StartRelativeDensityDifferenceThreshold"		Type="1C"	Condition="AcquisitionStartConditionRDD"
+	Name="StartCardiacTriggerCountThreshold"			Type="1C"	Condition="AcquisitionStartConditionCARD_TRIG"
+	Name="StartRespiratoryTriggerCountThreshold"		Type="1C"	Condition="AcquisitionStartConditionRESP_TRIG"
+	Name="AcquisitionTerminationCondition"				Type="1C"	Condition="ImageTypeValue1Original" mbpo="true" StringDefinedTerms="EnhancedPETAcquisitionTerminationCondition"
+	Name="TerminationCountsThreshold"					Type="1C"	Condition="AcquisitionTerminationConditionCNTS"
+	Name="TerminationDensityThreshold"					Type="1C"	Condition="AcquisitionTerminationConditionDENS"
+	Name="TerminationRelativeDensityThreshold"			Type="1C"	Condition="AcquisitionTerminationConditionRDD"
+	Name="TerminationTimeThreshold"						Type="1C"	Condition="AcquisitionTerminationConditionTIME"
+	Name="TerminationCardiacTriggerCountThreshold"		Type="1C"	Condition="AcquisitionTerminationConditionCARD_TRIG"
+	Name="TerminationRespiratoryTriggerCountThreshold"	Type="1C"	Condition="AcquisitionTerminationConditionRESP_TRIG"
+	Name="TypeOfDetectorMotion"							Type="1C"	Condition="ImageTypeValue1Original" mbpo="true" StringDefinedTerms="EnhancedPETTypeOfDetectorMotion"
+	Name="DetectorGeometry"								Type="1C"	Condition="OriginalAndTypeOfDetectorMotionIsStationary" mbpo="true" StringDefinedTerms="DetectorGeometry"
+	Verify="DetectorGeometry"										Condition="DetectorGeometryPresentAndTypeOfDetectorMotionIsNotStationary"	ThenErrorMessage="may only be present when TypeOfDetectorMotion is STATIONARY " ShowValueWithMessage="false"
+	Name="TransverseDetectorSeparation"					Type="1C"	Condition="ImageTypeValue1Original" mbpo="true"
+	Name="AxialDetectorDimension"						Type="1C"	Condition="ImageTypeValue1Original" mbpo="true"
+	Name="CollimatorType"								Type="1C"	Condition="ImageTypeValue1Original" mbpo="true" StringDefinedTerms="PETCollimatorType"
+	Name="CoincidenceWindowWidth"						Type="1C"	Condition="ImageTypeValue1Original" mbpo="true"
+	Sequence="EnergyWindowRangeSequence"				Type="1C"	VM="1-n"	Condition="ImageTypeValue1Original" mbpo="true"
+		Name="EnergyWindowLowerLimit"					Type="1"
+		Name="EnergyWindowUpperLimit"					Type="1"
+	SequenceEnd
+	Name="TableMotion"									Type="1"	StringEnumValues="TableMotion"
+	Name="TimeOfFlightInformationUsed"					Type="1"	StringEnumValues="TrueFalseFull"
+	InvokeMacro="MandatoryViewAndSliceProgressionDirectionMacro"
+ModuleEnd
+
+Module="EnhancedPETImage"
+	Name="ImageType"									Type="1"	VM="4"
+	Verify="ImageType"											ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"											ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"											ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3"
+	Verify="ImageType"											ValueSelector="3"	StringDefinedTerms="CommonEnhancedImageType4"
+	InvokeMacro="CommonCTMRImageDescriptionImageLevelMacro"
+	Name="AcquisitionNumber"							Type="3"
+	Name="AcquisitionDateTime"							Type="1C"	Condition="ImageTypeValue1OriginalAndNotLegacyConvertedPET" mbpo="true"
+	Name="AcquisitionDuration"							Type="1C"	Condition="ImageTypeValue1OriginalAndNotLegacyConvertedPET" mbpo="true"
+	Sequence="ReferencedRawDataSequence"				Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedWaveformSequence"				Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedImageEvidenceSequence"			Type="1C"	VM="1-n"	Condition="ReferencedImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="SourceImageEvidenceSequence"				Type="1C"	VM="1-n"	Condition="SourceImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="SamplesPerPixel"							Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"							Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"								Type="1"	BinaryEnumValues="BitsAre16"
+	Name="HighBit"									Type="1"	BinaryEnumValues="BitsAre15"
+	Name="ContentQualification"						Type="1"	StringEnumValues="ContentQualification"
+	Name="ImageComments"							Type="3"
+	Name="BurnedInAnnotation"						Type="1C"	StringEnumValues="NoFull"	Condition="NotLegacyConvertedPET" mbpo="true"
+	Name="RecognizableVisualFeatures"				Type="3"	StringEnumValues="YesNoFull"
+	Name="LossyImageCompression"					Type="1C"	StringEnumValues="LossyImageCompression"	Condition="NotLegacyConvertedPET" mbpo="true"
+	Name="LossyImageCompressionRatio"				Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"				Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"						Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="PresentationLUTShape"						Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Sequence="IconImageSequence"					Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedPETCorrections"
+	Name="CountsSource"									Type="1"	StringEnumValues="CountsSource"
+	Name="DecayCorrected"								Type="1"	StringEnumValues="YesNoFull"
+	Name="AttenuationCorrected"							Type="1"	StringEnumValues="YesNoFull"
+	Name="ScatterCorrected"								Type="1"	StringEnumValues="YesNoFull"
+	Name="DeadTimeCorrected"							Type="1"	StringEnumValues="YesNoFull"
+	Name="GantryMotionCorrected"						Type="1"	StringEnumValues="YesNoFull"
+	Name="PatientMotionCorrected"						Type="1"	StringEnumValues="YesNoFull"
+	Name="CountLossNormalizationCorrected"				Type="1"	StringEnumValues="YesNoFull"
+	Name="RandomsCorrected"								Type="1"	StringEnumValues="YesNoFull"
+	Name="NonUniformRadialSamplingCorrected"			Type="1"	StringEnumValues="YesNoFull"
+	Name="SensitivityCalibrated"						Type="1"	StringEnumValues="YesNoFull"
+	Name="DetectorNormalizationCorrection"				Type="1"	StringEnumValues="YesNoFull"
+	Name="RandomsCorrectionMethod"						Type="1C"	Condition="IsRandomsCorrected"	StringDefinedTerms="RandomsCorrectionMethodEnhanced"
+	Name="AttenuationCorrectionSource"					Type="1C"	Condition="IsAttenuationCorrected"	StringDefinedTerms="AttenuationCorrectionSource"
+	Name="AttenuationCorrectionTemporalRelationship"	Type="1C"	Condition="IsAttenuationCorrected"	StringDefinedTerms="AttenuationCorrectionTemporalRelationship"
+	Name="ScatterCorrectionMethod"						Type="1C"	Condition="IsScatterCorrected"
+	Name="DecayCorrectionDateTime"						Type="1C"	Condition="IsDecayCorrected"
+ModuleEnd
+
diff --git a/libsrc/standard/module/rt.tpl b/libsrc/standard/module/rt.tpl
new file mode 100755
index 0000000..d072be4
--- /dev/null
+++ b/libsrc/standard/module/rt.tpl
@@ -0,0 +1,1464 @@
+DefineMacro="BeamLimitingDevicePositionMacro"
+	Sequence="BeamLimitingDevicePositionSequence"				Type="1C"	VM="1-n"	NoCondition=""
+		Name="RTBeamLimitingDeviceType"							Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+		Name="LeafJawPositions"									Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PatientSupportIdentificationMacro"
+	Name="PatientSupportType"									Type="1"	StringDefinedTerms="PatientSupportType"
+	Name="PatientSupportID"										Type="3"
+	Name="PatientSupportAccessoryCode"							Type="3"
+MacroEnd
+
+Module="RTSeries"
+	Name="Modality"										Type="1"	StringEnumValues="RTModality"
+	Name="SeriesInstanceUID"							Type="1"
+	Name="SeriesNumber"									Type="2"
+	Name="SeriesDescription"							Type="3"
+	Name="SeriesDate"									Type="3"
+	Name="SeriesTime"									Type="3"
+	Sequence="SeriesDescriptionCodeSequence"			Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="OperatorsName"								Type="2"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="RequestAttributesSequence"				Type="3"	VM="1-n"
+		InvokeMacro="RequestAttributesMacro"
+	SequenceEnd
+	InvokeMacro="PerformedProcedureStepSummaryMacro"
+ModuleEnd
+
+Module="RTImage"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre8Or12To16"	#should real be 8 if BitsAllocated is 8 and 12 to 16 if BitsAllocated is 16
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre7Or11To15"	#should real be one less than BitsStored
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="PixelIntensityRelationship"					Type="1"	StringEnumValues="DXPixelIntensityRelationship"
+	Name="PixelIntensityRelationshipSign"				Type="1"	BinaryEnumValues="PixelIntensityRelationshipSign"
+	Name="RTImageLabel"									Type="1"
+	Name="RTImageName"									Type="3"
+	Name="RTImageDescription"							Type="3"
+	Name="ImageType"									Type="1"	ValueSelector="2"	StringDefinedTerms="RTImageTypeValue3"
+	Verify="ImageType"									Condition="ImageTypeValue3MissingOrEmpty"	ThenErrorMessage="A value is required for value 3 in RT Images"
+	Name="ConversionType"								Type="2"	StringDefinedTerms="ConversionType"
+	Name="ReportedValuesOrigin"							Type="2C"	Condition="ImageTypeValue3SimulatorOrPortal"	StringEnumValues="ReportedValuesOrigin"
+	Name="RTImagePlane"									Type="1"	StringEnumValues="RTImagePlane"
+	Name="XRayImageReceptorAngle"						Type="2"
+	Name="RTImageOrientation"							Type="2C"	Condition="RTImagePlaneIsNonNormal" mbpo="true"
+	Name="ImagePlanePixelSpacing"						Type="2"
+	Name="RTImagePosition"								Type="2"
+	Name="RadiationMachineName"							Type="2"
+	Name="PrimaryDosimeterUnit"							Type="2"	StringEnumValues="PrimaryDosimeterUnit"
+	Name="RadiationMachineSAD"							Type="2"
+	Name="RadiationMachineSSD"							Type="3"
+	Name="RTImageSID"									Type="2"
+	Name="SourceToReferenceObjectDistance"				Type="3"
+	Sequence="ReferencedRTPlanSequence"					Type="3"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="ReferencedBeamNumber"							Type="3"
+	Name="ReferencedFractionGroupNumber"				Type="3"
+	Name="FractionNumber"								Type="3"
+	Name="StartCumulativeMetersetWeight"				Type="3"
+	Name="EndCumulativeMetersetWeight"					Type="3"
+	Sequence="ExposureSequence"							Type="3"	VM="1-n"
+		Name="ReferencedFrameNumber"					Type="1C"	Condition="NeedExposureSequenceReferencedFrameNumber"	NotZeroError=""
+		Name="KVP"										Type="2C"	Condition="ImageTypeValue3SimulatorOrPortalOrRadiograph"
+		Sequence="PrimaryFluenceModeSequence"			Type="3"	VM="1"
+			Name="FluenceMode"							Type="1"	StringEnumValues="FluenceMode"
+			Name="FluenceModeID"						Type="1C"	Condition="FluenceModeIsNonStandard"
+		SequenceEnd
+		Name="XRayTubeCurrent"							Type="2C"	Condition="ImageTypeValue3SimulatorOrRadiograph"
+		Name="XRayTubeCurrentInmA"						Type="3"
+		Name="ExposureTime"								Type="2C"	Condition="ImageTypeValue3SimulatorOrRadiograph"
+		Name="ExposureTimeInms"							Type="3"
+		Name="MetersetExposure"							Type="2C"	Condition="ImageTypeValue3Portal"
+		Name="DiaphragmPosition"						Type="3"
+		Sequence="BeamLimitingDeviceSequence"			Type="3"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"				Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="SourceToBeamLimitingDeviceDistance"	Type="3"
+			Name="NumberOfLeafJawPairs"					Type="1"
+			Name="LeafPositionBoundaries"				Type="2C"	Condition="RTBeamLimitingDeviceTypeMLCXOrMLCY" mbpo="true"
+			Name="LeafJawPositions"						Type="1"
+		SequenceEnd
+		Sequence="ApplicatorSequence"					Type="3"	VM="1"
+			Name="ApplicatorID"							Type="1"
+			Name="ApplicatorType"						Type="1"	StringDefinedTerms="ApplicatorType"
+			Name="ApplicatorDescription"				Type="3"
+		SequenceEnd
+		Sequence="GeneralAccessorySequence"				Type="3"	VM="1-n"
+			Name="GeneralAccessoryNumber"				Type="1"
+			Name="GeneralAccessoryID"					Type="1"
+			Name="GeneralAccessoryDescription"			Type="3"
+			Name="GeneralAccessoryType"					Type="3"	StringDefinedTerms="RTGeneralAccessoryType"
+			Name="AccessoryCode"						Type="3"
+			Name="SourceToGeneralAccessoryDistance"		Type="3"
+		SequenceEnd
+		Name="NumberOfBlocks"							Type="1"
+		Sequence="BlockSequence"						Type="2C"	VM="0-n"	Condition="NumberOfBlocksNotZero"
+			Name="BlockTrayID"							Type="3"
+			Name="SourceToBlockTrayDistance"			Type="2"
+			Name="BlockType"							Type="1"	StringEnumValues="BlockType"
+			Name="BlockDivergence"						Type="2"	StringEnumValues="BlockDivergence"
+			Name="BlockMountingPosition"				Type="3"	StringEnumValues="BlockMountingPosition"
+			Name="BlockNumber"							Type="1"
+			Name="BlockName"							Type="3"
+			Name="MaterialID"							Type="2"
+			Name="BlockThickness"						Type="3"
+			Name="BlockNumberOfPoints"					Type="2"
+			Name="BlockData"							Type="2"
+		SequenceEnd
+	SequenceEnd
+	Sequence="FluenceMapSequence"						Type="1C"	VM="1"	Condition="ImageTypeValue3Fluence"
+		Name="FluenceDataSource"						Type="1"	StringEnumValues="FluenceDataSource"
+		Name="FluenceDataScale"							Type="3"
+	SequenceEnd
+	Name="GantryAngle"									Type="3"
+	Name="GantryPitchAngle"								Type="3"
+	Name="BeamLimitingDeviceAngle"						Type="3"
+	Name="PatientSupportAngle"							Type="3"
+	Name="TableTopEccentricAxisDistance"				Type="3"
+	Name="TableTopEccentricAngle"						Type="3"
+	Name="TableTopPitchAngle"							Type="3"
+	Name="TableTopRollAngle"							Type="3"
+	Name="TableTopVerticalPosition"						Type="3"
+	Name="TableTopLongitudinalPosition"					Type="3"
+	Name="TableTopLateralPosition"						Type="3"
+	Name="IsocenterPosition"							Type="3"
+	Name="PatientPosition"								Type="1C"	Condition="IsocenterPositionIsPresent"
+ModuleEnd
+
+Module="RTDose"
+	Name="SamplesPerPixel"										Type="1C"	Condition="PixelDataPresent"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"							Type="1C"	Condition="PixelDataPresent"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"										Type="1C"	Condition="PixelDataPresent"	BinaryEnumValues="BitsAre16Or32"
+	Name="BitsStored"											Type="1C"	Condition="PixelDataPresent"	BinaryEnumValues="BitsAre16Or32"	#should real be same as BitsAllocated
+	Name="HighBit"												Type="1C"	Condition="PixelDataPresent"	BinaryEnumValues="BitsAre15Or31"	#should real be one less than BitsStored
+	Name="PixelRepresentation"									Type="1C"	Condition="PixelDataPresent"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="DoseUnits"											Type="1"	StringEnumValues="DoseUnits"
+	Name="DoseType"												Type="1"	StringDefinedTerms="DoseType"
+	Name="SpatialTransformOfDose"								Type="3"	StringDefinedTerms="SpatialTransformOfDose"
+	Sequence="ReferencedSpatialRegistrationSequence"			Type="2C"	VM="0-n"		Condition="SpatialTransformOfDoseIsRigidOrNonRigid"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="InstanceNumber"										Type="3"
+	Name="DoseComment"											Type="3"
+	Name="NormalizationPoint"									Type="3"
+	Name="DoseSummationType"									Type="1"	StringDefinedTerms="DoseSummationType"
+	Sequence="ReferencedRTPlanSequence"							Type="1C"	VM="1-n"		Condition="NeedReferencedRTPlanSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="ReferencedFractionGroupSequence"				Type="1C"	VM="1"		Condition="NeedReferencedFractionGroupSequence"
+			Name="ReferencedFractionGroupNumber"				Type="1"
+			Sequence="ReferencedBeamSequence"					Type="1C"	VM="1-n"	Condition="NeedReferencedBeamSequence"
+				Name="ReferencedBeamNumber"						Type="1"
+				Sequence="ReferencedControlPointSequence"		Type="1C"	VM="1"		Condition="DoseSummationTypeControlPoint"
+					Name="ReferencedStartControlPointIndex"		Type="1"
+					Name="ReferencedStopControlPointIndex"		Type="1"
+				SequenceEnd
+			SequenceEnd
+			Sequence="ReferencedBrachyApplicationSetupSequence"	Type="1C"	VM="1-n"	Condition="NeedReferencedBrachyApplicationSetupSequence"
+				Name="ReferencedBrachyApplicationSetupNumber"	Type="1"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	Verify="ReferencedRTPlanSequence"										Condition="DoseSummationTypeIsNotMultiPlanAndReferencedRTPlanSequenceHasMultipleItems"	ThenErrorMessage="Multiple items not permitted unless DoseSummationType is MULTI_PLAN"
+	Verify="ReferencedRTPlanSequence"										Condition="DoseSummationTypeIsMultiPlanAndReferencedRTPlanSequenceHasLessThanTwoItems"	ThenErrorMessage="Two or more items required if DoseSummationType is MULTI_PLAN"
+	Name="GridFrameOffsetVector"								Type="1C"	Condition="NeedGridFrameOffsetVector"
+	Name="DoseGridScaling"										Type="1C"	Condition="PixelDataPresent"
+	Name="TissueHeterogeneityCorrection"						Type="3"	StringEnumValues="TissueHeterogeneityCorrection"
+ModuleEnd
+
+Module="RTDVH"
+	Sequence="ReferencedStructureSetSequence"					Type="1"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="DVHNormalizationPoint"								Type="3"
+	Name="DVHNormalizationDoseValue"							Type="3"
+	Sequence="DVHSequence"										Type="1"	VM="1-n"
+		Sequence="DVHReferencedROISequence"						Type="1"	VM="1-n"
+			Name="ReferencedROINumber"							Type="1"
+			Name="DVHROIContributionType"						Type="1"	StringEnumValues="DVHROIContributionType"
+		SequenceEnd
+		Name="DVHType"											Type="1"	StringEnumValues="DVHType"
+		Name="DoseUnits"										Type="1"	StringEnumValues="DVHDoseUnits"
+		Name="DoseType"											Type="1"	StringDefinedTerms="DVHDoseType"
+		Name="DVHDoseScaling"									Type="1"
+		Name="DVHVolumeUnits"									Type="1"	StringDefinedTerms="DVHVolumeUnits"
+		Name="DVHNumberOfBins"									Type="1"
+		Name="DVHData"											Type="1"
+		Name="DVHMinimumDose"									Type="3"
+		Name="DVHMaximumDose"									Type="3"
+		Name="DVHMeanDose"										Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="StructureSet"
+	Name="StructureSetLabel"									Type="1"
+	Name="StructureSetName"										Type="3"
+	Name="StructureSetDescription"								Type="3"
+	Name="InstanceNumber"										Type="3"
+	Name="StructureSetDate"										Type="2"
+	Name="StructureSetTime"										Type="2"
+	Sequence="ReferencedFrameOfReferenceSequence"				Type="3"	VM="1-n"
+		Name="FrameOfReferenceUID"								Type="1"
+		Sequence="FrameOfReferenceRelationshipSequence"			Type="3"	VM="1-n"
+			Name="RelatedFrameOfReferenceUID"					Type="1"
+			Name="FrameOfReferenceTransformationType"			Type="1"	StringDefinedTerms="TransformationType"
+			Name="FrameOfReferenceTransformationMatrix"			Type="1"
+			Name="FrameOfReferenceTransformationComment"		Type="3"
+		SequenceEnd
+		Sequence="RTReferencedStudySequence"					Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Sequence="RTReferencedSeriesSequence"				Type="1"	VM="1-n"
+				Name="SeriesInstanceUID"						Type="1"
+				Sequence="ContourImageSequence"					Type="1"	VM="1-n"
+					InvokeMacro="ImageSOPInstanceReferenceMacro"
+				SequenceEnd
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	Sequence="StructureSetROISequence"							Type="1"	VM="1-n"
+		Name="ROINumber"										Type="1"
+		Name="ReferencedFrameOfReferenceUID"					Type="1"
+		Name="ROIName"											Type="2"
+		Name="ROIDescription"									Type="3"
+		Name="ROIVolume"										Type="3"
+		Name="ROIGenerationAlgorithm"							Type="2"	StringDefinedTerms="ROIGenerationAlgorithm"
+		Name="ROIGenerationDescription"							Type="3"
+	SequenceEnd
+	Sequence="PredecessorStructureSetSequence"					Type="3"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="ROIContour"
+	Sequence="ROIContourSequence"								Type="1"	VM="1-n"
+		Name="ReferencedROINumber"								Type="1"
+		Name="ROIDisplayColor"									Type="3"
+		Sequence="ContourSequence"								Type="3"	VM="1-n"
+			Name="ContourNumber"								Type="3"
+			Name="AttachedContours"								Type="3"
+			Sequence="ContourImageSequence"						Type="3"	VM="1-n"
+				InvokeMacro="ImageSOPInstanceReferenceMacro"
+			SequenceEnd
+			Name="ContourGeometricType"							Type="1"	StringEnumValues="ContourGeometricType"
+			Name="ContourSlabThickness"							Type="3"
+			Name="ContourOffsetVector"							Type="3"
+			Name="NumberOfContourPoints"						Type="1"
+			Name="ContourData"									Type="1"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTDoseROI"
+	Sequence="RTDoseROISequence"								Type="1"	VM="1-n"
+		Name="ReferencedROINumber"								Type="1"
+		Name="DoseUnits"										Type="1"	StringEnumValues="DoseUnits"
+		Name="DoseValue"										Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="RTROIObservations"
+	Sequence="RTROIObservationsSequence"						Type="1"	VM="1-n"
+		Name="ObservationNumber"								Type="1"
+		Name="ReferencedROINumber"								Type="1"
+		Name="ROIObservationLabel"								Type="3"
+		Name="ROIObservationDescription"						Type="3"
+		Sequence="RTRelatedROISequence"							Type="3"	VM="1-n"
+			Name="ReferencedROINumber"							Type="1"
+			Name="RTROIRelationship"							Type="3"	StringDefinedTerms="RTROIRelationship"
+		SequenceEnd
+		Sequence="RTROIIdentificationCodeSequence"				Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="RelatedRTROIObservationsSequence"				Type="3"	VM="1-n"
+			Name="ObservationNumber"							Type="1"
+		SequenceEnd
+		Name="RTROIInterpretedType"								Type="2"	StringDefinedTerms="RTROIInterpretedType"
+		Name="ROIInterpreter"									Type="2"
+		Name="MaterialID"										Type="3"
+		Sequence="ROIPhysicalPropertiesSequence"				Type="3"	VM="1-n"
+			Name="ROIPhysicalProperty"							Type="1"	StringDefinedTerms="ROIPhysicalProperty"
+			Sequence="ROIElementalCompositionSequence"				Type="1C"	VM="1-n"	Condition="ROIPhysicalPropertyIsElemFraction"
+				Name="ROIElementalCompositionAtomicNumber"			Type="1"
+				Name="ROIElementalCompositionAtomicMassFraction"	Type="1"
+			SequenceEnd
+			Name="ROIPhysicalPropertyValue"						Type="1"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTGeneralPlan"
+	Name="RTPlanLabel"											Type="1"
+	Name="RTPlanName"											Type="3"
+	Name="RTPlanDescription"									Type="3"
+	Name="InstanceNumber"										Type="3"
+	Name="RTPlanDate"											Type="2"
+	Name="RTPlanTime"											Type="2"
+	Name="TreatmentProtocols"									Type="3"
+	Name="PlanIntent"											Type="3"	StringDefinedTerms="PlanIntent"
+	Name="TreatmentSites"										Type="3"
+	Name="RTPlanGeometry"										Type="1"	StringDefinedTerms="RTPlanGeometry"
+	Sequence="ReferencedStructureSetSequence"					Type="1C"	VM="1"	Condition="RTPlanGeometryIsPatient"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedDoseSequence"							Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedRTPlanSequence"							Type="3"`	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Name="RTPlanRelationship"								Type="1"	StringDefinedTerms="RTPlanRelationship"
+		Verify="RTPlanRelationship"											Condition="PlanIntentIsVerification" StringDefinedTerms="RTPlanRelationshipVerifiedPlan"
+	SequenceEnd
+ModuleEnd
+
+Module="RTPrescription"
+	Name="PrescriptionDescription"								Type="3"
+	Sequence="DoseReferenceSequence"							Type="3"	VM="1-n"
+		Name="DoseReferenceNumber"								Type="1"
+		Name="DoseReferenceUID"									Type="3"
+		Name="DoseReferenceStructureType"						Type="1"	StringDefinedTerms="DoseReferenceStructureType"
+		Name="DoseReferenceDescription"							Type="3"
+		Name="ReferencedROINumber"								Type="1C"	Condition="DoseReferenceStructureTypePointOrVolume"
+		Name="DoseReferencePointCoordinates"					Type="1C"	Condition="DoseReferenceStructureTypeCoordinates"
+		Name="NominalPriorDose"									Type="3"
+		Name="DoseReferenceType"								Type="1"	StringDefinedTerms="DoseReferenceType"
+		Name="ConstraintWeight"									Type="3"
+		Name="DeliveryWarningDose"								Type="3"
+		Name="DeliveryMaximumDose"								Type="3"
+		Name="TargetMinimumDose"								Type="3"
+		Name="TargetPrescriptionDose"							Type="3"
+		Name="TargetMaximumDose"								Type="3"
+		Name="TargetUnderdoseVolumeFraction"					Type="3"
+		Name="OrganAtRiskFullVolumeDose"						Type="3"
+		Name="OrganAtRiskLimitDose"								Type="3"
+		Name="OrganAtRiskMaximumDose"							Type="3"
+		Name="OrganAtRiskOverdoseVolumeFraction"				Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="RTToleranceTables"
+	Sequence="ToleranceTableSequence"							Type="3"	VM="1-n"
+		Name="ToleranceTableNumber"								Type="1"
+		Name="ToleranceTableLabel"								Type="3"
+		Name="GantryAngleTolerance"								Type="3"
+		Name="GantryPitchAngleTolerance"						Type="3"
+		Name="BeamLimitingDeviceAngleTolerance"					Type="3"
+		Sequence="BeamLimitingDeviceToleranceSequence"			Type="3"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"						Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="BeamLimitingDevicePositionTolerance"			Type="1"
+		SequenceEnd
+		Name="PatientSupportAngleTolerance"						Type="3"
+		Name="TableTopEccentricAngleTolerance"					Type="3"
+		Name="TableTopPitchAngleTolerance"						Type="3"
+		Name="TableTopRollAngleTolerance"						Type="3"
+		Name="TableTopVerticalPositionTolerance"				Type="3"
+		Name="TableTopLongitudinalPositionTolerance"			Type="3"
+		Name="TableTopLateralPositionTolerance"					Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="RTPatientSetup"
+	Sequence="PatientSetupSequence"								Type="1"	VM="1-n"
+		Name="PatientSetupNumber"								Type="1"
+		Name="PatientSetupLabel"								Type="3"
+		Name="PatientPosition"									Type="1C"	Condition="PatientAdditionalPositionNotPresent"		StringDefinedTerms="RTPatientPosition"
+		Name="PatientAdditionalPosition"						Type="1C"	Condition="PatientPositionNotPresent"
+		Sequence="ReferencedSetupImageSequence"					Type="3"	VM="1-n"
+			Name="SetupImageComment"							Type="3"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="FixationDeviceSequence"						Type="3"	VM="1-n"
+			Name="FixationDeviceType"							Type="1"	StringDefinedTerms="FixationDeviceType"
+			Name="FixationDeviceLabel"							Type="2"
+			Name="FixationDeviceDescription"					Type="3"
+			Name="FixationDevicePosition"						Type="3"
+			Name="FixationDevicePitchAngle"						Type="3"
+			Name="FixationDeviceRollAngle"						Type="3"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Sequence="ShieldingDeviceSequence"						Type="3"	VM="1-n"
+			Name="ShieldingDeviceType"							Type="1"	StringDefinedTerms="ShieldingDeviceType"
+			Name="ShieldingDeviceLabel"							Type="2"
+			Name="ShieldingDeviceDescription"					Type="3"
+			Name="ShieldingDevicePosition"						Type="3"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="SetupTechnique"									Type="3"	StringDefinedTerms="SetupTechnique"
+		Name="SetupTechniqueDescription"						Type="3"
+		Sequence="SetupDeviceSequence"							Type="3"	VM="1-n"
+			Name="SetupDeviceType"								Type="1"	StringDefinedTerms="SetupDeviceType"
+			Name="SetupDeviceLabel"								Type="2"
+			Name="SetupDeviceDescription"						Type="3"
+			Name="SetupDeviceParameter"							Type="2"
+			Name="SetupReferenceDescription"					Type="3"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="TableTopVerticalSetupDisplacement"				Type="3"
+		Name="TableTopLongitudinalSetupDisplacement"			Type="3"
+		Name="TableTopLateralSetupDisplacement"					Type="3"
+		Sequence="MotionSynchronizationSequence"				Type="3"	VM="1-n"
+			Name="RespiratoryMotionCompensationTechnique"		Type="1"	StringDefinedTerms="RTRespiratoryMotionCompensationTechnique"
+			Name="RespiratorySignalSource"						Type="1"	StringDefinedTerms="RTRespiratorySignalSource"
+			Name="RespiratoryMotionCompensationTechniqueDescription"	Type="3"
+			Name="RespiratorySignalSourceID"					Type="3"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTFractionScheme"
+	Sequence="FractionGroupSequence"							Type="1"	VM="1-n"
+		Name="FractionGroupNumber"								Type="1"
+		Name="FractionGroupDescription"							Type="3"
+		Sequence="ReferencedDoseSequence"						Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="ReferencedDoseReferenceSequence"				Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1"
+			Name="ConstraintWeight"								Type="3"
+			Name="DeliveryWarningDose"							Type="3"
+			Name="DeliveryMaximumDose"							Type="3"
+			Name="TargetMinimumDose"							Type="3"
+			Name="TargetPrescriptionDose"						Type="3"
+			Name="TargetMaximumDose"							Type="3"
+			Name="TargetUnderdoseVolumeFraction"				Type="3"
+			Name="OrganAtRiskFullVolumeDose"					Type="3"
+			Name="OrganAtRiskLimitDose"							Type="3"
+			Name="OrganAtRiskMaximumDose"						Type="3"
+			Name="OrganAtRiskOverdoseVolumeFraction"			Type="3"
+		SequenceEnd
+		Name="NumberOfFractionsPlanned"							Type="2"
+		Name="NumberOfFractionPatternDigitsPerDay"				Type="3"
+		Name="RepeatFractionCycleLength"						Type="3"
+		Name="FractionPattern"									Type="3"
+		Name="BeamDoseMeaning"									Type="3"	StringEnumValues="BeamDoseMeaning"
+		Name="NumberOfBeams"									Type="1"
+		Sequence="ReferencedBeamSequence"						Type="1C"	VM="1-n"	Condition="NumberOfBeamsNotZero"
+			Name="ReferencedBeamNumber"							Type="1"
+			Name="BeamDoseSpecificationPoint"					Type="3"
+			Name="BeamDose"										Type="3"
+			Sequence="BeamDoseVerificationControlPointSequence"	Type="3"	VM="2-n"
+				Name="CumulativeMetersetWeight"					Type="1"
+				Name="ReferencedControlPointIndex"				Type="1C"	NoCondition=""		# Required if the Referenced Cumulative Meterset corresponds to a Control Point in the Control Point Sequence:(
+				Name="AverageBeamDosePointDepth"				Type="2C"	NoCondition=""		# Required for all but the last items in that sequence :(
+				Name="AverageBeamDosePointEquivalentDepth"		Type="2C"	NoCondition=""		# Required for all but the last items in that sequence :(
+				Name="AverageBeamDosePointSSD"					Type="2C"	NoCondition=""		# Required for all but the last items in that sequence :(
+			SequenceEnd
+			Name="BeamMeterset"									Type="3"
+		SequenceEnd
+		Name="NumberOfBrachyApplicationSetups"					Type="1"
+		Sequence="ReferencedBrachyApplicationSetupSequence"		Type="1C"	VM="1-n"	Condition="NumberOfBrachyApplicationSetupsNotZero"
+			Name="ReferencedBrachyApplicationSetupNumber"		Type="1"
+			Name="BrachyApplicationSetupDoseSpecificationPoint"	Type="3"
+			Name="BrachyApplicationSetupDose"					Type="3"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTBeams"
+	Sequence="BeamSequence"										Type="1"	VM="1-n"
+		Name="BeamNumber"										Type="1"
+		Name="BeamName"											Type="3"
+		Name="BeamDescription"									Type="3"
+		Name="BeamType"											Type="1"	StringEnumValues="BeamType"
+		Name="RadiationType"									Type="2"	StringDefinedTerms="RadiationType"
+		Sequence="PrimaryFluenceModeSequence"					Type="3"	VM="1"
+			Name="FluenceMode"									Type="1"	StringEnumValues="FluenceMode"
+			Name="FluenceModeID"								Type="1C"	Condition="FluenceModeIsNonStandard"
+		SequenceEnd
+		Name="HighDoseTechniqueType"							Type="1C"	StringDefinedTerms="HighDoseTechniqueType"	NoCondition="" # real-world
+		Name="TreatmentMachineName"								Type="2"
+		Name="Manufacturer"										Type="3"
+		Name="InstitutionName"									Type="3"
+		Name="InstitutionAddress"								Type="3"
+		Name="InstitutionalDepartmentName"						Type="3"
+		Name="ManufacturerModelName"							Type="3"
+		Name="DeviceSerialNumber"								Type="3"
+		Name="PrimaryDosimeterUnit"								Type="3"	StringEnumValues="PrimaryDosimeterUnit"
+		Name="ReferencedToleranceTableNumber"					Type="3"
+		Name="SourceAxisDistance"								Type="3"
+		Sequence="BeamLimitingDeviceSequence"					Type="1"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"						Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="SourceToBeamLimitingDeviceDistance"			Type="3"
+			Name="NumberOfLeafJawPairs"							Type="1"
+			Name="LeafPositionBoundaries"						Type="2C"	Condition="RTBeamLimitingDeviceTypeMLCXOrMLCY" mbpo="true"
+		SequenceEnd
+		Name="ReferencedPatientSetupNumber"						Type="3"
+		Sequence="ReferencedReferenceImageSequence"				Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Name="ReferenceImageNumber"							Type="1"
+			Name="StartCumulativeMetersetWeight"				Type="3"
+			Name="EndCumulativeMetersetWeight"					Type="3"
+		SequenceEnd
+		Sequence="PlannedVerificationImageSequence"				Type="3"	VM="1-n"
+			Name="StartCumulativeMetersetWeight"				Type="3"
+			Name="MetersetExposure"								Type="3"
+			Name="EndCumulativeMetersetWeight"					Type="3"
+			Name="RTImagePlane"									Type="3"	StringEnumValues="RTImagePlane"
+			Name="XRayImageReceptorAngle"						Type="3"
+			Name="RTImageOrientation"							Type="3"
+			Name="RTImagePosition"								Type="3"
+			Name="RTImageSID"									Type="3"
+			Name="ImagingDeviceSpecificAcquisitionParameters"	Type="3"
+			Name="ReferencedReferenceImageNumber"		Type="3"
+		SequenceEnd
+		Name="TreatmentDeliveryType"							Type="3"	StringDefinedTerms="TreatmentDeliveryType"
+		Sequence="ReferencedDoseSequence"						Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="NumberOfWedges"									Type="1"
+		Sequence="WedgeSequence"								Type="1C"	VM="1-n"	Condition="NumberOfWedgesNotZero"
+			Name="WedgeNumber"									Type="1"
+			Name="WedgeType"									Type="2"	StringDefinedTerms="WedgeType"
+			Name="WedgeID"										Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="WedgeAngle"									Type="2"
+			Name="WedgeFactor"									Type="2"
+			Name="WedgeOrientation"								Type="2"
+			Name="SourceToWedgeTrayDistance"					Type="3"
+		SequenceEnd
+		Name="NumberOfCompensators"								Type="1"
+		Name="TotalCompensatorTrayFactor"						Type="3"
+		Sequence="CompensatorSequence"							Type="1C"	VM="1-n"	Condition="NumberOfCompensatorsNotZero"
+			Name="CompensatorDescription"						Type="3"
+			Name="CompensatorNumber"							Type="1"
+			Name="MaterialID"									Type="2"
+			Name="CompensatorID"								Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="SourceToCompensatorTrayDistance"				Type="2"
+			Name="CompensatorDivergence"						Type="3"	StringEnumValues="CompensatorDivergence"
+			Name="CompensatorMountingPosition"					Type="3"	StringEnumValues="CompensatorMountingPosition"
+			Name="CompensatorRows"								Type="1"
+			Name="CompensatorColumns"							Type="1"
+			Name="CompensatorPixelSpacing"						Type="1"
+			Name="CompensatorPosition"							Type="1"
+			Name="CompensatorTransmissionData"					Type="1"
+			Name="CompensatorThicknessData"						Type="1"
+			Name="SourceToCompensatorDistance"					Type="1C"	Condition="NeedSourceToCompensatorDistance"
+		SequenceEnd
+		Name="NumberOfBoli"										Type="1"
+		Sequence="ReferencedBolusSequence"						Type="1C"	VM="1-n"	Condition="NumberOfBoliNotZero"
+			Name="ReferencedROINumber"							Type="1"
+			Name="BolusID"										Type="3"
+			Name="BolusDescription"								Type="3"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfBlocks"									Type="1"
+		Name="TotalBlockTrayFactor"								Type="3"
+		Sequence="BlockSequence"								Type="1C"	VM="1-n"	Condition="NumberOfBlocksNotZero"
+			Name="BlockTrayID"									Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="SourceToBlockTrayDistance"					Type="2"
+			Name="BlockType"									Type="1"	StringEnumValues="BlockType"
+			Name="BlockDivergence"								Type="2"	StringEnumValues="BlockDivergence"
+			Name="BlockMountingPosition"						Type="3"	StringEnumValues="BlockMountingPosition"
+			Name="BlockNumber"									Type="1"
+			Name="BlockName"									Type="3"
+			Name="MaterialID"									Type="2"
+			Name="BlockThickness"								Type="2"
+			Name="BlockTransmission"							Type="2"
+			Name="BlockNumberOfPoints"							Type="2"
+			Name="BlockData"									Type="2"
+		SequenceEnd
+		Sequence="ApplicatorSequence"							Type="3"	VM="1"
+			Name="ApplicatorID"									Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="ApplicatorType"								Type="1"	StringDefinedTerms="ApplicatorType"
+			Name="ApplicatorDescription"						Type="3"
+			Sequence="GeneralAccessorySequence"					Type="3"	VM="1-n"
+				Name="GeneralAccessoryNumber"					Type="1"
+				Name="GeneralAccessoryID"						Type="1"
+				Name="GeneralAccessoryDescription"				Type="3"
+				Name="GeneralAccessoryType"						Type="3"	StringDefinedTerms="RTGeneralAccessoryType"
+				Name="AccessoryCode"							Type="3"
+				Name="SourceToGeneralAccessoryDistance"			Type="3"
+			SequenceEnd
+		SequenceEnd
+		Name="FinalCumulativeMetersetWeight"					Type="1C"	NoCondition=""
+		Name="NumberOfControlPoints"							Type="1"
+		Sequence="ControlPointSequence"							Type="1"	VM="2-n"
+			Name="ControlPointIndex"							Type="1"
+			Name="CumulativeMetersetWeight"						Type="2"
+			Sequence="ReferencedDoseReferenceSequence"			Type="3"	VM="1-n"
+				Name="ReferencedDoseReferenceNumber"			Type="1"
+				Name="CumulativeDoseReferenceCoefficient"		Type="2"
+			SequenceEnd
+			Sequence="ReferencedDoseSequence"					Type="1C"	VM="1-n"	Condition="DoseSummationTypeControlPoint"
+				InvokeMacro="SOPInstanceReferenceMacro"
+			SequenceEnd
+			Name="NominalBeamEnergy"							Type="3"
+			Name="DoseRateSet"									Type="3"
+			Sequence="WedgePositionSequence"					Type="3"	VM="1-n"
+				Name="ReferencedWedgeNumber"					Type="1"
+				Name="WedgePosition"							Type="1"	StringEnumValues="WedgePosition"
+			SequenceEnd
+			Sequence="BeamLimitingDevicePositionSequence"		Type="1C"	VM="1-n"	NoCondition=""
+				Name="RTBeamLimitingDeviceType"					Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+				Name="LeafJawPositions"							Type="1"
+			SequenceEnd
+			Name="GantryAngle"									Type="1C"	NoCondition=""
+			Name="GantryRotationDirection"						Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="GantryPitchAngle"								Type="3"
+			Name="GantryPitchRotationDirection"					Type="3"	StringEnumValues="RotationDirectionWithNone"
+			Name="BeamLimitingDeviceAngle"						Type="1C"	NoCondition=""
+			Name="BeamLimitingDeviceRotationDirection"			Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="PatientSupportAngle"							Type="1C"	NoCondition=""
+			Name="PatientSupportRotationDirection"				Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopEccentricAxisDistance"				Type="3"
+			Name="TableTopEccentricAngle"						Type="1C"	NoCondition=""
+			Name="TableTopEccentricRotationDirection"			Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopPitchAngle"							Type="1C"	NoCondition=""
+			Name="TableTopPitchRotationDirection"				Type="1C""	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopRollAngle"							Type="1C"	NoCondition=""
+			Name="TableTopRollRotationDirection"				Type="1C""	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopVerticalPosition"						Type="2C"	NoCondition=""
+			Name="TableTopLongitudinalPosition"					Type="2C"	NoCondition=""
+			Name="TableTopLateralPosition"						Type="2C"	NoCondition=""
+			Name="IsocenterPosition"							Type="2C"	NoCondition=""
+			Name="SurfaceEntryPoint"							Type="3"
+			Name="SourceToSurfaceDistance"						Type="3"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTBrachyApplicationSetups"
+	Name="BrachyTreatmentTechnique"								Type="1"	StringEnumValues="BrachyTreatmentTechnique"
+	Name="BrachyTreatmentType"									Type="1"	StringDefinedTerms="BrachyTreatmentType"
+	Sequence="TreatmentMachineSequence"							Type="1"	VM="1"
+		Name="TreatmentMachineName"								Type="2"
+		Name="Manufacturer"										Type="3"
+		Name="InstitutionName"									Type="3"
+		Name="InstitutionAddress"								Type="3"
+		Name="InstitutionalDepartmentName"						Type="3"
+		Name="ManufacturerModelName"							Type="3"
+		Name="DeviceSerialNumber"								Type="3"
+	SequenceEnd
+	Sequence="SourceSequence"									Type="1"	VM="1-n"
+		Name="SourceNumber"										Type="1"
+		Name="SourceSerialNumber"								Type="3"
+		Name="SourceModelID"									Type="3"
+		Name="SourceDescription"								Type="3"
+		Name="SourceType"										Type="1"
+		Name="SourceManufacturer"								Type="3"
+		Name="ActiveSourceDiameter"								Type="3"
+		Name="ActiveSourceLength"								Type="3"
+		Name="MaterialID"										Type="3"
+		Name="SourceEncapsulationNominalThickness"				Type="3"
+		Name="SourceEncapsulationNominalTransmission"			Type="3"
+		Name="SourceIsotopeName"								Type="1"
+		Name="SourceIsotopeHalfLife"							Type="1"
+		Name="SourceStrengthUnits"								Type="1C"	Condition="SourceIsNotGammaEmitter"	StringEnumValues="SourceStrengthUnits" mbpo="true"
+		Name="ReferenceAirKermaRate"							Type="1"
+		Name="SourceStrength"									Type="1C"	Condition="SourceIsNotGammaEmitter"
+		Name="SourceStrengthReferenceDate"						Type="1"
+		Name="SourceStrengthReferenceTime"						Type="1"
+	SequenceEnd
+	Sequence="ApplicationSetupSequence"							Type="1"	VM="1-n"
+		Name="ApplicationSetupType"								Type="1"	StringDefinedTerms="ApplicationSetupType"
+		Name="ApplicationSetupNumber"							Type="1"
+		Name="ApplicationSetupName"								Type="3"
+		Name="ApplicationSetupManufacturer"						Type="3"
+		Name="TemplateNumber"									Type="3"
+		Name="TemplateType"										Type="3"
+		Name="TemplateName"										Type="3"
+		Sequence="ReferencedReferenceImageSequence"				Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="TotalReferenceAirKerma"							Type="1"
+		Sequence="BrachyAccessoryDeviceSequence"				Type="3"	VM="1-n"
+			Name="BrachyAccessoryDeviceNumber"					Type="2"
+			Name="BrachyAccessoryDeviceID"						Type="2"
+			Name="BrachyAccessoryDeviceType"					Type="1"	StringDefinedTerms="BrachyAccessoryDeviceType"
+			Name="BrachyAccessoryDeviceName"					Type="3"
+			Name="MaterialID"									Type="3"
+			Name="BrachyAccessoryDeviceNominalThickness"		Type="3"
+			Name="BrachyAccessoryDeviceNominalTransmission"		Type="3"
+			Name="ReferencedROINumber"							Type="2"
+		SequenceEnd
+		Sequence="ChannelSequence"								Type="1"	VM="1-n"
+			Name="ChannelNumber"								Type="1"
+			Name="ChannelLength"								Type="2"
+			Name="ChannelTotalTime"								Type="1"
+			Name="SourceMovementType"							Type="1"	StringDefinedTerms="SourceMovementType"
+			Name="NumberOfPulses"								Type="1C"	Condition="BrachyTreatmentTypePDR"
+			Name="PulseRepetitionInterval"						Type="1C"	Condition="BrachyTreatmentTypePDR"
+			Name="SourceApplicatorNumber"						Type="3"
+			Name="SourceApplicatorID"							Type="2C"	Condition="SourceApplicatorNumberPresent"
+			Name="SourceApplicatorType"							Type="1C"	Condition="SourceApplicatorNumberPresent"	StringDefinedTerms="SourceApplicatorType"
+			Name="SourceApplicatorName"							Type="3"
+			Name="SourceApplicatorLength"						Type="1C"	Condition="SourceApplicatorNumberPresent"
+			Name="SourceApplicatorManufacturer"					Type="3"
+			Name="MaterialID"									Type="3"
+			Name="SourceApplicatorWallNominalThickness"			Type="3"
+			Name="SourceApplicatorWallNominalTransmission"		Type="3"
+			Name="SourceApplicatorStepSize"						Type="1C"	Condition="SourceMovementTypeStepwise"
+			Name="ReferencedROINumber"							Type="2C"	Condition="SourceApplicatorNumberPresent"
+			Name="TransferTubeNumber"							Type="2"
+			Name="TransferTubeLength"							Type="2C"	Condition="TransferTubeNumberNotNull"
+			Sequence="ChannelShieldSequence"					Type="3"	VM="1-n"
+				Name="ChannelShieldNumber"						Type="1"
+				Name="ChannelShieldID"							Type="2"
+				Name="ChannelShieldName"						Type="3"
+				Name="MaterialID"								Type="3"
+				Name="ChannelShieldNominalThickness"			Type="3"
+				Name="ChannelShieldNominalTransmission"			Type="3"
+				Name="ReferencedROINumber"						Type="2"
+			SequenceEnd
+			Name="ReferencedSourceNumber"						Type="1"
+			Name="NumberOfControlPoints"						Type="1"
+			Name="FinalCumulativeTimeWeight"					Type="1C"	NoCondition=""
+			Sequence="BrachyControlPointSequence"				Type="1"	VM="2-n"
+				Name="ControlPointIndex"						Type="1"
+				Name="CumulativeTimeWeight"						Type="2"
+				Name="ControlPointRelativePosition"				Type="1"
+				Name="ControlPoint3DPosition"					Type="3"
+				Name="ControlPointOrientation"					Type="3"
+				Sequence="BrachyReferencedDoseReferenceSequence"	Type="3"	VM="1-n"
+					Name="ReferencedDoseReferenceNumber"		Type="1"
+					Name="CumulativeDoseReferenceCoefficient"	Type="1"
+				SequenceEnd
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="Approval"
+	Name="ApprovalStatus"										Type="1"	StringEnumValues="ApprovalStatus"
+	Name="ReviewDate"											Type="2C"	Condition="ApprovalStatusApprovedOrRejected"
+	Name="ReviewTime"											Type="2C"	Condition="ApprovalStatusApprovedOrRejected"
+	Name="ReviewerName"											Type="2C"	Condition="ApprovalStatusApprovedOrRejected"
+ModuleEnd
+
+Module="RTGeneralTreatmentRecord"
+	Name="InstanceNumber"										Type="1"
+	Name="TreatmentDate"										Type="2"
+	Name="TreatmentTime"										Type="2"
+	Sequence="ReferencedRTPlanSequence"							Type="2"	VM="0-1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedTreatmentRecordSequence"				Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="RTTreatmentMachineRecord"
+	Sequence="TreatmentMachineSequence"							Type="1"	VM="1"
+		Name="TreatmentMachineName"								Type="2"
+		Name="Manufacturer"										Type="2"
+		Name="InstitutionName"									Type="2"
+		Name="InstitutionAddress"								Type="3"
+		Name="InstitutionalDepartmentName"						Type="3"
+		Name="ManufacturerModelName"							Type="2"
+		Name="DeviceSerialNumber"								Type="2"
+	SequenceEnd
+ModuleEnd
+
+Module="MeasuredDoseReferenceRecord"
+	Sequence="MeasuredDoseReferenceSequence"					Type="1"	VM="1-n"
+		Name="ReferencedDoseReferenceNumber"					Type="1C"	Condition="MeasuredDoseReferenceNumberNotPresent"
+		Name="MeasuredDoseReferenceNumber"						Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+		Name="DoseUnits"										Type="1"	StringEnumValues="DoseUnits"
+		Name="MeasuredDoseValue"								Type="2"
+		Name="MeasuredDoseType"									Type="2"	StringDefinedTerms="MeasuredDoseType"
+		Name="MeasuredDoseDescription"							Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="CalculatedDoseReferenceRecord"
+	Sequence="CalculatedDoseReferenceSequence"					Type="1"	VM="1-n"
+		Name="ReferencedDoseReferenceNumber"					Type="1C"	Condition="CalculatedDoseReferenceNumberNotPresent"
+		Name="CalculatedDoseReferenceNumber"					Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+		Name="CalculatedDoseReferenceDoseValue"					Type="2"
+		Name="CalculatedDoseReferenceDescription"				Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="RTBeamsSessionRecord"
+	Name="ReferencedFractionGroupNumber"						Type="3"
+	Name="NumberOfFractionsPlanned"								Type="2"
+	Name="PrimaryDosimeterUnit"									Type="1"	StringEnumValues="PrimaryDosimeterUnit"
+	Sequence="TreatmentSessionBeamSequence"						Type="1"	VM="1-n"
+		Name="ReferencedBeamNumber"								Type="3"
+		Name="BeamName"											Type="3"
+		Name="BeamDescription"									Type="3"
+		Name="BeamType"											Type="1"	StringEnumValues="BeamType"
+		Name="RadiationType"									Type="1"	StringDefinedTerms="RadiationType"
+		Sequence="PrimaryFluenceModeSequence"					Type="3"	VM="1"
+			Name="FluenceMode"									Type="1"	StringEnumValues="FluenceMode"
+			Name="FluenceModeID"								Type="1C"	Condition="FluenceModeIsNonStandard"
+		SequenceEnd
+		Name="HighDoseTechniqueType"							Type="1C"	StringDefinedTerms="HighDoseTechniqueType"	NoCondition="" #real-world
+		Sequence="ReferencedVerificationImageSequence"			Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Name="StartMeterset"								Type="3"
+			Name="EndMeterset"									Type="3"
+		SequenceEnd
+		Sequence="ReferencedMeasuredDoseReferenceSequence"		Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1C"	Condition="ReferencedMeasuredDoseReferenceNumberNotPresent"
+			Name="ReferencedMeasuredDoseReferenceNumber"		Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+			Name="MeasuredDoseValue"							Type="1"
+		SequenceEnd
+		Sequence="ReferencedCalculatedDoseReferenceSequence"	Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1C"	Condition="ReferencedCalculatedDoseReferenceNumberNotPresent"
+			Name="ReferencedCalculatedDoseReferenceNumber"		Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+			Name="CalculatedDoseReferenceDoseValue"				Type="1"
+		SequenceEnd
+		Name="SourceAxisDistance"								Type="3"
+		Sequence="BeamLimitingDeviceLeafPairsSequence"			Type="1"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"						Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="NumberOfLeafJawPairs"							Type="1"
+		SequenceEnd
+		Name="ReferencedPatientSetupNumber"						Type="3"
+		Name="NumberOfWedges"									Type="1"
+		Sequence="RecordedWedgeSequence"						Type="1C"	VM="1-n"	Condition="NumberOfWedgesNotZero"
+			Name="WedgeNumber"									Type="3"
+			Name="WedgeType"									Type="2"	StringDefinedTerms="WedgeType"
+			Name="WedgeID"										Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="WedgeAngle"									Type="3"
+			Name="WedgeOrientation"								Type="3"
+		SequenceEnd
+		Name="NumberOfCompensators"								Type="2"
+		Sequence="RecordedCompensatorSequence"					Type="3"	VM="1-n"
+			Name="ReferencedCompensatorNumber"					Type="1"
+			Name="CompensatorType"								Type="2"	StringDefinedTerms="CompensatorType"
+			Name="CompensatorID"								Type="3"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfBoli"										Type="2"
+		Sequence="ReferencedBolusSequence"						Type="3"	VM="1-n"
+			Name="ReferencedROINumber"							Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfBlocks"									Type="2"	
+		Sequence="RecordedBlockSequence"						Type="3"	VM="1-n"
+			Name="BlockTrayID"									Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="ReferencedBlockNumber"						Type="3"
+			Name="BlockName"									Type="2"
+		SequenceEnd
+		Sequence="ApplicatorSequence"							Type="3"	VM="1"
+			Name="ApplicatorID"									Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="ApplicatorType"								Type="1"	StringDefinedTerms="ApplicatorType"
+			Name="ApplicatorDescription"						Type="3"
+			Sequence="GeneralAccessorySequence"					Type="3"	VM="1-n"
+				Name="GeneralAccessoryNumber"					Type="1"
+				Name="GeneralAccessoryID"						Type="1"
+				Name="GeneralAccessoryDescription"				Type="3"
+				Name="GeneralAccessoryType"						Type="3"	StringDefinedTerms="RTGeneralAccessoryType"
+				Name="AccessoryCode"							Type="3"
+				Name="SourceToGeneralAccessoryDistance"			Type="3"
+			SequenceEnd
+		SequenceEnd
+		Name="CurrentFractionNumber"							Type="2"
+		Name="TreatmentDeliveryType"							Type="2"	StringDefinedTerms="TreatmentDeliveryType"
+		Name="TreatmentTerminationStatus"						Type="1"	StringEnumValues="TreatmentTerminationStatus"
+		Name="TreatmentTerminationCode"							Type="3"
+		Name="TreatmentVerificationStatus"						Type="2"	StringEnumValues="TreatmentVerificationStatus"
+		Name="SpecifiedPrimaryMeterset"							Type="3"
+		Name="SpecifiedSecondaryMeterset"						Type="3"
+		Name="DeliveredPrimaryMeterset"							Type="3"
+		Name="DeliveredSecondaryMeterset"						Type="3"
+		Name="SpecifiedTreatmentTime"							Type="3"
+		Name="DeliveredTreatmentTime"							Type="3"
+		Name="NumberOfControlPoints"							Type="1"
+		Sequence="ControlPointDeliverySequence"					Type="1"	VM="1-n"
+			Name="ReferencedControlPointIndex"					Type="3"
+			Name="TreatmentControlPointDate"					Type="1"
+			Name="TreatmentControlPointTime"					Type="1"
+			Name="SpecifiedMeterset"							Type="2"
+			Name="DeliveredMeterset"							Type="1"
+			Name="DoseRateSet"									Type="2"
+			Name="DoseRateDelivered"							Type="2"
+			Name="NominalBeamEnergy"							Type="3"
+			Name="NominalBeamEnergyUnit"						Type="1C"	Condition="NominalBeamEnergyIsPresent"	StringDefinedTerms="NominalBeamEnergyUnit"
+			Sequence="WedgePositionSequence"					Type="3"	VM="1-n"
+				Name="ReferencedWedgeNumber"					Type="1"
+				Name="WedgePosition"							Type="1"	StringEnumValues="WedgePosition"
+			SequenceEnd
+			Sequence="BeamLimitingDevicePositionSequence"		Type="1C"	VM="1-n"	NoCondition="" # too hard :(
+				Name="RTBeamLimitingDeviceType"					Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+				Name="LeafJawPositions"							Type="1"
+			SequenceEnd
+			Name="GantryAngle"									Type="1C"	NoCondition="" # too hard :(
+			Name="GantryRotationDirection"						Type="1C"	StringEnumValues="RotationDirectionWithNone"	NoCondition="" # too hard :(
+			Name="GantryPitchAngle"								Type="3"
+			Name="GantryPitchRotationDirection"					Type="3"	StringEnumValues="RotationDirectionWithNone"
+			Name="BeamStopperPosition"							Type="3"	StringEnumValues="BeamStopperPosition"
+			Name="BeamLimitingDeviceAngle"						Type="1C"	NoCondition="" # too hard :(
+			Name="BeamLimitingDeviceRotationDirection"			Type="1C"	NoCondition="" # too hard :(
+			Name="PatientSupportAngle"							Type="1C"	NoCondition="" # too hard :(
+			Name="PatientSupportRotationDirection"				Type="1C"	StringEnumValues="RotationDirectionWithNone"	NoCondition="" # too hard :(
+			Name="TableTopEccentricAxisDistance"				Type="3"
+			Name="TableTopEccentricAngle"						Type="1C"	NoCondition="" # too hard :(
+			Name="TableTopEccentricRotationDirection"			Type="1C"	StringEnumValues="RotationDirectionWithNone"	NoCondition="" # too hard :(
+			Name="TableTopPitchAngle"							Type="1C"	NoCondition="" # too hard :(
+			Name="TableTopPitchRotationDirection"				Type="1C""	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopRollAngle"							Type="1C"	NoCondition="" # too hard :(
+			Name="TableTopRollRotationDirection"				Type="1C""	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopVerticalPosition"						Type="2C"	NoCondition="" # too hard :(
+			Name="TableTopLongitudinalPosition"					Type="2C"	NoCondition="" # too hard :(
+			Name="TableTopLateralPosition"						Type="2C"	NoCondition="" # too hard :(
+			Sequence="CorrectedParameterSequence"				Type="3"	VM="1-n"
+				Name="ParameterSequencePointer"					Type="1"
+				Name="ParameterItemIndex"						Type="1"
+				Name="ParameterPointer"							Type="1"
+				Name="CorrectionValue"							Type="1"
+			SequenceEnd
+			Sequence="OverrideSequence"							Type="3"	VM="1-n"
+				Name="OverrideParameterPointer"					Type="2"
+				Name="ParameterSequencePointer"					Type="3"
+				Name="ParameterItemIndex"						Type="3"
+				Name="OperatorsName"							Type="2"
+				Name="OverrideReason"							Type="3"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTBrachySessionRecord"
+	Name="ReferencedFractionGroupNumber"						Type="3"
+	Name="NumberOfFractionsPlanned"								Type="2"
+	Name="BrachyTreatmentTechnique"								Type="1"	StringEnumValues="BrachyTreatmentTechnique"
+	Name="BrachyTreatmentType"									Type="1"	StringDefinedTerms="BrachyTreatmentType"
+	Sequence="RecordedSourceSequence"							Type="1"	VM="1-n"
+		Name="SourceNumber"										Type="1"
+		Name="SourceType"										Type="1"	StringDefinedTerms="SourceType"
+		Name="SourceManufacturer"								Type="2"
+		Name="SourceSerialNumber"								Type="2"
+		Name="SourceIsotopeName"								Type="1"
+		Name="SourceIsotopeHalfLife"							Type="1"
+		Name="SourceStrengthUnits"								Type="1C"	Condition="SourceIsNotGammaEmitter"	StringEnumValues="SourceStrengthUnits" mbpo="true"
+		Name="ReferenceAirKermaRate"							Type="1"
+		Name="SourceStrength"									Type="1C"	Condition="SourceIsNotGammaEmitter"
+		Name="SourceStrengthReferenceDate"						Type="1"
+		Name="SourceStrengthReferenceTime"						Type="1"
+	SequenceEnd
+	Sequence="TreatmentSessionApplicationSetupSequence"			Type="1"	VM="1-n"
+		Name="ApplicationSetupType"								Type="1"	StringDefinedTerms="ApplicationSetupType"
+		Name="ReferencedBrachyApplicationSetupNumber"			Type="3"
+		Name="ApplicationSetupName"								Type="3"
+		Name="ApplicationSetupManufacturer"						Type="3"
+		Name="TemplateNumber"									Type="3"
+		Name="TemplateType"										Type="3"
+		Name="TemplateName"										Type="3"
+		Name="ApplicationSetupCheck"							Type="3"	StringEnumValues="ApplicationSetupCheck"
+		Sequence="ReferencedVerificationImageSequence"			Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="TotalReferenceAirKerma"							Type="1"
+		Sequence="ReferencedMeasuredDoseReferenceSequence"		Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1C"	Condition="ReferencedMeasuredDoseReferenceNumberNotPresent"
+			Name="ReferencedMeasuredDoseReferenceNumber"		Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+			Name="MeasuredDoseValue"							Type="1"
+		SequenceEnd
+		Sequence="ReferencedCalculatedDoseReferenceSequence"	Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1C"	Condition="ReferencedCalculatedDoseReferenceNumberNotPresent"
+			Name="ReferencedCalculatedDoseReferenceNumber"		Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+			Name="CalculatedDoseReferenceDoseValue"				Type="1"
+		SequenceEnd
+		Name="CurrentFractionNumber"							Type="2"
+		Name="TreatmentDeliveryType"							Type="2"	StringDefinedTerms="TreatmentDeliveryTypeNormalOrContinuation"
+		Name="TreatmentTerminationStatus"						Type="1"	StringEnumValues="TreatmentTerminationStatus"
+		Name="TreatmentTerminationCode"							Type="3"
+		Name="TreatmentVerificationStatus"						Type="2"	StringEnumValues="TreatmentVerificationStatus"
+		Sequence="RecordedBrachyAccessoryDeviceSequence"		Type="3"	VM="1-n"
+			Name="ReferencedBrachyAccessoryDeviceNumber"		Type="2"
+			Name="BrachyAccessoryDeviceID"						Type="2"
+			Name="BrachyAccessoryDeviceType"					Type="1"	StringDefinedTerms="BrachyAccessoryDeviceType"
+			Name="BrachyAccessoryDeviceName"					Type="3"
+		SequenceEnd
+		Sequence="RecordedChannelSequence"						Type="1"	VM="1-n"
+			Name="ChannelNumber"								Type="1"
+			Name="ChannelLength"								Type="2"
+			Name="SpecifiedChannelTotalTime"					Type="1"
+			Name="DeliveredChannelTotalTime"					Type="1"
+			Name="SourceMovementType"							Type="1"	StringDefinedTerms="SourceMovementType"
+			Name="SpecifiedNumberOfPulses"						Type="1C"	Condition="BrachyTreatmentTypeIsPDR"
+			Name="DeliveredNumberOfPulses"						Type="1C"	Condition="BrachyTreatmentTypeIsPDR"
+			Name="SpecifiedPulseRepetitionInterval"				Type="1C"	Condition="BrachyTreatmentTypeIsPDR"
+			Name="DeliveredPulseRepetitionInterval"				Type="1C"	Condition="BrachyTreatmentTypeIsPDR"
+			Sequence="ReferencedMeasuredDoseReferenceSequence"	Type="3"	VM="1-n"
+				Name="ReferencedDoseReferenceNumber"			Type="1C"	Condition="ReferencedMeasuredDoseReferenceNumberNotPresent"
+				Name="ReferencedMeasuredDoseReferenceNumber"	Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+				Name="MeasuredDoseValue"						Type="1"
+			SequenceEnd
+			Sequence="ReferencedCalculatedDoseReferenceSequence"	Type="3"	VM="1-n"
+				Name="ReferencedDoseReferenceNumber"			Type="1C"	Condition="ReferencedCalculatedDoseReferenceNumberNotPresent"
+				Name="ReferencedCalculatedDoseReferenceNumber"	Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+				Name="CalculatedDoseReferenceDoseValue"			Type="1"
+			SequenceEnd
+			Sequence="RecordedSourceApplicatorSequence"			Type="3"	VM="1-n"
+				Name="ReferencedSourceApplicatorNumber"			Type="2"
+				Name="SourceApplicatorID"						Type="2"
+				Name="SourceApplicatorType"						Type="1"	StringDefinedTerms="SourceApplicatorType"
+				Name="SourceApplicatorName"						Type="3"
+				Name="SourceApplicatorLength"					Type="1"
+				Name="SourceApplicatorManufacturer"				Type="3"
+				Name="SourceApplicatorStepSize"					Type="1C"	NoCondition="" # need StringValueAbove SourceMovementType Stepwise :(
+			SequenceEnd
+			Name="TransferTubeNumber"							Type="2"
+			Name="TransferTubeLength"							Type="2C"	Condition="TransferTubeNumberIsNotEmpty"
+			Sequence="RecordedChannelShieldSequence"			Type="3"	VM="1-n"
+				Name="ReferencedChannelShieldNumber"			Type="2"
+				Name="ChannelShieldID"							Type="2"
+				Name="ChannelShieldName"						Type="3"
+			SequenceEnd
+			Name="ReferencedSourceNumber"						Type="1"
+			Name="SafePositionExitDate"							Type="1C"	NoCondition="" # Need StringValueAbove BrachyTreatmentType Not Manual :(
+			Name="SafePositionExitTime"							Type="1C"	NoCondition="" # Need StringValueAbove BrachyTreatmentType Not Manual :(
+			Name="SafePositionReturnDate"						Type="1C"	NoCondition="" # Need StringValueAbove BrachyTreatmentType Not Manual :(
+			Name="SafePositionReturnTime"						Type="1C"	NoCondition="" # Need StringValueAbove BrachyTreatmentType Not Manual :(
+			Name="NumberOfControlPoints"						Type="1"
+			Sequence="BrachyControlPointDeliveredSequence"		Type="1"	VM="2-n"
+				Name="ReferencedControlPointIndex"				Type="3"
+				Name="TreatmentControlPointDate"				Type="1"
+				Name="TreatmentControlPointTime"				Type="1"
+				Name="ControlPointRelativePosition"				Type="1"
+				Sequence="OverrideSequence"						Type="3"	VM="1-n"
+					Name="OverrideParameterPointer"				Type="2"
+					Name="OperatorsName"						Type="2"
+					Name="OverrideReason"						Type="3"
+				SequenceEnd
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTTreatmentSummaryRecord"
+	Name="CurrentTreatmentStatus"								Type="1"	StringEnumValues="CurrentTreatmentStatus"
+	Name="TreatmentStatusComment"								Type="3"
+	Name="FirstTreatmentDate"									Type="2"
+	Name="MostRecentTreatmentDate"								Type="2"
+	Sequence="FractionGroupSummarySequence"						Type="3"	VM="1-n"
+		Name="ReferencedFractionGroupNumber"					Type="3"
+		Name="FractionGroupType"								Type="2"	StringEnumValues="FractionGroupType"
+		Name="NumberOfFractionsPlanned"							Type="2"
+		Name="NumberOfFractionsDelivered"						Type="2"
+		Sequence="FractionStatusSummarySequence"				Type="3"	VM="1-n"
+			Name="ReferencedFractionNumber"						Type="1"
+			Name="TreatmentDate"								Type="2"
+			Name="TreatmentTime"								Type="2"
+			Name="TreatmentTerminationStatus"					Type="2"	StringEnumValues="TreatmentTerminationStatus"
+		SequenceEnd
+	SequenceEnd
+	Sequence="TreatmentSummaryMeasuredDoseReferenceSequence"	Type="3"	VM="1-n"
+		Name="ReferencedDoseReferenceNumber"					Type="3"
+		Name="DoseReferenceDescription"							Type="3"
+		Name="CumulativeDoseToDoseReference"					Type="1"
+	SequenceEnd
+	Sequence="TreatmentSummaryCalculatedDoseReferenceSequence"	Type="3"	VM="1-n"
+		Name="ReferencedDoseReferenceNumber"					Type="3"
+		Name="DoseReferenceDescription"							Type="3"
+		Name="CumulativeDoseToDoseReference"					Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="RTIonToleranceTables"
+	Sequence="IonToleranceTableSequence"						Type="3"	VM="1-n"
+		Name="ToleranceTableNumber"								Type="1"
+		Name="ToleranceTableLabel"								Type="3"
+		Name="GantryAngleTolerance"								Type="3"
+		Name="BeamLimitingDeviceAngleTolerance"					Type="3"
+		Sequence="BeamLimitingDeviceToleranceSequence"			Type="3"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"						Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="BeamLimitingDevicePositionTolerance"			Type="1"
+		SequenceEnd
+		Name="PatientSupportAngleTolerance"						Type="3"
+		Name="TableTopVerticalPositionTolerance"				Type="3"
+		Name="TableTopLongitudinalPositionTolerance"			Type="3"
+		Name="TableTopLateralPositionTolerance"					Type="3"
+		Name="TableTopPitchAngleTolerance"						Type="3"
+		Name="TableTopRollAngleTolerance"						Type="3"
+		Name="SnoutPositionTolerance"							Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="RTIonBeams"
+	Sequence="IonBeamSequence"									Type="1"	VM="1-n"
+		Name="BeamNumber"										Type="1"
+		Name="BeamName"											Type="1"
+		Name="BeamDescription"									Type="3"
+		Name="BeamType"											Type="1"	StringEnumValues="BeamType"
+		Name="RadiationType"									Type="1"	StringDefinedTerms="IonRadiationType"
+		Name="RadiationMassNumber"								Type="1C"	Condition="RadiationTypeIsIon"
+		Name="RadiationAtomicNumber"							Type="1C"	Condition="RadiationTypeIsIon"
+		Name="RadiationChargeState"								Type="1C"	Condition="RadiationTypeIsIon"
+		Name="ScanMode"											Type="1"	StringDefinedTerms="IonScanMode"
+		Name="TreatmentMachineName"								Type="2"
+		Name="Manufacturer"										Type="3"
+		Name="InstitutionName"									Type="3"
+		Name="InstitutionAddress"								Type="3"
+		Name="InstitutionalDepartmentName"						Type="3"
+		Name="ManufacturerModelName"							Type="3"
+		Name="DeviceSerialNumber"								Type="3"
+		Name="PrimaryDosimeterUnit"								Type="3"	StringEnumValues="IonPrimaryDosimeterUnit"
+		Name="ReferencedToleranceTableNumber"					Type="3"
+		Name="VirtualSourceAxisDistances"						Type="1"
+		Sequence="IonBeamLimitingDeviceSequence"				Type="3"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"						Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="IsocenterToBeamLimitingDeviceDistance"		Type="2"
+			Name="NumberOfLeafJawPairs"							Type="1"
+			Name="LeafPositionBoundaries"						Type="1C"	Condition="RTBeamLimitingDeviceTypeMLCXOrMLCY" mbpo="true"
+		SequenceEnd
+		Name="ReferencedPatientSetupNumber"						Type="3"
+		Sequence="ReferencedReferenceImageSequence"				Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+			Name="ReferenceImageNumber"							Type="1"
+		SequenceEnd
+		Name="TreatmentDeliveryType"							Type="1"	StringDefinedTerms="TreatmentDeliveryType"
+		Sequence="ReferencedDoseSequence"						Type="3"	VM="1-n"
+			# SOPInstanceReferenceMacro, but want to check SOPClassUID
+			Name="ReferencedSOPClassUID"						Type="1"	StringEnumValues="RTDoseSOPClass"
+			Name="ReferencedSOPInstanceUID"						Type="1"
+		SequenceEnd
+		Name="NumberOfWedges"									Type="1"
+		Name="TotalWedgeTrayWaterEquivalentThickness"			Type="3"
+		Sequence="IonWedgeSequence"								Type="1C"	VM="1-n"	Condition="NumberOfWedgesNotZero"
+			Name="WedgeNumber"									Type="1"
+			Name="WedgeType"									Type="2"	StringDefinedTerms="IonWedgeType"
+			Name="WedgeID"										Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="WedgeAngle"									Type="2"
+			Name="WedgeOrientation"								Type="2"
+			Name="IsocenterToWedgeTrayDistance"					Type="1"
+		SequenceEnd
+		Name="NumberOfCompensators"								Type="1"
+		Name="TotalCompensatorTrayWaterEquivalentThickness"		Type="3"
+		Sequence="IonRangeCompensatorSequence"					Type="1C"	VM="1-n"	Condition="NumberOfCompensatorsNotZero"
+			Name="CompensatorDescription"						Type="3"
+			Name="CompensatorNumber"							Type="1"
+			Name="MaterialID"									Type="2"
+			Name="CompensatorID"								Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="IsocenterToCompensatorTrayDistance"			Type="1C"	Condition="CompensatorMountingPositionNotDoubleSided"
+			Name="CompensatorDivergence"						Type="1"	StringEnumValues="CompensatorDivergence"
+			Name="CompensatorMountingPosition"					Type="1"	StringEnumValues="CompensatorMountingPosition"
+			Name="CompensatorRows"								Type="1"
+			Name="CompensatorColumns"							Type="1"
+			Name="CompensatorPixelSpacing"						Type="1"
+			Name="CompensatorPosition"							Type="1"
+			Name="CompensatorColumnOffset"						Type="1C"	NoCondition=""	# if compensator pattern is hexagonal
+			Name="CompensatorThicknessData"						Type="1"
+			Name="IsocenterToCompensatorDistances"				Type="1C"	Condition="NeedIsocenterToCompensatorDistance"
+			Name="CompensatorRelativeStoppingPowerRatio"		Type="3"
+			Name="CompensatorMillingToolDiameter"				Type="3"
+		SequenceEnd
+		Name="NumberOfBoli"										Type="1"
+		Sequence="ReferencedBolusSequence"						Type="1C"	VM="1-n"	Condition="NumberOfBoliNotZero"
+			Name="ReferencedROINumber"							Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfBlocks"									Type="1"
+		Name="TotalBlockTrayWaterEquivalentThickness"			Type="3"
+		Sequence="IonBlockSequence"								Type="1C"	VM="1-n"	Condition="NumberOfBlocksNotZero"
+			Name="BlockTrayID"									Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="IsocenterToBlockTrayDistance"					Type="1"
+			Name="BlockType"									Type="1"	StringEnumValues="BlockType"
+			Name="BlockDivergence"								Type="1"	StringEnumValues="BlockDivergence"
+			Name="BlockMountingPosition"						Type="1"	StringEnumValues="BlockMountingPosition"
+			Name="BlockNumber"									Type="1"
+			Name="BlockName"									Type="3"
+			Name="MaterialID"									Type="2"
+			Name="BlockThickness"								Type="1"
+			Name="BlockNumberOfPoints"							Type="1"
+			Name="BlockData"									Type="1"
+		SequenceEnd
+		Sequence="SnoutSequence"								Type="3"	VM="1"
+			Name="SnoutID"										Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Sequence="ApplicatorSequence"							Type="3"	VM="1"
+			Name="ApplicatorID"									Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="ApplicatorType"								Type="1"	StringDefinedTerms="IonApplicatorType"
+			Name="ApplicatorDescription"						Type="3"
+			Sequence="GeneralAccessorySequence"					Type="3"	VM="1-n"
+				Name="GeneralAccessoryNumber"					Type="1"
+				Name="GeneralAccessoryID"						Type="1"
+				Name="GeneralAccessoryDescription"				Type="3"
+				Name="GeneralAccessoryType"						Type="3"	StringDefinedTerms="RTGeneralAccessoryType"
+				Name="AccessoryCode"							Type="3"
+				Name="SourceToGeneralAccessoryDistance"			Type="3"
+			SequenceEnd
+		SequenceEnd
+		Name="NumberOfRangeShifters"							Type="1"
+		Sequence="RangeShifterSequence"							Type="1C"	VM="1-n"	Condition="NumberOfRangeShiftersNotZero"
+			Name="RangeShifterNumber"							Type="1"
+			Name="RangeShifterID"								Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="RangeShifterType"								Type="1"	StringDefinedTerms="RangeShifterType"
+			Name="RangeShifterDescription"						Type="3"
+		SequenceEnd
+		Name="NumberOfLateralSpreadingDevices"					Type="1"
+		Sequence="LateralSpreadingDeviceSequence"				Type="1C"	VM="1-n"	Condition="NumberOfLateralSpreadingDevicesNotZero"
+			Name="LateralSpreadingDeviceNumber"					Type="1"
+			Name="LateralSpreadingDeviceID"						Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="LateralSpreadingDeviceType"					Type="1"	StringDefinedTerms="LateralSpreadingDeviceType"
+			Name="LateralSpreadingDeviceDescription"			Type="3"
+		SequenceEnd
+		Name="NumberOfRangeModulators"							Type="1"
+		Sequence="RangeModulatorSequence"						Type="1C"	VM="1-n"	Condition="NumberOfRangeModulatorsNotZero"
+			Name="RangeModulatorNumber"							Type="1"
+			Name="RangeModulatorID"								Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="RangeModulatorType"							Type="1"	StringDefinedTerms="RangeModulatorType"
+			Name="RangeModulatorDescription"					Type="3"
+			Name="BeamCurrentModulationID"						Type="1C"	Condition="RangeModulatorTypeIsWhlModWeights"
+		SequenceEnd
+		InvokeMacro="PatientSupportIdentificationMacro"
+		Name="FixationLightAzimuthalAngle"						Type="3"
+		Name="FixationLightPolarAngle"							Type="3"
+		Name="FinalCumulativeMetersetWeight"					Type="1C"	NoCondition=""
+		Name="NumberOfControlPoints"							Type="1"
+		Sequence="IonControlPointSequence"						Type="1"	VM="2-n"
+			Name="ControlPointIndex"							Type="1"
+			Name="CumulativeMetersetWeight"						Type="2"
+			Sequence="ReferencedDoseReferenceSequence"			Type="3"	VM="1-n"
+				Name="ReferencedDoseReferenceNumber"			Type="1"
+				Name="CumulativeDoseReferenceCoefficient"		Type="2"
+			SequenceEnd
+			Name="NominalBeamEnergy"							Type="1C"	NoCondition=""
+			Name="KVP"											Type="1C"	NoCondition=""
+			Name="MetersetRate"									Type="3"
+			Sequence="IonWedgePositionSequence"					Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedWedgeNumber"					Type="1"
+				Name="WedgePosition"							Type="1"	StringEnumValues="WedgePosition"
+				Name="WedgeThinEdgePosition"					Type="1C"	NoCondition=""
+			SequenceEnd
+			Sequence="RangeShifterSettingsSequence"				Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedRangeShifterNumber"				Type="1"
+				Name="RangeShifterSetting"						Type="1"
+				Name="IsocenterToRangeShifterDistance"			Type="3"
+				Name="RangeShifterWaterEquivalentThickness"		Type="3"
+			SequenceEnd
+			Sequence="LateralSpreadingDeviceSettingsSequence"			Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedLateralSpreadingDeviceNumber"			Type="1"
+				Name="LateralSpreadingDeviceSetting"					Type="1"
+				Name="IsocenterToLateralSpreadingDeviceDistance"		Type="3"
+				Name="LateralSpreadingDeviceWaterEquivalentThickness"	Type="3"
+			SequenceEnd
+			Sequence="RangeModulatorSettingsSequence"						Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedRangeModulatorNumber"						Type="1"
+				Name="RangeModulatorGatingStartValue"						Type="1C"	NoCondition=""
+				Name="RangeModulatorGatingStopValue"						Type="1C"	NoCondition=""
+				Name="RangeModulatorGatingStartWaterEquivalentThickness"	Type="3"
+				Name="RangeModulatorGatingStopWaterEquivalentThickness"		Type="3"
+			SequenceEnd
+			InvokeMacro="BeamLimitingDevicePositionMacro"
+			Name="GantryAngle"									Type="1C"	NoCondition=""
+			Name="GantryRotationDirection"						Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="GantryPitchAngle"								Type="3"
+			Name="GantryPitchRotationDirection"					Type="3"	StringEnumValues="RotationDirectionWithNone"
+			Name="BeamLimitingDeviceAngle"						Type="1C"	NoCondition=""
+			Name="BeamLimitingDeviceRotationDirection"			Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="ScanSpotPositionMap"							Type="1C"	Condition="ScanModeIsModulated"
+			Name="ScanSpotMetersetWeights"						Type="1C"	Condition="ScanModeIsModulated"
+			Name="ScanningSpotSize"								Type="3"
+			Name="NumberOfPaintings"							Type="1C"	Condition="ScanModeIsModulated"
+			Name="PatientSupportAngle"							Type="1C"	NoCondition=""
+			Name="PatientSupportRotationDirection"				Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopPitchAngle"							Type="2C"	NoCondition=""
+			Name="TableTopPitchRotationDirection"				Type="2C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopRollAngle"							Type="2C"	NoCondition=""
+			Name="TableTopRollRotationDirection"				Type="2C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="HeadFixationAngle"							Type="3"
+			Name="TableTopVerticalPosition"						Type="2C"	NoCondition=""
+			Name="TableTopLongitudinalPosition"					Type="2C"	NoCondition=""
+			Name="TableTopLateralPosition"						Type="2C"	NoCondition=""
+			Name="SnoutPosition"								Type="2C"	NoCondition=""
+			Name="IsocenterPosition"							Type="2C"	NoCondition=""
+			Name="SurfaceEntryPoint"							Type="3"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="RTIonBeamsSessionRecord"
+	Name="ReferencedFractionGroupNumber"						Type="3"
+	Name="NumberOfFractionsPlanned"								Type="2"
+	Name="PrimaryDosimeterUnit"									Type="1"	StringEnumValues="IonPrimaryDosimeterUnit"
+	Sequence="TreatmentSessionIonBeamSequence"					Type="1"	VM="1-n"
+		Name="ReferencedBeamNumber"								Type="1"
+		Name="BeamName"											Type="1"
+		Name="BeamDescription"									Type="3"
+		Name="BeamType"											Type="1"	StringEnumValues="BeamType"
+		Name="RadiationType"									Type="1"	StringDefinedTerms="IonRadiationType"
+		Name="RadiationMassNumber"								Type="1C"	Condition="RadiationTypeIsIon"
+		Name="RadiationAtomicNumber"							Type="1C"	Condition="RadiationTypeIsIon"
+		Name="RadiationChargeState"								Type="1C"	Condition="RadiationTypeIsIon"
+		Name="ScanMode"											Type="1"	StringDefinedTerms="IonScanMode"
+		Name="ReferencedToleranceTableNumber"					Type="3"
+		Sequence="BeamLimitingDeviceLeafPairsSequence"			Type="3"	VM="1-n"
+			Name="RTBeamLimitingDeviceType"						Type="1"	StringEnumValues="RTBeamLimitingDeviceType"
+			Name="NumberOfLeafJawPairs"							Type="1"
+		SequenceEnd
+		Name="ReferencedPatientSetupNumber"						Type="3"
+		Sequence="ReferencedVerificationImageSequence"			Type="3"	VM="1-n"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="ReferencedMeasuredDoseReferenceSequence"		Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1C"	Condition="ReferencedMeasuredDoseReferenceNumberNotPresent"
+			Name="ReferencedMeasuredDoseReferenceNumber"		Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+			Name="MeasuredDoseValue"							Type="1"
+		SequenceEnd
+		Sequence="ReferencedCalculatedDoseReferenceSequence"	Type="3"	VM="1-n"
+			Name="ReferencedDoseReferenceNumber"				Type="1C"	Condition="ReferencedCalculatedDoseReferenceNumberNotPresent"
+			Name="ReferencedCalculatedDoseReferenceNumber"		Type="1C"	Condition="ReferencedDoseReferenceNumberNotPresent"
+			Name="CalculatedDoseReferenceDoseValue"				Type="1"
+		SequenceEnd
+		Name="NumberOfWedges"									Type="1"
+		Sequence="RecordedWedgeSequence"						Type="1C"	VM="1-n"	Condition="NumberOfWedgesNotZero"
+			Name="WedgeNumber"									Type="1"
+			Name="WedgeType"									Type="2"	StringDefinedTerms="IonWedgeType"
+			Name="WedgeID"										Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="WedgeAngle"									Type="3"
+			Name="WedgeOrientation"								Type="3"
+		SequenceEnd
+		Name="NumberOfCompensators"								Type="1"
+		Sequence="RecordedCompensatorSequence"					Type="1C"	VM="1-n"	Condition="NumberOfCompensatorsNotZero"
+			Name="ReferencedCompensatorNumber"					Type="1"
+			Name="CompensatorType"								Type="2"	StringDefinedTerms="CompensatorType"
+			Name="CompensatorID"								Type="3"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfBoli"										Type="1"
+		Sequence="ReferencedBolusSequence"						Type="1C"	VM="1-n"	Condition="NumberOfBoliNotZero"
+			Name="ReferencedROINumber"							Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfBlocks"									Type="1"
+		Sequence="RecordedBlockSequence"						Type="1C"	VM="1-n"	Condition="NumberOfBlocksNotZero"
+			Name="BlockTrayID"									Type="3"
+			Name="AccessoryCode"								Type="3"
+			Name="ReferencedBlockNumber"						Type="1"
+			Name="BlockName"									Type="2"
+		SequenceEnd
+		Sequence="RecordedSnoutSequence"						Type="1C"	VM="1"	NoCondition=""
+			Name="SnoutID"										Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Sequence="ApplicatorSequence"							Type="1C"	VM="1"	NoCondition=""
+			Name="ApplicatorID"									Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="ApplicatorType"								Type="1"	StringDefinedTerms="IonApplicatorType"
+			Name="ApplicatorDescription"						Type="3"
+			Sequence="GeneralAccessorySequence"					Type="3"	VM="1-n"
+				Name="GeneralAccessoryNumber"					Type="1"
+				Name="GeneralAccessoryID"						Type="1"
+				Name="GeneralAccessoryDescription"				Type="3"
+				Name="GeneralAccessoryType"						Type="3"	StringDefinedTerms="RTGeneralAccessoryType"
+				Name="AccessoryCode"							Type="3"
+				Name="SourceToGeneralAccessoryDistance"			Type="3"
+			SequenceEnd
+		SequenceEnd
+		Name="NumberOfRangeShifters"							Type="1"
+		Sequence="RecordedRangeShifterSequence"					Type="1C"	VM="1-n"	Condition="NumberOfRangeShiftersNotZero"
+			Name="ReferencedRangeShifterNumber"					Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfLateralSpreadingDevices"					Type="1"
+		Sequence="RecordedLateralSpreadingDeviceSequence"		Type="1C"	VM="1-n"	Condition="NumberOfLateralSpreadingDevicesNotZero"
+			Name="ReferencedLateralSpreadingDeviceNumber"		Type="1"
+			Name="LateralSpreadingDeviceID"						Type="1"
+			Name="AccessoryCode"								Type="3"
+		SequenceEnd
+		Name="NumberOfRangeModulators"							Type="1"
+		Sequence="RecordedRangeModulatorSequence"				Type="1C"	VM="1-n"	Condition="NumberOfRangeModulatorsNotZero"
+			Name="ReferencedRangeModulatorNumber"				Type="1"
+			Name="RangeModulatorID"								Type="1"
+			Name="AccessoryCode"								Type="3"
+			Name="RangeModulatorType"							Type="1"	StringDefinedTerms="RangeModulatorType"
+			Name="BeamCurrentModulationID"						Type="1C"	Condition="RangeModulatorTypeIsWhlModWeights"
+		SequenceEnd
+		InvokeMacro="PatientSupportIdentificationMacro"
+		Name="FixationLightAzimuthalAngle"						Type="3"
+		Name="FixationLightPolarAngle"							Type="3"
+		Name="CurrentFractionNumber"							Type="2"
+		Name="TreatmentDeliveryType"							Type="2"	StringDefinedTerms="TreatmentDeliveryType"
+		Name="TreatmentTerminationStatus"						Type="1"	StringEnumValues="TreatmentTerminationStatus"
+		Name="TreatmentTerminationCode"							Type="3"
+		Name="TreatmentVerificationStatus"						Type="2"	StringEnumValues="TreatmentVerificationStatus"
+		Name="SpecifiedPrimaryMeterset"							Type="3"
+		Name="SpecifiedSecondaryMeterset"						Type="3"
+		Name="DeliveredPrimaryMeterset"							Type="3"
+		Name="DeliveredSecondaryMeterset"						Type="3"
+		Name="SpecifiedTreatmentTime"							Type="3"
+		Name="DeliveredTreatmentTime"							Type="3"
+		Name="NumberOfControlPoints"							Type="1"
+		Sequence="IonControlPointDeliverySequence"				Type="1"	VM="1-n"
+			Name="ReferencedControlPointIndex"					Type="1"
+			Name="TreatmentControlPointDate"					Type="1"
+			Name="TreatmentControlPointTime"					Type="1"
+			Name="SpecifiedMeterset"							Type="2"
+			Name="DeliveredMeterset"							Type="1"
+			Name="MetersetRateSet"								Type="3"
+			Name="MetersetRateDelivered"						Type="3"
+			Name="NominalBeamEnergy"							Type="1C"	NoCondition=""
+			Name="KVP"											Type="1C"	NoCondition=""
+			Sequence="IonWedgePositionSequence"					Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedWedgeNumber"					Type="1"
+				Name="WedgePosition"							Type="1"	StringEnumValues="WedgePosition"
+				Name="WedgeThinEdgePosition"					Type="1C"	NoCondition=""
+			SequenceEnd
+			InvokeMacro="BeamLimitingDevicePositionMacro"
+			Sequence="RangeShifterSettingsSequence"				Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedRangeShifterNumber"				Type="1"
+				Name="RangeShifterSetting"						Type="1"
+			SequenceEnd
+			Sequence="LateralSpreadingDeviceSettingsSequence"			Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedLateralSpreadingDeviceNumber"			Type="1"
+				Name="LateralSpreadingDeviceSetting"					Type="1"
+			SequenceEnd
+			Sequence="RangeModulatorSettingsSequence"						Type="1C"	VM="1-n"	NoCondition=""
+				Name="ReferencedRangeModulatorNumber"						Type="1"
+				Name="RangeModulatorGatingStartValue"						Type="1C"	NoCondition=""
+				Name="RangeModulatorGatingStopValue"						Type="1C"	NoCondition=""
+			SequenceEnd
+			Name="GantryAngle"									Type="1C"	NoCondition=""
+			Name="GantryRotationDirection"						Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="GantryPitchAngle"								Type="3"
+			Name="GantryPitchRotationDirection"					Type="3"	StringEnumValues="RotationDirectionWithNone"
+			Name="BeamLimitingDeviceAngle"						Type="1C"	NoCondition=""
+			Name="BeamLimitingDeviceRotationDirection"			Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="ScanSpotTuneID"								Type="1C"	Condition="ScanModeIsModulated"
+			Name="NumberOfScanSpotPositions"					Type="1C"	Condition="ScanModeIsModulated"
+			Name="ScanSpotPositionMap"							Type="1C"	Condition="ScanModeIsModulated"
+			Name="ScanSpotMetersetsDelivered"					Type="1C"	Condition="ScanModeIsModulated"
+			Name="ScanningSpotSize"								Type="3"
+			Name="NumberOfPaintings"							Type="1C"	Condition="ScanModeIsModulated"
+			Name="PatientSupportAngle"							Type="1C"	NoCondition=""
+			Name="PatientSupportRotationDirection"				Type="1C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopPitchAngle"							Type="2C"	NoCondition=""
+			Name="TableTopPitchRotationDirection"				Type="2C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="TableTopRollAngle"							Type="2C"	NoCondition=""
+			Name="TableTopRollRotationDirection"				Type="2C"	NoCondition=""	StringEnumValues="RotationDirectionWithNone"
+			Name="HeadFixationAngle"							Type="3"
+			Name="TableTopVerticalPosition"						Type="2C"	NoCondition=""
+			Name="TableTopLongitudinalPosition"					Type="2C"	NoCondition=""
+			Name="TableTopLateralPosition"						Type="2C"	NoCondition=""
+			Name="SnoutPosition"								Type="2C"	NoCondition=""
+			Sequence="CorrectedParameterSequence"				Type="3"	VM="1-n"
+				Name="ParameterSequencePointer"					Type="1"
+				Name="ParameterItemIndex"						Type="1"
+				Name="ParameterPointer"							Type="1"
+				Name="CorrectionValue"							Type="1"
+			SequenceEnd
+			Sequence="OverrideSequence"							Type="3"	VM="1-n"
+				Name="ParameterSequencePointer"					Type="1"
+				Name="OverrideParameterPointer"					Type="1"
+				Name="ParameterItemIndex"						Type="1"
+				Name="OperatorsName"							Type="2"
+				Name="OverrideReason"							Type="3"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
diff --git a/libsrc/standard/module/softcopy.tpl b/libsrc/standard/module/softcopy.tpl
new file mode 100755
index 0000000..45e077d
--- /dev/null
+++ b/libsrc/standard/module/softcopy.tpl
@@ -0,0 +1,386 @@
+Module="BitmapDisplayShutter"
+	Name="ShutterShape"							Type="1"	StringEnumValues="BitmapShutterShape"
+	Name="ShutterOverlayGroup"					Type="1"	BinaryEnumValues="AllPossibleOverlayGroups"
+	Name="ShutterPresentationValue"				Type="1"
+	Name="ShutterPresentationColorCIELabValue"	Type="3"
+ModuleEnd
+
+Module="DisplayedArea"
+	Sequence="DisplayedAreaSelectionSequence"		Type="1"	VM="1-n"
+		Sequence="ReferencedImageSequence"			Type="1C"	VM="1-n"	NoCondition=""	# realworld
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="PixelOriginInterpretation"			Type="1C"	Condition="VLWholeSlideMicroscopyImageInstance"	mbpo="true"	StringEnumValues="PixelOriginInterpretation"
+		Name="DisplayedAreaTopLeftHandCorner"		Type="1"
+		Name="DisplayedAreaBottomRightHandCorner"	Type="1"
+		Name="PresentationSizeMode"					Type="1"	StringEnumValues="PresentationSizeMode"
+		Name="PresentationPixelSpacing"				Type="1C"	NotZeroError=""	Condition="RequirePresentationPixelSpacing"
+		Name="PresentationPixelAspectRatio"			Type="1C"	NotZeroError=""	Condition="RequirePresentationPixelAspectRatio"
+		Name="PresentationPixelMagnificationRatio"	Type="1C"	NotZeroError=""	Condition="RequirePresentationPixelMagnificationRatio"
+	SequenceEnd
+ModuleEnd
+
+Module="GraphicAnnotation"
+	Sequence="GraphicAnnotationSequence"					Type="1"	VM="1-n"
+		Sequence="ReferencedImageSequence"					Type="1C"	VM="1-n"	NoCondition=""	# realworld
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="GraphicLayer"									Type="1"
+		Sequence="TextObjectSequence"						Type="1C"	VM="1-n"	Condition="RequireTextObjectSequence"
+			Name="BoundingBoxAnnotationUnits"				Type="1C"	Condition="BoundingBoxTopLeftHandCornerOrBottomRightHandCornerPresent"	StringEnumValues="AnnotationUnits"
+			Name="AnchorPointAnnotationUnits"				Type="1C"	Condition="AnchorPointPresent"	StringEnumValues="AnnotationUnits"
+			Name="UnformattedTextValue"						Type="1"
+			Name="BoundingBoxTopLeftHandCorner"				Type="1C"	Condition="BoundingBoxNeeded"
+			Name="BoundingBoxBottomRightHandCorner"			Type="1C"	Condition="BoundingBoxNeeded"
+			Name="BoundingBoxTextHorizontalJustification"	Type="1C"	Condition="BoundingBoxTopLeftHandCornerPresent"	StringEnumValues="BoundingBoxTextHorizontalJustification"
+			Name="AnchorPoint"								Type="1C"	Condition="AnchorPointNeeded" mbpo="true"
+			Name="AnchorPointVisibility"					Type="1C"	Condition="AnchorPointPresent"	StringEnumValues="YesNoLetter"
+		SequenceEnd
+		Sequence="GraphicObjectSequence"					Type="1C"	VM="1-n"	Condition="RequireGraphicObjectSequence"
+			Name="GraphicAnnotationUnits"					Type="1"	StringEnumValues="AnnotationUnits"
+			Name="GraphicDimensions"						Type="1"	BinaryEnumValues="Two"
+			Name="NumberOfGraphicPoints"					Type="1"	NotZeroError=""
+			Name="GraphicData"								Type="1"
+			Verify="GraphicData"										VM="2"	Condition="GraphicTypeIsPOINT"
+			Verify="GraphicData"										VM="4"	Condition="GraphicTypeIsCIRCLE"
+			Verify="GraphicData"										VM="8"	Condition="GraphicTypeIsELLIPSE"
+			Name="GraphicType"								Type="1"	StringEnumValues="GraphicType"
+			Name="GraphicFilled"							Type="1C"	NoCondition=""	StringEnumValues="YesNoLetter"	# very hard to check
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="SpatialTransformation"
+	Name="ImageRotation"					Type="1"	BinaryEnumValues="ImageRotationValues"
+	Name="ImageHorizontalFlip"				Type="1"	StringEnumValues="YesNoLetter"
+ModuleEnd
+
+Module="GraphicLayer"
+	Sequence="GraphicLayerSequence"							Type="1"	VM="1-n"
+		Name="GraphicLayer"									Type="1"
+		Name="GraphicLayerOrder"							Type="1"
+		Name="GraphicLayerRecommendedDisplayGrayscaleValue"	Type="3"
+		Name="GraphicLayerRecommendedDisplayCIELabValue"	Type="3"
+		Name="GraphicLayerDescription"						Type="3"
+	SequenceEnd
+
+ModuleEnd
+
+Module="SoftcopyPresentationLUT"
+	Sequence="PresentationLUTSequence"			Type="1C"	VM="1"	Condition="PresentationLUTShapeNotPresent"
+		Name="LUTDescriptor"					Type="1"
+		Verify="LUTDescriptor"								ValueSelector="2"	BinaryEnumValues="BitsAre8To16"
+		Name="LUTExplanation"					Type="3"
+		Name="LUTData"							Type="1"
+	SequenceEnd
+	Name="PresentationLUTShape"					Type="1C"	Condition="PresentationLUTSequenceNotPresent"	StringEnumValues="SoftcopyPresentationLUTShape"
+ModuleEnd
+
+Module="OverlayActivation"
+	Name="OverlayActivationLayer"				Type="2C"	NoCondition=""	# may require access to referenced image
+ModuleEnd
+
+Module="SoftcopyVOILUT"
+	Sequence="SoftcopyVOILUTSequence"			Type="1"	VM="1-n"
+		Sequence="ReferencedImageSequence"		Type="1C"	VM="1-n"	NoCondition=""	# realworld
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		InvokeMacro="VOILUTMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="PresentationSeries"
+	Name="Modality"								Type="1"	StringEnumValues="PresentationStateModality"
+ModuleEnd
+
+Module="PresentationStateIdentification"
+	Name="PresentationCreationDate"				Type="1"
+	Name="PresentationCreationTime"				Type="1"
+	InvokeMacro="ContentIdentificationMacro"
+ModuleEnd
+
+DefineMacro="PresentationStateRelationshipMacro"
+	Sequence="ReferencedSeriesSequence"			Type="1"	VM="1-n"
+		Name="SeriesInstanceUID"				Type="1"
+		Sequence="ReferencedImageSequence"		Type="1"	VM="1-n"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+Module="PresentationStateRelationship"
+	InvokeMacro="PresentationStateRelationshipMacro"
+ModuleEnd
+
+Module="PresentationStateShutter"
+	Name="ShutterPresentationValue"				Type="1C"	Condition="DisplayOrBitmapDisplayShutterModulePresent"
+	Name="ShutterPresentationColorCIELabValue"	Type="1C"	Condition="DisplayOrBitmapDisplayShutterModulePresentAndNotGrayscaleSoftcopyPresentationState"
+ModuleEnd
+
+Module="PresentationStateMask"
+	Sequence="MaskSubtractionSequence"			Type="1C"	VM="1"	Condition="MaskModulePresent"
+		Name="MaskOperation"					Type="1"	StringEnumValues="MaskOperationForPresentationState"
+		Name="ContrastFrameAveraging"			Type="1"
+	SequenceEnd
+	Name="RecommendedViewingMode"				Type="1C"	Condition="MaskModulePresent"	StringEnumValues="RecommendedViewingMode"
+ModuleEnd
+
+Module="PresentationStateBlending"
+	Sequence="BlendingSequence"								Type="1"	VM="2"
+		Name="BlendingPosition"								Type="1"	StringEnumValues="BlendingPosition"
+		Name="StudyInstanceUID"								Type="1"
+		InvokeMacro="PresentationStateRelationshipMacro"
+		InvokeMacro="ModalityLUTMacro"
+		Sequence="SoftcopyVOILUTSequence"					Type="1C"	VM="1-n"	NoCondition=""	# real-world "if a VOI LUT is to be applied"
+			Sequence="ReferencedImageSequence"				Type="1C"	VM="1-n"	NoCondition=""	# real-world "does not apply to all the images and frames in the enclosing Item"
+				InvokeMacro="ImageSOPInstanceReferenceMacro"
+			SequenceEnd
+			InvokeMacro="VOILUTMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="RelativeOpacity"								Type="1"
+	Sequence="ReferencedSpatialRegistrationSequence"	Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="ICCProfile"
+	Name="ICCProfile"											Type="1"
+ModuleEnd
+
+DefineMacro="HangingProtocolSelectorAttributeContextMacro"
+	Name="SelectorSequencePointer"							Type="1C"	NoCondition=""
+	Name="FunctionalGroupPointer"							Type="1C"	NoCondition=""
+	Name="SelectorSequencePointerPrivateCreator"			Type="1C"	NoCondition=""
+	Name="FunctionalGroupPrivateCreator"					Type="1C"	NoCondition=""
+	Name="SelectorAttributePrivateCreator"					Type="1C"	NoCondition=""
+MacroEnd
+
+DefineMacro="HangingProtocolSelectorAttributeValueMacro"
+	Name="SelectorATValue"						Type="1C"	Condition="SelectorAttributeVRIsAT"
+	Name="SelectorCSValue"						Type="1C"	Condition="SelectorAttributeVRIsCS"
+	Name="SelectorISValue"						Type="1C"	Condition="SelectorAttributeVRIsIS"
+	Name="SelectorLOValue"						Type="1C"	Condition="SelectorAttributeVRIsLO"
+	Name="SelectorLTValue"						Type="1C"	Condition="SelectorAttributeVRIsLT"
+	Name="SelectorPNValue"						Type="1C"	Condition="SelectorAttributeVRIsPN"
+	Name="SelectorSHValue"						Type="1C"	Condition="SelectorAttributeVRIsSH"
+	Name="SelectorSTValue"						Type="1C"	Condition="SelectorAttributeVRIsST"
+	Name="SelectorUTValue"						Type="1C"	Condition="SelectorAttributeVRIsUT"
+	Name="SelectorDSValue"						Type="1C"	Condition="SelectorAttributeVRIsDS"
+	Name="SelectorFDValue"						Type="1C"	Condition="SelectorAttributeVRIsFD"
+	Name="SelectorFLValue"						Type="1C"	Condition="SelectorAttributeVRIsFL"
+	Name="SelectorULValue"						Type="1C"	Condition="SelectorAttributeVRIsUL"
+	Name="SelectorUSValue"						Type="1C"	Condition="SelectorAttributeVRIsUS"
+	Name="SelectorSLValue"						Type="1C"	Condition="SelectorAttributeVRIsSL"
+	Name="SelectorSSValue"						Type="1C"	Condition="SelectorAttributeVRIsSS"
+	Sequence="SelectorCodeSequenceValue"		Type="1C"	VM="1-n"	Condition="SelectorAttributeVRIsSQ"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+MacroEnd
+
+Module="HangingProtocolDefinition"
+	Name="HangingProtocolName"									Type="1"
+	Name="HangingProtocolDescription"							Type="1"
+	Name="HangingProtocolLevel"									Type="1"	StringEnumValues="HangingProtocolLevel"
+	Name="HangingProtocolCreator"								Type="1"
+	Name="HangingProtocolCreationDateTime"						Type="1"
+	Sequence="HangingProtocolDefinitionSequence"				Type="1"	VM="1-n"
+		Name="Modality"											Type="1C"	Condition="AnatomicRegionSequenceNotPresent"	StringDefinedTerms="Modality"
+		Sequence="AnatomicRegionSequence"						Type="1C"	VM="1-n"	Condition="ModalityNotPresent"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="Laterality"										Type="2C"	Condition="AnatomicRegionSequencePresent"	StringDefinedTerms="ImageLaterality"
+		Sequence="ProcedureCodeSequence"						Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ReasonForRequestedProcedureCodeSequence"		Type="2"	VM="0-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="NumberOfPriorsReferenced"								Type="1"
+	Sequence="ImageSetsSequence"								Type="1"	VM="1-n"
+		Sequence="ImageSetSelectorSequence"						Type="1"	VM="1-n"
+			Name="ImageSetSelectorUsageFlag"					Type="1"	StringEnumValues="ImageSetSelectorUsageFlag"
+			Name="SelectorAttribute"							Type="1"
+			Name="SelectorAttributeVR"							Type="1"	StringEnumValues="SelectorAttributeVR"
+			InvokeMacro="HangingProtocolSelectorAttributeContextMacro"
+			InvokeMacro="HangingProtocolSelectorAttributeValueMacro"
+			Name="SelectorValueNumber"							Type="1"
+		SequenceEnd
+		Sequence="TimeBasedImageSetsSequence"					Type="1"	VM="1-n"
+			Name="ImageSetNumber"								Type="1"
+			Name="ImageSetSelectorCategory"						Type="1"	StringEnumValues="ImageSetSelectorCategory"
+			Name="RelativeTime"									Type="1C"	Condition="ImageSetSelectorCategoryIsRelativeTime"
+			Name="RelativeTimeUnits"							Type="1C"	Condition="RelativeTimePresent"	StringEnumValues="RelativeTimeUnits"
+			Name="AbstractPriorValue"							Type="1C"	Condition="ImageSetSelectorCategoryIsAbstractPriorAndAbstractPriorCodeSequenceNotPresent"
+			Sequence="AbstractPriorCodeSequence"				Type="1C"	VM="1"	Condition="ImageSetSelectorCategoryIsAbstractPriorAndAbstractPriorValueNotPresent"
+				InvokeMacro="CodeSequenceMacro"								DefinedContextID="31"
+			SequenceEnd
+			Name="ImageSetLabel"								Type="3"
+		SequenceEnd
+	SequenceEnd
+	Sequence="HangingProtocolUserIdentificationCodeSequence"	Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="HangingProtocolUserGroupName"							Type="3"
+	Sequence="SourceHangingProtocolSequence"					Type="3"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="HangingProtocolEnvironment"
+	Name="NumberOfScreens"										Type="2"
+	Sequence="NominalScreenDefinitionSequence"					Type="2"	VM="0-n"
+		InvokeMacro="ScreenSpecificationsMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="ScreenSpecificationsMacro"
+	Name="NumberOfVerticalPixels"								Type="1"
+	Name="NumberOfHorizontalPixels"								Type="1"
+	Name="DisplayEnvironmentSpatialPosition"					Type="1"
+	Name="ScreenMinimumGrayscaleBitDepth"						Type="1C"	Condition="ScreenMinimumColorBitDepthNotPresent"
+	Name="ScreenMinimumColorBitDepth"							Type="1C"	Condition="ScreenMinimumGrayscaleBitDepthNotPresent"
+	Name="ApplicationMaximumRepaintTime"						Type="3"
+MacroEnd
+
+Module="HangingProtocolDisplay"
+	Sequence="DisplaySetsSequence"								Type="1"	VM="1-n"
+		Name="DisplaySetNumber"									Type="1"
+		Name="DisplaySetLabel"									Type="3"
+		Name="DisplaySetPresentationGroup"						Type="1"
+		Name="ImageSetNumber"									Type="1"
+		Sequence="ImageBoxesSequence"							Type="1"	VM="1-n"	# is sometimes one, and sometimes more than one, depending on whether tiled :(
+			Name="ImageBoxNumber"								Type="1"
+			Name="DisplayEnvironmentSpatialPosition"			Type="1"
+			Name="ImageBoxLayoutType"							Type="1"	StringDefinedTerms="ImageBoxLayoutTypeForHangingProtocol"
+			Name="ImageBoxTileHorizontalDimension"				Type="1C"	Condition="ImageBoxLayoutTypeIsTiled"
+			Name="ImageBoxTileVerticalDimension"				Type="1C"	Condition="ImageBoxLayoutTypeIsTiled"
+			Name="ImageBoxScrollDirection"						Type="1C"	Condition="ImageBoxLayoutTypeIsTiledAndMoreThanOneTile"	StringEnumValues="ImageBoxScrollDirection"
+			Name="ImageBoxSmallScrollType"						Type="2C"	Condition="ImageBoxLayoutTypeIsTiledAndMoreThanOneTile"	StringEnumValues="ImageBoxScrollType"
+			Name="ImageBoxSmallScrollAmount"					Type="1C"	Condition="ImageBoxSmallScrollTypePresentWithValue"
+			Name="ImageBoxLargeScrollType"						Type="2C"	Condition="ImageBoxLayoutTypeIsTiledAndMoreThanOneTile"	StringEnumValues="ImageBoxScrollType"
+			Name="ImageBoxLargeScrollAmount"					Type="1C"	Condition="ImageBoxLargeScrollTypePresentWithValue"
+			Name="ImageBoxOverlapPriority"						Type="3"	# should check value is between 1 and 100
+			Name="PreferredPlaybackSequencing"					Type="1C"	Condition="ImageBoxLayoutTypeIsCine"	BinaryEnumValues="PreferredPlaybackSequencingForHangingProtocol"
+			Name="RecommendedDisplayFrameRate"					Type="1C"	Condition="ImageBoxLayoutTypeIsCineAndCineRelativeToRealTimeNotPresent"
+			Name="CineRelativeToRealTime"						Type="1C"	Condition="ImageBoxLayoutTypeIsCineAndRecommendedDisplayFrameRateNotPresent"
+		SequenceEnd
+		Sequence="FilterOperationsSequence"						Type="2"	VM="0-n"
+			Name="FilterByCategory"								Type="1C"	Condition="SelectorAttributeNotPresent"	StringDefinedTerms="FilterByCategory"
+			Name="FilterByAttributePresence"					Type="1C"	Condition="SelectorAttributePresentAndFilterByOperatorNotPresent"	StringDefinedTerms="FilterByAttributePresence"
+			Name="SelectorAttribute"							Type="1C"	Condition="FilterByCategoryNotPresent"
+			Name="SelectorAttributeVR"							Type="1C"	Condition="SelectorAttributeOrFilterByCategoryAndFilterByOperatorPresent"
+			InvokeMacro="HangingProtocolSelectorAttributeContextMacro"
+			InvokeMacro="HangingProtocolSelectorAttributeValueMacro"
+			Name="SelectorValueNumber"							Type="1C"	Condition="SelectorAttributeAndFilterByOperatorPresent"
+			Name="FilterByOperator"								Type="1C"	Condition="SelectorAttributePresentAndFilterByAttributePresenceNotPresentOrFilterByCategoryPresent"	StringEnumValues="FilterByOperator"
+			Name="ImageSetSelectorUsageFlag"					Type="3"	StringEnumValues="ImageSetSelectorUsageFlag"
+		SequenceEnd
+		Sequence="SortingOperationsSequence"					Type="2"	VM="0-n"
+			Name="SelectorAttribute"							Type="1C"	Condition="SortByCategoryNotPresent"
+			InvokeMacro="HangingProtocolSelectorAttributeContextMacro"
+			Name="SelectorValueNumber"							Type="1C"	Condition="SelectorAttributePresent"
+			Name="SortByCategory"								Type="1C"	Condition="SelectorAttributeNotPresent"	StringDefinedTerms="SortByCategory"
+			Name="SortingDirection"								Type="1"	StringEnumValues="SortingDirection"
+		SequenceEnd
+		Name="BlendingOperationType"							Type="3"	StringDefinedTerms="BlendingOperationType"
+		Name="ReformattingOperationType"						Type="3"	StringDefinedTerms="ReformattingOperationType"
+		Name="ReformattingThickness"							Type="1C"	Condition="ReformattingOperationTypeIsSlabOrMPR"
+		Name="ReformattingInterval"								Type="1C"	Condition="ReformattingOperationTypeIsSlabOrMPR"
+		Name="ReformattingOperationInitialViewDirection"		Type="1C"	Condition="ReformattingOperationTypeIsMPROr3D"	StringDefinedTerms="ReformattingOperationInitialViewDirection"
+		Name="ThreeDRenderingType"								Type="1C"	Condition="ReformattingOperationTypeIs3D"	StringDefinedTerms="ThreeDRenderingType"
+		Name="DisplaySetPatientOrientation"						Type="3"
+		Name="DisplaySetHorizontalJustification"				Type="3"	StringEnumValues="DisplaySetHorizontalJustification"
+		Name="DisplaySetVerticalJustification"					Type="3"	StringEnumValues="DisplaySetVerticalJustification"
+		Name="VOIType"											Type="3"	StringDefinedTerms="VOIType"
+		Name="PseudoColorType"									Type="3"	StringDefinedTerms="PseudoColorType"
+		Name="ShowGrayscaleInverted"							Type="3"	StringDefinedTerms="YesNoFull"
+		Name="ShowImageTrueSizeFlag"							Type="3"	StringDefinedTerms="YesNoFull"
+		Name="ShowGraphicAnnotationFlag"						Type="3"	StringDefinedTerms="YesNoFull"
+		Name="ShowPatientDemographicsFlag"						Type="3"	StringDefinedTerms="YesNoFull"
+		Name="ShowAcquisitionTechniquesFlag"					Type="3"	StringDefinedTerms="YesNoFull"
+		Name="DisplaySetPresentationGroupDescription"			Type="3"
+	SequenceEnd
+	Name="PartialDataDisplayHandling"							Type="3"	StringEnumValues="PartialDataDisplayHandling"
+	Sequence="SynchronizedScrollingSequence"					Type="3"	VM="1-n"
+		Name="DisplaySetScrollingGroup"							Type="1"
+	SequenceEnd
+	Sequence="NavigationIndicatorSequence"						Type="3"	VM="1-n"
+		Name="NavigationDisplaySet"								Type="1C"	NoCondition=""	# real world
+		Name="ReferenceDisplaySets"								Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="ColorPaletteDefinition"
+	InvokeMacro="ContentIdentificationMacro"
+ModuleEnd
+
+Module="StructuredDisplay"
+	InvokeMacro="ContentIdentificationMacro"
+	Name="PresentationCreationDate"								Type="1"
+	Name="PresentationCreationTime"								Type="1"
+	Name="NumberOfScreens"										Type="1"
+	Verify="NumberOfScreens"												BinaryEnumValues="One"	Condition="BasicStructuredDisplayInstance"
+	Sequence="NominalScreenDefinitionSequence"					Type="1"	VM="1-n"	# should check length is == NumberOfScreens, but no mechanism for that :(
+		InvokeMacro="ScreenSpecificationsMacro"
+	SequenceEnd
+	Sequence="IconImageSequence"								Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	Name="StructuredDisplayBackgroundCIELabValue"				Type="3"
+	Name="EmptyImageBoxCIELabValue"								Type="3"
+ModuleEnd
+
+Module="StructuredDisplayImageBox"
+	Sequence="StructuredDisplayImageBoxSequence"				Type="1"	VM="1-n"
+		Name="DisplayEnvironmentSpatialPosition"				Type="1"
+		Name="ImageBoxNumber"									Type="1"
+		Name="ImageBoxLayoutType"								Type="1"	StringDefinedTerms="ImageBoxLayoutTypeForStructuredDisplay"
+		Name="ImageBoxOverlapPriority"							Type="3"
+		Verify="ImageBoxOverlapPriority"									Condition="ImageBoxOverlapPriorityValueNot1To100"	ThenErrorMessage="Is not a positive integer in the range 1 to 100" ShowValueWithMessage="true"
+		Name="DisplaySetHorizontalJustification"				Type="3"	StringEnumValues="DisplaySetHorizontalJustification"
+		Name="DisplaySetVerticalJustification"					Type="3"	StringEnumValues="DisplaySetVerticalJustification"
+		Name="PreferredPlaybackSequencing"						Type="1C"	Condition="ImageBoxLayoutTypeIsCine"	BinaryEnumValues="PreferredPlaybackSequencingForStructuredDisplay"
+		Name="RecommendedDisplayFrameRate"						Type="1C"	Condition="ImageBoxLayoutTypeIsCineAndCineRelativeToRealTimeNotPresent"
+		Verify="RecommendedDisplayFrameRate"								Condition="RecommendedDisplayFrameRateNotGreaterThanZero"	ThenErrorMessage="Is not greater than 0" ShowValueWithMessage="true"
+		Name="CineRelativeToRealTime"							Type="1C"	Condition="ImageBoxLayoutTypeIsCineAndRecommendedDisplayFrameRateNotPresent"
+		Verify="CineRelativeToRealTime"										Condition="CineRelativeToRealTimeNotGreaterThanZero"	ThenErrorMessage="Is not greater than 0" ShowValueWithMessage="true"
+		Name="InitialCineRunState"								Type="1C"	Condition="ImageBoxLayoutTypeIsCine"	StringDefinedTerms="InitialCineRunState"
+		Name="StartTrim"										Type="2C"	Condition="ImageBoxLayoutTypeIsCine"
+		Name="StopTrim"											Type="2C"	Condition="ImageBoxLayoutTypeIsCine"
+		Sequence="ReferencedFirstFrameSequence"					Type="2C"	VM="0-1"	Condition="ImageBoxLayoutTypeIsStack"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="ReferencedImageSequence"						Type="2C"	VM="0-n"	Condition="NoReferencedPresentationStateOrStereometricInstanceOrInstance"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+			Sequence="ReferencedPresentationStateSequence"		Type="1C"	VM="1"		NoCondition=""
+				InvokeMacro="SOPInstanceReferenceMacro"
+			SequenceEnd
+		SequenceEnd
+		Sequence="ReferencedPresentationStateSequence"			Type="1C"	VM="1"		Condition="NoReferencedImageOrStereometricInstanceOrInstance"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="ReferencedInstanceSequence"					Type="1C"	VM="1"		Condition="NoReferencedPresentationStateOrStereometricInstanceOrImage"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="ReferencedStereometricInstanceSequence"		Type="1C"	VM="1"		Condition="NoReferencedPresentationStateOrInstanceOrImage"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="ImageBoxSynchronizationSequence"					Type="1C"	VM="1-n"	NoCondition=""
+		Name="SynchronizedImageBoxList"							Type="1"	VM="2-n"
+		Name="TypeOfSynchronization"							Type="1"				StringEnumValues="TypeOfSynchronizationBetweenImageBoxes"
+	SequenceEnd
+ModuleEnd
+
+Module="StructuredDisplayAnnotation"
+	Sequence="StructuredDisplayTextBoxSequence"					Type="1"	VM="1-n"
+		Name="UnformattedTextValue"								Type="1"
+		Name="DisplayEnvironmentSpatialPosition"				Type="1"
+		Name="BoundingBoxTextHorizontalJustification"			Type="1"				StringEnumValues="BoundingBoxTextHorizontalJustification"
+		Name="GraphicLayerRecommendedDisplayCIELabValue"		Type="3"
+	SequenceEnd
+ModuleEnd
+
+
diff --git a/libsrc/standard/module/specimen.tpl b/libsrc/standard/module/specimen.tpl
new file mode 100755
index 0000000..effc5e6
--- /dev/null
+++ b/libsrc/standard/module/specimen.tpl
@@ -0,0 +1,55 @@
+DefineMacro="SpecimenMacro"
+	Name="ContainerIdentifier"								Type="1"
+	Sequence="IssuerOfTheContainerIdentifierSequence"		Type="2"	VM="0-1"
+		InvokeMacro="HL7v2HierarchicDesignatorMacro"
+	SequenceEnd
+	Sequence="AlternateContainerIdentifierSequence"			Type="3"	VM="1-n"
+		Name="ContainerIdentifier"							Type="1"
+		Sequence="IssuerOfTheContainerIdentifierSequence"	Type="2"	VM="0-1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="ContainerTypeCodeSequence"					Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"						BaselineContextID="8101"
+	SequenceEnd
+	Name="ContainerDescription"								Type="3"
+	Sequence="ContainerComponentSequence"					Type="3"	VM="1-n"
+		Sequence="ContainerComponentTypeCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"					BaselineContextID="8102"
+		SequenceEnd
+		Name="Manufacturer"									Type="3"
+		Name="ManufacturerModelName"						Type="3"
+		Name="ContainerComponentID"							Type="3"
+		Name="ContainerComponentLength"						Type="3"
+		Name="ContainerComponentWidth"						Type="3"
+		Name="ContainerComponentDiameter"					Type="3"
+		Name="ContainerComponentThickness"					Type="3"
+		Name="ContainerComponentMaterial"					Type="3"	StringDefinedTerms="ContainerComponentMaterial"
+		Name="ContainerComponentDescription"				Type="3"
+	SequenceEnd
+	Sequence="SpecimenDescriptionSequence"					Type="1"	VM="1-n"
+		Name="SpecimenIdentifier"							Type="1"
+		Sequence="IssuerOfTheSpecimenIdentifierSequence"	Type="2"	VM="0-1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="SpecimenUID"									Type="1"
+		Sequence="SpecimenTypeCodeSequence"					Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"					BaselineContextID="8103"
+		SequenceEnd
+		Name="SpecimenShortDescription"						Type="3"
+		Name="SpecimenDetailedDescription"					Type="3"
+		Sequence="SpecimenPreparationSequence"				Type="2"	VM="0-n"
+			Sequence="SpecimenPreparationStepContentItemSequence"	Type="1"	VM="1-n"
+				InvokeMacro="ContentItemMacro"
+			SequenceEnd
+		SequenceEnd
+		InvokeMacro="PrimaryAnatomicStructureMacro" 
+		Sequence="SpecimenLocalizationContentItemSequence"	Type="1C"	VM="1-n"	NoCondition=""	mbpo="true" # real-world multiple specimens
+			InvokeMacro="ContentItemMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+Module="Specimen"
+	InvokeMacro="SpecimenMacro"
+ModuleEnd
diff --git a/libsrc/standard/module/sr.tpl b/libsrc/standard/module/sr.tpl
new file mode 100755
index 0000000..e43f262
--- /dev/null
+++ b/libsrc/standard/module/sr.tpl
@@ -0,0 +1,380 @@
+DefineMacro="HierarchicalSOPInstanceReferenceMacro"
+	Name="StudyInstanceUID"									Type="1"
+	Sequence="ReferencedSeriesSequence"						Type="1"	VM="1-n"
+		InvokeMacro="HierarchicalSeriesReferenceMacro"
+	SequenceEnd
+MacroEnd
+	
+DefineMacro="HierarchicalSeriesReferenceMacro"
+	Name="SeriesInstanceUID"							Type="1"
+	Name="RetrieveAETitle"								Type="3"
+	Name="RetrieveLocationUID"							Type="3"
+	Name="StorageMediaFileSetID"						Type="3"
+	Name="StorageMediaFileSetUID"						Type="3"
+	Sequence="ReferencedSOPSequence"					Type="1"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"		Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ReferencedDigitalSignatureSequence"	Type="3"	VM="1-n"
+			Name="DigitalSignatureUID"					Type="1"
+			Name="Signature"							Type="1"
+		SequenceEnd
+		Sequence="ReferencedSOPInstanceMACSequence"		Type="3"	VM="1"
+			Name="MACCalculationTransferSyntaxUID"		Type="1"
+			Name="MACAlgorithm"							Type="1"	StringDefinedTerms="MACAlgorithm"
+			Name="DataElementsSigned"					Type="1"
+			Name="MAC"									Type="1"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="IdentifiedPersonOrDeviceMacro"
+	Name="ObserverType"										Type="1"	StringEnumValues="ObserverType"
+	Name="PersonName"										Type="1C"	Condition="ObserverTypeIsPerson"
+	Sequence="PersonIdentificationCodeSequence"				Type="2C"	VM="0-1"	Condition="ObserverTypeIsPerson"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="StationName"										Type="2C"	Condition="ObserverTypeIsDevice"
+	Name="DeviceUID"										Type="1C"	Condition="ObserverTypeIsDevice"
+	Name="Manufacturer"										Type="1C"	Condition="ObserverTypeIsDevice"
+	Name="ManufacturerModelName"							Type="1C"	Condition="ObserverTypeIsDevice"
+	Name="InstitutionName"									Type="2"
+	Sequence="InstitutionCodeSequence"						Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="NumericMeasurementMacro"
+	Sequence="MeasuredValueSequence"						Type="2"	VM="0-1"
+		Name="NumericValue"									Type="1"
+		Name="FloatingPointValue"							Type="1C"	NoCondition=""
+		Name="RationalNumeratorValue"						Type="1C"	NoCondition=""
+		Name="RationalDenominatorValue"						Type="1C"	Condition="RationalNumeratorValueIsPresent" NotZeroError=""
+		Sequence="MeasurementUnitsCodeSequence"				Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"								DefinedContextID="82"
+		SequenceEnd
+	SequenceEnd
+	Sequence="NumericValueQualifierCodeSequence"			Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"									DefinedContextID="42"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CodeMacro"
+	Sequence="ConceptCodeSequence"							Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CompositeObjectReferenceMacro"
+	Sequence="ReferencedSOPSequence"								Type="1"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="ImageReferenceMacro"
+	Sequence="ReferencedSOPSequence"								Type="1"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Name="ReferencedFrameNumber"								Type="1C"	NoCondition=""	NotZeroError=""	# cannot just check SOP Class and mbpo false, since may be absent for multi-frame if applies to all frames (including multi-frame SOP Class with only 1 frame) :(
+		Verify="ReferencedFrameNumber"											Condition="ReferencedFrameNumberPresentAndReferencedSOPClassUIDIsNotMultiFrame"	ThenErrorMessage="May not be present for Referenced SOP Class that is not multi-frame"
+		Name="ReferencedSegmentNumber"								Type="1C"	NoCondition=""	NotZeroError=""	# cannot just check SOP Class and mbpo false, since may be absent for segmentation if applies to all segments :(
+		Verify="ReferencedSegmentNumber"										Condition="ReferencedSegmentNumberPresentAndReferencedSOPClassUIDIsNotSegmentationOrSurfaceSegmentation"	ThenErrorMessage="May not be present for Referenced SOP Class that is not segmentation"
+		Verify="ReferencedSegmentNumber"										Condition="ReferencedFrameNumberAndReferencedSegmentNumberPresent"	ThenErrorMessage="May not be present when ReferencedFrameNumber is present"
+		Sequence="ReferencedSOPSequence"							Type="3"	VM="1"	# presentation states
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="ReferencedRealWorldValueMappingInstanceSequence"	Type="3"	VM="1"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="IconImageSequence"								Type="3"	VM="1"
+			InvokeMacro="IconImageSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="WaveformReferenceMacro"
+	Sequence="ReferencedSOPSequence"								Type="1"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Name="ReferencedWaveformChannels"							Type="1C"	NoCondition=""  # too hard for multi-channel :(
+	SequenceEnd
+MacroEnd
+
+DefineMacro="SpatialCoordinatesMacro"
+	Name="GraphicData"					Type="1"
+	Verify="GraphicData"							VM="2"	Condition="GraphicTypeIsPOINT"
+	Verify="GraphicData"							VM="4"	Condition="GraphicTypeIsCIRCLE"
+	Verify="GraphicData"							VM="8"	Condition="GraphicTypeIsELLIPSE"
+	Name="GraphicType"					Type="1"	StringEnumValues="SRGraphicType"
+	Name="PixelOriginInterpretation"	Type="1C"	NoCondition=""	StringEnumValues="PixelOriginInterpretation"
+	Name="FiducialUID"					Type="3"
+MacroEnd
+
+DefineMacro="SpatialCoordinates3DMacro"
+	Name="ReferencedFrameOfReferenceUID"	Type="3"
+	Name="GraphicData"						Type="1"
+	Verify="GraphicData"								VM="3"	Condition="GraphicTypeIsPOINT"
+	Verify="GraphicData"								VM="12"	Condition="GraphicTypeIsELLIPSE"
+	Verify="GraphicData"								VM="18"	Condition="GraphicTypeIsELLIPSOID"
+	Name="GraphicType"						Type="1"	StringEnumValues="SRGraphicType3D"
+	Name="FiducialUID"						Type="3"
+MacroEnd
+
+DefineMacro="TemporalCoordinatesMacro"
+	Name="TemporalRangeType"			Type="1"	StringEnumValues="TemporalRangeType"
+	Name="ReferencedSamplePositions"	Type="1C"	Condition="NoReferencedDateTimeOrReferencedTimeOffsets"
+	Name="ReferencedTimeOffsets"		Type="1C"	Condition="NoReferencedDateTimeOrReferencedSamplePositions"
+	Name="ReferencedDateTime"			Type="1C"	Condition="NoReferencedTimeOffsetsOrReferencedSamplePositions"
+MacroEnd
+
+DefineMacro="ContainerMacro"
+	Name="ContinuityOfContent"			Type="1"	StringEnumValues="ContinuityOfContent"
+	Sequence="ContentTemplateSequence"	Type="1C"	VM="1"	NoCondition=""
+		Name="MappingResource"			Type="1"	StringDefinedTerms="SRTemplateMappingResource"
+		Name="MappingResourceUID"		Type="3"	StringDefinedTerms="MappingResourceUIDs"
+		Name="TemplateIdentifier"		Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="DocumentContentMacro"
+	Name="ValueType"								Type="1"	StringEnumValues="SRValueTypes"
+	Verify="ValueType"											Condition="BasicTextSRStorageInstance"	StringEnumValues="BasicTextSRValueTypes"
+	Verify="ValueType"											Condition="EnhancedSRStorageInstance"	StringEnumValues="EnhancedAndComprehensiveSRValueTypes"
+	Verify="ValueType"											Condition="ComprehensiveSRStorageInstance"	StringEnumValues="EnhancedAndComprehensiveSRValueTypes"
+	Verify="ValueType"											Condition="KeyObjectSelectionDocumentStorageInstance"	StringEnumValues="KeyObjectSelectionDocumentValueTypes"
+	Verify="ValueType"											Condition="MammographyCADSRStorageInstance"	StringEnumValues="MammographyCADSRValueTypes"
+	Verify="ValueType"											Condition="ChestCADSRStorageInstance"	StringEnumValues="ChestCADSRValueTypes"
+	Verify="ValueType"											Condition="ProcedureLogStorageInstance"	StringEnumValues="ProcedureLogValueTypes"
+	Verify="ValueType"											Condition="XRayRadiationDoseSRStorageInstance"	StringEnumValues="XRayRadiationDoseSRValueTypes"
+	Sequence="ConceptNameCodeSequence"				Type="1C"	VM="1"	Condition="NeedConceptName"	mbpo="true"	# the mbpo is not correct but avoids incomplete condition issues
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="TextValue"								Type="1C"	Condition="ValueTypeIsText"
+	Name="DateTime"									Type="1C"	Condition="ValueTypeIsDateTime"
+	Name="Date"										Type="1C"	Condition="ValueTypeIsDate"
+	Name="Time"										Type="1C"	Condition="ValueTypeIsTime"
+	Name="PersonName"								Type="1C"	Condition="ValueTypeIsPersonName"
+	Name="UID"										Type="1C"	Condition="ValueTypeIsUID"
+	InvokeMacro="NumericMeasurementMacro"			Type="1C"	Condition="ValueTypeIsNum"
+	InvokeMacro="CodeMacro"							Type="1C"	Condition="ValueTypeIsCode"
+	InvokeMacro="CompositeObjectReferenceMacro"		Type="1C"	Condition="ValueTypeIsComposite"
+	InvokeMacro="ImageReferenceMacro"				Type="1C"	Condition="ValueTypeIsImage"
+	InvokeMacro="WaveformReferenceMacro"			Type="1C"	Condition="ValueTypeIsWaveform"
+	InvokeMacro="SpatialCoordinatesMacro"			Type="1C"	Condition="ValueTypeIsSpatialCoordinates"
+	InvokeMacro="SpatialCoordinates3DMacro"			Type="1C"	Condition="ValueTypeIsSpatialCoordinates3D"
+	InvokeMacro="ContainerMacro"					Type="1C"	Condition="ValueTypeIsContainer"
+MacroEnd
+
+DefineMacro="DocumentRelationshipMacro"
+	Name="ObservationDateTime"								Type="1C"	NoCondition=""	# Real world condition
+	Name="ObservationUID"									Type="3"
+	Sequence="ContentSequence"								Type="1C"	VM="1-n"	NoCondition=""  # whether or not leaf is real world
+		Name="RelationshipType"								Type="1"	StringDefinedTerms="SRRelationshipType"
+		InvokeMacro="DocumentRelationshipMacro"				Type="1C"	Condition="RelationshipByValue"
+		InvokeMacro="DocumentContentMacro"					Type="1C"	Condition="RelationshipByValue"
+		Name="ReferencedContentItemIdentifier"				Type="1C"	Condition="RelationshipByReference"	NotZeroError=""
+	SequenceEnd
+MacroEnd
+
+Module="SRDocumentSeries"
+	Name="Modality"										Type="1"	StringEnumValues="SRModality"
+	Name="SeriesInstanceUID"							Type="1"
+	Name="SeriesNumber"									Type="1"
+	Name="SeriesDate"									Type="3"
+	Name="SeriesTime"									Type="3"
+	Name="ProtocolName"									Type="3"
+	Name="SeriesDescription"							Type="3"
+	Sequence="SeriesDescriptionCodeSequence"			Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="2"	VM="0-1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="SRDocumentGeneral"
+	Name="InstanceNumber"											Type="1"
+	Name="PreliminaryFlag"											Type="3"	StringEnumValues="PreliminaryFlag"
+	Name="CompletionFlag"											Type="1"	StringEnumValues="CompletionFlag"
+	Name="CompletionFlagDescription"								Type="3"
+	Name="VerificationFlag"											Type="1"	StringEnumValues="VerificationFlag"
+	Verify="VerificationFlag"													Condition="VerificationFlagIsVerifiedAndCompletionFlagIsNotComplete"	ThenErrorMessage="Only permitted to be VERIFIED if CompletionFlag is COMPLETE"
+	Name="ContentDate"												Type="1"
+	Name="ContentTime"												Type="1"
+	Sequence="VerifyingObserverSequence"							Type="1C"	VM="1-n"	Condition="VerificationFlagIsVerified"
+		Name="VerifyingObserverName"								Type="1"
+		Sequence="VerifyingObserverIdentificationCodeSequence"		Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="VerifyingOrganization"								Type="1"
+		Name="VerificationDateTime"									Type="1"
+	SequenceEnd
+	Sequence="AuthorObserverSequence"								Type="3"	VM="1-n"
+		InvokeMacro="IdentifiedPersonOrDeviceMacro"
+	SequenceEnd
+	Sequence="ParticipantSequence"									Type="3"	VM="1-n"
+		Name="ParticipationType"									Type="1"	StringDefinedTerms="ParticipationType"
+		Name="ParticipationDateTime"								Type="2"
+		InvokeMacro="IdentifiedPersonOrDeviceMacro"
+	SequenceEnd
+	Sequence="CustodialOrganizationSequence"						Type="3"	VM="1"
+		Name="InstitutionName"										Type="2"
+		Sequence="InstitutionCodeSequence"							Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PredecessorDocumentsSequence"							Type="1C"	VM="1-n"	NoCondition=""	# real world
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="IdenticalDocumentsSequence"							Type="1C"	VM="1-n"	NoCondition=""	# Real world condition
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedRequestSequence"							Type="1C"	VM="1-n"	NoCondition=""	# Real world condition
+		Name="StudyInstanceUID"										Type="1"
+		Sequence="ReferencedStudySequence"							Type="2"	VM="0-1"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="AccessionNumber"										Type="2"
+		Sequence="IssuerOfAccessionNumberSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="PlacerOrderNumberImagingServiceRequest"				Type="2"
+		Sequence="OrderPlacerIdentifierSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="FillerOrderNumberImagingServiceRequest"				Type="2"
+		Sequence="OrderFillerIdentifierSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="RequestedProcedureID"									Type="2"
+		Name="RequestedProcedureDescription"						Type="2"
+		Sequence="RequestedProcedureCodeSequence"					Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+ 		Name="ReasonForTheRequestedProcedure"						Type="3"
+		Sequence="ReasonForRequestedProcedureCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PerformedProcedureCodeSequence"						Type="2"	VM="0-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="CurrentRequestedProcedureEvidenceSequence"			Type="1C"	VM="1-n"	NoCondition=""	# real world
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="PertinentOtherEvidenceSequence"						Type="1C"	VM="1-n"	NoCondition=""	# real world
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedInstanceSequence"							Type="1C"	VM="1"	NoCondition=""	# real world
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"					Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="SRDocumentContent"
+	InvokeMacro="DocumentContentMacro"
+	Verify="ConceptNameCodeSequence"								Condition="ConceptNameCodeSequenceNotPresent"	ThenErrorMessage="ConceptNameCodeSequence is required for root content item (in top level dataset)"
+	InvokeMacro="DocumentRelationshipMacro"
+ModuleEnd
+
+Module="KeyObjectDocumentSeries"
+	Name="Modality"										Type="1"	StringEnumValues="KOModality"
+	Name="SeriesInstanceUID"							Type="1"
+	Name="SeriesNumber"									Type="1"
+	Name="SeriesDate"									Type="3"
+	Name="SeriesTime"									Type="3"
+	Name="ProtocolName"									Type="3"
+	Name="SeriesDescription"							Type="3"
+	Sequence="SeriesDescriptionCodeSequence"			Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="2"	VM="0-1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="KeyObjectDocument"
+	Name="InstanceNumber"											Type="1"
+	Name="ContentDate"												Type="1"
+	Name="ContentTime"												Type="1"
+	Sequence="ReferencedRequestSequence"							Type="1C"	VM="1-n"	NoCondition=""	# Real world condition
+		Name="StudyInstanceUID"										Type="1"
+		Sequence="ReferencedStudySequence"							Type="2"	VM="0-1"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="AccessionNumber"										Type="2"
+		Sequence="IssuerOfAccessionNumberSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="PlacerOrderNumberImagingServiceRequest"				Type="2"
+		Sequence="OrderPlacerIdentifierSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="FillerOrderNumberImagingServiceRequest"				Type="2"
+		Sequence="OrderFillerIdentifierSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="RequestedProcedureID"									Type="2"
+		Name="RequestedProcedureDescription"						Type="2"
+		Sequence="RequestedProcedureCodeSequence"					Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+ 		Name="ReasonForTheRequestedProcedure"						Type="3"
+		Sequence="ReasonForRequestedProcedureCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="CurrentRequestedProcedureEvidenceSequence"			Type="1"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="IdenticalDocumentsSequence"							Type="1C"	VM="1-n"	NoCondition=""	# real world
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="IHEREMProfile"
+	Name="SeriesDescription"										Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"				Type="1"	VM="1"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="PerformedProcedureCodeSequence"						Type="1"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="ReferencedRequestSequence"							Type="1C"	VM="1-n"	NoCondition=""	# Real world condition
+		Name="StudyInstanceUID"										Type="1"
+		Sequence="ReferencedStudySequence"							Type="2"	VM="0-1"
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Name="AccessionNumber"										Type="2"
+		Sequence="IssuerOfAccessionNumberSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="PlacerOrderNumberImagingServiceRequest"				Type="2"
+		Sequence="OrderPlacerIdentifierSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="FillerOrderNumberImagingServiceRequest"				Type="2"
+		Sequence="OrderFillerIdentifierSequence"					Type="3"	VM="1"
+			InvokeMacro="HL7v2HierarchicDesignatorMacro"
+		SequenceEnd
+		Name="RequestedProcedureID"									Type="2"
+		Name="RequestedProcedureDescription"						Type="1"
+		Sequence="RequestedProcedureCodeSequence"					Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+ 		Name="ReasonForTheRequestedProcedure"						Type="1"
+		Sequence="ReasonForRequestedProcedureCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="AdmittingDiagnosesDescription"							Type="1"
+	Sequence="AdmittingDiagnosesCodeSequence"						Type="1"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="PatientWeight"											Type="1"	NotZeroWarning=""
+	Name="PatientSize"												Type="1"	NotZeroWarning=""
+	Name="PatientAge"												Type="1"
+	Name="PatientSex"												Type="1"
+	
+ModuleEnd
diff --git a/libsrc/standard/module/us.tpl b/libsrc/standard/module/us.tpl
new file mode 100644
index 0000000..9546972
--- /dev/null
+++ b/libsrc/standard/module/us.tpl
@@ -0,0 +1,522 @@
+Module="EnhancedPaletteColorLookupTable"
+	Sequence="DataFrameAssignmentSequence"				Type="1"	VM="1-3"
+		Name="DataType"									Type="1"
+		Name="DataPathAssignment"						Type="1"	StringEnumValues="DataPathAssignment"
+		Name="BitsMappedToColorLookupTable"				Type="3"
+		InvokeMacro="VOILUTMacro"
+	SequenceEnd
+	Sequence="BlendingLUT1Sequence"						Type="1C"	VM="1"	Condition="AnyDataPathAssignmentIsOtherThanPrimaryPValues"
+		Name="BlendingLUT1TransferFunction"				Type="1"	StringEnumValues="BlendingLUT1TransferFunction"
+		Name="BlendingWeightConstant"					Type="1C"	Condition="BlendingLUT1TransferFunctionIsConstant"
+		Name="BlendingLookupTableDescriptor"			Type="1C"	Condition="BlendingLUT1TransferFunctionIsTable"
+		Verify="BlendingLookupTableDescriptor"						ValueSelector="1"	BinaryEnumValues="Zero"	
+		Name="BlendingLookupTableData"					Type="1C"	Condition="BlendingLUT1TransferFunctionIsTable"
+	SequenceEnd
+	Sequence="BlendingLUT2Sequence"						Type="1C"	VM="1"	Condition="AnyDataPathAssignmentIsOtherThanPrimaryPValues"
+		Name="BlendingLUT2TransferFunction"				Type="1"	StringEnumValues="BlendingLUT2TransferFunction"
+		Name="BlendingWeightConstant"					Type="1C"	Condition="BlendingLUT2TransferFunctionIsConstant"
+		Name="BlendingLookupTableDescriptor"			Type="1C"	Condition="BlendingLUT1TransferFunctionIsTable"
+		Verify="BlendingLookupTableDescriptor"						ValueSelector="1"	BinaryEnumValues="Zero"	
+		Name="BlendingLookupTableData"					Type="1C"	Condition="BlendingLUT1TransferFunctionIsTable"
+	SequenceEnd
+	Sequence="EnhancedPaletteColorLookupTableSequence"	Type="1C"	VM="1-2"	Condition="AnyDataPathAssignmentIsOtherThanPrimaryPValues"
+		Name="DataPathID"								Type="1"	StringEnumValues="DataPathID"
+		Name="RGBLUTTransferFunction"					Type="1"	StringEnumValues="RGBLUTTransferFunction"
+		Name="AlphaLUTTransferFunction"					Type="1"	StringEnumValues="AlphaLUTTransferFunction"
+		Name="RedPaletteColorLookupTableDescriptor"		Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Verify="RedPaletteColorLookupTableDescriptor"				ValueSelector="1"	BinaryEnumValues="Zero"	
+		Name="GreenPaletteColorLookupTableDescriptor"	Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Verify="GreenPaletteColorLookupTableDescriptor"				ValueSelector="1"	BinaryEnumValues="Zero"	
+		Name="BluePaletteColorLookupTableDescriptor"	Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Verify="BluePaletteColorLookupTableDescriptor"				ValueSelector="1"	BinaryEnumValues="Zero"	
+		Name="AlphaPaletteColorLookupTableDescriptor"	Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Verify="AlphaPaletteColorLookupTableDescriptor"				ValueSelector="1"	BinaryEnumValues="Zero"	
+		Name="RedPaletteColorLookupTableData"			Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Name="GreenPaletteColorLookupTableData"			Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Name="BluePaletteColorLookupTableData"			Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+		Name="AlphaPaletteColorLookupTableData"			Type="1C"	Condition="RGBLUTTransferFunctionIsTable"
+	SequenceEnd
+	Name="ICCProfile"									Type="1C"	Condition="AnyDataPathAssignmentIsOtherThanPrimaryPValues"
+ModuleEnd
+
+DefineMacro="PlanePositionVolumeMacro" InformationEntity="FunctionalGroup"
+	Sequence="PlanePositionVolumeSequence"			Type="1"	VM="1"
+		Name="ImagePositionVolume"					Type="1" 
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PlaneOrientationVolumeMacro" InformationEntity="FunctionalGroup"
+	Sequence="PlaneOrientationVolumeSequence"		Type="1"	VM="1"
+		Name="ImageOrientationVolume"				Type="1" 
+	SequenceEnd
+MacroEnd
+
+DefineMacro="TemporalPositionMacro" InformationEntity="FunctionalGroup"
+	Sequence="TemporalPositionSequence"				Type="1"	VM="1"
+		Name="TemporalPositionTimeOffset"			Type="1" 
+	SequenceEnd
+MacroEnd
+
+DefineMacro="ImageDataTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="ImageDataTypeSequence"				Type="1"	VM="1"
+		Name="DataType"								Type="1"	StringDefinedTerms="EnhancedUSVolumeDataType"
+		Name="AliasedDataType"						Type="1"	StringEnumValues="YesNoFull"
+		Name="ZeroVelocityPixelValue"				Type="1C"	Condition="NeedZeroVelocityPixelValue" mbpo="true"
+	SequenceEnd
+MacroEnd
+
+Module="EnhancedUSSeries"
+	Name="Modality"										Type="1"	StringEnumValues="USOrIVUSModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="PerformedProtocolCodeSequence"			Type="1C"	VM="1"	NoCondition=""	mbpo="true"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="ProtocolContextSequence"				Type="3"	VM="1-n"
+			InvokeMacro="ContentItemMacro"
+			Sequence="ContentItemModifierSequence"		Type="3"	VM="1-n"
+				InvokeMacro="ContentItemMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	Name="PerformedProtocolType"						Type="1C"	Condition="PerformedProtocolCodeSequenceIsPresent"	StringEnumValues="PerformedProtocolType"
+ModuleEnd
+
+Module="UltrasoundFrameOfReference"
+	Name="VolumeFrameOfReferenceUID"						Type="1"
+	Name="UltrasoundAcquisitionGeometry"					Type="1"	StringDefinedTerms="UltrasoundAcquisitionGeometry"
+	Name="ApexPosition"										Type="1C"	Condition="UltrasoundAcquisitionGeometryIsApex"
+	Name="VolumeToTransducerRelationship"					Type="1C"	NoCondition=""	StringEnumValues="VolumeToTransducerRelationship"
+	Name="VolumeToTransducerMappingMatrix"					Type="1"
+	Name="PatientFrameOfReferenceSource"					Type="1C"	Condition="NeedPatientFrameOfReferenceSource"	StringEnumValues="PatientFrameOfReferenceSource"
+	Name="TableFrameOfReferenceUID"							Type="1C"	Condition="PatientFrameOfReferenceSourceIsTable"
+	Name="VolumeToTableMappingMatrix"						Type="1C"	Condition="PatientFrameOfReferenceSourceIsTable"
+ModuleEnd
+
+Module="EnhancedUSImage"
+	Name="ImageType"										Type="1"	VM="2-n"
+	Verify="ImageType"													ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"													ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"													ValueSelector="2"	StringEnumValues="EmptyValue"
+	Verify="ImageType"													ValueSelector="3"	StringEnumValues="EmptyValue"
+	Name="SamplesPerPixel"									Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"						Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"									Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"										Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="HighBit"											Type="1"	BinaryEnumValues="BitsAre7Or15"
+	Name="PixelRepresentation"								Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="DimensionOrganizationType"						Type="1"	StringEnumValues="DimensionOrganizationType3DOr3DTemporal"
+	Name="AcquisitionDateTime"								Type="1"
+	Name="AcquisitionDuration"								Type="1"
+	Name="PositionMeasuringDeviceUsed"						Type="1C"	Condition="NeedPositionMeasuringDeviceUsed"	StringEnumValues="PositionMeasuringDeviceUsed"	mbpo="true"
+	Name="LossyImageCompression"							Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"						Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="PresentationLUTShape"								Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Name="RescaleIntercept"									Type="1"	BinaryEnumValues="Zero"
+	Name="RescaleSlope"										Type="1"	BinaryEnumValues="One"
+	Sequence="SourceImageSequence"							Type="1C"	VM="1-n"	Condition="ImageTypeValue1Derived"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="ReferencedImageSequence"						Type="3"	VM="1-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="ReferencedRawDataSequence"					Type="3"	VM="1-n"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedInstanceSequence"					Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Name="NumberOfStages"									Type="1C"	Condition="PerformedProtocolTypeIsStaged"
+	Name="StageNumber"										Type="1C"	Condition="PerformedProtocolTypeIsStaged"
+	Sequence="StageCodeSequence"							Type="1C"	VM="1"	Condition="PerformedProtocolTypeIsStaged"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	InvokeMacro="MandatoryViewAndSliceProgressionDirectionMacro"
+	Sequence="EventTimerSequence"							Type="3"	VM="1-n"
+		Name="EventTimeOffset"								Type="1"
+		Sequence="EventCodeSequence"						Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="EventTimerNames"								Type="3"	VM="1"
+	SequenceEnd
+	InvokeMacro="GeneralAnatomyMandatoryMacro"
+	Name="BurnedInAnnotation"								Type="1"	StringEnumValues="NoFull"
+	Name="RecognizableVisualFeatures"						Type="3"	StringEnumValues="YesNoFull"
+	Sequence="IconImageSequence"							Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	Name="TransducerData"									Type="3"
+	Sequence="TransducerScanPatternCodeSequence"			Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"									DefinedContextID=12032"
+	SequenceEnd
+	Sequence="TransducerGeometryCodeSequence"				Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"									DefinedContextID=12033"
+	SequenceEnd
+	Sequence="TransducerBeamSteeringCodeSequence"			Type="1"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"									DefinedContextID=12034"
+	SequenceEnd
+	Sequence="TransducerApplicationCodeSequence"			Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"									DefinedContextID=12035"
+	SequenceEnd
+	Name="ProcessingFunction"								Type="3"
+	Name="MechanicalIndex"									Type="1"
+	Name="BoneThermalIndex"									Type="1"
+	Name="CranialThermalIndex"								Type="1"
+	Name="SoftTissueThermalIndex"							Type="1"
+	Name="DepthsOfFocus"									Type="1"
+	Name="DepthOfScanField"									Type="1"
+ModuleEnd
+
+Module="IVUSImage"
+	Name="IVUSAcquisition"									Type="1"	StringDefinedTerms="IVUSAcquisition"
+	Name="IVUSPullbackRate"									Type="1C"	Condition="IVUSAcquisitionIsMotor"
+	Name="IVUSGatedRate"									Type="1C"	Condition="IVUSAcquisitionIsGated"
+	Name="IVUSPullbackStartFrameNumber"						Type="1C"	Condition="IVUSAcquisitionIsMotorOrGated"	NotZeroError=""
+	Name="IVUSPullbackStopFrameNumber"						Type="1C"	Condition="IVUSAcquisitionIsMotorOrGated"	NotZeroError=""
+ModuleEnd
+
+Module="ExcludedIntervals"
+	Sequence="ExcludedIntervalsSequence"					Type="1C"	VM="1-n"	NoCondition=""
+		Name="ExclusionStartDateTime"						Type="1"
+		Name="ExclusionDuration"							Type="1"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="USImageDescriptionMacro" InformationEntity="FunctionalGroup"
+	Sequence="USImageDescriptionSequence"				Type="1"	VM="1"
+		Name="FrameType"								Type="1"	VM="2-n"
+		Verify="FrameType"											ValueSelector="0"	StringEnumValues="CommonEnhancedFrameType1"
+		Verify="FrameType"											ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"											ValueSelector="2"	StringEnumValues="EmptyValue"
+		Verify="FrameType"											ValueSelector="3"	StringEnumValues="EmptyValue"
+		Name="VolumetricProperties"						Type="1"	StringEnumValues="CommonCTMRVolumetricPropertiesImageLevel"
+		Name="VolumeBasedCalculationTechnique"			Type="1"	StringDefinedTerms="CommonCTMRVolumeBasedCalculationTechniqueImageLevel"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="USImageDescriptionMacroForEnhancedUSVolume" InformationEntity="FunctionalGroup"
+	Sequence="USImageDescriptionSequence"				Type="1"	VM="1"
+		Name="VolumetricProperties"						Type="1"	StringEnumValues="Volume"
+		Name="VolumeBasedCalculationTechnique"			Type="1"	StringEnumValues="None"
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForEnhancedUSVolume"
+	Sequence="SharedFunctionalGroupsSequence"			Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"				Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"				Condition="PlanePositionSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"				Condition="PlaneOrientationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"				Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"				Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequenceRegardlessOfImageType"
+		InvokeMacro="FrameVOILUTMacro"					Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"		Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"			Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PatientOrientationInFrameMacro"	Condition="PatientOrientationInFrameMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"			Condition="FrameDisplayShutterMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"	Condition="NeedRespiratorySynchronizationMacroInSharedFunctionalGroupSequenceRegardlessOfImageType"
+		InvokeMacro="PlaneOrientationVolumeMacro"
+		InvokeMacro="TemporalPositionMacro"				Condition="TemporalPositionMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ImageDataTypeMacro"				Condition="ImageDataTypeSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="USImageDescriptionMacro"
+		InvokeMacro="USImageDescriptionMacroForEnhancedUSVolume"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"			Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PixelMeasuresMacro"				Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"				Condition="PlanePositionSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"				Condition="PlaneOrientationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"				Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"				Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequenceRegardlessOfImageType"
+		InvokeMacro="FrameVOILUTMacro"					Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"		Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"			Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PatientOrientationInFrameMacro"	Condition="PatientOrientationInFrameMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"			Condition="FrameDisplayShutterMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"	Condition="NeedRespiratorySynchronizationMacroInPerFrameFunctionalGroupSequenceRegardlessOfImageType"
+		InvokeMacro="PlanePositionVolumeMacro"
+		InvokeMacro="TemporalPositionMacro"				Condition="TemporalPositionMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ImageDataTypeMacro"				Condition="ImageDataTypeSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="QTUSEnhancedUltrasoundVolumeProfilePatient"
+	Name="IssuerOfPatientID"								Type="1"
+ModuleEnd
+
+Module="QTUSEnhancedUltrasoundVolumeProfileStudy"
+	Name="StudyDate"										Type="1"
+	Name="StudyTime"										Type="1"
+	Name="StudyID"											Type="1"
+	Name="AccessionNumber"									Type="1"
+	Name="StudyDescription"									Type="1"
+	Sequence="ProcedureCodeSequence"						Type="1"	VM="1"
+		Name="CodeValue"									Type="1"	StringEnumValues="CodeValueForLOINCBreastUltrasound"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="CodingSchemeDesignatorLOINC"
+		Name="CodeMeaning"									Type="1"	StringEnumValues="CodeMeaningForLOINCBreastUltrasound"
+	SequenceEnd
+	Name="PatientSize"										Type="1"
+	Name="PatientWeight"									Type="1"
+ModuleEnd
+
+Module="QTUSEnhancedUltrasoundVolumeProfileSeries"
+	Name="SeriesNumber"										Type="1"
+	Name="Laterality"										Type="1"
+	Name="SeriesDate"										Type="1"
+	Name="SeriesTime"										Type="1"
+	Name="SeriesDescription"								Type="1"
+	Name="OperatorsName"									Type="1"
+	Name="BodyPartExamined"									Type="1"	StringEnumValues="BodyPartExaminedBreast"
+ModuleEnd
+
+Module="QTUSEnhancedUltrasoundVolumeProfileFrameOfReference"
+	Name="UltrasoundAcquisitionGeometry"					Type="1"	StringEnumValues="UltrasoundAcquisitionGeometryPatient"
+	Name="VolumeToTransducerRelationship"					Type="1"	StringEnumValues="VolumeToTransducerRelationshipFixed"
+
+	Name="VolumeToTransducerMappingMatrix"					Type="1"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="0"	BinaryEnumValues="One"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="1"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="2"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="3"	BinaryEnumValues="Zero"
+
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="4"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="5"	BinaryEnumValues="One"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="6"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="7"	BinaryEnumValues="Zero"
+
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="8"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="9"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="10"	BinaryEnumValues="One"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="11"	BinaryEnumValues="Zero"
+
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="12"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="13"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="14"	BinaryEnumValues="Zero"
+	Verify="VolumeToTransducerMappingMatrix"							ValueSelector="15"	BinaryEnumValues="One"
+
+	Name="PatientFrameOfReferenceSource"					Type="1"	StringEnumValues="PatientFrameOfReferenceSourceTable"
+
+	Name="TableFrameOfReferenceUID"							Type="1"
+	Name="VolumeToTableMappingMatrix"						Type="1"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="0"	BinaryEnumValues="One"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="1"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="2"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="3"	BinaryEnumValues="Zero"
+
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="4"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="5"	BinaryEnumValues="One"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="6"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="7"	BinaryEnumValues="Zero"
+
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="8"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="9"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="10"	BinaryEnumValues="One"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="11"	BinaryEnumValues="Zero"
+
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="12"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="13"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="14"	BinaryEnumValues="Zero"
+	Verify="VolumeToTableMappingMatrix"									ValueSelector="15"	BinaryEnumValues="One"
+
+	Name="SynchronizationFrameOfReferenceUID"				Type="1"
+	Name="SynchronizationTrigger"							Type="1"	StringEnumValues="SynchronizationTriggerNoTrigger"
+	Name="AcquisitionTimeSynchronized"						Type="1"	StringEnumValues="NoLetter"
+ModuleEnd
+
+Module="QTUSEnhancedUltrasoundVolumeProfileEquipment"
+	Name="Manufacturer"										Type="1"
+	Name="InstitutionName"									Type="1"
+	Name="InstitutionAddress"								Type="1"
+	Name="StationName"										Type="1"
+	Name="InstitutionalDepartmentName"						Type="1"
+	Name="ManufacturerModelName"							Type="1"
+	Name="DeviceSerialNumber"								Type="1"
+	Name="SoftwareVersions"									Type="1"
+ModuleEnd
+
+Module="QTUSEnhancedUltrasoundVolumeProfileInstance"
+	Name="InstanceNumber"									Type="1"
+	Name="ContentDate"										Type="1"
+	Name="ContentTime"										Type="1"
+
+	Name="ImageType"										Type="1"	VM="4"
+	Verify="ImageType"													ValueSelector="0"	StringEnumValues="ImageType1OriginalOnly"
+	Verify="ImageType"													ValueSelector="1"	StringEnumValues="ImageType2PrimaryOnly"
+	Verify="ImageType"													ValueSelector="2"	StringEnumValues="QTUSImageAndFrameTypeValue3"
+	Verify="ImageType"													ValueSelector="3"	StringEnumValues="EmptyValue"
+
+	Name="AcquisitionNumber"								Type="1"
+	Name="AcquisitionDateTime"								Type="1"
+	Name="BurnedInAnnotation"								Type="1"
+	Name="RecognizableVisualFeatures"						Type="1"
+	Name="LossyImageCompression"							Type="1"
+	Name="PresentationLUTShape"								Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+
+	Name="BitsAllocated"									Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"										Type="1"	BinaryEnumValues="BitsAre16"
+	Name="HighBit"											Type="1"	BinaryEnumValues="BitsAre15"
+	Name="PixelRepresentation"								Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+
+	Name="PositionMeasuringDeviceUsed"						Type="1"	StringEnumValues="PositionMeasuringDeviceUsedRigid"
+
+	Sequence="ViewCodeSequence"								Type="1"	VM="1"
+		Name="CodeValue"									Type="1"	StringEnumValues="CoronalCodeValue"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="CoronalCodingSchemeDesignator"
+		Name="CodeMeaning"									Type="1"	StringEnumValues="CoronalCodeMeaning"
+	SequenceEnd
+
+	Sequence="AnatomicRegionSequence"						Type="1"	VM="1"
+		Name="CodeValue"									Type="1"	StringEnumValues="BreastCodeValue"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="BreastCodingSchemeDesignator"
+		Name="CodeMeaning"									Type="1"	StringEnumValues="BreastCodeMeaning"
+	SequenceEnd
+
+	Sequence="TransducerScanPatternCodeSequence"			Type="1"	VM="1"
+		Name="CodeValue"									Type="1"	StringEnumValues="TransducerScanPatternCodeSequenceCodeValue"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="TransducerScanPatternCodeSequenceCodingSchemeDesignator"
+		Name="CodeMeaning"									Type="1"	StringEnumValues="TransducerScanPatternCodeSequenceCodeMeaning"
+	SequenceEnd
+
+	Sequence="TransducerGeometryCodeSequence"				Type="1"	VM="1"
+		Name="CodeValue"									Type="1"
+		Verify="CodeValue"												Condition="ImageTypeValue3IsSoundSpeedOrAttenuation"	StringEnumValues="TransducerGeometryCodeSequenceCodeValueForTransmission"
+		Verify="CodeValue"												Condition="ImageTypeValue3IsTissueIntensity"			StringEnumValues="TransducerGeometryCodeSequenceCodeValueForReflection"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="TransducerGeometryCodeSequenceCodingSchemeDesignator"
+		Name="CodeMeaning"									Type="1"
+		Verify="CodeMeaning"											Condition="ImageTypeValue3IsSoundSpeedOrAttenuation"	StringEnumValues="TransducerGeometryCodeSequenceCodeMeaningForTransmission"
+		Verify="CodeMeaning"											Condition="ImageTypeValue3IsTissueIntensity"			StringEnumValues="TransducerGeometryCodeSequenceCodeMeaningForReflection"
+	SequenceEnd
+
+	Sequence="TransducerBeamSteeringCodeSequence"			Type="1"	VM="1"
+		Name="CodeValue"									Type="1"	StringEnumValues="TransducerBeamSteeringCodeSequenceCodeValue"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="TransducerBeamSteeringCodeSequenceCodingSchemeDesignator"
+		Name="CodeMeaning"									Type="1"	StringEnumValues="TransducerBeamSteeringCodeSequenceCodeMeaning"
+	SequenceEnd
+
+	Sequence="TransducerApplicationCodeSequence"			Type="1"	VM="1"
+		Name="CodeValue"									Type="1"	StringEnumValues="TransducerApplicationCodeSequenceCodeValue"
+		Name="CodingSchemeDesignator"						Type="1"	StringEnumValues="TransducerApplicationCodeSequenceCodingSchemeDesignator"
+		Name="CodeMeaning"									Type="1"	StringEnumValues="TransducerApplicationCodeSequenceCodeMeaning"
+	SequenceEnd
+
+	Sequence="DimensionOrganizationSequence"				Type="1"	VM="1"
+		Name="DimensionOrganizationUID"						Type="1"
+	SequenceEnd
+	Name="DimensionOrganizationType"						Type="1"	StringEnumValues="DimensionOrganizationType3D"
+	Sequence="DimensionIndexSequence"						Type="1"	VM="3"
+		Name="DimensionIndexPointer"						Type="1"	TagEnumValues="QTUSDimensionOrganization3DDimensionIndexPointerValues"	# do not have sequence item specific selector mechansism so cannot check per item, but can check one of the expected values:(
+		Name="FunctionalGroupPointer"						Type="1"	TagEnumValues="QTUSDimensionOrganization3DFunctionalGroupPointerValues"	# do not have sequence item specific selector mechansism so cannot check per item, but can check one of the expected values:(
+		Name="DimensionOrganizationUID"						Type="1"
+		Name="DimensionDescriptionLabel"					Type="1"	StringEnumValues="QTUSDimensionDescriptionLabel"	# do not have sequence item specific selector mechansism so cannot check per item, but can check one of the expected values:(
+	SequenceEnd
+
+	Name="SpecificCharacterSet"								Type="1"	StringEnumValues="SpecificCharacterSetISOIR100"
+	Name="InstanceCreationDate"								Type="1"
+	Name="InstanceCreationTime"								Type="1"
+	Name="InstanceCreatorUID"								Type="1"
+	Name="TimezoneOffsetFromUTC"							Type="1"
+
+	Sequence="SharedFunctionalGroupsSequence"				Type="1"	VM="1"
+		InvokeMacro="QTUSPixelMeasuresMacro"
+		InvokeMacro="PlaneOrientationMacro"
+		InvokeMacro="FrameVOILUTMacro"
+		InvokeMacro="QTUSRealWorldValueMappingMacro"
+		InvokeMacro="PlaneOrientationVolumeMacro"
+		InvokeMacro="TemporalPositionMacro"
+		InvokeMacro="QTUSTemporalPositionMacro"
+		InvokeMacro="QTUSImageDataTypeMacro"
+		InvokeMacro="QTUSUSImageDescriptionMacro"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"				Type="1"	VM="1-n"
+		InvokeMacro="QTUSFrameContentMacro"
+		InvokeMacro="PlanePositionMacro"
+		InvokeMacro="PlanePositionVolumeMacro"
+	SequenceEnd
+
+ModuleEnd
+
+DefineMacro="QTUSFrameContentMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameContentSequence"							Type="1"	VM="1"
+		Name="FrameAcquisitionNumber"						Type="1"
+		Name="FrameReferenceDateTime"						Type="1"
+		Name="FrameAcquisitionDateTime"						Type="1"
+		Name="FrameAcquisitionDuration"						Type="1"
+		Name="DimensionIndexValues"							Type="1"
+		Name="TemporalPositionIndex"						Type="1"	BinaryEnumValues="One"
+		Name="StackID"										Type="1"	StringEnumValues="DigitOne"
+		Name="InStackPositionNumber"						Type="1"	NotZeroError=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="QTUSPixelMeasuresMacro" InformationEntity="FunctionalGroup"
+	Sequence="PixelMeasuresSequence"						Type="1"	VM="1"
+		Name="PixelSpacing"									Type="1"	NotZeroError=""
+		Name="SliceThickness"								Type="1"	NotZeroError=""
+		Name="SpacingBetweenSlices"							Type="1"	NotZeroError=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="QTUSRealWorldValueMappingMacro" InformationEntity="FunctionalGroup"
+	Sequence="RealWorldValueMappingSequence"		Type="1"	VM="1"
+		InvokeMacro="QTUSRealWorldValueMappingItemMacro"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="QTUSRealWorldValueMappingItemMacro" InformationEntity="FunctionalGroup"
+	Name="RealWorldValueFirstValueMapped"		Type="1" 	BinaryEnumValues="Zero"
+	Name="RealWorldValueLastValueMapped"		Type="1" 	BinaryEnumValues="FFFF"
+	Name="RealWorldValueIntercept"				Type="1" 	BinaryEnumValues="Zero"
+	Name="RealWorldValueSlope"					Type="1"	# should check scaled values once decided on ... hard to switch on DataType, since in functional group :(
+	Name="LUTExplanation"						Type="1"	StringEnumValues="QTUSRealWorldValueMappingLUTExplanation"	# should check scaled values once decided on ... hard to switch on DataType, since in functional group :(
+	Name="LUTLabel"								Type="1"	StringEnumValues="QTUSRealWorldValueMappingLUTLabel"	# should check scaled values once decided on ... hard to switch on DataType, since in functional group :(
+	Sequence="MeasurementUnitsCodeSequence"		Type="1"	VM="1"	# should check codes once decided on ... hard to switch on DataType, since in functional group :(
+		Name="CodeValue"						Type="1"	StringEnumValues="QTUSRealWorldValueMappingMeasurementUnitsCodeValue"
+		Name="CodingSchemeDesignator"			Type="1"	StringEnumValues="CodingSchemeDesignatorUCUM"
+		Name="CodeMeaning"						Type="1"	StringEnumValues="QTUSRealWorldValueMappingMeasurementUnitsCodeMeaning"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="QTUSImageDataTypeMacro" InformationEntity="FunctionalGroup"
+	Sequence="ImageDataTypeSequence"				Type="1"	VM="1"
+		Name="DataType"								Type="1"	StringEnumValues="QTUSEnhancedUSVolumeDataType"
+		Verify="DataType"										Condition="ImageTypeValue3IsSoundSpeed"			StringEnumValues="EnhancedUSVolumeDataTypeSoundSpeed"
+		Verify="DataType"										Condition="ImageTypeValue3IsAttenuation"		StringEnumValues="EnhancedUSVolumeDataTypeAttenuation"
+		Verify="DataType"										Condition="ImageTypeValue3IsTissueIntensity"	StringEnumValues="EnhancedUSVolumeDataTypeTissueIntensity"
+
+		Name="AliasedDataType"						Type="1"	StringEnumValues="NoFull"
+		Name="ZeroVelocityPixelValue"				Type="1C"	Condition="ImageTypeValue3IsSoundSpeed"	BinaryEnumValues="Zero"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="QTUSTemporalPositionMacro" InformationEntity="FunctionalGroup"
+	Sequence="TemporalPositionSequence"				Type="1"	VM="1"
+		Name="TemporalPositionTimeOffset"			Type="1"  	BinaryEnumValues="Zero"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="QTUSUSImageDescriptionMacro" InformationEntity="FunctionalGroup"
+	Sequence="USImageDescriptionSequence"				Type="1"	VM="1"
+		Name="FrameType"								Type="1"	VM="4"
+		Verify="FrameType"											ValueSelector="0"	StringEnumValues="ImageType1OriginalOnly"
+		Verify="FrameType"											ValueSelector="1"	StringEnumValues="ImageType2PrimaryOnly"
+		Verify="FrameType"											ValueSelector="2"	StringEnumValues="QTUSImageAndFrameTypeValue3"
+		Verify="FrameType"											Condition="ImageTypeValue3IsSoundSpeed"			ValueSelector="2"	StringEnumValues="QTUSImageAndFrameTypeValue3SoundSpeed"
+		Verify="FrameType"											Condition="ImageTypeValue3IsAttenuation"		ValueSelector="2"	StringEnumValues="QTUSImageAndFrameTypeValue3Attenuation"
+		Verify="FrameType"											Condition="ImageTypeValue3IsTissueIntensity"	ValueSelector="2"	StringEnumValues="QTUSImageAndFrameTypeValue3SoundSpeed"
+		Verify="FrameType"											ValueSelector="3"	StringEnumValues="EmptyValue"
+	SequenceEnd
+MacroEnd
diff --git a/libsrc/standard/module/vl.tpl b/libsrc/standard/module/vl.tpl
new file mode 100755
index 0000000..63d5e43
--- /dev/null
+++ b/libsrc/standard/module/vl.tpl
@@ -0,0 +1,918 @@
+Module="VLImage"
+	Name="ImageType"									Type="1"	ValueSelector="0"	StringEnumValues="ImageType1"
+	Verify="ImageType"									Type="1"	ValueSelector="1"	StringEnumValues="ImageType2"
+	Verify="ImageType"									Type="1"	ValueSelector="2"	StringEnumValues="VLImageType3"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2OrRGBorYBRFULL422orYBRPARTIAL420orYBRRCTorYBRICT"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre8"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre7"
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOneOrThree"
+	Verify="SamplesPerPixel"										Condition="PhotometricInterpretationNeedsOneSample"	BinaryEnumValues="One"
+	Verify="SamplesPerPixel"										Condition="PhotometricInterpretationNeedsThreeSamples"	BinaryEnumValues="Three"
+	Name="PlanarConfiguration"							Type="1C"	BinaryEnumValues="PlanarConfigurationIsColorByPixel"	Condition="SamplesPerPixelGreaterThanOne"
+	Name="ContentTime"									Type="1C"	NoCondition=""	# "if temporally related" ... real world
+	Name="LossyImageCompression"						Type="2"	StringEnumValues="LossyImageCompression"
+	Sequence="ReferencedImageSequence"					Type="1C"	VM="1-n"	Condition="ImageTypeValue3StereoLOrR" mbpo="true"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"		Type="2"	VM="0-1"
+			InvokeMacro="CodeSequenceMacro"							DefinedContextID="7201"
+		SequenceEnd
+	SequenceEnd
+	Name="WindowCenter"									Type="3C"	Condition="PhotometricInterpretationIsMonochrome2"
+	Name="WindowWidth"									Type="1C"	Condition="WindowCenterPresent" 	NotZeroError=""
+	Verify="WindowWidth"											Condition="WindowWidthIsNegative"	ThenErrorMessage="Not permitted to be negative" ShowValueWithMessage="true"
+	Sequence="AnatomicRegionSequence"					Type="1C"	VM="1"	Condition="MultiFrameIODAndNotSpecimen" mbpo="true"
+		InvokeMacro="CodeSequenceMacro"
+		Sequence="AnatomicRegionModifierSequence"		Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="2"
+		SequenceEnd
+	SequenceEnd
+	InvokeMacro="PrimaryAnatomicStructureMacro"
+ModuleEnd
+
+Module="VLEndoscopicSeriesPseudo"
+	Name="Modality"										Type="1"	StringEnumValues="VLEndoscopyModality"
+ModuleEnd
+
+Module="VLMicroscopicSeriesPseudo"
+	Name="Modality"										Type="1"	StringEnumValues="VLMicroscopyModality"
+ModuleEnd
+
+Module="VLSlideCoordinatesMicroscopicSeriesPseudo"
+	Name="Modality"										Type="1"	StringEnumValues="VLSlideCoordinatesMicroscopyModality"
+ModuleEnd
+
+Module="VLPhotographicSeriesPseudo"
+	Name="Modality"										Type="1"	StringEnumValues="VLPhotographyModality"
+ModuleEnd
+
+Module="SlideCoordinates"
+	Sequence="ImageCenterPointCoordinatesSequence"		Type="2"	VM="0-1"
+		Name="XOffsetInSlideCoordinateSystem"			Type="1"
+		Name="YOffsetInSlideCoordinateSystem"			Type="1"
+		Name="ZOffsetInSlideCoordinateSystem"			Type="2"
+	SequenceEnd
+ModuleEnd
+
+Module="OphthalmicPhotographySeries"
+	Name="Modality"										Type="1"	StringEnumValues="OphthalmologyModality"
+ModuleEnd
+
+Module="OphthalmicPhotography8BitImagePseudo"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre8"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre7"
+ModuleEnd
+
+Module="OphthalmicPhotography16BitImagePseudo"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre16"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre15"
+ModuleEnd
+
+Module="OphthalmicPhotographyImage"
+	Name="ImageType"									Type="1"	ValueSelector="0"	StringEnumValues="ImageType1"
+	Verify="ImageType"									Type="1"	ValueSelector="1"	StringEnumValues="OphthalmologyImageType2"
+	
+	Verify="ImageType"									Type="1"	Condition="ImageTypeValue1Derived" ValueSelector="2"	StringDefinedTerms="OphthalmologyImageType3IfDerived"
+	Verify="ImageType"												Condition="ImageTypeValue1DerivedAndImageTypeValue3MissingOrEmpty"	ThenErrorMessage="A value for Value 3 is required for DERIVED images"
+	Verify="ImageType"												Condition="ImageTypeValue1NotDerivedAndImageTypeValueNotMissingOrEmpty"	ThenErrorMessage="A value for Value 3 may not be present for non-DERIVED images"
+	
+	Verify="ImageType"									Type="1"	ValueSelector="3"	StringDefinedTerms="OphthalmologyImageType4"
+
+	Name="InstanceNumber"								Type="1"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOneOrThree"
+	Verify="SamplesPerPixel"										Condition="PhotometricInterpretationNeedsOneSample"	BinaryEnumValues="One"
+	Verify="SamplesPerPixel"										Condition="PhotometricInterpretationNeedsThreeSamples"	BinaryEnumValues="Three"
+	Name="SamplesPerPixelUsed"							Type="1C"	NoCondition="" BinaryEnumValues="SamplesPerPixelUsedIsTwo"		# condition is real world
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2OrRGBorYBRFULL422orYBRPARTIAL420orYBRRCTorYBRICT"
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="PlanarConfiguration"							Type="1C"	BinaryEnumValues="PlanarConfigurationIsColorByPixel"	Condition="SamplesPerPixelGreaterThanOne"
+	Name="PixelSpacing"									Type="1C"	NoCondition=""		# too hard to check code in Acquisition Device Type Code Sequence :(
+	Name="ContentDate"									Type="1"
+	Name="ContentTime"									Type="1"
+	Name="AcquisitionDateTime"							Type="1C"	Condition="ImageTypeValue1Original" mbpo="true"
+	Sequence="SourceImageSequence"						Type="2C"	VM="0-n"	Condition="ImageTypeValue1Derived"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							DefinedContextID="7202"
+		SequenceEnd
+	SequenceEnd
+	Name="LossyImageCompression"						Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"					Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"					Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"							Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="PresentationLUTShape"							Type="1C"	Condition="PhotometricInterpretationIsMonochrome2"	StringEnumValues="IdentityPresentationLUTShape"
+	Name="CalibrationImage"								Type="3"	StringEnumValues="YesNoFull"
+	Name="BurnedInAnnotation"							Type="1"	StringEnumValues="YesNoFull"
+	Name="RecognizableVisualFeatures"					Type="3"	StringEnumValues="YesNoFull"
+ModuleEnd
+
+Module="OphthalmicPhotographicParameters"
+	Sequence="AcquisitionDeviceTypeCodeSequence"		Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4202"
+	SequenceEnd
+	Sequence="IlluminationTypeCodeSequence"				Type="2"	VM="0-1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4203"
+	SequenceEnd
+	Sequence="LightPathFilterTypeStackCodeSequence"		Type="2"	VM="0-n"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4204"
+	SequenceEnd
+	Name="LightPathFilterPassThroughWavelength"			Type="3"
+	Name="LightPathFilterPassBand"						Type="3"
+	Sequence="ImagePathFilterTypeStackCodeSequence"		Type="2"	VM="0-n"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4204"
+	SequenceEnd
+	Name="ImagePathFilterPassThroughWavelength"			Type="3"
+	Name="ImagePathFilterPassBand"						Type="3"
+	Sequence="LensesCodeSequence"						Type="2"	VM="0-n"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4205"
+	SequenceEnd
+	Name="DetectorType"									Type="2"	StringDefinedTerms="OphthalmologyDetectorType"
+	Sequence="ChannelDescriptionCodeSequence"			Type="1C"	VM="1-3"	NoCondition=""
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4206"
+	SequenceEnd
+	Name="CameraAngleOfView"							Type="3"
+ModuleEnd
+
+DefineMacro="OphthalmicAcquisitionParametersMacro" InformationEntity="Image"
+	Sequence="RefractiveStateSequence"					Type="2"	VM="0-1"
+		Name="SphericalLensPower"						Type="1"	NotZeroWarning=""
+		Name="CylinderLensPower"						Type="1"	NotZeroWarning=""
+		Name="CylinderAxis"								Type="1"	NotZeroWarning=""
+	SequenceEnd
+	Name="EmmetropicMagnification"						Type="2"	NotZeroWarning=""
+	Name="IntraOcularPressure"							Type="2"	NotZeroWarning=""
+	Name="HorizontalFieldOfView"						Type="2"	NotZeroWarning=""
+	Name="PupilDilated"									Type="2"	StringEnumValues="YesNoFull"
+	Sequence="MydriaticAgentSequence"					Type="2C"	VM="0-n"	Condition="PupilDilatedIsYes"
+		Sequence="MydriaticAgentCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="4208"
+		SequenceEnd
+		Name="MydriaticAgentConcentration"				Type="3"	NotZeroWarning=""
+		Sequence="MydriaticAgentConcentrationUnitsSequence"	Type="1C"	VM="1" Condition="MydriaticAgentConcentrationIsPresent"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="3082"
+		SequenceEnd
+	SequenceEnd
+	Name="DegreeOfDilation"								Type="2C"	Condition="PupilDilatedIsYes"
+MacroEnd
+
+Module="OphthalmicPhotographyAcquisitionParameters"
+	Name="PatientEyeMovementCommanded"					Type="2"	StringEnumValues="YesNoFull"
+	Sequence="PatientEyeMovementCommandCodeSequence"	Type="1C"	VM="1"	Condition="PatientEyeMovementCommandedIsYes"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4201"
+	SequenceEnd
+	InvokeMacro="OphthalmicAcquisitionParametersMacro"
+ModuleEnd
+
+Module="OcularRegionImaged"
+	Name="ImageLaterality"								Type="1"	StringEnumValues="OphthalmologyImageLaterality"
+	Sequence="RelativeImagePositionCodeSequence"		Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4207"
+	SequenceEnd
+	InvokeMacro="GeneralAnatomyMandatoryMacro"
+ModuleEnd
+
+Module="StereometricSeries"
+	Name="Modality"										Type="1"	StringEnumValues="StereometricModality"
+ModuleEnd
+
+Module="StereometricRelationship"
+	Sequence="StereoPairsSequence"						Type="1"	VM="1-n"
+		Name="StereoBaselineAngle"						Type="3"
+		Name="StereoBaselineDisplacement"				Type="3"
+		Name="StereoHorizontalPixelOffset"				Type="3"
+		Name="StereoVerticalPixelOffset"				Type="3"
+		Name="StereoRotation"							Type="3"
+		Sequence="LeftImageSequence"					Type="1"	VM="1"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="RightImageSequence"					Type="1"	VM="1"
+			InvokeMacro="ImageSOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="OphthalmicTomographySeries"
+	Name="Modality"										Type="1"	StringEnumValues="OphthalmicTomographyModality"
+	Name="SeriesNumber"									Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="0-1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="OphthalmicTomographyImage"
+	Name="ImageType"									Type="1"	ValueSelector="0"	StringEnumValues="ImageType1"
+	Verify="ImageType"									Type="1"	ValueSelector="1"	StringEnumValues="ImageType2"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="AcquisitionDateTime"							Type="1"
+	Name="AcquisitionDuration"							Type="1C"	Condition="ImageTypeValue1Original" mbpo="true"
+	Name="AcquisitionNumber"							Type="1"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre8Or12Or16"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre7Or11Or15"
+	Name="PresentationLUTShape"							Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Name="LossyImageCompression"						Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"					Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"					Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"							Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="BurnedInAnnotation"							Type="1"	StringEnumValues="NoFull"
+	Name="RecognizableVisualFeatures"					Type="3"	StringEnumValues="YesNoFull"
+	Name="ConcatenationFrameOffsetNumber"				Type="1"	BinaryEnumValues="Zero"
+	Name="InConcatenationNumber"						Type="1"	BinaryEnumValues="One"
+	Name="InConcatenationTotalNumber"					Type="1"	BinaryEnumValues="One"
+	Name="ImageComments"								Type="3"
+ModuleEnd
+
+Module="OphthalmicTomographyAcquisitionParameters"
+	Name="AxialLengthOfTheEye"								Type="2"
+	Name="HorizontalFieldOfView"						Type="2"
+	InvokeMacro="OphthalmicAcquisitionParametersMacro"
+ModuleEnd
+
+Module="OphthalmicTomographyParameters"
+	Sequence="AcquisitionDeviceTypeCodeSequence"		Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4210"
+	SequenceEnd
+	Sequence="LightPathFilterTypeStackCodeSequence"		Type="2"	VM="0-n"
+		InvokeMacro="CodeSequenceMacro"								BaselineContextID="4204"
+	SequenceEnd
+	Name="LightPathFilterPassThroughWavelength"			Type="3"
+	Name="LightPathFilterPassBand"						Type="3"
+	Name="DetectorType"									Type="1"	StringDefinedTerms="OphthalmicTomographyDetectorType"
+	Name="IlluminationWaveLength"						Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="IlluminationPower"							Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="IlluminationBandwidth"						Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="DepthSpatialResolution"						Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="MaximumDepthDistortion"						Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="AlongScanSpatialResolution"					Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="MaximumAlongScanDistortion"					Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="AcrossScanSpatialResolution"					Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+	Name="MaximumAcrossScanDistortion"					Type="1C"	Condition="AcquisitionDeviceTypeCodeSequenceIsOpticalCoherenceTomographyScanner" mbpo="true"
+ModuleEnd
+
+DefineMacro="OphthalmicFrameLocationMacro" InformationEntity="Frame"
+	Sequence="OphthalmicFrameLocationSequence"			Type="1"	VM="1-n"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+			Name="CodeValue"							Type="1"	VM="1" StringDefinedTerms="LocalizerDCMCodeValue"		# this is a bit hokey, but cannot parametrize invocation yet, and macro as nested as if modules not inline :(
+		SequenceEnd
+		Name="ReferenceCoordinates"						Type="1"
+		Name="DepthOfTransverseImage"					Type="2C"	Condition="OphthalmicImageOrientationIsTransverse"
+		Name="OphthalmicImageOrientation"				Type="1"	StringEnumValues="OphthalmicImageOrientation"
+	SequenceEnd
+MacroEnd
+
+Module="MultiFrameFunctionalGroupsForOphthalmicTomography"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"			Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"			Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"			Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"			Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"			Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"				Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"	Condition="NeedCardiacSynchronizationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="OphthalmicFrameLocationMacro"	Condition="NeedOphthalmicFrameLocationMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"			Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"			Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"			Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"			Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"			Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"				Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"	Condition="NeedCardiacSynchronizationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="OphthalmicFrameLocationMacro"	Condition="NeedOphthalmicFrameLocationMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+
+Module="WholeSlideMicroscopySeries"
+	Name="Modality"										Type="1"	StringEnumValues="VLWholeSlideMicroscopyModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="WholeSlideMicroscopyImage"
+	Name="ImageType"									Type="1"	VM="4"
+	Verify="ImageType"									Type="1"	ValueSelector="0"	StringEnumValues="WholeSlideImageType1"
+	Verify="ImageType"									Type="1"	ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"									Type="1"	ValueSelector="2"	StringEnumValues="WholeSlideImageType3"
+	Verify="ImageType"									Type="1"	ValueSelector="3"	StringEnumValues="WholeSlideImageType4"
+	Name="ImagedVolumeWidth"							Type="1"	NotZeroError=""
+	Name="ImagedVolumeHeight"							Type="1"	NotZeroError=""
+	Name="ImagedVolumeDepth"							Type="1"	NotZeroError=""
+	Name="TotalPixelMatrixColumns"						Type="1"	NotZeroError=""
+	Name="TotalPixelMatrixRows"							Type="1"	NotZeroError=""
+	Sequence="TotalPixelMatrixOriginSequence"			Type="1"	VM="1"
+		Name="XOffsetInSlideCoordinateSystem"			Type="1"
+		Name="YOffsetInSlideCoordinateSystem"			Type="1"
+	SequenceEnd
+	Name="ImageOrientationSlide"						Type="1"
+	Name="SamplesPerPixel"								Type="1"	BinaryEnumValues="SamplesPerPixelIsOneOrThree"
+	Verify="SamplesPerPixel"										Condition="PhotometricInterpretationNeedsOneSample"	BinaryEnumValues="One"
+	Verify="SamplesPerPixel"										Condition="PhotometricInterpretationNeedsThreeSamples"	BinaryEnumValues="Three"
+	Name="PhotometricInterpretation"					Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2OrRGBorYBRFULL422orYBRRCTorYBRICT"
+	Name="PlanarConfiguration"							Type="1C"	BinaryEnumValues="PlanarConfigurationIsColorByPixel"	Condition="SamplesPerPixelGreaterThanOne"
+	Name="NumberOfFrames"								Type="1"
+	Verify="NumberOfFrames"											Condition="ImageTypeValue3LocalizerOrLabel"	BinaryEnumValues="One"
+	Name="BitsAllocated"								Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"									Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="HighBit"										Type="1"	BinaryEnumValues="BitsAre7Or15"
+	Name="PixelRepresentation"							Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="AcquisitionDateTime"							Type="1"
+	Name="AcquisitionDuration"							Type="1"
+	Name="LossyImageCompression"						Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"					Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"					Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"							Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Name="PresentationLUTShape"							Type="1C"	Condition="PhotometricInterpretationIsMonochrome2"	StringEnumValues="IdentityPresentationLUTShape"
+	Name="RescaleSlope"									Type="1C"	Condition="PhotometricInterpretationIsMonochrome2"	BinaryEnumValues="One"
+	Name="RescaleIntercept"								Type="1C"	Condition="PhotometricInterpretationIsMonochrome2"	BinaryEnumValues="Zero"
+	Name="VolumetricProperties"							Type="1"	StringEnumValues="VolumetricPropertiesVolume"
+	Name="SpecimenLabelInImage"							Type="1"	StringEnumValues="YesNoFull"
+	Name="BurnedInAnnotation"							Type="1"	StringEnumValues="YesNoFull"
+	Name="FocusMethod"									Type="1"	StringEnumValues="WholeSlideFocusMethod"
+	Name="ExtendedDepthOfField"							Type="1"	StringEnumValues="YesNoFull"
+	Name="NumberOfFocalPlanes"							Type="1C"	Condition="ExtendedDepthOfFieldIsYes"	NotZeroError=""
+	Name="DistanceBetweenFocalPlanes"					Type="1C"	Condition="ExtendedDepthOfFieldIsYes"	NotZeroError=""
+	Name="AcquisitionDeviceProcessingDescription"		Type="3"
+	Name="ConvolutionKernel"							Type="3"
+	Name="RecommendedAbsentPixelCIELabValue"			Type="3"
+ModuleEnd
+
+Module="OpticalPath"
+	Sequence="OpticalPathSequence"						Type="1"	VM="1-n"
+		Name="OpticalPathIdentifier"					Type="1"
+		Name="OpticalPathDescription"					Type="3"
+		Sequence="IlluminatorTypeCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="IlluminationWaveLength"					Type="1C"	Condition="IlluminationColorCodeSequenceNotPresent"	mbpo="true"
+		Sequence="IlluminationColorCodeSequence"		Type="1C"	VM="1"	Condition="IlluminationWaveLengthNotPresent"	mbpo="true"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="IlluminationTypeCodeSequence"			Type="1"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="LightPathFilterTypeStackCodeSequence"	Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="LightPathFilterPassThroughWavelength"		Type="3"	NotZeroWarning=""
+		Name="LightPathFilterPassBand"					Type="3"	NotZeroWarning=""	# one of the two value may be zero length, but not zero
+		Sequence="ImagePathFilterTypeStackCodeSequence"	Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="ImagePathFilterPassThroughWavelength"		Type="3"	NotZeroWarning=""
+		Name="ImagePathFilterPassBand"					Type="3"	NotZeroWarning=""	# one of the two value may be zero length, but not zero
+		Sequence="LensesCodeSequence"					Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Name="CondenserLensPower"						Type="3"	NotZeroWarning=""
+		Name="ObjectiveLensPower"						Type="3"	NotZeroWarning=""
+		Name="ObjectiveLensNumericalAperture"			Type="3"	NotZeroWarning=""
+		Sequence="ChannelDescriptionCodeSequence"		Type="1C"	NoCondition=""	VM="1-3"			# real-world condition but should check number of items matches Samples per Pixel Used or Samples per Pixel :(
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="PaletteColorLookupTableSequence"		Type="3"	VM="1"
+			InvokeMacro="PaletteColorLookupTableMacro"
+		SequenceEnd
+		Name="ICCProfile"								Type="1C"	Condition="NeedICCProfileInOpticalPathSequence"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="PlanePositionSlideMacro" InformationEntity="FunctionalGroup"
+	Sequence="PlanePositionSlideSequence"				Type="1"	VM="1"
+		Name="ColumnPositionInTotalImagePixelMatrix"	Type="1"	NotZeroError=""
+		Name="RowPositionInTotalImagePixelMatrix"		Type="1"	NotZeroError=""
+		Name="XOffsetInSlideCoordinateSystem"			Type="1"
+		Name="YOffsetInSlideCoordinateSystem"			Type="1"
+		Name="ZOffsetInSlideCoordinateSystem"			Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="OpticalPathIdentificationMacro" InformationEntity="FunctionalGroup"
+	Sequence="OpticalPathIdentificationSequence"		Type="1"	VM="1"
+		Name="OpticalPathIdentifier"					Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="SpecimenReferenceMacro" InformationEntity="FunctionalGroup"
+	Sequence="SpecimenReferenceSequence"				Type="2"	VM="0-1"
+		Name="SpecimenUID"								Type="1"
+	SequenceEnd
+MacroEnd
+
+Module="MultiResolutionNavigation"
+	Sequence="ReferencedImageNavigationSequence"		Type="1"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Name="ReferencedFrameNumber"					Type="1"	VM="1"	NotZeroError=""
+		Name="TopLeftHandCornerOfLocalizerArea"			Type="1"
+		Name="BottomRightHandCornerOfLocalizerArea"		Type="1"
+		Name="PixelSpacing"								Type="1"
+		Name="ZOffsetInSlideCoordinateSystem"			Type="1"
+		Name="SamplesPerPixel"							Type="1"
+		Name="OpticalPathIdentifier"					Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="SlideLabel"
+	Name="BarcodeValue"									Type="2"
+	Name="LabelText"									Type="2"
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForWholeSlideMicroscopy"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"
+		InvokeMacro="ReferencedImageMacro"				Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"				Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"		Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PlanePositionSlideMacro"			Condition="PlanePositionSlideSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="OpticalPathIdentificationMacro"	Condition="OpticalPathIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="SpecimenReferenceMacro"			Condition="SpecimenReferenceMacroOKInSharedFunctionalGroupSequence"
+	SequenceEnd
+
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="ReferencedImageMacro"				Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"				Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"		Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionSlideMacro"			Condition="PlanePositionSlideSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="OpticalPathIdentificationMacro"	Condition="OpticalPathIdentificationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="SpecimenReferenceMacro"			Condition="SpecimenReferenceMacroOKInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="LensometryMeasurementsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="LensometryModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="AutorefractionMeasurementsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="AutorefractionModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="KeratometryMeasurementsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="KeratometryModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="SubjectiveRefractionMeasurementsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="SubjectiveRefractionModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="VisualAcuityMeasurementsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="VisualAcuityModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="CylinderSequenceMacro"
+	Sequence="CylinderSequence"							Type="1C"	VM="1"	NoCondition=""
+		Name="CylinderPower"							Type="1"		
+		Name="CylinderAxis"								Type="1"		
+	SequenceEnd
+MacroEnd
+
+DefineMacro="PrismSequenceMacro"
+	Sequence="PrismSequence"							Type="1C"	VM="1"	NoCondition=""
+		Name="HorizontalPrismPower"						Type="1"		
+		Name="HorizontalPrismBase"						Type="1"		
+		Name="VerticalPrismPower"						Type="1"		
+		Name="VerticalPrismBase"						Type="1"		
+	SequenceEnd
+MacroEnd
+
+Module="GeneralOphthalmicRefractiveMeasurements"
+	Name="InstanceNumber"								Type="1"		
+	Name="ContentDate"									Type="1"		
+	Name="ContentTime"									Type="1"		
+	Name="MeasurementLaterality"						Type="3"			StringEnumValues="OphthalmicRefractiveMeasurementLaterality"
+	Name="ImageComments"								Type="3"		
+	Sequence="ReferencedRefractiveMeasurementsSequence"	Type="2C"	VM="0-n"	Condition="VisualAcuityTypeCodeSequencePresent"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="LensometryMeasurements"
+	Name="LensDescription"								Type="2"		
+	Sequence="RightLensSequence"						Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="LensometryMeasurementsMacro"
+	SequenceEnd
+	Sequence="LeftLensSequence"							Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="LensometryMeasurementsMacro"
+	SequenceEnd
+	Sequence="UnspecifiedLateralityLensSequence"		Type="1C"	VM="1"	Condition="RightLensSequenceAndLeftLensSequenceAbsent"
+		InvokeMacro="LensometryMeasurementsMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="LensometryMeasurementsMacro"
+	Name="SpherePower"									Type="1"		
+	InvokeMacro="CylinderSequenceMacro"
+	Sequence="AddNearSequence"							Type="1C"	VM="1"	NoCondition=""
+		Name="AddPower"									Type="1"		
+		Name="ViewingDistance"							Type="3"		
+	SequenceEnd
+	Sequence="AddIntermediateSequence"					Type="1C"	VM="1"	NoCondition=""
+		Name="AddPower"									Type="1"		
+		Name="ViewingDistance"							Type="3"		
+	SequenceEnd
+	InvokeMacro="PrismSequenceMacro"
+	Name="LensSegmentType"								Type="3"	VM="1"	StringEnumValues="LensSegmentType"
+	Name="OpticalTransmittance"							Type="3"		
+	Name="ChannelWidth"									Type="3"		
+MacroEnd
+
+Module="AutorefractionMeasurements"
+	Sequence="AutorefractionRightEyeSequence"			Type="1C"	VM="1"	NoCondition=""
+		Name="SpherePower"								Type="1"		
+		InvokeMacro="CylinderSequenceMacro"
+		Name="PupilSize"								Type="3"		
+		Name="CornealSize"								Type="3"		
+	SequenceEnd
+	Sequence="AutorefractionLeftEyeSequence"			Type="1C"	VM="1"	NoCondition=""
+		Name="SpherePower"								Type="1"		
+		InvokeMacro="CylinderSequenceMacro"
+		Name="PupilSize"								Type="3"		
+		Name="CornealSize"								Type="3"		
+	SequenceEnd
+	Name="DistancePupillaryDistance"					Type="3"		
+	Name="NearPupillaryDistance"						Type="3"		
+ModuleEnd
+
+Module="KeratometryMeasurements"
+	Sequence="KeratometryRightEyeSequence"				Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="KeratometricMeasurementsMacro"
+	SequenceEnd
+	Sequence="KeratometryLeftEyeSequence"				Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="KeratometricMeasurementsMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="KeratometricMeasurementsMacro"
+	Sequence="SteepKeratometricAxisSequence"			Type="1"	VM="1"
+		Name="RadiusOfCurvature"						Type="1"
+		Name="KeratometricPower"						Type="1"
+		Name="KeratometricAxis"							Type="1"
+	SequenceEnd
+	Sequence="FlatKeratometricAxisSequence"				Type="1"	VM="1"
+		Name="RadiusOfCurvature"						Type="1"
+		Name="KeratometricPower"						Type="1"
+		Name="KeratometricAxis"							Type="1"
+	SequenceEnd
+MacroEnd
+
+Module="SubjectiveRefractionMeasurements"
+	Sequence="SubjectiveRefractionRightEyeSequence"		Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="SubjectiveRefractionMeasurementsMacro"
+	SequenceEnd
+	Sequence="SubjectiveRefractionLeftEyeSequence"		Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="SubjectiveRefractionMeasurementsMacro"
+	SequenceEnd
+	Name="DistancePupillaryDistance"					Type="3"
+	Name="NearPupillaryDistance"						Type="3"
+	Name="IntermediatePupillaryDistance"				Type="3"
+	Name="OtherPupillaryDistance"						Type="3"
+ModuleEnd
+
+DefineMacro="SubjectiveRefractionMeasurementsMacro"
+	Name="SpherePower"									Type="1"
+	InvokeMacro="CylinderSequenceMacro"
+	InvokeMacro="PrismSequenceMacro"
+	Sequence="AddNearSequence"							Type="1C"	VM="1"	NoCondition=""
+		Name="AddPower"									Type="1"
+		Name="ViewingDistance"							Type="3"
+	SequenceEnd
+	Sequence="AddIntermediateSequence"					Type="1C"	VM="1"	NoCondition=""
+		Name="AddPower"									Type="1"
+		Name="ViewingDistance"							Type="3"
+	SequenceEnd
+	Sequence="AddOtherSequence"							Type="1C"	VM="1"	NoCondition=""
+		Name="AddPower"									Type="1"
+		Name="ViewingDistance"							Type="3"
+	SequenceEnd
+MacroEnd
+
+Module="VisualAcuityMeasurements"
+	Name="ViewingDistanceType"							Type="1"	StringEnumValues="ViewingDistanceType"
+	Sequence="VisualAcuityTypeCodeSequence"				Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"					DefinedContextID="4216"
+	SequenceEnd
+	Name="BackgroundColor"								Type="1"	StringDefinedTerms="VisualAcuityMeasurementsBackgroundColor"
+	Name="Optotype"										Type="1"	StringDefinedTerms="Optotype"
+	Name="OptotypeDetailedDefinition"					Type="1C"	Condition="OptotypeIsLettersNumbersOrPictures"
+	Name="OptotypePresentation"							Type="1"	StringEnumValues="OptotypePresentation"
+	Sequence="VisualAcuityRightEyeSequence"				Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="VisualAcuityMeasurementsMacro"
+	SequenceEnd
+	Sequence="VisualAcuityLeftEyeSequence"				Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="VisualAcuityMeasurementsMacro"
+	SequenceEnd
+	Sequence="VisualAcuityBothEyesOpenSequence"			Type="3"	VM="1"
+		InvokeMacro="VisualAcuityMeasurementsMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="VisualAcuityMeasurementsMacro"
+	Name="DecimalVisualAcuity"							Type="1"
+	Name="VisualAcuityModifiers"						Type="3"
+MacroEnd
+
+Module="OphthalmicAxialMeasurementsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="OphthalmicAxialMeasurementsModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="OphthalmicAxialMeasurements"
+	Name="OphthalmicAxialMeasurementsDeviceType"			Type="1"			StringDefinedTerms="OphthalmicAxialMeasurementsDeviceType"
+	Sequence="OphthalmicUltrasoundMethodCodeSequence"		Type="1C"	VM="1"	Condition="OphthalmicAxialMeasurementsDeviceTypeIsUltrasound"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="AnteriorChamberDepthDefinitionCodeSequence"	Type="3"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Sequence="OphthalmicAxialMeasurementsRightEyeSequence"	Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="OphthalmicAxialMeasurementsMacro"
+		InvokeMacro="OphthalmicAxialMeasurementsSelectedMacro"
+	SequenceEnd
+	Sequence="OphthalmicAxialMeasurementsLeftEyeSequence"	Type="1C"	VM="1"	NoCondition=""
+		InvokeMacro="OphthalmicAxialMeasurementsMacro"
+		InvokeMacro="OphthalmicAxialMeasurementsSelectedMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="OphthalmicAxialMeasurementsMacro"
+	Sequence="LensStatusCodeSequence"												Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"																		DefinedContextID="4231"
+	SequenceEnd
+	Name="LensStatusDescription"													Type="3"
+	Sequence="VitreousStatusCodeSequence"											Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"																		DefinedContextID="4232"
+	SequenceEnd
+	Name="VitreousStatusDescription"												Type="3"
+	Name="PupilDilated"																Type="2"				StringEnumValues="YesNoFull"
+	Name="DegreeOfDilation"															Type="2C"				Condition="PupilDilatedIsYes"
+	Sequence="MydriaticAgentSequence"												Type="2C"	VM="0-n"	Condition="PupilDilatedIsYes"
+		Sequence="MydriaticAgentCodeSequence"										Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"																	DefinedContextID="4208"
+		SequenceEnd
+		Name="MydriaticAgentConcentration"											Type="3"
+		Sequence="MydriaticAgentConcentrationUnitsSequence"							Type="1C"	VM="1"		Condition="MydriaticAgentConcentrationPresent"
+			InvokeMacro="CodeSequenceMacro"																	DefinedContextID="4244"
+		SequenceEnd
+	SequenceEnd
+	Sequence="OphthalmicAxialLengthMeasurementsSequence"							Type="1"	VM="1-n"
+		Name="OphthalmicAxialLengthMeasurementsType"								Type="1"				StringEnumValues="OphthalmicAxialLengthMeasurementsType"
+		Sequence="OphthalmicAxialLengthMeasurementsTotalLengthSequence"				Type="1C"	VM="1-n"	Condition="OphthalmicAxialLengthMeasurementsTypeIsTotalLength"
+			Name="OphthalmicAxialLength"											Type="1"
+			Name="OphthalmicAxialLengthMeasurementModified"							Type="1"				StringEnumValues="YesNoFull"
+			Sequence="ReferencedOphthalmicAxialLengthMeasurementQCImageSequence"	Type="1"	VM="1"
+				InvokeMacro="OphthalmicAxialMeasurementsQualityImageSOPInstanceReferenceMacro"
+			SequenceEnd
+			InvokeMacro="OphthalmicAxialMeasurementsRelatedInformationMacro"
+		SequenceEnd
+		Sequence="OphthalmicAxialLengthMeasurementsLengthSummationSequence"			Type="1C"	VM="1-n"	Condition="OphthalmicAxialLengthMeasurementsTypeIsLengthSummation"
+			Name="OphthalmicAxialLength"											Type="1"
+			Name="OphthalmicAxialLengthMeasurementModified"							Type="1"				StringEnumValues="YesNoFull"
+			Sequence="ReferencedOphthalmicAxialLengthMeasurementQCImageSequence"	Type="1"	VM="1"
+				InvokeMacro="OphthalmicAxialMeasurementsQualityImageSOPInstanceReferenceMacro"
+			SequenceEnd
+			Sequence="OphthalmicAxialLengthMeasurementsSegmentalLengthSequence"		Type="1"	VM="1-n"
+				InvokeMacro="OphthalmicAxialLengthSegmentalMeasurementsMacro"
+			SequenceEnd
+		SequenceEnd
+		Sequence="OphthalmicAxialLengthMeasurementsSegmentalLengthSequence"			Type="1C"	VM="1"		Condition="OphthalmicAxialLengthMeasurementsTypeIsSegmentalLength"
+			InvokeMacro="OphthalmicAxialLengthSegmentalMeasurementsMacro"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="OphthalmicAxialLengthSegmentalMeasurementsMacro"
+	Name="OphthalmicAxialLength"										Type="1"
+	Name="OphthalmicAxialLengthMeasurementModified"						Type="1"				StringEnumValues="YesNoFull"
+	Sequence="OphthalmicAxialLengthMeasurementsSegmentNameCodeSequence"	Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	InvokeMacro="OphthalmicAxialMeasurementsRelatedInformationMacro"
+MacroEnd
+
+DefineMacro="OphthalmicAxialMeasurementsRelatedInformationMacro"
+	Sequence="UltrasoundOphthalmicAxialLengthMeasurementsSequence"		Type="1C"	VM="1"		Condition="OphthalmicAxialMeasurementsDeviceTypeIsUltrasound"
+		Name="OphthalmicAxialLengthVelocity"							Type="1"
+		Name="ObserverType"												Type="1"				StringEnumValues="OphthalmicAxialMeasurementsObserverType"
+		Sequence="OphthalmicAxialLengthDataSourceCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"														DefinedContextID="4240"
+		SequenceEnd
+		Name="OphthalmicAxialLengthDataSourceDescription"				Type="3"
+	SequenceEnd
+	Sequence="OpticalOphthalmicAxialLengthMeasurementsSequence"			Type="1C"	VM="1"		Condition="OphthalmicAxialMeasurementsDeviceTypeIsOptical"
+		Name="SignalToNoiseRatio"										Type="1C"				Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsTotalLength"
+		Sequence="OphthalmicAxialLengthDataSourceCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"														DefinedContextID="4240"
+		SequenceEnd
+		Name="OphthalmicAxialLengthDataSourceDescription"				Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="OphthalmicAxialMeasurementsSelectedMacro"
+	Sequence="UltrasoundSelectedOphthalmicAxialLengthSequence"						Type="1C"	VM="1"		Condition="OphthalmicAxialMeasurementsDeviceTypeIsUltrasound"
+		Name="OphthalmicAxialLength"												Type="1"
+		Sequence="OphthalmicAxialLengthSelectionMethodCodeSequence"					Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"																	DefinedContextID="4241"
+		SequenceEnd
+		Sequence="ReferencedOphthalmicAxialLengthMeasurementQCImageSequence"		Type="1"	VM="1"
+			InvokeMacro="OphthalmicAxialMeasurementsQualityImageSOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="OphthalmicAxialLengthQualityMetricSequence"						Type="1"	VM="1"
+			InvokeMacro="OphthalmicAxialLengthQualityMetricMacro"
+		SequenceEnd
+		Sequence="SelectedSegmentalOphthalmicAxialLengthSequence"					Type="1C"	VM="1"		Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsLengthSummation"
+			Name=OphthalmicAxialLength"												Type="1"
+			Sequence="OphthalmicAxialLengthMeasurementsSegmentNameCodeSequence"		Type="1"	VM="1"
+				InvokeMacro="CodeSequenceMacro"																DefinedContextID="4233"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	Sequence="OpticalSelectedOphthalmicAxialLengthSequence"							Type="1C"	VM="1-n"	Condition="OphthalmicAxialMeasurementsDeviceTypeIsOptical"
+		Sequence="SelectedTotalOphthalmicAxialLengthSequence"						Type="1C"	VM="1"		Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsTotalLength"
+			Name="OphthalmicAxialLength"											Type="1"
+			Sequence="ReferencedOphthalmicAxialLengthMeasurementQCImageSequence"	Type="1"	VM="1"
+				InvokeMacro="OphthalmicAxialMeasurementsQualityImageSOPInstanceReferenceMacro"
+			SequenceEnd
+			Sequence="OphthalmicAxialLengthQualityMetricSequence"					Type="1"	VM="1"
+				InvokeMacro="OphthalmicAxialLengthQualityMetricMacro"
+			SequenceEnd
+		SequenceEnd
+		Sequence="SelectedSegmentalOphthalmicAxialLengthSequence"					Type="1C"	VM="1-n"	Condition="OphthalmicAxialLengthMeasurementsTypeAboveIsSegmentalLength"
+			Sequence="OphthalmicAxialLengthMeasurementsSegmentNameCodeSequence"		Type="1"	VM="1"
+				InvokeMacro="CodeSequenceMacro"																DefinedContextID="4233"
+			SequenceEnd
+			Name="OphthalmicAxialLength"											Type="1"
+			Sequence="ReferencedOphthalmicAxialLengthMeasurementQCImageSequence"	Type="3"	VM="1"
+				InvokeMacro="OphthalmicAxialMeasurementsQualityImageSOPInstanceReferenceMacro"
+			SequenceEnd
+			Sequence="OphthalmicAxialLengthQualityMetricSequence"					Type="3"	VM="1"
+				InvokeMacro="OphthalmicAxialLengthQualityMetricMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="OphthalmicAxialLengthQualityMetricMacro"
+	Sequence="ConceptNameCodeSequence"					Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"										DefinedContextID="4243"
+	SequenceEnd
+	Name="NumericValue"									Type="1"
+	Sequence="MeasurementUnitsCodeSequence"				Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"										DefinedContextID="82"
+	SequenceEnd
+MacroEnd
+
+Module="IntraocularLensCalculationsSeries"
+	Name="Modality"										Type="1"			StringEnumValues="IntraocularLensCalculationsModality"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="IntraocularLensCalculations"
+	Sequence="IntraocularLensCalculationsRightEyeSequence"	Type="1C"	VM="1-n"	NoCondition=""
+		InvokeMacro="IntraocularLensCalculationsMacro"
+	SequenceEnd
+	Sequence="IntraocularLensCalculationsLeftEyeSequence"	Type="1C"	VM="1-n"	NoCondition=""
+		InvokeMacro="IntraocularLensCalculationsMacro"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="IntraocularLensCalculationsMacro"
+	Name="TargetRefraction"											Type="1"
+	Name="RefractiveProcedureOccurred"								Type="2"				StringEnumValues="YesNoFull"
+	Sequence="RefractiveSurgeryTypeCodeSequence"					Type="2C"	VM="0-n"	Condition="RefractiveProcedureOccurredIsYes"
+		InvokeMacro="CodeSequenceMacro"														DefinedContextID="4234"
+	SequenceEnd
+	Sequence="RefractiveErrorBeforeRefractiveSurgeryCodeSequence"	Type="2C"	VM="0-1"	Condition="RefractiveProcedureOccurredIsYes"
+		InvokeMacro="CodeSequenceMacro"														DefinedContextID="4238"
+	SequenceEnd
+	Name="CornealSize"												Type="3"
+	Sequence="LensThicknessSequence"								Type="3"	VM="1"
+		Name="LensThickness"										Type="1"
+		Sequence="SourceOfLensThicknessDataCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"													DefinedContextID="4240"
+		SequenceEnd
+		Sequence="ReferencedSOPSequence"							Type="1C"	VM="1"		NoCondition="" # too hard to check that SourceOfLensThicknessDataCodeSequence contains (111782, DCM, "Axial Measurements SOP Instance")
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="AnteriorChamberDepthSequence"							Type="3"	VM="1"
+		Name="AnteriorChamberDepth"	Type="1"
+		Sequence="SourceOfAnteriorChamberDepthDataCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+		Sequence="ReferencedSOPSequence"							Type="1C"	VM="1"		NoCondition="" # too hard to check that SourceOfAnteriorChamberDepthDataCodeSequence contains (111782, DCM, "Axial Measurements SOP Instance")
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+	SequenceEnd
+	Sequence="RefractiveStateSequence"								Type="2"	VM="0-1"
+		Name="SphericalLensPower"									Type="1"
+		Name="CylinderLensPower"									Type="1"
+		Name="CylinderAxis"											Type="1"
+		Sequence="SourceOfRefractiveMeasurementsSequence"			Type="1"	VM="1"
+			Sequence="SourceOfRefractiveMeasurementsCodeSequence"	Type="1"	VM="1"
+				InvokeMacro="CodeSequenceMacro"												DefinedContextID="4240"
+			SequenceEnd
+			Sequence="ReferencedSOPSequence"						Type="1C"	VM="1"		NoCondition="" # too hard to check that SourceOfRefractiveMeasurementsCodeSequence contains (111783, DCM, "Refractive Measurements SOP Instance")
+				InvokeMacro="SOPInstanceReferenceMacro"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+	InvokeMacro="KeratometryMacro"
+	Sequence="IOLFormulaCodeSequence"								Type="1"	VM="1"
+		InvokeMacro="CodeSequenceMacro"														DefinedContextID="4236"
+	SequenceEnd
+	Name="IOLFormulaDetail"											Type="3"
+	InvokeMacro="IOLOphthalmicAxialLengthMacro"
+	InvokeMacro="CalculatedIOLMacro"
+MacroEnd
+
+DefineMacro="KeratometryMacro"
+	Sequence="SteepKeratometricAxisSequence"						Type="1"	VM="1"
+		Name="RadiusOfCurvature"									Type="1"
+		Name="KeratometricPower"									Type="2"
+		Name="KeratometricAxis"										Type="2"
+	SequenceEnd
+	Sequence="FlatKeratometricAxisSequence"							Type="1"	VM="1"
+		Name="RadiusOfCurvature"									Type="1"
+		Name="KeratometricPower"									Type="2"
+		Name="KeratometricAxis"										Type="2"
+	SequenceEnd
+	Sequence="KeratometryMeasurementTypeCodeSequence"				Type="2"	VM="1"
+		InvokeMacro="CodeSequenceMacro"														DefinedContextID="4235"
+	SequenceEnd
+	Name="KeratometerIndex"											Type="2"
+MacroEnd
+
+DefineMacro="IOLOphthalmicAxialLengthMacro"
+	Sequence="OphthalmicAxialLengthSequence"						Type="1"	VM="1"
+		Name="OphthalmicAxialLength"								Type="1"
+		Sequence="OphthalmicAxialLengthSelectionMethodCodeSequence"	Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"													DefinedContextID="4241"
+		SequenceEnd
+		Sequence="SourceOfOphthalmicAxialLengthCodeSequence"		Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"													DefinedContextID="4240"
+		SequenceEnd
+		Sequence="ReferencedSOPSequence"							Type="1C"	VM="1"		NoCondition="" # too hard to check that SourceOfOphthalmicAxialLengthCodeSequence contains (111782, DCM, "Axial Measurements SOP Instance")
+			InvokeMacro="SOPInstanceReferenceMacro"
+		SequenceEnd
+		Sequence="OphthalmicUltrasoundMethodCodeSequence"			Type="1C"	VM="1"		Condition="OphthalmicAxialMeasurementsDeviceTypeIsUltrasound"
+			InvokeMacro="CodeSequenceMacro"													DefinedContextID="4230"
+		SequenceEnd
+	SequenceEnd
+MacroEnd
+
+DefineMacro="CalculatedIOLMacro"
+	Name="IOLManufacturer"							Type="1"
+	Name="ImplantName"								Type="1"
+	Sequence="LensConstantSequence"					Type="1"	VM="1-n"
+		Sequence="ConceptNameCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"									DefinedContextID="4237"
+		SequenceEnd
+		Name="NumericValue"	Type="1"
+	SequenceEnd
+	Sequence="IOLPowerSequence"						Type="1"	VM="1-n"
+		Name="IOLPower"								Type="1"
+		Name="PredictedRefractiveError"				Type="1"
+		Name="ImplantPartNumber"					Type="2"
+	SequenceEnd
+	Name="IOLPowerForExactEmmetropia"				Type="2"
+	Name="IOLPowerForExactTargetRefraction"			Type="2"
+MacroEnd
+
+DefineMacro="OphthalmicAxialMeasurementsQualityImageSOPInstanceReferenceMacro"
+	Name="ReferencedSOPClassUID"	Type="1"	StringEnumValues="OphthalmicAxialMeasurementsQualityImageSOPClassUIDs"
+	Name="ReferencedSOPInstanceUID"	Type="1"
+	Name="ReferencedFrameNumber"	Type="1"
+MacroEnd
+
diff --git a/libsrc/standard/module/waveform.tpl b/libsrc/standard/module/waveform.tpl
new file mode 100755
index 0000000..ef90524
--- /dev/null
+++ b/libsrc/standard/module/waveform.tpl
@@ -0,0 +1,117 @@
+Module="Synchronization"
+	Name="SynchronizationFrameOfReferenceUID"		Type="1"
+	Name="SynchronizationTrigger"					Type="1"	StringEnumValues="SynchronizationTrigger"
+	Name="TriggerSourceOrType"						Type="3"
+	Name="SynchronizationChannel"					Type="1C"	NoCondition=""	# real world
+	Name="AcquisitionTimeSynchronized"				Type="1"	StringEnumValues="YesNoLetter"
+	Name="TimeSource"								Type="3"
+	Name="TimeDistributionProtocol"					Type="3"	StringEnumValues="TimeDistributionProtocol"
+	Name="NTPSourceAddress"							Type="3"
+ModuleEnd
+
+Module="WaveformIdentification"
+	Name="InstanceNumber"							Type="1"
+	Name="ContentDate"								Type="1"
+	Name="ContentTime"								Type="1"
+	Name="AcquisitionDateTime"						Type="1"
+	Sequence="ReferencedInstanceSequence"			Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="Waveform"
+	Sequence="WaveformSequence"							Type="1"	VM="1-n"
+		Name="MultiplexGroupTimeOffset"					Type="1C"	Condition="AcquisitionTimeSynchronizedIsY"
+		Name="TriggerTimeOffset"						Type="1C"	NoCondition=""	# real world
+		Name="TriggerSamplePosition"					Type="3"
+		Name="WaveformOriginality"						Type="1"	StringEnumValues="WaveformOriginality"
+		Name="NumberOfWaveformChannels"					Type="1"	NotZeroError=""
+		Name="NumberOfWaveformSamples"					Type="1"	NotZeroError=""
+		Name="SamplingFrequency"						Type="1"
+		Name="MultiplexGroupLabel"						Type="3"
+		Sequence="ChannelDefinitionSequence"			Type="1"	VM="1-n"
+			Name="WaveformChannelNumber"				Type="3"
+			Name="ChannelLabel"							Type="3"
+			Name="ChannelStatus"						Type="3"	StringDefinedTerms="ChannelStatus"
+			Sequence="ChannelSourceSequence"			Type="1"	VM="1"
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+			Sequence="ChannelSourceModifiersSequence"	Type="1C"	VM="1-n"	NoCondition=""
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+			Sequence="SourceWaveformSequence"			Type="3"	VM="1-n"
+				InvokeMacro="SOPInstanceReferenceMacro"
+				Name="ReferencedWaveformChannels"		Type="1"
+			SequenceEnd
+			Name="ChannelDerivationDescription"			Type="3"
+			Name="ChannelSensitivity"					Type="1C"	NoCondition=""	# real world
+			Sequence="ChannelSensitivityUnitsSequence"	Type="1C"	VM="1"	Condition="ChannelSensitivityIsPresent"
+				InvokeMacro="CodeSequenceMacro"						DefinedContextID="3082"
+			SequenceEnd
+			Name="ChannelSensitivityCorrectionFactor"	Type="1C"	Condition="ChannelSensitivityIsPresent"
+			Name="ChannelBaseline"						Type="1C"	Condition="ChannelSensitivityIsPresent"
+			Name="ChannelTimeSkew"						Type="1C"	Condition="ChannelSampleSkewNotPresent"
+			Name="ChannelSampleSkew"					Type="1C"	Condition="ChannelTimeSkewNotPresent"
+			Name="ChannelOffset"						Type="3"
+			Name="WaveformBitsStored"					Type="1"
+			Name="FilterLowFrequency"					Type="3"
+			Name="FilterHighFrequency"					Type="3"
+			Name="NotchFilterFrequency"					Type="3"
+			Name="NotchFilterBandwidth"					Type="3"
+			Name="ChannelMinimumValue"					Type="3"
+			Name="ChannelMaximumValue"					Type="3"
+		SequenceEnd
+		Name="WaveformBitsAllocated"					Type="1"	BinaryEnumValues="BitsAre8Or16"
+		Verify="WaveformBitsAllocated"								Condition="WaveformSampleInterpretationNeeds8Bit" BinaryEnumValues="BitsAre8"
+		Verify="WaveformBitsAllocated"								Condition="WaveformSampleInterpretationNeeds16Bit" BinaryEnumValues="BitsAre16"
+		Name="WaveformSampleInterpretation"				Type="1"	StringEnumValues="WaveformSampleInterpretation"	
+		Name="WaveformPaddingValue"						Type="1C"	NoCondition=""	# real world
+		Name="WaveformData"								Type="1"
+		Name="WaveformDataDisplayScale"						Type="3"	NotZeroError=""
+		Name="WaveformDisplayBackgroundCIELabValue"			Type="3"
+		Sequence="WaveformPresentationGroupSequence"		Type="3"	VM="1-n"
+			Name="PresentationGroupNumber"					Type="1"
+			Sequence="ChannelDisplaySequence"				Type="1"	VM="1-n"
+				Name="ReferencedWaveformChannels"			Type="1"
+				Name="ChannelOffset"						Type="3"
+				Name="ChannelRecommendedDisplayCIELabValue"	Type="1"
+				Name="ChannelPosition"						Type="1"
+				Name="DisplayShadingFlag"					Type="3"	StringEnumValues="DisplayShadingFlag"
+				Name="FractionalChannelDisplayScale"		Type="1C"	Condition="AbsoluteChannelDisplayScaleIsNotPresent"
+				Name="AbsoluteChannelDisplayScale"			Type="1C"	Condition="FractionalChannelDisplayScaleIsNotPresent"
+			SequenceEnd
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="WaveformAnnotation"
+	Sequence="WaveformAnnotationSequence"				Type="1"	VM="1-n"
+		Name="UnformattedTextValue"						Type="1C"	Condition="ConceptNameCodeSequenceNotPresent"
+		Sequence="ConceptNameCodeSequence"				Type="1C"	VM="1"	Condition="UnformattedTextValueNotPresent"
+			InvokeMacro="CodeSequenceMacro"
+			Sequence="ModifierCodeSequence"				Type="1C"	VM="1-n"	NoCondition=""	# real world
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+		SequenceEnd
+		Sequence="ConceptCodeSequence"					Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"
+			Sequence="ModifierCodeSequence"				Type="1C"	VM="1-n"	NoCondition=""	# real world
+				InvokeMacro="CodeSequenceMacro"
+			SequenceEnd
+		SequenceEnd
+		Name="NumericValue"								Type="3"
+		Sequence="MeasurementUnitsCodeSequence"			Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"							BaselineContextID="82"
+		SequenceEnd
+		Name="ReferencedWaveformChannels"				Type="1"
+		Name="TemporalRangeType"						Type="1C"	NoCondition=""	StringEnumValues="TemporalRangeTypeForWaveformAnnotation""
+		Name="ReferencedSamplePositions"				Type="1C"	Condition="AnnotationNeedsReferencedSamplePositions"
+		Name="ReferencedTimeOffsets"					Type="1C"	Condition="AnnotationNeedsReferencedTimeOffsets"
+		Name="ReferencedDateTime"						Type="1C"	Condition="AnnotationNeedsReferencedDateTime"
+		Name="AnnotationGroupNumber"					Type="3"
+	SequenceEnd
+ModuleEnd
+
diff --git a/libsrc/standard/module/xaxrf.tpl b/libsrc/standard/module/xaxrf.tpl
new file mode 100755
index 0000000..e379378
--- /dev/null
+++ b/libsrc/standard/module/xaxrf.tpl
@@ -0,0 +1,776 @@
+Module="FramePointers"
+	Name="RepresentativeFrameNumber"	Type="3"	NotZeroError=""
+	Name="FrameNumbersOfInterest"		Type="3"	NotZeroError=""
+	Name="FrameOfInterestDescription"	Type="3"
+	Name="FrameOfInterestType"			Type="3"	StringDefinedTerms="FrameOfInterestTypeForUS"
+
+ModuleEnd
+
+Module="Mask"
+	Sequence="MaskSubtractionSequence"		Type="1"	VM="1-n"
+		Name="MaskOperation"				Type="1"	StringDefinedTerms="MaskOperation"
+		Name="SubtractionItemID"			Type="1C"	Condition="SOPClassIsEnhancedXAXRF" mbpo="true"
+		Name="ApplicableFrameRange"			Type="1C"	Condition="MaskOperationIsRevTID" mbpo="true"
+		Name="MaskFrameNumbers"				Type="1C"	Condition="MaskOperationIsAvgSub"	NotZeroError=""
+		Name="ContrastFrameAveraging"		Type="3"
+		Name="MaskSubPixelShift"			Type="3"
+		Name="TIDOffset"					Type="2C"	Condition="MaskOperationIsTIDOrRevTID"
+		Name="MaskOperationExplanation"		Type="3"
+		Name="MaskSelectionMode"			Type="3"	StringDefinedTerms="MaskSelectionMode"
+	SequenceEnd
+	Name="RecommendedViewingMode"			Type="2"	StringDefinedTerms="RecommendedViewingMode"
+
+ModuleEnd
+
+Module="DisplayShutter"
+	InvokeMacro="DisplayShutterMacro"
+ModuleEnd
+
+Module="Device"
+	# need to work in the 3 vs. 2C business for device parameters (C.7.6.12.1)
+	Sequence="DeviceSequence"		Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"
+		Name="Manufacturer"			Type="3"
+		Name="ManufacturerModelName"	Type="3"
+		Name="DeviceSerialNumber"	Type="3"
+		Name="DeviceID"				Type="3"
+		Name="DeviceLength"			Type="3"	NotZeroWarning=""
+		Name="DeviceDiameter"		Type="3"	NotZeroWarning=""
+		Name="DeviceDiameterUnits"	Type="2C"	Condition="DeviceDiameterIsPresent"	StringEnumValues="DeviceDiameterUnits"
+		Name="DeviceVolume"			Type="3"	NotZeroWarning=""
+		Name="InterMarkerDistance"	Type="3"
+		Name="DeviceDescription"	Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="Intervention"
+	Sequence="InterventionSequence"					Type="3"	VM="1-n"
+		InvokeMacro="CodeSequenceMacro"							BaselineContextID="9"
+		Name="InterventionStatus"					Type="2"	StringEnumValues="InterventionStatus"
+		Sequence="InterventionDrugCodeSequence"		Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"						BaselineContextID="10"
+		SequenceEnd
+		Name="InterventionDrugStartTime"			Type="3"
+		Name="InterventionDrugStopTime"				Type="3"
+		Sequence="AdministrationRouteCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"						BaselineContextID="11"
+		SequenceEnd
+		Name="InterventionDescription"				Type="3"
+	SequenceEnd
+ModuleEnd
+
+Module="XRayImage"
+	Name="FrameIncrementPointer"					Type="1C"	Condition="NeedModuleMultiFrame"	TagEnumValues="XRayFrameIncrementPointerValues"
+	Name="LossyImageCompression"					Type="1C"	NoCondition=""	StringEnumValues="LossyImageCompression"
+	Name="ImageType"								Type="1"	ValueSelector="2"	StringEnumValues="XRayImageTypeValue3"
+	Verify="ImageType"								Condition="ImageTypeValue3MissingOrEmpty"	ThenErrorMessage="A value is required for value 3 in XA/XRF Images"
+	Name="PixelIntensityRelationship"				Type="1"	StringDefinedTerms="PixelIntensityRelationship"
+	Name="SamplesPerPixel"							Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"				Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="BitsAllocated"							Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"								Type="1"	BinaryEnumValues="BitsAre8Or10Or12Or16"
+	Name="HighBit"									Type="1"	BinaryEnumValues="BitsAre7Or9Or11Or15"
+	Name="PixelRepresentation"						Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="ScanOptions"								Type="3"	StringDefinedTerms="XRayImageScanOptions"
+	InvokeMacro="GeneralAnatomyOptionalMacro"
+	Name="RWavePointer"								Type="3"
+	Sequence="ReferencedImageSequence"				Type="1C"	VM="1-n"	Condition="ImageTypeValue3BiplaneAOrB" mbpo="true"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"	Type="3"	VM="1"
+			InvokeMacro="CodeSequenceMacro"			DefinedContextID="7201"
+		SequenceEnd
+	SequenceEnd
+	Name="DerivationDescription"					Type="3"
+	Name="AcquisitionDeviceProcessingDescription"	Type="3"
+	Name="FrameLabelVector"							Type="3"
+	Name="FrameDimensionPointer"					Type="3"	TagEnumValues="XAFrameDimensionPointerValues"
+	Name="CalibrationImage"							Type="3"	StringEnumValues="YesNoFull"
+ModuleEnd
+
+Module="XRayAcquisition"
+	Name="KVP"										Type="2"	NotZeroWarning=""
+	Name="RadiationSetting"							Type="1"	StringEnumValues="RadiationSetting"
+	Name="XRayTubeCurrent"							Type="2C"	Condition="ExposureNotPresent" mbpo="true"	NotZeroWarning=""
+	Name="XRayTubeCurrentInuA"						Type="3"	NotZeroWarning=""
+	Verify="XRayTubeCurrentInmA"								Condition="XRayTubeCurrentInmAIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayAcquisition> - use XRayTubeCurrent and/or XRayTubeCurrentInuA instead of"
+	
+	Name="ExposureTime"								Type="2C"	Condition="ExposureNotPresent" mbpo="true"	NotZeroWarning=""
+	Name="ExposureTimeInuS"							Type="3"	NotZeroWarning=""
+	Verify="ExposureTimeInms"									Condition="ExposureTimeInmsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayAcquisition> - use ExposureTime and/or ExposureTimeInuS instead of"
+	
+	Name="Exposure"									Type="2C"	Condition="XRayTubeCurrentAndExposureTimeNotPresent" mbpo="true"	NotZeroWarning=""
+	Name="ExposureInuAs"							Type="3"	NotZeroWarning=""
+	Verify="ExposureInmAs"										Condition="ExposureInmAsIsPresentAndOthersAreNot" ThenErrorMessage="Attribute should not be used with Module <XRayAcquisition> - use Exposure and/or ExposureInuAs instead of"
+	
+	Name="Grid"										Type="3"	StringDefinedTerms="Grid"
+	Name="AveragePulseWidth"						Type="3"	NotZeroWarning=""
+	Name="RadiationMode"							Type="3"	StringDefinedTerms="RadiationMode"
+	Name="TypeOfFilters"							Type="3"
+	Name="IntensifierSize"							Type="3"
+	Name="FieldOfViewShape"							Type="3"	StringDefinedTerms="XRayFieldOfViewShape"
+	Name="FieldOfViewDimensions"					Type="3"	NotZeroWarning=""
+	Name="ImagerPixelSpacing"						Type="3"	NotZeroError=""
+	InvokeMacro="BasicPixelSpacingCalibrationMacro"
+	Name="FocalSpots"								Type="3"
+	Name="ImageAndFluoroscopyAreaDoseProduct"		Type="3"	NotZeroWarning=""
+ModuleEnd
+
+DefineMacro="XRayCollimatorDimensionsMacro" InformationEntity="Image"
+	Name="CollimatorLeftVerticalEdge"		Type="1C"	Condition="CollimatorShapeIsRectangular"
+	Name="CollimatorRightVerticalEdge"		Type="1C"	Condition="CollimatorShapeIsRectangular"
+	Name="CollimatorUpperHorizontalEdge"	Type="1C"	Condition="CollimatorShapeIsRectangular"
+	Name="CollimatorLowerHorizontalEdge"	Type="1C"	Condition="CollimatorShapeIsRectangular"
+	Name="CenterOfCircularCollimator"		Type="1C"	Condition="CollimatorShapeIsCircular"
+	Name="RadiusOfCircularCollimator"		Type="1C"	Condition="CollimatorShapeIsCircular"	NotZeroWarning=""
+	Name="VerticesOfThePolygonalCollimator"	Type="1C"	Condition="CollimatorShapeIsPolygonal"
+MacroEnd
+
+Module="XRayCollimator"
+	Name="CollimatorShape"					Type="1"	StringEnumValues="CollimatorShape"
+	InvokeMacro="XRayCollimatorDimensionsMacro"
+ModuleEnd
+
+Module="XRayTable"
+	Name="TableMotion"					Type="2"	StringDefinedTerms="TableMotion"
+	Name="TableVerticalIncrement"		Type="2C"	Condition="TableMotionDynamic"
+	Name="TableLongitudinalIncrement"	Type="2C"	Condition="TableMotionDynamic"
+	Name="TableLateralIncrement"		Type="2C"	Condition="TableMotionDynamic"
+	Name="TableAngle"					Type="3"
+ModuleEnd
+
+Module="XAPositioner"
+	Name="DistanceSourceToPatient"					Type="3"	NotZeroWarning=""
+	Name="DistanceSourceToDetector"					Type="3"	NotZeroWarning=""
+	Name="EstimatedRadiographicMagnificationFactor"	Type="3"	NotZeroWarning=""
+	Name="PositionerMotion"							Type="2C"	StringDefinedTerms="PositionerMotion"		Condition="NumberOfFramesGreaterThanOne" mbpo="true"
+	Verify="PositionerMotion"									StringEnumValues="PositionerMotionStatic"	Condition="PositionerMotionIsPresentAndNumberOfFramesIsAbsentOrOne"		
+	Name="PositionerPrimaryAngle"					Type="2"
+	Name="PositionerSecondaryAngle"					Type="2"
+	Name="PositionerPrimaryAngleIncrement"			Type="2C"	Condition="PositionerMotionDynamic"	NotZeroWarning=""
+	Name="PositionerSecondaryAngleIncrement"		Type="2C"	Condition="PositionerMotionDynamic"	NotZeroWarning=""
+	Name="DetectorPrimaryAngle"						Type="3"
+	Name="DetectorSecondaryAngle"					Type="3"
+
+ModuleEnd
+
+Module="XRFPositioner"
+	Name="DistanceSourceToDetector"					Type="3"	NotZeroWarning=""
+	Name="DistanceSourceToPatient"					Type="3"	NotZeroWarning=""
+	Name="EstimatedRadiographicMagnificationFactor"	Type="3"	NotZeroWarning=""
+	Name="ColumnAngulation"							Type="3"
+ModuleEnd
+
+Module="XRayTomographyAcquisition"
+	Name="TomoLayerHeight"							Type="1"
+	Name="TomoAngle"								Type="3"
+	Name="TomoTime"									Type="3"
+	Name="TomoType"									Type="3"	StringDefinedTerms="TomoType"
+	Name="TomoClass"								Type="3"	StringDefinedTerms="TomoClass"
+	Name="NumberOfTomosynthesisSourceImages"		Type="3"
+ModuleEnd
+
+# enhanced XA/XRF stuff ...
+
+Module="XAXRFSeries"
+	Name="Modality"										Type="1"	StringEnumValues="EnhancedXAXRFModality"
+	Name="SeriesNumber"									Type="1"
+	Sequence="ReferencedPerformedProcedureStepSequence"	Type="1C"	VM="1"	Condition="SeriesNeedReferencedPerformedProcedureStepSequence"
+		InvokeMacro="SOPInstanceReferenceMacro"
+	SequenceEnd
+ModuleEnd
+
+Module="EnhancedXAXRFImage"
+	Name="ImageType"										Type="1"	VM="4-n"
+	Verify="ImageType"													ValueSelector="0"	StringEnumValues="EnhancedXAXRFImageType1"
+	Verify="ImageType"													ValueSelector="1"	StringEnumValues="EnhancedXAXRFImageType2"
+	Verify="ImageType"													ValueSelector="2"	StringDefinedTerms="EnhancedXAXRFImageType3"
+	Verify="ImageType"													ValueSelector="3"	StringEnumValues="EnhancedXAXRFImageType4"
+	Name="PlanesInAcquisition"								Type="1"	StringDefinedTerms="PlaneIdentification"
+	Name="PlaneIdentification"								Type="1C"	Condition="PlanesInAcquisitionNotUndefined"	StringDefinedTerms="PlaneIdentification"
+	Name="AcquisitionNumber"								Type="3"
+	Name="AcquisitionDateTime"								Type="1"
+	Name="BitsAllocated"									Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"										Type="1"	BinaryEnumValues="BitsAre8To16"
+	Verify="BitsStored"													Condition="BitsAllocatedIs8"	BinaryEnumValues="BitsAre8"
+	Verify="BitsStored"													Condition="BitsAllocatedIs16"	BinaryEnumValues="BitsAre9To16"
+	Name="HighBit"											Type="1"	BinaryEnumValues="BitsAre7To15"
+	Verify="HighBit"													Condition="BitsAllocatedIs8"	BinaryEnumValues="BitsAre7"
+	Verify="HighBit"													Condition="BitsAllocatedIs16"	BinaryEnumValues="BitsAre8To15"
+	Name="SamplesPerPixel"									Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PixelRepresentation"								Type="1"	BinaryEnumValues="PixelRepresentationUnsigned"
+	Name="PhotometricInterpretation"						Type="1"	StringEnumValues="PhotometricInterpretationMonochrome"
+	Name="AcquisitionProtocolName"							Type="3"
+	Name="AcquisitionProtocolDescription"					Type="3"
+	Name="ScanOptions"										Type="3"	StringDefinedTerms="EnhancedXAXRFScanOptions"
+	Name="ContentQualification"								Type="1"	StringEnumValues="ContentQualification"
+	Sequence="PatientOrientationCodeSequence"				Type="1C"	VM="1"	Condition="PositionerIsCArmWithTableTopRelationship"
+		InvokeMacro="CodeSequenceMacro"									BaselineContextID="19"
+		Sequence="PatientOrientationModifierCodeSequence"   Type="1C"	VM="1"	NoCondition=""	# real-world - orientation wrt. gravity
+ 			InvokeMacro="CodeSequenceMacro"								BaselineContextID="20"
+		SequenceEnd
+	SequenceEnd
+	Sequence="PatientGantryRelationshipCodeSequence"		Type="2C"	VM="0-1"	Condition="PositionerIsCArmWithTableTopRelationship"
+		InvokeMacro="CodeSequenceMacro"									BaselineContextID="21"
+	SequenceEnd
+	Name="ExaminedBodyThickness"							Type="3"	NotZeroWarning=""
+	Name="BurnedInAnnotation"								Type="1"	StringEnumValues="NoFull"
+	Name="RecognizableVisualFeatures"						Type="3"	StringEnumValues="YesNoFull"
+	Name="LossyImageCompression"							Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"						Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Sequence="ReferencedOtherPlaneSequence"					Type="1C"	VM="1"	Condition="ImageTypeValue3BiplaneAOrB"
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedImageEvidenceSequence"				Type="1C"	VM="1-n"	Condition="ReferencedImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="SourceImageEvidenceSequence"					Type="1C"	VM="1-n"	Condition="SourceImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Sequence="ReferencedInstanceSequence"					Type="3"	VM="1-n"
+		InvokeMacro="SOPInstanceReferenceMacro"
+		Sequence="PurposeOfReferenceCodeSequence"			Type="1"	VM="1"
+			InvokeMacro="CodeSequenceMacro"								DefinedContextID="7004"
+		SequenceEnd
+	SequenceEnd
+	Name="ImageComments"									Type="3"
+	Name="QualityControlImage"								Type="3"	StringEnumValues="YesNoFull"
+	Sequence="IconImageSequence"							Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	Name="PresentationLUTShape"								Type="1"	StringEnumValues="IdentityOrInversePresentationLUTShape"
+	Verify="PresentationLUTShape"										Condition="PhotometricInterpretationIsMonochrome2"	StringEnumValues="IdentityPresentationLUTShape"
+	Verify="PresentationLUTShape"										Condition="PhotometricInterpretationIsMonochrome1"	StringEnumValues="InversePresentationLUTShape"
+ModuleEnd
+
+Module="XAXRFAcquisition"
+	Name="KVP"												Type="1"	NotZeroWarning=""
+	Name="RadiationSetting"									Type="1"	StringEnumValues="EnhancedXAXRFRadiationSetting"
+	Name="XRayTubeCurrentInmA"								Type="1C"	Condition="ExposureInmAsNotPresent"	NotZeroWarning=""
+	Name="ExposureTimeInms"									Type="1C"	Condition="ExposureInmAsNotPresent"	NotZeroWarning=""
+	Name="ExposureInmAs"									Type="1C"	Condition="XRayTubeCurrentInmAOrExposureTimeInmsNotPresent"	NotZeroWarning=""
+	Name="AveragePulseWidth"								Type="1"	NotZeroWarning=""
+	Name="AcquisitionDuration"								Type="1"	NotZeroWarning=""
+	Name="RadiationMode"									Type="1"	StringDefinedTerms="EnhancedXAXRFRadiationMode"
+	Name="FocalSpots"										Type="3"
+	Name="AnodeTargetMaterial"								Type="3"	StringDefinedTerms="AnodeTargetMaterial"
+	Name="RectificationType"								Type="3"	StringDefinedTerms="RectificationType"
+	Name="XRayReceptorType"									Type="3"	StringEnumValues="XRayReceptorType"
+	Name="DistanceReceptorPlaneToDetectorHousing"			Type="2"	NotZeroWarning=""
+	Name="PositionerType"									Type="2"	StringDefinedTerms="EnhancedXAXRFPositionerType"
+	Name="CArmPositionerTabletopRelationship"				Type="1C"	Condition="PositionerIsCArm"	StringEnumValues="YesNoFull"
+	Name="AcquiredImageAreaDoseProduct"						Type="2"	NotZeroWarning=""
+ModuleEnd
+
+Module="XRayImageIntensifier"
+	Name="IntensifierSize"									Type="1"	NotZeroWarning=""
+	Name="IntensifierActiveShape"							Type="1"	StringEnumValues="IntensifierActiveShape"
+	Name="IntensifierActiveDimensions"						Type="1"	NotZeroWarning=""
+ModuleEnd
+
+Module="XRayDetector"
+	InvokeMacro="DigitalXRayDetectorMacro"
+	Name="PhysicalDetectorSize"								Type="1"	NotZeroError=""
+	Name="PositionOfIsocenterProjection"					Type="1C"	Condition="IsocenterReferenceSystemSequencePresent"
+ModuleEnd
+
+DefineMacro="XRayFrameCharacteristicsMacro" InformationEntity="FunctionalGroup"
+	Sequence="XAXRFFrameCharacteristicsSequence"			Type="1"	VM="1"
+		Name="DerivationDescription"						Type="3" 
+		Sequence="DerivationCodeSequence"					Type="3"	VM="1-n"
+			InvokeMacro="CodeSequenceMacro"								DefinedContextID="7203"
+		SequenceEnd
+		Name="AcquisitionDeviceProcessingDescription"		Type="3"
+		Name="AcquisitionDeviceProcessingCode"				Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayFieldOfViewMacro" InformationEntity="FunctionalGroup"
+	Sequence="FieldOfViewSequence"							Type="1"	VM="1"
+		Name="FieldOfViewShape"								Type="3" 	StringEnumValues="FieldOfViewShape"
+		Name="FieldOfViewDimensionsInFloat"					Type="3"	NotZeroWarning=""
+		Name="FieldOfViewOrigin"							Type="1C"	Condition="XRayReceptorTypeIsDigitalDetector" mbpo="true"
+		Name="FieldOfViewRotation"							Type="1"	StringEnumValues="DXFieldOfViewRotation"
+		Name="FieldOfViewHorizontalFlip"					Type="1"	StringEnumValues="YesNoFull"
+		Name="FieldOfViewDescription"						Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayExposureControlSensingRegionsMacro" InformationEntity="FunctionalGroup"
+	Sequence="ExposureControlSensingRegionsSequence"				Type="1"	VM="1-n"
+		Name="ExposureControlSensingRegionShape"					Type="1" 	StringEnumValues="ExposureControlSensingRegionShape"
+		Name="ExposureControlSensingRegionLeftVerticalEdge"			Type="1C" 	Condition="ExposureControlSensingRegionShapeIsRectangular"
+		Name="ExposureControlSensingRegionRightVerticalEdge"		Type="1C" 	Condition="ExposureControlSensingRegionShapeIsRectangular"
+		Name="ExposureControlSensingRegionUpperHorizontalEdge"		Type="1C" 	Condition="ExposureControlSensingRegionShapeIsRectangular"
+		Name="ExposureControlSensingRegionLowerHorizontalEdge"		Type="1C" 	Condition="ExposureControlSensingRegionShapeIsRectangular"
+		Name="CenterOfCircularExposureControlSensingRegion"			Type="1C" 	Condition="ExposureControlSensingRegionShapeIsCircular"
+		Name="RadiusOfCircularExposureControlSensingRegion"			Type="1C" 	Condition="ExposureControlSensingRegionShapeIsCircular"
+		Name="VerticesOfThePolygonalExposureControlSensingRegion"	Type="1C" 	Condition="ExposureControlSensingRegionShapeIsPolygonal"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayFramePixelDataPropertiesMacro" InformationEntity="FunctionalGroup"
+	Sequence="FramePixelDataPropertiesSequence"				Type="1"	VM="1"
+		Name="FrameType"									Type="1"	VM="4-n"
+		Verify="FrameType"												ValueSelector="0"	StringEnumValues="EnhancedXAXRFImageType1"
+		Verify="FrameType"												ValueSelector="1"	StringEnumValues="EnhancedXAXRFImageType2"
+		Verify="FrameType"												ValueSelector="2"	StringDefinedTerms="EnhancedXAXRFImageType3"
+		Verify="FrameType"												ValueSelector="3"	StringEnumValues="EnhancedXAXRFImageType4"
+		Name="PixelIntensityRelationship"					Type="1"	StringDefinedTerms="XAXRFPixelIntensityRelationship"
+		Name="PixelIntensityRelationshipSign"				Type="1"	BinaryEnumValues="PixelIntensityRelationshipSign"
+		Name="ImagerPixelSpacing"							Type="1C"	Condition="ImageTypeValue1IsOriginal" mbpo="true"
+		Name="GeometricalProperties"						Type="1"	StringEnumValues="XAXRFGeometricalProperties"
+		Name="GeometricMaximumDistortion"					Type="2C" 	Condition="GeometricalPropertiesIsNonUniform"
+		Name="ImageProcessingApplied"						Type="1"	StringDefinedTerms="XAXRFImageProcessingApplied"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayFrameDetectorParametersMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameDetectorParametersSequence"				Type="1"	VM="1"
+		Name="DetectorActiveTime"							Type="3"
+		Name="DetectorActivationOffsetFromExposure"			Type="3"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayCalibrationDeviceUsageMacro" InformationEntity="FunctionalGroup"
+	Sequence="CalibrationSequence"							Type="1"	VM="1"
+		Name="CalibrationImage"								Type="3"	StringEnumValues="YesNoFull"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayObjectThicknessMacro" InformationEntity="FunctionalGroup"
+	Sequence="ObjectThicknessSequence"							Type="1"	VM="1"
+		Name="CalculatedAnatomyThickness"						Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayFrameAcquisitionMacro" InformationEntity="FunctionalGroup"
+	Sequence="FrameAcquisitionSequence"							Type="1"	VM="1"
+		Name="KVP"												Type="1"	NotZeroWarning=""
+		Name="XRayTubeCurrentInmA"								Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayProjectionPixelCalibrationMacro" InformationEntity="FunctionalGroup"
+	Sequence="ProjectionPixelCalibrationSequence"				Type="1"	VM="1"
+		Name="DistanceObjectToTableTop"							Type="2"
+		Name="ObjectPixelSpacingInCenterOfBeam"					Type="1C"	Condition="DistanceObjectToTableTopNotEmpty"
+		Name="TableHeight"										Type="1C"	Condition="ImageTypeValue1Original"
+		Name="BeamAngle"										Type="1C"	Condition="ImageTypeValue1Original"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayPositionerMacro" InformationEntity="FunctionalGroup"
+	Sequence="PositionerPositionSequence"						Type="1"	VM="1"
+		Name="PositionerPrimaryAngle"							Type="1C"	Condition="PositionerIsCArm"
+		Name="PositionerSecondaryAngle"							Type="1C"	Condition="PositionerIsCArm"
+		Name="ColumnAngulationPatient"							Type="1C"	Condition="PositionerIsColumn"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayTablePositionMacro" InformationEntity="FunctionalGroup"
+	Sequence="TablePositionSequence"							Type="1"	VM="1"
+		Name="TableTopVerticalPosition"							Type="1"
+		Name="TableTopLongitudinalPosition"						Type="1"
+		Name="TableTopLateralPosition"							Type="1"
+		Name="TableHorizontalRotationAngle"						Type="1"
+		Name="TableHeadTiltAngle"								Type="1"
+		Name="TableCradleTiltAngle"								Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayCollimatorMacro" InformationEntity="FunctionalGroup"
+	Sequence="CollimatorShapeSequence"							Type="1"	VM="1"
+		Name="CollimatorShape"									Type="1"	StringEnumValues="CollimatorShape"
+		Name="CollimatorLeftVerticalEdge"						Type="1C"	Condition="CollimatorShapeIsRectangular"
+		Name="CollimatorRightVerticalEdge"						Type="1C"	Condition="CollimatorShapeIsRectangular"
+		Name="CollimatorUpperHorizontalEdge"					Type="1C"	Condition="CollimatorShapeIsRectangular"
+		Name="CollimatorLowerHorizontalEdge"					Type="1C"	Condition="CollimatorShapeIsRectangular"
+		Name="CenterOfCircularCollimator"						Type="1C"	Condition="CollimatorShapeIsCircular"	NotZeroWarning=""
+		Name="RadiusOfCircularCollimator"						Type="1C"	Condition="CollimatorShapeIsCircular"	NotZeroWarning=""
+		Name="VerticesOfThePolygonalCollimator"					Type="1C"	Condition="CollimatorShapeIsPolygonal"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayIsocenterReferenceSystemMacro" InformationEntity="FunctionalGroup"
+	Sequence="IsocenterReferenceSystemSequence"					Type="1"	VM="1"
+		Name="PositionerIsocenterPrimaryAngle"					Type="1"
+		Name="PositionerIsocenterSecondaryAngle"				Type="1"
+		Name="PositionerIsocenterDetectorRotationAngle"			Type="1"
+		Name="TableXPositionToIsocenter"						Type="1"
+		Name="TableYPositionToIsocenter"						Type="1"
+		Name="TableZPositionToIsocenter"						Type="1"
+		Name="TableHorizontalRotationAngle"						Type="1"
+		Name="TableHeadTiltAngle"								Type="1"
+		Name="TableCradleTiltAngle"								Type="1"
+	SequenceEnd
+MacroEnd
+
+DefineMacro="XRayGeometryMacro" InformationEntity="FunctionalGroup"
+	Sequence="XRayGeometrySequence"								Type="1"	VM="1"
+		Name="DistanceSourceToIsocenter"						Type="1"	NotZeroWarning=""
+		Name="DistanceSourceToDetector"							Type="1"	NotZeroWarning=""
+	SequenceEnd
+MacroEnd
+
+Module="XAXRFMultiFramePresentation"
+	Name="PreferredPlaybackSequencing"							Type="3"	BinaryEnumValues="PreferredPlaybackSequencing"
+	Sequence="FrameDisplaySequence"								Type="3"	VM="1-n"
+		Name="StartTrim"										Type="1"
+		Name="StopTrim"											Type="1"
+		Name="SkipFrameRangeFlag"								Type="1"	StringDefinedTerms="SkipFrameRangeFlag"
+		Name="RecommendedDisplayFrameRateInFloat"				Type="1"
+		Name="RecommendedViewingMode"							Type="2"	StringDefinedTerms="RecommendedViewingMode"
+		Name="DisplayFilterPercentage"							Type="2"
+		Name="MaskVisibilityPercentage"							Type="1C"	Condition="RecommendedViewingModeIsSUB"
+	SequenceEnd
+ModuleEnd
+
+
+Module="MultiFrameFunctionalGroupsForEnhancedXAImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"		Condition="NeedPixelIntensityRelationshipLUTMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FramePixelShiftMacro"		Condition="FramePixelShiftMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PatientOrientationInFrameMacro"		Condition="NeedPatientOrientationInFrameMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"		Condition="FrameDisplayShutterMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"			Condition="IrradiationEventIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameCharacteristicsMacro"		Condition="XRayFrameCharacteristicsMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFieldOfViewMacro"		Condition="NeedXRayFieldOfViewMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayExposureControlSensingRegionsMacro"		Condition="XRayExposureControlSensingRegionsMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFramePixelDataPropertiesMacro"			Condition="FramePixelDataPropertiesSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameDetectorParametersMacro"		Condition="NeedXRayFrameDetectorParametersMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayCalibrationDeviceUsageMacro"		Condition="XRayCalibrationDeviceUsageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayObjectThicknessMacro"		Condition="XRayObjectThicknessMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameAcquisitionMacro"		Condition="XRayFrameAcquisitionMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayProjectionPixelCalibrationMacro"		Condition="NeedXRayProjectionPixelCalibrationMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayPositionerMacro"		Condition="NeedXRayPositionerMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayTablePositionMacro"		Condition="NeedXRayTablePositionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayCollimatorMacro"		Condition="NeedXRayCollimatorMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayIsocenterReferenceSystemMacro"		Condition="XRayIsocenterReferenceSystemMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayGeometryMacro"		Condition="NeedXRayGeometryMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"		Condition="NeedPixelIntensityRelationshipLUTMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FramePixelShiftMacro"		Condition="FramePixelShiftMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PatientOrientationInFrameMacro"		Condition="NeedPatientOrientationInFrameMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"		Condition="FrameDisplayShutterMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"			Condition="IrradiationEventIdentificationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameCharacteristicsMacro"		Condition="XRayFrameCharacteristicsMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFieldOfViewMacro"		Condition="NeedXRayFieldOfViewMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayExposureControlSensingRegionsMacro"		Condition="XRayExposureControlSensingRegionsMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFramePixelDataPropertiesMacro"			Condition="FramePixelDataPropertiesSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameDetectorParametersMacro"		Condition="NeedXRayFrameDetectorParametersMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayCalibrationDeviceUsageMacro"		Condition="XRayCalibrationDeviceUsageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayObjectThicknessMacro"		Condition="XRayObjectThicknessMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameAcquisitionMacro"		Condition="XRayFrameAcquisitionMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayProjectionPixelCalibrationMacro"		Condition="NeedXRayProjectionPixelCalibrationMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayPositionerMacro"		Condition="NeedXRayPositionerMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayTablePositionMacro"		Condition="NeedXRayTablePositionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayCollimatorMacro"		Condition="NeedXRayCollimatorMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayIsocenterReferenceSystemMacro"		Condition="XRayIsocenterReferenceSystemMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayGeometryMacro"		Condition="NeedXRayGeometryMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForEnhancedXRFImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"		Condition="NeedPixelIntensityRelationshipLUTMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FramePixelShiftMacro"		Condition="FramePixelShiftMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="PatientOrientationInFrameMacro"		Condition="NeedPatientOrientationInFrameMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"		Condition="FrameDisplayShutterMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"			Condition="IrradiationEventIdentificationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameCharacteristicsMacro"		Condition="XRayFrameCharacteristicsMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFieldOfViewMacro"		Condition="NeedXRayFieldOfViewMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayExposureControlSensingRegionsMacro"		Condition="XRayExposureControlSensingRegionsMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFramePixelDataPropertiesMacro"			Condition="FramePixelDataPropertiesSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameDetectorParametersMacro"		Condition="NeedXRayFrameDetectorParametersMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayCalibrationDeviceUsageMacro"		Condition="XRayCalibrationDeviceUsageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayObjectThicknessMacro"		Condition="XRayObjectThicknessMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameAcquisitionMacro"		Condition="XRayFrameAcquisitionMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayPositionerMacro"		Condition="NeedXRayPositionerMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayTablePositionMacro"		Condition="NeedXRayTablePositionMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayCollimatorMacro"		Condition="NeedXRayCollimatorMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayGeometryMacro"		Condition="NeedXRayGeometryMacroInSharedFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelIntensityRelationshipLUTMacro"		Condition="NeedPixelIntensityRelationshipLUTMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FramePixelShiftMacro"		Condition="FramePixelShiftMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PatientOrientationInFrameMacro"		Condition="NeedPatientOrientationInFrameMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameDisplayShutterMacro"		Condition="FrameDisplayShutterMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="IrradiationEventIdentificationMacro"			Condition="IrradiationEventIdentificationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameCharacteristicsMacro"		Condition="XRayFrameCharacteristicsMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFieldOfViewMacro"		Condition="NeedXRayFieldOfViewMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayExposureControlSensingRegionsMacro"		Condition="XRayExposureControlSensingRegionsMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFramePixelDataPropertiesMacro"			Condition="FramePixelDataPropertiesSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="XRayFrameDetectorParametersMacro"		Condition="NeedXRayFrameDetectorParametersMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayCalibrationDeviceUsageMacro"		Condition="XRayCalibrationDeviceUsageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayObjectThicknessMacro"		Condition="XRayObjectThicknessMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayFrameAcquisitionMacro"		Condition="XRayFrameAcquisitionMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayPositionerMacro"		Condition="NeedXRayPositionerMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayTablePositionMacro"		Condition="NeedXRayTablePositionMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayCollimatorMacro"		Condition="NeedXRayCollimatorMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRayGeometryMacro"		Condition="NeedXRayGeometryMacroInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForXRay3DAngiographicImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="CardiacSynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="XRay3DFrameTypeMacro"		Condition="XRay3DFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="CardiacSynchronizationMacro"		Condition="CardiacSynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RespiratorySynchronizationMacro"		Condition="RespiratorySynchronizationMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRay3DFrameTypeMacro"		Condition="XRay3DFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+Module="MultiFrameFunctionalGroupsForXRay3DCraniofacialImage"
+	Sequence="SharedFunctionalGroupsSequence"	Type="1"	VM="1"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceOKInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInPerFrameFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInSharedFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInSharedFunctionalGroupSequence"
+		InvokeMacro="XRay3DFrameTypeMacro"		Condition="XRay3DFrameTypeSequenceNotInPerFrameFunctionalGroupSequence"
+	SequenceEnd
+	Sequence="PerFrameFunctionalGroupsSequence"	Type="1"	VM="1-n"
+		InvokeMacro="PixelMeasuresMacro"		Condition="PixelMeasuresSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="FrameContentMacro"
+		InvokeMacro="PlanePositionMacro"		Condition="PlanePositionSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PlaneOrientationMacro"		Condition="PlaneOrientationSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="ReferencedImageMacro"		Condition="ReferencedImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="DerivationImageMacro"		Condition="DerivationImageMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameAnatomyMacro"			Condition="FrameAnatomySequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="PixelValueTransformationMacro"	Condition="PixelValueTransformationSequenceOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="FrameVOILUTMacro"			Condition="FrameVOILUTSequenceNotInSharedFunctionalGroupSequence"
+		InvokeMacro="RealWorldValueMappingMacro"	Condition="RealWorldValueMappingMacroOKInPerFrameFunctionalGroupSequence"
+		InvokeMacro="ContrastBolusUsageMacro"		Condition="NeedContrastBolusUsageMacroInPerFrameFunctionalGroupSequence"
+		InvokeMacro="XRay3DFrameTypeMacro"		Condition="XRay3DFrameTypeSequenceNotInSharedFunctionalGroupSequence"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="CommonCTMRImageDescriptionImageLevelMacroForXRay3DImage" InformationEntity="Image"
+	Name="PixelPresentation"						Type="1"	StringEnumValues="CommonCTMRPixelPresentationImageLevel"
+	Verify="PixelPresentation"									Condition="EnhancedMRColorImageInstance"	StringEnumValues="PixelPresentationTrueColor"
+	Name="VolumetricProperties"						Type="1"	StringEnumValues="CommonCTMRVolumetricPropertiesImageLevel"
+	Name="VolumeBasedCalculationTechnique"			Type="1"	StringDefinedTerms="XRay3DImageVolumeBasedCalculationTechniqueImageLevel"
+MacroEnd
+
+Module="XRay3DImage"
+	Name="ImageType"										Type="1"	VM="4"
+	Verify="ImageType"													ValueSelector="0"	StringEnumValues="CommonEnhancedImageType1"
+	Verify="ImageType"													ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+	Verify="ImageType"													Condition="NotBreastTomosynthesisInstance" ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3"
+	Verify="ImageType"													Condition="NotBreastTomosynthesisInstance" ValueSelector="3"	StringEnumValues="XRay3DImageAndFrameType4"
+	InvokeMacro="CommonCTMRImageDescriptionImageLevelMacroForXRay3DImage"
+	Name="BitsAllocated"									Type="1"	BinaryEnumValues="BitsAre8Or16"
+	Name="BitsStored"										Type="1"	BinaryEnumValues="BitsAre8To16"
+	Name="HighBit"											Type="1"	BinaryEnumValues="BitsAre7To15"
+	Name="SamplesPerPixel"									Type="1"	BinaryEnumValues="SamplesPerPixelIsOne"
+	Name="PhotometricInterpretation"						Type="1"	StringEnumValues="PhotometricInterpretationMonochrome2"
+	Name="ContentQualification"								Type="1"	StringEnumValues="ContentQualification"
+	Name="BurnedInAnnotation"								Type="1"	StringEnumValues="NoFull"
+	Name="RecognizableVisualFeatures"						Type="3"	StringEnumValues="YesNoFull"
+	Name="LossyImageCompression"							Type="1"	StringEnumValues="LossyImageCompression"
+	Name="LossyImageCompressionRatio"						Type="1C"	Condition="LossyImageCompressionIs01"
+	Name="LossyImageCompressionMethod"						Type="1C"	StringDefinedTerms="LossyImageCompressionMethod"	Condition="LossyImageCompressionIs01"
+	Verify="LossyImageCompressionMethod"								Condition="LossyImageCompressionMethodInconsistentWithTransferSyntax"	ThenWarningMessage="method inconsistent with transfer syntax" ShowValueWithMessage="true"
+	Sequence="ReferencedImageEvidenceSequence"				Type="1C"	VM="1-n"	Condition="ReferencedImageSequenceIsPresentInFunctionalGroups"
+		InvokeMacro="HierarchicalSOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="ImageComments"									Type="3"
+	Name="QualityControlImage"								Type="3"	StringEnumValues="YesNoFull"
+	Sequence="IconImageSequence"							Type="3"	VM="1"
+		InvokeMacro="IconImageSequenceMacro"
+	SequenceEnd
+	Name="PresentationLUTShape"								Type="1"	StringEnumValues="IdentityPresentationLUTShape"
+	Sequence="SourceIrradiationEventSequence"				Type="3"	VM="1-n"
+		Name="IrradiationEventUID"							Type="1"
+	SequenceEnd
+ModuleEnd
+
+Module="XRay3DAngiographicImageContributingSources"
+	Sequence="ContributingSourcesSequence"		Type="1"	VM="1-n"
+		InvokeMacro="GeneralContributingSourcesMacro"
+		InvokeMacro="ContributingImageSourcesMacro"
+		Name="AcquisitionDeviceProcessingDescription"		Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		Name="AcquisitionDeviceProcessingCode"				Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		Name="PlaneIdentification"							Type="1C"	NoCondition=""	StringEnumValues="PlaneIdentification"	# if present and have an equal value in the contributing SOP Instances :(
+		Name="ImagerPixelSpacing"							Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	SequenceEnd
+ModuleEnd
+
+Module="XRay3DCraniofacialImageContributingSources"
+	Sequence="ContributingSourcesSequence"		Type="1"	VM="1-n"
+		InvokeMacro="GeneralContributingSourcesMacro"
+		InvokeMacro="ContributingImageSourcesMacro"
+		Name="AcquisitionDeviceProcessingDescription"		Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		Name="AcquisitionDeviceProcessingCode"				Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+		Name="ImagerPixelSpacing"							Type="1C"	NoCondition=""	# if present and have an equal value in the contributing SOP Instances :(
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="XRay3DGeneralSharedAcquisitionMacro"
+	Sequence="SourceImageSequence"						Type="1C"	VM="1-n"	Condition="SourceImageSequenceIsPresent"		# if if the reconstruction is created from DICOM SOP Instances :(
+		InvokeMacro="ImageSOPInstanceReferenceMacro"
+	SequenceEnd
+	Name="FieldOfViewDimensionsInFloat"					Type="1C"	VM="1-2"	NotZeroWarning=""	Condition="ModalityIsMG" mbpo="true"			# since also real world if present and consistent in contributing instances
+	Verify="FieldOfViewDimensionsInFloat"				Type="1C"	VM="2"		Condition="FieldOfViewDimensionsInFloatPresentAndFieldOfViewShapeIsRectangle"
+	Verify="FieldOfViewDimensionsInFloat"				Type="1C"	VM="1"		Condition="FieldOfViewDimensionsInFloatPresentAndFieldOfViewShapeIsRound"
+	Verify="FieldOfViewDimensionsInFloat"				Type="1C"	VM="1"		Condition="FieldOfViewDimensionsInFloatPresentAndFieldOfViewShapeIsHexagon"
+	Name="FieldOfViewOrigin"							Type="1C"	Condition="XRayReceptorTypeIsDigitalDetector"
+	Name="FieldOfViewRotation"							Type="1C"	NoCondition=""												# if present and have an equal value in the contributing SOP Instances :(
+	Name="FieldOfViewHorizontalFlip"					Type="1C"	NoCondition=""												# if present and have an equal value in the contributing SOP Instances :(
+	Name="Grid"											Type="1C"	NoCondition=""	StringDefinedTerms="XRayGrid"				# if present and have an equal value in the contributing SOP Instances :(
+	InvokeMacro="XRayGridDescriptionMacro"
+	Name="KVP"											Type="1C"	Condition="ModalityIsMG" mbpo="true"	NotZeroWarning=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="XRayTubeCurrentInmA"							Type="1C"	Condition="ModalityIsMG" mbpo="true"	NotZeroWarning=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="ExposureTimeInms"								Type="1C"	Condition="ModalityIsMG" mbpo="true"	NotZeroWarning=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="ExposureInmAs"								Type="1C"	Condition="ModalityIsMG" mbpo="true"	NotZeroWarning=""	# if present and have an equal value in the contributing SOP Instances :(
+	Name="ContrastBolusAgent"							Type="1C"	NoCondition=""												# if present and have an equal value in the contributing SOP Instances :(
+	Sequence="ContrastBolusAgentSequence"				Type="1C"	VM="1-n"	NoCondition=""									# if present and have an equal value in the contributing SOP Instances etc. :(
+		InvokeMacro="CodeSequenceMacro"
+	SequenceEnd
+	Name="StartAcquisitionDateTime"						Type="1C"	NoCondition=""												# if present and have an equal value in the contributing SOP Instances :(
+	Name="EndAcquisitionDateTime"						Type="1C"	NoCondition=""												# if present and have an equal value in the contributing SOP Instances :(
+MacroEnd
+
+DefineMacro="XRay3DGeneralPerProjectionAcquisitionMacro"
+	Name="KVP"											Type="1C"	Condition="ModalityIsMG" mbpo="true"	NotZeroWarning=""	# since also if present and have an equal value in the contributing SOP Instances :(
+	Name="XRayTubeCurrentInmA"							Type="1C"	Condition="ModalityIsMG" mbpo="true"	NotZeroWarning=""	# since also if present and have an equal value in the contributing SOP Instances :(
+	Name="FrameAcquisitionDuration"						Type="1C"	NoCondition=""	NotZeroWarning=""							# if present and have an equal value in the contributing SOP Instances :(
+	Name="CollimatorShape"								Type="1C"	NoCondition=""	StringEnumValues="CollimatorShape"			# if present and have an equal value in the contributing SOP Instances :(
+	InvokeMacro="XRayCollimatorDimensionsMacro"
+MacroEnd
+
+DefineMacro="XRay3DGeneralPositionerMovementMacro"
+	Name="PrimaryPositionerScanArc"							Type="1C"	Condition="ModalityIsMG" mbpo="true"						# since also real world if present and consistent in contributing instances
+	Name="PrimaryPositionerScanStartAngle"					Type="1C"	Condition="ModalityIsMG" mbpo="true"						# since also real world if present and consistent in contributing instances
+	Name="PrimaryPositionerIncrement"						Type="1C"	Condition="ModalityIsMG" mbpo="true"						# since also real world if present and consistent in contributing instances
+	Name="SecondaryPositionerScanArc"						Type="1C"	NoCondition=""												# real world if present and consistent in contributing instances
+	Name="SecondaryPositionerScanStartAngle"				Type="1C"	NoCondition=""												# real world if present and consistent in contributing instances
+	Name="SecondaryPositionerIncrement"						Type="1C"	NoCondition=""												# real world if present and consistent in contributing instances
+MacroEnd
+
+Module="XRay3DAngiographicAcquisition"
+	Sequence="XRay3DAcquisitionSequence"		Type="1"	VM="1-n"
+		Name="FieldOfViewShape"									Type="1C"	NoCondition=""	StringDefinedTerms="FieldOfViewShape"		# if present and have an equal value in the contributing SOP Instances :(
+		Name="XRayReceptorType"									Type="1C"	NoCondition=""	StringEnumValues="XRayReceptorTypeAngio"	# if present and have an equal value in the contributing SOP Instances :(
+		InvokeMacro="XRay3DGeneralSharedAcquisitionMacro"
+		InvokeMacro="DigitalXRayDetectorMacro"
+		Name="PhysicalDetectorSize"								Type="1C"	NoCondition=""	NotZeroError=""							# if present and have an equal value in the contributing SOP Instances :(
+		Name="PositionOfIsocenterProjection"					Type="1C"	Condition="IsocenterReferenceSystemSequencePresent"		# if present and have an equal value in the contributing SOP Instances :(
+		Name="DistanceSourceToPatient"							Type="1C"	NoCondition=""	NotZeroWarning=""						# if present and have an equal value in the contributing SOP Instances :(
+		Name="DistanceSourceToDetector"							Type="1C"	NoCondition=""	NotZeroWarning=""						# if present and have an equal value in the contributing SOP Instances :(
+		Name="FocalSpots"										Type="1C"	NoCondition=""
+		Name="FilterType"										Type="1C"	NoCondition=""	StringDefinedTerms="DXFilterType"		# if present and have an equal value in the contributing SOP Instances :(
+		Name="FilterMaterial"									Type="1C"	NoCondition=""	StringDefinedTerms="DXFilterMaterial"	# if present and have an equal value in the contributing SOP Instances :(
+		Name="FilterThicknessMaximum"							Type="1C"	NoCondition=""	NotZeroWarning=""						# if present and have an equal value in the contributing SOP Instances :(
+		Name="FilterThicknessMinimum"							Type="1C"	NoCondition=""	NotZeroWarning=""						# if present and have an equal value in the contributing SOP Instances :(
+		InvokeMacro="XRay3DGeneralPositionerMovementMacro"
+		Sequence="PerProjectionAcquisitionSequence"				Type="1C"	VM="1-n"	NoCondition=""								# if present and have an equal value in the contributing SOP Instances :(
+			InvokeMacro="XRay3DGeneralPerProjectionAcquisitionMacro"
+			Name="PositionerIsocenterPrimaryAngle"				Type="1C"	NoCondition=""											# if present and have an equal value in the contributing SOP Instances :(
+			Name="PositionerIsocenterSecondaryAngle"			Type="1C"	NoCondition=""											# if present and have an equal value in the contributing SOP Instances :(
+			Name="PositionerIsocenterDetectorRotationAngle"		Type="1C"	NoCondition=""											# if present and have an equal value in the contributing SOP Instances :(
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="XRay3DCraniofacialAcquisition"
+	Sequence="XRay3DAcquisitionSequence"		Type="1"	VM="1-n"
+		Name="FieldOfViewShape"									Type="1C"	NoCondition=""	StringDefinedTerms="FieldOfViewShape"		# if present and have an equal value in the contributing SOP Instances :(
+		Name="XRayReceptorType"									Type="1C"	NoCondition=""	StringEnumValues="XRayReceptorTypeCranio"	# if present and have an equal value in the contributing SOP Instances :(
+		InvokeMacro="XRay3DGeneralSharedAcquisitionMacro"
+		InvokeMacro="DigitalXRayDetectorMacro"
+		Sequence="PerProjectionAcquisitionSequence"				Type="1C"	VM="1-n"	NoCondition=""								# if present and have an equal value in the contributing SOP Instances :(
+			InvokeMacro="XRay3DGeneralPerProjectionAcquisitionMacro"
+		SequenceEnd
+	SequenceEnd
+ModuleEnd
+
+Module="XRay3DReconstruction"
+	Sequence="XRay3DReconstructionSequence"		Type="1"	VM="1-n"
+		Name="ReconstructionDescription"		Type="3"
+		Name="ApplicationName"					Type="1"
+		Name="ApplicationVersion"				Type="1"
+		Name="ApplicationManufacturer"			Type="1"
+		Name="AlgorithmType"					Type="1"	StringDefinedTerms="XRay3DReconstructionAlgorithmType"
+		Name="AlgorithmDescription"				Type="3"
+		Name="AcquisitionIndex "				Type="1"
+	SequenceEnd
+ModuleEnd
+
+DefineMacro="XRay3DFrameTypeMacro"
+	Sequence="XRay3DFrameTypeSequence"				Type="1"	VM="1"
+		Name="FrameType"							Type="1"	VM="4"
+		Verify="FrameType"										ValueSelector="0"	StringEnumValues="CommonEnhancedFrameType1"
+		Verify="FrameType"										ValueSelector="1"	StringEnumValues="CommonEnhancedImageAndFrameType2"
+		Verify="FrameType"										Condition="NotBreastTomosynthesisInstance"	ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3"
+		Verify="FrameType"										Condition="BreastTomosynthesisInstance"		ValueSelector="2"	StringDefinedTerms="CommonEnhancedImageAndFrameType3AndBreastTomoImageAndFrameType3"
+		Verify="FrameType"										Condition="NotBreastTomosynthesisInstance"	ValueSelector="3"	StringEnumValues="XRay3DImageAndFrameType4"
+		Verify="FrameType"										Condition="BreastTomosynthesisInstance"	ValueSelector="3"		StringEnumValues="BreastTomoImageAndFrameType4"
+		Verify="FrameType"										Condition="BreastTomosynthesisInstance"	ValueSelector="4"		StringEnumValues="BreastTomoImageAndFrameType5"
+		InvokeMacro="CommonCTMRImageDescriptionFrameLevelMacro"
+		Name="ReconstructionIndex"					Type="1C"	Condition="XRay3DReconstructionSequenceIsPresent"
+	SequenceEnd
+MacroEnd
diff --git a/libsrc/standard/reorder.sh b/libsrc/standard/reorder.sh
new file mode 100755
index 0000000..d04daa0
--- /dev/null
+++ b/libsrc/standard/reorder.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+sed 's/^\([(0-9a-zA-Z,()]*\)[ 	]*VERS=\(\".*\"\)[ 	]Keyword=\(\".*\"\)[ 	]Name=\(\".*\"\)[ 	]VR=\(\".*\"\)[ 	]VM=\(\".*\"\)[ 	]*$/\1 VERS=\2	VR=\5   VM=\6	Keyword=\4	Name=\4/' < sup11dic.old | sed -e 's/^\(.*Keyword=\"\)\([^ ]*\) \([^"]*[^"]*\)\(\".*\)$/\1\2\3\4/' -e 's/^\(.*Keyword=\"\)\([^ ]*\) \([^"]*[^"]*\)\(\".*\)$/\1\2\3\4/' -e 's/^\(.*Keyword=\"\)\([^ ]*\) \([^"]*[^"]*\)\(\".*\)$/\1\2\3\4/' -e 's/^\(.*Keyword=\"\)\([^ ]*\) \([^"]*[^"]*\)\(\".*\)$/\1\2\3\4/' > sup11dic.tpl
diff --git a/libsrc/standard/sopcl.tpl b/libsrc/standard/sopcl.tpl
new file mode 100755
index 0000000..3596618
--- /dev/null
+++ b/libsrc/standard/sopcl.tpl
@@ -0,0 +1,270 @@
+# NB. Type defaults to "Class"
+
+					Name="Verification"						Desc="Verification"						Uid="1.2.840.10008.1.1"
+					Name="MediaStorageDirectoryStorage"				Desc="Media Storage Directory Storage"				Uid="1.2.840.10008.1.3.10"
+					Name="BasicStudyContentNotification"				Desc="Basic Study Content Notification"				Uid="1.2.840.10008.1.9"
+
+					Name="StorageCommitmentPushModel"				Desc="Storage Commitment Push Model"				Uid="1.2.840.10008.1.20.1"
+					Name="StorageCommitmentPushModel"				Desc="Storage Commitment Push Model"	Type="Instance"		Uid="1.2.840.10008.1.20.1.1"
+					Name="StorageCommitmentPullModel"				Desc="Storage Commitment Pull Model"				Uid="1.2.840.10008.1.20.2"
+					Name="StorageCommitmentPullModel"				Desc="Storage Commitment Pull Model"	Type="Instance"		Uid="1.2.840.10008.1.20.2.1"
+
+DirectoryRecord="PATIENT"		Name="DetachedPatientManagement"				Desc="Detached Patient Management"				Uid="1.2.840.10008.3.1.2.1.1"
+					Name="DetachedPatientManagementMeta"				Desc="Detached Patient Management Meta"				Uid="1.2.840.10008.3.1.2.1.4"
+DirectoryRecord="VISIT"			Name="DetachedVisitManagement"					Desc="Detached Visit Management"				Uid="1.2.840.10008.3.1.2.2.1"
+DirectoryRecord="STUDY"			Name="DetachedStudyManagement"					Desc="Detached Study Management"				Uid="1.2.840.10008.3.1.2.3.1"
+DirectoryRecord="STUDY COMPONENT"	Name="StudyComponentManagement"					Desc="Study Component Management"				Uid="1.2.840.10008.3.1.2.3.2"
+DirectoryRecord="STUDY COMPONENT"	Name="ModalityPerformedProcedureStep"				Desc="Modality Performed Procedure Step"			Uid="1.2.840.10008.3.1.2.3.3"
+					Name="ModalityPerformedProcedureStepRetrieve"			Desc="Modality Performed Procedure Step Retrieve"		Uid="1.2.840.10008.3.1.2.3.4"
+					Name="ModalityPerformedProcedureStepNotification"		Desc="Modality Performed Procedure Step Notification"		Uid="1.2.840.10008.3.1.2.3.5"
+DirectoryRecord="RESULTS"		Name="DetachedResultsManagement"				Desc="Detached Results Management"				Uid="1.2.840.10008.3.1.2.5.1"
+					Name="DetachedResultsManagementMeta"				Desc="Detached Results Management Meta"				Uid="1.2.840.10008.3.1.2.5.4"
+					Name="DetachedStudyManagementMeta"				Desc="Detached Study Management Meta"				Uid="1.2.840.10008.3.1.2.5.5"
+DirectoryRecord="INTERPRETATION"	Name="DetachedInterpretationManagement"				Desc="Detached Interpretation Management"			Uid="1.2.840.10008.3.1.2.6.1"
+
+DirectoryRecord="FILM SESSION"		Name="BasicFilmSession"						Desc="Basic Film Session"					Uid="1.2.840.10008.5.1.1.1"
+DirectoryRecord="FILM BOX"		Name="BasicFilmBox"						Desc="Basic Film Box"						Uid="1.2.840.10008.5.1.1.2"
+DirectoryRecord="IMAGE BOX"		Name="BasicGrayscaleImageBox"					Desc="Basic Grayscale Image Box"				Uid="1.2.840.10008.5.1.1.4"
+DirectoryRecord="IMAGE BOX"		Name="BasicColorImageBox"					Desc="Basic Color Image Box"					Uid="1.2.840.10008.5.1.1.4.1"
+					Name="ReferencedImageBoxRetired"				Desc="Referenced Image Box - Retired"				Uid="1.2.840.10008.5.1.1.4.2"
+					Name="BasicGrayscalePrintManagementMeta"			Desc="Basic Grayscale Print Management Meta"			Uid="1.2.840.10008.5.1.1.9"
+					Name="ReferencedGrayscalePrintManagementMetaRetired"		Desc="Referenced Grayscale Print Management Meta - Retired"	Uid="1.2.840.10008.5.1.1.9.1"
+					Name="PrintJob"							Desc="Print Job"						Uid="1.2.840.10008.5.1.1.14"
+					Name="BasicAnnotationBox"					Desc="Basic Annotation Box"					Uid="1.2.840.10008.5.1.1.15"
+					Name="Printer"							Desc="Printer"							Uid="1.2.840.10008.5.1.1.16"
+					Name="Printer"							Desc="Printer"				Type="Instance"		Uid="1.2.840.10008.5.1.1.17"
+					Name="PrinterConfigurationRetrieval"				Desc="Printer Configuration Retrieval"				Uid="1.2.840.10008.5.1.1.16.376"
+					Name="PrinterConfigurationRetrieval"				Desc="Printer Configuration Retrieval"	Type="Instance"		Uid="1.2.840.10008.5.1.1.17.376"
+					Name="BasicColorPrintManagementMeta"				Desc="Basic Color Print Management Meta"			Uid="1.2.840.10008.5.1.1.18"
+					Name="ReferencedColorPrintManagementMetaRetired"		Desc="Referenced Color Print Management Meta - Retired"		Uid="1.2.840.10008.5.1.1.18.1"
+					Name="VOILUTBox"						Desc="VOI LUT Box"						Uid="1.2.840.10008.5.1.1.22"
+					Name="PresentationLUTBox"					Desc="Presentation LUT Box"					Uid="1.2.840.10008.5.1.1.23"
+					Name="ImageOverlayBoxRetired"					Desc="Image Overlay Box - Retired"				Uid="1.2.840.10008.5.1.1.24"
+					Name="BasicPrintImageOverlayBox"				Desc="Basic Print Image Overlay Box"				Uid="1.2.840.10008.5.1.1.24.1"
+					Name="PrintQueue"						Desc="Print Queue"		Type="Instance"			Uid="1.2.840.10008.5.1.1.25"
+DirectoryRecord="PRINT QUEUE"		Name="PrintQueueManagement"					Desc="Print Queue Management"					Uid="1.2.840.10008.5.1.1.26"
+DirectoryRecord="STORED PRINT"		Name="StoredPrintStorage"					Desc="Stored Print Storage"					Uid="1.2.840.10008.5.1.1.27"
+DirectoryRecord="IMAGE"			Name="HardcopyGrayscaleImageStorage"				Desc="Hardcopy Grayscale Image Storage"				Uid="1.2.840.10008.5.1.1.29"
+DirectoryRecord="IMAGE"			Name="HardcopyColorImageStorage"				Desc="Hardcopy Color Image Storage"				Uid="1.2.840.10008.5.1.1.30"
+					Name="PullPrintRequest"						Desc="Pull Print Request"					Uid="1.2.840.10008.5.1.1.31"
+					Name="PullStoredPrintManagementMeta"				Desc="Pull Stored Print Management Meta"			Uid="1.2.840.10008.5.1.1.32"
+
+DirectoryRecord="IMAGE"			Name="ComputedRadiographyImageStorage"				Desc="Computed Radiography Image Storage"				Uid="1.2.840.10008.5.1.4.1.1.1"
+DirectoryRecord="IMAGE"			Name="DigitalXRayImageStorageForPresentation"			Desc="Digital X-Ray Image Storage - For Presentation"			Uid="1.2.840.10008.5.1.4.1.1.1.1"
+DirectoryRecord="IMAGE"			Name="DigitalXRayImageStorageForProcessing"			Desc="Digital X-Ray Image Storage - For Processing"			Uid="1.2.840.10008.5.1.4.1.1.1.1.1"
+DirectoryRecord="IMAGE"			Name="DigitalMammographyXRayImageStorageForPresentation"	Desc="Digital Mammography X-Ray Image Storage - For Presentation"	Uid="1.2.840.10008.5.1.4.1.1.1.2"
+DirectoryRecord="IMAGE"			Name="DigitalMammographyXRayImageStorageForProcessing"		Desc="Digital Mammography X-Ray Image Storage - For Processing"		Uid="1.2.840.10008.5.1.4.1.1.1.2.1"
+DirectoryRecord="IMAGE"			Name="DigitalIntraoralXRayImageStorageForPresentation"		Desc="Digital Intra-oral X-Ray Image Storage - For Presentation"	Uid="1.2.840.10008.5.1.4.1.1.1.3"
+DirectoryRecord="IMAGE"			Name="DigitalIntraoralXRayImageStorageForProcessing"		Desc="Digital Intra-oral X-Ray Image Storage - For Processing"		Uid="1.2.840.10008.5.1.4.1.1.1.3.1"
+
+DirectoryRecord="IMAGE"			Name="CTImageStorage"							Desc="CT Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.2"
+DirectoryRecord="IMAGE"			Name="EnhancedCTImageStorage"					Desc="Enhanced CT Image Storage"					Uid="1.2.840.10008.5.1.4.1.1.2.1"
+DirectoryRecord="IMAGE"			Name="LegacyConvertedEnhancedCTImageStorage"	Desc="Legacy Converted Enhanced CT Image Storage"	Uid="1.2.840.10008.5.1.4.1.1.2.2"
+
+DirectoryRecord="IMAGE"			Name="UltrasoundMultiframeImageStorageRetired"			Desc="Ultrasound Multiframe Image Storage - Retired"			Uid="1.2.840.10008.5.1.4.1.1.3"
+DirectoryRecord="IMAGE"			Name="UltrasoundMultiframeImageStorage"				Desc="Ultrasound Multiframe Image Storage"				Uid="1.2.840.10008.5.1.4.1.1.3.1"
+
+DirectoryRecord="IMAGE"			Name="MRImageStorage"							Desc="MR Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.4"
+DirectoryRecord="IMAGE"			Name="EnhancedMRImageStorage"					Desc="Enhanced MR Image Storage"					Uid="1.2.840.10008.5.1.4.1.1.4.1"
+DirectoryRecord="IMAGE"			Name="EnhancedMRColorImageStorage"				Desc="Enhanced MR Color Image Storage"				Uid="1.2.840.10008.5.1.4.1.1.4.3"
+DirectoryRecord="IMAGE"			Name="LegacyConvertedEnhancedMRImageStorage"	Desc="Legacy Converted Enhanced MR Image Storage"	Uid="1.2.840.10008.5.1.4.1.1.4.4"
+
+DirectoryRecord="IMAGE"			Name="NuclearMedicineImageStorageRetired"			Desc="Nuclear Medicine Image Storage - Retired"				Uid="1.2.840.10008.5.1.4.1.1.5"
+DirectoryRecord="IMAGE"			Name="UltrasoundImageStorageRetired"				Desc="Ultrasound Image Storage - Retired"				Uid="1.2.840.10008.5.1.4.1.1.6"
+DirectoryRecord="IMAGE"			Name="UltrasoundImageStorage"					Desc="Ultrasound Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.6.1"
+DirectoryRecord="IMAGE"			Name="EnhancedUSVolumeStorage"					Desc="Enhanced US Volume Storage"					Uid="1.2.840.10008.5.1.4.1.1.6.2"
+DirectoryRecord="IMAGE"			Name="SecondaryCaptureImageStorage"				Desc="Secondary Capture Image Storage"					Uid="1.2.840.10008.5.1.4.1.1.7"
+DirectoryRecord="IMAGE"			Name="MultiframeSingleBitSecondaryCaptureImageStorage"		Desc="Multiframe Single Bit Secondary Capture Image Storage"		Uid="1.2.840.10008.5.1.4.1.1.7.1"
+DirectoryRecord="IMAGE"			Name="MultiframeGrayscaleByteSecondaryCaptureImageStorage"	Desc="Multiframe Grayscale Byte Secondary Capture Image Storage"	Uid="1.2.840.10008.5.1.4.1.1.7.2"
+DirectoryRecord="IMAGE"			Name="MultiframeGrayscaleWordSecondaryCaptureImageStorage"	Desc="Multiframe Grayscale Word Secondary Capture Image Storage"	Uid="1.2.840.10008.5.1.4.1.1.7.3"
+DirectoryRecord="IMAGE"			Name="MultiframeTrueColorSecondaryCaptureImageStorage"		Desc="Multiframe True Color Secondary Capture Image Storage"		Uid="1.2.840.10008.5.1.4.1.1.7.4"
+
+DirectoryRecord="OVERLAY"		Name="StandaloneOverlayStorage"					Desc="Standalone Overlay Storage"					Uid="1.2.840.10008.5.1.4.1.1.8"
+DirectoryRecord="CURVE"			Name="StandaloneCurveStorage"					Desc="Standalone Curve Storage"						Uid="1.2.840.10008.5.1.4.1.1.9"
+DirectoryRecord="WAVEFORM"		Name="TwelveLeadECGStorage"						Desc="Twelve Lead ECG Storage"						Uid="1.2.840.10008.5.1.4.1.1.9.1.1"
+DirectoryRecord="WAVEFORM"		Name="GeneralECGStorage"						Desc="General ECG Storage"							Uid="1.2.840.10008.5.1.4.1.1.9.1.2"
+DirectoryRecord="WAVEFORM"		Name="AmbulatoryECGStorage"						Desc="Ambulatory ECG Storage"						Uid="1.2.840.10008.5.1.4.1.1.9.1.3"
+DirectoryRecord="WAVEFORM"		Name="HemodynamicWaveformStorage"				Desc="Hemodynamic Waveform Storage"					Uid="1.2.840.10008.5.1.4.1.1.9.2.1"
+DirectoryRecord="WAVEFORM"		Name="CardiacElectrophysiologyWaveformStorage"	Desc="Cardiac Electrophysiology Waveform Storage"	Uid="1.2.840.10008.5.1.4.1.1.9.3.1"
+DirectoryRecord="WAVEFORM"		Name="ArterialPulseWaveformStorage"				Desc="Arterial Pulse Waveform Storage"				Uid="1.2.840.10008.5.1.4.1.1.9.5.1"
+DirectoryRecord="WAVEFORM"		Name="RespiratoryWaveformStorage"				Desc="Respiratory Waveform Storage"					Uid="1.2.840.10008.5.1.4.1.1.9.6.1"
+DirectoryRecord="WAVEFORM"		Name="BasicVoiceStorage"						Desc="Basic Voice Storage"							Uid="1.2.840.10008.5.1.4.1.1.9.4.1"
+DirectoryRecord="WAVEFORM"		Name="GeneralAudioWaveformStorage"				Desc="General Audio Waveform Storage"				Uid="1.2.840.10008.5.1.4.1.1.9.4.2"
+
+DirectoryRecord="MODALITY LUT"	Name="StandaloneModalityLUTStorage"				Desc="Standalone Modality LUT Storage"				Uid="1.2.840.10008.5.1.4.1.1.10"
+DirectoryRecord="VOI LUT"		Name="StandaloneVOILUTStorage"					Desc="Standalone VOI LUT Storage"					Uid="1.2.840.10008.5.1.4.1.1.11"
+
+DirectoryRecord="PRESENTATION"		Name="GrayscaleSoftcopyPresentationStateStorage"		Desc="Grayscale Softcopy Presentation State Storage"		Uid="1.2.840.10008.5.1.4.1.1.11.1"
+DirectoryRecord="PRESENTATION"		Name="ColorSoftcopyPresentationStateStorage"			Desc="Color Softcopy Presentation State Storage"			Uid="1.2.840.10008.5.1.4.1.1.11.2"
+DirectoryRecord="PRESENTATION"		Name="PseudoColorSoftcopyPresentationStateStorage"		Desc="Pseudo-Color Softcopy Presentation State Storage"		Uid="1.2.840.10008.5.1.4.1.1.11.3"
+DirectoryRecord="PRESENTATION"		Name="BlendingSoftcopyPresentationStateStorage"			Desc="Blending Softcopy Presentation State Storage"			Uid="1.2.840.10008.5.1.4.1.1.11.4"
+DirectoryRecord="PRESENTATION"		Name="XAXRFGrayscaleSoftcopyPresentationStateStorage"	Desc="XA/XRF Grayscale Softcopy Presentation State Storage"	Uid="1.2.840.10008.5.1.4.1.1.11.5"
+DirectoryRecord="PRESENTATION"		Name="GrayscalePlanarMPRVolumetricPresentationStateStorage"		Desc="Grayscale Planar MPR Volumetric Presentation State Storage"	Uid="1.2.840.10008.5.1.4.1.1.11.6"
+DirectoryRecord="PRESENTATION"		Name="CompositingPlanarMPRVolumetricPresentationStateStorage"	Desc="Compositing Planar MPR Volumetric Presentation State Storage"	Uid="1.2.840.10008.5.1.4.1.1.11.7"
+
+DirectoryRecord="IMAGE"			Name="XRayAngiographicImageStorage"				Desc="X-Ray Angiographic Image Storage"				Uid="1.2.840.10008.5.1.4.1.1.12.1"
+DirectoryRecord="IMAGE"			Name="EnhancedXAImageStorage"					Desc="Enhanced XA Image Storage"					Uid="1.2.840.10008.5.1.4.1.1.12.1.1"
+DirectoryRecord="IMAGE"			Name="XRayRadioFluoroscopicImageStorage"			Desc="X-Ray RadioFluoroscopic Image Storage"			Uid="1.2.840.10008.5.1.4.1.1.12.2"
+DirectoryRecord="IMAGE"			Name="EnhancedXRFImageStorage"						Desc="Enhanced XRF Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.12.2.1"
+DirectoryRecord="IMAGE"			Name="XRayAngiographicBiplaneImageStorage"			Desc="X-Ray Angiographic Biplane Image Storage"			Uid="1.2.840.10008.5.1.4.1.1.12.3"
+DirectoryRecord="IMAGE"			Name="XRay3DAngiographicImageStorage"			Desc="X-Ray 3D Angiographic Image Storage"			Uid="1.2.840.10008.5.1.4.1.1.13.1.1"
+DirectoryRecord="IMAGE"			Name="XRay3DCraniofacialImageStorage"			Desc="X-Ray 3D Craniofacial Image Storage"			Uid="1.2.840.10008.5.1.4.1.1.13.1.2"
+DirectoryRecord="IMAGE"			Name="BreastTomosynthesisImageStorage"			Desc="Breast Tomosynthesis Image Storage"			Uid="1.2.840.10008.5.1.4.1.1.13.1.3" 	
+DirectoryRecord="IMAGE"			Name="BreastProjectionXRayImageStorageForPresentation"			Desc="Breast Projection X-Ray Image Storage - For Presentation"			Uid="1.2.840.10008.5.1.4.1.1.13.1.4"
+DirectoryRecord="IMAGE"			Name="BreastProjectionXRayImageStorageForProcessing"			Desc="Breast Projection X-Ray Image Storage - For Processing"			Uid="1.2.840.10008.5.1.4.1.1.13.1.5"
+
+DirectoryRecord="IMAGE"			Name="NuclearMedicineImageStorage"							Desc="Nuclear Medicine Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.20"
+
+DirectoryRecord="IMAGE"			Name="VisibleLightDraftImageStorage"						Desc="Visible Light Draft Image Storage"							Uid="1.2.840.10008.5.1.4.1.1.77.1"
+DirectoryRecord="IMAGE"			Name="VisibleLightMultiFrameDraftImageStorage"				Desc="Visible Light Multi-frame Draft Image Storage"				Uid="1.2.840.10008.5.1.4.1.1.77.2"
+DirectoryRecord="IMAGE"			Name="VisibleLightEndoscopicImageStorage"					Desc="Visible Light Endoscopic Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.77.1.1"
+DirectoryRecord="IMAGE"			Name="VideoEndoscopicImageStorage"							Desc="Video Endoscopic Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.77.1.1.1"
+DirectoryRecord="IMAGE"			Name="VisibleLightMicroscopicImageStorage"					Desc="Visible Light Microscopic Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.77.1.2"
+DirectoryRecord="IMAGE"			Name="VideoMicroscopicImageStorage"							Desc="Video Microscopic Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.77.1.2.1"
+DirectoryRecord="IMAGE"			Name="VisibleLightSlideCoordinatesMicroscopicImageStorage"	Desc="Visible Light Slide Coordinates Microscopic Image Storage"	Uid="1.2.840.10008.5.1.4.1.1.77.1.3"
+DirectoryRecord="IMAGE"			Name="VisibleLightPhotographicImageStorage"					Desc="Visible Light Photographic Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.77.1.4"
+DirectoryRecord="IMAGE"			Name="VideoPhotographicImageStorage"						Desc="Video Photographic Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.77.1.4.1"
+
+DirectoryRecord="IMAGE"			Name="OphthalmicPhotography8BitImageStorage"				Desc="Ophthalmic Photography 8 Bit Image Storage"					Uid="1.2.840.10008.5.1.4.1.1.77.1.5.1"
+DirectoryRecord="IMAGE"			Name="OphthalmicPhotography16BitImageStorage"				Desc="Ophthalmic Photography 16 Bit Image Storage"					Uid="1.2.840.10008.5.1.4.1.1.77.1.5.2"
+DirectoryRecord="STEREOMETRIC"	Name="StereometricRelationshipStorage"						Desc="Stereometric Relationship Storage"							Uid="1.2.840.10008.5.1.4.1.1.77.1.5.3"
+DirectoryRecord="IMAGE"			Name="OphthalmicTomographyImageStorage"						Desc="Ophthalmic Tomography Image Storage"							Uid="1.2.840.10008.5.1.4.1.1.77.1.5.4"
+DirectoryRecord="IMAGE"			Name="WideFieldOphthalmicPhotographyStereographicProjectionImageStorage"	Desc="Wide Field Ophthalmic Photography Stereographic Projection Image Storage"	Uid="1.2.840.10008.5.1.4.1.1.77.1.5.5"
+DirectoryRecord="IMAGE"			Name="WideFieldOphthalmicPhotography3DCoordinatesImageStorage"				Desc="Wide Field Ophthalmic Photography 3D Coordinates Image Storage"			Uid="1.2.840.10008.5.1.4.1.1.77.1.5.6"
+
+DirectoryRecord="IMAGE"			Name="VLWholeSlideMicroscopyImageStorage"					Desc="VL Whole Slide Microscopy Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.77.1.6"
+
+DirectoryRecord="IMAGE"			Name="IVOCTImageStorageForPresentation"						Desc="Intravascular OCT Image Storage - For Presentation"			Uid="1.2.840.10008.5.1.4.1.1.14.1"
+DirectoryRecord="IMAGE"			Name="IVOCTImageStorageForProcessing"						Desc="Intravascular OCT Image Storage - For Processing"				Uid="1.2.840.10008.5.1.4.1.1.14.2"
+
+DirectoryRecord="SR DOCUMENT"		Name="BasicTextSRStorage"					Desc="Basic Text SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.11"
+DirectoryRecord="SR DOCUMENT"		Name="EnhancedSRStorage"					Desc="Enhanced SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.22"
+DirectoryRecord="SR DOCUMENT"		Name="ComprehensiveSRStorage"					Desc="Comprehensive SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.33"
+DirectoryRecord="SR DOCUMENT"		Name="Comprehensive3DSRStorage"					Desc="Comprehensive 3D SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.34"
+DirectoryRecord="SR DOCUMENT"		Name="ExtensibleSRStorage"						Desc="Extensible SR Storage"						Uid="1.2.840.10008.5.1.4.1.1.88.35"
+DirectoryRecord="SR DOCUMENT"		Name="MammographyCADSRStorage"					Desc="Mammography CAD SR Storage"				Uid="1.2.840.10008.5.1.4.1.1.88.50"
+DirectoryRecord="SR DOCUMENT"		Name="ChestCADSRStorage"					Desc="Chest CAD SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.65"
+DirectoryRecord="SR DOCUMENT"		Name="ProcedureLogStorage"					Desc="Procedure Log Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.40"
+DirectoryRecord="SR DOCUMENT"		Name="XRayRadiationDoseSRStorage"					Desc="X-Ray Radiation Dose SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.67"
+DirectoryRecord="SR DOCUMENT"		Name="RadiopharmaceuticalRadiationDoseSRStorage"	Desc="Radiopharmaceutical Radiation Dose SR Storage"	Uid="1.2.840.10008.5.1.4.1.1.88.68"
+DirectoryRecord="SR DOCUMENT"		Name="ColonCADSRStorage"					Desc="Colon CAD SR Storage"					Uid="1.2.840.10008.5.1.4.1.1.88.69"
+DirectoryRecord="SR DOCUMENT"		Name="ImplantationPlanSRStorage"			Desc="Implantation Plan SR Storage"			Uid="1.2.840.10008.5.1.4.1.1.88.70"
+DirectoryRecord="SR DOCUMENT"		Name="AcquisitionContextSRStorage"			Desc="Acquisition Context SR Storage"			Uid="1.2.840.10008.5.1.4.1.1.88.71"
+DirectoryRecord="SR DOCUMENT"		Name="MacularGridThicknessAndVolumeReportStorage"					Desc="Macular Grid Thickness and Volume Report Storage"					Uid="1.2.840.10008.5.1.4.1.1.79.1"
+
+DirectoryRecord="KEY OBJECT DOC"	Name="KeyObjectSelectionDocumentStorage"			Desc="Key Object Selection Document Storage"			Uid="1.2.840.10008.5.1.4.1.1.88.59"
+
+DirectoryRecord="ENCAP DOC"		Name="EncapsulatedPDFStorage"					Desc="Encapsulated PDF Storage"					Uid="1.2.840.10008.5.1.4.1.1.104.1"
+DirectoryRecord="ENCAP DOC"		Name="EncapsulatedCDAStorage"					Desc="Encapsulated CDA Storage"					Uid="1.2.840.10008.5.1.4.1.1.104.2"
+
+DirectoryRecord="IMAGE"			Name="PETImageStorage"							Desc="Positron Emission Tomography Image Storage"		Uid="1.2.840.10008.5.1.4.1.1.128"
+DirectoryRecord="IMAGE"			Name="LegacyConvertedEnhancedPETImageStorage"	Desc="Legacy Converted Enhanced PET Image Storage"		Uid="1.2.840.10008.5.1.4.1.1.128.1"
+DirectoryRecord="CURVE"			Name="StandalonePETCurveStorage"				Desc="Standalone PET Curve Storage"						Uid="1.2.840.10008.5.1.4.1.1.129"
+DirectoryRecord="IMAGE"			Name="EnhancedPETImageStorage"					Desc="Enhanced PET Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.130"
+
+DirectoryRecord="IMAGE"			Name="RTImageStorage"						Desc="RT Image Storage"						Uid="1.2.840.10008.5.1.4.1.1.481.1"
+DirectoryRecord="RT DOSE"		Name="RTDoseStorage"						Desc="RT Dose Storage"						Uid="1.2.840.10008.5.1.4.1.1.481.2"
+DirectoryRecord="RT STRUCTURE SET"	Name="RTStructureSetStorage"					Desc="RT Structure Set Storage"					Uid="1.2.840.10008.5.1.4.1.1.481.3"
+DirectoryRecord="RT TREAT RECORD"	Name="RTBeamsTreatmentRecordStorage"				Desc="RT Beams Treatment Record Storage"			Uid="1.2.840.10008.5.1.4.1.1.481.4"
+DirectoryRecord="RT TREAT RECORD"	Name="RTIonBeamsTreatmentRecordStorage"				Desc="RT Ion Beams Treatment Record Storage"			Uid="1.2.840.10008.5.1.4.1.1.481.9"
+DirectoryRecord="RT PLAN"		Name="RTPlanStorage"						Desc="RT Plan Storage"						Uid="1.2.840.10008.5.1.4.1.1.481.5"
+DirectoryRecord="RT PLAN"		Name="RTIonPlanStorage"						Desc="RT Ion Plan Storage"						Uid="1.2.840.10008.5.1.4.1.1.481.8"
+DirectoryRecord="RT TREAT RECORD"	Name="RTBrachyTreatmentRecordStorage"				Desc="RT Brachy Treatment Record Storage"			Uid="1.2.840.10008.5.1.4.1.1.481.6"
+DirectoryRecord="RT TREAT RECORD"	Name="RTTreatmentSummaryRecordStorage"				Desc="RT Treatment Summary Record Storage"			Uid="1.2.840.10008.5.1.4.1.1.481.7"
+
+DirectoryRecord="PLAN"		Name="RTBeamsDeliveryInstructionStorageTrial"	Desc="RT Beams Delivery Instruction Storage - Trial"				Uid="1.2.840.10008.5.1.4.34.1"
+DirectoryRecord="PLAN"		Name="RTBeamsDeliveryInstructionStorage"		Desc="RT Beams Delivery Instruction Storage"						Uid="1.2.840.10008.5.1.4.34.4"
+
+					Name="PatientRootQueryRetrieveInformationModelFind"		Desc="Patient Root Query/Retrieve Information Model Find"	Uid="1.2.840.10008.5.1.4.1.2.1.1"
+					Name="PatientRootQueryRetrieveInformationModelMove"		Desc="Patient Root Query/Retrieve Information Model Move"	Uid="1.2.840.10008.5.1.4.1.2.1.2"
+					Name="PatientRootQueryRetrieveInformationModelGet"		Desc="Patient Root Query/Retrieve Information Model Get"	Uid="1.2.840.10008.5.1.4.1.2.1.3"
+					Name="StudyRootQueryRetrieveInformationModelFind"		Desc="Study Root Query/Retrieve Information Model Find"		Uid="1.2.840.10008.5.1.4.1.2.2.1"
+					Name="StudyRootQueryRetrieveInformationModelMove"		Desc="Study Root Query/Retrieve Information Model Move"		Uid="1.2.840.10008.5.1.4.1.2.2.2"
+					Name="StudyRootQueryRetrieveInformationModelGet"		Desc="Study Root Query/Retrieve Information Model Get"		Uid="1.2.840.10008.5.1.4.1.2.2.3"
+					Name="PatientStudyOnlyQueryRetrieveInformationModelFind"	Desc="Patient Study Only Query/Retrieve Information Model Find"	Uid="1.2.840.10008.5.1.4.1.2.3.1"
+					Name="PatientStudyOnlyQueryRetrieveInformationModelMove"	Desc="Patient Study Only Query/Retrieve Information Model Move"	Uid="1.2.840.10008.5.1.4.1.2.3.2"
+					Name="PatientStudyOnlyQueryRetrieveInformationModelGet"		Desc="Patient Study Only Query/Retrieve Information Model Get"	Uid="1.2.840.10008.5.1.4.1.2.3.3"
+
+					Name="ModalityWorklistInformationModelFind"			Desc="Modality Worklist Information Model Find"			Uid="1.2.840.10008.5.1.4.31"
+
+					Name="GeneralPurposeWorklistInformationModelFindRetired"					Desc="General Purpose Worklist Information Model Find (Retired)"	Uid="1.2.840.10008.5.1.4.32.1"
+DirectoryRecord="STUDY COMPONENT"	Name="GeneralPurposeScheduledProcedureStepRetired"			Desc="General Purpose Scheduled Procedure Step (Retired)"			Uid="1.2.840.10008.3.1.4.32.2"
+DirectoryRecord="STUDY COMPONENT"	Name="GeneralPurposePerformedProcedureStepRetired"			Desc="General Purpose Performed Procedure Step (Retired)"			Uid="1.2.840.10008.3.1.4.32.3"
+					Name="GeneralPurposeWorklistManagementMetaRetired"							Desc="General Purpose Worklist Management Meta (Retired)"			Uid="1.2.840.10008.5.1.1.32"
+
+DirectoryRecord="IMAGE"			Name="GE_PrivateDicomMRImageInfoObject"				Desc="GE Private Dicom MR Image Info Object"			Uid="1.2.840.113619.4.2"
+DirectoryRecord="IMAGE"			Name="GE_PrivateDicomCTImageInfoObject"				Desc="GE Private Dicom CT Image Info Object"			Uid="1.2.840.113619.4.3"
+DirectoryRecord="IMAGE"			Name="GE_PrivateDicomDisplayImageInfoObject"			Desc="GE Private Dicom Display Image Info Object"		Uid="1.2.840.113619.4.4"
+
+					Name="GE_PrivateARMMigration"					Desc="GE Private ARM Migration"					Uid="1.2.840.113619.4.10"
+Type="Instance"				Name="GE_PrivateARMMigration"					Desc="GE Private ARM Migration"					Uid="1.2.840.113619.7.2"
+
+DirectoryRecord="IMAGE"			Name="VisibleLightImageStorageTrial"				Desc="Visible Light Image Storage - Trial"			Uid="1.2.840.10008.5.1.4.1.1.77.1"
+DirectoryRecord="IMAGE"			Name="VisibleLightMultiframeImageStorageTrial"			Desc="Visible Light Multiframe Image Storage - Trial"		Uid="1.2.840.10008.5.1.4.1.1.77.2"
+
+DirectoryRecord="WAVEFORM"		Name="WaveformStorageTrial"                                     Desc="Waveform Storage Trial"                                   Uid="1.2.840.10008.5.1.4.1.1.9.1"
+DirectoryRecord="SR DOCUMENT"		Name="TextSRStorageTrial"                                       Desc="Text SR Storage Trial"                                    Uid="1.2.840.10008.5.1.4.1.1.88.1"
+DirectoryRecord="SR DOCUMENT"		Name="AudioSRStorageTrial"                                      Desc="Audio SR Storage Trial"                                   Uid="1.2.840.10008.5.1.4.1.1.88.2"
+DirectoryRecord="SR DOCUMENT"		Name="DetailSRStorageTrial"                                     Desc="Detail SR Storage Trial"                                  Uid="1.2.840.10008.5.1.4.1.1.88.3"
+DirectoryRecord="SR DOCUMENT"		Name="ComprehensiveSRStorageTrial"                              Desc="Comprehensive SR Storage Trial"                           Uid="1.2.840.10008.5.1.4.1.1.88.4"
+
+DirectoryRecord="SPECTROSCOPY"		Name="MRSpectroscopyStorage"			 		Desc="MR Spectroscopy Storage"					Uid="1.2.840.10008.5.1.4.1.1.4.2"
+DirectoryRecord="RAW DATA"		Name="RawDataStorage"						Desc="Raw Data Storage"						Uid="1.2.840.10008.5.1.4.1.1.66"
+
+DirectoryRecord="REGISTRATION"		Name="SpatialRegistrationStorage"				Desc="Spatial Registration Storage"				Uid="1.2.840.10008.5.1.4.1.1.66.1"
+DirectoryRecord="FIDUCIAL"		Name="SpatialFiducialsStorage"					Desc="Spatial Fiducials Storage"				Uid="1.2.840.10008.5.1.4.1.1.66.2"
+DirectoryRecord="REGISTRATION"		Name="DeformableSpatialRegistrationStorage"				Desc="Deformable Spatial Registration Storage"				Uid="1.2.840.10008.5.1.4.1.1.66.3"
+
+DirectoryRecord="IMAGE"			Name="SegmentationStorage"				Desc="Segmentation Storage"				Uid="1.2.840.10008.5.1.4.1.1.66.4"
+DirectoryRecord="SURFACE"		Name="SurfaceSegmentationStorage"		Desc="Surface Segmentation Storage"		Uid="1.2.840.10008.5.1.4.1.1.66.5"
+DirectoryRecord="TRACT"			Name="TractographyResultsStorage"		Desc="Tractography Results Storage"		Uid="1.2.840.10008.5.1.4.1.1.66.6"
+
+DirectoryRecord="SURFACE"		Name="SurfaceScanMeshStorage"			Desc="Surface Scan Mesh Storage"		Uid="1.2.840.10008.5.1.4.1.1.68.1"
+DirectoryRecord="SURFACE"		Name="SurfaceScanPointCloudStorage"		Desc="Surface Scan Point Cloud Storage"	Uid="1.2.840.10008.5.1.4.1.1.68.2"
+
+DirectoryRecord="HANGING PROTOCOL"	Name="HangingProtocolStorage"					Desc="Hanging Protocol Storage"					Uid="1.2.840.10008.5.1.4.38.1"
+					Name="HangingProtocolInformationModelFind"			Desc="Hanging Protocol Information Model Find"			Uid="1.2.840.10008.5.1.4.38.2"
+					Name="HangingProtocolInformationModelMove"			Desc="Hanging Protocol Information Model Move"			Uid="1.2.840.10008.5.1.4.38.3"
+					Name="HangingProtocolInformationModelGet"			Desc="Hanging Protocol Information Model Get"			Uid="1.2.840.10008.5.1.4.38.4"
+DirectoryRecord="VALUE MAP"		Name="RealWorldValueMappingStorage"				Desc="Real World Value Mapping Storage"			Uid="1.2.840.10008.5.1.4.1.1.67"
+
+DirectoryRecord="PRESENTATION"	Name="BasicStructuredDisplayStorage"			Desc="Basic Structured Display Storage"				Uid="1.2.840.10008.5.1.4.1.1.131"
+
+DirectoryRecord="MEASUREMENT"	Name="LensometryMeasurementsStorage"			Desc="Lensometry Measurements Storage"				Uid="1.2.840.10008.5.1.4.1.1.78.1"
+DirectoryRecord="MEASUREMENT"	Name="AutorefractionMeasurementsStorage"		Desc="Autorefraction Measurements Storage"			Uid="1.2.840.10008.5.1.4.1.1.78.2"
+DirectoryRecord="MEASUREMENT"	Name="KeratometryMeasurementsStorage"			Desc="Keratometry Measurements Storage"				Uid="1.2.840.10008.5.1.4.1.1.78.3"
+DirectoryRecord="MEASUREMENT"	Name="SubjectiveRefractionMeasurementsStorage"	Desc="Subjective Refraction Measurements Storage"	Uid="1.2.840.10008.5.1.4.1.1.78.4"
+DirectoryRecord="MEASUREMENT"	Name="VisualAcuityMeasurementsStorage"			Desc="Visual Acuity Measurements Storage"			Uid="1.2.840.10008.5.1.4.1.1.78.5" 
+DirectoryRecord="SR DOCUMENT"	Name="SpectaclePrescriptionReportStorage"		Desc="Spectacle Prescription Report Storage"		Uid="1.2.840.10008.5.1.4.1.1.78.6"
+DirectoryRecord="MEASUREMENT"	Name="OphthalmicAxialMeasurementsStorage"		Desc="Ophthalmic Axial Measurements Storage"		Uid="1.2.840.10008.5.1.4.1.1.78.7" 
+DirectoryRecord="MEASUREMENT"	Name="IntraocularLensCalculationsStorage"		Desc="Intraocular Lens Calculations Storage"		Uid="1.2.840.10008.5.1.4.1.1.78.8" 
+
+DirectoryRecord="MEASUREMENT"	Name="OphthalmicVisualFieldStaticPerimetryMeasurementsStorage"	Desc="Ophthalmic Visual Field Static Perimetry Measurements Storage"	Uid="1.2.840.10008.5.1.4.1.1.80.1"
+
+DirectoryRecord="IMAGE"			Name="OphthalmicThicknessMapStorage"	Desc="Ophthalmic Thickness Map Storage"	Uid="1.2.840.10008.5.1.4.1.1.81.1"
+DirectoryRecord="IMAGE"			Name="CornealTopographyMapStorage"		Desc="Corneal Topography Map Storage"	Uid="1.2.840.10008.5.1.4.1.1.82.1"
+
+DirectoryRecord="IMAGE"			Name="ParametricMapStorage"				Desc="Parametric Map Storage"	Uid="1.2.840.10008.5.1.4.1.1.30"
+
+DirectoryRecord="PALETTE"		Name="ColorPaletteStorage"				Desc="Color Palette Storage"				Uid="1.2.840.10008.5.1.4.39.1"
+								Name="ColorPaletteInformationModelFind"	Desc="Color Palette Information Model Find"	Uid="1.2.840.10008.5.1.4.39.2"
+								Name="ColorPaletteInformationModelMove"	Desc="Color Palette Information Model Move"	Uid="1.2.840.10008.5.1.4.39.3"
+								Name="ColorPaletteInformationModelGet"	Desc="Color Palette Information Model Get"	Uid="1.2.840.10008.5.1.4.39.4"
+
+DirectoryRecord="IMAGE"			Name="DICOSCTImageStorage"							Desc="DICOS CT Image Storage"								Uid="1.2.840.10008.5.1.4.1.1.501.1"
+DirectoryRecord="IMAGE"			Name="DICOSDigitalXRayImageStorageForPresentation"	Desc="DICOS Digital X-Ray Image Storage - For Presentation"	Uid="1.2.840.10008.5.1.4.1.1.501.2.1"
+DirectoryRecord="IMAGE"			Name="DICOSDigitalXRayImageStorageForProcessing"	Desc="DICOS Digital X-Ray Image Storage - For Processing"	Uid="1.2.840.10008.5.1.4.1.1.501.2.2"
+DirectoryRecord="IMAGE"			Name="DICOSThreatDetectionReportStorage"			Desc="DICOS Threat Detection Report Storage"				Uid="1.2.840.10008.5.1.4.1.1.501.3"
+DirectoryRecord="IMAGE"			Name="DICOS2DAITStorage"							Desc="DICOS 2D AIT Storage"									Uid="1.2.840.10008.5.1.4.1.1.501.4"
+DirectoryRecord="IMAGE"			Name="DICOS3DAITStorage"							Desc="DICOS 3D AIT Storage"									Uid="1.2.840.10008.5.1.4.1.1.501.5"
+DirectoryRecord="IMAGE"			Name="DICOSQuadrupoleResonanceStorage"				Desc="DICOS Quadrupole Resonance Storage"					Uid="1.2.840.10008.5.1.4.1.1.501.6"
+
+DirectoryRecord="IMPLANT"			Name="GenericImplantTemplateStorage"			Desc="Generic Implant Template Storage"						Uid="1.2.840.10008.5.1.4.43.1"
+DirectoryRecord="IMPLANT ASSY"		Name="ImplantAssemblyTemplateStorage"			Desc="Implant Assembly Template Storage"					Uid="1.2.840.10008.5.1.4.44.1"
+DirectoryRecord="IMPLANT GROUP"		Name="ImplantTemplateGroupStorage"				Desc="Implant Template Group Storage"						Uid="1.2.840.10008.5.1.4.45.1"
+
+DirectoryRecord="IMAGE"			Name="PrivatePixelMedLegacyConvertedEnhancedCTImageStorage"		Desc="Private PixelMed Legacy Converted Enhanced CT Image Storage"	Uid="1.3.6.1.4.1.5962.301.1"
+DirectoryRecord="IMAGE"			Name="PrivatePixelMedLegacyConvertedEnhancedMRImageStorage"		Desc="Private PixelMed Legacy Converted Enhanced MR Image Storage"	Uid="1.3.6.1.4.1.5962.301.2"
+DirectoryRecord="IMAGE"			Name="PrivatePixelMedLegacyConvertedEnhancedPETImageStorage"	Desc="Private PixelMed Legacy Converted Enhanced PET Image Storage"	Uid="1.3.6.1.4.1.5962.301.3"
+DirectoryRecord="IMAGE"			Name="PrivatePixelMedLegacyFloatingPointImageStorage"			Desc="Private PixelMed Floating Point Image Storage"				Uid="1.3.6.1.4.1.5962.301.9"
+
diff --git a/libsrc/standard/strval/Imakefile b/libsrc/standard/strval/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/standard/strval/base.tpl b/libsrc/standard/strval/base.tpl
new file mode 100755
index 0000000..0b8ad62
--- /dev/null
+++ b/libsrc/standard/strval/base.tpl
@@ -0,0 +1,1537 @@
+StringValues="TrueFalseFull" {
+	TRUE,
+	FALSE
+}
+
+StringValues="YesNoLetter" {
+	Y = Yes,
+	N = No
+}
+
+StringValues="YesNoFull" {
+	YES,
+	NO
+}
+
+StringValues="YesNoFullUnknown" {
+	YES,
+	NO,
+	UNKNOWN
+}
+
+StringValues="YesLetter" {
+	Y = Yes
+}
+
+StringValues="NoLetter" {
+	N = No
+}
+
+StringValues="YesFull" {
+	YES
+}
+
+StringValues="NoFull" {
+	NO
+}
+
+StringValues="Priority" {
+	LOW,
+	MED,
+	HIGH
+}
+
+StringValues="SmokingStatus" {
+	YES,
+	NO,
+	UNKNOWN
+}
+
+StringValues="Orientation" {
+	LANDSCAPE,
+	PORTRAIT
+}
+
+StringValues="DiagnosticCodingSchemes" {
+	ACR = ACR Index for Radiological Diagnosis,
+	CE  = CEN ECG Diagnostic Codes,
+	E   = Euclides,
+	I9  = ICD9,
+	I9C = ICD9-CM,
+	I10 = ICD10,
+	LB  = Local Billing Code,
+	RC  = Read Classification,
+	SNM = SNOMED,
+	S3  = SNOMED III,
+	UML = Unified Medical Language
+}
+
+StringValues="ProcedureCodeScheme" {
+	AS4 = ASTM,
+	C4  = CPT-4,
+	C5  = CPT-5,
+	E   = Euclides,
+	FDK = FDA K10,
+	HB  = HIBCC,
+	ICS = ICCS,
+	I9C = ICD-9CM,
+	IBT = ISBT,
+	IUC = IUPAC/IFCC,
+	MCR = Medicare,
+	MCD = Madicaid,
+	UC  = UCDS,
+	JC8 = Japanese Chemistry,
+	HI  = Health Outcomes,
+	E6  = Euclides Lab Method Codes,
+	E7  = Euclides Lab Equipment Codes,
+	E5  = Euclides Kind Of Quantity Codes,
+	CAS = Chemical Abstract Codes,
+	NDC = National Drug Codes,
+	W1  = WHO Record Number 6 Digit Drug Codes,
+	W2  = WHO Record Number 8 Digit Drug Codes,
+	W4  = WHO Record Number With ASTM Extensions,
+	WC  = WHO ATC,
+	UMD = MDNS
+}
+
+StringValues="CodingSchemeDesignatorForSNOMEDDICOMMicroglossary"	{
+	99SDM = SNOMED DICOM Microglossary
+}
+
+StringValues="CodingSchemeDesignatorForSNOMED"	{
+	SNM3 = SNOMED
+}
+
+StringValues="CodingSchemeDesignatorForSRT"	{
+	SRT = SNOMED
+}
+
+StringValues="GeneralUnitsCodingSchemeForCG82"	{
+	UCUM = Unified Code for Units of Measure
+}
+
+StringValues="CodingSchemeUIDForACR" {
+	2.16.840.1.113883.6.76 = ACR
+}
+
+StringValues="CodingSchemeUIDForASTMSigpurpose" {
+	1.2.840.10065.1.12 = ASTM-sigpurpose
+}
+
+StringValues="CodingSchemeUIDForC4" {
+	2.16.840.1.113883.6.12 = C4
+}
+
+StringValues="CodingSchemeUIDForC5" {
+	2.16.840.1.113883.6.82 = C5
+}
+
+StringValues="CodingSchemeUIDForCD2" {
+	2.16.840.1.113883.6.13 = CD2
+}
+
+StringValues="CodingSchemeUIDForDCM" {
+	1.2.840.10008.2.16.4 = DCM
+}
+
+StringValues="CodingSchemeUIDForDCMUID" {
+	1.2.840.10008.2.6.1 = DCMUID
+}
+
+StringValues="CodingSchemeUIDForHPC" {
+	2.16.840.1.113883.6.14 = HPC
+}
+
+StringValues="CodingSchemeUIDForI10" {
+	2.16.840.1.113883.6.3 = I10
+}
+
+StringValues="CodingSchemeUIDForI10P" {
+	2.16.840.1.113883.6.4 = I10P
+}
+
+StringValues="CodingSchemeUIDForI9" {
+	2.16.840.1.113883.6.42 = I9
+}
+
+StringValues="CodingSchemeUIDForI9C" {
+	2.16.840.1.113883.6.2 = I9C
+}
+
+StringValues="CodingSchemeUIDForISO3166_1" {
+	2.16.1 = ISO3166_1
+}
+
+StringValues="CodingSchemeUIDForISO639_1" {
+	2.16.840.1.113883.6.99 = ISO639_1
+}
+
+StringValues="CodingSchemeUIDForISO639_2" {
+	2.16.840.1.113883.6.100 = ISO639_2
+}
+
+StringValues="CodingSchemeUIDForLN" {
+	2.16.840.1.113883.6.1 = LN
+}
+
+StringValues="CodingSchemeUIDForPOS" {
+	2.16.840.1.113883.6.50 = POS
+}
+
+StringValues="CodingSchemeUIDForRFC3066" {
+	2.16.840.1.113883.6.121 = RFC3066
+}
+
+StringValues="CodingSchemeUIDForSNM3" {
+	2.16.840.1.113883.6.51 = SNM3
+}
+
+StringValues="CodingSchemeUIDForSCT" {
+	2.16.840.1.113883.6.96 = SCT
+}
+
+StringValues="CodingSchemeUIDForSRT" {
+	2.16.840.1.113883.6.96 = SRT
+}
+
+StringValues="CodingSchemeUIDForCTV3" {
+	2.16.840.1.113883.6.6 = CTV3
+}
+
+StringValues="CodingSchemeUIDForUCUM" {
+	2.16.840.1.113883.6.8 = UCUM
+}
+	
+StringValues="CodingSchemeUIDForUMLS" {
+	2.16.840.1.113883.6.86 = UMLS
+}
+	
+StringValues="CodingSchemeUIDForUPC" {
+	2.16.840.1.113883.6.55 = UPC
+}
+
+StringValues="MiscellaneousCodingSchemeUIDs"	{
+	2.16.840.1.113883.6.76 = ACR,
+	1.2.840.10065.1.12 = ASTM-sigpurpose,
+	2.16.840.1.113883.6.12 = C4,
+	2.16.840.1.113883.6.82 = C5,
+	2.16.840.1.113883.6.13 = CD2,
+	2.16.840.1.113883.6.6 = CTV3,
+	1.2.840.10008.2.16.4 = DCM,
+	1.2.840.10008.2.6.1 = DCMUID,
+	2.16.840.1.113883.6.14 = HPC,
+	2.16.840.1.113883.6.3 = I10,
+	2.16.840.1.113883.6.4 = I10P,
+	2.16.840.1.113883.6.42 = I9,
+	2.16.840.1.113883.6.2 = I9C,
+	2.16.1 = ISO3166_1,
+	2.16.840.1.113883.6.99 = ISO639_1,
+	2.16.840.1.113883.6.100 = ISO639_2,
+	1.2.840.10008.2.16.7 = ITIS_TSN,
+	2.16.840.1.113883.6.1 = LN,
+	1.2.840.10008.2.16.5 = MA,
+	1.2.840.10008.2.16.8 = MGI,
+	2.16.840.1.113883.3.26.1.1 = NCIt,
+	2.16.840.1.113883.6.50 = POS,
+	2.16.840.1.113883.6.256 = RADLEX,
+	2.16.840.1.113883.6.121 = RFC3066,
+	2.16.840.1.113883.6.51 = SNM3,
+	2.16.840.1.113883.6.96 = SRT/SCT,
+	1.2.840.10008.2.16.6 = UBERON,
+	2.16.840.1.113883.6.8 = UCUM,
+	2.16.840.1.113883.6.86 = UMLS,
+	2.16.840.1.113883.6.55 = UPC,
+	1.2.276.0.7230010.3.0.0.1 = 99_OFFIS_DCMTK,
+	1.3.6.1.4.1.5962.98.1 = 99PMP,
+	1.3.6.1.4.1.5962.98.2 = 99IPCMR,
+	1.3.6.1.4.1.43046.3.0.0 = 99QIICR
+}
+
+StringValues="MiscellaneousCodingSchemeDesignators"	{
+	99_OFFIS_DCMTK = OFFIS DCMTK,
+	99QIICR = NCI QIICR Project 3DSlicer BWH,
+	99HOLX = Hologic,
+	99IHE = IHE Connectathon,
+	99PDL-rad = PointDX,
+	99GEMS = GE,
+	99_MI = Siemens,
+	99NMG = Siemens NM,
+	99SMS_CTMR = Siemens CT MR,
+	99PMSBLUS = Philips Ultrasound,
+	99RPH = RadPharm,
+	99RPANATLOC = RadPharm anatomical locations,
+	99RPH_USERS = RadPharm users,
+	99PMP = PixelMed Publishing,
+	99PMPMRMF = PixelMed Publishing NEMA MRMF,
+	99IPCMR = Imaging Procedure Code Mapping Resource,
+	99SDM = SNOMED DICOM Microglossary,
+	99NCIAIM = NCI Annotation Imaging Markup,
+	99HOLXDXA = Hologic DXA,
+	99KINETDX = Siemens Acuson Ultrasound,
+	ACR = ACR Index for Radiological Diagnosis,
+	ART = WHO Adverse Reaction terms,
+	AS4 = ASTM,
+	ASTM-sigpurpose = ASTM E 2084 Signature Purpose codes,
+	ATC = American Type Culture Collection,
+	BARI = Bypass Angiography Revascularization Inverstigation,
+	BI = BI-RADS,
+	C4  = CPT-4,
+	C5  = CPT-5,
+	CAS = Chemical Abstract Codes,
+	CD2 = American Dental Association Current Dental Terminology 2,
+	CDCA = CDC Analyte Codes,
+	CDCM = CDC Methods/Instruments Codes,
+	CDS = CDC Surveillance Codes,
+	CE  = CEN ECG Diagnostic Codes,
+	CST = COSTART coding system for adverse drug reactions,
+	CTV3 = NHS Clinical Terms Version 3 (Read Codes),
+	DCM = DICOM Controlled Terminology,
+	DCMUID = DICOM UID Registry,
+	E   = Euclides AFP codes,
+	E5  = Euclides Kind Of Quantity Codes,
+	E6  = Euclides Lab Method Codes,
+	E7  = Euclides Lab Equipment Codes,
+	ENZC = 	Enzyme Codes,
+	FDK = FDA K10,
+	FMA = Digital Anatomist Foundational Model of Anatomy,
+	HB  = HIBCC,
+	HHCC = Home Health Care Classification System,
+	HI  = Health Outcomes Institute codes for outcome variables,
+	HPC = Healthcare Financing Administration (HCFA) Common Procedure CodingSystem (HCPCS),
+	JC8 = Japanese Chemistry,
+	ICS = ICCS,
+	I9  = ICD9,
+	I9C = ICD9-CM,
+	I10 = ICD10,
+	I10P = ICD10 Procedure Coding System,
+	IBT = ISBT,
+	ICS = ICCS,
+	ISO3166_1 = ISO 2 letter country codes,
+	ISO639_1 = ISO 2 letter language codes,
+	ISO639_2 = ISO 3 letter language codes,
+	ISO_OID =  ISO OSI Object Identifier Tree,
+	ITIS_TSN = Integrated Taxonomic Information System Taxonomic Serial Number,
+	IUC = IUPAC/IFCC Recommendations of Quantities and Units in Clinical Chemistry,
+	IUPC = IUPAC component (analyte) codes,
+	IUPP = IUPAC property codes,
+	JC8 = Japanese Chemistry Clinical examination classification code,
+	LN = LOINC,
+	MA = Adult Mouse Anatomy Ontology,
+	MCD = Medicaid billing codes/names,
+	MCR = Medicare billing codes/names,
+	MDDX = Medispan diagnostic codes,
+	MDNS = Universal Medical Device Nomenclature System,
+	MEDC = Medical Economics Drug Codes,
+	MEDR = Medical Dictionary for Drug Regulatory Affairs (MEDDRA),
+	MEDX = Medical Economics Diagnostic Codes,
+	MGI = Mouse Genome Initiative,
+	MGPI = Medispan GPI hierarchical drug codes,
+	MVX = CDC Vaccine Codes,
+	NCDR = American College of Cardiology National Cardiovascular Data Registry Cath Lab Module,
+	NCIt = NCI Thesaurus,
+	NDC = National Drug Codes FDA,
+	NIC = Nursing Interventions Iowa Intervention Project,
+	NPI = HCFA National Provider Identifier,
+	POS = HCFA Place of Service (POS) Codes for Professional Claims,
+	RADLEX = RadLex,
+	RC  = Read Clinical Classification of Medicine,
+	RFC3066 = IETF RFC 3066 language codes,
+	SCPECG = Standard Communications Protocol for Computer-Assisted Electrocardiography,
+	SNM3 = SNOMED International Version 3,
+	SCT = SNOMED-CT,
+	SRT = SNOMED-RT,
+	UBERON  = Uberon integrated cross-species ontology,
+	UC  = UCDS,
+	UCUM = Unified Code for Units of Measure,
+	UMD = Universal Medical Device Nomenclature System MDNS, 
+	UML = Unified Medical Language,
+	UMLS = UMLS codes as CUIs making up the values in a coding system,
+	UPC = Universal Product Code - Universal Code Council,
+	UPIN = HCFA Universal Physician Identification Numbers,
+	W1  = WHO Record Number 6 Digit Drug Codes,
+	W2  = WHO Record Number 8 Digit Drug Codes,
+	W4  = WHO Record Number With ASTM Extensions,
+	WC  = WHO ATC
+}
+
+StringValues="CodingSchemeDesignatorUCUM"	{
+	UCUM = Unified Code for Units of Measure
+}
+
+StringValues="CodingSchemeDesignatorLOINC"	{
+	LN = LOINC
+}
+
+StringValues="VisitStatusID" {
+	CREATED,
+	SCHEDULED,
+	ADMITTED,
+	DISCHARGED
+}
+
+StringValues="StudyStatusID" {
+	CREATED,
+	SCHEDULED,
+	ARRIVED,
+	STARTED,
+	COMPLETED,
+	VERIFIED,
+	READ
+}
+
+StringValues="StudyComponentStatusID" {
+	CREATED,
+	INCOMPLETE,
+	COMPLETED,
+	VERIFIED,
+	POSTINTERPRET
+}
+
+StringValues="InterpretationTypeID" {
+	REPORT,
+	AMMENDMENT
+}
+
+StringValues="InterpretationStatusID" {
+	CREATED,
+	RECORDED,
+	TRANSCRIBED,
+	APPROVED
+}
+
+StringValues="Sex" {
+	M = Male,
+	F = Female,
+	O = Other
+}
+
+StringValues="Laterality" {
+	R = Right,
+	L = Left
+}
+
+StringValues="BodyPartExaminedHuman" {
+	ABDOMEN,
+	ABDOMENPELVIS,
+	ADRENAL,
+	ANKLE,
+	AORTA,
+	ARM,
+	AXILLA,
+	BACK,
+	BLADDER,
+	BRAIN,
+	BREAST,
+	BRONCHUS,
+	BUTTOCK,
+	CALCANEUS,
+	CALF,
+	CAROTID,
+	CEREBELLUM,
+	CSPINE,
+	CTSPINE,
+	CERVIX,
+	CHEEK,
+	CHEST,
+	CHESTABDOMEN,
+	CHESTABDPELVIS,
+	CIRCLEOFWILLIS,
+	CLAVICLE,
+	COCCYX,
+	COLON,
+	CORNEA,
+	CORONARYARTERY,
+	DUODENUM,
+	EAR,
+	ELBOW,
+	WHOLEBODY,
+	ESOPHAGUS,
+	EXTREMITY,
+	EYE,
+	EYELID,
+	FACE,
+	FEMUR,
+	FINGER,
+	FOOT,
+	GALLBLADDER,
+	HAND,
+	HEAD,
+	HEADNECK,
+	HEART,
+	HIP,
+	HUMERUS,
+	ILEUM,
+	ILIUM,
+	IAC,
+	JAW,
+	JEJUNUM,
+	KIDNEY,
+	KNEE,
+	LARYNX,
+	LEG,
+	LIVER,
+	LSPINE,
+	LSSPINE,
+	LUNG,
+	JAW,
+	MAXILLA,
+	MEDIASTINUM,
+	MOUTH,
+	NECK,
+	NECKCHEST,
+	NECKCHESTABDOMEN,
+	NECKCHESTABDPELV,
+	NOSE,
+	ORBIT,
+	OVARY,
+	PANCREAS,
+	PAROTID,
+	PATELLA,
+	PELVIS,
+	PENIS,
+	PHARYNX,
+	PROSTATE,
+	RECTUM,
+	RIB,
+	SSPINE,
+	SCALP,
+	SCAPULA,
+	SCLERA,
+	SCROTUM,
+	SHOULDER,
+	SKULL,
+	SPINE,
+	SPLEEN,
+	STERNUM,
+	STOMACH,
+	SUBMANDIBULAR,
+	TMJ,
+	TESTIS,
+	THIGH,
+	TSPINE,
+	TLSPINE,
+	THUMB,
+	THYMUS,
+	THYROID,
+	TOE,
+	TONGUE,
+	TRACHEA,
+	URETER,
+	URETHRA,
+	UTERUS,
+	VAGINA,
+	VULVA,
+	WRIST,
+	ZYGOMA
+}
+
+StringValues="BodyPartExaminedAnimal" {
+	ABDOMEN,
+	LEGS,
+	ATLANTOAXIAL,
+	ATLANTOOCCIPITAL,
+	BLADDER,
+	CARPUS,
+	CSPINE,
+	CTSPINE,
+	CHEST,
+	CHESTABDOMEN,
+	TAIL,
+	COLON,
+	DIGIT,
+	DISTALPHALANX,
+	ELBOW,
+	WHOLEBODY,
+	ESOPHAGUS,
+	FEMUR,
+	FOREFETLOCK,
+	HINDFETLOCK,
+	FOREFOOT,
+	FRONTALSINUS,
+	HINDFOOT,
+	HIP,
+	HUMERUS,
+	LSPINE,
+	LSSPINE,
+	JAW,
+	METACARPUS,
+	METATARSUS,
+	NAVICULAR,
+	FOREPASTERN,
+	HINDPASTERN,
+	PATELLA,
+	PELVIS,
+	RADIUSULNA,
+	SSPINE,
+	SHOULDER,
+	SKULL,
+	STIFLE,
+	TARSUS,
+	TSPINE,
+	TLSPINE,
+	TIBIAFIBULA,
+	UGITRACT,
+	URETHRA,
+	URINARYTRACT,
+	WING
+}
+
+StringValues="Modality"	{
+	AR = Autorefraction,
+	AU = Audio,
+	BI = Biomagnetic Imaging,
+	BDUS = Bone Densitometry (ultrasound),
+	BMD	= Bone Densitometry (X-ray),
+	CR = Computed Radiography,
+	CT = Computed Tomography,
+	DG = Diaphanography,
+	DOC	= Document,
+	DX = Digital Radiography,
+	ECG = Electrocardiography,
+	EPS = Cardiac Electrophysiology,
+	ES = Endoscopy,
+	FID = Fiducials,
+	GM = General Microscopy,
+	HC = Hard Copy,
+	HD = Hemodynamic Waveform,
+	IO = Intra-oral Radiography,
+	IOL = Intraocular Lens Data,
+	IVOCT = Intravascular Optical Coherence Tomography,
+	IVUS = Intravascular Ultrasound,
+	KER = Keratometry,
+	KO = Key Object Selection,
+	LEN = Lensometry,
+	LS = Laser Surface Scan,
+	MG = Mammography,
+	MR = Magnetic Resonance,
+	NM = Nuclear Medicine,
+	OAM = Ophthalmic Axial Measurements,
+	OCT	= Optical Coherence Tomography (non-Ophthalmic),
+	OP = Ophthalmic Photography,
+	OPM	= Ophthalmic Mapping,
+	OPT	= Ophthalmic Tomography,
+	OPV	= Ophthalmic Visual Field,
+	OT = Other,
+	PLAN = Plan,
+	PR = Presentation State,
+	PT = Positron Emmission Tomography,
+	PX = Panoramic X-Ray,
+	REG	= Registration,
+	RESP = Respiratory Waveform,
+	RF = RadioFluoroscopy,
+	RG = Radiographic Imaging Conventional Film Screen,
+	RTDOSE = RT Dose,
+	RTIMAGE = RT Image,
+	RTPLAN = RT Plan,
+	RTRECORD = RT Treatment Record,
+	RTSTRUCT = RT Structure Set,
+	RWV = Real World Value,
+	SEG	= Segmentation,
+	SM = Slide Microscopy,
+	SMR = Stereometric Relationship,
+	SR = SR Document,
+	SRF = Subjective Refraction,
+	STAIN = Automated Slide Stainer,
+	TG = Thermography,
+	US = Ultrasound,
+	VA = Visual Acuity,
+	XA = X-Ray Angiography,
+	XC = External Camera Photography
+}
+
+StringValues="PatientPosition" {
+	HFP  = Head First Prone,
+	HFS  = Head First Supine,
+	HFDR = Head First Decubitus Right,
+	HFDL = Head First Decubitus Right,
+	FFP  = Feet First Prone,
+	FFS  = Feet First Supine,
+	FFDR = Feet First Decubitus Right,
+	FFDL = Feet First Decubitus Right,
+	LFP = Left First-Prone,
+	LFS = Left First-Supine,
+	RFP = Right First-Prone,
+	RFS = Right First-Supine,
+	AFDR = Anterior First Decubitus Right,
+	AFDL = Anterior First Decubitus Left,
+	PFDR = Posterior First Decubitus Right,
+	PFDL = Posterior First Decubitus Left
+}
+
+StringValues="ViewPositionHuman" {
+	AP  = Anterior Posterior,
+	PA  = Posterior Anterior,
+	LL  = Left Lateral,
+	RL  = Right Lateral,
+	RLD = Right Lateral Decubitus,
+	LLD = Left Lateral Decubitus,
+	RLO = Right Lateral Oblique,
+	LLO = Left Lateral Oblique
+}
+
+StringValues="ViewPositionAnimal" {
+	CDDI_CRPRO,
+	CD10DI_CRPRO,
+	CDCR,
+	DV,
+	DL_PAMO,
+	D35L_PAMO,
+	D40L_PAMO,
+	D60L_PAMO,
+	DL_PLMO,
+	D35L_PLMO,
+	D40L_PLMO,
+	D45L_PLMO,
+	D60L_PLMO,
+	DM_PALO,
+	D35M_PALO,
+	D40M_PALO,
+	D45M_PALO,
+	D60M_PALO,
+	DM_PLLO,
+	D35M_PLLO,
+	D40M_PLLO,
+	D45M_PLLO,
+	D60M_PLLO,
+	DPA,
+	DPL,
+	DPR_PADIO,
+	D65PR_PADIO,
+	DPR_PLDIO,
+	D65PR_PLDIO,
+	DR_VCDO,
+	D20R_VCDO,
+	LDPR_MPADIO,
+	L45D50PR_MPADIO,
+	LDPR_MPLDIO,
+	L45D50PR_MPLDIO,
+	LM,
+	LECD_RTRO,
+	LE30CD_RTRO,
+	LED_RTVO,
+	LE20D_RTVO,
+	LE45D_RTVO,
+	LER_RTCDO,
+	LE20R_RTCDO,
+	LEV_RTDO,
+	LE20V_RTDO,
+	LE45V_RTDO,
+	LERTL,
+	ML,
+	PAM_DLO,
+	PA45M_DLO,
+	PAPR_DDIO,
+	PA75PR_DDIO,
+	PLL_DMO,
+	PL60L_DMO,
+	PLPR_DDIO,
+	PL75PR_DDIO,
+	PRDI,
+	RTCD_LERO,
+	RT30CD_LERO,
+	RTD_LEVO,
+	RT20D_LEVO,
+	RT45D_LEVO,
+	RTR_LECDO,
+	RT20R_LECDO,
+	RTV_LEDO,
+	RT20V_LEDO,
+	RT45V_LEDO,
+	RTLEL,
+	RCD,
+	RD_CDVO,
+	R20D_CDVO,
+	RV_CDDO,
+	R30V_CDDO,
+	VLE_DRTO,
+	V30LE_DRTO,
+	VRT_DLEO,
+	V30RT_DLEO,
+	VD,
+	VR_DCDO,
+	V20R_DCDO
+}
+
+StringValues="CassetteSize" {
+	18CMX24CM,
+	8INX10IN,
+	24CMX30CM,
+	10INX12IN,
+	30CMX35CM,
+	30CMX40CM,
+	11INX14IN,
+	35CMX35CM,
+	14INX14IN,
+	35CMX43CM
+	14INX17IN,
+}
+
+StringValues="RotationDirection" {
+	CW = Clockwise,
+	CC = CounterClockwise
+}
+
+StringValues="RotationDirectionWithNone" {
+	CW = Clockwise,
+	CC = CounterClockwise,
+	NONE = No Rotation
+}
+
+StringValues="ScanningSequence" {
+	SE = Spin Echo,
+	IR = Inversion Recovery,
+	GR = Gradient Recalled,
+	EP = Echo Planar,
+	RM = Research Mode
+}
+
+StringValues="SequenceVariant"	{
+	SK   = Segmented K Space,
+	MTC  = Magnetization Transfer CDontrast,
+	SS   = Steady State,
+	TRSS = Time Reversed Steady State,
+	SP   = Spoiled,
+	MP   = Magnetization Prepared,
+	OSP  = Oversampling Phase,
+	NONE = No Sequence Variant
+}
+
+StringValues="ScanOptions" {
+	PER = Phase Encode Reordering,
+	RG  = Respiratory Gating,
+	CG  = Cardiac Gating,
+	PPG = Peripheral Pulse Gating,
+	FC  = Flow Compensation,
+	PFF = Partial Fourier Frequency,
+	PFP = Partial Fourier Phase,
+	SP  = Spatial Presaturation,
+	FS  = Fat Saturation
+}
+
+StringValues="MRAcquisitionType" {
+	2D = Frequency x Phase,
+	3D = Frequency x Phase x Phase
+}
+
+StringValues="AngioFlag" {
+	Y = Image is Angio,
+	N = Image is not Angio
+}
+
+StringValues="PhaseEncodingDirection" {
+	ROW = Phase Encoded in Rows,
+	COL = Phase Encoded in Columns
+}
+
+StringValues="PhotometricInterpretation" {
+	MONOCHROME1,
+	MONOCHROME2,
+	PALETTE COLOR,
+	RGB,
+	YBR_FULL,
+	YBR_FULL_422,
+	YBR_PARTIAL_422,
+	YBR_PARTIAL_420,
+	YBR_RCT,
+	YBR_ICT
+}
+
+StringValues="PhotometricInterpretationMonochrome" {
+	MONOCHROME1,
+	MONOCHROME2
+}
+
+StringValues="PhotometricInterpretationRGB" {
+	RGB
+}
+
+StringValues="PhotometricInterpretationMonochrome2OrRGB" {
+	MONOCHROME2,
+	RGB
+}
+
+StringValues="PhotometricInterpretationMonochrome2OrRGBorYBR_FULL422" {
+	MONOCHROME2,
+	YBR_FULL_422,
+	RGB
+}
+
+StringValues="PhotometricInterpretationYBRFull422" {
+	YBR_FULL_422
+}
+
+StringValues="PhotometricInterpretationYBRRCT" {
+	YBR_RCT
+}
+
+StringValues="PhotometricInterpretationYBRRCTOrICT" {
+	YBR_RCT,
+	YBR_ICT
+}
+
+StringValues="PhotometricInterpretationYBRPartial420" {
+	YBR_PARTIAL_420
+}
+
+StringValues="PhotometricInterpretationYBRFull" {
+	YBR_FULL
+}
+
+StringValues="PhotometricInterpretationYBRFullOrRGBorYBR_RCTorYBR_ICT" {
+	YBR_FULL,
+	YBR_RCT,
+	YBR_ICT,
+	RGB
+}
+
+StringValues="PhotometricInterpretationRGBorYBR_FULL_422orYBR_RCTorYBR_ICTorYBR_PARTIAL_420" {
+	YBR_FULL_422,
+	YBR_PARTIAL_420,
+	YBR_RCT,
+	YBR_ICT,
+	RGB
+}
+
+StringValues="PhotometricInterpretationMonochrome2OrRGBorYBR_FULL_422orYBR_RCTorYBR_ICTorYBR_PARTIAL_420" {
+	MONOCHROME2,
+	YBR_FULL_422,
+	YBR_PARTIAL_420,
+	YBR_RCT,
+	YBR_ICT,
+	RGB
+}
+
+StringValues="PhotometricInterpretationRGBorYBR_RCT" {
+	YBR_RCT,
+	RGB
+}
+
+StringValues="ImageType1"	{
+	ORIGINAL,
+	DERIVED
+}
+
+StringValues="ImageType1OriginalOnly"	{
+	ORIGINAL
+}
+
+StringValues="ImageType1DerivedOnly"	{
+	DERIVED
+}
+
+StringValues="ImageType2"	{
+	PRIMARY,
+	SECONDARY
+}
+
+StringValues="ImageType2PrimaryOnly"	{
+	PRIMARY
+}
+
+StringValues="CTImageType3" {
+	AXIAL,
+	LOCALIZER
+}
+
+StringValues="MRImageType3" {
+	MPR,
+	PROJECTION IMAGE,
+	T1 MAP,
+	T2 MAP,
+	DIFFUSION MAP,
+	DENSITY MAP,
+	PHASE MAP,
+	VELOCITY MAP,
+	IMAGE ADDITION,
+	PHASE SUBTRACT,
+	MODULUS SUBTRACT,
+	OTHER
+}
+
+StringValues="ConversionType" {
+	DV  = Digitized Video,
+	DI  = Digital Interface,
+	DF  = Digitized Film,
+	WSD = Workstation,
+	SD = Scanned Document,
+	SI = Scanned Image,
+	DRW = Drawing,
+	SYN = Synthetic Image
+}
+
+StringValues="OverlayType" {
+	G = Graphics,
+	R = ROI
+}
+
+StringValues="CurveTypeOfData" {
+	TAC      = Time Activity Curve ,
+	PROF     = Image Profile ,
+	HIST     = Histogram ,
+	ROI      = Polygraphic Region Of Interest,
+	TABL     = Table of Values ,
+	FILT     = Filter Kernel,
+	POLY     = Poly Line ,
+	ECG      = ECG Data,
+	PRESSURE = Pressure Data,
+	FLOW     = Flow Data,
+	PHYSIO   = Physiological Data,
+	RESP     = Respiration Trace
+}
+
+StringValues="CurveAxisUnits" {
+	SEC     = Seconds ,
+	CNTS    = Counts ,
+	MM      = millimeters,
+	PIXL    = Pixels   ,
+	NONE    = Unitless,
+	BPM     = beats/min,
+	CM      = centimeters,
+	CMS     = centimeters/second ,
+	CM2     = cm**2,
+	CM2S    = cm**2/second,
+	CM3     = cm**3,
+	CM3S    = cm**3/second,
+	CMS2    = cm/second**2,
+	DB      = dB,
+	DBS     = dB/second,
+	DEG     = degrees,
+	GM      = gram,
+	GMM2    = gram/meter**2,
+	HZ      = Hertz,
+	IN      = inch,
+	KG      = kg,
+	LMIN    = liters/minute,
+	LMINM2  = liters/minute/meter**2,
+	M2      = meters **2,
+	MS2     = meters/sec**2,
+	MLM2    = milliliters/meter**2,
+	MILS    = milliseconds,
+	MILV    = millivolts,
+	MMHG    = mmHg,
+	PCNT    = percent,
+	LB      = pound
+}
+
+StringValues="ModalityLUTType" {
+	OD = Optical Density (thousandths),
+	HU = Hounsfield Units,
+	US = Unspecified
+}
+
+StringValues="ModalityLUTTypeUnspecified" {
+	US = Unspecified
+}
+
+StringValues="LossyImageCompression" {
+	00 = Image has not been subjected to lossy compression,
+	01 = Image has been subjected to lossy compression
+}
+
+StringValues="PerformedProcedureStepStatus"	{
+	IN PROGRESS,
+	DISCONTINUED,
+	COMPLETED
+}
+
+StringValues="SecondaryCapturePresentationLUTShape"	{
+	IDENTITY
+}
+
+StringValues="RescaleTypeUnspecified"	{
+	US
+}
+
+StringValues="TransportDirection"	{
+	ROW,
+	COLUMN
+}
+
+StringValues="MACAlgorithm"	{
+	RIPEMD160,
+	MD5,
+	SHA1
+}
+
+StringValues="CertificateType"	{
+	X509_1993_SIG
+}
+
+StringValues="CertifiedTimestampType"	{
+	CMS_TSP
+}
+
+StringValues="CodingSchemeRegistries"	{
+	HL7
+}
+
+StringValues="SEGModality" {
+	SEG
+}
+
+StringValues="REGModality" {
+	REG
+}
+
+StringValues="FIDModality" {
+	FID
+}
+
+StringValues="FrameOfReferenceTransformationMatrixType" {
+	RIGID,
+	RIGID_SCALE,
+	AFFINE
+}
+
+StringValues="FiducialShapeType" {
+	POINT,
+	LINE,
+	PLANE,
+	SURFACE,
+	RULER,
+	L_SHAPE,
+	T_SHAPE,
+	SHAPE
+}
+
+StringValues="IdentityPresentationLUTShape"	{
+	IDENTITY
+}
+
+StringValues="InversePresentationLUTShape"	{
+	INVERSE
+}
+
+StringValues="IdentityOrInversePresentationLUTShape"	{
+	IDENTITY,
+	INVERSE
+}
+
+# should really have a case insensitive match :(
+StringValues="MIMETypeApplicationPDF"	{
+	application/pdf,
+	application/PDF,
+	Application/PDF,
+	APPLICATION/PDF
+}
+
+# should really have a case insensitive match :(
+StringValues="MIMETypeApplicationCDA"	{
+	text/xml,
+	text/XML,
+	Text/XML,
+	TEXT/XML
+}
+
+StringValues="LossyImageCompressionMethod" {
+	ISO_10918_1 = JPEG Lossy Compression,
+	ISO_14495_1 = JPEG-LS Near-lossless Compression,
+	ISO_15444_1 = JPEG 2000 Irreversible Compression,
+	ISO_13818_2 = MPEG2 Compression,
+	ISO_14496_10 = MPEG-4 AVC/H.264 Compression
+}
+
+StringValues="ContentItemValueTypes" {
+	DATETIME,
+	DATE,
+	TIME,
+	PNAME,
+	UIDREF,
+	TEXT,
+	CODE,
+	NUMERIC,
+	IMAGE,
+	COMPOSITE
+}
+
+StringValues="PixelIntensityRelationshipLUTFunction" {
+	TO_LOG,
+	TO_LINEAR
+}
+
+StringValues="OverlaySubtype" {
+	USER = User created graphic annotation,
+	AUTOMATED = Machine created graphic annotation
+}
+
+StringValues="RealWorldValueMappingModality" {
+	RWV
+}
+
+StringValues="TypeOfPatientID" {
+	TEXT,
+	RFID,
+	BARCODE
+}
+
+StringValues="ResponsiblePersonRole" {
+	OWNER,
+	PARENT,
+	CHILD,
+	SPOUSE,
+	SIBLING,
+	RELATIVE,
+	GUARDIAN,
+	CUSTODIAN,
+	AGENT,
+	INVESTIGATOR,
+	VETERINARIAN
+}
+
+StringValues="PatientSexNeutered" {
+	ALTERED,
+	UNALTERED
+}
+
+StringValues="YesNoReorientedOnly" {
+	YES,
+	NO,
+	REORIENTED_ONLY
+}
+
+
+StringValues="EquipmentCoordinateSystemIdentification" {
+	ISOCENTER
+}
+
+StringValues="CommonEnhancedImageType1" {
+	ORIGINAL,
+	DERIVED,
+	MIXED
+}
+
+StringValues="CommonEnhancedFrameType1" {
+	ORIGINAL,
+	DERIVED
+}
+
+StringValues="CommonEnhancedImageAndFrameType2" {
+	PRIMARY
+}
+
+StringValues="CommonEnhancedImageAndFrameType3" {
+	ANGIO,
+	CARDIAC,
+	CARDIAC_GATED,
+	CARDRESP_GATED,
+	DYNAMIC,
+	FLUOROSCOPY,
+	LOCALIZER,
+	MOTION,
+	PERFUSION,
+	PRE_CONTRAST,
+	POST_CONTRAST,
+	RESP_GATED,
+	REST,
+	STATIC,
+	STRESS,
+	VOLUME,
+	NON_PARALLEL,
+	PARALLEL,
+	WHOLE_BODY
+}
+
+StringValues="CommonEnhancedImageType4" {
+	ADDITION,
+	DIVISION,
+	MASKED,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MTT,
+	MULTIPLICATION,
+	RCBF,
+	RCBV,
+	RESAMPLED,
+	STD_DEVIATION,
+	SUBTRACTION,
+	T_TEST,
+	TTP,
+	Z_SCORE,
+	NONE,
+	MIXED
+}
+
+StringValues="CommonEnhancedFrameType4" {
+	ADDITION,
+	DIVISION,
+	MASKED,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MTT,
+	MULTIPLICATION,
+	RCBF,
+	RCBV,
+	RESAMPLED,
+	STD_DEVIATION,
+	SUBTRACTION,
+	T_TEST,
+	TTP,
+	Z_SCORE,
+	NONE
+}
+
+StringValues="RespiratoryPhase" {
+	INSPIRATION,
+	MAXIMUM,
+	EXPIRATION,
+	MINIMUM
+}
+
+StringValues="CardiacFramingType" {
+	FORW = time forward from trigger,
+	BACK = time back before trigger,
+	PCNT  = percentage of R-R forward from trigger
+}
+
+StringValues="RespiratoryTriggerType" {
+	TIME,
+	AMPLITUDE,
+	BOTH
+}
+
+StringValues="UniversalEntityIDType" {
+	DNS = An Internet dotted name either in ASCII or as integers,
+	EUI64 = An IEEE Extended Unique Identifier,
+	ISO = An International Standards Organization Object Identifier,
+	URI = Uniform Resource Identifier,
+	UUID = The DCE Universal Unique Identifier,
+	X400 = An X.400 MHS identifier,
+	X500 = An X.500 directory name
+}
+
+StringValues="HL7Table0203IdentifierType" {
+	AM = American Express,
+	AN = Account number,
+	ANON = Anonymous identifier,
+	ANC = Account number Creditor,
+	AND = Account number debitor,
+	ANT = Temporary Account Number,
+	APRN = Advanced Practice Registered Nurse number,
+	BA = Bank Account Number,
+	BC = Bank Card Number,
+	BR = Birth registry number,
+	BRN = Breed Registry Number,
+	CC = Cost Center number,
+	CY = County number,
+	DDS = Dentist license number,
+	DEA = Drug Enforcement Administration registration number,
+	DI = Diner’s Club card,
+	DFN = Drug Furnishing or prescriptive authority Number,
+	DL = Driver’s license number,
+	DN = Doctor number,
+	DPM = Podiatrist license number,
+	DO = Osteopathic License number,
+	DR = Donor Registration Number,
+	DS = Discover Card,
+	EI = Employee number,
+	EN = Employer number,
+	FI = Facility ID,
+	GI = Guarantor internal identifier,
+	GL = General ledger number,
+	GN = Guarantor external  identifier,
+	HC = Health Card Number,
+	JHN = Jurisdictional health number Canada,
+	IND = Indigenous/Aboriginal ,
+	LI = Labor and industries number,
+	LN = License number,
+	LR = Local Registry ID,
+	MA = Patient Medicaid number,
+	MB = Member Number,
+	MC = Patients Medicare number,
+	MCD = Practitioner Medicaid number,
+	MCN = Microchip Number,
+	MCR = Practitioner Medicare number,
+	MD = Medical License number,
+	MI = Military ID number,
+	MR = Medical record number,
+	MRT = Temporary Medical Record Number,
+	MS = MasterCard,
+	NE = National employer identifier,
+	NH = National Health Plan Identifier,
+	NI = National unique individual identifier,
+	NII = National Insurance Organization Identifier,
+	NIIP = National Insurance Payor Identifier,
+	NNxxx = National Person Identifier where the xxx is the ISO table 3166 3-character alphabetic country code,
+	NNUSA = National Person Identifier USA,
+	NP = Nurse practitioner number,
+	NPI = National provider identifier,
+	OD = Optometrist license number,
+	PA = Physician Assistant number,
+	PCN = Penitentiary correctional institution Number,
+	PE = Living Subject Enterprise Number,
+	PEN = Pension Number,
+	PI = Patient internal identifier,
+	PN = Person number,
+	PNT = Temporary Living Subject Number,
+	PPN = Passport number,
+	PRC = Permanent Resident Card Number,
+	PRN = Provider number,
+	PT = Patient external identifier,
+	QA = QA number,
+	RI = Resource identifier,
+	RPH = Pharmacist license number,
+	RN = Registered Nurse Number,
+	RR = Railroad Retirement number,
+	RRI = Regional registry ID,
+	SL = State license,
+	SN = Subscriber Number,
+	SR = State registry ID,
+	SS = Social Security number,
+	TAX = Tax ID number,
+	TN = Treaty Number Canada,
+	U = Unspecified identifier,
+	UPIN = Medicare CMS Universal Physician Identification numbers,
+	VN = Visit number,
+	VS = VISA,
+	WC = WIC identifier,
+	WCN = Workers Comp Number,
+	XX = Organization identifier
+}
+
+StringValues="SegmentationType" {
+	BINARY,
+	FRACTIONAL
+}
+
+StringValues="SegmentationFractionalType" {
+	PROBABILITY,
+	OCCUPANCY
+}
+
+StringValues="SegmentAlgorithmType" {
+	AUTOMATIC,
+	SEMIAUTOMATIC,
+	MANUAL
+}
+
+StringValues="RecommendedPresentationType" {
+	SURFACE,
+	WIREFRAME,
+	POINTS
+}
+
+StringValues="DistributionType" {
+	NAMED_PROTOCOL,
+	RESTRICTED_REUSE,
+	PUBLIC_RELEASE
+}
+
+StringValues="ConsentForDistributionFlag" {
+	NO,
+	YES,
+	WITHDRAWN 
+}
+
+StringValues="AnatomicalOrientationType" {
+	BIPED,
+	QUADRUPED
+}
+
+StringValues="ContainerComponentMaterial" {
+	GLASS,
+	PLASTIC,
+	METAL
+}
+
+StringValues="LongitudinalTemporalInformationModified" {
+	UNMODIFIED,
+	MODIFIED,
+	REMOVED
+}
+
+StringValues="DimensionOrganizationType" {
+	3D,
+	3D_TEMPORAL
+}
+
+StringValues="DimensionOrganizationType3D" {
+	3D
+}
+
+StringValues="IVOCTModality" {
+	IVOCT
+}
+
+StringValues="IVOCTPixelPresentationImageLevel" {
+	COLOR,
+	COLOR_REF,
+	MONOCHROME
+}
+
+StringValues="IVOCTImageAndFrameTypeValue3"	{
+	AXIAL,
+	LONGITUDINAL
+}
+
+StringValues="IVOCTVolumetricProperties"	{
+	DISTORTED
+}
+
+StringValues="IVOCTInterpolationType"	{
+	REPLICATE,
+	CUBIC,
+	BILINEAR
+}
+
+StringValues="OCTAcquisitionDomain"	{
+	TIME,
+	FREQUENCY,
+	SPECTRAL
+}
+
+StringValues="IVOCTIVUSAcquisition"	{
+	MOTORIZED,
+	MANUAL,
+	SELECTIVE,
+	MEASURED
+}
+
+StringValues="IVOCTPixelIntensityRelationship"	{
+	LIN,
+	LOG
+}
+
+StringValues="CatheterDirectionOfRotation"	{
+	CW,
+	CC
+}
+
+StringValues="WellKnownColorPaletteInstanceUIDs" {
+	1.2.840.10008.1.5.1 = Hot Iron Color Palette SOP Instance,
+	1.2.840.10008.1.5.2 = PET Color Palette SOP Instance,
+	1.2.840.10008.1.5.3 = Hot Metal Blue Color Palette SOP Instance,
+	1.2.840.10008.1.5.4 = PET 20 Step Color Palette SOP Instance
+}
+
+StringValues="Volume"	{
+	VOLUME
+}
+
+StringValues="None"	{
+	NONE
+}
+
+StringValues="EmptyValue"	{
+	***EMPTYVALUE***
+}
+
+StringValues="DigitOne"	{
+	1
+}
+
+StringValues="ParametricMapImageAndFrameType1" {
+	DERIVED
+}
+
+StringValues="MappingResourceUIDs" {
+	DERIVED
+}
+
+StringValues="QueryRetrieveView" {
+	CLASSIC,
+	ENHANCED
+}
+
+
diff --git a/libsrc/standard/strval/charset.tpl b/libsrc/standard/strval/charset.tpl
new file mode 100755
index 0000000..0a68e4f
--- /dev/null
+++ b/libsrc/standard/strval/charset.tpl
@@ -0,0 +1,38 @@
+StringValues="SpecificCharacterSet" {
+	***EMPTYVALUE*** = Default ASCII,
+	ISO_IR 100 =	Latin alphabet No. 1,
+	ISO_IR 101 =	Latin alphabet No. 2,
+	ISO_IR 109 =	Latin alphabet No. 3,
+	ISO_IR 110 =	Latin alphabet No. 4,
+	ISO_IR 144 =	Cyrillic,
+	ISO_IR 127 =	Arabic,
+	ISO_IR 126 =	Greek,
+	ISO_IR 138 =	Hebrew,
+	ISO_IR 148 =	Latin alphabet No. 5,
+	ISO_IR 13  =	Japanese,
+	ISO_IR 166 =	Thai,
+	ISO 2022 IR 6 =	Code extension Single byte Default repertoire,
+	ISO 2022 IR 100 =	Code extension Single byte Latin alphabet No. 1,
+	ISO 2022 IR 101 =       Code extension Single byte Latin alphabet No. 2,
+	ISO 2022 IR 109 =       Code extension Single byte Latin alphabet No. 3,
+	ISO 2022 IR 110 =       Code extension Single byte Latin alphabet No. 4,
+	ISO 2022 IR 144 =       Code extension Single byte Cyrillic,
+	ISO 2022 IR 127 =       Code extension Single byte Arabic,
+	ISO 2022 IR 126 =       Code extension Single byte Greek,
+	ISO 2022 IR 138 =       Code extension Single byte Hebrew,
+	ISO 2022 IR 148 =       Code extension Single byte Latin alphabet No. 5,
+	ISO 2022 IR 13  =       Code extension Single byte Japanese Katakana and Romaji,
+	ISO 2022 IR 166 =       Code extension Single byte Thai,
+	ISO 2022 IR 87  =       Code extension Multi byte Japanese Kanji,
+	ISO 2022 IR 159 =       Code extension Multi byte Japanese Supplementary Kanji,
+	ISO 2022 IR 149 =       Code extension Multi byte Korean,
+	ISO 2022 IR 58 =        Code extension Multi byte Simplified Chinese,
+	ISO_IR 192 =	Unicode UTF-8,
+	GB18030 =	Chinese,
+	GBK =	Simplified Chinese
+}
+
+StringValues="SpecificCharacterSetISOIR100" {
+	ISO_IR 100 =	Latin alphabet No. 1
+}
+
diff --git a/libsrc/standard/strval/ct.tpl b/libsrc/standard/strval/ct.tpl
new file mode 100644
index 0000000..39a9fc1
--- /dev/null
+++ b/libsrc/standard/strval/ct.tpl
@@ -0,0 +1,146 @@
+StringValues="CTModality" {
+	CT
+}
+
+StringValues="EnhancedCTWindowCenterWidthExplanation" {
+	BRAIN,
+	SOFT_TISSUE,
+	LUNG,
+	BONE
+}
+
+StringValues="ContrastBolusAgentPhase" {
+	PRE_CONTRAST,
+	POST_CONTRAST,
+	IMMEDIATE,
+	DYNAMIC,
+	STEADY_STATE,
+	DELAYED,
+	ARTERIAL,
+	CAPILLARY,
+	VENOUS,
+	PORTAL_VENOUS
+}
+
+StringValues="EnhancedCTImageAndFrameType3" {
+	ANGIO,
+	CARDIAC,
+	CARDIAC_GATED,
+	CARDRESP_GATED,
+	DYNAMIC,
+	FLUOROSCOPY,
+	LOCALIZER,
+	MOTION,
+	PERFUSION,
+	PRE_CONTRAST,
+	POST_CONTRAST,
+	RESP_GATED,
+	REST,
+	STATIC,
+	STRESS,
+	VOLUME,
+	NON_PARALLEL,
+	PARALLEL,
+	WHOLE_BODY,
+	ATTENUATION,
+	REFERENCE
+}
+
+StringValues="EnhancedCTImageType4" {
+	ADDITION,
+	DIVISION,
+	MASKED,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MTT,
+	MULTIPLICATION,
+	RCBF,
+	RCBV,
+	RESAMPLED,
+	STD_DEVIATION,
+	SUBTRACTION,
+	T_TEST,
+	TTP,
+	Z_SCORE,
+	NONE,
+	FILTERED,
+	MEDIAN,
+	MIXED,
+	ENERGY_PROP_WT
+}
+
+StringValues="EnhancedCTFrameType4" {
+	ADDITION,
+	DIVISION,
+	MASKED,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MTT,
+	MULTIPLICATION,
+	RCBF,
+	RCBV,
+	RESAMPLED,
+	STD_DEVIATION,
+	SUBTRACTION,
+	T_TEST,
+	TTP,
+	Z_SCORE,
+	NONE,
+	FILTERED,
+	MEDIAN,
+	ENERGY_PROP_WT
+}
+
+StringValues="CTAcquisitionType" {
+	SEQUENCED,
+	SPIRAL,
+	CONSTANT_ANGLE,
+	STATIONARY,
+	FREE
+}
+
+StringValues="CTReconstructionAlgorithm" {
+	FILTER_BACK_PROJ,
+	ITERATIVE
+}
+
+StringValues="CTConvolutionKernelGroup" {
+	BRAIN,
+	SOFT_TISSUE,
+	LUNG,
+	BONE,
+	OTHER
+}
+
+StringValues="CTExposureModulationType" {
+	NONE
+}
+
+StringValues="CTFilterMaterial"	{
+	MOLYBDENUM,
+	ALUMINUM,
+	COPPER,
+	RHODIUM,
+	NIOBIUM,
+	EUROPIUM,
+	LEAD,
+	MIXED
+}
+
+StringValues="CTFilterType" {
+	WEDGE,
+	BUTTERFLY,
+	MULTIPLE,
+	FLAT,
+	SHAPED,
+	NONE
+}
+
+StringValues="RescaleTypeHounsfieldUnits" {
+	HU = Hounsfield Units
+}
+
+
+
diff --git a/libsrc/standard/strval/dx.tpl b/libsrc/standard/strval/dx.tpl
new file mode 100755
index 0000000..498305a
--- /dev/null
+++ b/libsrc/standard/strval/dx.tpl
@@ -0,0 +1,317 @@
+StringValues="TomoType"	{
+	LINEAR,
+	SPIRAL,
+	POLYCYCLOIDAL,
+	CIRCULAR
+}
+
+StringValues="TomoClass"	{
+	MOTION,
+	TOMOSYNTHESIS
+}
+
+StringValues="OrganExposed"	{
+	BREAST,
+	GONADS,
+	BONE MARROW,
+	FETUS,
+	LENS
+}
+
+StringValues="MammographyOrganExposed"	{
+	BREAST
+}
+
+StringValues="AnodeTargetMaterial"	{
+	TUNGSTEN,
+	MOLYBDENUM,
+	RHODIUM
+}
+
+StringValues="DXFilterMaterial"	{
+	MOLYBDENUM,
+	ALUMINUM,
+	COPPER,
+	RHODIUM,
+	NIOBIUM,
+	EUROPIUM,
+	LEAD
+}
+
+StringValues="DXFilterType"	{
+	STRIP,
+	WEDGE,
+	BUTTERFLY,
+	MULTIPLE,
+	NONE
+}
+
+StringValues="RectificationType"	{
+	SINGLE PHASE,
+	THREE PHASE,
+	CONST POTENTIAL
+}
+
+StringValues="ExposureControlMode"	{
+	MANUAL,
+	AUTOMATIC
+}
+
+StringValues="ExposureStatus"	{
+	NORMAL,
+	ABORTED
+}
+
+StringValues="XRayGrid"	{
+	FIXED,
+	FOCUSED,
+	RECIPROCATING,
+	PARALLEL,
+	CROSSED,
+	NONE
+}
+
+StringValues="DXModality"	{
+	DX = Digital Radiography,
+	IO = Intra-oral Radiography,
+	MG = Mammography,
+	PX = Panoramic X-Ray
+}
+
+StringValues="MammographyModality"	{
+	MG = Mammography
+}
+
+StringValues="IntraoralModality"	{
+	IO = Intra-oral Radiography,
+}
+
+StringValues="PresentationIntentType"	{
+	FOR PROCESSING,
+	FOR PRESENTATION
+}
+
+StringValues="ForProcessing"	{
+	FOR PROCESSING
+}
+
+StringValues="ForPresentation"	{
+	FOR PRESENTATION
+}
+
+StringValues="ImageLaterality"	{
+	R = Right,
+	L = Left,
+	U = Unpaired,
+	B = Both left and right
+}
+
+StringValues="MammographyImageLaterality"	{
+	R = Right,
+	L = Left,
+	B = Both left and right
+}
+
+StringValues="IntraoralImageLaterality"	{
+	R = Right,
+	L = Left,
+	B = Both left and right
+}
+
+StringValues="DXImageType3"	{
+	***EMPTYVALUE***
+}
+
+# C.8.11.7.1.4
+StringValues="MammoImageType3"	{
+	***EMPTYVALUE***,
+	STEREO_SCOUT,
+	STEREO_MINUS,
+	STEREO_PLUS,
+	PREFIRE_MINUS,
+	PREFIRE_PLUS,
+	POSTFIRE_MINUS,
+	POSTFIRE_PLUS,
+	POSTBIOPSY_MINUS,
+	POSTBIOPSY_PLUS,
+	POSTBIOPSY,
+	POSTMARKER_MINUS,
+	POSTMARKER_PLUS,
+	POSTMARKER,
+	TOMO_PROJ,
+	TOMOSYNTHESIS,
+	TOMO_SCOUT,
+	PREFIRE,
+	POSTFIRE,
+	PRE_CONTRAST,
+	POST_CONTRAST
+}
+
+# C.8.11.7.1.4
+StringValues="MammoImageType4"	{
+	***EMPTYVALUE***,
+	GENERATED_2D,
+	ADDITION,
+	SUBTRACTION
+}
+
+# C.8.21.6.1.1
+StringValues="BreastTomoImageAndFrameType4"	{
+	***EMPTYVALUE***,
+	NONE,
+	GENERATED_2D,
+	MAXIMUM,
+	MEAN,
+	ADDITION,
+	SUBTRACTION
+}
+
+# C.8.11.7.1.4
+StringValues="MammoImageType5"	{
+	***EMPTYVALUE***,
+	LOW_ENERGY,
+	HIGH_ENERGY
+}
+
+# C.8.21.6.1.1
+StringValues="BreastTomoImageAndFrameType5"	{
+	***EMPTYVALUE***,
+	LOW_ENERGY,
+	HIGH_ENERGY
+}
+
+# C.8.21.6.1.1
+StringValues="CommonEnhancedImageAndFrameType3AndBreastTomoImageAndFrameType3"	{
+	ANGIO,
+	CARDIAC,
+	CARDIAC_GATED,
+	CARDRESP_GATED,
+	DYNAMIC,
+	FLUOROSCOPY,
+	LOCALIZER,
+	MOTION,
+	PERFUSION,
+	PRE_CONTRAST,
+	POST_CONTRAST,
+	RESP_GATED,
+	REST,
+	STATIC,
+	STRESS,
+	VOLUME,
+	NON_PARALLEL,
+	PARALLEL,
+	WHOLE_BODY,
+	TOMO_PROJ,
+	TOMOSYNTHESIS,
+	TOMO_SCOUT,
+	PREFIRE,
+	POSTFIRE,
+	POSTBIOPSY,
+	POSTMARKER
+}
+
+StringValues="DXPixelIntensityRelationship" {
+	LIN = Approximately proportional to X-Ray beam intensity,
+	LOG = Non-linear Log Function
+}
+
+StringValues="DXPresentationLUTShape"	{
+	IDENTITY,
+	INVERSE
+}
+
+StringValues="DetectorType"	{
+	DIRECT,
+	SCINTILLATOR,
+	STORAGE,
+	FILM
+}
+
+StringValues="DetectorTypeExcludingFilm"	{
+	DIRECT,
+	SCINTILLATOR,
+	STORAGE
+}
+
+StringValues="DetectorConfiguration"	{
+	AREA,
+	SLOT
+}
+
+StringValues="DXShape" {
+	RECTANGLE,
+	ROUND,
+	HEXAGONAL
+}
+
+StringValues="DXFieldOfViewRotation" {
+	0,
+	90,
+	180,
+	270
+}
+
+StringValues="DXPositionerType" {
+	CARM,
+	COLUMN,
+	MAMMOGRAPHIC,
+	PANORAMIC,
+	CEPHALOSTAT,
+	RIGID,
+	NONE
+}
+
+StringValues="MammographyPositionerType" {
+	MAMMOGRAPHIC,
+	NONE
+}
+
+StringValues="MammographyPositionerTypeWithoutNone" {
+	MAMMOGRAPHIC
+}
+
+StringValues="IntraoralPositionerType" {
+	CEPHALOSTAT,
+	RIGID,
+	NONE
+}
+
+StringValues="DXTableType" {
+	FIXED,
+	TILTING,
+	NONE
+}
+
+StringValues="CodeValueForScreeningOrDiagnostic" {
+	R-42453 = Screening,
+	R-408C3 = Diagnostic
+}
+
+StringValues="PolygonalShutterShape" {
+	POLYGONAL
+}
+
+StringValues="BreastTomosynthesisFieldOfViewShape" {
+	RECTANGLE
+}
+
+StringValues="BreastTomosynthesisXRayReceptorType" {
+	DIGITAL_DETECTOR
+}
+
+StringValues="PositionerPrimaryAngleDirection" {
+	CW = Clockwise,
+	CC = CounterClockwise
+}
+
+StringValues="MammographyPositionerAndDetectorMotion" {
+	STATIONARY = No motion,
+	ROTATION_STEP = Circular arc motion, stepped, acquire only while stationary,
+	ROTATION_CONT = Circular arc motion, continuous during acquisition,
+	TRANSLATION_STEP = Linear motion, stepped, acquire only while stationary,
+	TRANSLATION_CONT = Linear motion, continuous during acquisition,
+	COMPLEX_STEP = Complex motion, stepped, acquire only while stationary,
+	COMPLEX_CONT = Complex motion, continuous during acquisition
+}
+
+
diff --git a/libsrc/standard/strval/file.tpl b/libsrc/standard/strval/file.tpl
new file mode 100755
index 0000000..e884c8e
--- /dev/null
+++ b/libsrc/standard/strval/file.tpl
@@ -0,0 +1,46 @@
+StringValues="IconImagePhotometricInterpretation" {
+	MONOCHROME1,
+	MONOCHROME2,
+	PALETTE COLOR
+}
+
+StringValues="DirectoryRecordType" {
+	PATIENT,
+	STUDY,
+	SERIES,
+	IMAGE,
+	RT DOSE,
+	RT STRUCTURE SET,
+	RT PLAN,
+	RT TREAT RECORD,
+	PRESENTATION,
+	SR DOCUMENT,
+	KEY OBJECT DOC,
+	WAVEFORM,
+	SPECTROSCOPY,
+	RAW DATA,
+	REGISTRATION,
+	FIDUCIAL,
+	HANGING PROTOCOL,
+	ENCAP DOC,
+	HL7 STRUC DOC,
+	STEREOMETRIC,
+	VALUE MAP,
+	PALETTE,
+	IMPLANT,
+	IMPLANT GROUP,
+	IMPLANT ASSY,
+	MEASUREMENT,
+	SURFACE,
+	PRIVATE
+}
+
+StringValues="DentalMediaProfileSOPClasses" {
+	1.2.840.10008.5.1.4.1.1.1.3,
+	1.2.840.10008.5.1.4.1.1.1.1
+}
+
+StringValues="DentalMediaProfileTransferSyntaxes" {
+	1.2.840.10008.1.2.1
+}
+
diff --git a/libsrc/standard/strval/mr.tpl b/libsrc/standard/strval/mr.tpl
new file mode 100755
index 0000000..3e225b8
--- /dev/null
+++ b/libsrc/standard/strval/mr.tpl
@@ -0,0 +1,669 @@
+StringValues="MRModality" {
+	MR
+}
+
+StringValues="CardiacCyclePosition" {
+	END_SYSTOLE,
+	END_DIASTOLE,
+	UNDETERMINED
+}
+
+StringValues="RespiratoryCyclePosition" {
+	START_RESPIR,
+	END_RESPIR,
+	UNDETERMINED
+}
+
+StringValues="CardiacSynchronizationTechnique" {
+	NONE,
+	REALTIME
+	PROSPECTIVE,
+	RETROSPECTIVE,
+	PACED
+}
+
+
+StringValues="CardiacSignalSource" {
+	ECG,
+	VCG,
+	PP,
+	MR
+}
+
+
+StringValues="CardiacBeatRejectionTechnique" {
+	NONE,
+	RR_INTERVAL,
+	QRS_LOOP,
+	PVC
+}
+
+StringValues="RespiratoryMotionCompensationTechnique" {
+	NONE,
+	BREATH_HOLD,
+	REALTIME,
+	GATING,
+	TRACKING,
+	PHASE_ORDERING,
+	PHASE_RESCANNING,
+	RETROSPECTIVE,
+	CORRECTION
+}
+
+StringValues="RespiratorySignalSource" {
+	NONE,
+	BELT,
+	NASAL_PROBE,
+	CO2_SENSOR,
+	NAVIGATOR,
+	MR_PHASE,
+	ECG
+}
+
+StringValues="BulkMotionCompensationTechnique" {
+	NONE,
+	REALTIME,
+	GATING,
+	TRACKING,
+	RETROSPECTIVE,
+	CORRECTION
+}
+
+StringValues="BulkMotionSignalSource" {
+	JOINT,
+	NAVIGATOR,
+	MR_PHASE
+}
+
+StringValues="ContentQualification" {
+	PRODUCT,
+	RESEARCH,
+	SERVICE
+}
+
+StringValues="ResonantNucleus" {
+	1H,
+	3HE,
+	7LI,
+	13C,
+	19F,
+	23NA,
+	31P,
+	129XE
+}
+
+StringValues="ApplicableSafetyStandardAgency" {
+	IEC,
+	FDA,
+	MHW
+}
+
+StringValues="EnhancedMRImageAndFrameType3" {
+	ANGIO,
+	CARDIAC,
+	CARDIAC_GATED,
+	CARDRESP_GATED,
+	DYNAMIC,
+	FLUOROSCOPY,
+	LOCALIZER,
+	MOTION,
+	PERFUSION,
+	PRE_CONTRAST,
+	POST_CONTRAST,
+	RESP_GATED,
+	REST,
+	STATIC,
+	STRESS,
+	VOLUME,
+	NON_PARALLEL,
+	PARALLEL,
+	WHOLE_BODY,
+	ANGIO_TIME,
+	ASL,
+	CINE,
+	DIFFUSION,
+	FLOW_ENCODED,
+	FLUID_ATTENUATED,
+	FMRI,
+	MAX_IP,
+	MIN_IP,
+	M_MODE,
+	METABOLITE_MAP,
+	MULTIECHO,
+	PROTON_DENSITY,
+	REALTIME,
+	STIR,
+	TAGGING,
+	TEMPERATURE,
+	T1,
+	T2,
+	T2_STAR,
+	TOF,
+	VELOCITY
+}
+
+StringValues="EnhancedMRSpectroscopyImageAndFrameType3" {
+	SPECTROSCOPY
+}
+
+StringValues="EnhancedMRImageType4" {
+	ADDITION,
+	DIVISION,
+	MASKED,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MTT,
+	MULTIPLICATION,
+	RCBF,
+	RCBV,
+	RESAMPLED,
+	STD_DEVIATION,
+	SUBTRACTION,
+	T_TEST,
+	TTP,
+	Z_SCORE,
+	NONE,
+	ADC,
+	PERFUSION_ASL,
+	DIFFUSION,
+	DIFFUSION_ANISO,
+	DIFFUSION_ATTNTD,
+	DIFFUSION_ISO,
+	METABOLITE_MAP,
+	NEI,
+	R_COEFFICIENT,
+	RHO,
+	SCM,
+	SNR_MAP,
+	T1_MAP,
+	T2_STAR_MAP,
+	T2_MAP,
+	TCS,
+	TEMPERATURE,
+	VELOCITY,
+	MIXED
+}
+
+StringValues="EnhancedMRFrameType4" {
+	ADDITION,
+	DIVISION,
+	MASKED,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MTT,
+	MULTIPLICATION,
+	RCBF,
+	RCBV,
+	RESAMPLED,
+	STD_DEVIATION,
+	SUBTRACTION,
+	T_TEST,
+	TTP,
+	Z_SCORE,
+	NONE,
+	ADC,
+	PERFUSION_ASL,
+	DIFFUSION,
+	DIFFUSION_ANISO,
+	DIFFUSION_ATTNTD,
+	DIFFUSION_ISO,
+	METABOLITE_MAP,
+	NEI,
+	R_COEFFICIENT,
+	RHO,
+	SCM,
+	SNR_MAP,
+	T1_MAP,
+	T2_STAR_MAP,
+	T2_MAP,
+	TCS,
+	TEMPERATURE,
+	VELOCITY
+}
+
+StringValues="EnhancedMRSpectroscopyImageType4" {
+	ADDITION,
+	DIVISION,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MULTIPLICATION,
+	STD_DEVIATION,
+	SUBTRACTION,
+	NONE,
+	MIXED
+}
+
+StringValues="EnhancedMRSpectroscopyFrameType4" {
+	ADDITION,
+	DIVISION,
+	MAXIMUM,
+	MEAN,
+	MINIMUM,
+	MULTIPLICATION,
+	STD_DEVIATION,
+	SUBTRACTION,
+	NONE
+}
+
+StringValues="CommonCTMRPixelPresentationFrameLevel" {
+	COLOR,
+	MONOCHROME,
+	TRUE_COLOR
+}
+
+StringValues="CommonCTMRPixelPresentationImageLevel" {
+	COLOR,
+	MONOCHROME,
+	MIXED,
+	TRUE_COLOR
+}
+
+StringValues="PixelPresentationTrueColor" {
+	TRUE_COLOR
+}
+
+StringValues="CommonCTMRVolumetricPropertiesFrameLevel" {
+	VOLUME,
+	SAMPLED,
+	DISTORTED
+}
+
+StringValues="CommonCTMRVolumetricPropertiesImageLevel" {
+	VOLUME,
+	SAMPLED,
+	DISTORTED,
+	MIXED
+}
+
+StringValues="CommonCTMRVolumeBasedCalculationTechniqueFrameLevel" {
+	MAX_IP,
+	MIN_IP,
+	VOLUME_RENDER,
+	SURFACE_RENDER,
+	MPR,
+	CURVED_MPR,
+	NONE
+}
+
+StringValues="CommonCTMRVolumeBasedCalculationTechniqueImageLevel" {
+	MAX_IP,
+	MIN_IP,
+	VOLUME_RENDER,
+	SURFACE_RENDER,
+	MPR,
+	CURVED_MPR,
+	NONE,
+	MIXED
+}
+
+
+StringValues="MRSpectroscopyVolumeBasedCalculationTechniqueFrameLevel" {
+	MAX_IP,
+	MIN_IP,
+	NONE
+}
+
+StringValues="MRSpectroscopyVolumeBasedCalculationTechniqueImageLevel" {
+	MAX_IP,
+	MIN_IP,
+	NONE,
+	MIXED
+}
+
+StringValues="EnhancedMRComplexImageComponentFrameLevel" {
+	MAGNITUDE,
+	PHASE,
+	REAL,
+	IMAGINARY
+}
+
+StringValues="EnhancedMRComplexImageComponentImageLevel" {
+	MAGNITUDE,
+	PHASE,
+	REAL,
+	IMAGINARY,
+	MIXED
+}
+
+StringValues="MRSpectroscopyComplexImageComponentFrameLevel" {
+	MAGNITUDE,
+	PHASE,
+	REAL,
+	IMAGINARY,
+	COMPLEX
+}
+
+StringValues="MRSpectroscopyComplexImageComponentImageLevel" {
+	MAGNITUDE,
+	PHASE,
+	REAL,
+	IMAGINARY,
+	COMPLEX,
+	MIXED
+}
+
+StringValues="EnhancedMRAcquisitionContrastFrameLevel" {
+	DIFFUSION,
+	FLOW_ENCODED,
+	FLUID_ATTENUATED,
+	PERFUSION,
+	PROTON_DENSITY,
+	STIR,
+	TAGGING,
+	T1,
+	T2,
+	T2_STAR,
+	TOF,
+	UNKNOWN
+}
+
+StringValues="EnhancedMRAcquisitionContrastImageLevel" {
+	DIFFUSION,
+	FLOW_ENCODED,
+	FLUID_ATTENUATED,
+	PERFUSION,
+	PROTON_DENSITY,
+	STIR,
+	TAGGING,
+	T1,
+	T2,
+	T2_STAR,
+	TOF,
+	UNKNOWN,
+	MIXED
+}
+
+
+StringValues="MRSpectroscopyAcquisitionContrastFrameLevel" {
+	PROTON_DENSITY,
+	T1,
+	T2,
+	UNKNOWN
+}
+
+StringValues="MRSpectroscopyAcquisitionContrastImageLevel" {
+	PROTON_DENSITY,
+	T1,
+	T2,
+	UNKNOWN,
+	MIXED
+}
+
+StringValues="EnhancedMRAcquisitionType" {
+	1D,
+	2D,
+	3D
+}
+
+StringValues="EchoPulseSequence" {
+	SPIN,
+	GRADIENT,
+	BOTH
+}
+
+StringValues="SteadyStatePulseSequence" {
+	FREE_PRECESSION,
+	TRANSVERSE,
+	TIME_REVERSED,
+	LONGITUDINAL,
+	NONE
+}
+
+StringValues="SpectrallySelectedSuppression" {
+	FAT,
+	WATER,
+	FAT_AND_WATER,
+	SILICON_GEL,
+	NONE
+}
+
+StringValues="OversamplingPhase" {
+	2D = phase direction,
+	3D = out of plane direction,
+	2D_3D = both,
+	NONE
+}
+
+StringValues="GeometryOfKSpaceTraversal" {
+	RECTILINEAR,
+	RADIAL,
+	SPIRAL
+}
+
+StringValues="RectilinearPhaseEncodeReordering" {
+	LINEAR,
+	CENTRIC,
+	SEGMENTED,
+	REVERSE_LINEAR,
+	REVERSE_CENTRIC
+}
+
+StringValues="SegmentedKSpaceTraversal" {
+	SINGLE,
+	PARTIAL,
+	FULL
+}
+
+StringValues="CoverageOfKSpace" {
+	FULL,
+	CYLINDRICAL,
+	ELLIPSOIDAL,
+	WEIGHTED
+}
+
+StringValues="SpecificAbsorptionRateDefinition" {
+	IEC_WHOLE_BODY,
+	IEC_PARTIAL_BODY,
+	IEC_HEAD,
+	IEC_LOCAL
+}
+
+StringValues="GradientOutputType" {
+	DB_DT,
+	ELECTRIC_FIELD,
+	PER_NERVE_STIM
+}
+
+StringValues="OperatingModeType" {
+	STATIC FIELD,
+	RF,
+	GRADIENT
+}
+StringValues="OperatingMode" {
+	IEC_NORMAL,
+	IEC_FIRST_LEVEL,
+	IEC_SECOND_LEVEL
+}
+
+StringValues="InplanePhaseEncodingDirection" {
+	COLUMN,
+	ROW,
+	OTHER
+}
+
+StringValues="FlowCompensation" {
+	ACCELERATION,
+	VELOCITY,
+	OTHER,
+	NONE
+}
+
+StringValues="FlowCompensationDirection" {
+	PHASE,
+	FREQUENCY,
+	SLICE_SELECT,
+	SLICE_AND_FREQ,
+	SLICE_FREQ_PHASE,
+	PHASE_AND_FREQ,
+	SLICE_AND_PHASE,
+	OTHER
+}
+
+StringValues="Spoiling" {
+	RF,
+	GRADIENT,
+	RF_AND_GRADIENT,
+	NONE
+}
+
+StringValues="SpectrallySelectedExcitation" {
+	WATER,
+	FAT,
+	NONE
+}
+
+StringValues="SpatialPresaturation" {
+	SLAB,
+	NONE
+}
+
+StringValues="PartialFourierDirection" {
+	PHASE,
+	FREQUENCY,
+	SLICE_SELECT,
+	COMBINATION
+}
+
+StringValues="ParallelAcquisitionTechnique" {
+	PILS,
+	SENSE,
+	SMASH,
+	OTHER
+}
+
+StringValues="MagnetizationTransfer" {
+	ON_RESONANCE,
+	OFF_RESONANCE,
+	NONE
+}
+
+StringValues="Tagging" {
+	GRID,
+	LINE,
+	NONE
+}
+
+StringValues="ReceiveCoilType" {
+	BODY,
+	VOLUME,
+	SURFACE,
+	MULTICOIL
+}
+
+StringValues="TransmitCoilType" {
+	BODY,
+	VOLUME,
+	SURFACE
+}
+
+StringValues="DiffusionDirectionality" {
+	DIRECTIONAL,
+	BMATRIX,
+	ISOTROPIC,
+	NONE
+}
+
+StringValues="DiffusionAnisotropyType" {
+	FRACTIONAL,
+	RELATIVE,
+	VOLUME_RATIO
+}
+
+StringValues="VolumeLocalizationTechnique" {
+	ILOPS,
+	ISIS,
+	PRIME,
+	PRESS,
+	SLIM,
+	SLOOP,
+	STEAM,
+	NONE
+}
+
+StringValues="DecoupledNucleus" {
+	1H,
+	3HE,
+	7LI,
+	13C,
+	19F,
+	23NA,
+	31P,
+	129XE
+}
+
+StringValues="DecouplingMethod" {
+	MLEV,
+	WALTZ,
+	NARROWBAND
+}
+
+StringValues="KSpaceFiltering" {
+	COSINE,
+	COSINE_SQUARED,
+	FERMI,
+	GAUSSIAN,
+	HAMMING,
+	HANNING,
+	LORENTZIAN,
+	LRNTZ_GSS_TRNSFM,
+	RIESZ,
+	TUKEY,
+	NONE
+}
+
+StringValues="TimeDomainFiltering" {
+	COSINE,
+	COSINE_SQUARED,
+	EXPONENTIAL,
+	GAUSSIAN,
+	HAMMING,
+	HANNING,
+	LORENTZIAN,
+	LRNTZ_GSS_TRNSFM,
+	NONE
+}
+
+StringValues="BaselineCorrection" {
+	LINEAR_TILT,
+	LOCAL_LINEAR_FIT,
+	POLYNOMIAL_FIT,
+	SINC_DECONVOLUTN,
+	TIME_DOMAIN_FIT,
+	SPLINE,
+	NONE
+}
+
+StringValues="MRSpectroscopyAcquisitionType" {
+	SINGLE_VOXEL,
+	ROW,
+	PLANE,
+	VOLUME
+}
+
+StringValues="MRSpectroscopyDataRepresentation" {
+	COMPLEX,
+	REAL,
+	IMAGINARY,
+	MAGNITUDE
+}
+
+StringValues="SpectroscopySignalDomain" {
+	FREQUENCY,
+	TIME
+}
+
+StringValues="ArterialSpinLabelingContrast" {
+	CONTINUOUS,
+	PSEUDOCONTINUOUS,
+	PULSED 
+}
+
+StringValues="ASLContext" {
+	LABEL,
+	CONTROL,
+	M_ZERO_SCAN
+}
+
diff --git a/libsrc/standard/strval/nm.tpl b/libsrc/standard/strval/nm.tpl
new file mode 100755
index 0000000..75f1c14
--- /dev/null
+++ b/libsrc/standard/strval/nm.tpl
@@ -0,0 +1,158 @@
+StringValues="NuclearMedicineSeriesTypeRetired" {
+	STATIC,
+	DYNAMIC,
+	GATED,
+	WHOLE BODY,
+	STEP_SHOOT TOMO,
+	CONTINUOUS TOMO,
+	GATED TOMO
+}
+
+StringValues="WholeBodyTechnique" {
+	1PS = One Pass,
+	2PS = Two Pass,
+	PCN = Patient Contour Following Employed 
+	DIV = Diverging Collimator Used,
+	MSP = Multiple Static Images Collected Into a Whole Body Image
+}
+
+StringValues="NMFieldOfViewShape" {
+	RECTANGLE,
+	ROUND,
+	HEXAGONAL
+}
+
+StringValues="CollimatorType" {
+	PARA = Parallel,
+	PINH = PinHole,
+	FANB = Fan Beam,
+	CONE = Cone Beam,
+	SLNT = Slant Hole,
+	ASTG = Astigmatic
+}
+
+StringValues="AcquisitionTerminationCondition" {
+	CNTS = Counts,
+	DENS = Density,
+	MANU = Manual,
+	OVFL = Data Overflow,
+	TIME = Time,
+	TRIG = Physiological Trigger
+}
+
+StringValues="NMCorrectedImageRetired" {
+	UNIF = Flood Corrected,
+	COR  = Center of Rotation Corrected,
+	NCO  = Non-circular Orbit Corrected,
+	DECY = Decay Corrected,
+	ATTN = Attenuation Corrected,
+	SCAT = Scatter Corrected,
+	DTIM = Dead Time Corrected
+}
+
+
+StringValues="NMPhotometricInterpretation" {
+	MONOCHROME2,
+	PALETTE COLOR
+}
+
+StringValues="NMImageTypeValue2"	{
+	PRIMARY
+}
+
+StringValues="NMImageTypeValue3"	{
+	STATIC,
+	DYNAMIC,
+	GATED,
+	WHOLE BODY,
+	TOMO,
+	GATED TOMO,
+	RECON TOMO,
+	RECON GATED TOMO
+}
+
+StringValues="NMImageTypeValue4"	{
+	EMISSION,
+	TRANSMISSION
+}
+
+StringValues="NMAcquisitionTerminationCondition" {
+	CNTS = preset count limit was reached,
+	DENS = preset count density was reached,
+	MANU = acquisition was terminated manually,
+	OVFL = acquisition was terminated automatically by pixel data overflow condition,
+	TIME = preset time limit was reached,
+	TRIG = preset number Of physiological triggers was reached,
+}
+
+StringValues="NMCorrectedImage"	{
+	UNIF = flood corrected,
+	COR = center Of rotation corrected,
+	NCO = non-circular orbit corrected,
+	DECY = decay corrected,
+	ATTN = attenuation corrected,
+	SCAT = scatter corrected,
+	DTIM = dead time corrected,
+	NRGY = energy corrected,
+	LIN = linearity corrected,
+	MOTN = motion corrected,
+	CLN = count loss normalization
+}
+
+StringValues="NMWholeBodyTechnique"	{
+	1PS = one pass,
+	2PS = two pass, 
+	PCN = patient contour following employed,
+	MSP = multiple static frames collected into a whole body frame
+}
+
+StringValues="EKG"	{
+	EKG
+}
+
+StringValues="NMCollimatorType"	{
+	PARA = Parallel,
+	PINH = Pinhole,
+	FANB = Fan-beam,
+	CONE = Cone-beam,
+	SLNT = Slant hole,
+	ASTG = Astigmatic,
+	DIVG = Diverging,
+	NONE = No collimator,
+	UNKN = Unknown
+}
+
+StringValues="NMTypeOfDetectorMotion"	{
+	STEP AND SHOOT = Interrupted motion - acquire only while stationary,
+	CONTINUOUS = Gantry motion and acquisition are simultaneous and continuous,
+	ACQ DURING STEP = Interrupted motion - acquisition is continuous
+}
+
+StringValues="PositionerMotion" {
+	STATIC,
+	DYNAMIC
+}
+
+StringValues="TableMotion" {
+	STATIC,
+	DYNAMIC
+}
+
+StringValues="NMPhaseDescription" {
+	FLOW,
+	WASHOUT,
+	UPTAKE,
+	EMPTYING,
+	EXCRETION
+}
+
+StringValues="CardiacSliceProgressionDirection" {
+	APEX_TO_BASE,
+	BASE_TO_APEX,
+	ANT_TO_INF,
+	INF_TO_ANT,
+	SEPTUM_TO_WALL,
+	WALL_TO_SEPTUM
+}
+
+
diff --git a/libsrc/standard/strval/pet.tpl b/libsrc/standard/strval/pet.tpl
new file mode 100755
index 0000000..81460fd
--- /dev/null
+++ b/libsrc/standard/strval/pet.tpl
@@ -0,0 +1,258 @@
+StringValues="PETUnits" {
+	CNTS = counts,
+	NONE = unitless,
+	CM2 = centimeter**2,
+	PCNT = percent,
+	CPS = counts/second,
+	BQML = Becquerels/milliliter,
+	MGMINML = milligram/minute/milliliter,
+	UMOLMINML = micromole/minute/milliliter,
+	MLMING = milliliter/minute/gram,
+	MLG = milliliter/gram,
+	1CM = 1/centimeter,
+	UMOLML = micromole/milliliter,
+	PROPCNTS = proportional to counts,
+	PROPCPS = proportional to counts/sec,
+	MLMINML = milliliter/minute/milliliter,
+	MLML = milliliter/milliliter,
+	GML = grams/milliliter,
+	STDDEV = standard deviations
+}
+
+StringValues="SUVType"	{
+	BSA,
+	BW,
+	LBM,
+	IBW 
+}
+
+StringValues="CountsSource"	{
+	EMISSION,
+	TRANSMISSION
+}
+
+StringValues="PETSeriesType1" {
+	STATIC,
+	DYNAMIC,
+	GATED,
+	WHOLE BODY
+}
+
+StringValues="PETSeriesType2" {
+	IMAGE,
+	REPROJECTION
+}
+
+StringValues="ReprojectionMethod" {
+	SUM,
+	MAX PIXEL
+}
+
+StringValues="CorrectedImage" {
+	DECY = decay corrected,
+	ATTN = attenuation corrected,
+	SCAT = scatter corrected,
+	DTIM = dead time corrected,
+	MOTN = gantry motion corrected (e.g. wobble or clamshell),
+	PMOT = patient motion corrected,
+	CLN  = count loss normalization (correction for count loss in gated Time Slots),
+	RAN  = randoms corrected,
+	RADL = non-uniform radial sampling corrected,
+	DCAL = sensitivity calibrated using dose calibrator,
+	NORM = detector normalization
+}
+
+StringValues="RandomsCorrectionMethod" {
+	NONE = no randoms correction,
+	DLYD = delayed event subtraction,
+	SING = singles estimation
+}
+
+StringValues="RandomsCorrectionMethodEnhanced" {
+	DLYD = delayed event subtraction,
+	SING = singles estimation,
+	PDDL = processed delays
+}
+
+StringValues="DecayCorrection" {
+	NONE = no decay correction,
+	START= acquisition start time,
+	ADMIN = radiopharmaceutical administration time
+}
+
+StringValues="AcquisitionStartCondition" {
+	DENS = density (counts/sec),
+	RDD = relative density difference (change in counts/sec),
+	MANU = manual,
+	TIME = time,
+	AUTO = automatic, when ready,
+	TRIG = physiological trigger
+}
+
+StringValues="PETAcquisitionTerminationCondition" {
+	CNTS = counts,
+	DENS = density (counts/sec),
+	RDD = relative density difference (change in counts/sec),
+	MANU = manual,
+	OVFL = data overflow,
+	TIME = time,
+	TRIG = physiological trigger
+}
+
+StringValues="PETFieldOfViewShape" {
+	CYLINDRICAL RING
+	HEXAGONAL
+	MULTIPLE PLANAR
+}
+
+StringValues="TypeOfDetectorMotion" {
+	NONE = stationary gantry,
+	STEP AND SHOOT = Interrupted motion, acquire only while stationary,
+	CONTINUOUS = Gantry motion and acquisition are simultaneous and continuous,
+	WOBBLE = wobble motion,
+	CLAMSHELL = clamshell motion
+}
+
+StringValues="PETCollimatorType" {
+	NONE = no collimator,
+	RING = transverse septa
+}
+
+StringValues="SecondaryCountsType" {
+	DLYD=delayed events,
+	SCAT=scattered events in secondary window,
+	SING=singles,
+	DTIM=events lost due to deadtime
+}
+
+StringValues="FramingType" {
+	FORW = forward,
+	BACK = backward,
+	PCNT  = forward/backward by percentage
+}
+
+StringValues="PETImageTypeValue2"	{
+	PRIMARY
+}
+
+StringValues="PETTypeOfData"	{
+	SYSRATE = system count rate,
+	SLICERATE = slice count rate,
+	BLDSMPL = blood samples,
+	CPM = cardiac polar map
+}
+
+StringValues="PETAxisUnits"	{
+	SEC = seconds,
+	CNTS = counts,
+	MM = millimeters,
+	NONE = unitless,
+	CM = centimeters
+	CM2 = cm**2,
+	DEG = degrees,
+	MILS = milliseconds,
+	PCNT = percent,
+	CPS = counts/second,
+	BQML = Becquerels/milliliter,
+	MGMINML = milligram/minute/milliliter,
+	UMOLMINML = micromole/minute/milliliter,
+	MLMING = milliliter/minute/gram,
+	MLG = milliliter/gram,
+	1CM = 1/centimeter,
+	UMOLML = micromole/milliliter,
+	PROPCNTS = proportional to counts,
+	PROPCPS = proportional to counts/sec,
+	MLMINML = milliliter/minute/milliliter,
+	MLML = milliliter/milliliter,
+	GML = grams/milliliter,
+	STDDEV = standard deviations
+}
+
+StringValues="CountsIncluded"	{
+	TRUES,
+	SCATTER,
+	RANDOMS,
+	SINGLES
+}
+
+StringValues="SliceProgressionDirection"	{
+	APEX_TO_BASE,
+	BASE_TO_APEX
+}
+
+StringValues="PETModality" {
+	PT
+}
+
+StringValues="EnhancedPETTypeOfDetectorMotion" {
+	STATIONARY,
+	STEP AND SHOOT,
+	CONTINUOUS,
+	WOBBLE,
+	CLAMSHELL 
+}
+
+StringValues="DetectorGeometry" {
+	CYLINDRICAL_RING,
+	CYL_RING_PARTIAL,
+	MULTIPLE_PLANAR,
+	MUL_PLAN_PARTIAL
+}
+
+StringValues="PETSliceProgressionDirection" {
+	APEX_TO_BASE,
+	BASE_TO_APEX,
+	ANT_TO_INF,
+	INF_TO_ANT,
+	SEPTUM_TO_WALL,
+	WALL_TO_SEPTUM
+}
+
+StringValues="EnhancedPETAcquisitionStartCondition" {
+	DENS,
+	RDD,
+	MANU,
+	AUTO,
+	CARD_TRIG,
+	RESP_TRIG
+}
+
+StringValues="EnhancedPETAcquisitionTerminationCondition" {
+	CNTS,
+	DENS,
+	RDD,
+	MANU,
+	OVFL,
+	TIME,
+	CARD_TRIG,
+	RESP_TRIG
+}
+
+StringValues="AttenuationCorrectionSource" {
+	CT,
+	MR,
+	POSITRON SOURCE,
+	SINGLE PHOTON,
+	CALCULATED
+}
+
+StringValues="AttenuationCorrectionTemporalRelationship" {
+	CONCURRENT, 
+	SEPARATE,
+	SIMULTANEOUS
+}
+
+StringValues="PETReconstructionType" {
+	2D,
+	3D,
+	3D_REBINNED
+}
+
+StringValues="PETReconstructionAlgorithm" {
+	FILTER_BACK_PROJ,
+	REPROJECTION,
+	RAMLA,
+	MLEM
+}
+
+
diff --git a/libsrc/standard/strval/rt.tpl b/libsrc/standard/strval/rt.tpl
new file mode 100755
index 0000000..8502471
--- /dev/null
+++ b/libsrc/standard/strval/rt.tpl
@@ -0,0 +1,562 @@
+StringValues="RTModality"	{
+	RTIMAGE = RT Image,
+	RTDOSE = RT Dose,
+	RTSTRUCT = RT Structure Set,
+	RTPLAN = RT Plan,
+	RTRECORD = RT Treatment Record
+}
+
+StringValues="RTImageTypeValue3"	{
+	DRR = digitally reconstructed radiograph,
+	PORTAL = digital portal image or portal film image,
+	SIMULATOR = conventional simulator image,
+	RADIOGRAPH = radiographic image,
+	BLANK = image pixels set to background value,
+	FLUENCE = fluence map
+}
+
+StringValues="ReportedValuesOrigin"	{
+	OPERATOR = manually entered by operator,
+	PLAN = planned parameter values,
+	ACTUAL = electronically recorded
+}
+
+StringValues="RTImagePlane"	{
+	NORMAL = image plane normal to beam axis,
+	NON_NORMAL = image plane non-normal to beam axis
+}
+
+StringValues="PrimaryDosimeterUnit"	{
+	MU = Monitor Unit,
+	MINUTE = minute
+}
+
+StringValues="IonPrimaryDosimeterUnit"	{
+	MU = Monitor Unit,
+	NP = number of particles
+}
+
+StringValues="RTBeamLimitingDeviceType"	{
+	X = symmetric jaw pair in IEC X direction,
+	Y = symmetric jaw pair in IEC Y direction,
+	ASYMX = asymmetric jaw pair in IEC X direction,
+	ASYMY = asymmetric pair in IEC Y direction,
+	MLCX = multileaf (multi-element) jaw pair in IEC X direction,
+	MLCY = multileaf (multi-element) jaw pair in IEC Y direction
+}
+
+StringValues="ApplicatorType"	{
+	ELECTRON_SQUARE = square electron applicator,
+	ELECTRON_RECT = rectangular electron applicator,
+	ELECTRON_CIRC = circular electron applicator,
+	ELECTRON_SHORT = short electron applicator,
+	ELECTRON_OPEN = open (dummy) electron applicator,
+	INTRAOPERATIVE = intraoperative (custom) applicator,
+	STEREOTACTIC = stereotactic applicator
+}
+
+StringValues="IonApplicatorType"	{
+	ION_SQUARE = square ion applicator,
+	ION_RECT = rectangular ion applicator,
+	ION_CIRC = circular ion applicator,
+	ION_SHORT = short ion applicator,
+	ION_OPEN = open (dummy) ion applicator,
+	INTRAOPERATIVE = intraoperative (custom) applicator,
+	STEREOTACTIC = stereotactic applicator
+}
+
+StringValues="BlockType"	{
+	SHIELDING = blocking material is inside contour,
+	APERTURE = blocking material is outside contour
+}
+
+StringValues="BlockDivergence"	{
+	PRESENT = block edges are shaped for beam divergence,
+	ABSENT = block edges are not shaped for beam divergence
+}
+
+StringValues="BlockMountingPosition"	{
+	PATIENT_SIDE = the block is mounted on the side of the Block Tray which is towards the patient,
+	SOURCE_SIDE = the block is mounted on the side of the Block Tray which is towards the radiation source
+}
+
+StringValues="DoseUnits"	{
+	GY = Gray,
+	RELATIVE = dose relative to implicit reference value
+}
+
+StringValues="TissueHeterogeneityCorrection"	{
+	IMAGE,
+	ROI_OVERRIDE,
+	WATER 
+}
+
+StringValues="DoseType"	{
+	PHYSICAL = physical dose,
+	EFFECTIVE = physical dose after correction for biological effect using user-defined modeling technique,
+	ERROR = difference between desired and planned dose
+}
+
+StringValues="DoseSummationType"	{
+	PLAN = dose calculated for entire delivery of all fraction groups of RT Plan,
+	MULTI_PLAN = dose calculated for entire delivery of 2 or more RT Plans,
+	FRACTION = dose calculated for entire delivery of a single Fraction Group within RT Plan,
+	BEAM = dose calculated for entire delivery of one or more Beams within RT Plan,
+	BRACHY = dose calculated for entire delivery of one or more Brachy Application Setups within RT Plan,
+	FRACTION_SESSION = dose calculated for a single session (“fraction”) of a single Fraction Group within RT Plan,
+	BEAM_SESSION = dose calculated for a single session (“fraction”) of one or more Beams within RT Plan,
+	BRACHY_SESSION = dose calculated for a single session (“fraction”) of one or more Brachy Application Setups within RT Plan,
+	CONTROL_POINT = dose calculated for one or more Control Points within a Beam for a single fraction
+}
+
+StringValues="DVHROIContributionType"	{
+	INCLUDED
+	EXCLUDED
+}
+
+StringValues="DVHType"	{
+	DIFFERENTIAL = differential dose-volume histogram,
+	CUMULATIVE = cumulative dose-volume histogram,
+	NATURAL = natural dose-volume histogram
+}
+
+StringValues="DVHDoseUnits"	{
+	GY = Gray,
+	RELATIVE = dose relative to reference value specified in DVH Normalization Dose Value
+}
+
+StringValues="DVHDoseType"	{
+	PHYSICAL = physical dose,
+	EFFECTIVE = physical dose after correction for biological effect using user-defined modeling technique,
+	ERROR = difference between desired and planned dose
+}
+
+StringValues="DVHVolumeUnits"	{
+	CM3 = cubic centimeters,
+	PERCENT = percent,
+	PER_U = volume per u
+}
+
+StringValues="TransformationType"	{
+	HOMOGENEOUS
+}
+
+StringValues="ROIGenerationAlgorithm"	{
+	AUTOMATIC = calculated ROI,
+	SEMIAUTOMATIC = ROI calculated with user assistance,
+	MANUAL = user-entered ROI
+}
+
+StringValues="ContourGeometricType"	{
+	POINT = single point,
+	OPEN_PLANAR = open contour containing coplanar points,
+	OPEN_NONPLANAR = open contour containing non-coplanar points,
+	CLOSED_PLANAR = closed contour (polygon) containing coplanar points
+}
+
+StringValues="RTROIRelationship"	{
+	SAME = ROIs represent the same entity,
+	ENCLOSED = referenced ROI completely encloses referencing ROI,
+	ENCLOSING = referencing ROI completely encloses referenced ROI
+}
+
+StringValues="RTROIInterpretedType"	{
+	EXTERNAL = external patient contour,
+	PTV = Planning Target Volume (as defined in ICRU50),
+	CTV = Clinical Target Volume (as defined in ICRU50),
+	GTV = Gross Tumor Volume (as defined in ICRU50),
+	TREATED_VOLUME = Treated Volume (as defined in ICRU50),
+	IRRAD_VOLUME = Irradiated Volume (as defined in ICRU50),
+	BOLUS = patient bolus to be used for external beam therapy,
+	AVOIDANCE = region in which dose is to be minimized,
+	ORGAN = patient organ,
+	MARKER = patient marker,
+	REGISTRATION = registration ROI,
+	ISOCENTER = treatment isocenter to be used for external beam therapy,
+	CONTRAST_AGENT = volume into which a contrast agent has been injected,
+	CAVITY = patient anatomical cavity,
+	BRACHY_CHANNEL = brachytherapy channel,
+	BRACHY_ACCESSORY = brachytherapy accessory device,
+	BRACHY_SRC_APP = brachytherapy source applicator,
+	BRACHY_CHNL_SHLD = brachytherapy channel shield,
+	SUPPORT = external patient support device,
+	FIXATION = external patient fixation or immobilisation device,
+	DOSE_REGION = ROI to be used as a dose reference,
+	CONTROL = ROI to be used in control of dose optimization and calculation
+}
+
+StringValues="ROIPhysicalProperty"	{
+	REL_MASS_DENSITY = mass density relative to water,
+	REL_ELEC_DENSITY = electron density relative to water,
+	EFFECTIVE_Z = effective atomic number,
+	EFF_Z_PER_A = ratio of effective atomic number to mass (AMU-1),
+	REL_STOP_RATIO = linear stopping power ratio relative to water,
+	ELEM_FRACTION = elemental composition of the material
+}
+
+StringValues="PlanIntent"	{
+	CURATIVE,
+	PALLIATIVE,
+	PROPHYLACTIC,
+	VERIFICATION,
+	MACHINE_QA,
+	RESEARCH,
+	SERVICE 
+}
+
+StringValues="RTPlanGeometry"	{
+	PATIENT = RT Structure Set exists,
+	TREATMENT_DEVICE = RT Structure Set does not exist
+}
+
+StringValues="RTPlanRelationship"	{
+	PRIOR = plan delivered prior to current treatment,
+	ALTERNATIVE = alternative plan prepared for current treatment,
+	PREDECESSOR = plan used in derivation of current plan,
+	VERIFIED_PLAN = plan which is verified using the current plan
+}
+
+StringValues="RTPlanRelationshipVerifiedPlan"	{
+	VERIFIED_PLAN = plan which is verified using the current plan
+}
+
+StringValues="DoseReferenceStructureType"	{
+	POINT = dose reference point specified as ROI,
+	VOLUME = dose reference volume specified as ROI,
+	COORDINATES = point specified by Dose Reference Point Coordinates (300A,0018),
+	SITE = dose reference clinical site
+}
+
+StringValues="DoseReferenceType"	{
+	TARGET = treatment target (corresponding to GTV, PTV, or CTV in ICRU50),
+	ORGAN_AT_RISK = Organ at Risk (as defined in ICRU50)
+}
+
+StringValues="SetupTechnique"	{
+	ISOCENTRIC,
+	FIXED_SSD,
+	TBI,
+	BREAST_BRIDGE,
+	SKIN_APPOSITION
+}
+
+StringValues="SetupDeviceType"	{
+	LASER_POINTER,
+	DISTANCE_METER,
+	TABLE_HEIGHT,
+	MECHANICAL_PTR,
+	ARC
+}
+
+StringValues="BeamType"	{
+	STATIC = all beam parameters remain unchanged during delivery,
+	DYNAMIC = one or more beam parameters changes during delivery
+}
+
+StringValues="RadiationType"	{
+	PHOTON,
+	ELECTRON,
+	NEUTRON,
+	PROTON
+}
+
+StringValues="FluenceMode"	{
+	STANDARD,
+	NON_STANDARD
+}
+
+StringValues="IonRadiationType"	{
+	PHOTON,
+	PROTON,
+	ION
+}
+
+StringValues="IonScanMode"	{
+	NONE,
+	UNIFORM,
+	MODULATED
+}
+
+StringValues="TreatmentDeliveryType"	{
+	TREATMENT = normal patient treatment,
+	OPEN_PORTFILM = portal image acquisition with open field,
+	TRMT_PORTFILM = portal image acquisition with treatment port,
+	CONTINUATION = continuation of interrupted treatment,
+	SETUP = no treatment beam is applied for this RT Beam
+}
+
+StringValues="WedgeType"	{
+	STANDARD = standard (static) wedge,
+	DYNAMIC = moving beam limiting device (collimator) jaw simulating wedge,
+	MOTORIZED = single wedge which can be removed from beam remotely
+}
+
+StringValues="IonWedgeType"	{
+	STANDARD = standard (static) wedge,
+	MOTORIZED = single wedge which can be removed from beam remotely,
+	PARTIAL_STANDARD = wedge does not extend across the whole field and is operated manually,
+	PARTIAL_MOTORIZED = wedge does not extend across the whole field and can be removed from beam remotely
+}
+
+StringValues="CompensatorDivergence"	{
+	PRESENT = the compensator is shaped according to the beam geometrical divergence,
+	ABSENT = the compensator is not shaped according to the beam geometrical divergence
+}
+
+StringValues="CompensatorMountingPosition"	{
+	PATIENT_SIDE = the compensator is mounted on the side of the Compensator Tray which is towards the patient,
+	SOURCE_SIDE = the compensator is mounted on the side of the Compensator Tray which is towards the radiation source,
+	DOUBLE_SIDED = the compensator has a shaped surface on both sides of the Compensator Tray
+}
+
+StringValues="BrachyTreatmentTechnique"	{
+	INTRALUMENARY,
+	INTRACAVITARY,
+	INTERSTITIAL,
+	CONTACT,
+	INTRAVASCULAR,
+	PERMANENT
+}
+
+StringValues="BrachyTreatmentType"	{
+	MANUAL = manually positioned,
+	HDR = High dose rate,
+	MDR = Medium dose rate,
+	LDR = Low dose rate,
+	PDR = Pulsed dose rate
+}
+
+StringValues="ApplicationSetupType"	{
+	FLETCHER_SUIT,
+	DELCLOS,
+	BLOEDORN,
+	JOSLIN_FLYNN,
+	CHANDIGARH,
+	MANCHESTER,
+	HENSCHKE,
+	NASOPHARYNGEAL,
+	OESOPHAGEAL,
+	ENDOBRONCHIAL,
+	SYED_NEBLETT,
+	ENDORECTAL,
+	PERINEAL
+}
+
+StringValues="BrachyAccessoryDeviceType"	{
+	SHIELD,
+	DILATATION,
+	MOLD,
+	PLAQUE,
+	FLAB
+}
+
+StringValues="SourceMovementType"	{
+	STEPWISE,
+	FIXED,
+	OSCILLATING,
+	UNIDIRECTIONAL
+}
+
+StringValues="ApprovalStatus"	{
+	APPROVED = Reviewer recorded that object met an implied criterion,
+	UNAPPROVED = No review of object has been recorded,
+	REJECTED = Reviewer recorded that object failed to meet an implied criterion
+}
+
+StringValues="FixationDeviceType"	{
+	BITEBLOCK,
+	HEADFRAME,
+	MASK,
+	MOLD,
+	CAST,
+	HEADREST,
+	BREAST_BOARD,
+	BODY_FRAME,
+	VACUUM_MOLD,
+	WHOLE_BODY_POD,
+	RECTAL_BALLOON
+}
+
+StringValues="ShieldingDeviceType"	{
+	GUM,
+	EYE,
+	GONAD
+}
+
+StringValues="HighDoseTechniqueType"	{
+	TBI,
+	HDR
+}
+
+StringValues="TreatmentTerminationStatus"	{
+	NORMAL,
+	OPERATOR,
+	MACHINE,
+	UNKNOWN
+}
+
+StringValues="FractionGroupType"	{
+	EXTERNAL_BEAM,
+	BRACHY
+}
+
+StringValues="CurrentTreatmentStatus"	{
+	NOT_STARTED,
+	ON_TREATMENT,
+	ON_BREAK,
+	SUSPENDED,
+	STOPPED,
+	COMPLETED
+}
+
+StringValues="SourceApplicatorType"	{
+	FLEXIBLE,
+	RIGID
+}
+
+StringValues="TreatmentVerificationStatus"	{
+	VERIFED,
+	VERIFIED_OVR,
+	NOT_VERIFED
+}
+
+StringValues="TreatmentDeliveryTypeNormalOrContinuation"	{
+	TREATMENT,
+	CONTINUATION
+}
+
+StringValues="ApplicationSetupCheck"	{
+	PASSED,
+	FAILED,
+	UNKNOWN
+}
+
+StringValues="SourceType"	{
+	POINT,
+	LINE,
+	CYLINDER,
+	SPHERE
+}
+
+StringValues="BeamStopperPosition"	{
+	EXTENDED,
+	RETRACTED,
+	UNKNOWN
+}
+
+StringValues="WedgePosition"	{
+	IN,
+	OUT
+}
+
+StringValues="NominalBeamEnergyUnit"	{
+	MV = Megavolt,
+	MEV = Mega electron-Volt
+}
+
+StringValues="CompensatorType"	{
+	STANDARD,
+	DYNAMIC
+}
+
+StringValues="MeasuredDoseType"	{
+	DIODE,
+	TLD,
+	ION_CHAMBER,
+	GEL,
+	EPID,
+	FILM
+}
+
+StringValues="FluenceDataSource"	{
+	CALCULATED,
+	MEASURED
+}
+
+StringValues="RTRespiratoryMotionCompensationTechnique" {
+	NONE,
+	BREATH_HOLD,
+	REALTIME,
+	GATING,
+	TRACKING,
+	PHASE_ORDERING,
+	PHASE_RESCANNING,
+	RETROSPECTIVE,
+	CORRECTION,
+	UNKNOWN
+}
+
+StringValues="RTRespiratorySignalSource" {
+	NONE,
+	BELT,
+	NASAL_PROBE,
+	CO2_SENSOR,
+	NAVIGATOR,
+	MR_PHASE,
+	ECG,
+	SPIROMETER,
+	EXTERNAL_MARKER,
+	INTERNAL_MARKER,
+	IMAGE,
+	UNKNOWN
+}
+
+StringValues="SourceStrengthUnits"	{
+	AIR_KERMA_RATE,
+	DOSE_RATE_WATER
+}
+
+StringValues="RTDoseSOPClass"	{
+	1.2.840.10008.5.1.4.1.1.481.2
+}
+
+StringValues="RangeShifterType"	{
+	ANALOG,
+	BINARY
+}
+
+StringValues="LateralSpreadingDeviceType"	{
+	SCATTERER,
+	MAGNET
+}
+
+StringValues="RangeModulatorType"	{
+	FIXED,
+	WHL_FIXEDWEIGHTS,
+	WHL_MODWEIGHTS
+}
+
+StringValues="PatientSupportType"	{
+	TABLE,
+	CHAIR
+}
+
+StringValues="RTGeneralAccessoryType"	{
+	GRATICULE = Accessory tray with a radio-opaque grid,
+	IMAGE_DETECTOR = Image acquisition device positioned in the beam line,
+	RETICLE = Accessory tray with radio-transparent markers or grid
+}
+
+StringValues="RTPatientPosition" {
+	HFP  = Head First Prone,
+	HFS  = Head First Supine,
+	HFDR = Head First Decubitus Right,
+	HFDL = Head First Decubitus Right,
+	FFP  = Feet First Prone,
+	FFS  = Feet First Supine,
+	FFDR = Feet First Decubitus Right,
+	FFDL = Feet First Decubitus Right,
+	SITTING = Sitting
+}
+
+StringValues="BeamDoseMeaning" {
+	BEAM_LEVEL,
+	FRACTION_LEVEL
+}
+
+StringValues="SpatialTransformOfDose" {
+	NONE,
+	RIGID,
+	NON_RIGID
+}
+
diff --git a/libsrc/standard/strval/sdmdx.tpl b/libsrc/standard/strval/sdmdx.tpl
new file mode 100755
index 0000000..197b20b
--- /dev/null
+++ b/libsrc/standard/strval/sdmdx.tpl
@@ -0,0 +1,345 @@
+StringValues="SDMCID4009CodeValue"	{
+	T-D3000 = Chest,
+	T-280A0 = Apex of lung,
+	T-25000 = Trachea,
+	T-26000 = Bronchus,
+	T-24100 = Larynx,
+	T-D3300 = Mediastinum,
+	T-32000 = Heart,
+	T-D1600 = Neck,
+	T-11210 = Sternum,
+	T-15610 = Sternoclavicular joint,
+	T-11300 = Rib,
+	T-11500 = Spine,
+	T-11600 = Cervical spine,
+	T-11700 = Thoracic spine,
+	T-11900 = Lumbar spine,
+	T-11AD0 = Sacrum,
+	T-11BF0 = Coccyx,
+	T-D4000 = Abdomen,
+	T-D0300 = Extremity,
+	T-D8200 = Arm,
+	T-D8810 = Thumb,
+	T-D8800 = Finger,
+	T-D8700 = Hand,
+	T-D8600 = Wrist,
+	T-12402 = Forearm bone,
+	T-D8300 = Elbow,
+	T-12410 = Humerus,
+	T-D2220 = Shoulder,
+	T-12310 = Clavicle,
+	T-12280 = Scapula,
+	T-15420 = Acromioclavicular joint,
+	T-D9800 = Toe,
+	T-12980 = Sesamoid bones of foot,
+	T-D9700 = Foot,
+	T-12770 = Calcaneus,
+	T-15770 = Tarsal joint,
+	T-15750 = Ankle joint,
+	T-D9400 = Leg,
+	T-D9200 = Knee,
+	T-12730 = Patella,
+	T-12710 = Femur,
+	T-15710 = Hip joint,
+	T-D6000 = Pelvis,
+	T-15680 = Sacroiliac joint,
+	T-D1100 = Head,
+	T-11100 = Skull,
+	T-11196 = Facial bones,
+	T-11167 = Zygomatic arch,
+	T-11149 = Nasal bone,
+	T-D1480 = Orbit,
+	T-11102 = Optic canal,
+	T-11180 = Mandible,
+	T-11170 = Maxilla,
+	T-D1217 = Maxilla and mandible,
+	T-15290 = Temporomandibular joint,
+	T-22000 = Paranasal sinus,
+	T-11133 = Mastoid bone,
+	T-D1460 = Sella turcica,
+	T-04000 = Breast,
+	T-61100 = Parotid gland,
+	T-61300 = Submandibular gland,
+	T-63000 = Gall bladder,
+	T-60610 = Bile duct,
+	T-56000 = Esophagus,
+	T-57000 = Stomach,
+	T-58200 = Duodenum,
+	T-58000 = Small intestine,
+	T-59000 = Large intestine,
+	T-59600 = Rectum,
+	T-70010 = Upper urinary tract,
+	T-74000 = Bladder,
+	T-75000 = Urethra,
+	T-D6151 = Uterus and fallopian tubes
+}
+
+StringValues="SDMCID4013CodeValue"	{
+	T-04000 = Breast
+}
+
+StringValues="SDMCID4016CodeValue"	{
+	T-11180 = Mandible,
+	T-11170 = Maxilla,
+	T-D1217 = Maxilla and mandible
+}
+
+StringValues="SDMCID4010CodeValue" {
+	R-10202 = frontal,
+	R-10204 = frontal oblique,
+	R-10206 = antero-posterior,
+	R-10208 = antero-posterior oblique,
+	R-10210 = right posterior oblique,
+	R-10212 = left posterior oblique,
+	R-10214 = postero-anterior,
+	R-10216 = postero-anterior oblique,
+	R-10218 = right anterior oblique,
+	R-10220 = left anterior oblique,
+	R-10222 = sagittal,
+	R-10224 = medial-lateral,
+	R-10226 = lateral oblique,
+	R-10228 = lateral-medial,
+	R-10230 = medial oblique,
+	R-10232 = right lateral,
+	R-10234 = right oblique,
+	R-10236 = left lateral,
+	R-10238 = left oblique,
+	R-10241 = axial,
+	R-10242 = cranio-caudal,
+	R-10244 = caudo-cranial,
+	R-10246 = oblique axial,
+	R-10248 = oblique cranio-caudal,
+	R-10250 = oblique caudo-cranial,
+	R-10252 = frontal-oblique axial,
+	R-10254 = sagittal-oblique axial,
+	R-102C1 = oblique,
+	R-102CD = lateral,
+	R-102C2 = tangential,
+	R-10256 = submentovertical,
+	R-10257 = verticosubmental,
+	R-102C3 = plantodorsal,
+	R-102C4 = dorsoplantar,
+	R-102C5 = parietoacanthal,
+	R-102C6 = acanthoparietal,
+	R-102C7 = orbitoparietal,
+	R-102C8 = parieto-orbital
+}
+
+StringValues="SDMCID4014CodeValue" {
+	R-10224 = medio-lateral,
+	R-10226 = medio-lateral oblique,
+	R-10228 = latero-medial,
+	R-10230 = latero-medial oblique,
+	R-10242 = cranio-caudal,
+	R-10244 = caudo-cranial (from below),
+	R-102D0 = superolateral to inferomedial oblique,
+	R-102CF = exaggerated cranio-caudal,
+	Y-X1770 = cranio-caudal exaggerated laterally,
+	Y-X1771 = cranio-caudal exaggerated medially
+}
+
+StringValues="SDMCID4015CodeValue" {
+	R-102D2 = Cleavage,
+	R-102D1 = Axillary Tail,
+	R-102D3 = Rolled Lateral,
+	R-102D4 = Rolled Medial,
+	R-102D5 = Implant Displaced,
+	R-102D6 = Magnification,
+	R-102D7 = Spot Compression,
+	R-102C2 = Tangential
+}
+
+StringValues="SDMCID4011CodeValue" {
+	R-10244 = cephalad,
+	R-10242 = caudad,
+	R-102C9 = transthoracic,
+	R-102CA = lordotic,
+	R-102CB = transforamenal,
+	R-102CC = transoral,
+	R-102CE = transorbital
+}
+
+StringValues="SDMCID19CodeValue" {
+	F-10440 = erect,
+	F-10450 = recumbent,
+	F-10460 = semi-erect
+}
+
+StringValues="SDMCID20CodeValue" {
+	F-10310 = prone,
+	F-10316 = semi-prone,
+	F-10318 = lateral  decubitus,
+	F-10320 = standing,
+	F-10326 = anatomical,
+	F-10330 = kneeling,
+	F-10336 = knee-chest,
+	F-10340 = supine,
+	F-10346 = lithotomy,
+	F-10348 = Trendelenburg,
+	F-10349 = inverse Trendelenburg,
+	F-10380 = frog,
+	F-10390 = stooped-over,
+	F-103A0 = sitting,
+	F-10410 = curled-up,
+	F-10317 = right lateral decubitus,
+	F-10319 = left lateral decubitus
+}
+
+StringValues="SDMCID21CodeValue" {
+	R-10516 = oblique,
+	F-10470 = headfirst,
+	F-10480 = feet-first,
+	R-10515 = transverse
+}
+
+StringValues="SDMCID4012CodeValue" {
+	R-10261 = Albers-Schonberg,
+	R-10262 = Alexander,
+	R-10263 = Arcelin,
+	R-10264 = Beclere,
+	R-10265 = Bertel,
+	R-10266 = Blackett-Healy,
+	R-10267 = Broden,
+	R-10268 = Cahoon,
+	R-10269 = Caldwell,
+	R-1026A = Camp-Coventry,
+	R-1026B = Causton,
+	R-1026C = Chamberlain,
+	R-1026D = Chassard-Lapine,
+	R-1026E = Chausse,
+	R-1026F = Cleaves,
+	R-10270 = Clements,
+	R-10271 = Clements-Nakayama,
+	R-10272 = Dunlap,
+	R-10273 = Ferguson,
+	R-10274 = Fleischner,
+	R-10275 = Friedman,
+	R-10276 = Fuchs,
+	R-10277 = Gaynor-Hart,
+	R-10278 = Grandy,
+	R-10279 = Grashey,
+	R-1027A = Haas,
+	R-1027B = Henschen,
+	R-1027C = Hickey,
+	R-1027D = Holly,
+	R-1027E = Holmblad,
+	R-1027F = Hough,
+	R-10280 = Hsieh,
+	R-10281 = Hughston,
+	R-10282 = Isherwood,
+	R-10283 = Judd,
+	R-10284 = Kandel,
+	R-10285 = Kasabach,
+	R-10286 = Kemp Harper,
+	R-10287 = Kovacs,
+	R-10288 = Kuchendorf,
+	R-10289 = Kurzbauer,
+	R-1028A = Laquerriere-Pierquin,
+	R-1028B = Lauenstein,
+	R-1028C = Law,
+	R-1028D = Lawrence,
+	R-1028E = Leonard-George,
+	R-1028F = Lewis,
+	R-10290= Lilienfeld,
+	R-10291 = Lindblom,
+	R-10292 = Lorenz,
+	R-10293 = Low-Beer,
+	R-10294 = Lysholm,
+	R-10295 = May,
+	R-10296 = Mayer,
+	R-10297 = Merchant,
+	R-10298 = Miller,
+	R-10299 = Nolke,
+	R-1029A = Norgaard,
+	R-1029B = Ottonello,
+	R-1029C = Pawlow,
+	R-1029D = Pearson,
+	R-1029E= Penner,
+	R-1029F = Pirie,
+	R-102A0 = Rhese,
+	R-102A1 = Schuller,
+	R-102A2 = Settegast,
+	R-102A3 = Staunig,
+	R-102A4 = Stecher,
+	R-102A5 = Stenvers,
+	R-102A6 = Swanson,
+	R-102A7 = Tarrant,
+	R-102A8 = Taylor,
+	R-102A9 = Teufel,
+	R-102AA = Titterington,
+	R-102AB = Towne,
+	R-102AC = Twining,
+	R-102AD = Valdini,
+	R-102AE = Waters,
+	R-102AF = West Point,
+	R-102B0 = Wigby-Taylor,
+	R-102B1 = Zanelli
+}
+
+StringValues="SDMCID4017CodeValue" {
+	T-51005 = Anterior 1,
+	T-51006 = Anterior 2,
+	T-51007 = Anterior 3,
+	T-51008 = Premolar 1,
+	T-51009 = Premolar 2,
+	T-5100A = Molar 1,
+	T-5100B = Molar 2,
+	T-5100C = Molar 3,
+	T-5100D = Occlusal
+}
+
+StringValues="SDMCID4018or4019CodeValue" {
+	T-54210 = Maxillary right third molar tooth
+	T-54220 = Maxillary right second molar tooth
+	T-54230 = Maxillary right first molar tooth
+	T-54240 = Maxillary right second premolar tooth
+	T-54250 = Maxillary right first premolar tooth
+	T-54260 = Maxillary right canine tooth
+	T-54270 = Maxillary right lateral incisor tooth
+	T-54280 = Maxillary right central incisor tooth
+	T-54290 = Maxillary left central incisor tooth
+	T-54300 = Maxillary left lateral incisor tooth
+	T-54310 = Maxillary left canine tooth
+	T-54320 = Maxillary left first premolar tooth
+	T-54330 = Maxillary left second premolar tooth
+	T-54340 = Maxillary left first molar tooth
+	T-54350 = Maxillary left second molar tooth
+	T-54360 = Maxillary left third molar tooth
+	T-54370 = Mandibular left third molar tooth
+	T-54380 = Mandibular left second molar tooth
+	T-54390 = Mandibular left first molar tooth
+	T-54400 = Mandibular left second premolar tooth
+	T-54410 = Mandibular left first premolar tooth
+	T-54420 = Mandibular left canine tooth
+	T-54430 = Mandibular left lateral tooth
+	T-54440 = Mandibular left central incisor tooth
+	T-54450 = Mandibular right central incisor tooth
+	T-54460 = Mandibular right lateral incisor tooth
+	T-54470 = Mandibular right canine tooth
+	T-54480 = Mandibular right first premolar tooth
+	T-54490 = Mandibular right second premolar tooth
+	T-54500 = Mandibular right first molar tooth
+	T-54510 = Mandibular right second molar tooth
+	T-54520 = Mandibular right third molar tooth
+	T-54610 = Deciduous maxillary right central incisor tooth
+	T-54620 = Deciduous maxillary right lateral incisor tooth
+	T-54630 = Deciduous maxillary right canine tooth
+	T-54640 = Deciduous maxillary right first molar tooth
+	T-54650 = Deciduous maxillary right second molar tooth
+	T-54660 = Deciduous maxillary left central incisor tooth
+	T-54670 = Deciduous maxillary left lateral incisor tooth
+	T-54680 = Deciduous maxillary left canine tooth
+	T-54690 = Deciduous maxillary left first molar tooth
+	T-54700 = Deciduous maxillary left second molar tooth
+	T-54760 = Deciduous mandibular left central incisor tooth
+	T-54770 = Deciduous mandibular left lateral incisor tooth
+	T-54780 = Deciduous mandibular left canine tooth
+	T-54790 = Deciduous mandibular left first molar tooth
+	T-54800 = Deciduous mandibular left second molar tooth
+	T-54710 = Deciduous mandibular right central incisor tooth
+	T-54720 = Deciduous mandibular right lateral incisor tooth
+	T-54730 = Deciduous mandibular right canine tooth
+	T-54740 = Deciduous mandibular right first molar tooth
+	T-54750 = Deciduous mandibular right second molar tooth
+}
+
diff --git a/libsrc/standard/strval/softcopy.tpl b/libsrc/standard/strval/softcopy.tpl
new file mode 100755
index 0000000..d172d6e
--- /dev/null
+++ b/libsrc/standard/strval/softcopy.tpl
@@ -0,0 +1,233 @@
+StringValues="AnnotationUnits"	{
+	PIXEL,
+	DISPLAY,
+	MATRIX
+}
+
+StringValues="GraphicType"	{
+	POINT,
+	POLYLINE,
+	INTERPOLATED,
+	CIRCLE,
+	ELLIPSE
+}
+
+StringValues="SoftcopyPresentationLUTShape"	{
+	IDENTITY,
+	INVERSE
+}
+
+StringValues="PresentationStateModality"	{
+	PR = Presentation State
+}
+
+StringValues="MaskOperationForPresentationState" {
+	AVG_SUB = Average Subtraction,
+	TID = Time Interval Differencing
+}
+
+StringValues="PresentationSizeMode"	{
+	SCALE TO FIT,
+	TRUE SIZE,
+	MAGNIFY
+}
+
+StringValues="HangingProtocolLevel"	{
+	MANUFACTURER,
+	SITE,
+	USER_GROUP,
+	SINGLE_USER
+}
+
+StringValues="ImageSetSelectorUsageFlag"	{
+	MATCH,
+	NO_MATCH
+}
+
+StringValues="SelectorAttributeVR"	{
+	AE,
+	AS,
+	AT,
+	CS,
+	DA,
+	DS,
+	DT,
+	FL,
+	FD,
+	IS,
+	LO,
+	LT,
+	PN,
+	SH,
+	SL,
+	SQ,
+	SS,
+	ST,
+	TM,
+	UI,
+	UL,
+	US,
+	UT
+}
+
+StringValues="ImageSetSelectorCategory"	{
+	RELATIVE_TIME,
+	ABSTRACT_PRIOR
+}
+
+StringValues="RelativeTimeUnits"	{
+	SECONDS,
+	MINUTES,
+	HOURS,
+	DAYS,
+	WEEKS,
+	MONTHS,
+	YEARS
+}
+
+StringValues="ImageBoxLayoutTypeForHangingProtocol"	{
+	TILED,
+	STACK,
+	CINE,
+	PROCESSED,
+	SINGLE
+}
+
+StringValues="ImageBoxScrollDirection"	{
+	VERTICAL,
+	HORIZONTAL
+}
+
+StringValues="ImageBoxScrollType"	{
+	PAGE,
+	ROW_COLUMN,
+	IMAGE
+}
+
+StringValues="FilterByCategory"	{
+	IMAGE_PLANE
+}
+
+StringValues="FilterByAttributePresence"	{
+	PRESENT,
+	NOT_PRESENT
+}
+
+StringValues="FilterByOperator"	{
+	RANGE_INCL,
+	RANGE_EXCL,
+	GREATER_OR_EQUAL,
+	LESS_OR_EQUAL,
+	GREATER_THAN,
+	LESS_THAN,
+	MEMBER_OF,
+	NOT_MEMBER_OF
+}
+
+StringValues="SortByCategory"	{
+	ALONG_AXIS,
+	BY_ACQ_TIME
+}
+
+StringValues="SortingDirection"	{
+	INCREASING,
+	DECREASING
+}
+
+StringValues="BlendingOperationType"	{
+	COLOR
+}
+
+StringValues="ReformattingOperationType"	{
+	MPR,
+	3D_RENDERING,
+	SLAB
+}
+
+StringValues="ReformattingOperationInitialViewDirection"	{
+	SAGITTAL,
+	AXIAL,
+	CORONAL,
+	OBLIQUE
+}
+
+StringValues="ThreeDRenderingType"	{
+	MIP,
+	SURFACE,
+	VOLUME
+}
+
+StringValues="DisplaySetHorizontalJustification"	{
+	LEFT,
+	CENTER,
+	RIGHT
+}
+
+StringValues="DisplaySetVerticalJustification"	{
+	TOP,
+	CENTER,
+	BOTTOM
+}
+StringValues="VOIType"	{
+	LUNG,
+	MEDIASTINUM,
+	ABDO_PELVIS,
+	LIVER,
+	SOFT_TISSUE,
+	BONE,
+	BRAIN,
+	POST_FOSSA
+}
+
+StringValues="PseudoColorType"	{
+	BLACK_BODY,
+	HOT_IRON,
+	DEFAULT
+}
+
+StringValues="PartialDataDisplayHandling"	{
+	MAINTAIN_LAYOUT,
+	ADAPT_LAYOUT
+}
+
+StringValues="VOILUTFunction"	{
+	LINEAR,
+	SIGMOID,
+	LINEAR_EXACT
+}
+
+StringValues="BlendingPosition"	{
+	SUPERIMPOSED,
+	UNDERLYING
+}
+
+StringValues="ImageBoxLayoutTypeForStructuredDisplay" {
+	STACK,
+	CINE,
+	SINGLE
+}
+
+StringValues="InitialCineRunState" {
+	STOPPED,
+	RUNNING
+}
+
+StringValues="TypeOfSynchronizationBetweenImageBoxes" {
+	FRAME,
+	POSITION,
+	TIME,
+	PHASE
+}
+
+StringValues="BoundingBoxTextHorizontalJustification" {
+	LEFT,
+	RIGHT,
+	CENTER
+}
+
+StringValues="PixelOriginInterpretation"	{
+	FRAME,
+	VOLUME
+}
+
+
diff --git a/libsrc/standard/strval/sr.tpl b/libsrc/standard/strval/sr.tpl
new file mode 100755
index 0000000..e633d95
--- /dev/null
+++ b/libsrc/standard/strval/sr.tpl
@@ -0,0 +1,202 @@
+StringValues="SRModality" {
+	SR
+}
+
+StringValues="KOModality" {
+	KO
+}
+
+StringValues="PreliminaryFlag" {
+	PRELIMINARY,
+	FINAL
+}
+
+StringValues="CompletionFlag" {
+	PARTIAL,
+	COMPLETE
+}
+
+StringValues="VerificationFlag" {
+	UNVERIFIED,
+	VERIFIED
+}
+
+StringValues="ContinuityOfContent" {
+	SEPARATE,
+	CONTINUOUS
+}
+
+StringValues="SRRelationshipType" {
+	CONTAINS,
+	HAS PROPERTIES,
+	HAS CONCEPT MOD,
+	HAS OBS CONTEXT,
+	HAS ACQ CONTEXT,
+	INFERRED FROM,
+	SELECTED FROM
+}
+
+StringValues="SRRelationshipTypeHasConceptModifier" {
+	HAS CONCEPT MOD
+}
+
+StringValues="SRValueTypes" {
+	TEXT,
+	NUM,
+	CODE,
+	DATETIME,
+	DATE,
+	TIME,
+	UIDREF,
+	PNAME,
+	IMAGE,
+	WAVEFORM,
+	COMPOSITE,
+	SCOORD,
+	SCOORD3D,
+	TCOORD,
+	CONTAINER
+}
+
+StringValues="EnhancedAndComprehensiveSRValueTypes" {
+	TEXT,
+	NUM,
+	CODE,
+	DATETIME,
+	DATE,
+	TIME,
+	UIDREF,
+	PNAME,
+	IMAGE,
+	WAVEFORM,
+	COMPOSITE,
+	SCOORD,
+	TCOORD,
+	CONTAINER
+}
+
+StringValues="BasicTextSRValueTypes" {
+	TEXT,
+	CODE,
+	DATETIME,
+	DATE,
+	TIME,
+	UIDREF,
+	PNAME,
+	COMPOSITE,
+	IMAGE,
+	WAVEFORM,
+	CONTAINER
+}
+
+StringValues="KeyObjectSelectionDocumentValueTypes" {
+	TEXT,
+	CODE,
+	UIDREF,
+	PNAME,
+	IMAGE,
+	WAVEFORM,
+	COMPOSITE,
+	CONTAINER
+}
+
+StringValues="MammographyCADSRValueTypes" {
+	TEXT,
+	CODE,
+	NUM,
+	DATE,
+	TIME,
+	PNAME,
+	SCOORD,
+	COMPOSITE,
+	IMAGE,
+	CONTAINER
+}
+
+StringValues="ChestCADSRValueTypes" {
+	TEXT,
+	CODE,
+	NUM,
+	DATE,
+	TIME,
+	PNAME,
+	SCOORD,
+	TCOORD,
+	COMPOSITE,
+	IMAGE,
+	CONTAINER,
+	UIDREF,
+	WAVEFORM
+}
+
+StringValues="ProcedureLogValueTypes" {
+	CODE,
+	CONTAINER,
+	COMPOSITE,
+	DATETIME,
+	DATE,
+	IMAGE,
+	NUM,
+	PNAME,
+	TEXT,
+	TIME,
+	UIDREF,
+	WAVEFORM
+}
+
+StringValues="XRayRadiationDoseSRValueTypes" {
+	TEXT,
+	CODE,
+	NUM,
+	DATETIME,
+	UIDREF,
+	PNAME,
+	COMPOSITE,
+	IMAGE,
+	CONTAINER
+}
+
+StringValues="SRGraphicType" {
+	POINT,
+	MULTIPOINT,
+	POLYLINE,
+	CIRCLE,
+	ELLIPSE
+}
+
+StringValues="SRGraphicType3D" {
+	POINT,
+	MULTIPOINT,
+	POLYLINE,
+	POLYGON,
+	ELLIPSE,
+	ELLIPSOID
+}
+
+StringValues="TemporalRangeType" {
+	POINT,
+	MULTIPOINT,
+	SEGMENT,
+	MULTISEGMENT,
+	BEGIN,
+	END
+}
+
+StringValues="ParticipationType" {
+	SOURCE,
+	ENT,
+	ATTEST 
+}
+
+StringValues="ObserverType" {
+	PSN,
+	DEV 
+}
+
+StringValues="SRTemplateMappingResource" {
+	DCMR,
+	99RPH,
+	99SMS_CTMR = Siemens CT MR,
+	99PMP = PixelMed,
+	99QIICR = NCI QIICR Project 3DSlicer BWH
+}
diff --git a/libsrc/standard/strval/us.tpl b/libsrc/standard/strval/us.tpl
new file mode 100755
index 0000000..df6503f
--- /dev/null
+++ b/libsrc/standard/strval/us.tpl
@@ -0,0 +1,965 @@
+StringValues="OverlaySubtypeUS" {
+	ACTIVE 2D/BMODE IMAGE AREA = Identification of the active area of a 2D/B-mode image
+}
+
+StringValues="USPhotometricInterpretation" {
+	MONOCHROME2,
+	PALETTE COLOR,
+	RGB,
+	ARGB,
+	YBR_FULL,
+	YBR_FULL_422,
+	YBR_PARTIAL_422,
+	YBR_RCT,
+	YBR_ICT
+}
+
+StringValues="USImageType3"	{
+	ABDOMINAL,
+	BREAST,
+	CHEST,
+	ENDOCAVITARY,
+	ENDORECTAL,
+	ENDOVAGINAL,
+	EPICARDIAL,
+	FETAL HEART,
+	GYNECOLOGY,
+	INTRACARDIAC,
+	INTRAOPERATIVE,
+	INTRAVASCULAR,
+	MUSCULOSKELETAL,
+	NEONATAL HEAD,
+	OBSTETRICAL,
+	OPHTHALMIC,
+	PEDIATRIC,
+	PELVIC,
+	RETROPERITONEAL,
+	SCROTAL,
+	SMALL PARTS,
+	TEE,
+	THYROID,
+	TRANSCRANIAL,
+	TTE,
+	USBIOPSY,
+	VASCULAR
+}
+
+StringValues="USTransducerPosition" {
+	ANTERIOR,
+	AORTA,
+	APICAL ,
+	ARTERY,
+	BASAL ESOPHAGUS,
+	BYPASS GRAFT,
+	CAUDAL,
+	CRANIAL,
+	DISTAL,
+	ENDOVAGINAL,
+	ENDORECTAL,
+	EPICARDIAL,
+	ESOPHAGUS,
+	GASTRIC,
+	INFERIOR,
+	L ATRIUM,
+	L CORONARY ART,
+	L LIQ,
+	L LOQ,
+	L PARASTERN,
+	L SUBCLAVIAN,
+	L SUPRACLAVICULAR,
+	L UIQ,
+	L UOQ,
+	L VENTRICLE LATER,
+	LEFT,
+	LEFT PARA,
+	LOWER ESOPHAGUS,
+	MEDIAL,
+	MID ESOPHAGUS,
+	MIDLINE,
+	OCCIPITAL,
+	POSTERIOR,
+	PROXIMAL,
+	PULMONARY ART,
+	R ATRIUM,
+	R CORONARY ART,
+	R LIQ,
+	R LOQ,
+	R PARASTERN,
+	R SUBCLAVIAN,
+	RSUPRACLAVICULAR,
+	R UIQ,
+	R UOQ,
+	R VENTRICLE,
+	RIGHT,
+	RIGHT PARA,
+	SUBCLAVIAN,
+	SUBCOSTAL,
+	SUP STERN NOTCH,
+	SUPERIOR ,
+	SUPRACLAVICULAR,
+	SURFACE,
+	TRANSGASTRIC,
+	TRANSORBITAL,
+	TRANSTEMPORAL,
+	UPPER ESOPHAGUS,
+	VEIN
+}
+
+StringValues="USTransducerOrientation" {
+	2 CHAMBER,
+	4 CHAMBER,
+	5 CHAMBER,
+	AXIAL,
+	CORONAL,
+	L PARASAG,
+	LONG AXIS,
+	LONGITUDINAL,
+	OBLIQUE,
+	R PARASAG,
+	SAGITTAL,
+	SHORT AXIS,
+	TRANSVERSE
+}
+
+StringValues="USAnatomicStructure" {
+	4 CH HEART,
+	3RD VENTRICLE,
+	4TH VENTRICLE,
+	AC,
+	ADRENAL,
+	AMNIOTIC FLUID,
+	AORTA,
+	APPENDIX,
+	ASCENDING COLON,
+	BASILAR ART,
+	BILE DUCT,
+	BLADDER,
+	BPD,
+	C SPINE,
+	CELIAC ART,
+	CENTRAL ZONE,
+	CEREBELLUM,
+	CEREB HEMISPHERE,
+	CERVIX,
+	COLON,
+	CUL DE SAC,
+	DESCENDING COLON,
+	DUODENUM,
+	ENDOMETRIUM,
+	FETAL ARMS,
+	FETAL DIGITS,
+	FETAL HEART,
+	FETAL LEGS,
+	FETAL POLE,
+	FEMUR LENGTH,
+	FUNDUS,
+	GALLBLADDER,
+	GEST SAC,
+	HC,
+	HEPATIC ART,
+	ILEUM,
+	ISTHMUS,
+	INF MES ART,
+	INF VENA CAVA,
+	L ACA,
+	L AXILLARY A,
+	L AXILLARY V,
+	L BRACHIAL A,
+	L BRACHIAL V,
+	L BREAST,
+	L BULB,
+	L CCA,
+	L CFA,
+	L CFV,
+	L CHOROID PLEXUS,
+	L COM ILIAC ART,
+	L COM ILIAC V,
+	L ECA,
+	L EPIDIDYMIS,
+	L EXT ILIAC A,
+	L EXT ILIAC V,
+	L EXT JUG V,
+	L EYE,
+	L FEMUR,
+	L GSV,
+	L HEPATIC V,
+	L HUMERUS,
+	L ICA,
+	L ILIAC A,
+	L ILIAC V,
+	L INT JUG V,
+	L KIDNEY,
+	L MCA,
+	L OVARY,
+	L PCA ,
+	L POP A,
+	L POP V,
+	L PROF FEM A,
+	L PROF FEM V,
+	L RADIAL A,
+	L RADIUS,
+	L RENAL ART,
+	L RENAL V,
+	L SEM VESICLE,
+	L SAPH V,
+	L SFA,
+	L SFV,
+	L SPINE,
+	L SUBCLAVIAN A,
+	L SUBCLAVIAN V,
+	L TESTIS,
+	L THALAMUS,
+	L TIB FIB,
+	L ULNA,
+	L ULNAR ART,
+	L VENTRICLE,
+	L VERT,
+	LAT VENTRICLES,
+	LIVER,
+	L PORTAL V,
+	MID HEPATIC V,
+	MORRISONS POUCH,
+	OFD,
+	PANCREAS,
+	PENILE VESSELS,
+	PERIPHERAL ZONE,
+	PLACENTA,
+	PORTAL V,
+	PROSTATE,
+	R ACA,
+	R AXILLARY A,
+	R AXILLARY V,
+	R BRACHIAL A,
+	R BRACHIAL V,
+	R BREAST,
+	R BULB,
+	R CCA,
+	R CFA,
+	R CFV,
+	R CHOROID PLEXUS
+	R COM ILIAC ART,
+	R COM ILIAC V,
+	R ECA,
+	R EYE,
+	R EPIDIDYMIS,
+	R EXT ILIAC A,
+	R EXT ILIAC V,
+	R EXT JUV V,
+	R FEMUR,
+	R GSV,
+	R HEPATIC V,
+	R HUMERUS,
+	R ICA,
+	R ILIAC A,
+	R ILIAC V,
+	R INT JUG V,
+	R KIDNEY,
+	R MCA,
+	R OVARY,
+	R PCAR POP A,
+	R POP V,
+	R PROF FEM A,
+	R PROF FEM V,
+	R RADIAL A,
+	R RADIUS,
+	R RENAL ART,
+	R RENAL V,
+	R SAPH V,
+	R SEM VESICLE,
+	R SFA,
+	R SFV,
+	R SUBCLAVIAN A,
+	R SUBCLAVIAN V,
+	R TESTIS,
+	R THALAMUS,
+	R TIB FIB,
+	R ULNA,
+	R ULNAR ART,
+	R VENTRICLE,
+	R VERT,
+	R PORTAL V,
+	RECTUM,
+	RETROPERITONEUM,
+	SACRUM,
+	SCROTUM,
+	SIGMOID,
+	SMA,
+	SMALL INTESTINE,
+	SMV,
+	SPLEEN,
+	SPLENIC ART,
+	SPLENIC V,
+	STOMACH,
+	TESTICLE,
+	T SPINE,
+	THYROID,
+	TRANSITION ZONE,
+	TRANSVERSE COLON,
+	SIGMOID,
+	UMB CORD,
+	UTERINE FUNDUS,
+	UTERUS,
+	VAGINA,
+	YOLK SAC,
+	ABD AO,
+	AO ANNULUS,
+	AO ARCH,
+	AO LFLT TIPS,
+	AO VALVE,
+	ASCENDING AO,
+	ASD,
+	AZYGOS VEIN,
+	CORONARY SINUS,
+	DIAGONAL,
+	DISTAL LAD,
+	DISTAL LCX,
+	DISTAL RCA,
+	IAS,
+	INNOMINATE A,
+	INT ATRIAL SEPT,
+	INT VENT SEPT,
+	IVS,
+	L ATRIAL APPEN,
+	L ATRIUM,
+	L FOOT,
+	L GERMINAL MATRX,
+	L HIP,
+	L SHOULDER,
+	L MAIN COR ART,
+	L SAPH V,
+	L SVC,
+	LAD,
+	LAD D1,
+	LAD D2,
+	LAD D3,
+	LAD S1,
+	LAD S2,
+	LCX,
+	LCXDM1,
+	LCXDM2,
+	LIMA,
+	LLPV,
+	LOWER DESC AO,
+	LPA,
+	LPV,
+	LUPV,
+	LV APEX,
+	LV BASE,
+	LV CAVITY,
+	LV MID,
+	LVOT,
+	MAIN PA,
+	MID LAD,
+	MID LCX,
+	MID RCA,
+	MITRAL ANNULUS,
+	MITRAL LFLT TIPS,
+	MITRAL VALVE,
+	OBTUSE MARGINAL,
+	PERINEUM,
+	PLV COR ART,
+	POST DESC ART,
+	POST LV BRANCH,
+	PROX CIRC,
+	PROX LAD,
+	PROX LCX,
+	PROX RCA,
+	PULM ANNULUS,
+	PULM VALVE,
+	PULM VEIN,
+	PV TIPS,
+	R ATRIUM,
+	R FOOT,
+	R GERMINAL MATRX,
+	R HIP,
+	R PV,
+	R SAPH V,
+	R SHOULDER,
+	RAA,
+	RCA,
+	RIMA,
+	RLPV,
+	RPA,
+	RUPV,
+	RV CAVITY,
+	RVOT,
+	SAPH V GRAFT LAD,
+	SUP VENA CAVA,
+	SVG D,
+	SVG LAD,
+	SVG LCX,
+	SVG OM,
+	SVG PDA,
+	SVG PLV,
+	SVG RCA,
+	TRICUSPID ANN,
+	TRICUSPID TIPS,
+	TRICUSPID VALVE,
+	UPPER DESC AO,
+	VSD
+}
+
+StringValues="USTransducerType" {
+	SECTOR_PHASED,
+	SECTOR_MECH,
+	SECTOR_ANNULAR,
+	LINEAR,
+	CURVED LINEAR,
+	SINGLE CRYSTAL,
+	SPLIT XTAL CWD,
+	IV_PHASED,
+	IV_ROT XTAL,
+	IV_ROT MIRROR,
+	ENDOCAV_PA,
+	ENDOCAV_MECH,
+	ENDOCAV_CLA,
+	ENDOCAV_AA,
+	ENDOCAV_LINEAR,
+	VECTOR_PHASED
+}
+
+StringValues="USImageType4"	{
+	0001 = 2D Imaging,
+	0002 = M-Mode,
+	0003 = 2D Imaging + M-Mode,
+	0004 = CW Doppler,
+	0005 = 2D Imaging + CW Doppler,
+	0006 = M-Mode + CW Doppler,
+	0007 = 2D Imaging + M-Mode + CW Doppler,
+	0008 = PW Doppler,
+	0009 = 2D Imaging + PW Doppler,
+	000a = M-Mode + PW Doppler,
+	000b = 2D Imaging + M-Mode + PW Doppler,
+	000c = CW Doppler + PW Doppler,
+	000d = 2D Imaging + CW Doppler + PW Doppler,
+	000e = M-Mode + CW Doppler + PW Doppler,
+	000f = 2D Imaging + M-Mode + CW Doppler + PW Doppler,
+	0010 = Color Doppler,
+	0011 = 2D Imaging + Color Doppler,
+	0012 = M-Mode + Color Doppler,
+	0013 = 2D Imaging + M-Mode + Color Doppler,
+	0014 = CW Doppler + Color Doppler,
+	0015 = 2D Imaging + CW Doppler + Color Doppler,
+	0016 = M-Mode + CW Doppler + Color Doppler,
+	0017 = 2D Imaging + M-Mode + CW Doppler + Color Doppler,
+	0018 = PW Doppler + Color Doppler,
+	0019 = 2D Imaging + PW Doppler + Color Doppler,
+	001a = M-Mode + PW Doppler + Color Doppler,
+	001b = 2D Imaging + M-Mode + PW Doppler + Color Doppler,
+	001c = CW Doppler + PW Doppler + Color Doppler,
+	001d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler,
+	001e = M-Mode + CW Doppler + PW Doppler + Color Doppler,
+	001f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler,
+	0020 = Color M-Mode,
+	0021 = 2D Imaging + Color M-Mode,
+	0022 = M-Mode + Color M-Mode,
+	0023 = 2D Imaging + M-Mode + Color M-Mode,
+	0024 = CW Doppler + Color M-Mode,
+	0025 = 2D Imaging + CW Doppler + Color M-Mode,
+	0026 = M-Mode + CW Doppler + Color M-Mode,
+	0027 = 2D Imaging + M-Mode + CW Doppler + Color M-Mode,
+	0028 = PW Doppler + Color M-Mode,
+	0029 = 2D Imaging + PW Doppler + Color M-Mode,
+	002a = M-Mode + PW Doppler + Color M-Mode,
+	002b = 2D Imaging + M-Mode + PW Doppler + Color M-Mode,
+	002c = CW Doppler + PW Doppler + Color M-Mode,
+	002d = 2D Imaging + CW Doppler + PW Doppler + Color M-Mode,
+	002e = M-Mode + CW Doppler + PW Doppler + Color M-Mode,
+	002f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color M-Mode,
+	0030 = Color Doppler + Color M-Mode,
+	0031 = 2D Imaging + Color Doppler + Color M-Mode,
+	0032 = M-Mode + Color Doppler + Color M-Mode,
+	0033 = 2D Imaging + M-Mode + Color Doppler + Color M-Mode,
+	0034 = CW Doppler + Color Doppler + Color M-Mode,
+	0035 = 2D Imaging + CW Doppler + Color Doppler + Color M-Mode,
+	0036 = M-Mode + CW Doppler + Color Doppler + Color M-Mode,
+	0037 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + Color M-Mode,
+	0038 = PW Doppler + Color Doppler + Color M-Mode,
+	0039 = 2D Imaging + PW Doppler + Color Doppler + Color M-Mode,
+	003a = M-Mode + PW Doppler + Color Doppler + Color M-Mode,
+	003b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + Color M-Mode,
+	003c = CW Doppler + PW Doppler + Color Doppler + Color M-Mode,
+	003d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + Color M-Mode,
+	003e = M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode,
+	003f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode,
+	0040 = 3D Rendering
+	0041 = 2D Imaging + 3D Rendering,
+	0042 = M-Mode + 3D Rendering,
+	0043 = 2D Imaging + M-Mode + 3D Rendering,
+	0044 = CW Doppler + 3D Rendering,
+	0045 = 2D Imaging + CW Doppler + 3D Rendering,
+	0046 = M-Mode + CW Doppler + 3D Rendering,
+	0047 = 2D Imaging + M-Mode + CW Doppler + 3D Rendering,
+	0048 = PW Doppler + 3D Rendering,
+	0049 = 2D Imaging + PW Doppler + 3D Rendering,
+	004a = M-Mode + PW Doppler + 3D Rendering,
+	004b = 2D Imaging + M-Mode + PW Doppler + 3D Rendering,
+	004c = CW Doppler + PW Doppler + 3D Rendering,
+	004d = 2D Imaging + CW Doppler + PW Doppler + 3D Rendering,
+	004e = M-Mode + CW Doppler + PW Doppler + 3D Rendering,
+	004f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + 3D Rendering,
+	0050 = Color Doppler + 3D Rendering,
+	0051 = 2D Imaging + Color Doppler + 3D Rendering,
+	0052 = M-Mode + Color Doppler + 3D Rendering,
+	0053 = 2D Imaging + M-Mode + Color Doppler + 3D Rendering,
+	0054 = CW Doppler + Color Doppler + 3D Rendering,
+	0055 = 2D Imaging + CW Doppler + Color Doppler + 3D Rendering,
+	0056 = M-Mode + CW Doppler + Color Doppler + 3D Rendering,
+	0057 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + 3D Rendering,
+	0058 = PW Doppler + Color Doppler + 3D Rendering,
+	0059 = 2D Imaging + PW Doppler + Color Doppler + 3D Rendering,
+	005a = M-Mode + PW Doppler + Color Doppler + 3D Rendering,
+	005b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + 3D Rendering,
+	005c = CW Doppler + PW Doppler + Color Doppler + 3D Rendering,
+	005d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + 3D Rendering,
+	005e = M-Mode + CW Doppler + PW Doppler + Color Doppler + 3D Rendering,
+	005f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + 3D Rendering,
+	0060 = Color M-Mode + 3D Rendering,
+	0061 = 2D Imaging + Color M-Mode + 3D Rendering,
+	0062 = M-Mode + Color M-Mode + 3D Rendering,
+	0063 = 2D Imaging + M-Mode + Color M-Mode + 3D Rendering,
+	0064 = CW Doppler + Color M-Mode + 3D Rendering,
+	0065 = 2D Imaging + CW Doppler + Color M-Mode + 3D Rendering,
+	0066 = M-Mode + CW Doppler + Color M-Mode + 3D Rendering,
+	0067 = 2D Imaging + M-Mode + CW Doppler + Color M-Mode + 3D Rendering,
+	0068 = PW Doppler + Color M-Mode + 3D Rendering,
+	0069 = 2D Imaging + PW Doppler + Color M-Mode + 3D Rendering,
+	006a = M-Mode + PW Doppler + Color M-Mode + 3D Rendering,
+	006b = 2D Imaging + M-Mode + PW Doppler + Color M-Mode + 3D Rendering,
+	006c = CW Doppler + PW Doppler + Color M-Mode + 3D Rendering,
+	006d = 2D Imaging + CW Doppler + PW Doppler + Color M-Mode + 3D Rendering,
+	006e = M-Mode + CW Doppler + PW Doppler + Color M-Mode + 3D Rendering,
+	006f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color M-Mode + 3D Rendering,
+	0070 = Color Doppler + Color M-Mode + 3D Rendering,
+	0071 = 2D Imaging + Color Doppler + Color M-Mode + 3D Rendering,
+	0072 = M-Mode + Color Doppler + Color M-Mode + 3D Rendering,
+	0073 = 2D Imaging + M-Mode + Color Doppler + Color M-Mode + 3D Rendering,
+	0074 = CW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	0075 = 2D Imaging + CW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	0076 = M-Mode + CW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	0077 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	0078 = PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	0079 = 2D Imaging + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	007a = M-Mode + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	007b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	007c = CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	007d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	007e = M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering,
+	007f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering
+	0100 = Color Power Mode,
+	0101 = 2D Imaging + Color Power Mode,
+	0102 = M-Mode + Color Power Mode,
+	0103 = 2D Imaging + M-Mode + Color Power Mode,
+	0104 = CW Doppler + Color Power Mode,
+	0105 = 2D Imaging + CW Doppler + Color Power Mode,
+	0106 = M-Mode + CW Doppler + Color Power Mode,
+	0107 = 2D Imaging + M-Mode + CW Doppler + Color Power Mode,
+	0108 = PW Doppler + Color Power Mode,
+	0109 = 2D Imaging + PW Doppler + Color Power Mode,
+	010a = M-Mode + PW Doppler + Color Power Mode,
+	010b = 2D Imaging + M-Mode + PW Doppler + Color Power Mode,
+	010c = CW Doppler + PW Doppler + Color Power Mode,
+	010d = 2D Imaging + CW Doppler + PW Doppler + Color Power Mode,
+	010e = M-Mode + CW Doppler + PW Doppler + Color Power Mode,
+	010f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Power Mode,
+	0110 = Color Doppler + Color Power Mode,
+	0111 = 2D Imaging + Color Doppler + Color Power Mode,
+	0112 = M-Mode + Color Doppler + Color Power Mode,
+	0113 = 2D Imaging + M-Mode + Color Doppler + Color Power Mode,
+	0114 = CW Doppler + Color Doppler + Color Power Mode,
+	0115 = 2D Imaging + CW Doppler + Color Doppler + Color Power Mode,
+	0116 = M-Mode + CW Doppler + Color Doppler + Color Power Mode,
+	0117 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + Color Power Mode,
+	0118 = PW Doppler + Color Doppler + Color Power Mode,
+	0119 = 2D Imaging + PW Doppler + Color Doppler + Color Power Mode,
+	011a = M-Mode + PW Doppler + Color Doppler + Color Power Mode,
+	011b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + Color Power Mode,
+	011c = CW Doppler + PW Doppler + Color Doppler + Color Power Mode,
+	011d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + Color Power Mode,
+	011e = M-Mode + CW Doppler + PW Doppler + Color Doppler + Color Power Mode,
+	011f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + Color Power Mode,
+	0120 = Color M-Mode + Color Power Mode,
+	0121 = 2D Imaging + Color M-Mode + Color Power Mode,
+	0122 = M-Mode + Color M-Mode + Color Power Mode,
+	0123 = 2D Imaging + M-Mode + Color M-Mode + Color Power Mode,
+	0124 = CW Doppler + Color M-Mode + Color Power Mode,
+	0125 = 2D Imaging + CW Doppler + Color M-Mode + Color Power Mode,
+	0126 = M-Mode + CW Doppler + Color M-Mode + Color Power Mode,
+	0127 = 2D Imaging + M-Mode + CW Doppler + Color M-Mode + Color Power Mode,
+	0128 = PW Doppler + Color M-Mode + Color Power Mode,
+	0129 = 2D Imaging + PW Doppler + Color M-Mode + Color Power Mode,
+	012a = M-Mode + PW Doppler + Color M-Mode + Color Power Mode,
+	012b = 2D Imaging + M-Mode + PW Doppler + Color M-Mode + Color Power Mode,
+	012c = CW Doppler + PW Doppler + Color M-Mode + Color Power Mode,
+	012d = 2D Imaging + CW Doppler + PW Doppler + Color M-Mode + Color Power Mode,
+	012e = M-Mode + CW Doppler + PW Doppler + Color M-Mode + Color Power Mode,
+	012f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color M-Mode + Color Power Mode,
+	0130 = Color Doppler + Color M-Mode + Color Power Mode,
+	0131 = 2D Imaging + Color Doppler + Color M-Mode + Color Power Mode,
+	0132 = M-Mode + Color Doppler + Color M-Mode + Color Power Mode,
+	0133 = 2D Imaging + M-Mode + Color Doppler + Color M-Mode + Color Power Mode,
+	0134 = CW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	0135 = 2D Imaging + CW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	0136 = M-Mode + CW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	0137 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	0138 = PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	0139 = 2D Imaging + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	013a = M-Mode + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	013b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	013c = CW Doppler + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	013d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	013e = M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	013f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + Color Power Mode,
+	0140 = 3D Rendering + Color Power Mode
+	0141 = 2D Imaging + 3D Rendering + Color Power Mode,
+	0142 = M-Mode + 3D Rendering + Color Power Mode,
+	0143 = 2D Imaging + M-Mode + 3D Rendering + Color Power Mode,
+	0144 = CW Doppler + 3D Rendering + Color Power Mode,
+	0145 = 2D Imaging + CW Doppler + 3D Rendering + Color Power Mode,
+	0146 = M-Mode + CW Doppler + 3D Rendering + Color Power Mode,
+	0147 = 2D Imaging + M-Mode + CW Doppler + 3D Rendering + Color Power Mode,
+	0148 = PW Doppler + 3D Rendering + Color Power Mode,
+	0149 = 2D Imaging + PW Doppler + 3D Rendering + Color Power Mode,
+	014a = M-Mode + PW Doppler + 3D Rendering + Color Power Mode,
+	014b = 2D Imaging + M-Mode + PW Doppler + 3D Rendering + Color Power Mode,
+	014c = CW Doppler + PW Doppler + 3D Rendering + Color Power Mode,
+	014d = 2D Imaging + CW Doppler + PW Doppler + 3D Rendering + Color Power Mode,
+	014e = M-Mode + CW Doppler + PW Doppler + 3D Rendering + Color Power Mode,
+	014f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + 3D Rendering + Color Power Mode,
+	0150 = Color Doppler + 3D Rendering + Color Power Mode,
+	0151 = 2D Imaging + Color Doppler + 3D Rendering + Color Power Mode,
+	0152 = M-Mode + Color Doppler + 3D Rendering + Color Power Mode,
+	0153 = 2D Imaging + M-Mode + Color Doppler + 3D Rendering + Color Power Mode,
+	0154 = CW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	0155 = 2D Imaging + CW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	0156 = M-Mode + CW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	0157 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	0158 = PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	0159 = 2D Imaging + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	015a = M-Mode + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	015b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	015c = CW Doppler + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	015d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	015e = M-Mode + CW Doppler + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	015f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + 3D Rendering + Color Power Mode,
+	0160 = Color M-Mode + 3D Rendering + Color Power Mode,
+	0161 = 2D Imaging + Color M-Mode + 3D Rendering + Color Power Mode,
+	0162 = M-Mode + Color M-Mode + 3D Rendering + Color Power Mode,
+	0163 = 2D Imaging + M-Mode + Color M-Mode + 3D Rendering + Color Power Mode,
+	0164 = CW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0165 = 2D Imaging + CW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0166 = M-Mode + CW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0167 = 2D Imaging + M-Mode + CW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0168 = PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0169 = 2D Imaging + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	016a = M-Mode + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	016b = 2D Imaging + M-Mode + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	016c = CW Doppler + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	016d = 2D Imaging + CW Doppler + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	016e = M-Mode + CW Doppler + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	016f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0170 = Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0171 = 2D Imaging + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0172 = M-Mode + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0173 = 2D Imaging + M-Mode + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0174 = CW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0175 = 2D Imaging + CW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0176 = M-Mode + CW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0177 = 2D Imaging + M-Mode + CW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0178 = PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	0179 = 2D Imaging + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	017a = M-Mode + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	017b = 2D Imaging + M-Mode + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	017c = CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	017d = 2D Imaging + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	017e = M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode,
+	017f = 2D Imaging + M-Mode + CW Doppler + PW Doppler + Color Doppler + Color M-Mode + 3D Rendering + Color Power Mode
+
+}
+
+StringValues="IVUSAcquisition" {
+	MOTOR_PULLBACK,
+	MANUAL_PULLBACK,
+	SELECTIVE,
+	GATED_PULLBACK
+}
+
+StringValues="FrameOfInterestTypeForUS" {
+	HIGHMI,
+	RWAVE,
+	TRIGGER,
+	ENDSYSTOLE
+}
+
+StringValues="USStageName" {
+	PRE-EXERCISE,
+	POST-EXERCISE,
+	PEAK-EXERCISE,
+	RECOVERY,
+	BASELINE,
+	LOW DOSE,
+	PEAK DOSE
+}
+
+StringValues="UltrasoundAcquisitionGeometry" {
+	APEX
+}
+
+StringValues="UltrasoundAcquisitionGeometryPatient" {
+	PATIENT
+}
+
+StringValues="PatientFrameOfReferenceSource" {
+	TABLE,
+	ESTIMATED,
+	REGISTRATION
+}
+
+StringValues="PatientFrameOfReferenceSourceTable" {
+	TABLE
+}
+
+StringValues="USOrIVUSModality" {
+	US,
+	IVUS
+}
+
+StringValues="PerformedProtocolType" {
+	STAGED,
+	NON_STAGED
+}
+
+StringValues="DimensionOrganizationType3DOr3DTemporal" {
+	3D,
+	3D_TEMPORAL
+}
+
+StringValues="PositionMeasuringDeviceUsed" {
+	RIGID,
+	FREEHAND
+}
+
+StringValues="PositionMeasuringDeviceUsedRigid" {
+	RIGID
+}
+
+StringValues="EnhancedUSVolumeDataType" {
+	TISSUE_INTENSITY,
+	TISSUE_VELOCITY,
+	FLOW_VELOCITY,
+	FLOW_POWER,
+	FLOW_VARIANCE,
+	ELASTICITY,
+	PERFUSION,
+	SOUND_SPEED,
+	ATTENUATION
+}
+
+StringValues="DataPathAssignment" {
+	PRIMARY_PVALUES,
+	PRIMARY_SINGLE,
+	SECONDARY_SINGLE,
+	SECONDARY_HIGH,
+	SECONDARY_LOW
+}
+
+StringValues="BlendingLUT1TransferFunction" {
+	CONSTANT,
+	ALPHA_1,
+	ALPHA_2,
+	TABLE
+}
+
+StringValues="BlendingLUT2TransferFunction" {
+	CONSTANT,
+	ONE_MINUS,
+	ALPHA_1,
+	ALPHA_2,
+	TABLE
+}
+
+StringValues="DataPathID" {
+	PRIMARY,
+	SECONDARY
+}
+
+StringValues="RGBLUTTransferFunction" {
+	EQUAL_RGB,
+	TABLE
+}
+
+StringValues="AlphaLUTTransferFunction" {
+	NONE,
+	IDENTITY,
+	TABLE
+}
+
+StringValues="VolumeToTransducerRelationship" {
+	FIXED,
+	POSITION_VAR,
+	ORIENTATION_VAR,
+	VARIABLE
+}
+
+StringValues="VolumeToTransducerRelationshipFixed" {
+	FIXED
+}
+
+StringValues="BodyPartExaminedBreast" {
+	BREAST
+}
+
+StringValues="BreastCodeValue" {
+	T-04000
+}
+
+StringValues="BreastCodingSchemeDesignator" {
+	SRT
+}
+
+StringValues="BreastCodeMeaning" {
+	Breast
+}
+
+StringValues="CoronalCodeValue" {
+	G-A138
+}
+
+StringValues="CoronalCodingSchemeDesignator" {
+	SRT
+}
+
+StringValues="CoronalCodeMeaning" {
+	Coronal
+}
+
+StringValues="TransducerScanPatternCodeSequenceCodeValue" {
+	125242
+}
+
+StringValues="TransducerScanPatternCodeSequenceCodingSchemeDesignator" {
+	DCM
+}
+
+StringValues="TransducerScanPatternCodeSequenceCodeMeaning" {
+	Volume scan pattern
+}
+
+StringValues="TransducerGeometryCodeSequenceCodeValueForReflection" {
+	125253
+}
+
+StringValues="TransducerGeometryCodeSequenceCodeMeaningForReflection" {
+	Curved ultrasound transducer geometry
+}
+
+StringValues="TransducerGeometryCodeSequenceCodingSchemeDesignator" {
+	DCM
+}
+
+StringValues="TransducerGeometryCodeSequenceCodeValueForTransmission" {
+	125252
+}
+
+StringValues="TransducerGeometryCodeSequenceCodeMeaningForTransmission" {
+	Linear ultrasound transducer geometry
+}
+
+StringValues="TransducerBeamSteeringCodeSequenceCodeValue" {
+	125258
+}
+
+StringValues="TransducerBeamSteeringCodeSequenceCodingSchemeDesignator" {
+	DCM
+}
+
+StringValues="TransducerBeamSteeringCodeSequenceCodeMeaning" {
+	Mechanical beam steering
+}
+
+StringValues="TransducerApplicationCodeSequenceCodeValue" {
+	125261
+}
+
+StringValues="TransducerApplicationCodeSequenceCodingSchemeDesignator" {
+	DCM
+}
+
+StringValues="TransducerApplicationCodeSequenceCodeMeaning" {
+	External
+}
+
+StringValues="QTUSImageAndFrameTypeValue3" {
+	TISSUE_INTENSITY,
+	SOUND_SPEED,
+	ATTENUATION
+}
+
+StringValues="QTUSEnhancedUSVolumeDataType" {
+	TISSUE_INTENSITY,
+	SOUND_SPEED,
+	ATTENUATION
+}
+
+StringValues="EnhancedUSVolumeDataTypeTissueIntensity" {
+	TISSUE_INTENSITY
+}
+
+StringValues="EnhancedUSVolumeDataTypeAttenuation" {
+	ATTENUATION
+}
+
+StringValues="EnhancedUSVolumeDataTypeSoundSpeed" {
+	SOUND_SPEED
+}
+
+StringValues="QTUSImageAndFrameTypeValue3TissueIntensity" {
+	TISSUE_INTENSITY
+}
+
+StringValues="QTUSImageAndFrameTypeValue3Attenuation" {
+	ATTENUATION
+}
+
+StringValues="QTUSImageAndFrameTypeValue3SoundSpeed" {
+	SOUND_SPEED
+}
+
+StringValues="QTUSDimensionDescriptionLabel" {
+	time,
+	position,
+	data type
+}
+
+StringValues="QTUSRealWorldValueMappingLUTExplanation" {
+	Atten dB/m/MHz,
+	Speed Sound m/s,
+	Imp Mismatch dB
+}
+
+StringValues="QTUSRealWorldValueMappingLUTLabel" {
+	Atten dB/m/MHz,
+	Speed Sound m/s,
+	Imp Mismatch dB
+}
+
+StringValues="QTUSRealWorldValueMappingMeasurementUnitsCodeValue" {
+	dB/m/MHz,
+	m/s,
+	dB
+}
+
+StringValues="QTUSRealWorldValueMappingMeasurementUnitsCodeMeaning" {
+	dB/m/MHz,
+	m/s,
+	dB
+}
+
+StringValues="CodeValueForLOINCBreastUltrasound" {
+	24601-7
+}
+
+StringValues="CodeMeaningForLOINCBreastUltrasound" {
+	Breast US
+}
+
diff --git a/libsrc/standard/strval/vl.tpl b/libsrc/standard/strval/vl.tpl
new file mode 100755
index 0000000..2e49e95
--- /dev/null
+++ b/libsrc/standard/strval/vl.tpl
@@ -0,0 +1,223 @@
+StringValues="VLEndoscopyModality" {
+	ES
+}
+
+StringValues="VLMicroscopyModality" {
+	GM
+}
+
+StringValues="VLSlideCoordinatesMicroscopyModality" {
+	SM
+}
+
+StringValues="VLWholeSlideMicroscopyModality" {
+	SM
+}
+
+StringValues="VLPhotographyModality" {
+	XC
+}
+
+StringValues="VLImageType3" {
+	STEREO L,
+	STEREO R,
+	***EMPTYVALUE***
+}
+
+StringValues="PhotometricInterpretationMonochrome2OrRGBorYBRFULL422orYBRPARTIAL420orYBRRCTorYBRICT" {
+	MONOCHROME2,
+	YBR_PARTIAL_420,
+	YBR_FULL_422,
+	RGB,
+	YBR_RCT,
+	YBR_ICT
+}
+
+StringValues="PhotometricInterpretationMonochrome2OrRGBorYBRFULL422orYBRRCTorYBRICT" {
+	MONOCHROME2,
+	YBR_FULL_422,
+	RGB,
+	YBR_RCT,
+	YBR_ICT
+}
+
+StringValues="AcquisitionContextValueTypes" {
+	TEXT,
+	NUM,
+	CODE,
+	DATE,
+	TIME,
+	PNAME
+}
+
+StringValues="OphthalmologyModality" {
+	OP
+}
+
+StringValues="OphthalmologyImageType2" {
+	PRIMARY
+}
+
+StringValues="OphthalmologyImageType3IfDerived" {
+	MONTAGE
+}
+
+StringValues="OphthalmologyImageType4" {
+	COLOR,
+	REDFREE,
+	RED,
+	BLUE,
+	FA,
+	ICG
+}
+
+StringValues="OphthalmologyImageLaterality"	{
+	R = Right,
+	L = Left,
+	B = Both left and right
+}
+
+StringValues="OphthalmicRefractiveMeasurementLaterality"	{
+	R = Right,
+	L = Left,
+	B = Both left and right
+}
+
+StringValues="OphthalmologyDetectorType"	{
+	CCD,
+	CMOS
+}
+
+StringValues="StereometricModality" {
+	SMR
+}
+
+StringValues="OphthalmicTomographyModality" {
+	OPT
+}
+
+StringValues="OphthalmicTomographyDetectorType" {
+	CCD = Charge Coupled Device,
+	CMOS = Complementary Metal Oxide Semiconductor,
+	PHOTO = Photodetector,
+	INT = Interferometer
+}
+
+StringValues="OphthalmicImageOrientation" {
+	LINEAR,
+	NONLINEAR,
+	TRANSVERSE
+}
+
+
+StringValues="WholeSlideImageType1" {
+	ORIGINAL,
+	DERIVED
+}
+
+StringValues="WholeSlideImageType3" {
+	LOCALIZER,
+	VOLUME,
+	LABEL
+}
+
+StringValues="WholeSlideImageType4" {
+	NONE,
+	RESAMPLED
+}
+
+StringValues="VolumetricPropertiesVolume" {
+	VOLUME
+}
+
+StringValues="WholeSlideFocusMethod" {
+	AUTO,
+	MANUAL
+}
+
+StringValues="LocalizerDCMCodeValue" {
+	121311
+}
+
+StringValues="LensometryModality" {
+	LEN
+}
+
+StringValues="AutorefractionModality" {
+	AR
+}
+
+StringValues="SubjectiveRefractionModality" {
+	SRF
+}
+
+StringValues="VisualAcuityModality" {
+	VA
+}
+
+StringValues="OphthalmicAxialMeasurementsModality" {
+	OAM
+}
+
+StringValues="IntraocularLensCalculationsModality" {
+	IOL
+}
+
+StringValues="KeratometryModality" {
+	KER
+}
+
+StringValues="LensSegmentType" {
+	PROGRESSIVE,
+	NONPROGRESSIVE
+}
+
+StringValues="ViewingDistanceType" {
+	DISTANCE,
+	NEAR,
+	INTERMEDIATE,
+	OTHER
+}
+
+StringValues="VisualAcuityMeasurementsBackgroundColor" {
+	RED,
+	GREEN,
+	WHITE,
+	REDGREENSPLIT
+}
+
+StringValues="Optotype" {
+	LETTERS,
+	NUMBERS,
+	PICTURES,
+	TUMBLING E,
+	LANDOLT C
+}
+
+StringValues="OptotypePresentation" {
+	SINGLE,
+	MULTIPLE
+}
+
+StringValues="OphthalmicAxialMeasurementsDeviceType" {
+	ULTRASOUND,
+	OPTICAL
+}
+
+StringValues="OphthalmicAxialLengthMeasurementsType" {
+	TOTAL LENGTH = the total axial length was taken withone measurement,
+	LENGTH SUMMATION = a summation of segmental lengthsthat determine the total axial length,
+	SEGMENTAL LENGTH = a segmental axial length
+}
+
+StringValues="OphthalmicAxialMeasurementsObserverType" {
+	PSN = Person; manually selected,
+	DEV = Device; automatically selected
+}
+
+StringValues="OphthalmicAxialMeasurementsQualityImageSOPClassUIDs" {
+	1.2.840.10008.5.1.4.1.1.7.2 = Multi-frame Grayscale ByteSecondary Capture Image Storage,
+	1.2.840.10008.5.1.4.1.1.7.4 = Multi-frame True Color SecondaryCapture Image Storage
+}
+
+
diff --git a/libsrc/standard/strval/waveform.tpl b/libsrc/standard/strval/waveform.tpl
new file mode 100755
index 0000000..65de8c9
--- /dev/null
+++ b/libsrc/standard/strval/waveform.tpl
@@ -0,0 +1,58 @@
+StringValues="WaveformOriginality" {
+	ORIGINAL,
+	DERIVED
+}
+
+StringValues="ChannelStatus" {
+	OK,
+	TEST DATA,
+	DISCONNECTED,
+	QUESTIONABLE,
+	INVALID,
+	UNCALIBRATED,
+	UNZEROED
+}
+
+StringValues="WaveformSampleInterpretation" {
+	SB = signed 8 bit linear,
+	UB = unsigned 8 bit linear,
+	MB = 8 bit mu-law,
+	AB = 8 bit A-law,
+	SS = signed 16 bit linear,
+	US = unsigned 16 bit linear
+}
+
+StringValues="TemporalRangeTypeForWaveformAnnotation" {
+	POINT,
+	MULTIPOINT,
+	SEGMENT,
+	MULTISEGMENT,
+	BEGIN,
+	END
+}
+
+StringValues="SynchronizationTrigger" {
+	SOURCE,
+	EXTERNAL,
+	PASSTHRU,
+	NO TRIGGER
+}
+
+StringValues="SynchronizationTriggerNoTrigger" {
+	NO TRIGGER
+}
+
+StringValues="TimeDistributionProtocol" {
+	NTP  = Network Time Protocol,
+	IRIG = InterRange Instrument Group,
+	GPS  = Global Positioning System,
+	SNTP  = Simple Network Time Protocol
+}
+
+StringValues="DisplayShadingFlag" {
+	NONE,
+	BASELINE,
+	ABSOLUTE,
+	DIFFERENCE
+}
+
diff --git a/libsrc/standard/strval/xaxrf.tpl b/libsrc/standard/strval/xaxrf.tpl
new file mode 100755
index 0000000..ca14a2d
--- /dev/null
+++ b/libsrc/standard/strval/xaxrf.tpl
@@ -0,0 +1,271 @@
+StringValues="XRayFieldOfViewShape" {
+	ROUND,
+	RECTANGLE
+}
+
+StringValues="Grid" {
+	IN = Grid is positioned,
+	NONE = No Grid is used
+}
+
+StringValues="RadiationSetting" {
+	SC = low dose exposure for preparation,
+	GR = high dose exposure for diagnostic quality image acquisition
+}
+
+StringValues="XRayImageScanOptions" {
+	EKG = EKG Event Trigger,
+	PHY = Physiological Event Trigger,
+	TOMO = Tomography,
+	CHASE = Bolus Chasing,
+	STEP = Stepping,
+	ROTA = Rotation
+}
+
+StringValues="PhotometricInterpretationMonochrome2" {
+	MONOCHROME2
+}
+
+StringValues="PixelIntensityRelationship" {
+	LIN = Approximately proportional to X-Ray beam intensity,
+	LOG = Non-linear Log Function,
+	DISP = Ready to be displayed
+}
+
+StringValues="XRayImageTypeValue3" {
+	SINGLE PLANE = Image is a single plane acquisition,
+	BIPLANE A = Image is the first plane of a Bi-plane acquisition,
+	BIPLANE B = Image is the second plane of a Bi-plane acquisition,
+	BIPLANE = Image is both planes of a Bi-plane acquisition 
+}
+
+
+StringValues="InterventionStatus" {
+	PRE,
+	INTERMEDIATE,
+	POST,
+	NONE
+}
+
+StringValues="XADeviceCodingSchemeDesignators" {
+	99DEV = X-Ray Angiographic IOD Interim Intervention Device List,
+	99SDM = SNOMED DICOM Microglossary
+}
+
+StringValues="XATherapyCodingSchemeDesignators" {
+	99THR = X-Ray Angiographic IOD Interim Intervention Therapy List,
+	99SDM = SNOMED DICOM Microglossary
+}
+
+StringValues="XAAnatomyCodingSchemeDesignators" {
+	99ANA = X-Ray Angiographic IOD Interim Anatomic Term List,
+	99SDM = SNOMED DICOM Microglossary
+}
+
+StringValues="DeviceDiameterUnits" {
+	FR = French,
+	GA = Gauge,
+	IN = Inch,
+	MM = Millimeter
+}
+
+StringValues="ShutterShape" {
+	RECTANGULAR,
+	CIRCULAR,
+	POLYGONAL
+}
+
+StringValues="BitmapShutterShape" {
+	BITMAP
+}
+
+StringValues="CollimatorShape" {
+	RECTANGULAR,
+	CIRCULAR,
+	POLYGONAL
+}
+
+StringValues="MaskOperation" {
+	NONE = No Subtraction,
+	AVG_SUB = Average Subtraction,
+	TID = Time Interval Differencing
+	REV_TID = Reversed Time Interval Differencing
+}
+
+StringValues="RecommendedViewingMode" {
+	SUB = for subtraction with mask images,
+	NAT = native viewing of image as sent
+}
+
+StringValues="RadiationMode" {
+	CONTINUOUS,
+	PULSED
+}
+
+StringValues="MaskSelectionMode" {
+	SYSTEM,
+	USER
+}
+
+# enhanced XA/XRF stuff ...
+
+StringValues="EnhancedXAXRFModality" {
+	XA,
+	XRF
+}
+
+StringValues="EnhancedXAXRFImageType1" {
+	ORIGINAL,
+	DERIVED
+}
+
+StringValues="EnhancedXAXRFImageType2" {
+	PRIMARY,
+	SECONDARY
+}
+
+StringValues="EnhancedXAXRFImageType3" {
+	ANGIO,
+	CARDIAC,
+	CARDIAC_GATED,
+	CARDRESP_GATED,
+	DYNAMIC,
+	FLUOROSCOPY,
+	LOCALIZER,
+	MOTION,
+	PERFUSION,
+	PRE_CONTRAST,
+	POST_CONTRAST,
+	RESP_GATED,
+	REST,
+	STATIC,
+	STRESS,
+	VOLUME,
+	NON_PARALLEL,
+	PARALLEL,
+	WHOLE_BODY
+}
+
+
+StringValues="EnhancedXAXRFImageType4" {
+	NONE
+}
+
+StringValues="PlanesInAcquisition" {
+	SINGLE PLANE,
+	BIPLANE,
+	UNDEFINED
+}
+
+
+StringValues="PlaneIdentification" {
+	MONOPLANE,
+	PLANE A,
+	PLANE B
+}
+
+StringValues="EnhancedXAXRFScanOptions" {
+	TOMO,
+	CHASE,
+	STEP,
+	ROTA
+}
+
+StringValues="EnhancedXAXRFRadiationSetting" {
+	SC,
+	GR
+}
+
+StringValues="EnhancedXAXRFRadiationMode" {
+	CONTINUOUS,
+	PULSED
+}
+
+StringValues="XRayReceptorType" {
+	IMG_INTENSIFIER,
+	DIGITAL_DETECTOR
+}
+
+StringValues="XRayReceptorTypeAngio" {
+	IMG_INTENSIFIER,
+	DIGITAL_DETECTOR
+}
+
+StringValues="XRayReceptorTypeCranio" {
+	DIGITAL_DETECTOR
+}
+
+StringValues="EnhancedXAXRFPositionerType" {
+	CARM,
+	COLUMN
+}
+
+StringValues="IntensifierActiveShape" {
+	RECTANGLE,
+	ROUND,
+	HEXAGONAL
+}
+
+StringValues="FieldOfViewShape" {
+	RECTANGLE,
+	ROUND,
+	HEXAGONAL
+}
+
+StringValues="ExposureControlSensingRegionShape" {
+	RECTANGULAR,
+	CIRCULAR,
+	POLYGONAL
+}
+
+StringValues="XAXRFPixelIntensityRelationship" {
+	LIN,
+	LOG,
+	OTHER
+}
+
+StringValues="XAXRFGeometricalProperties" {
+	UNIFORM,
+	NON_UNIFORM
+}
+
+StringValues="XAXRFImageProcessingApplied" {
+	DIGITAL_SUBTR,
+	HIGH_PASS_FILTER,
+	LOW_PASS_FILTER,
+	MULTI_BAND_FLTR,
+	FRAME_AVERAGING,
+	NONE
+}
+
+StringValues="SkipFrameRangeFlag" {
+	DISPLAY,
+	SKIP
+}
+
+StringValues="XRay3DImageAndFrameType4" {
+	NONE
+}
+
+StringValues="XRay3DReconstructionAlgorithmType" {
+	FILTER_BACK_PROJ,
+	ITERATIVE
+}
+
+StringValues="PositionerMotionStatic" {
+	STATIC
+}
+
+StringValues="XRay3DImageVolumeBasedCalculationTechniqueImageLevel" {
+	MAX_IP,
+	MIN_IP,
+	VOLUME_RENDER,
+	SURFACE_RENDER,
+	MPR,
+	CURVED_MPR,
+	NONE,
+	MIXED,
+	TOMOSYNTHESIS
+}
+
+
diff --git a/libsrc/standard/tagval.tpl b/libsrc/standard/tagval.tpl
new file mode 100755
index 0000000..c8025cc
--- /dev/null
+++ b/libsrc/standard/tagval.tpl
@@ -0,0 +1,79 @@
+# should check these with data dictionary ?
+# should match with ImageType value 3 allowed combinations ?
+
+TagValues="NMFrameIncrementPointerValues" {
+	0x0054,0x0010 = Energy Window Vector,
+	0x0054,0x0020 = Detector Vector,
+	0x0054,0x0030 = Phase Vector,
+	0x0054,0x0050 = Rotation Vector,
+	0x0054,0x0060 = RR Interval Vector,
+	0x0054,0x0070 = Time Slot Vector,
+	0x0054,0x0080 = Slice Vector,
+	0x0054,0x0090 = Angular View Vector,
+	0x0054,0x0100 = Time Slice Vector
+}
+
+TagValues="XRayFrameIncrementPointerValues" {
+	0x0018,0x1063 = Frame Time,
+	0x0018,0x1065 = Frame Time Vector
+}
+
+TagValues="FrameIncrementPointerIsEnergyWindowVector" {
+	0x0054,0x0010 = Energy Window Vector
+}
+
+TagValues="FrameIncrementPointerIsDetectorVector" {
+	0x0054,0x0020 = Detector Vector
+}
+
+TagValues="FrameIncrementPointerIsPhaseVector" {
+	0x0054,0x0030 = Phase Vector
+}
+
+TagValues="FrameIncrementPointerIsRotationVector" {
+	0x0054,0x0050 = Rotation Vector
+}
+
+TagValues="FrameIncrementPointerIsRRIntervalVector" {
+	0x0054,0x0060 = RR Interval Vector
+}
+
+TagValues="FrameIncrementPointerIsTimeSlotVector" {
+	0x0054,0x0070 = Time Slot Vector
+}
+
+TagValues="FrameIncrementPointerIsSliceVector" {
+	0x0054,0x0080 = Slice Vector
+}
+
+TagValues="FrameIncrementPointerIsAngularViewVector" {
+	0x0054,0x0090 = Angular View Vector
+}
+
+TagValues="FrameIncrementPointerIsTimeSliceVector" {
+	0x0054,0x0100 = Time Slice Vector
+}
+
+TagValues="XAFrameDimensionPointerValues" {
+	0x0018,0x1063 = Frame Time, 
+	0x0018,0x1065 = Frame Time Vector,
+	0x0018,0x1520 = Positioner Primary Angle Increment,
+	0x0018,0x1521 = Positioner Secondary Angle Increment,
+	0x0018,0x1135 = Table Vertical Increment,
+	0x0018,0x1137 = Table Longitudinal Increment,
+	0x0018,0x1136 = Table Lateral Increment,
+	0x0018,0x2002 = Frame Label Vector
+}
+
+TagValues="QTUSDimensionOrganization3DDimensionIndexPointerValues" {
+	0x0020,0x930D = Temporal Position Time Offset,
+	0x0020,0x9301 = Image Position (Volume),
+	0x0018,0x9808 = Data Type,
+}
+
+TagValues="QTUSDimensionOrganization3DFunctionalGroupPointerValues" {
+	0x0020,0x9310 = Temporal Position Sequence,
+	0x0020,0x930E = Plane Position (Volume) Sequence,
+	0x0018,0x9807 = Image Data Type Sequence,
+}
+
diff --git a/libsrc/standard/transyn.tpl b/libsrc/standard/transyn.tpl
new file mode 100755
index 0000000..37c0c25
--- /dev/null
+++ b/libsrc/standard/transyn.tpl
@@ -0,0 +1,61 @@
+Name="ImplicitVRLittleEndian"	Desc="Implicit VR Little Endian"				Uid="1.2.840.10008.1.2"		Endian="little"	VR="implicit"	Encap="no"
+Name="Default"			Desc="Implicit VR Little Endian"				Uid="1.2.840.10008.1.2"		Endian="little"	VR="implicit"	Encap="no"
+Name="Command"			Desc="Implicit VR Little Endian"				Uid="1.2.840.10008.1.2"		Endian="little"	VR="implicit"	Encap="no"
+
+Name="Papyrus3"			Desc="Papyrus 3 Implicit VR Little Endian"			Uid="1.2.840.10008.1.20"	Endian="little"	VR="implicit"	Encap="no"
+
+Name="ExplicitVRLittleEndian"	Desc="Explicit VR Little Endian"				Uid="1.2.840.10008.1.2.1"	Endian="little" VR="explicit"	Encap="no"
+Name="MetaInformation"		Desc="Explicit VR Little Endian"				Uid="1.2.840.10008.1.2.1"	Endian="little" VR="explicit"	Encap="no"
+
+Name="ExplicitVRBigEndian"	Desc="Explicit VR Big Endian"					Uid="1.2.840.10008.1.2.2"	Endian="big" 	VR="explicit"	Encap="no"
+
+Name="JPEGProcess1"		Desc="JPEG Baseline"						Uid="1.2.840.10008.1.2.4.50"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess2_4"		Desc="JPEG Extended"						Uid="1.2.840.10008.1.2.4.51"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess3_5"		Desc="JPEG Extended"						Uid="1.2.840.10008.1.2.4.52"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess6_8"		Desc="JPEG Spectral Selection, Non-hierarchical"		Uid="1.2.840.10008.1.2.4.53"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess7_9"		Desc="JPEG Spectral Selection, Non-hierarchical"		Uid="1.2.840.10008.1.2.4.54"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess10_12"		Desc="JPEG Full Progression, Non-hierarchical"			Uid="1.2.840.10008.1.2.4.55"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess11_13"		Desc="JPEG Full Progression, Non-hierarchical"			Uid="1.2.840.10008.1.2.4.56"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess14"		Desc="JPEG Lossless, Non-hierarchical"				Uid="1.2.840.10008.1.2.4.57"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess15"		Desc="JPEG Lossless, Non-hierarchical"				Uid="1.2.840.10008.1.2.4.58"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess16_18"		Desc="JPEG Extended, Hierarchical"				Uid="1.2.840.10008.1.2.4.59"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess17_19"		Desc="JPEG Extended, Hierarchical"				Uid="1.2.840.10008.1.2.4.60"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess20_22"		Desc="JPEG Spectral Selection, Hierarchical"			Uid="1.2.840.10008.1.2.4.61"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess21_23"		Desc="JPEG Spectral Selection, Hierarchical"			Uid="1.2.840.10008.1.2.4.62"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess24_26"		Desc="JPEG Full Progression, Hierarchical"			Uid="1.2.840.10008.1.2.4.63"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess25_27"		Desc="JPEG Full Progression, Hierarchical"			Uid="1.2.840.10008.1.2.4.64"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess28"		Desc="JPEG Lossless, Hierarchical"				Uid="1.2.840.10008.1.2.4.65"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess29"		Desc="JPEG Lossless, Hierarchical"				Uid="1.2.840.10008.1.2.4.66"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGProcess14SV1"		Desc="JPEG Lossless, Non-hierarchical, 1st Order Prediction"	Uid="1.2.840.10008.1.2.4.70"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="JPEGLSLossless"		Desc="JPEG-LS Lossless"						Uid="1.2.840.10008.1.2.4.80"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEGLSNearLossless"	Desc="JPEG-LS Near-Lossless"					Uid="1.2.840.10008.1.2.4.81"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="JPEG2000Lossless"		Desc="JPEG 2000 Lossless Only"					Uid="1.2.840.10008.1.2.4.90"	Endian="little" VR="explicit"	Encap="yes"
+Name="JPEG2000"			Desc="JPEG 2000"						Uid="1.2.840.10008.1.2.4.91"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="MPEG2MPML"		Desc="MPEG2 Main Profile @ Main Level"				Uid="1.2.840.10008.1.2.4.100"	Endian="little" VR="explicit"	Encap="yes"
+Name="MPEG2MPHL"		Desc="MPEG2 Main Profile @ High Level"				Uid="1.2.840.10008.1.2.4.101"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="MPEG4HP41"		Desc="MPEG-4 AVC/H.264 High Profile/Level 4.1"					Uid="1.2.840.10008.1.2.4.102"	Endian="little" VR="explicit"	Encap="yes"
+Name="MPEG4HP41BD"		Desc="MPEG-4 AVC/H.264 BD-compatible High Profile/Level 4.1"	Uid="1.2.840.10008.1.2.4.103"	Endian="little" VR="explicit"	Encap="yes"
+Name="MPEG4HP422D"		Desc="MPEG-4 AVC/H.264 High Profile / Level 4.2 For 2D Video"	Uid="1.2.840.10008.1.2.4.104"	Endian="little" VR="explicit"	Encap="yes"
+Name="MPEG4HP423D"		Desc="MPEG-4 AVC/H.264 High Profile / Level 4.2 For 3D Video"	Uid="1.2.840.10008.1.2.4.105"	Endian="little" VR="explicit"	Encap="yes"
+Name="MPEG4HP42ST"		Desc="MPEG-4 AVC/H.264 Stereo High Profile / Level 4.2"			Uid="1.2.840.10008.1.2.4.106"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="RLELossless"		Desc="RLE Lossless"						Uid="1.2.840.10008.1.2.5"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="GEImplicitVRLEExceptBEPixels" Desc="GE Implicit VR Little Endian Except Big Endian Pixels" Uid="1.2.840.113619.5.2"	Endian="little"	VR="implicit"	Encap="no"	Pixel="big"
+
+Name="DeflatedExplicitVRLittleEndian"	Desc="Deflated Explicit VR Little Endian"		Uid="1.2.840.10008.1.2.1.99"	Endian="little" VR="explicit"	Encap="no"
+
+Name="PixelMedBzip2ExplicitVRLittleEndian"	Desc="PixelMed Bzip2 Explicit VR Little Endian"	Uid="1.3.6.1.4.1.5962.300.1"	Endian="little" VR="explicit"	Encap="no"
+Name="PixelMedEncapsulatedRawLittleEndian"	Desc="PixelMed Encapsulated Raw Little Endian"	Uid="1.3.6.1.4.1.5962.300.2"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="AlgotecCompressed"	Desc="Algotec Compressed"				Uid="1.2.840.113704.7.0.4.4"	Endian="little" VR="explicit"	Encap="no"
+Name="ALIWavelet"			Desc="ALI Wavelet"						Uid="1.2.840.113711.1.2.100.1"	Endian="little" VR="explicit"	Encap="yes"
+
+Name="SectraCompression"	Desc="Sectra Compression"				Uid="1.2.752.24.3.7.6"	Endian="little" VR="explicit"	Encap="yes"
+Name="SectraCompressionLS"	Desc="Sectra Compression LS"			Uid="1.2.752.24.3.7.7"	Endian="little" VR="explicit"	Encap="yes"
+
+
diff --git a/libsrc/standard/vxtldict.txt b/libsrc/standard/vxtldict.txt
new file mode 100755
index 0000000..0a2d156
--- /dev/null
+++ b/libsrc/standard/vxtldict.txt
@@ -0,0 +1,74 @@
+(0019,0039) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="AxialType"				Name="Axial Type"
+(0019,008F) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="SwapPhaseFrequencyAxis"		Name="Swap Phase Frequency Axis"
+(0019,009C) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PulseSequenceName"			Name="Pulse Sequence Name"
+(0019,009F) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="CoilType"				Name="Coil Type"
+(0019,00A4) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="SAT"					Name="SAT"
+(0019,00C0) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="BitmapOfSATSelections"			Name="Bitmap Of SAT Selections"
+(0019,00C1) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="SurfaceCoilIntensityCorrectionFlag"	Name="Surface Coil Intensity Correction Flag"
+(0019,00CB) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PhaseContrastFlowAxis"			Name="Phase Contrast Flow Axis"
+(0019,00CC) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PhaseContrastVelocityEncoding"		Name="Phase Contrast Velocity Encoding"
+(0019,00D5) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="FractionalEcho"			Name="Fractional Echo"
+(0019,00D8) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="VariableEchoFlag"			Name="Variable Echo Flag"
+(0019,00D9) VERS="GEM"  VR="DS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="ConcatenatedSat"			Name="Concatenated Sat"
+(0019,00F2) VERS="GEM"  VR="SS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="NumberOfPhases"			Name="Number Of Phases"
+
+(0039,0080) VERS="GEM"  VR="IS"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityNumber"			Name="Private Entity Number"
+(0039,0085) VERS="GEM"  VR="DA"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityDate"			Name="Private Entity Date"
+(0039,0090) VERS="GEM"  VR="TM"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityTime"			Name="Private Entity Time"
+(0039,0095) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityLaunchCommand"		Name="Private Entity Launch Command"
+(0039,00AA) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_ADWSoft_DPO"	Keyword="PrivateEntityType"			Name="Private Entity Type"
+(0043,001E) VERS="GEM"  VR="DS"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="DeltaStartTime"			Name="Delta Start Time"
+(0043,0027) VERS="GEM"  VR="SH"   VM="1"	Owner="GE_GENESIS_REV3.0"	Keyword="PitchRatio"				Name="Pitch Ratio"
+
+(0047,0001) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="Reconstruction Parameters Sequence"	Name="Reconstruction Parameters Sequence"
+(0047,0050) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeVoxelCount"			Name="Volume Voxel Count"
+(0047,0051) VERS="GEM"  VR="UL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSegmentCount"			Name="Volume Segment Count"
+(0047,0053) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSliceSize"			Name="Volume Slice Size"
+(0047,0054) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSliceCount"			Name="Volume Slice Count"
+(0047,0055) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeThresholdValue"			Name="Volume Threshold Value"
+(0047,0057) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeVoxelRatio"			Name="Volume Voxel Ratio"
+(0047,0058) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeVoxelSize"			Name="Volume Voxel Size"
+(0047,0059) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeZPositionSize"			Name="Volume Z Position Size"
+(0047,0060) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeBaseLine"			Name="Volume Base Line"
+(0047,0061) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeCenterPoint"			Name="Volume Center Point"
+(0047,0063) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSkewBase"			Name="Volume Skew Base"
+(0047,0064) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeRegistrationTransformRotationMatrix"	Name="Volume Registration Transform Rotation Matrix"
+(0047,0065) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeRegistrationTransformTranslationVector"	Name="Volume Registration Transform Translation Vector"
+(0047,0070) VERS="GEM"  VR="DS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="KVPList"				Name="KVP List"
+(0047,0071) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="XRayTubeCurrentList"			Name="XRay Tube Current List"
+(0047,0072) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="ExposureList"				Name="Exposure List"
+(0047,0080) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="AcquisitionDLXIdentifier"		Name="Acquisition DLX Identifier"
+(0047,0085) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="AcquisitionDLX2DSeriesSequence"	Name="Acquisition DLX 2D Series Sequence"
+(0047,0089) VERS="GEM"  VR="DS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="ContrastAgentVolumeList"		Name="Contrast Agent Volume List"
+(0047,008A) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="NumberOfInjections"			Name="Number Of Injections"
+(0047,008B) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="FrameCount"				Name="Frame Count"
+(0047,0096) VERS="GEM"  VR="IS"   VM="1-n"	Owner="GEMS_ADWSoft_3D1"	Keyword="UsedFrames"				Name="Used Frames"
+(0047,0091) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="XA3DReconstructionAlgorithmName"	Name="XA 3D Reconstruction Algorithm Name"
+(0047,0092) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="XA3DReconstructionAlgorithmVersion"	Name="XA 3D Reconstruction Algorithm Version"
+(0047,0093) VERS="GEM"  VR="DA"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="DLXCalibrationDate"			Name="DLX Calibration Date"
+(0047,0094) VERS="GEM"  VR="TM"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="DLXCalibrationTime"			Name="DLX Calibration Time"
+(0047,0095) VERS="GEM"  VR="CS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="DLXCalibrationStatus"			Name="DLX Calibration Status"
+(0047,0098) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformCount"			Name="Transform Count"
+(0047,0099) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformSequence"			Name="Transform Sequence"
+(0047,009A) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformRotationMatrix"		Name="Transform Rotation Matrix"
+(0047,009B) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformTranslationVector"		Name="Transform Translation Vector"
+(0047,009C) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="TransformLabel"			Name="Transform Label"
+(0047,00B1) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeCount"			Name="Wireframe Count"
+(0047,00B2) VERS="GEM"  VR="US"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="LocationSystem"			Name="Location System"
+(0047,00B0) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeList"				Name="Wireframe List"
+(0047,00B5) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeName"				Name="Wireframe Name"
+(0047,00B6) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeGroupName"			Name="Wireframe Group Name"
+(0047,00B7) VERS="GEM"  VR="LO"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeColor"			Name="Wireframe Color"
+(0047,00B8) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeAttributes"			Name="Wireframe Attributes"
+(0047,00B9) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframePointCount"			Name="Wireframe Point Count"
+(0047,00BA) VERS="GEM"  VR="SL"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframeTimestamp"			Name="Wireframe Timestamp"
+(0047,00BB) VERS="GEM"  VR="SQ"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframePointList"			Name="Wireframe Point List"
+(0047,00BC) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="WireframePointsCoordinates"		Name="Wireframe Points Coordinates"
+(0047,00C0) VERS="GEM"  VR="DS"   VM="3"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeUpperLeftHighCornerRAS"		Name="Volume Upper Left High Corner RAS"
+(0047,00C1) VERS="GEM"  VR="DS"   VM="9"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSliceToRASRotationMatrix"	Name="Volume Slice To RAS Rotation Matrix"
+(0047,00C2) VERS="GEM"  VR="DS"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeUpperLeftHighCornerTLOC"		Name="Volume Upper Left High Corner TLOC"
+(0047,00D1) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeSegmentList"			Name="Volume Segment List"
+(0047,00D2) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeGradientList"			Name="Volume Gradient List"
+(0047,00D3) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeDensityList"			Name="Volume Density List"
+(0047,00D4) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeZPositionList"			Name="Volume Z Position List"
+(0047,00D5) VERS="GEM"  VR="OB"   VM="1"	Owner="GEMS_ADWSoft_3D1"	Keyword="VolumeOriginalIndexList"		Name="Volume Original Index List"
diff --git a/libsrc/support/DicomDictionary_header.txt b/libsrc/support/DicomDictionary_header.txt
new file mode 100755
index 0000000..7b855e9
--- /dev/null
+++ b/libsrc/support/DicomDictionary_header.txt
@@ -0,0 +1,24 @@
+/* Copyright (c) 2001-2007, David A. Clunie DBA Pixelmed Publishing. All rights reserved. */
+
+// Automatically generated from template - EDITS WILL BE LOST
+
+package com.pixelmed.dicom;
+
+import java.util.HashMap;
+import java.util.TreeSet;
+import java.util.Iterator;
+
+/**
+ * <p>The {@link com.pixelmed.dicom.DicomDictionary DicomDictionary} class
+ * is a complete standard dictionary of DICOM attributes and associated information.</p>
+ *
+ * <p>The accessor methods that an application would normally use are defined in the
+ * {@link com.pixelmed.dicom.DicomDictionaryBase DicomDictionaryBase} class.</p>
+ *
+ * @author	dclunie
+ */
+
+public class DicomDictionary extends DicomDictionaryBase {
+
+	private static final String identString = "@(#) $Header: /userland/cvs/dicom3tools/libsrc/support/DicomDictionary_header.txt,v 1.1 2007/03/21 22:12:34 dclunie Exp $";
+
diff --git a/libsrc/support/DicomDictionary_trailer.txt b/libsrc/support/DicomDictionary_trailer.txt
new file mode 100755
index 0000000..5c34318
--- /dev/null
+++ b/libsrc/support/DicomDictionary_trailer.txt
@@ -0,0 +1 @@
+}
diff --git a/libsrc/support/Imakefile b/libsrc/support/Imakefile
new file mode 100755
index 0000000..e69de29
diff --git a/libsrc/support/binval.awk b/libsrc/support/binval.awk
new file mode 100644
index 0000000..6ccfcd0
--- /dev/null
+++ b/libsrc/support/binval.awk
@@ -0,0 +1,196 @@
+#  binval.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from binary values template 
+
+# can set these values on the command line:
+#
+#	role	  - either "declare" or "define"
+
+# 970706 Change \'\\0\' to ends for HPUX awk which outputs the \
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by binval.awk with options " role " " outname
+	print ""
+
+	if (role == "declare" || role == "define") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	mode=""
+	}
+
+/^[ 	]*BinaryBitMap/ {
+	name=""
+	if (match($0,"BinaryBitMap=\"[^\"]*\""))
+		name=substr($0,RSTART+length("BinaryBitMap=\""),
+			RLENGTH-length("BinaryBitMap=\"")-1);
+	mode="bitmap"
+
+	if (role == "declare") {
+		print "char *\tBinaryBitMapDescription_" name "(Uint16 value);"
+	}
+	else if (role == "define") {
+		print "char *"
+		print "BinaryBitMapDescription_" name "(Uint16 value)"
+		print "{"
+		print "\tUint16 validmask=0;"
+		print "\tostrstream ost;"
+	}
+
+	}
+
+/^[ 	]*BinaryValues/ {
+	name=""
+	if (match($0,"BinaryValues=\"[^\"]*\""))
+		name=substr($0,RSTART+length("BinaryValues=\""),
+			RLENGTH-length("BinaryValues=\"")-1);
+	mode="values"
+
+	if (role == "declare") {
+		print "char *\tBinaryValueDescription_" name "(Uint16 value);"
+	}
+	else if (role == "define") {
+		print "char *"
+		print "BinaryValueDescription_" name "(Uint16 value)"
+		print "{"
+		print "\tostrstream ost;"
+		print "\tswitch (value) {"
+	}
+
+	}
+
+/^[ 	]*[0-9]/ {
+
+	if (mode == "values") {
+		valueline=$0
+		if (!match(valueline,"[0-9][x0-9a-fA-F]*")) {
+			print "Line " FNR \
+				": error in value line - no code <" \
+				valueline ">" >"/dev/tty"
+			next
+		}
+		code=substr(valueline,RSTART,RLENGTH)
+		valueline=substr(valueline,RSTART+RLENGTH)
+		if (match(valueline,"[ 	]*=[ 	]*")) {
+			meaning=substr(valueline,RSTART+RLENGTH)
+			if (match(meaning,"[ 	]*,*[ 	]*$")) {
+				meaning=substr(meaning,0,RSTART-1)
+			}
+		}
+		else {
+			meaning=code
+		}
+
+		if (role == "define") {
+			print "\t\tcase " code ":"
+			print "\t\t\tost << \"" meaning "\" << ends;"
+			print "\t\t\treturn ost.str();"
+		}
+	}
+	else if (mode == "bitmap") {
+		valueline=$0
+		if (!match(valueline,"[0-9][x0-9a-f]*")) {
+			print "Line " FNR \
+				": error in value line - no bit number <" \
+				valueline ">" >"/dev/tty"
+			next
+		}
+		bitnumber=substr(valueline,RSTART,RLENGTH)
+		valueline=substr(valueline,RSTART+RLENGTH)
+
+		if (match(valueline,"[ 	]*=[ 	]*")) {
+			meaning=substr(valueline,RSTART+RLENGTH)
+			if (match(meaning,"[ 	]*[:]")) {
+				meaning=substr(meaning,0,RSTART-1)
+			}
+		}
+		else {
+			meaning=bitnumber
+		}
+
+		if (match(valueline,"[ 	]*:[ 	]*")) {
+			falsevalue=substr(valueline,RSTART+RLENGTH)
+			if (match(falsevalue,"[ 	]*[,]")) {
+				falsevalue=substr(falsevalue,0,RSTART-1)
+			}
+			else {
+				print "Line " FNR \
+					": error in bitmap - bad false value <" \
+					valueline ">" >"/dev/tty"
+				falsevalue=""
+			}
+		}
+		else {
+			print "Line " FNR \
+				": error in bitmap - no false value <" \
+				valueline ">" >"/dev/tty"
+			falsevalue=""
+		}
+
+		if (match(valueline,"[ 	]*,[ 	]*")) {
+			truevalue=substr(valueline,RSTART+RLENGTH)
+			if (match(truevalue,"[ 	]*(;|$)")) {
+				truevalue=substr(truevalue,0,RSTART-1)
+			}
+			else {
+				print "Line " FNR \
+					": error in bitmap - bad true value <" \
+					valueline ">" >"/dev/tty"
+				truevalue=""
+			}
+		}
+		else {
+			print "Line " FNR \
+				": error in bitmap - no true value <" \
+				valueline ">" >"/dev/tty"
+			truevalue=""
+		}
+
+		if (role == "define") {
+			print "\t{"
+			print "\t\tvalidmask|=(1<<" bitnumber ");"
+			print "\t\tUint16 bitvalue=value&(1<<" bitnumber ");"
+			print "\t\tost << \"" meaning "(\" << (bitvalue ? \"" truevalue "\" : \"" falsevalue "\") << \") \" << ends;"
+			print "\t}"
+		}
+	}
+	else {
+		print "Line " FNR ": error - no group name" >"/dev/tty"
+	}
+
+	}
+
+/^[ 	]*}/ {
+	if (role == "define" && mode == "bitmap") {
+		print "\tif (value&~validmask)"
+		print "\t\treturn 0;"
+		print "\telse"
+		print "\t\treturn ost.str();"
+		print "}"
+		print ""
+	}
+	else if (role == "define" && mode == "values") {
+		print "\t\tdefault:"
+		print "\t\t\treturn 0;"
+		print "\t}"
+		print "}"
+		print ""
+	}
+
+	mode=""
+	}
+
+END {
+	if (role == "declare" || role == "define") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/canonicalizespacinginelmdict.sed b/libsrc/support/canonicalizespacinginelmdict.sed
new file mode 100644
index 0000000..3690575
--- /dev/null
+++ b/libsrc/support/canonicalizespacinginelmdict.sed
@@ -0,0 +1 @@
+s/\([(][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f],[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][)]\)[ 	]*\(VERS="[^"]*"\)[ 	]*\(VR="[^"]*"\)[ 	]*\(VM="[^"]*"\)[ 	]*\(Owner="[^"]*"\)[ 	]*\(Keyword="[^"]*"\)[ 	]*\(Name="[^"]*"\)/\1	\2	\3	\4	\5	\6	\7/
\ No newline at end of file
diff --git a/libsrc/support/cleanelm.awk b/libsrc/support/cleanelm.awk
new file mode 100644
index 0000000..ebd1936
--- /dev/null
+++ b/libsrc/support/cleanelm.awk
@@ -0,0 +1,67 @@
+#  cleanelm.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+/^\([0-9A-Fa-fxX]/ {
+
+	element=$1
+
+	owner=""
+	if (match($0,"Owner=\"[^\"]*\""))
+		owner=substr($0,RSTART+length("Owner=\""),
+			RLENGTH-length("Owner=\"")-1);
+
+	keyword=""
+	if (match($0,"Keyword=\"[^\"]*\""))
+		keyword=substr($0,RSTART+length("Keyword=\""),
+			RLENGTH-length("Keyword=\"")-1);
+
+	name=""
+	if (match($0,"Name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+
+	vers=""
+	if (match($0,"VERS=\"[^\"]*\""))
+		vers=substr($0,RSTART+length("VERS=\""),
+			RLENGTH-length("VERS=\"")-1);
+
+	vr=""
+	if (match($0,"VR=\"[^\"]*\""))
+		vr=substr($0,RSTART+length("VR=\""),
+			RLENGTH-length("VR=\"")-1);
+
+	vm=""
+	if (match($0,"VM=\"[^\"]*\""))
+		vm=substr($0,RSTART+length("VM=\""),
+			RLENGTH-length("VM=\"")-1);
+
+	units=""
+	if (match($0,"Units=\"[^\"]*\""))
+		units=substr($0,RSTART+length("Units=\""),
+			RLENGTH-length("Units=\"")-1);
+
+	definedterms=""
+	if (match($0,"DefinedTerms=\"[^\"]*\""))
+		definedterms=substr($0,RSTART+length("DefinedTerms=\""),
+			RLENGTH-length("DefinedTerms=\"")-1);
+
+	enumeratedvalues=""
+	if (match($0,"EnumeratedValues=\"[^\"]*\""))
+		enumeratedvalues=substr($0,RSTART+length("EnumeratedValues=\""),
+			RLENGTH-length("EnumeratedValues=\"")-1);
+
+	privateblock=""
+	if (match($0,"PrivateBlock=\"[^\"]*\""))
+		privateblock=substr($0,RSTART+length("PrivateBlock=\""),
+			RLENGTH-length("PrivateBlock=\"")-1);
+
+	extras=""
+	if (units != "") extras=extras "\tUnits=\"" units "\""
+	if (privateblock != "") extras=extras "\tPrivateBlock=\"" privateblock "\""
+	if (definedterms != "") extras=extras "\tDefinedTerms=\"" definedterms "\""
+	if (enumeratedvalues != "") extras=extras "\tEnumeratedValues=\"" enumeratedvalues "\""
+
+	ownertoprint=""
+	if (owner != "") ownertoprint="\tOwner=\"" owner "\""
+
+	print element " VERS=\"" vers "\"\tVR=\"" vr "\"   VM=\"" vm "\"" ownertoprint "\tKeyword=\"" keyword "\"\t\t\tName=\"" name "\"" extras
+}
+
diff --git a/libsrc/support/condn.awk b/libsrc/support/condn.awk
new file mode 100644
index 0000000..cfaf413
--- /dev/null
+++ b/libsrc/support/condn.awk
@@ -0,0 +1,432 @@
+#  condn.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from conditions template 
+
+# can set these values on the command line:
+#
+#	role	  - either "declare" or "define"
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by condn.awk with options " role " " outname
+	print ""
+
+	# Never and Always need to be callable as functions ...
+
+	if (role == "declare" || role == "define") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	if (role == "declare") {
+		print "bool Condition_Never(AttributeList *list,AttributeList *parentlist=0,AttributeList *rootlist=0);"
+		print "bool Condition_Always(AttributeList *list,AttributeList *parentlist=0,AttributeList *rootlist=0);"
+		print ""
+	}
+	else if (role == "define") {
+		print "bool Condition_Never(AttributeList *list,AttributeList *parentlist,AttributeList *rootlist)  { (void)list; (void)parentlist; return false; }"
+		print "bool Condition_Always(AttributeList *list,AttributeList *parentlist,AttributeList *rootlist) { (void)list; (void)parentlist; return true; }"
+		print ""
+	}
+
+	condition=""
+	}
+
+/^[ 	]*Condition=/ {
+
+	condition=""
+	if (match($0,"Condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("Condition=\""),
+			RLENGTH-length("Condition=\"")-1);
+
+	if (role == "declare") {
+		print "bool	Condition_" condition "(AttributeList *list,AttributeList *parentlist=0,AttributeList *rootlist=0);"
+	}
+	else if (role == "define") {
+		nestinglevel=0
+		print "bool"
+		print "Condition_" condition "(AttributeList *list,AttributeList *parentlist,AttributeList *rootlist)"
+		print "{"
+		print "\tint condition" nestinglevel " =0;"
+		print "\t(void)list;"
+		print "\t(void)parentlist;"
+		print "\t(void)rootlist;"
+		print ""
+	}
+
+	}
+
+/^[ 	]*ConditionEnd/ {
+
+	if (role == "define") {
+		print ""
+		print "\treturn (condition" nestinglevel " & 1) != 0;"
+		print "}"
+		print ""
+	}
+	condition=""
+
+	}
+
+/^[ 	]*Element/ {
+
+	element=""
+	if (match($0,"Element=\"[^\"]*\""))
+		element=substr($0,RSTART+length("Element=\""),
+			RLENGTH-length("Element=\"")-1);
+
+	operator=""
+	if (match($0,"Operator=\"[^\"]*\""))
+		operator=substr($0,RSTART+length("Operator=\""),
+			RLENGTH-length("Operator=\"")-1);
+
+	if (operator == "or" || operator == "Or" || operator == "|" || operator == "||") {
+		operator="|"
+	}
+	else if (operator == "xor" || operator == "Xor" || operator == "^") {
+		operator="^"
+	}
+	else if (operator == "and" || operator == "And" || operator == "&" || operator == "&&") {
+		operator="&"
+	}
+	else if (length(operator) == 0) {
+		operator="|"
+	}
+	else {
+		print "Error - Operator \"" operator "\" invalid, assuming or, at line" FNR >"/dev/tty"
+	}
+
+	modifier=""
+	if (match($0,"Modifier=\"[^\"]*\""))
+		modifier=substr($0,RSTART+length("Modifier=\""),
+			RLENGTH-length("Modifier=\"")-1);
+
+	if (modifier == "not" || modifier == "Not" || modifier == "~" || modifier == "!") {
+		modifier="~"
+	}
+	else if (length(modifier) == 0) {
+		modifier=""
+	}
+	else {
+		print "Error - Modifier \"" modifier "\" invalid, assuming none, at line" FNR >"/dev/tty"
+	}
+
+	selector=""
+	if (match($0,"ValueSelector=\"[^\"]*\""))
+		selector=substr($0,RSTART+length("ValueSelector=\""),
+			RLENGTH-length("ValueSelector=\"")-1);
+
+	if (length(selector) == 0) {
+		selector="-1"		# default is wildcard not 1st value !
+	}
+	else if (selector == "*") {
+		selector="-1"		# wildcard
+	}
+
+	valuepresent=0
+	if (match($0,"ValuePresent=\"[^\"]*\"")) {
+		valuepresent=1
+	}
+	
+	elementpresent=0
+	elementpresentmask=""
+	if (match($0,"ElementPresent=\"[^\"]*\"")) {
+		elementpresent=1;
+		elementpresentmask=substr($0,RSTART+length("ElementPresent=\""),
+			RLENGTH-length("ElementPresent=\"")-1);
+	}
+
+	elementpresentabove=0
+	if (match($0,"ElementPresentAbove=\"[^\"]*\"")) {
+		elementpresentabove=1;
+	}
+
+	elementpresentinroot=0
+	if (match($0,"ElementPresentInRoot=\"[^\"]*\"")) {
+		elementpresentinroot=1;
+	}
+
+	elementpresentwithin=0
+	elementpresentwithinsequence=""
+	if (match($0,"ElementPresentWithin=\"[^\"]*\"")) {
+		elementpresentwithin=1;
+		elementpresentwithinsequence=substr($0,RSTART+length("ElementPresentWithin=\""),
+			RLENGTH-length("ElementPresentWithin=\"")-1);
+	}
+
+	elementpresentinpath=0
+	elementpresentinpathfromroot=""
+	if (match($0,"ElementPresentInPathFromRoot=\"[^\"]*\"")) {
+		elementpresentinpath=1;
+		elementpresentinpathfromroot=substr($0,RSTART+length("ElementPresentInPathFromRoot=\""),
+			RLENGTH-length("ElementPresentInPathFromRoot=\"")-1);
+	}
+
+	grouppresent=0;
+	grouppresentmask=""
+	if (match($0,"GroupPresent=\"[^\"]*\"")) {
+		grouppresent=1;
+		grouppresentmask=substr($0,RSTART+length("GroupPresent=\""),
+			RLENGTH-length("GroupPresent=\"")-1);
+	}
+
+	stringconstant=""
+	stringconstantused=0
+	if (match($0,"StringConstant=\"[^\"]*\"")) {
+		stringconstantused=1
+		stringconstant=substr($0,RSTART+length("StringConstant=\""),
+			RLENGTH-length("StringConstant=\"")-1);
+	}
+	
+	stringconstantfromrootattribute=""
+	stringconstantfromrootattributeused=0
+	if (match($0,"StringConstantFromRootAttribute=\"[^\"]*\"")) {
+		stringconstantfromrootattributeused=1
+		stringconstantfromrootattribute=substr($0,RSTART+length("StringConstantFromRootAttribute=\""),
+			RLENGTH-length("StringConstantFromRootAttribute=\"")-1);
+	}
+
+	stringvalue=""
+	stringvalueused=0
+	if (match($0,"StringValue=\"[^\"]*\"")) {
+		stringvalueused=1
+		stringvalue=substr($0,RSTART+length("StringValue=\""),
+			RLENGTH-length("StringValue=\"")-1);
+	}
+	
+	stringvalueabove=""
+	stringvalueaboveused=0
+	if (match($0,"StringValueAbove=\"[^\"]*\"")) {
+		stringvalueaboveused=1
+		stringvalueabove=substr($0,RSTART+length("StringValueAbove=\""),
+			RLENGTH-length("StringValueAbove=\"")-1);
+	}
+	
+	stringvaluefromrootattribute=""
+	stringvaluefromrootattributeused=0
+	if (match($0,"StringValueFromRootAttribute=\"[^\"]*\"")) {
+		stringvaluefromrootattributeused=1
+		stringvaluefromrootattribute=substr($0,RSTART+length("StringValueFromRootAttribute=\""),
+			RLENGTH-length("StringValueFromRootAttribute=\"")-1);
+	}
+
+	binaryvalue=""
+	binaryvaluematchoperator=""
+	if (match($0,"BinaryValue=\"[^\"]*\"")) {
+		binaryvaluewithoperator=substr($0,RSTART+length("BinaryValue=\""),
+			RLENGTH-length("BinaryValue=\"")-1);
+		# e.g., "== 1" ; "< 367"
+		spacestart=index(binaryvaluewithoperator," "); # 3 ; 2
+		binaryvalue=substr(binaryvaluewithoperator,spacestart+1,length(binaryvaluewithoperator)-spacestart);	# 4, 4-3=1 ; 3, 5-2=3
+		matchoperatorstring=substr(binaryvaluewithoperator,1,spacestart-1);	# 1,2 ; 1,1
+		if (matchoperatorstring == "==") binaryvaluematchoperator = "Equals"
+		else if (matchoperatorstring == "!=") binaryvaluematchoperator = "NotEquals"
+		else if (matchoperatorstring == "<") binaryvaluematchoperator = "LessThan"
+		else if (matchoperatorstring == "<=") binaryvaluematchoperator = "LessThanOrEquals"
+		else if (matchoperatorstring == ">") binaryvaluematchoperator = "GreaterThan"
+		else if (matchoperatorstring == ">=") binaryvaluematchoperator = "GreaterThanOrEquals"
+		else print "Error - Binary Match Operator \"" matchoperatorstring "\" invalid at line" FNR >"/dev/tty"
+	}
+
+	binaryvaluefromrootattribute=""
+	binaryvaluematchoperatorfromrootattribute=""
+	if (match($0,"BinaryValueFromRootAttribute=\"[^\"]*\"")) {
+		binaryvaluewithoperator=substr($0,RSTART+length("BinaryValueFromRootAttribute=\""),
+			RLENGTH-length("BinaryValueFromRootAttribute=\"")-1);
+		# e.g., "== 1" ; "< 367"
+		spacestart=index(binaryvaluewithoperator," "); # 3 ; 2
+		binaryvaluefromrootattribute=substr(binaryvaluewithoperator,spacestart+1,length(binaryvaluewithoperator)-spacestart);	# 4, 4-3=1 ; 3, 5-2=3
+		matchoperatorstring=substr(binaryvaluewithoperator,1,spacestart-1);	# 1,2 ; 1,1
+		if (matchoperatorstring == "==") binaryvaluematchoperatorfromrootattribute = "Equals"
+		else if (matchoperatorstring == "!=") binaryvaluematchoperatorfromrootattribute = "NotEquals"
+		else if (matchoperatorstring == "<") binaryvaluematchoperatorfromrootattribute = "LessThan"
+		else if (matchoperatorstring == "<=") binaryvaluematchoperatorfromrootattribute = "LessThanOrEquals"
+		else if (matchoperatorstring == ">") binaryvaluematchoperatorfromrootattribute = "GreaterThan"
+		else if (matchoperatorstring == ">=") binaryvaluematchoperatorfromrootattribute = "GreaterThanOrEquals"
+		else print "Error - Binary Match Operator \"" matchoperatorstring "\" invalid at line" FNR >"/dev/tty"
+	}
+
+	tagvalue=""
+	if (match($0,"TagValue=\"[^\"]*\""))
+		tagvalue=substr($0,RSTART+length("TagValue=\""),
+			RLENGTH-length("TagValue=\"")-1);
+
+	tagvaluefromrootattribute=""
+	if (match($0,"TagValueFromRootAttribute=\"[^\"]*\""))
+		tagvaluefromrootattribute=substr($0,RSTART+length("TagValueFromRootAttribute=\""),
+			RLENGTH-length("TagValueFromRootAttribute=\"")-1);
+
+	sequencehasitems=0
+	if (match($0,"SequenceHasItems=\"[^\"]*\"")) {
+		sequencehasitems=1;
+	}
+
+	sequencehasoneitem=0
+	if (match($0,"SequenceHasOneItem=\"[^\"]*\"")) {
+		sequencehasoneitem=1;
+	}
+	
+	sequencehasmultipleitems=0
+	if (match($0,"SequenceHasMultipleItems=\"[^\"]*\"")) {
+		sequencehasmultipleitems=1;
+	}
+
+	if (role == "define") {
+		if (valuepresent) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(ValuePresent(list,TagFromName(" element ")," selector ")?1:0);"
+		}
+		if (elementpresent) {
+			if (length(elementpresentmask) > 0) {
+				print "\tcondition" nestinglevel " " operator "=" modifier "(ElementPresentMasked(list,TagFromName(" element ")," elementpresentmask ")?1:0);"
+			}
+			else {
+				print "\tcondition" nestinglevel " " operator "=" modifier "(ElementPresent(list,TagFromName(" element "))?1:0);"
+			}
+		}
+		if (elementpresentabove) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(ElementPresentAbove(parentlist,TagFromName(" element "))?1:0);"
+		}
+		if (elementpresentwithin) {
+			if (length(elementpresentwithinsequence) > 0) {
+				if (stringvalueused) {
+					print "\tcondition" nestinglevel " " operator "=" modifier "(ElementStringValueMatchWithin(list,TagFromName(" element "),TagFromName(" elementpresentwithinsequence ")," selector ",\"" stringvalue "\")?1:0);"
+					stringvalueused=0	# i.e., don't use it again below !
+				}
+				else if (stringconstantused) {
+					print "\tcondition" nestinglevel " " operator "=" modifier "(ElementStringValueMatchWithin(list,TagFromName(" element "),TagFromName(" elementpresentwithinsequence ")," selector ",\"" stringconstant "\")?1:0);"
+					stringconstantused=0	# i.e., don't use it again below !
+				}
+				else {
+					print "\tcondition" nestinglevel " " operator "=" modifier "(ElementPresentWithin(list,TagFromName(" element "),TagFromName(" elementpresentwithinsequence "))?1:0);"
+				}
+			}
+			else {
+				print "Error - Must specify sequence attribute argument for ElementPresentWithin " FNR >"/dev/tty"
+			}
+		}
+		if (elementpresentinpath) {
+			# For now we only support descending from root into items of a top level sequence
+			if (length(elementpresentinpathfromroot) > 0) {
+				print "\tcondition" nestinglevel " " operator "=" modifier "(ElementPresentInPathFromRoot(rootlist,TagFromName(" element "),TagFromName(" elementpresentinpathfromroot "))?1:0);"
+			}
+			else {
+				print "Error - Must specify sequence attribute argument for ElementPresentInPathFromRoot " FNR >"/dev/tty"
+			}
+		}
+		if (elementpresentinroot) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(ElementPresent(rootlist,TagFromName(" element "))?1:0);"
+		}
+		if (grouppresent) {
+			if (length(grouppresentmask) > 0) {
+				print "\tcondition" nestinglevel " " operator "=" modifier "(GroupPresentMasked(list,TagFromName(" element ")," grouppresentmask ")?1:0);"
+			}
+			else {
+				print "\tcondition" nestinglevel " " operator "=" modifier "GroupPresent(list,TagFromName(" element "))?1:0;"
+			}
+		}
+		if (stringconstantused) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(StringValueMatch(list,TagFromName(" element ")," selector "," stringconstant ")?1:0);"
+		}
+		if (stringconstantfromrootattributeused) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(StringValueMatch(rootlist,TagFromName(" element ")," selector "," stringconstantfromrootattribute ")?1:0);"
+		}
+		if (stringvalueused) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(StringValueMatch(list,TagFromName(" element ")," selector ",\"" stringvalue "\")?1:0);"
+		}
+		if (stringvalueaboveused) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(StringValueMatch(parentlist,TagFromName(" element ")," selector ",\"" stringvalueabove "\")?1:0);"
+		}
+		if (stringvaluefromrootattributeused) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(StringValueMatch(rootlist,TagFromName(" element ")," selector ",\"" stringvaluefromrootattribute "\")?1:0);"
+		}
+		if (length(binaryvalue) > 0) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(BinaryValueMatch(list,TagFromName(" element ")," selector "," binaryvaluematchoperator "," binaryvalue ")?1:0);"
+		}
+		if (length(binaryvaluefromrootattribute) > 0) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(BinaryValueMatch(rootlist,TagFromName(" element ")," selector "," binaryvaluematchoperatorfromrootattribute "," binaryvaluefromrootattribute ")?1:0);"
+		}
+		if (length(tagvalue) > 0) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(TagValueMatch(list,TagFromName(" element ")," selector ",Tag(" tagvalue "))?1:0);"
+		}
+		if (length(tagvaluefromrootattribute) > 0) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(TagValueMatch(rootlist,TagFromName(" element ")," selector ",Tag(" tagvaluefromrootattribute "))?1:0);"
+		}
+		if (sequencehasitems) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(SequenceHasItems(list,TagFromName(" element "))?1:0);"
+		}
+		if (sequencehasoneitem) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(SequenceHasOneItem(list,TagFromName(" element "))?1:0);"
+		}
+		if (sequencehasmultipleitems) {
+			print "\tcondition" nestinglevel " " operator "=" modifier "(SequenceHasMultipleItems(list,TagFromName(" element "))?1:0);"
+		}
+	}
+
+	}
+
+/^[ 	]*[(]/ {
+	if (role == "define") {
+		++nestinglevel
+		print "{"
+		print "\tint condition" nestinglevel " =0;"
+	}
+	
+	}
+	
+/^[ 	]*[)]/ {
+	operator=""
+	if (match($0,"Operator=\"[^\"]*\""))
+		operator=substr($0,RSTART+length("Operator=\""),
+			RLENGTH-length("Operator=\"")-1);
+
+	if (operator == "or" || operator == "Or" || operator == "|" || operator == "||") {
+		operator="|"
+	}
+	else if (operator == "xor" || operator == "Xor" || operator == "^") {
+		operator="^"
+	}
+	else if (operator == "and" || operator == "And" || operator == "&" || operator == "&&") {
+		operator="&"
+	}
+	else if (length(operator) == 0) {
+		operator="|"
+	}
+	else {
+		print "Error - Operator \"" operator "\" invalid, assuming or, at line" FNR >"/dev/tty"
+	}
+
+	modifier=""
+	if (match($0,"Modifier=\"[^\"]*\""))
+		modifier=substr($0,RSTART+length("Modifier=\""),
+			RLENGTH-length("Modifier=\"")-1);
+
+	if (modifier == "not" || modifier == "Not" || modifier == "~" || modifier == "!") {
+		modifier="~"
+	}
+	else if (length(modifier) == 0) {
+		modifier=""
+	}
+	else {
+		print "Error - Modifier \"" modifier "\" invalid, assuming none, at line" FNR >"/dev/tty"
+	}
+
+	if (role == "define") {
+		print "\tcondition" (nestinglevel-1) " " operator "=" modifier "condition" nestinglevel ";"
+		print "}"
+		--nestinglevel
+	}
+	
+	}
+	
+END {
+	if (role == "declare" || role == "define") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/convcln.awk b/libsrc/support/convcln.awk
new file mode 100644
index 0000000..1787d45
--- /dev/null
+++ b/libsrc/support/convcln.awk
@@ -0,0 +1,94 @@
+#  convcln.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+#
+# Clean a conversion template by converting offset to dec from 0
+# in each block
+#
+
+function hextodec(hex) {
+		gsub("x","0",hex);
+		gsub("X","0",hex);
+		n=length(hex);
+		dec=0;
+		i=1;
+		while (i <= n) {
+			digit=substr(hex,i,1);
+			if (digit == "a") digit=10;
+			else if (digit == "b") digit=11;
+			else if (digit == "c") digit=12;
+			else if (digit == "d") digit=13;
+			else if (digit == "e") digit=14;
+			else if (digit == "f") digit=15;
+			else if (index("0123456789",digit) == 0) break;
+			dec=dec*16+digit;
+			++i;
+		}
+		return dec;
+}
+
+function octtodec(oct) {
+		n=length(oct);
+		dec=0;
+		i=1;
+		while (i <= n) {
+			digit=substr(oct,i,1);
+			if (index("01234567",digit) == 0) break;
+			dec=dec*8+digit;
+			++i;
+		}
+		return dec;
+}
+
+function anytodec(any) {
+		if (substr(any,1,1) == "0") {
+			if (substr(any,2,1) == "x" || substr(any,2,1) == "X")
+				return hextodec(any)
+			else
+				return octtodec(any)
+		}
+		else
+			return any
+}
+
+NR==1	{
+	blockoffset=0
+	lastblock=""
+}
+
+!/^block/ { print }
+
+/^block/{
+	block=""
+	if (match($0,"block=\"[^\"]*\""))
+		block=substr($0,RSTART+length("block=\""),
+			RLENGTH-length("block=\"")-1);
+	offset=""
+	if (match($0,"offset=\"[^\"]*\""))
+		offset=anytodec(substr($0,RSTART+length("offset=\""),
+			RLENGTH-length("offset=\"")-1));
+
+	ok="yes";
+
+	if (block == "" || block == "?" ) {
+		print "Line " FNR ": error - no block" >"/dev/tty"
+		ok="no";
+	}
+	if (offset == "" || offset == "?" ) {
+		print "Line " FNR ": error - no offset" >"/dev/tty"
+		ok="no";
+	}
+
+	if (block != lastblock) {
+		if (offset != 0) {
+			print "Block " block ": add " offset " (dec) to origin" >"/dev/tty"
+		}
+		blockoffset=offset
+	}
+
+	if (blockoffset != 0) offset-=blockoffset
+
+	sub("offset=\"[^\"]*\"","offset=\"" offset "\"")
+	print
+
+	lastblock=block
+}
+
diff --git a/libsrc/support/convert.awk b/libsrc/support/convert.awk
new file mode 100644
index 0000000..b55eea1
--- /dev/null
+++ b/libsrc/support/convert.awk
@@ -0,0 +1,693 @@
+#  convert.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create a C++ header file to read keywords & make dicom attributes
+# according to a description in the input template file
+
+# goes to great effort to make sure things are read
+#	- in order
+#	- once
+# so that theoretically the C++ routine could read from standard input
+# (assuming of course that the template file is in ascending block
+# and offset order)
+
+# can set these values on the command line:
+#
+#	role	  - "dicom"           - function to extract dicom tags
+#		  - "headerpart"      - header part class declarations
+#		  - "wholeheader"     - header whole class declarations
+#		  - "constructheader" - header whole class constructor
+#	prefix
+#	offsetwarning=off
+#	headerclassparameters=",..."
+#		eg. headerclassparameters=",GEN_FileStructureInformation &fileinfo"
+
+function hextodec(hex) {
+		gsub("x","0",hex);
+		gsub("X","0",hex);
+		n=length(hex);
+		dec=0;
+		i=1;
+		while (i <= n) {
+			digit=substr(hex,i,1);
+			if (digit == "a") digit=10;
+			else if (digit == "b") digit=11;
+			else if (digit == "c") digit=12;
+			else if (digit == "d") digit=13;
+			else if (digit == "e") digit=14;
+			else if (digit == "f") digit=15;
+			else if (index("0123456789",digit) == 0) break;
+			dec=dec*16+digit;
+			++i;
+		}
+		return dec;
+}
+
+function octtodec(oct) {
+		n=length(oct);
+		dec=0;
+		i=1;
+		while (i <= n) {
+			digit=substr(oct,i,1);
+			if (index("01234567",digit) == 0) break;
+			dec=dec*8+digit;
+			++i;
+		}
+		return dec;
+}
+
+function anytodec(any) {
+		if (substr(any,1,1) == "0") {
+			if (substr(any,2,1) == "x" || substr(any,2,1) == "X")
+				return hextodec(any)
+			else
+				return octtodec(any)
+		}
+		else
+			return any
+}
+
+NR==1	{
+
+	if (prefix == "" ) prefix="Proprietary"
+
+	if (dicomfunctionname             == "" ) dicomfunctionname	        = "ToDicom_Template"
+	if (dumpcommonfunctionname        == "" ) dumpcommonfunctionname        = "DumpCommon"
+	if (dumpselectedimagefunctionname == "" ) dumpselectedimagefunctionname = "DumpSelectedImage"
+	if (conditionprefix               == "" ) conditionprefix	        = prefix
+	if (headeroffsetprefix            == "" ) headeroffsetprefix	        = prefix "Offset"
+	if (headeroffsetsuffix            == "" ) headeroffsetsuffix	        = "ptr"
+	if (headerclassprefix             == "" ) headerclassprefix	        = prefix "HeaderClass"
+	if (headerdicomclassprefix        == "" ) headerdicomclassprefix        = prefix "Header_BothClass"
+	if (headerdumpclassprefix         == "" ) headerdumpclassprefix	        = prefix "Header_BothClass"
+	if (headerinstanceprefix          == "" ) headerinstanceprefix          = prefix "HeaderInstance"
+	if (methodnameprefix              == "" ) methodnameprefix              = prefix "Method"
+	if (methodconstructorargsprefix   == "" ) methodconstructorargsprefix   = prefix "MethodConstructorArgs"
+
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print "//"
+	print "// Generated by convert.awk with options or defaults ..."
+	print "//"
+	print "// \t role=" role
+	print "// \t prefix=" prefix
+	print "// \t dicomfunctionname=" dicomfunctionname
+	print "// \t dumpcommonfunctionname=" dumpcommonfunctionname
+	print "// \t dumpselectedimagefunctionname=" dumpselectedimagefunctionname
+	print "// \t headeroffsetprefix=" headeroffsetprefix
+	print "// \t headeroffsetsuffix=" headeroffsetsuffix
+	print "// \t headerclassprefix=" headerclassprefix
+	print "// \t headerdicomclassprefix=" headerdicomclassprefix
+	print "// \t headerdumpclassprefix=" headerdumpclassprefix
+	print "// \t headerinstanceprefix=" headerinstanceprefix
+	print "// \t methodnameprefix=" methodnameprefix
+	print "// \t methodconstructorargsprefix=" methodconstructorargsprefix
+	print "// \t headerclassparameters=" headerclassparameters
+	print ""
+
+	if (role == "dicom") {
+		print "void "
+		print headerdicomclassprefix "::" dicomfunctionname "(AttributeList *list,unsigned imagenumber)"
+		print "{"
+		print "\t(void)imagenumber;"
+		print ""
+	}
+	if (role == "dump") {
+		print "void "
+		print headerdumpclassprefix "::" dumpcommonfunctionname "(TextOutputStream *log)"
+		print "{"
+	}
+	if (role == "wholeheader") {
+		print "class " headerclassprefix
+		print "{"
+		print "public:"
+		print "\t" headerclassprefix "(istream *ist" headerclassparameters ");"
+		print ""
+	}
+	if (role == "constructheader") {
+		print headerclassprefix "::" headerclassprefix "(istream *ist" headerclassparameters ")"
+		print "{"
+	}
+
+	accumulatedoffset=0
+	lastblock=""
+	lastmethod=""
+	selectimagedone=""
+	reservedfieldcount=0
+}
+
+/^block/{
+	block=""
+	if (match($0,"block=\"[^\"]*\""))
+		block=substr($0,RSTART+length("block=\""),
+			RLENGTH-length("block=\"")-1);
+	condition=""
+	if (match($0,"condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("condition=\""),
+			RLENGTH-length("condition=\"")-1);
+	select=""
+	if (match($0,"select=\"[^\"]*\""))
+		select=substr($0,RSTART+length("select=\""),
+			RLENGTH-length("select=\"")-1);
+	method=""
+	if (match($0,"method=\"[^\"]*\""))
+		method=substr($0,RSTART+length("method=\""),
+			RLENGTH-length("method=\"")-1);
+	offset=""
+	if (match($0,"offset=\"[^\"]*\""))
+		offset=anytodec(substr($0,RSTART+length("offset=\""),
+			RLENGTH-length("offset=\"")-1));
+	intype=""
+	if (match($0,"intype=\"[^\"]*\""))
+		intype=substr($0,RSTART+length("intype=\""),
+			RLENGTH-length("intype=\"")-1);
+	inlength=""
+	if (match($0,"inlength=\"[^\"]*\""))
+		inlength=anytodec(substr($0,RSTART+length("inlength=\""),
+			RLENGTH-length("inlength=\"")-1));
+	keyword=""
+	if (match($0,"keyword=\"[^\"]*\""))
+		keyword=substr($0,RSTART+length("keyword=\""),
+			RLENGTH-length("keyword=\"")-1);
+	name=""
+	if (match($0,"name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("name=\""),
+			RLENGTH-length("name=\"")-1);
+	dicomtype=""
+	if (match($0,"dicomtype=\"[^\"]*\""))
+		dicomtype=substr($0,RSTART+length("dicomtype=\""),
+			RLENGTH-length("dicomtype=\"")-1);
+	dicomtag=""
+	if (match($0,"dicomtag=\"[^\"]*\""))
+		dicomtag=substr($0,RSTART+length("dicomtag=\""),
+			RLENGTH-length("dicomtag=\"")-1);
+	enum=""
+	if (match($0,"enum=\"[^\"]*\""))
+		enum=substr($0,RSTART+length("enum=\""),
+			RLENGTH-length("enum=\"")-1);
+	bitmap=""
+	if (match($0,"bitmap=\"[^\"]*\""))
+		bitmap=substr($0,RSTART+length("bitmap=\""),
+			RLENGTH-length("bitmap=\"")-1);
+	comment=""
+	if (match($0,"#.*$"))
+		comment=substr($0,RSTART+length("#"),
+			RLENGTH-length("#"));
+
+	ok="yes";
+
+	if (block == "" || block == "?" ) {
+		print "Line " FNR ": error - no block" >"/dev/tty"
+		ok="no";
+	}
+
+	if (select != "image" && select != "") {
+		print "Line " FNR ": select may only have value of image" >"/dev/tty"
+		ok="no";
+	}
+
+	if (method == "" || method == "?") {
+		if (lastmethod != "" || lastmethod == "?") {
+			print "Line " FNR ": error - must use only method or offset/intype throughout block" >"/dev/tty"
+			ok="no";
+		}
+		if (offset == "" || offset == "?") {
+			print "Line " FNR ": error - no offset or method" >"/dev/tty"
+			ok="no";
+		}
+		if (intype == "" || intype == "?") {
+			print "Line " FNR ": error - no intype or method" >"/dev/tty"
+			ok="no";
+		}
+		usemethod="no";
+	}
+	else {
+		if ((offset != "" && offset != "?") || (intype != "" && intype != "?")) {
+			print "Line " FNR ": error - if method can't have offset or intype" >"/dev/tty"
+			ok="no";
+		}
+		usemethod="yes";
+		methodname=methodnameprefix "_" method;
+	}
+	lastmethod=method;
+
+	if (condition == "")
+		conditiontest=""
+	else
+		conditiontest="if (" conditionprefix condition ") "
+
+	if (block != lastblock) {
+		blockclassname=headerclassprefix "_" block
+		blockinstancename=headerinstanceprefix "_" block
+		if (usemethod == "no") {
+			offsetname=headeroffsetprefix "_" block "_" headeroffsetsuffix
+		}
+		else {
+			offsetname="\"" block "\""
+		}
+		if (role == "headerpart") {
+			if (lastblock != "" && lastmethod == "") {
+				print "};"
+				print ""
+			}
+			if (usemethod == "no") {
+				print "class " blockclassname " {"
+				print "public:"
+				print "\t"   blockclassname "(istream *ist,long offset)"
+				print "\t\t { ReadProprietaryHeader(ist,offset,sizeof *this,(char *)this); }"
+				print ""
+			}
+		}
+		if (role == "wholeheader") {
+			print "\t" blockclassname " *" blockinstancename ";"
+		}
+		if (role == "constructheader") {
+			print "\t" blockinstancename " = 0;"
+			print "\t" conditiontest blockinstancename " = new"
+			if (usemethod == "no") {
+				print "\t\t" blockclassname "(ist," offsetname ");"
+			}
+			else {
+				# note the space preceeding the methodconstructorargsprefix
+				# (which may be null, but if not will have leading comma)
+				print "\t\t" blockclassname "(ist " methodconstructorargsprefix "_" block ");"
+			}
+			print ""
+		}
+		if (select == "image") {
+			if (selectimagedone == "yes") {
+				print "Line " FNR ": error - select by image can only be used in one (the last) block" >"/dev/tty"
+				ok="no";
+			}
+			else {
+				selectimagedone="yes"
+				if (role == "dump") {
+					print "}"
+					print ""
+					print "void "
+					print headerdumpclassprefix "::" dumpselectedimagefunctionname "(TextOutputStream *log,unsigned imagenumber)"
+					print "{"
+				}
+			}
+		}
+		lastblock=""
+	}
+
+	if (role == "dicom") {
+		if (dicomtype != "" && dicomtype != "?") {
+			if      (dicomtype == "AE") { dicomtypedesc="ApplicationEntity" ; }
+			else if (dicomtype == "AS") { dicomtypedesc="AgeString"         ; }
+			else if (dicomtype == "AT") { dicomtypedesc="AttributeTag"      ; }
+			else if (dicomtype == "CS") { dicomtypedesc="CodeString"        ; }
+			else if (dicomtype == "DA") { dicomtypedesc="DateString"        ; }
+			else if (dicomtype == "DS") { dicomtypedesc="DecimalString"     ; }
+			else if (dicomtype == "DT") { dicomtypedesc="DateTimeString"    ; }
+			else if (dicomtype == "IS") { dicomtypedesc="IntegerString"     ; }
+			else if (dicomtype == "LO") { dicomtypedesc="LongString"        ; }
+			else if (dicomtype == "LT") { dicomtypedesc="LongText"          ; }
+			else if (dicomtype == "OB") { dicomtypedesc="OtherByteString"   ; }
+			else if (dicomtype == "OW") { dicomtypedesc="OtherWordString"   ; }
+			else if (dicomtype == "PN") { dicomtypedesc="PersonName"        ; }
+			else if (dicomtype == "SH") { dicomtypedesc="ShortString"       ; }
+			else if (dicomtype == "SL") { dicomtypedesc="SignedLong"        ; }
+			else if (dicomtype == "SS") { dicomtypedesc="SignedShort"       ; }
+			else if (dicomtype == "ST") { dicomtypedesc="ShortText"         ; }
+			else if (dicomtype == "TM") { dicomtypedesc="TimeString"        ; }
+			else if (dicomtype == "UI") { dicomtypedesc="UIString"          ; }
+			else if (dicomtype == "UL") { dicomtypedesc="UnsignedLong"      ; }
+			else if (dicomtype == "US") { dicomtypedesc="UnsignedShort"     ; }
+			else if (dicomtype == "XS") { dicomtypedesc="UnspecifiedShort"  ; }
+			else if (dicomtype == "XL") { dicomtypedesc="UnspecifiedLong"   ; }
+			else {
+				print "Line " FNR ": error in dicomtype - bad type <" \
+					dicomtype ">" >"/dev/tty"
+				ok="no";
+			}
+			putdicom="yes"
+		}
+		else {
+			putdicom="no"
+		}
+	}
+
+	if (usemethod == "no" && (role == "headerpart" || role == "dicom" || role == "dump")) {
+		if      (intype == "String"   )           { structtype="String";              sizeoftype=1; fromtype="String";   array="yes"; }
+		else if (intype == "Uint8"    )           { structtype="Uint8_8";             sizeoftype=1; fromtype="Unsigned"; array="no";  }
+		else if (intype == "Uint16_L" )           { structtype="Uint16_L";            sizeoftype=2; fromtype="Unsigned"; array="no";  }
+		else if (intype == "Uint16_B" )           { structtype="Uint16_B";            sizeoftype=2; fromtype="Unsigned"; array="no";  }
+		else if (intype == "Uint32_L" )           { structtype="Uint32_L";            sizeoftype=4; fromtype="Unsigned"; array="no";  }
+		else if (intype == "Uint32_B" )           { structtype="Uint32_B";            sizeoftype=4; fromtype="Unsigned"; array="no";  }
+		else if (intype == "Int8"     )           { structtype="Int8_8";              sizeoftype=1; fromtype="Signed";   array="no";  }
+		else if (intype == "Int16_L"  )           { structtype="Int16_L";             sizeoftype=2; fromtype="Signed";   array="no";  }
+		else if (intype == "Int16_B"  )           { structtype="Int16_B";             sizeoftype=2; fromtype="Signed";   array="no";  }
+		else if (intype == "Int32_L"  )           { structtype="Int32_L";             sizeoftype=4; fromtype="Signed";   array="no";  }
+		else if (intype == "Int32_B"  )           { structtype="Int32_B";             sizeoftype=4; fromtype="Signed";   array="no";  }
+		else if (intype == "IEEE_Float32_L")      { structtype="IEEE_Float32_L";      sizeoftype=4; fromtype="Double";   array="no";  }
+		else if (intype == "IEEE_Float32_B")      { structtype="IEEE_Float32_B";      sizeoftype=4; fromtype="Double";   array="no";  }
+		else if (intype == "IEEE_Float64_L")      { structtype="IEEE_Float64_L";      sizeoftype=8; fromtype="Double";   array="no";  }
+		else if (intype == "IEEE_Float64_B")      { structtype="IEEE_Float64_B";      sizeoftype=8; fromtype="Double";   array="no";  }
+		else if (intype == "Vax_Float_F")         { structtype="Vax_Float_F";         sizeoftype=4; fromtype="Double";   array="no";  }
+		else if (intype == "DG_Float_F")          { structtype="DG_Float_F";          sizeoftype=4; fromtype="Double";   array="no";  }
+		else if (intype == "Time_Milliseconds_B") { structtype="Time_Milliseconds_B"; sizeoftype=4; fromtype="Time";     array="no";  }
+		else if (intype == "Time_Milliseconds_L") { structtype="Time_Milliseconds_L"; sizeoftype=4; fromtype="Time";     array="no";  }
+		else if (intype == "Pace_Date")           { structtype="Pace_Date";           sizeoftype=4; fromtype="Date";     array="no";  }
+		else if (intype == "Unix_DateTime_L")     { structtype="Unix_DateTime_L";      sizeoftype=4; fromtype="DateTime"; array="no";  }
+		else if (intype == "Unix_DateTime_B")     { structtype="Unix_DateTime_B";      sizeoftype=4; fromtype="DateTime"; array="no";  }
+		else if (intype == "String_Date_YMD")     { structtype="String";              sizeoftype=1; fromtype="String";   array="yes"; }
+		else if (intype == "String_Date_DMY")     { structtype="String";              sizeoftype=1; fromtype="String";   array="yes"; }
+		else if (intype == "String_Date_MDY")     { structtype="String";              sizeoftype=1; fromtype="String";   array="yes"; }
+		else if (intype == "String_Time")         { structtype="String";              sizeoftype=1; fromtype="String";   array="yes"; }
+		else {
+			print "Line " FNR ": error in intype - bad type <" \
+				intype ">" >"/dev/tty"
+			ok="no";
+		}
+
+		if (array == "yes") {
+			if (inlength == "" || inlength == "?")
+				arraylength=1;
+			else
+				arraylength=inlength
+		}
+		else {
+			arraylength=0
+			if (inlength != "" && inlength != "1") {
+				print "Line " FNR ": error - no inlength allowed for this type" >"/dev/tty"
+				ok="no";
+			}
+		}
+	}
+
+	if (keyword != "" && keyword != "?") {
+		usename=keyword
+	}
+	else if (name != "" && name != "?") {
+		usename=name
+	}
+	else {
+		#print "Line " FNR ": error - must have name or keyword" >"/dev/tty"
+		#ok="no";
+		usename = "unknown" FNR
+	}
+
+	if (usemethod == "yes") {
+		if (select == "image") {
+			valuename=blockinstancename "->" methodname "(imagenumber,\"" usename "\")"
+		}
+		else {
+			valuename=blockinstancename "->" methodname "(\"" usename "\")"
+		}
+	}
+	else {
+		if (select == "image") {
+			print "Line " FNR ": error - select by image only supported for method not offset" >"/dev/tty"
+			ok="no";
+		}
+		else {
+			valuename=blockinstancename "->" usename
+		}
+	}
+
+	if (block != lastblock) accumulatedoffset=0
+
+	if (ok == "yes") {
+		if (role == "headerpart") {
+			if (usemethod == "no") {
+				if (offset%sizeoftype > 0 && offsetwarning != "off") {
+					print "Line " FNR ": warning - offset " offset \
+						" % size of type (" sizeoftype \
+						" bytes) not zero - possible alignment problem" >"/dev/tty"
+				}
+				lengthtopad=offset-accumulatedoffset
+				if (lengthtopad > 0) {
+					++reservedfieldcount
+					print "\tchar \t\treserved_" reservedfieldcount "\t[" lengthtopad "]\t;"
+					accumulatedoffset+=lengthtopad
+				}
+				else if (lengthtopad < 0) {
+					print "Line " FNR ": error - offset " offset \
+						" < the " accumulatedoffset " already allocated" >"/dev/tty"
+				}
+				if (arraylength == 0)
+					part=structtype " \t" usename
+				else if (fromtype == "String")
+					part=structtype "<" arraylength "> \t" usename
+				else
+					part=structtype " \t" usename "[" arraylength "]"
+
+				print "\t" part "\t; // at " accumulatedoffset
+
+				if (arraylength == 0)
+					accumulatedoffset+=sizeoftype
+				else
+					accumulatedoffset+=sizeoftype*arraylength
+			}
+		}
+
+		if (fromtype == "String")
+			putname="String_Use(" valuename ")"
+		else if (dicomtype == "DA")
+			putname="Date(" valuename ")"
+		else if (dicomtype == "TM")
+			putname="Time(" valuename ")"
+		else
+			putname=valuename
+
+		if (role == "dicom" && putdicom == "yes") {
+			print "\t" conditiontest "(*list)+=new " dicomtypedesc "Attribute("
+			print "\t\tTagFromName(" dicomtag "),"
+			print "\t\t" putname ");"
+			print ""
+		}
+		if (role == "dump") {
+			if (keyword != "" && keyword != "?")
+				keydesc=" (" keyword ")"
+			else if (name != "" && name != "?")
+				keydesc=" (" name ")"
+			else
+				keydesc=""
+
+			if (usemethod == "no") {
+				offsetdescription="\"[\" << " offsetname " << \":\" << " offset " << \"] \""
+			}
+			else {
+				offsetdescription="\"[" block ":" keyword "] \""
+			}
+
+			print "\t" conditiontest "(*log)\t << " offsetdescription "<< \"\\t" comment keydesc "\\t <\""
+
+			if (fromtype == "Date") {
+				print "\t\t <<          Date(" putname ").getYYYY()"
+				print "\t\t << \"/\" << Date(" putname ").getMMM()"
+				print "\t\t << \"/\" << Date(" putname ").getDD()"
+			}
+			else if (fromtype == "Time") {
+				print "\t\t <<          Time(" putname ").getHour()"
+				print "\t\t << \":\" << Time(" putname ").getMinute()"
+				print "\t\t << \":\" << Time(" putname ").getSecond()"
+			}
+			else if (fromtype == "DateTime") {
+				print "\t\t <<          DateTime(" putname ").getYYYY()"
+				print "\t\t << \"/\" << DateTime(" putname ").getMMM()"
+				print "\t\t << \"/\" << DateTime(" putname ").getDD()"
+				print "\t\t << \" \" << DateTime(" putname ").getHour()"
+				print "\t\t << \":\" << DateTime(" putname ").getMinute()"
+				print "\t\t << \":\" << DateTime(" putname ").getSecond()"
+			}
+			else {
+				print "\t\t << " putname
+			}
+			print "\t\t << \">\\n\";"
+
+			while (enum != "") {
+				#if (!match(enum,"[a-zA-Z\'0-9\-][a-zA-Z\'0-9]*=")) {
+				if (!match(enum,"[^=]*=")) {
+					print "Line " FNR \
+						": error in enum - no code <" \
+						enum ">" >"/dev/tty"
+					next
+				}
+				code=substr(enum,RSTART,RLENGTH-1)
+				enum=substr(enum,RSTART+RLENGTH)
+				if (!match(enum,"[^,][^,]*")) {
+					print "Line " FNR \
+						": error in enum - no value <" \
+						enum ">" >"/dev/tty"
+					next
+				}
+				meaning=substr(enum,RSTART,RLENGTH)
+				enum=substr(enum,RSTART+RLENGTH)
+				if (match(code,"\'")) {
+					unquotecode=substr(code,2,length(code)-2);
+					print "\t" conditiontest "if (strncmp(" putname ",\"" unquotecode \
+						"\"," arraylength ")==0) (*log) << \"\\t\\t " \
+						code " = " meaning "\\n\";"
+				}
+				else {
+					print "\t" conditiontest "if (" putname " == " code \
+						") (*log) << \"\\t\\t\\t " \
+						code " = " meaning "\\n\";"
+				}
+				if (match(enum,"^,")) {
+					enum=substr(enum,RSTART+RLENGTH)
+				}
+				else {
+					if (length(enum) != 0) {
+					print "Line " FNR \
+						": error in enum - trailing garbage <" \
+						enum ">" >"/dev/tty"
+					}
+					next
+				}
+			}
+
+			while (bitmap != "") {
+				if (!match(bitmap,"[0-9][0-9]*:")) {
+					print "Line " FNR \
+						": error in bitmap - no bit number <" \
+						bitmap ">" >"/dev/tty"
+					next
+				}
+				bitnumber=substr(bitmap,RSTART,RLENGTH-1)
+				bitmap=substr(bitmap,RSTART+RLENGTH)
+
+				if (!match(bitmap,"[^,;][^,;]*")) {
+					print "Line " FNR \
+						": error in bitmap - no false value <" \
+						bitmap ">" >"/dev/tty"
+					next
+				}
+				zeromeaning=substr(bitmap,RSTART,RLENGTH)
+				bitmap=substr(bitmap,RSTART+RLENGTH)
+
+				if (match(bitmap,"^,")) {
+					bitmap=substr(bitmap,RSTART+RLENGTH)
+				}
+				else {
+					print "Line " FNR \
+						": error in bitmap - no comma <" \
+						bitmap ">" >"/dev/tty"
+					next
+				}
+
+				if (!match(bitmap,"[^;,][^;,]*")) {
+					print "Line " FNR \
+						": error in bitmap - no true value <" \
+						bitmap ">" >"/dev/tty"
+					next
+				}
+				onemeaning=substr(bitmap,RSTART,RLENGTH)
+				bitmap=substr(bitmap,RSTART+RLENGTH)
+
+				print "\t" conditiontest "(*log) << \"\\t\\t\\t bit " bitnumber " \""
+				print "\t     << ((" putname "&(1<<" bitnumber "))?\"true \":\"false\") "
+				print "\t     << \" = \" << ((" putname "&(1<<" bitnumber "))?\"" onemeaning \
+						"\":\"" zeromeaning "\")"
+				print "\t     << \"\\n\";"
+
+				if (match(bitmap,"^;")) {
+					bitmap=substr(bitmap,RSTART+RLENGTH)
+				}
+				else {
+					if (length(bitmap) != 0) {
+					print "Line " FNR \
+					    ": error in bitmap - trailing garbage <" \
+						bitmap ">" >"/dev/tty"
+					}
+					next
+				}
+			}
+
+		}
+	}
+	lastblock=block
+}
+
+/^constant/{
+	constant=""
+	if (match($0,"constant=\"[^\"]*\""))
+		constant=substr($0,RSTART+length("constant=\""),
+			RLENGTH-length("constant=\"")-1);
+	condition=""
+	if (match($0,"condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("condition=\""),
+			RLENGTH-length("condition=\"")-1);
+	dicomtype=""
+	if (match($0,"dicomtype=\"[^\"]*\""))
+		dicomtype=substr($0,RSTART+length("dicomtype=\""),
+			RLENGTH-length("dicomtype=\"")-1);
+	dicomtag=""
+	if (match($0,"dicomtag=\"[^\"]*\""))
+		dicomtag=substr($0,RSTART+length("dicomtag=\""),
+			RLENGTH-length("dicomtag=\"")-1);
+
+	ok="yes";
+
+	if (condition == "")
+		conditiontest=""
+	else
+		conditiontest="if (" conditionprefix condition ") "
+
+	if (role == "dicom") {
+		if (dicomtype == "" || dicomtype == "?" ) {
+			print "Line " FNR ": error - no dicomtype" >"/dev/tty"
+			ok="no";
+		}
+		if (dicomtag == "" || dicomtag == "?" ) {
+			print "Line " FNR ": error - no dicomtag" >"/dev/tty"
+			ok="no";
+		}
+
+		if      (dicomtype == "AE") { dicomtypedesc="ApplicationEntity" ; fromtype="String"; }
+		else if (dicomtype == "AS") { dicomtypedesc="AgeString"         ; fromtype="String"; }
+		else if (dicomtype == "CS") { dicomtypedesc="CodeString"        ; fromtype="String"; }
+		else if (dicomtype == "DA") { dicomtypedesc="DateString"        ; fromtype="String"; }
+		else if (dicomtype == "DS") { dicomtypedesc="DecimalString"     ; fromtype="String"; }
+		else if (dicomtype == "DT") { dicomtypedesc="DateTimeString"    ; fromtype="String"; }
+		else if (dicomtype == "IS") { dicomtypedesc="IntegerString"     ; fromtype="String"; }
+		else if (dicomtype == "LO") { dicomtypedesc="LongString"        ; fromtype="String"; }
+		else if (dicomtype == "LT") { dicomtypedesc="LongText"          ; fromtype="String"; }
+		else if (dicomtype == "PN") { dicomtypedesc="PersonName"        ; fromtype="String"; }
+		else if (dicomtype == "SH") { dicomtypedesc="ShortString"       ; fromtype="String"; }
+		else if (dicomtype == "SL") { dicomtypedesc="SignedLong"        ; fromtype="Signed"; }
+		else if (dicomtype == "SS") { dicomtypedesc="SignedShort"       ; fromtype="Signed"; }
+		else if (dicomtype == "ST") { dicomtypedesc="ShortText"         ; fromtype="String"; }
+		else if (dicomtype == "TM") { dicomtypedesc="TimeString"        ; fromtype="String"; }
+		else if (dicomtype == "UI") { dicomtypedesc="UIString"          ; fromtype="String"; }
+		else if (dicomtype == "UL") { dicomtypedesc="UnsignedLong"      ; fromtype="Unsigned"; }
+		else if (dicomtype == "US") { dicomtypedesc="UnsignedShort"     ; fromtype="Unsigned"; }
+		else if (dicomtype == "XS") { dicomtypedesc="UnspecifiedShort"  ; fromtype="Unsigned"; }
+		else if (dicomtype == "XL") { dicomtypedesc="UnspecifiedLong"   ; fromtype="Unsigned"; }
+		else {
+			print "Line " FNR ": error in dicomtype - bad or unsupported type <" \
+				dicomtype ">" >"/dev/tty"
+			ok="no";
+		}
+
+		if (constant == "")
+			usevalue="";
+		else if (fromtype == "String")
+			usevalue=",\"" constant "\"";
+		else
+			usevalue="," constant;
+
+		if (ok == "yes") {
+			print "\t" conditiontest "(*list)+=new " dicomtypedesc "Attribute("
+			print "\t\tTagFromName(" dicomtag ")" usevalue ");"
+			print ""
+		}
+	}
+}
+
+END {
+	if (role == "headerpart") {
+		if (lastblock != "") {
+			print "};"
+			print ""
+		}
+	}
+	if (role == "wholeheader") {
+		print "};"
+	}
+	if (role == "dicom" || role == "dump" || role == "constructheader") {
+		print "}"
+		print ""
+	}
+}
diff --git a/libsrc/support/elmdict.awk b/libsrc/support/elmdict.awk
new file mode 100644
index 0000000..a969000
--- /dev/null
+++ b/libsrc/support/elmdict.awk
@@ -0,0 +1,172 @@
+#  elmdict.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ code from element dictionary template 
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by elmdict.awk with options " role " " outname
+	print ""
+
+	if (role == "constant") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else if (role == "table") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+		print "static ElementDictionaryTableEntry"
+		print "\t\tElementDictionaryTable[] = {"
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	owner=""
+	if (match($0,"Owner=\"[^\"]*\""))
+		owner=substr($0,RSTART+length("Owner=\""),
+			RLENGTH-length("Owner=\"")-1);
+
+	privateblock="0000"	# only 0010 to 00ff are valid
+	if (match($0,"PrivateBlock=\"[^\"]*\""))
+		privateblock=substr($0,RSTART+length("PrivateBlock=\""),
+			RLENGTH-length("PrivateBlock=\"")-1);
+
+	# Transformations must match those in dictionary ... see elmdict.awk,elmdict.tpl,attrtag.cc
+
+	# Note that some are from element 0xxx00 and others from 0xxx10
+
+	if (group == "0020" && element == "31xx") element="3100";	# PS 300 - Source Image IDs
+
+	if (group == "0028" && element == "04x0") element="0410";	# PS 2 - RowsForNthOrderCoefficients
+	if (group == "0028" && element == "04x1") element="0411";	# PS 2 - ColumnsForNthOrderCoefficients
+	if (group == "0028" && element == "04x2") element="0412";	# PS 2 - CoefficientCoding
+	if (group == "0028" && element == "04x3") element="0413";	# PS 2 - CoefficientCodingPointers
+
+	if (group == "0028" && element == "08x0") element="0800";	# PS 2 - CodeLabel
+	if (group == "0028" && element == "08x2") element="0802";	# PS 2 - NumberOfTables
+	if (group == "0028" && element == "08x3") element="0803";	# PS 2 - CodeTableLocation
+	if (group == "0028" && element == "08x4") element="0804";	# PS 2 - BitsForCodeWord
+	if (group == "0028" && element == "08x8") element="0808";	# PS 2 - ImageDataLocation
+
+	if (group == "1000" && element == "00x0") element="0010";	# PS 2 - Escape Triplet
+	if (group == "1000" && element == "00x1") element="0011";	# PS 2 - Run Length Triplet
+	if (group == "1000" && element == "00x2") element="0012";	# PS 2 - Huffman Table Size
+	if (group == "1000" && element == "00x3") element="0013";	# PS 2 - Huffman Table Triplet
+	if (group == "1000" && element == "00x4") element="0014";	# PS 2 - Shift Table Size
+	if (group == "1000" && element == "00x5") element="0015";	# PS 2 - Shift Table Triplet
+
+	if (group == "1010" && element == "xxxx") element="0004";	# PS 2 - Zonal Map (0x0004 to 0xfffe)
+
+	if (group == "50xx") group="5000";				# PS 3 - Curve stuff
+
+	if (group == "60xx") {
+		if (owner == "")
+			group="6000";					# PS 3 and earlier - Overlay stuff
+		else
+			group="6001";					# For Papyrus annotations
+	}
+
+	if (group == "70xx") {
+		if (owner == "")
+			group="7000";					# Not actually in use
+		else
+			group="7001";					# Private DLX TextAnnotaion etc.
+	}
+
+	if (group == "7Fxx") group="7F00";				# PS 2 - VariablePixelData
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	match($0,"VR=\"[^\"]*\"");
+	vr=substr($0,RSTART+length("VR=\""),RLENGTH-length("VR=\"")-1);
+	if (vr == "US or SS") vr= "XS";
+	if (vr == "US or OW") vr= "XO";
+	if (vr == "US or SS or OW") vr= "XO";
+	if (vr == "US\\US or SS\\US") vr = "XS";
+	if (vr == "OW/OB") vr = "OX";
+
+	match($0,"VM=\"[^\"]*\"");
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="VMUNLIMITED";
+	}
+	if (match(vm,"-")) {
+#print "Matched vm with - " vm >"/dev/tty"
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+#print "Matched vmmin = " vmmin >"/dev/tty"
+		match(vm,"-[0-9n]*");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+#print "Matched vmmax = " vmmax >"/dev/tty"
+		if (match(vmmax,"[0-9]*n")) vmmax="VMUNLIMITED";		# handle 2-2n, 3-3n, etc. as if just 2-n, 3-n, etc.
+#print "Set vmmax to " vmmax >"/dev/tty"
+	}
+
+	match($0,"VERS=\"[^\"]*\"");
+	version=substr($0,RSTART+length("VERS=\""),RLENGTH-length("VERS=\"")-1);
+	
+	if (match(version,"RET")) {
+		retired="true"
+	}
+	else {
+		retired="false"
+	}
+
+	renderAsString="false"
+	if (match($0,"RenderAsString=\"[^\"]*\""))
+		renderAsString=substr($0,RSTART+length("RenderAsString=\""),
+			RLENGTH-length("RenderAsString=\"")-1);
+
+	if (renderAsString == "true" && vr != "OB") {
+		print "Warning - (0x" group ",0x" element ",\"" owner "\") renderAsString only valid for OB VR not " vr >"/dev/tty"
+	}
+
+	if (role == "constant") {
+		if (owner == "") {
+			print "#define\t" keyword "_GROUP\t0x" group
+			print "#define\t" keyword "_ELEMENT\t0x" element
+		}
+	}
+	else if (role == "table") {
+		print "\t0x" group ",0x" element ",0x" privateblock ",\"" vr "\"," vmmin "," vmmax ",\"" owner "\",\"" keyword "\",\"" name "\"," retired "," renderAsString ","
+	}
+
+	}
+
+END {
+	if (role == "constant") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+	if (role == "table") {
+		print "\t0, 0, 0, NULL, 0, 0, NULL, NULL, NULL, false, false"
+		print "};"
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/elmtojava_DicomDictionary_CreateFullNameByTag.awk b/libsrc/support/elmtojava_DicomDictionary_CreateFullNameByTag.awk
new file mode 100644
index 0000000..47874c1
--- /dev/null
+++ b/libsrc/support/elmtojava_DicomDictionary_CreateFullNameByTag.awk
@@ -0,0 +1,29 @@
+#  elmtojava_DicomDictionary_CreateFullNameByTag.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create Java from element dictionary template 
+
+NR==1	{
+	print "\tprotected void createFullNameByTag() {"
+	print ""
+	print "\t\tfullNameByTag = new HashMap(100);"
+	print ""
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	print "\t\tfullNameByTag.put(TagFromName." keyword ",\"" name "\");"
+}
+
+END {
+	print "\t}"
+}
+
diff --git a/libsrc/support/elmtojava_DicomDictionary_CreateIEByTag.awk b/libsrc/support/elmtojava_DicomDictionary_CreateIEByTag.awk
new file mode 100644
index 0000000..fa1deba
--- /dev/null
+++ b/libsrc/support/elmtojava_DicomDictionary_CreateIEByTag.awk
@@ -0,0 +1,309 @@
+#  elmtojava_DicomDictionary_CreateIEByTag.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+NR==1	{
+	if (role != "java" && role != "csv") {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	trace=0
+	emitFrameLevel=0
+	
+	if (role == "java") {
+		print "\tprotected void createInformationEntityByTag() {"
+		print ""
+		print "\t\tinformationEntityByTag = new HashMap(100);"
+		print ""
+	}
+	else if (role = "csv") {
+		#print "\"Element\",\"IE\""
+	}
+	
+	predefinedIEByName["StudyInstanceUID"]="STUDY";
+	predefinedIEByName["SeriesInstanceUID"]="SERIES";
+	predefinedIEByName["SOPInstanceUID"]="INSTANCE";
+	predefinedIEByName["SOPClassUID"]="INSTANCE";
+	predefinedIEByName["TransferSyntaxUID"]="INSTANCE";
+	predefinedIEByName["SourceApplicationEntityTitle"]="INSTANCE";
+	predefinedIEByName["InstanceNumber"]="CONCATENATION";
+	predefinedIEByName["ConcatenationUID"]="CONCATENATION";
+	predefinedIEByName["InConcatenationTotalNumber"]="CONCATENATION";
+	predefinedIEByName["NumberOfPatientRelatedStudies"]="PATIENT";
+	predefinedIEByName["NumberOfPatientRelatedSeries"]="PATIENT";
+	predefinedIEByName["NumberOfPatientRelatedInstances"]="PATIENT";
+	predefinedIEByName["NumberOfStudyRelatedSeries"]="STUDY";
+	predefinedIEByName["NumberOfStudyRelatedInstances"]="STUDY";
+	predefinedIEByName["NumberOfSeriesRelatedInstances"]="SERIES";
+	predefinedIEByName["ModalitiesInStudy"]="STUDY";
+	predefinedIEByName["SOPClassesInStudy"]="STUDY";
+	predefinedIEByName["OtherStudyNumbers"]="STUDY";		# for IHE Query Images transaction
+	predefinedIEByName["InterpretationAuthor"]="STUDY";		# for IHE Query Images transaction
+	predefinedIEByName["AccessionNumber"]="STUDY";			# is used within references at instance level in key objects
+	predefinedIEByName["IssuerOfAccessionNumberSequence"]="STUDY";
+
+	# supress various generic references ...
+	
+	predefinedIEByName["ContentItemModifierSequence"]="";
+	predefinedIEByName["ProtocolContextSequence"]="";
+	predefinedIEByName["PurposeOfReferenceCodeSequence"]="";
+	predefinedIEByName["ReferencedSOPClassUID"]="";
+	predefinedIEByName["ReferencedSOPInstanceUID"]="";
+	predefinedIEByName["ReferencedStudySequence"]="";
+	predefinedIEByName["ReferencedImageSequence"]="";
+
+	# supress or declare (at lowest level) series versus instance or frame conflicts ...
+
+	predefinedIEByName["ViewPosition"]="INSTANCE";
+	predefinedIEByName["InstitutionAddress"]="SERIES";		
+	predefinedIEByName["InstitutionName"]="SERIES";
+	predefinedIEByName["InstitutionCodeSequence"]="SERIES";
+
+	predefinedIEByName["AcquisitionStartCondition"]="INSTANCE";
+	predefinedIEByName["AcquisitionTerminationCondition"]="INSTANCE";
+	predefinedIEByName["CollimatorType"]="INSTANCE";
+	predefinedIEByName["CoincidenceWindowWidth"]="INSTANCE";
+	predefinedIEByName["CountsSource"]="INSTANCE";
+	predefinedIEByName["EnergyWindowRangeSequence"]="INSTANCE";
+	predefinedIEByName["RandomsCorrectionMethod"]="INSTANCE";
+	predefinedIEByName["ScatterCorrectionMethod"]="INSTANCE";
+	
+	predefinedIEByName["BeatRejectionFlag"]="";
+	predefinedIEByName["ConversionType"]="";
+	predefinedIEByName["ConvolutionKernel"]="";
+	predefinedIEByName["CorrectedImage"]="";
+	predefinedIEByName["FieldOfViewDimensions"]="";
+	predefinedIEByName["FieldOfViewShape"]="";
+	predefinedIEByName["FilterType"]="";
+	
+	predefinedIEByName["FocalSpots"]="INSTANCE";
+	
+	predefinedIEByName["GantryDetectorTilt"]="";
+	predefinedIEByName["HeartRate"]="";
+	predefinedIEByName["InterventionDrugInformationSequence"]="";
+	predefinedIEByName["NumberOfRRIntervals"]="";
+	predefinedIEByName["NumberOfSlices"]="";
+	predefinedIEByName["NumberOfTimeSlots"]="";
+	predefinedIEByName["PVCRejection"]="";
+	predefinedIEByName["PatientGantryRelationshipCodeSequence"]="";
+	predefinedIEByName["PatientOrientationCodeSequence"]="";
+	predefinedIEByName["PatientPosition"]="";
+	predefinedIEByName["RadiopharmaceuticalInformationSequence"]="";
+	predefinedIEByName["ReconstructionDiameter"]="";
+	predefinedIEByName["SkipBeats"]="";
+	predefinedIEByName["TriggerSourceOrType"]="";
+	predefinedIEByName["TypeOfDetectorMotion"]="";
+	predefinedIEByName["CardiacFramingType"]="";
+
+	# do not need to actively supress frame versus instance conflicts caused by enhanced multi-frame family
+	# since the refusal to descend into sequences mitigates this problem
+
+	iodcomp=""
+	profile=""
+	ie=""
+	module=""
+	macro=""
+	macroie=""
+	
+	withinSequence=0
+}
+
+/^[ 	]*CompositeIOD=/ {
+	iodcomp=""
+	if (match($0,"CompositeIOD=\"[^\"]*\""))
+		iodcomp=substr($0,RSTART+length("CompositeIOD=\""),
+			RLENGTH-length("CompositeIOD=\"")-1);
+
+	profile=""
+	if (match($0,"Profile=\"[^\"]*\""))
+		profile=substr($0,RSTART+length("Profile=\""),
+			RLENGTH-length("Profile=\"")-1);
+
+	if (trace) print "(CompositeIOD): iodcomp=" iodcomp " profile=" profile >"/dev/stderr"
+}
+
+/^[ 	]*CompositeIODEnd/ {
+	if (trace) print "(CompositeIODEnd):" >"/dev/stderr"
+	
+	iodcomp=""
+	profile=""
+	module=""		# since no corresponding ModuleEnd in IODs ... else last module in IE in IOD carries into first module definition
+}
+
+/^[ 	]*InformationEntity=/ {
+	ie=""
+	if (match($0,"InformationEntity=\"[^\"]*\""))
+		ie=substr($0,RSTART+length("InformationEntity=\""),
+			RLENGTH-length("InformationEntity=\"")-1);
+
+	if (trace) print "(InformationEntity): ie=" ie " profile=" profile >"/dev/stderr"
+
+	if (profile != "") {
+		if (trace) print "Supressing ie " ie " in " iodcomp " because of profile " profile >"/dev/stderr"
+		ie=""	# supress information that occurs in profiles, since for convenience it may be at wrong level (e.g., always instance), e.g., IHEMammoProfile, DentalImageOnMediaProfile
+	}
+}
+
+/^[ 	]*InformationEntityEnd/ {
+	if (trace) print "(InformationEntityEnd):" >"/dev/stderr"
+	
+	ie=""
+	module=""		# since no corresponding ModuleEnd in IODs ... else last module in IE in IOD carries into first module definition
+}
+
+/^[ 	]*DefineMacro=/ {
+	macro=""
+	if (match($0,"DefineMacro=\"[^\"]*\""))
+		macroie=substr($0,RSTART+length("DefineMacro=\""),
+			RLENGTH-length("DefineMacro=\"")-1);
+
+	macroie=""
+	if (match($0,"InformationEntity=\"[^\"]*\""))
+		macroie=substr($0,RSTART+length("InformationEntity=\""),
+			RLENGTH-length("InformationEntity=\"")-1);
+
+	if (trace) print "(DefineMacro): macro=" macro " macroie=" macroie >"/dev/stderr"
+}
+
+/^[ 	]*MacroEnd/ {
+	if (trace) print "(MacroEnd):" >"/dev/stderr"
+	
+	if (withinSequence != 0) {
+		print "Error - unterminated sequence " sequence " within macro " macro >"/dev/stderr"
+	}
+	macro=""
+	macroie=""
+}
+
+/^[ 	]*Module/ {
+
+	module=""
+	if (match($0,"Module=\"[^\"]*\""))
+		module=substr($0,RSTART+length("Module=\""),
+			RLENGTH-length("Module=\"")-1);
+
+	if (trace) print "(Module): module=" module " ie=" ie >"/dev/stderr"
+                        
+	if (ie != "") {
+		ieByModule[module]=ie;
+	}
+}
+
+/^[ 	]*ModuleEnd/ {
+	if (trace) print "(ModuleEnd):" >"/dev/stderr"
+	
+	if (withinSequence != 0) {
+		print "Error - unterminated sequence " sequence " within module " module >"/dev/stderr"
+	}
+	module=""
+}
+
+/^[ 	]*SequenceEnd/ {
+	if (trace) print "(SequenceEnd):" >"/dev/stderr"
+	
+	--withinSequence
+}
+
+/^[ 	]*(Name|Sequence)=/ {
+	
+	name=""
+	if (match($0,"Name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+
+	sequence=""
+	if (match($0,"Sequence=\"[^\"]*\"")) {
+		sequence=substr($0,RSTART+length("Sequence=\""),
+			RLENGTH-length("Sequence=\"")-1);
+	}
+	
+	if (trace) print "(Name|Sequence): name=" name " sequence=" sequence " in module=" module " macro=" macro " macroie=" macroie >"/dev/stderr"
+
+	if (name == "" && sequence != "" && sequence != "BiplaneSequence") {
+		name=sequence
+	}
+
+	if (withinSequence > 0) {
+		if (trace) print "Skipping " name " within sequence in " module macro >"/dev/stderr"
+		if (sequence  != "") {
+			++withinSequence
+		}
+		next
+	}
+	else {
+		if (trace) print "Not skipping " name " since not within sequence in " module macro >"/dev/stderr"
+	}
+	
+	if (sequence  != "") {
+		++withinSequence
+	}
+	
+	if (name != "" && (module != "" || macroie != "")) {
+		if (trace) print "Doing " name " in " module macro >"/dev/stderr"
+		if (!(name in predefinedIEByName)) {		# else will be written out in bulk at the end
+			if (macroie != "") {
+				ourie=macroie
+			}
+			else {
+				ourie=ieByModule[module];
+			}
+			useie="";
+			if (ourie == "Patient") useie="PATIENT"
+			else if (ourie == "Study") useie="STUDY"
+			else if (ourie == "Series") useie="SERIES"
+			else if (ourie == "Equipment") useie="SERIES"
+			else if (ourie == "FrameOfReference") useie="SERIES"
+			else if (ourie == "Image") useie="INSTANCE"
+			else if (ourie == "Document") useie="INSTANCE"
+			else if (ourie == "Waveform") useie="INSTANCE"
+			else if (ourie == "Presentation") useie="INSTANCE"
+			else if (ourie == "Instance") useie="INSTANCE"
+			else if (ourie == "Surface") useie="INSTANCE"
+			else if (ourie == "Frame") {
+				if (emitFrameLevel) {
+					useie="FRAME"
+				}
+				else {
+					useie="INSTANCE"
+				}
+			}
+			else if (ourie == "FunctionalGroup" && emitFrameLevel) useie="FRAME"
+			
+			#else ignore Curve, Directory, File, ModalityLUT, Overlay, Plan, StructureSet, TreatmentRecord, VOILUT, etc.
+
+			if (useie != "") {
+				if (ieByName[name] != "") {
+					if (useie != ieByName[name]) {
+						print "Error - different IE specified for " name " - " useie " (" ourie " in " module macro "), conflicts with first encountered " ieByName[name] " - using the latter"  >"/dev/stderr"
+						#print name " " useie " " ieByName[name] >"/dev/stderr"
+					}
+					next;
+				}
+				ieByName[name]=useie;
+				if (role == "java") {
+					print "\t\tinformationEntityByTag.put(TagFromName." name ",InformationEntity." useie ");"
+				}
+				else if (role = "csv") {
+					print name "," useie
+				}
+			}
+		}
+	}
+}
+
+END {
+	for (name in predefinedIEByName) {
+		useie=predefinedIEByName[name]
+		if (useie != "") {
+			if (role == "java") {
+				print "\t\tinformationEntityByTag.put(TagFromName." name ",InformationEntity." useie ");"
+			}
+			else if (role = "csv") {
+				print name "," useie
+			}
+		}
+	}
+	if (role == "java") {
+		print "\t}"
+		print ""
+	}
+}
+
diff --git a/libsrc/support/elmtojava_DicomDictionary_CreateNameByTag.awk b/libsrc/support/elmtojava_DicomDictionary_CreateNameByTag.awk
new file mode 100644
index 0000000..7331128
--- /dev/null
+++ b/libsrc/support/elmtojava_DicomDictionary_CreateNameByTag.awk
@@ -0,0 +1,65 @@
+#  elmtojava_DicomDictionary_CreateNameByTag.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create Java from element dictionary template 
+
+NR==1	{
+	print "\tprotected void createNameByTag() {"
+	print ""
+	print "\t\tnameByTag = new HashMap(100);"
+	print ""
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	gsub("\&","\\\&",name);
+	gsub("'","\\\'",name);
+	gsub("\"","\\\"",name);
+	gsub("<","\\\<",name);
+	gsub(">","\\\>",name);
+
+	match($0,"VR=\"[^\"]*\"");
+	vr=substr($0,RSTART+length("VR=\""),RLENGTH-length("VR=\"")-1);
+
+	match($0,"VM=\"[^\"]*\"");
+	if (vr == "US or SS") vr= "XS";
+	if (vr == "US or SS or OW") vr= "XO";
+	if (vr == "US\\US or SS\\US") vr = "XS";
+	if (vr == "OW/OB") vr = "OX";
+
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="n";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="n";
+	}
+
+        print "\t\tnameByTag.put(TagFromName." keyword ",\"" keyword "\");"
+	}
+
+END {
+	print "\t}"
+}
+
diff --git a/libsrc/support/elmtojava_DicomDictionary_CreateTagByName.awk b/libsrc/support/elmtojava_DicomDictionary_CreateTagByName.awk
new file mode 100644
index 0000000..b6f946e
--- /dev/null
+++ b/libsrc/support/elmtojava_DicomDictionary_CreateTagByName.awk
@@ -0,0 +1,137 @@
+#  elmtojava_DicomDictionary_CreateTagByName.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create Java from element dictionary template 
+
+NR==1	{
+	print "\tprotected void createTagByName() {"
+	print ""
+	print "\t\ttagByName = new HashMap(100);"
+	print ""
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	gsub("\&","\\\&",name);
+	gsub("'","\\\'",name);
+	gsub("\"","\\\"",name);
+	gsub("<","\\\<",name);
+	gsub(">","\\\>",name);
+
+	match($0,"VR=\"[^\"]*\"");
+	vr=substr($0,RSTART+length("VR=\""),RLENGTH-length("VR=\"")-1);
+
+	match($0,"VM=\"[^\"]*\"");
+	if (vr == "US or SS") vr= "XS";
+	if (vr == "US or SS or OW") vr= "XO";
+	if (vr == "US\\US or SS\\US") vr = "XS";
+	if (vr == "OW/OB") vr = "OX";
+
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="n";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="n";
+	}
+
+	print "\t\ttagByName.put(\"" keyword "\",TagFromName." keyword ");"
+	}
+
+END {
+	print "\t\t"
+	print "\t\t// include old toolkit keywords prior to CP 850 establishment of official keywords, in case old code uses them ..."
+	print "\t\t"
+	print "\t\ttagByName.put(\"FileSetCharacterSet\",TagFromName.SpecificCharacterSetOfFileSetDescriptorFile);"
+	print "\t\ttagByName.put(\"RootDirectoryFirstRecord\",TagFromName.OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity);"
+	print "\t\ttagByName.put(\"RootDirectoryLastRecord\",TagFromName.OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity);"
+	print "\t\ttagByName.put(\"NextDirectoryRecordOffset\",TagFromName.OffsetOfTheNextDirectoryRecord);"
+	print "\t\ttagByName.put(\"LowerLevelDirectoryOffset\",TagFromName.OffsetOfReferencedLowerLevelDirectoryEntity);"
+	print "\t\ttagByName.put(\"ReferringPhysicianTelephoneNumber\",TagFromName.ReferringPhysicianTelephoneNumbers);"
+	print "\t\ttagByName.put(\"PhysicianOfRecord\",TagFromName.PhysiciansOfRecord);"
+	print "\t\ttagByName.put(\"PhysicianOfRecordIdentificationSequence\",TagFromName.PhysiciansOfRecordIdentificationSequence);"
+	print "\t\ttagByName.put(\"PhysicianReadingStudy\",TagFromName.NameOfPhysiciansReadingStudy);"
+	print "\t\ttagByName.put(\"PhysicianReadingStudyIdentificationSequence\",TagFromName.PhysiciansReadingStudyIdentificationSequence);"
+	print "\t\ttagByName.put(\"OperatorName\",TagFromName.OperatorsName);"
+	print "\t\ttagByName.put(\"OldLossyImageCompression\",TagFromName.LossyImageCompressionRetired);"
+	print "\t\ttagByName.put(\"EventElapsedTime\",TagFromName.EventElapsedTimes);"
+	print "\t\ttagByName.put(\"EventTimerName\",TagFromName.EventTimerNames);"
+	print "\t\ttagByName.put(\"OtherPatientID\",TagFromName.OtherPatientIDs);"
+	print "\t\ttagByName.put(\"OtherPatientName\",TagFromName.OtherPatientNames);"
+	print "\t\ttagByName.put(\"OtherPatientIDSequence\",TagFromName.OtherPatientIDsSequence);"
+	print "\t\ttagByName.put(\"PatientTelephoneNumber\",TagFromName.PatientTelephoneNumbers);"
+	print "\t\ttagByName.put(\"EchoNumber\",TagFromName.EchoNumbers);"
+	print "\t\ttagByName.put(\"SecondaryCaptureDeviceSoftwareVersion\",TagFromName.SecondaryCaptureDeviceSoftwareVersions);"
+	print "\t\ttagByName.put(\"SoftwareVersion\",TagFromName.SoftwareVersions);"
+	print "\t\ttagByName.put(\"FocalSpot\",TagFromName.FocalSpots);"
+	print "\t\ttagByName.put(\"VerticesOfPolygonalShutter\",TagFromName.VerticesOfThePolygonalShutter);"
+	print "\t\ttagByName.put(\"VerticesOfPolygonalCollimator\",TagFromName.VerticesOfThePolygonalCollimator);"
+	print "\t\ttagByName.put(\"MultiplanarExcitation\",TagFromName.MultiPlanarExcitation);"
+	print "\t\ttagByName.put(\"MetaboliteCodeSequence\",TagFromName.MetaboliteMapCodeSequence);"
+	print "\t\ttagByName.put(\"ChemicalShiftMinimumIntegrationLimitInPPM\",TagFromName.ChemicalShiftMinimumIntegrationLimitInppm);"
+	print "\t\ttagByName.put(\"ChemicalShiftMaximumIntegrationLimitInPPM\",TagFromName.ChemicalShiftMaximumIntegrationLimitInppm);"
+	print "\t\ttagByName.put(\"VerticesOfPolygonalExposureControlSensingRegion\",TagFromName.VerticesOfThePolygonalExposureControlSensingRegion);"
+	print "\t\ttagByName.put(\"DiffusionBMatrixValueXX\",TagFromName.DiffusionBValueXX);"
+	print "\t\ttagByName.put(\"DiffusionBMatrixValueXY\",TagFromName.DiffusionBValueXY);"
+	print "\t\ttagByName.put(\"DiffusionBMatrixValueXZ\",TagFromName.DiffusionBValueXZ);"
+	print "\t\ttagByName.put(\"DiffusionBMatrixValueYY\",TagFromName.DiffusionBValueYY);"
+	print "\t\ttagByName.put(\"DiffusionBMatrixValueYZ\",TagFromName.DiffusionBValueYZ);"
+	print "\t\ttagByName.put(\"DiffusionBMatrixValueZZ\",TagFromName.DiffusionBValueZZ);"
+	print "\t\ttagByName.put(\"ReportNumberTrial\",TagFromName.ReportNumber);"
+	print "\t\ttagByName.put(\"PatientFrameofReferenceSource\",TagFromName.PatientFrameOfReferenceSource);"
+	print "\t\ttagByName.put(\"PatientEyeMovementCommandedCodeSequence\",TagFromName.PatientEyeMovementCommandCodeSequence);"
+	print "\t\ttagByName.put(\"AxialLengthOfEye\",TagFromName.AxialLengthOfTheEye);"
+	print "\t\ttagByName.put(\"SmallestPixelValueInPlane\",TagFromName.SmallestImagePixelValueInPlane);"
+	print "\t\ttagByName.put(\"LargestPixelValueInPlane\",TagFromName.LargestImagePixelValueInPlane);"
+	print "\t\ttagByName.put(\"BiplaneAcquisitionSequence\",TagFromName.BiPlaneAcquisitionSequence);"
+	print "\t\ttagByName.put(\"MaskPointer\",TagFromName.MaskPointers);"
+	print "\t\ttagByName.put(\"MultiframePresentationSequence\",TagFromName.MultiFramePresentationSequence);"
+	print "\t\ttagByName.put(\"CommentsOnPerformedProcedureStep\",TagFromName.CommentsOnThePerformedProcedureStep);"
+	print "\t\ttagByName.put(\"CommentsOnScheduledProcedureStep\",TagFromName.CommentsOnTheScheduledProcedureStep);"
+	print "\t\ttagByName.put(\"ReasonForRequestedProcedure\",TagFromName.ReasonForTheRequestedProcedure);"
+	print "\t\ttagByName.put(\"PlacerOrderNumberOfProcedure\",TagFromName.PlacerOrderNumberProcedure);"
+	print "\t\ttagByName.put(\"FillerOrderNumberOfProcedure\",TagFromName.FillerOrderNumberProcedure);"
+	print "\t\ttagByName.put(\"ReasonForImagingServiceRequest\",TagFromName.ReasonForTheImagingServiceRequest);"
+	print "\t\ttagByName.put(\"PlacerOrderNumberOfImagingServiceRequestRetired\",TagFromName.PlacerOrderNumberImagingServiceRequestRetired);"
+	print "\t\ttagByName.put(\"FillerOrderNumberOfImagingServiceRequestRetired\",TagFromName.FillerOrderNumberImagingServiceRequestRetired);"
+	print "\t\ttagByName.put(\"PlacerOrderNumberOfImagingServiceRequest\",TagFromName.PlacerOrderNumberImagingServiceRequest);"
+	print "\t\ttagByName.put(\"FillerOrderNumberOfImagingServiceRequest\",TagFromName.FillerOrderNumberImagingServiceRequest);"
+	print "\t\ttagByName.put(\"ScheduledProcedureStepStartDateAndTime\",TagFromName.ScheduledProcedureStepStartDateTime);"
+	print "\t\ttagByName.put(\"ScheduledProcedureStepModificationDateAndTime\",TagFromName.ScheduledProcedureStepModificationDateTime);"
+	print "\t\ttagByName.put(\"ExpectedCompletionDateAndTime\",TagFromName.ExpectedCompletionDateTime);"
+	print "\t\ttagByName.put(\"HumanPerformersOrganization\",TagFromName.HumanPerformerOrganization);"
+	print "\t\ttagByName.put(\"HumanPerformersName\",TagFromName.HumanPerformerName);"
+	print "\t\ttagByName.put(\"ImageRotationTrial\",TagFromName.ImageRotationRetired);"
+	print "\t\ttagByName.put(\"ContentCreatorsName\",TagFromName.ContentCreatorName);"
+	print "\t\ttagByName.put(\"ContentCreatorsIdentificationCodeSequence\",TagFromName.ContentCreatorIdentificationCodeSequence);"
+	print "\t\ttagByName.put(\"PseudocolorType\",TagFromName.PseudoColorType);"
+	print "\t\ttagByName.put(\"TopicKeyWords\",TagFromName.TopicKeywords);"
+	print "\t\ttagByName.put(\"SOPAuthorizationDateAndTime\",TagFromName.SOPAuthorizationDateTime);"
+	print "\t\ttagByName.put(\"ReferencedPrintJobSequencePull\",TagFromName.ReferencedPrintJobSequencePullStoredPrint);"
+	print "\t\ttagByName.put(\"ReferencedPrintJobSequenceQueue\",TagFromName.ReferencedPrintJobSequence);"
+	print "\t\t"
+	print "\t}"
+	print ""
+}
+
diff --git a/libsrc/support/elmtojava_DicomDictionary_CreateTagList.awk b/libsrc/support/elmtojava_DicomDictionary_CreateTagList.awk
new file mode 100644
index 0000000..bc09159
--- /dev/null
+++ b/libsrc/support/elmtojava_DicomDictionary_CreateTagList.awk
@@ -0,0 +1,66 @@
+#  elmtojava_DicomDictionary_CreateTagList.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create Java from element dictionary template 
+
+NR==1	{
+	print "\tprotected void createTagList() {"
+	print ""
+	print "\t\ttagList = new TreeSet();	// sorted, based on AttributeTag's implementation of Comparable"
+	print ""
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	gsub("\&","\\\&",name);
+	gsub("'","\\\'",name);
+	gsub("\"","\\\"",name);
+	gsub("<","\\\<",name);
+	gsub(">","\\\>",name);
+
+	match($0,"VR=\"[^\"]*\"");
+	vr=substr($0,RSTART+length("VR=\""),RLENGTH-length("VR=\"")-1);
+
+	match($0,"VM=\"[^\"]*\"");
+	if (vr == "US or SS") vr= "XS";
+	if (vr == "US or SS or OW") vr= "XO";
+	if (vr == "US\\US or SS\\US") vr = "XS";
+	if (vr == "OW/OB") vr = "OX";
+
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="n";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="n";
+	}
+
+        print "\t\ttagList.add(TagFromName." keyword ");"
+	}
+
+END {
+	print "\t}"
+	print ""
+}
+
diff --git a/libsrc/support/elmtojava_DicomDictionary_CreateVRByTag.awk b/libsrc/support/elmtojava_DicomDictionary_CreateVRByTag.awk
new file mode 100644
index 0000000..1dc8d0d
--- /dev/null
+++ b/libsrc/support/elmtojava_DicomDictionary_CreateVRByTag.awk
@@ -0,0 +1,67 @@
+#  elmtojava_DicomDictionary_CreateVRByTag.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create Java from element dictionary template 
+
+NR==1	{
+	print "\tprotected void createValueRepresentationsByTag() {"
+	print ""
+	print "\t\tvalueRepresentationsByTag = new HashMap(100);"
+	print ""
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	gsub("\&","\\\&",name);
+	gsub("'","\\\'",name);
+	gsub("\"","\\\"",name);
+	gsub("<","\\\<",name);
+	gsub(">","\\\>",name);
+
+	match($0,"VR=\"[^\"]*\"");
+	vr=substr($0,RSTART+length("VR=\""),RLENGTH-length("VR=\"")-1);
+
+	match($0,"VM=\"[^\"]*\"");
+	if (vr == "US or SS") vr= "XS";
+	if (vr == "US or OW") vr= "XO";
+	if (vr == "US or SS or OW") vr= "XO";
+	if (vr == "US\\US or SS\\US") vr = "XS";
+	if (vr == "OW/OB") vr = "OX";
+
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="n";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="n";
+	}
+
+        print "\t\tvalueRepresentationsByTag.put(TagFromName." keyword ",ValueRepresentation." vr ");"
+	}
+
+END {
+	print "\t}"
+	print ""
+}
+
diff --git a/libsrc/support/elmtojava_TagFromName.awk b/libsrc/support/elmtojava_TagFromName.awk
new file mode 100755
index 0000000..8b33fb8
--- /dev/null
+++ b/libsrc/support/elmtojava_TagFromName.awk
@@ -0,0 +1,111 @@
+#  elmtojava_TagFromName.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create XML from element dictionary template 
+
+NR==1	{
+	print "/* Copyright (c) 2001-2011, David A. Clunie DBA Pixelmed Publishing. All rights reserved. */"
+	print ""
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "package com.pixelmed.dicom;"
+	print ""
+	print "public class TagFromName {"
+	print ""
+	print "private static final String identString = \"@(#) $Header: /userland/cvs/dicom3tools/libsrc/support/elmtojava_TagFromName.awk,v 1.7 2015/08/26 13:00:43 dclunie Exp $\";"
+	print ""
+}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	print "\tstatic public AttributeTag " keyword " = new AttributeTag(0x" group ",0x" element ");"
+}
+
+END {
+	print "\t"
+	print "\t// include old toolkit keywords prior to CP 850 establishment of official keywords, in case old code uses them ..."
+	print "\t"
+	print "\tstatic public AttributeTag FileSetCharacterSet = new AttributeTag(0x0004,0x1142);"
+	print "\tstatic public AttributeTag RootDirectoryFirstRecord = new AttributeTag(0x0004,0x1200);"
+	print "\tstatic public AttributeTag RootDirectoryLastRecord = new AttributeTag(0x0004,0x1202);"
+	print "\tstatic public AttributeTag NextDirectoryRecordOffset = new AttributeTag(0x0004,0x1400);"
+	print "\tstatic public AttributeTag LowerLevelDirectoryOffset = new AttributeTag(0x0004,0x1420);"
+	print "\tstatic public AttributeTag OldDataSetType = new AttributeTag(0x0008,0x0040);"
+	print "\tstatic public AttributeTag OldDataSetSubtype = new AttributeTag(0x0008,0x0041);"
+	print "\tstatic public AttributeTag NuclearMedicineSeriesTypeRetired = new AttributeTag(0x0008,0x0042);"
+	print "\tstatic public AttributeTag ReferringPhysicianTelephoneNumber = new AttributeTag(0x0008,0x0094);"
+	print "\tstatic public AttributeTag PhysicianOfRecord = new AttributeTag(0x0008,0x1048);"
+	print "\tstatic public AttributeTag PhysicianOfRecordIdentificationSequence = new AttributeTag(0x0008,0x1049);"
+	print "\tstatic public AttributeTag PhysicianReadingStudy = new AttributeTag(0x0008,0x1060);"
+	print "\tstatic public AttributeTag PhysicianReadingStudyIdentificationSequence = new AttributeTag(0x0008,0x1062);"
+	print "\tstatic public AttributeTag OperatorName = new AttributeTag(0x0008,0x1070);"
+	print "\tstatic public AttributeTag OldLossyImageCompression = new AttributeTag(0x0008,0x2110);"
+	print "\tstatic public AttributeTag EventElapsedTime = new AttributeTag(0x0008,0x2130);"
+	print "\tstatic public AttributeTag EventTimerName = new AttributeTag(0x0008,0x2132);"
+	print "\tstatic public AttributeTag OtherPatientID = new AttributeTag(0x0010,0x1000);"
+	print "\tstatic public AttributeTag OtherPatientName = new AttributeTag(0x0010,0x1001);"
+	print "\tstatic public AttributeTag OtherPatientIDSequence = new AttributeTag(0x0010,0x1002);"
+	print "\tstatic public AttributeTag PatientTelephoneNumber = new AttributeTag(0x0010,0x2154);"
+	print "\tstatic public AttributeTag EchoNumber = new AttributeTag(0x0018,0x0086);"
+	print "\tstatic public AttributeTag SecondaryCaptureDeviceSoftwareVersion = new AttributeTag(0x0018,0x1019);"
+	print "\tstatic public AttributeTag SoftwareVersion = new AttributeTag(0x0018,0x1020);"
+	print "\tstatic public AttributeTag FocalSpot = new AttributeTag(0x0018,0x1190);"
+	print "\tstatic public AttributeTag VerticesOfPolygonalShutter = new AttributeTag(0x0018,0x1620);"
+	print "\tstatic public AttributeTag VerticesOfPolygonalCollimator = new AttributeTag(0x0018,0x1720);"
+	print "\tstatic public AttributeTag MultiplanarExcitation = new AttributeTag(0x0018,0x9012);"
+	print "\tstatic public AttributeTag MetaboliteCodeSequence = new AttributeTag(0x0018,0x9083);"
+	print "\tstatic public AttributeTag ChemicalShiftMinimumIntegrationLimitInPPM = new AttributeTag(0x0018,0x9295);"
+	print "\tstatic public AttributeTag ChemicalShiftMaximumIntegrationLimitInPPM = new AttributeTag(0x0018,0x9296);"
+	print "\tstatic public AttributeTag VerticesOfPolygonalExposureControlSensingRegion = new AttributeTag(0x0018,0x9442);"
+	print "\tstatic public AttributeTag DiffusionBMatrixValueXX = new AttributeTag(0x0018,0x9602);"
+	print "\tstatic public AttributeTag DiffusionBMatrixValueXY = new AttributeTag(0x0018,0x9603);"
+	print "\tstatic public AttributeTag DiffusionBMatrixValueXZ = new AttributeTag(0x0018,0x9604);"
+	print "\tstatic public AttributeTag DiffusionBMatrixValueYY = new AttributeTag(0x0018,0x9605);"
+	print "\tstatic public AttributeTag DiffusionBMatrixValueYZ = new AttributeTag(0x0018,0x9606);"
+	print "\tstatic public AttributeTag DiffusionBMatrixValueZZ = new AttributeTag(0x0018,0x9607);"
+	print "\tstatic public AttributeTag ReportNumberTrial = new AttributeTag(0x0020,0x00AA);"
+	print "\tstatic public AttributeTag PatientFrameofReferenceSource = new AttributeTag(0x0020,0x930C);"
+	print "\tstatic public AttributeTag PatientEyeMovementCommandedCodeSequence = new AttributeTag(0x0022,0x0006);"
+	print "\tstatic public AttributeTag AxialLengthOfEye = new AttributeTag(0x0022,0x0030);"
+	print "\tstatic public AttributeTag SmallestPixelValueInPlane = new AttributeTag(0x0028,0x0110);"
+	print "\tstatic public AttributeTag LargestPixelValueInPlane = new AttributeTag(0x0028,0x0111);"
+	print "\tstatic public AttributeTag BiplaneAcquisitionSequence = new AttributeTag(0x0028,0x5000);"
+	print "\tstatic public AttributeTag MaskPointer = new AttributeTag(0x0028,0x6030);"
+	print "\tstatic public AttributeTag MultiframePresentationSequence = new AttributeTag(0x0028,0x9505);"
+	print "\tstatic public AttributeTag CommentsOnPerformedProcedureStep = new AttributeTag(0x0040,0x0280);"
+	print "\tstatic public AttributeTag CommentsOnScheduledProcedureStep = new AttributeTag(0x0040,0x0400);"
+	print "\tstatic public AttributeTag ReasonForRequestedProcedure = new AttributeTag(0x0040,0x1002);"
+	print "\tstatic public AttributeTag PlacerOrderNumberOfProcedure = new AttributeTag(0x0040,0x1006);"
+	print "\tstatic public AttributeTag FillerOrderNumberOfProcedure = new AttributeTag(0x0040,0x1007);"
+	print "\tstatic public AttributeTag ReasonForImagingServiceRequest = new AttributeTag(0x0040,0x2001);"
+	print "\tstatic public AttributeTag PlacerOrderNumberOfImagingServiceRequestRetired = new AttributeTag(0x0040,0x2006);"
+	print "\tstatic public AttributeTag FillerOrderNumberOfImagingServiceRequestRetired = new AttributeTag(0x0040,0x2007);"
+	print "\tstatic public AttributeTag PlacerOrderNumberOfImagingServiceRequest = new AttributeTag(0x0040,0x2016);"
+	print "\tstatic public AttributeTag FillerOrderNumberOfImagingServiceRequest = new AttributeTag(0x0040,0x2017);"
+	print "\tstatic public AttributeTag ScheduledProcedureStepStartDateAndTime = new AttributeTag(0x0040,0x4005);"
+	print "\tstatic public AttributeTag ScheduledProcedureStepModificationDateAndTime = new AttributeTag(0x0040,0x4010);"
+	print "\tstatic public AttributeTag ExpectedCompletionDateAndTime = new AttributeTag(0x0040,0x4011);"
+	print "\tstatic public AttributeTag HumanPerformersOrganization = new AttributeTag(0x0040,0x4036);"
+	print "\tstatic public AttributeTag HumanPerformersName = new AttributeTag(0x0040,0x4037);"
+	print "\tstatic public AttributeTag RelationshipTypeCodeSequenceModifierTrial = new AttributeTag(0x0040,0xDB73);"
+	print "\tstatic public AttributeTag ImageRotationTrial = new AttributeTag(0x0070,0x0040);"
+	print "\tstatic public AttributeTag ContentCreatorsName = new AttributeTag(0x0070,0x0084);"
+	print "\tstatic public AttributeTag ContentCreatorsIdentificationCodeSequence = new AttributeTag(0x0070,0x0086);"
+	print "\tstatic public AttributeTag PseudocolorType = new AttributeTag(0x0072,0x0704);"
+	print "\tstatic public AttributeTag TopicKeyWords = new AttributeTag(0x0088,0x0912);"
+	print "\tstatic public AttributeTag SOPAuthorizationDateAndTime = new AttributeTag(0x0100,0x0420);"
+	print "\tstatic public AttributeTag ReferencedPrintJobSequencePull = new AttributeTag(0x2100,0x0500);"
+	print "\tstatic public AttributeTag ReferencedPrintJobSequenceQueue = new AttributeTag(0x2120,0x0070);"
+	print "}"
+}
+
diff --git a/libsrc/support/elmtoxml.awk b/libsrc/support/elmtoxml.awk
new file mode 100644
index 0000000..053e5a5
--- /dev/null
+++ b/libsrc/support/elmtoxml.awk
@@ -0,0 +1,76 @@
+#  elmtoxml.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create XML from element dictionary template 
+
+NR==1	{
+	print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
+	print "<!DOCTYPE DataDictionary ["
+	print "<!ELEMENT DataDictionary (DataElement*)>"
+	print "<!ELEMENT DataElement (Group,Element,VR,VMMin,VMMax,Keyword,Name)>"
+	print "<!ELEMENT Group (#PCDATA)>"
+	print "<!ELEMENT Element (#PCDATA)>"
+	print "<!ELEMENT VR (#PCDATA)>"
+	print "<!ELEMENT VMMin (#PCDATA)>"
+	print "<!ELEMENT VMMax (#PCDATA)>"
+	print "<!ELEMENT Keyword (#PCDATA)>"
+	print "<!ELEMENT Name (#PCDATA)>"
+	print "]>"
+	print ""
+	print "<DataDictionary xmlns:Dicom=\"http://www.nema.org/medical/dicom\">"
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*[(]/ {
+
+	match($0,"[(][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX],");
+	group=substr($0,RSTART+1,4);
+
+	match($0,",[0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX][0-9a-fA-FxX]");
+	element=substr($0,RSTART+1,4);
+
+	match($0,"Keyword=\"[^\"]*\"")
+	keyword=substr($0,RSTART+length("Keyword=\""),
+		RLENGTH-length("Keyword=\"")-1);
+
+	match($0,"Name=\"[^\"]*\"")
+	name=substr($0,RSTART+length("Name=\""),
+		RLENGTH-length("Name=\"")-1);
+
+	gsub("\&","\\\&",name);
+	gsub("'","\\\'",name);
+	gsub("\"","\\\"",name);
+	gsub("<","\\\<",name);
+	gsub(">","\\\>",name);
+
+	match($0,"VR=\"[^\"]*\"");
+	vr=substr($0,RSTART+length("VR=\""),RLENGTH-length("VR=\"")-1);
+
+	match($0,"VM=\"[^\"]*\"");
+	if (vr == "US or SS") vr= "XS";
+	if (vr == "US or SS or OW") vr= "XO";
+	if (vr == "US\\US or SS\\US") vr = "XS";
+	if (vr == "OW/OB") vr = "OX";
+
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="n";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="n";
+	}
+
+	print "\t<DataElement><Group>0x" group "</Group><Element>0x" element "</Element><VR>" vr "</VR><VMMin>" vmmin "</VMMin><VMMax>" vmmax "</VMMax><Keyword>" keyword "</Keyword><Name>" name "</Name></DataElement>"
+
+	}
+
+END {
+	print "</DataDictionary>"
+}
+
diff --git a/libsrc/support/extractiodandmodulerelationshipsbytag.awk b/libsrc/support/extractiodandmodulerelationshipsbytag.awk
new file mode 100644
index 0000000..1d28862
--- /dev/null
+++ b/libsrc/support/extractiodandmodulerelationshipsbytag.awk
@@ -0,0 +1,166 @@
+#  extractiodandmodulerelationshipsbytag.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+NR==1	{
+	gIod=""
+	gIe=""
+	gModule=""
+	gMacro=""
+}
+
+/^[ 	]*CompositeIOD=/ {
+	gIod=""
+	if (match($0,"CompositeIOD=\"[^\"]*\""))
+		gIod=substr($0,RSTART+length("CompositeIOD=\""),
+			RLENGTH-length("CompositeIOD=\"")-1);
+	if (gIod != "") {
+		gIodList[gIod]=1
+	}
+}
+
+/^[ 	]*CompositeIODEnd/ {
+	gIod=""
+	gModule=""			# we need this, because as we move from IOD template file to Module template file, the overloaded use of Module= changes from invocation to definition
+}
+
+/^[ 	]*InformationEntity=/ {
+	gIe=""
+	if (match($0,"InformationEntity=\"[^\"]*\""))
+		gIe=substr($0,RSTART+length("InformationEntity=\""),
+			RLENGTH-length("InformationEntity=\"")-1);
+	if (gIe != "") {
+		gIeList[gIe]=1
+	}
+}
+
+/^[ 	]*InformationEntityEnd/ {
+	gIe=""
+}
+
+/^[ 	]*DefineMacro=/ {
+	gMacro=""
+	if (match($0,"Macro=\"[^\"]*\""))
+		gMacro=substr($0,RSTART+length("Macro=\""),
+			RLENGTH-length("Macro=\"")-1);
+	if (gMacro != "") {
+		gMacroList[gMacro]=1
+		#print "Defining macro " gMacro >"/dev/stderr"
+	}
+}
+
+/^[ 	]*MacroEnd/ {
+	gMacro=""
+}
+
+/^[ 	]*InvokeMacro=/ {
+	useMacro=""
+	if (match($0,"InvokeMacro=\"[^\"]*\""))
+		useMacro=substr($0,RSTART+length("InvokeMacro=\""),
+			RLENGTH-length("InvokeMacro=\"")-1);
+	if (useMacro != "") {
+		#print "Invoking macro " useMacro >"/dev/stderr"
+		if (gModule != "") {
+			for (tryIOD in gIodList) {
+				if ((tryIOD,gModule) in gModulesByIOD_usage) {
+					if (useMacro in gMacroList) {
+						for (tryMacroAndName in gNamesByMacro_type) {
+							if (split(tryMacroAndName,subscripts,SUBSEP) == 2) {
+								if (useMacro == subscripts[1]) {
+									print subscripts[2] "," tryIOD "," gModule "," gModulesByIOD_usage[tryIOD,gModule] "," gNamesByMacro_path[useMacro,subscripts[2]] "," gNamesByMacro_type[useMacro,subscripts[2]] "," gNamesByMacro_vm[useMacro,subscripts[2]]
+									#print "Defining " subscripts[2] " in module " gModule " because of inclusion of " useMacro " (path = " gNamesByMacro_path[useMacro,subscripts[2]] ")" >"/dev/stderr"
+								}
+							}
+						}
+					}
+					else {
+						print "ERROR: undefined macro " useMacro " required in " gModule " in " tryIOD >"/dev/stderr"
+					}
+				}
+			}
+		}
+		else if (gMacro != "") {
+			# we are invoking a macro within another macro definition, so "expand" it 
+			if (useMacro in gMacroList) {
+				for (tryMacroAndName in gNamesByMacro_type) {
+					if (split(tryMacroAndName,subscripts,SUBSEP) == 2) {
+						if (useMacro == subscripts[1]) {
+							gNamesByMacro_type[gMacro,subscripts[2]]=gNamesByMacro_type[useMacro,subscripts[2]]
+							gNamesByMacro_vm[gMacro,subscripts[2]]=gNamesByMacro_vm[useMacro,subscripts[2]]
+							gNamesByMacro_path[gMacro,subscripts[2]]= gMacro "/" gNamesByMacro_path[useMacro,subscripts[2]]
+							#print "Defining " subscripts[2] " in macro " gMacro " because of inclusion of " useMacro " (path = " gNamesByMacro_path[gMacro,subscripts[2]] ")" >"/dev/stderr"
+						}
+					}
+				}
+			}
+			else {
+				print "ERROR: undefined macro " useMacro " required in " gMacro >"/dev/stderr"
+			}
+		}
+	}
+}
+
+
+/^[ 	]*Module/ {
+	gModule=""
+	if (match($0,"Module=\"[^\"]*\""))
+		gModule=substr($0,RSTART+length("Module=\""),
+			RLENGTH-length("Module=\"")-1);
+
+	usage=""
+	if (match($0,"Usage=\"[^\"]*\""))
+		usage=substr($0,RSTART+length("Usage=\""),
+			RLENGTH-length("Usage=\"")-1);
+
+	if (gModule != "") {
+		gModuleList[gModule]=1
+		if (gIod != "") {
+			gModulesByIOD_usage[gIod,gModule]=usage
+		}
+		# else we are doing the module.tpl file not the iodcomp.tpl file
+		# and this is the definition of the module rather than its use
+	}
+}
+
+/^[ 	]*ModuleEnd/ {
+	gModule=""
+}
+
+/^[ 	]*(Name|Sequence)=/ {
+	nameOrSequence=""
+	if (match($0,"Name=\"[^\"]*\""))
+		nameOrSequence=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+	if (match($0,"Sequence=\"[^\"]*\""))
+		nameOrSequence=substr($0,RSTART+length("Sequence=\""),
+			RLENGTH-length("Sequence=\"")-1);
+
+	type=""
+	if (match($0,"Type=\"[^\"]*\""))
+		type=substr($0,RSTART+length("Type=\""),
+			RLENGTH-length("Type=\"")-1);
+
+	vm=""
+	match($0,"VM=\"[^\"]*\"");
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+
+	if (!match($0,"Condition=\"Never")) {
+		if (nameOrSequence != "") {
+			if (gModule != "") {
+				for (tryIOD in gIodList) {
+					if ((tryIOD,gModule) in gModulesByIOD_usage) {
+						print nameOrSequence "," tryIOD "," gModule "," gModulesByIOD_usage[tryIOD,gModule] ",," type "," vm
+						#print "Adding " nameOrSequence " to module " gModule " in " tryIOD >"/dev/stderr"
+					}
+				}
+			}
+			if (gMacro != "") {
+				gNamesByMacro_type[gMacro,nameOrSequence]=type
+				gNamesByMacro_vm[gMacro,nameOrSequence]=vm
+				gNamesByMacro_path[gMacro,nameOrSequence]= gMacro
+				#print "Defining " nameOrSequence " in macro " gMacro " (path = " gNamesByMacro_path[gMacro,nameOrSequence] ")" >"/dev/stderr"
+			}
+		}
+	}
+}
+
+END {
+}
+
diff --git a/libsrc/support/inserttagumberbeforekeyword.sh b/libsrc/support/inserttagumberbeforekeyword.sh
new file mode 100755
index 0000000..64ee417
--- /dev/null
+++ b/libsrc/support/inserttagumberbeforekeyword.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# invoke as xargs -L 1 $0 dictionary
+#
+
+#DICTIONARY="elmdict/dicom3.tpl"
+DICTIONARY="$1"
+shift
+
+srcLine="$*"
+keyword=`echo "${srcLine}" | awk -F, '{print $1}'`
+dictionaryLine=`grep Keyword=\"${keyword}\" ${DICTIONARY} | head -1`
+tag=`echo "${dictionaryLine}" | awk '{print $1}'`
+#vm=`echo "${srcLine}" | awk -F, '{print $7}'`
+#if [ -z "${vm}" ]
+#then
+#	vm=`echo "${dictionaryLine}" | sed -e 's/^.*VM="\([^"]*\)".*$/\1/'`
+#	echo "\"${tag}\",${srcLine}${vm}"
+#else
+	echo "\"${tag}\",${srcLine}"
+#fi
diff --git a/libsrc/support/iodcomp.awk b/libsrc/support/iodcomp.awk
new file mode 100644
index 0000000..c293488
--- /dev/null
+++ b/libsrc/support/iodcomp.awk
@@ -0,0 +1,214 @@
+#  iodcomp.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from composite iod template
+
+# can set these values on the command line:
+#
+#	role	  - either "declare" or "build" or "verify" or "write" or "select"
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by iodcomp.awk with options " role " " outname
+	print ""
+
+	if (role == "declare" || role == "build" || role == "verify" || role == "write" || role == "select") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	if (role == "select") {
+		print "CompositeIOD *"
+		print "selectCompositeIOD(AttributeList *list,const char *profile)"
+		print "{"
+		print "\t(void)list;"
+		print "\tAssert(list);"
+		print ""
+		print "CompositeIOD *iod=0;"
+		print ""
+	}
+
+	iodcomp=""
+	ie=""
+	}
+
+/^[ 	]*CompositeIOD=/ {
+
+	iodcomp=""
+	if (match($0,"CompositeIOD=\"[^\"]*\""))
+		iodcomp=substr($0,RSTART+length("CompositeIOD=\""),
+			RLENGTH-length("CompositeIOD=\"")-1);
+
+	condition=""
+	if (match($0,"Condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("Condition=\""),
+			RLENGTH-length("Condition=\"")-1);
+
+	profile=""
+	if (match($0,"Profile=\"[^\"]*\""))
+		profile=substr($0,RSTART+length("Profile=\""),
+			RLENGTH-length("Profile=\"")-1);
+
+	retired="false"
+	if (match($0,"[Rr]etired=\"[^\"]*\""))
+		retired=substr($0,RSTART+length("retired=\""),
+			RLENGTH-length("retired=\"")-1);
+	
+	if (role == "declare") {
+		print "class CompositeIOD_" iodcomp " : public CompositeIOD {"
+	}
+	else if (role == "build") {
+		print "CompositeIOD_" iodcomp "::CompositeIOD_" iodcomp "(AttributeList *list)"
+		print "{"
+		print "\t(void)list; // Quiets compiler in case iodcomp empty"
+		print "\tAssert(list);"
+		print ""
+	}
+	else if (role == "verify") {
+		print "bool"
+		print "CompositeIOD_" iodcomp "::verify(AttributeList *list,bool verbose,TextOutputStream& log,ElementDictionary *dict) const"
+		print "{"
+		print "\tconst char *iodcomp = \"" iodcomp "\";"
+		print "\t(void)iodcomp;  // Quiets compiler in case iodcomp empty"
+		print "\t(void)list;"
+		print "\t(void)verbose;"
+		print "\t(void)log;"
+		print "\t(void)dict;"
+		print "\tAssert(list);"
+		print "\tAssert(dict);"
+		print ""
+		print "\tbool success=true;"
+		print ""
+		print ""
+		print "\tif (verbose)"
+		print "\t\tlog << MMsgDC(Verifying) << \" \" << MMsgDC(CompositeInformationObject) << \" \" << iodcomp << endl;"
+		print ""
+	}
+	else if (role == "write") {
+		print "void"
+		print "CompositeIOD_" iodcomp "::write(TextOutputStream& stream,AttributeList *list,ElementDictionary *dict) const"
+		print "{"
+		print "\tstream << \"\\tCompositeIOD <" iodcomp ">\\n\";"
+		print ""
+	}
+	else if (role == "select" && length(condition) > 0) {
+		if (length(profile) == 0) {
+			print "\t" selectelse "if (Condition_" condition "(list,0,list) && profile == NULL) {"
+		}
+		else{
+			print "\t" selectelse "if (Condition_" condition "(list,0,list) && profile && strcmp(profile,\"" profile "\") == 0) {"
+		}
+		print "\t\tiod = new CompositeIOD_" iodcomp "(list);"
+		print "\t}"
+		selectelse="else "
+	}
+
+	}
+
+/^[ 	]*CompositeIODEnd/ {
+
+	if (role == "declare") {
+		print "public:"
+		print "\t            CompositeIOD_" iodcomp "(AttributeList *list);"
+		print "\tconst char *identify(void) const { return \"" iodcomp "\"; }"
+		print "\tbool        retired(void) const { return " retired "; }"
+		print "\tvoid        write(TextOutputStream& stream,AttributeList *list,ElementDictionary *dict) const ;"
+		print "\tbool        verify(AttributeList *list,bool verbose,TextOutputStream& log,ElementDictionary *dict) const;"
+		print "};"
+		print ""
+	}
+	else if (role == "build") {
+		print "}"
+		print ""
+	}
+	else if (role == "verify") {
+		print "\treturn success;"
+		print "}"
+		print ""
+	}
+	else if (role == "write") {
+		print "}"
+		print ""
+	}
+	iodcomp=""
+
+	}
+
+/^[ 	]*Module/ {
+
+	module=""
+	if (match($0,"Module=\"[^\"]*\""))
+		module=substr($0,RSTART+length("Module=\""),
+			RLENGTH-length("Module=\"")-1);
+
+	usage=""
+	if (match($0,"Usage=\"[^\"]*\""))
+		usage=substr($0,RSTART+length("Usage=\""),
+			RLENGTH-length("Usage=\"")-1);
+
+	condition=""
+	if (match($0,"Condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("Condition=\""),
+			RLENGTH-length("Condition=\"")-1);
+
+	if (role == "declare") {
+		print "\tModule_" module " *" module ";"
+	}
+	else if (role == "build") {
+		if (length(condition) > 0) {
+			print "\tif (Condition_" condition "(list,0,list)) {"
+			print "\t\t" module " = new Module_" module "(list," ie "IE);"
+			print "\t\tAssert(" module ");"
+			print "\t}"
+			print "\telse"
+			print "\t\t" module "=0;"
+			print ""
+		}
+		else {
+			print "\t" module " = new Module_" module "(list," ie "IE);"
+			print "\tAssert(" module ");"
+			print ""
+		}
+	}
+	else if (role == "verify") {
+		# should put in required module checking here ?
+		print "\tif (" module " && !" module "->verify(list,NULL/*parentlist*/,list/*rootlist*/,verbose,log,dict)) success=false;"
+		print "\tif (verbose)"
+		print "\t\tlog << \"" iodcomp " success after verifying " module " \" << (success ? \"success\" : \"failure\") << endl;";
+		print ""
+	}
+	else if (role == "write") {
+		print "\tif (" module ")"
+		print "\t\t" module "->write(stream,list,dict);"
+		print "\telse"
+		print "\t\tstream << \"\\tModule <" module "> not present\\n\";"
+		print ""
+	}
+
+	}
+
+/^[ 	]*InformationEntity=/ {
+	ie=""
+	if (match($0,"InformationEntity=\"[^\"]*\""))
+		ie=substr($0,RSTART+length("InformationEntity=\""),
+			RLENGTH-length("InformationEntity=\"")-1);
+}
+
+END {
+	if (role == "select") {
+		print ""
+		print "\treturn iod;"
+		print "}"
+		print ""
+	}
+
+	if (role == "declare" || role == "build" || role == "verify" || role == "write" || role == "select") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/modtype.awk b/libsrc/support/modtype.awk
new file mode 100644
index 0000000..cfb3a68
--- /dev/null
+++ b/libsrc/support/modtype.awk
@@ -0,0 +1,59 @@
+#  modtype.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create list of composite iod elements by module 
+
+NR==1	{
+	module=""
+}
+
+/^[ 	]*Module=/ || /^[ 	]*DefineMacro=/ {
+
+	module=""
+	if (match($0,"Module=\"[^\"]*\""))
+		module=substr($0,RSTART+length("Module=\""),
+			RLENGTH-length("Module=\"")-1);
+	else if (match($0,"DefineMacro=\"[^\"]*\""))
+		module=substr($0,RSTART+length("DefineMacro=\""),
+			RLENGTH-length("DefineMacro=\"")-1);
+
+	sequencenestingdepth=0;
+}
+
+/^[ 	]*ModuleEnd/ || /^[ 	]*MacroEnd/{
+
+	module=""
+}
+
+/^[ 	]*Name.*[ 	][ 	]*Type=/ {
+
+	name=""
+	if (match($0,"Name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+
+	type=""
+	if (match($0,"Type=\"[^\"]*\""))
+		type=substr($0,RSTART+length("Type=\""),
+			RLENGTH-length("Type=\"")-1);
+
+	condition=""
+	if (match($0,"Condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("Condition=\""),
+			RLENGTH-length("Condition=\"")-1);
+
+	if (sequencenestingdepth == 0) {
+		printf("%35s  %-40s %-3s %-50s\n",module,name,type,condition);
+	}
+
+}
+
+/^[ 	]*Sequence=/ {
+	++sequencenestingdepth
+}
+
+/^[ 	]*SequenceEnd/ {
+	--sequencenestingdepth
+}
+
+END {
+}
+
diff --git a/libsrc/support/module.awk b/libsrc/support/module.awk
new file mode 100644
index 0000000..90b12c2
--- /dev/null
+++ b/libsrc/support/module.awk
@@ -0,0 +1,783 @@
+#  module.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from modules template 
+
+# can set these values on the command line:
+#
+#	role	  - either "declare" or "build" or "verify" or "write"
+
+function indentcode(count)
+{
+	if (count) {
+		count=count*3;
+		while (count-- > 0) {
+			printf("\t")
+		}
+	}
+}
+
+function indentforwrite(count)
+{
+	if (count) {
+		indentcode(count)
+		printf("\tstream << \"")
+		while (count-- > 0) {
+			printf("\\t")
+		}
+		printf("\";\n")
+	}
+}
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by module.awk with options " role " " outname
+	print ""
+
+	if (role == "declare" || role == "build" || role == "verify" || role == "write") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	module=""
+	macroormodule=""
+}
+
+/^[ 	]*Module=/ || /^[ 	]*DefineMacro=/ {
+
+	module=""
+	macroormodule=""
+	if (match($0,"Module=\"[^\"]*\"")) {
+		macroormodule="Module"
+		module=substr($0,RSTART+length("Module=\""),
+			RLENGTH-length("Module=\"")-1);
+		}
+	else if (match($0,"DefineMacro=\"[^\"]*\"")) {
+		macroormodule="Macro"	# not DefineMacro
+		module=substr($0,RSTART+length("DefineMacro=\""),
+			RLENGTH-length("DefineMacro=\"")-1);
+		}
+
+	if (role == "declare") {
+		print "class " macroormodule "_" module " : public Module {"
+		print "\tconst char *module;"
+	}
+	else if (role == "build") {
+		print macroormodule "_" module "::" macroormodule "_" module "(AttributeList *list,InformationEntity ie)"
+		print "{"
+		print "\t(void)list; // Quiets compiler in case module empty"
+		print "\tAssert(list);"
+		print "\tmodule = \"" module "\";"
+		print ""
+	}
+	else if (role == "verify") {
+		print "bool"
+		print macroormodule "_" module "::verify(AttributeList *list,AttributeList *parentlist,AttributeList *rootlist,bool verbose,TextOutputStream& log,ElementDictionary *dict) const"
+		print "{"
+		#print "\tconst char *module = \"" module "\";"
+		print "\t(void)module;  // Quiets compiler in case module empty"
+		print "\t(void)list;"
+		print "\t(void)verbose;"
+		print "\t(void)log;"
+		print "\t(void)dict;"
+		print "\tAssert(list);"
+		print "\tAssert(dict);"
+		print ""
+		print "\tbool success=true;"
+		print ""
+		print "\tif (verbose)"
+		print "\t\tlog << MMsgDC(Verifying) << \" \" << MMsgDC(" macroormodule ") << \" \" << module << endl;"
+		print ""
+	}
+	else if (role == "write") {
+		print "void"
+		print macroormodule "_" module "::write(TextOutputStream& stream,AttributeList *list,ElementDictionary *dict) const"
+		print "{"
+		print "\tstream << \"\\t" macroormodule " <" module ">\\n\";"
+		print ""
+	}
+	sequencenestingdepth=0;
+}
+
+/^[ 	]*ModuleEnd/ || /^[ 	]*MacroEnd/{
+
+	if (role == "declare") {
+		print "public:"
+		print "\t            " macroormodule "_" module "(AttributeList *list,InformationEntity ie);"
+		print "\tconst char *identify(void) const { return \"" module "\"; }"
+		print "\tvoid        write(TextOutputStream& stream,AttributeList *list,ElementDictionary *dict) const ;"
+		print "\tbool        verify(AttributeList *list,AttributeList *parentlist,AttributeList *rootlist,bool verbose,TextOutputStream& log,ElementDictionary *dict) const;"
+		print "};"
+		print ""
+	}
+	else if (role == "build") {
+		print "}"
+		print ""
+	}
+	else if (role == "verify") {
+		print "\treturn success;"
+		print "}"
+		print ""
+	}
+	else if (role == "write") {
+		print "}"
+		print ""
+	}
+
+	module=""
+	if (sequencenestingdepth != 0)
+		print "Error - sequence nesting depth invalid ( " sequencenestingdepth ") - missing or extra SequenceEnd at line " FNR >"/dev/tty"
+
+}
+
+/^[ 	]*Sequence=/ {
+
+	donotsetused="F"
+	if (match($0,"DoNotSetUsed=\"[^\"]*\""))
+		donotsetused="T";
+
+	sequence=""
+	if (match($0,"Sequence=\"[^\"]*\""))
+		sequence=substr($0,RSTART+length("Sequence=\""),
+			RLENGTH-length("Sequence=\"")-1);
+
+	type=""
+	if (match($0,"Type=\"[^\"]*\""))
+		type=substr($0,RSTART+length("Type=\""),
+			RLENGTH-length("Type=\"")-1);
+
+	vm=""
+	match($0,"VM=\"[^\"]*\"");
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") {
+		print "Warning - missing number of sequence items (VM) at line " FNR >"/dev/tty"
+		vm="n";	# supresses checking
+	}
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=0;
+		vmmax="VMUNLIMITED";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="VMUNLIMITED";
+	}
+
+	condition=""
+	if (match($0,"Condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("Condition=\""),
+			RLENGTH-length("Condition=\"")-1);
+
+	noconditionpresent="no"
+	if (match($0,"NoCondition=\"[^\"]*\""))
+		noconditionpresent="yes";
+
+	mbpo="false"
+	if (match($0,"[Mm]bpo=\"[^\"]*\""))
+		mbpo=substr($0,RSTART+length("mbpo=\""),
+			RLENGTH-length("mbpo=\"")-1);
+	
+	if (length(sequence) > 0) {
+		if (sequencenestingdepth == 0) {
+			# declare globally
+			if (role == "declare") {
+				print "\tAttribute *" sequence ";"
+			}
+			else if (role == "build") {
+				print "\t" sequence " = (*list)[TagFromName(" sequence ")];"
+				# do not reset it if already set (else calls during verify or write undo the work done during build)
+				print "\tif (" sequence ") {"
+				print "\t\tif (" sequence "->getInformationEntity() == UnknownIE) " sequence "->setInformationEntity(ie);"
+				print "\t}"
+				print ""
+			}
+		}
+		else {
+			# declare locally if going to be used
+			if (role == "write" || role == "verify") {
+				print "\tAttribute *" sequence " = (*list)[TagFromName(" sequence ")];"
+			}
+		}
+
+		if (role == "write") {
+			indentforwrite(sequencenestingdepth)
+			indentcode(sequencenestingdepth)
+			print "\tif (" sequence ")"
+			indentcode(sequencenestingdepth)
+			print "\t\tstream << \"\\t\\tSequence <" sequence ">\\n\";"
+			indentcode(sequencenestingdepth)
+			print "\telse"
+			indentcode(sequencenestingdepth)
+			print "\t\tstream << \"\\t\\tSequence <" sequence "> not present\\n\";"
+		}
+		else if (role == "verify") {
+			indentcode(sequencenestingdepth)
+			if (donotsetused == "F") {
+				printf("\tif (" sequence ") " sequence "->setUsed();\n")
+			}
+			#if (donotsetused == "T") {
+			#	printf("\t{ Attribute *a = (*list)[TagFromName(" sequence ")];}\n")
+			#}
+			#else {
+			#	printf("\t{ Attribute *a = (*list)[TagFromName(" sequence ")]; if (a) a->setUsed(); }\n")
+			#}
+			indentcode(sequencenestingdepth)
+			printf("\tif (! ")
+			if (length(type) > 0) {
+				print "verifyType" type
+			}
+			else {
+				print "verifyRequired"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\t\t(" sequence ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\t\"" module "\",\"" sequence "\","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict,"
+			indentcode(sequencenestingdepth)
+			if (type == "1C" || type == "2C" || type == "3C") {
+				if (length(condition) > 0) {
+					print "\t\t\tCondition_" condition ", "
+				}
+				else {
+					print "\t\t\t0, "
+					if (noconditionpresent == "no") {
+						print "Warning - missing Condition at line " FNR >"/dev/tty"
+					}
+				}
+				if (type == "1C" || type == "2C") {		# mbpo never applies to Type 3C
+					indentcode(sequencenestingdepth)
+					print "\t\t\t" mbpo ", "
+				}
+				indentcode(sequencenestingdepth)
+				print "\t\t\tlist,parentlist,rootlist, "
+			}
+			else {
+				if (length(condition) > 0) {
+					print "Error - unwanted Condition at line " FNR >"/dev/tty"
+				}
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\t\t" vmmin "," vmmax ")) success=false;"
+
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying " sequence " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+
+		if (role == "write" || role == "verify") {
+			# create new state for subsequent stuff enclosed in sequence ...
+
+			indentcode(sequencenestingdepth)
+			print "\tif (" sequence " && strcmp(" sequence "->getVR(),\"SQ\") == 0) {"
+			indentcode(sequencenestingdepth)
+			print "\t\tAttributeList **array;"
+			indentcode(sequencenestingdepth)
+			print "\t\tint n;"
+			indentcode(sequencenestingdepth)
+			print "\t\tif ((n="sequence "->getLists(&array)) > 0) {"
+			indentcode(sequencenestingdepth)
+			print "\t\t\tint i; for (i=0; i<n; ++i) {"
+			if (role == "verify") {
+				indentcode(sequencenestingdepth)
+				print "\t\t\t\tAttributeList *parentlist=list;"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\t\t\tAttributeList *list=array[i];"
+
+			if (role == "write") {
+				#indentcode(sequencenestingdepth)
+				#print "\t\t\t\tif (i) {"
+				indentforwrite(sequencenestingdepth)
+				indentcode(sequencenestingdepth)
+				#print "\t\t\t\t\tstream << \"\\t\\t----\" << endl;"
+				print "\t\t\t\t\tstream << \"\\t\\tItem\" << endl;"
+				#indentcode(sequencenestingdepth)
+				#print "\t\t\t\t}"
+			}
+
+			# this value of list will be used until a SequenceEnd is seen
+		}
+		++sequencenestingdepth
+	}
+}
+
+/^[ 	]*SequenceEnd/ {
+
+	--sequencenestingdepth
+
+	if (role == "write" || role == "verify") {
+		# take down nesting for stuff enclosed in sequence ...
+
+		indentcode(sequencenestingdepth)
+		print "\t\t\t}"
+		indentcode(sequencenestingdepth)
+		print "\t\t}"
+		indentcode(sequencenestingdepth)
+		print "\t}"
+	}
+}
+
+/^[ 	]*(Name|Verify)=/ {
+
+	donotsetused="F"
+	if (match($0,"DoNotSetUsed=\"[^\"]*\""))
+		donotsetused="T";
+
+	name=""
+	if (match($0,"Name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+
+	verify=""
+	if (match($0,"Verify=\"[^\"]*\""))
+		verify=substr($0,RSTART+length("Verify=\""),
+			RLENGTH-length("Verify=\"")-1);
+
+	type=""
+	if (match($0,"Type=\"[^\"]*\""))
+		type=substr($0,RSTART+length("Type=\""),
+			RLENGTH-length("Type=\"")-1);
+
+	stringdefinedterms=""
+	if (match($0,"StringDefinedTerms=\"[^\"]*\""))
+		stringdefinedterms=substr($0,RSTART+length("StringDefinedTerms=\""),
+			RLENGTH-length("StringDefinedTerms=\"")-1);
+
+	stringenumvalues=""
+	if (match($0,"StringEnumValues=\"[^\"]*\""))
+		stringenumvalues=substr($0,RSTART+length("StringEnumValues=\""),
+			RLENGTH-length("StringEnumValues=\"")-1);
+
+	binaryenumvalues=""
+	if (match($0,"BinaryEnumValues=\"[^\"]*\""))
+		binaryenumvalues=substr($0,RSTART+length("BinaryEnumValues=\""),
+			RLENGTH-length("BinaryEnumValues=\"")-1);
+
+	tagenumvalues=""
+	if (match($0,"TagEnumValues=\"[^\"]*\""))
+		tagenumvalues=substr($0,RSTART+length("TagEnumValues=\""),
+			RLENGTH-length("TagEnumValues=\"")-1);
+
+	binarybitmap=""
+	if (match($0,"BinaryBitMap=\"[^\"]*\""))
+		binarybitmap=substr($0,RSTART+length("BinaryBitMap=\""),
+			RLENGTH-length("BinaryBitMap=\"")-1);
+
+	match($0,"VM=\"[^\"]*\"");
+	vm=substr($0,RSTART+length("VM=\""),RLENGTH-length("VM=\"")-1);
+	if (vm == "") vm=0;
+	vmmin=vmmax=vm;
+	if (vm == "n") {
+		vmmin=1;
+		vmmax="VMUNLIMITED";
+	}
+	if (match(vm,"-")) {
+		match(vm,"[0-9]*-");
+		vmmin=substr(vm,RSTART,RLENGTH-1);
+		match(vm,"-[0-9n]");
+		vmmax=substr(vm,RSTART+1,RLENGTH-1);
+		if (vmmax == "n") vmmax="VMUNLIMITED";
+	}
+
+	selector=""
+	if (match($0,"ValueSelector=\"[^\"]*\""))
+		selector=substr($0,RSTART+length("ValueSelector=\""),
+			RLENGTH-length("ValueSelector=\"")-1);
+
+	if (length(selector) == 0) {
+		selector="-1"		# default is wildcard not 1st value !
+	}
+	else if (selector == "*") {
+		selector="-1"		# wildcard
+	}
+
+	condition=""
+	if (match($0,"Condition=\"[^\"]*\""))
+		condition=substr($0,RSTART+length("Condition=\""),
+			RLENGTH-length("Condition=\"")-1);
+
+	noconditionpresent="no"
+	if (match($0,"NoCondition=\"[^\"]*\""))
+		noconditionpresent="yes";
+
+	mbpo="false"
+	if (match($0,"[Mm]bpo=\"[^\"]*\""))
+		mbpo=substr($0,RSTART+length("mbpo=\""),
+			RLENGTH-length("mbpo=\"")-1);
+
+	notzero="no"
+	if (match($0,"NotZeroWarning=\"[^\"]*\"")) {
+		notzero="warning";
+	}
+	else if (match($0,"NotZeroError=\"[^\"]*\"")) {
+		notzero="error";
+	}
+	
+	message=""
+	messageConditionModifier=""
+	messageErrorOrWarning=""
+	if (match($0,"ThenErrorMessage=\"[^\"]*\"")) {
+		messageErrorOrWarning="E"
+		message=substr($0,RSTART+length("ThenErrorMessage=\""),
+			RLENGTH-length("ThenErrorMessage=\"")-1);
+	}
+	if (match($0,"ThenWarningMessage=\"[^\"]*\"")) {
+		messageErrorOrWarning="W"
+		message=substr($0,RSTART+length("ThenWarningMessage=\""),
+			RLENGTH-length("ThenWarningMessage=\"")-1);
+	}
+	if (match($0,"ThenMessage=\"[^\"]*\"")) {
+		messageErrorOrWarning="M"
+		message=substr($0,RSTART+length("ThenMessage=\""),
+			RLENGTH-length("ThenMessage=\"")-1);
+	}
+	
+	if (match($0,"ElseErrorMessage=\"[^\"]*\"")) {
+		messageErrorOrWarning="E"
+		messageConditionModifier="!"
+		message=substr($0,RSTART+length("ElseErrorMessage=\""),
+			RLENGTH-length("ElseErrorMessage=\"")-1);
+	}
+	if (match($0,"ElseWarningMessage=\"[^\"]*\"")) {
+		messageErrorOrWarning="W"
+		messageConditionModifier="!"
+		message=substr($0,RSTART+length("ElseWarningMessage=\""),
+			RLENGTH-length("ElseWarningMessage=\"")-1);
+	}
+	if (match($0,"ElseMessage=\"[^\"]*\"")) {
+		messageErrorOrWarning="M"
+		messageConditionModifier="!"
+		message=substr($0,RSTART+length("ElseMessage=\""),
+			RLENGTH-length("ElseMessage=\"")-1);
+	}
+
+	showValueWithMessage="false"
+	if (match($0,"ShowValueWithMessage=\"[^\"]*\""))
+		showValueWithMessage=substr($0,RSTART+length("ShowValueWithMessage=\""),
+			RLENGTH-length("ShowValueWithMessage=\"")-1);
+	
+	if (length(name) > 0) {
+		if (sequencenestingdepth == 0) {
+			# declare globally
+			if (role == "declare") {
+				print "\tAttribute *" name ";"
+			}
+			else if (role == "build") {
+				print "\t" name " = (*list)[TagFromName(" name ")];"
+				# do not reset it if already set (else calls during verify or write undo the work done during build)
+				print "\tif (" name ") {"
+				print "\t\tif (" name "->getInformationEntity() == UnknownIE) " name "->setInformationEntity(ie);"
+				print "\t}"
+				print ""
+			}
+		}
+		else {
+			# declare locally if going to be used
+			if (role == "write" || role == "verify") {
+				indentcode(sequencenestingdepth)
+				print "\tAttribute *" name " = (*list)[TagFromName(" name ")];"
+			}
+		}
+
+		if (role == "write") {
+			indentforwrite(sequencenestingdepth)
+			indentcode(sequencenestingdepth)
+			print "\tif (" name ") {"
+			indentcode(sequencenestingdepth)
+			print "\t\tstream << \"\\t\\t\";"
+			indentcode(sequencenestingdepth)
+			print "\t\t" name "->write(stream,dict);"
+			indentcode(sequencenestingdepth)
+			print "\t\tstream << \"\\n\";"
+			indentcode(sequencenestingdepth)
+			print "\t}"
+			indentcode(sequencenestingdepth)
+			print "\telse"
+			indentcode(sequencenestingdepth)
+			print "\t\tstream << \"\\t\\tElement <" name "> not present\\n\";"
+			print ""
+		}
+		else if (role == "verify") {
+			if (length(name) > 0) {
+				indentcode(sequencenestingdepth)
+				if (donotsetused == "F") {
+					printf("\tif (" name ") " name "->setUsed();\n")
+				}
+				#if (donotsetused == "T") {
+				#	printf("\t{ Attribute *a = (*list)[TagFromName(" name ")];}\n")
+				#}
+				#else {
+				#	printf("\t{ Attribute *a = (*list)[TagFromName(" name ")]; if (a) a->setUsed(); }\n")
+				#}
+			}
+			indentcode(sequencenestingdepth)
+			printf("\tif (! ");
+			if (length(type) > 0) {
+				print "verifyType" type
+			}
+			else {
+				print "verifyRequired"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\t\t(" name ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\t\"" module "\",\"" name "\","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict,"
+			indentcode(sequencenestingdepth)
+			if (type == "1C" || type == "2C" || type == "3C") {
+				if (length(condition) > 0) {
+					print "\t\t\tCondition_" condition ", "
+				}
+				else {
+					print "\t\t\t0, "
+					if (noconditionpresent == "no") {
+						print "Warning - missing Condition at line " FNR >"/dev/tty"
+					}
+				}
+				if (type == "1C" || type == "2C") {		# mbpo never applies to Type 3C
+					indentcode(sequencenestingdepth)
+					print "\t\t\t" mbpo ", "
+				}
+				indentcode(sequencenestingdepth)
+				print "\t\t\tlist,parentlist,rootlist, "
+			}
+			else {
+				if (length(condition) > 0) {
+					print "Error - unwanted Condition at line " FNR >"/dev/tty"
+				}
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\t\t" vmmin "," vmmax ")) success=false;"
+
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying " name " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+	}
+
+	if ((length(name) > 0 || length(verify) > 0) && role == "verify") {
+		if (length(name) == 0 && length(verify) > 0) name=verify;
+		if (length(verify) > 0 && vm != "0") {		# check that VM was explicitly specified and do NOT repeat VM check for other than verify case
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name " && !" name "->verifyVM("
+			indentcode(sequencenestingdepth)
+			print "\t\t\t\"" module "\",\"" name "\",log,dict," vmmin "," vmmax ",\"" condition "\")) success=false;"	# use condition as source
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+		}
+		if (length(stringdefinedterms) > 0) {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name ") " name "->verifyDefinedTerms("
+			indentcode(sequencenestingdepth)
+			print "\t\t\tStringValueDescription_" stringdefinedterms ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict," selector ");"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying string defined terms " name " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+		if (length(stringenumvalues) > 0) {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name " && !" name "->verifyEnumValues("
+			indentcode(sequencenestingdepth)
+			print "\t\t\tStringValueDescription_" stringenumvalues ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict," selector ")) success=false;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying string enumerated values " name " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+		if (length(binaryenumvalues) > 0) {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name " && !" name "->verifyEnumValues("
+			indentcode(sequencenestingdepth)
+			print "\t\t\tBinaryValueDescription_" binaryenumvalues ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict," selector ")) success=false;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying binary enumerated values " name " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+		if (length(tagenumvalues) > 0) {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name " && !" name "->verifyEnumValues("
+			indentcode(sequencenestingdepth)
+			print "\t\t\tTagValueDescription_" tagenumvalues ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict," selector ")) success=false;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying tag enumerated values " name " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+		if (length(binarybitmap) > 0) {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name " && !" name "->verifyBitMap("
+			indentcode(sequencenestingdepth)
+			print "\t\t\tBinaryBitMapDescription_" binarybitmap ","
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict," selector ")) success=false;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying binary bit map " name " \" << (success ? \"success\" : \"failure\") << endl;";
+		}
+		if (notzero != "no") {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tif (" name " && !" name "->verifyNotZero("
+			indentcode(sequencenestingdepth)
+			print "\t\t\tverbose,log,dict," selector "," (notzero == "warning" ? "true" : "false") ")) success=false;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+		}
+		if (length(message) > 0 && length(messageErrorOrWarning) > 0) {
+			print ""
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (" messageConditionModifier "Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << " messageErrorOrWarning "MsgDCNull() << \"" message " - attribute <" name ">\""
+			if (showValueWithMessage == "true") {
+				print "\t\t\t<< \" = <\" << (const char *)AttributeValue((*list)[TagFromName(" name ")],\"\") << \">\""
+			}
+			print "\t\t\t<< endl;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+		}
+		print ""
+	}
+	
+	}
+
+/^[	 ]*InvokeMacro=/ {
+
+        invokedmacro=""
+        if (match($0,"InvokeMacro=\"[^\"]*\""))
+                invokedmacro=substr($0,RSTART+length("InvokeMacro=\""),
+                        RLENGTH-length("InvokeMacro=\"")-1);
+
+        condition=""
+        if (match($0,"Condition=\"[^\"]*\""))
+                condition=substr($0,RSTART+length("Condition=\""),
+                        RLENGTH-length("Condition=\"")-1);
+
+        if (role == "verify") {
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\tif (Condition_" condition "(list,parentlist,rootlist)) {"
+			}
+			indentcode(sequencenestingdepth)
+			print "\tif (!Macro_" invokedmacro "(list,ie).verify(list,parentlist,rootlist,verbose,log,dict)) success=false;"
+			if (length(condition) > 0) {
+				indentcode(sequencenestingdepth)
+				print "\t}"
+			}
+			print ""
+			indentcode(sequencenestingdepth)
+			print "\tif (verbose)"
+			indentcode(sequencenestingdepth)
+			print "\t\tlog << \"" module " success after verifying " invokedmacro " \" << (success ? \"success\" : \"failure\") << endl;";
+        }
+        else if (role == "write") {
+			indentforwrite(sequencenestingdepth+1)
+			print "\tMacro_" invokedmacro "(list,ie).write(stream,list,dict);"
+			indentforwrite(sequencenestingdepth+1)
+			print "\tstream << \"\\tEndMacro <" invokedmacro ">\\n\";"
+			print ""
+        }
+		else if (role == "build") {
+			if (module != "DocumentRelationshipMacro") {
+				# build a macro, just to set the IE of the attributes that it uses - need to be sure that subsequent constructor calls during write or verify do not undo setting of IE
+				print "\tnew Macro_" invokedmacro "(list,ie);"
+			}
+			# else supress, since causes infinite recursive invocation, and we don't need it anyway
+		}
+
+        }
+
+END {
+	if (role == "declare" || role == "build" || role == "verify" || role == "write") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
+
+
diff --git a/libsrc/support/sopcl.awk b/libsrc/support/sopcl.awk
new file mode 100644
index 0000000..b2de3a3
--- /dev/null
+++ b/libsrc/support/sopcl.awk
@@ -0,0 +1,85 @@
+#  sopcl.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from SOP class template 
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by sopcl.awk with options " role outname
+	print ""
+
+	if (role == "define" || role == "extern" || role == "constant") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else if (role == "table") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+		print "static SOPClassTableEntry"
+		print "\t\tSOPClassTable[] = {"
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*Name=/ || /^[ 	]*DirectoryRecord=/ {
+
+	name=""
+	if (match($0,"Name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+
+	desc=name
+	if (match($0,"Desc=\"[^\"]*\""))
+		desc=substr($0,RSTART+length("Desc=\""),
+			RLENGTH-length("Desc=\"")-1);
+
+	type="Class"
+	if (match($0,"Type=\"[^\"]*\""))
+		type=substr($0,RSTART+length("Type=\""),
+			RLENGTH-length("Type=\"")-1);
+
+	uid=""
+	if (match($0,"Uid=\"[^\"]*\""))
+		uid=substr($0,RSTART+length("Uid=\""),
+			RLENGTH-length("Uid=\"")-1);
+
+	dirrec=""
+	if (match($0,"DirectoryRecord=\"[^\"]*\""))
+		dirrec=substr($0,RSTART+length("DirectoryRecord=\""),
+			RLENGTH-length("DirectoryRecord=\"")-1);
+
+	if (role == "define") {
+		print "#define\t" name "SOP" type "UID\t\"" uid "\""
+	}
+	else if (role== "extern") {
+		print "extern const char *" name "SOP" type "UID;"
+	}
+	else if (role == "constant") {
+		print "const char *" name "SOP" type "UID = \"" uid "\";"
+	}
+	else if (role == "table") {
+		print "\t\"" name "\",\"" desc "\",\"" uid "\",\"" dirrec "\","
+	}
+
+	}
+
+END {
+	if (role == "define" || role== "extern" || role == "constant") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+	else if (role == "table") {
+		print "\t0, 0, 0, 0, 0"
+		print "};"
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/strval.awk b/libsrc/support/strval.awk
new file mode 100644
index 0000000..c20421b
--- /dev/null
+++ b/libsrc/support/strval.awk
@@ -0,0 +1,119 @@
+#  strval.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from string values template 
+
+# can set these values on the command line:
+#
+#	role	  - either "declare" or "define"
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by strval.awk with options " role " " outname
+	print ""
+
+	if (role == "declare" || role == "define") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	mode=""
+	}
+
+/^[ 	]*StringValues/ {
+	name=""
+	if (match($0,"StringValues=\"[^\"]*\""))
+		name=substr($0,RSTART+length("StringValues=\""),
+			RLENGTH-length("StringValues=\"")-1);
+	mode="values"
+
+	if (role == "declare") {
+		print "char *\tStringValueDescription_" name "(char * value);"
+	}
+	else if (role == "define") {
+		print "static struct StringValueEntry"
+		print "StringValueTable_" name "[] = {"
+	}
+
+	}
+	
+$0 !~ /(.*[{}])|(^[ 	]*$)|(^[ 	]*#)/ {
+
+	if (mode == "values") {
+		valueline=$0
+#print "Line " FNR ": evaluating for code valueline = " valueline >"/dev/tty"
+		#if (match(valueline,"[0-9a-zA-Z _/-][0-9a-zA-Z _/-]*")) {
+		if (match(valueline,"[^ 	=,][^=,]*")) {
+			code=substr(valueline,RSTART,RLENGTH)
+#print "Line " FNR ": match code = " code >"/dev/tty"
+			# remove trailing spaces ...
+			if (match(code,"[ 	]*$")) {
+				sub("[ 	]*$","",code);
+				#code=substr(code,0,RSTART-1)
+#print "Line " FNR ": removed trailing spaces now code = " code >"/dev/tty"
+			}
+			valueline=substr(valueline,RSTART+RLENGTH)
+#print "Line " FNR ": now valueline = " valueline >"/dev/tty"
+			if (code == "***EMPTYVALUE***") {
+#print "Line " FNR ": empty value code " >"/dev/tty"
+				code=""
+			}
+		}
+		else {
+			print "Line " FNR \
+				": warning in value line - no code <" \
+				valueline ">" >"/dev/tty"
+			code=""
+#print "Line " FNR ": no code " >"/dev/tty"
+		}
+#print "Line " FNR ": evaluating for meaning valueline = " valueline >"/dev/tty"
+		if (match(valueline,"[ 	]*=[ 	]*")) {
+			meaning=substr(valueline,RSTART+RLENGTH)
+#print "Line " FNR ": match meaning = " meaning >"/dev/tty"
+			if (match(meaning,"[ 	]*,*[ 	]*$")) {
+				meaning=substr(meaning,0,RSTART-1)
+#print "Line " FNR ": removed trailing spaces now meaning = " meaning >"/dev/tty"
+			}
+		}
+		else {
+			meaning=""
+#print "Line " FNR ": no meaning " >"/dev/tty"
+		}
+
+		if (role == "define") {
+			print "\t\"" code "\",\t\"" meaning "\","
+		}
+	}
+	else {
+		print "Line " FNR ": error - no group name" >"/dev/tty"
+	}
+
+	}
+
+/^[ 	]*}/ {
+	if (role == "define" && mode == "values") {
+		print "\t0,0"
+		print "};"
+		print ""
+		print "char *"
+		print "StringValueDescription_" name "(char * value)"
+		print "{"
+		print "\treturn StringValueDescription(StringValueTable_" name ",value);"
+		print "}"
+		print ""
+	}
+
+	mode=""
+	}
+
+END {
+	if (role == "declare" || role == "define") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/tagval.awk b/libsrc/support/tagval.awk
new file mode 100644
index 0000000..1308c57
--- /dev/null
+++ b/libsrc/support/tagval.awk
@@ -0,0 +1,111 @@
+#  tagval.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ headers from tag values template 
+
+# can set these values on the command line:
+#
+#	role	  - either "declare" or "define"
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by tagval.awk with options " role " " outname
+	print ""
+
+	if (role == "declare" || role == "define") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	mode=""
+	}
+
+/^[ 	]*TagValues/ {
+	name=""
+	if (match($0,"TagValues=\"[^\"]*\""))
+		name=substr($0,RSTART+length("TagValues=\""),
+			RLENGTH-length("TagValues=\"")-1);
+
+	if (role == "declare") {
+		print "char *\tTagValueDescription_" name "(Uint16 group,Uint16 element);"
+	}
+	else if (role == "define") {
+		print "char *"
+		print "TagValueDescription_" name "(Uint16 group,Uint16 element)"
+		print "{"
+		print "\tostrstream ost;"
+		print "\tUint32 value=(((Uint32)group)<<16)|(Uint32)element;"
+		print "\tswitch (value) {"
+	}
+
+	}
+
+/^[ 	]*0x[0-9a-fA-F]*/ {
+
+	valueline=$0
+	if (!match(valueline,"[0-9][x0-9a-fA-F]*,[0-9][x0-9a-fA-F]*")) {
+		print "Line " FNR \
+			": error in value line - no group,element code <" \
+			valueline ">" >"/dev/tty"
+		next
+	}
+	code=substr(valueline,RSTART,RLENGTH)
+	valueline=substr(valueline,RSTART+RLENGTH)
+
+	group=""
+	if (match(code,"[0-9][x0-9a-fA-F]*,")) {
+		group=substr(code,RSTART,RLENGTH-1)
+	}
+	element=""
+	if (match(code,",[0-9][x0-9a-fA-F]*")) {
+		element=substr(code,RSTART+1,RLENGTH-1)
+	}
+
+	if (match(valueline,"[ 	]*=[ 	]*")) {
+		meaning=substr(valueline,RSTART+RLENGTH)
+		if (match(meaning,"[ 	]*,*[ 	]*$")) {
+			meaning=substr(meaning,0,RSTART-1)
+		}
+	}
+	else {
+		meaning=code
+	}
+
+	if (group == "" || element == "") {
+		print "Line " FNR \
+			": error in value line - can't interpret group,element code <" \
+			$0 ">" >"/dev/tty"
+	}
+	else {
+		if (role == "define") {
+			print "\t\tcase (((Uint32)" group ")<<16)|(Uint32)" element" :"
+			print "\t\t\tost << \"" meaning "\" << ends;"
+			print "\t\t\treturn ost.str();"
+		}
+	}
+
+	}
+
+/^[ 	]*}/ {
+	if (role == "define") {
+		print "\t\tdefault:"
+		print "\t\t\treturn 0;"
+		print "\t}"
+		print "}"
+		print ""
+	}
+
+	mode=""
+	}
+
+END {
+	if (role == "declare" || role == "define") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/transyn.awk b/libsrc/support/transyn.awk
new file mode 100644
index 0000000..3b46efe
--- /dev/null
+++ b/libsrc/support/transyn.awk
@@ -0,0 +1,124 @@
+#  transyn.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+# create C++ defines from SOP class template 
+
+NR==1	{
+	print "// Automatically generated from template - EDITS WILL BE LOST"
+	print ""
+	print "// Generated by transyn.awk with options " role " " outname
+	print ""
+
+	if (role == "define" || role == "extern" || role == "constant") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+	}
+	else if (role == "table") {
+		print "#ifndef __Header_" outname "__"
+		print "#define __Header_" outname "__"
+		print ""
+		print "static TransferSyntaxDictionaryEntry"
+		print "\t\tTransferSyntaxDictionaryTable[] = {"
+	}
+	else {
+		print "Error - role " role " invalid" >"/dev/tty"
+		exit 1
+	}
+
+	}
+
+/^[ 	]*[#]/	{}
+
+/^[ 	]*Name/ {
+
+	name=""
+	if (match($0,"Name=\"[^\"]*\""))
+		name=substr($0,RSTART+length("Name=\""),
+			RLENGTH-length("Name=\"")-1);
+
+	desc=name
+	if (match($0,"Desc=\"[^\"]*\""))
+		desc=substr($0,RSTART+length("Desc=\""),
+			RLENGTH-length("Desc=\"")-1);
+
+	uid=""
+	if (match($0,"Uid=\"[^\"]*\""))
+		uid=substr($0,RSTART+length("Uid=\""),
+			RLENGTH-length("Uid=\"")-1);
+
+	endian=""
+	if (match($0,"Endian=\"[^\"]*\""))
+		endian=substr($0,RSTART+length("Endian=\""),
+			RLENGTH-length("Endian=\"")-1);
+
+	pixel=""
+	if (match($0,"Pixel=\"[^\"]*\""))
+		pixel=substr($0,RSTART+length("Pixel=\""),
+			RLENGTH-length("Pixel=\"")-1);
+
+	vr=""
+	if (match($0,"VR=\"[^\"]*\""))
+		vr=substr($0,RSTART+length("VR=\""),
+			RLENGTH-length("VR=\"")-1);
+
+	encap=""
+	if (match($0,"Encap=\"[^\"]*\""))
+		encap=substr($0,RSTART+length("Encap=\""),
+			RLENGTH-length("Encap=\"")-1);
+
+	if (role == "define") {
+		print "#define\t" name "TransferSyntaxUID\t\"" uid "\""
+	}
+	else if (role== "extern") {
+		print "extern const char *" name "TransferSyntaxUID;"
+	}
+	else if (role == "constant") {
+		print "const char *" name "TransferSyntaxUID = \"" uid "\";"
+	}
+	else if (role == "table") {
+		if (endian == "big") pendian="BigEndian"
+		else if (endian == "little") pendian="LittleEndian"
+		else {
+			print "Error - line " NR " - invalid Endian" >"/dev/tty"
+			pendian="**BAD**"
+		}
+
+		if (vr == "implicit") pvr="ImplicitVR"
+		else if (vr == "explicit") pvr="ExplicitVR"
+		else {
+			print "Error - line " NR " - invalid VR" >"/dev/tty"
+			pvr="**BAD**"
+		}
+
+		if (encap == "yes") pencap="true"
+		else if (encap == "no") pencap="false"
+		else {
+			print "Error - line " NR " - invalid Encap" >"/dev/tty"
+			pencap="**BAD**"
+		}
+
+		if (pixel == "big") ppixel="BigEndian"
+		else if (pixel == "little") ppixel="LittleEndian"
+		else if (pixel == "") ppixel=pendian
+		else {
+			print "Error - line " NR " - invalid Pixel" >"/dev/tty"
+			ppixel="**BAD**"
+		}
+
+		print "\t\"" uid "\",\"" desc "\"," pendian "," pvr "," pencap "," ppixel ","
+	}
+
+	}
+
+END {
+	if (role == "define" || role== "extern" || role == "constant") {
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+	if (role == "table") {
+		print "\t0,0,NoEndian,NoVR,false,NoEndian"
+		print "};"
+		print ""
+		print "#endif /* __Header_" outname "__ */"
+	}
+}
+
diff --git a/libsrc/support/unkelm.awk b/libsrc/support/unkelm.awk
new file mode 100644
index 0000000..b499f3a
--- /dev/null
+++ b/libsrc/support/unkelm.awk
@@ -0,0 +1,25 @@
+#  unkelm.awk Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.
+/^\([0-9A-Fa-fxX]/ {
+
+	element=$1
+
+	owner=""
+	if (match($0,"Owner=\"[^\"]*\""))
+		owner=substr($0,RSTART+length("Owner=\""),
+			RLENGTH-length("Owner=\"")-1);
+
+	keyword=""
+	if (match($0,"Keyword=\"[^\"]*\""))
+		keyword=substr($0,RSTART+length("Keyword=\""),
+			RLENGTH-length("Keyword=\"")-1);
+
+	privateblock=""
+	if (match($0,"PrivateBlock=\"[^\"]*\""))
+		privateblock=substr($0,RSTART+length("PrivateBlock=\""),
+			RLENGTH-length("PrivateBlock=\"")-1);
+
+	if (length(keyword) == 0 || keyword == "?") {
+		print owner "\t" element "\t" privateblock
+	}
+}
+
diff --git a/support/Imakefile b/support/Imakefile
new file mode 100755
index 0000000..a83b3ba
--- /dev/null
+++ b/support/Imakefile
@@ -0,0 +1,2 @@
+AllTarget(mktime)
+NormalCCProgramTarget(mktime,mktime.o, , , )
diff --git a/support/findpre b/support/findpre
new file mode 100755
index 0000000..93e1afa
--- /dev/null
+++ b/support/findpre
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+find . -name '*[._]pre*' -print
+
diff --git a/support/gzip-1.2.4-patchfornoheader b/support/gzip-1.2.4-patchfornoheader
new file mode 100755
index 0000000..77a587c
--- /dev/null
+++ b/support/gzip-1.2.4-patchfornoheader
@@ -0,0 +1,617 @@
+diff -r -c gzip-1.2.4/gzip.1 gzip-1.2.4-dac/gzip.1
+*** gzip-1.2.4/gzip.1	Wed Aug 18 14:44:09 1993
+--- gzip-1.2.4-dac/gzip.1	Sun Dec 17 14:21:01 2000
+***************
+*** 5,11 ****
+  .SH SYNOPSIS
+  .ll +8
+  .B gzip
+! .RB [ " \-acdfhlLnNrtvV19 " ]
+  .RB [ \-S\ suffix ]
+  [
+  .I "name \&..."
+--- 5,11 ----
+  .SH SYNOPSIS
+  .ll +8
+  .B gzip
+! .RB [ " \-acdfhlLnNrtvV19x " ]
+  .RB [ \-S\ suffix ]
+  [
+  .I "name \&..."
+***************
+*** 173,178 ****
+--- 173,182 ----
+  or decompressing.
+  
+  .SH OPTIONS
++ .TP
++ .B \-x --no-header
++ Do not create or expect a gzip header ... write or read a purely compressed
++ bitstream only. Unless overridden, a suffix of ".dfl" will be added/expected.
+  .TP
+  .B \-a --ascii
+  Ascii text mode: convert end-of-lines using local conventions. This option
+diff -r -c gzip-1.2.4/gzip.c gzip-1.2.4-dac/gzip.c
+*** gzip-1.2.4/gzip.c	Thu Aug 19 09:39:43 1993
+--- gzip-1.2.4-dac/gzip.c	Sun Dec 17 14:19:10 2000
+***************
+*** 198,203 ****
+--- 198,204 ----
+  
+  		/* local variables */
+  
++ int noheader = 0;     /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  int ascii = 0;        /* convert end-of-lines to local OS conventions */
+  int to_stdout = 0;    /* output to stdout (-c) */
+  int decompress = 0;   /* decompress (-d) */
+***************
+*** 243,248 ****
+--- 244,250 ----
+  struct option longopts[] =
+  {
+   /* { name  has_arg  *flag  val } */
++     {"no-header",  0, 0, 'x'}, /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+      {"ascii",      0, 0, 'a'}, /* ascii text mode */
+      {"to-stdout",  0, 0, 'c'}, /* write output on standard output */
+      {"stdout",     0, 0, 'c'}, /* write output on standard output */
+***************
+*** 293,299 ****
+  local void copy_stat    OF((struct stat *ifstat));
+  local void do_exit      OF((int exitcode));
+        int main          OF((int argc, char **argv));
+! int (*work) OF((int infile, int outfile)) = zip; /* function to call */
+  
+  #ifndef NO_DIR
+  local void treat_dir    OF((char *dir));
+--- 295,301 ----
+  local void copy_stat    OF((struct stat *ifstat));
+  local void do_exit      OF((int exitcode));
+        int main          OF((int argc, char **argv));
+! int (*work) OF((int infile, int outfile, int noheader)) = zip; /* function to call */
+  
+  #ifndef NO_DIR
+  local void treat_dir    OF((char *dir));
+***************
+*** 307,313 ****
+  /* ======================================================================== */
+  local void usage()
+  {
+!     fprintf(stderr, "usage: %s [-%scdfhlLnN%stvV19] [-S suffix] [file ...]\n",
+  	    progname,
+  #if O_BINARY
+  	    "a",
+--- 309,315 ----
+  /* ======================================================================== */
+  local void usage()
+  {
+!     fprintf(stderr, "usage: %s [-%scdfhlLnN%stvV19x] [-S suffix] [file ...]\n",
+  	    progname,
+  #if O_BINARY
+  	    "a",
+***************
+*** 326,331 ****
+--- 328,334 ----
+  local void help()
+  {
+      static char  *help_msg[] = {
++  " -x --no-header   inflate/deflate only - don't write/check for gzip header",	/* DAC 2000/12/17 */
+  #if O_BINARY
+   " -a --ascii       ascii text; convert end-of-lines using local conventions",
+  #endif
+***************
+*** 478,486 ****
+      strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix)-1);
+      z_len = strlen(z_suffix);
+  
+!     while ((optc = getopt_long (argc, argv, "ab:cdfhH?lLmMnNqrS:tvVZ123456789",
+  				longopts, (int *)0)) != EOF) {
+  	switch (optc) {
+          case 'a':
+              ascii = 1; break;
+  	case 'b':
+--- 481,493 ----
+      strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix)-1);
+      z_len = strlen(z_suffix);
+  
+!     while ((optc = getopt_long (argc, argv, "xab:cdfhH?lLmMnNqrS:tvVZ123456789",
+  				longopts, (int *)0)) != EOF) {
+  	switch (optc) {
++         case 'x':
++ 	    strncpy(z_suffix, ".dfl", sizeof(z_suffix)-1);
++ 	    z_len = strlen(z_suffix);
++             noheader = 1; break;	/* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+          case 'a':
+              ascii = 1; break;
+  	case 'b':
+***************
+*** 672,678 ****
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(fileno(stdin), fileno(stdout)) != OK) return;
+  
+  	if (!decompress || last_member || inptr == insize) break;
+  	/* end of file */
+--- 679,685 ----
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(fileno(stdin), fileno(stdout), noheader) != OK) return;
+  
+  	if (!decompress || last_member || inptr == insize) break;
+  	/* end of file */
+***************
+*** 811,817 ****
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(ifd, ofd) != OK) {
+  	    method = -1; /* force cleanup */
+  	    break;
+  	}
+--- 818,824 ----
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(ifd, ofd, noheader) != OK) {
+  	    method = -1; /* force cleanup */
+  	    break;
+  	}
+***************
+*** 1154,1159 ****
+--- 1161,1175 ----
+      uch flags;     /* compression flags */
+      char magic[2]; /* magic header */
+      ulg stamp;     /* time stamp */
++ 
++     if (noheader) {		/* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
++ 	method = DEFLATED;
++ 	work=unzip;
++ 	flags=0;
++ 	inptr = 0;
++ 	last_member = 1;
++ 	return method;
++     }
+  
+      /* If --force and --stdout, zcat == cat, so do not complain about
+       * premature end of file: use try_byte instead of get_byte.
+diff -r -c gzip-1.2.4/gzip.h gzip-1.2.4-dac/gzip.h
+*** gzip-1.2.4/gzip.h	Fri Aug 13 08:35:33 1993
+--- gzip-1.2.4-dac/gzip.h	Sun Dec 17 13:53:26 2000
+***************
+*** 259,276 ****
+  		   if (exit_code == OK) exit_code = WARNING;}
+  
+  	/* in zip.c: */
+! extern int zip        OF((int in, int out));
+  extern int file_read  OF((char *buf,  unsigned size));
+  
+  	/* in unzip.c */
+! extern int unzip      OF((int in, int out));
+  extern int check_zipfile OF((int in));
+  
+  	/* in unpack.c */
+! extern int unpack     OF((int in, int out));
+  
+  	/* in unlzh.c */
+! extern int unlzh      OF((int in, int out));
+  
+  	/* in gzip.c */
+  RETSIGTYPE abort_gzip OF((void));
+--- 259,276 ----
+  		   if (exit_code == OK) exit_code = WARNING;}
+  
+  	/* in zip.c: */
+! extern int zip        OF((int in, int out, int noheader));
+  extern int file_read  OF((char *buf,  unsigned size));
+  
+  	/* in unzip.c */
+! extern int unzip      OF((int in, int out, int noheader));
+  extern int check_zipfile OF((int in));
+  
+  	/* in unpack.c */
+! extern int unpack     OF((int in, int out, int noheader));
+  
+  	/* in unlzh.c */
+! extern int unlzh      OF((int in, int out, int noheader));
+  
+  	/* in gzip.c */
+  RETSIGTYPE abort_gzip OF((void));
+***************
+*** 293,299 ****
+  extern   int (*read_buf) OF((char *buf, unsigned size));
+  
+  	/* in util.c: */
+! extern int copy           OF((int in, int out));
+  extern ulg  updcrc        OF((uch *s, unsigned n));
+  extern void clear_bufs    OF((void));
+  extern int  fill_inbuf    OF((int eof_ok));
+--- 293,299 ----
+  extern   int (*read_buf) OF((char *buf, unsigned size));
+  
+  	/* in util.c: */
+! extern int copy           OF((int in, int out, int noheader));
+  extern ulg  updcrc        OF((uch *s, unsigned n));
+  extern void clear_bufs    OF((void));
+  extern int  fill_inbuf    OF((int eof_ok));
+diff -r -c gzip-1.2.4/lzw.c gzip-1.2.4-dac/lzw.c
+*** gzip-1.2.4/lzw.c	Fri Aug 13 08:35:33 1993
+--- gzip-1.2.4-dac/lzw.c	Sun Dec 17 13:50:20 2000
+***************
+*** 13,20 ****
+  static int msg_done = 0;
+  
+  /* Compress in to out with lzw method. */
+! int lzw(in, out)
+      int in, out;
+  {
+      if (msg_done) return ERROR;
+      msg_done = 1;
+--- 13,21 ----
+  static int msg_done = 0;
+  
+  /* Compress in to out with lzw method. */
+! int lzw(in, out, noheader)
+      int in, out;
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      if (msg_done) return ERROR;
+      msg_done = 1;
+diff -r -c gzip-1.2.4/lzw.h gzip-1.2.4-dac/lzw.h
+*** gzip-1.2.4/lzw.h	Fri Aug 13 08:35:34 1993
+--- gzip-1.2.4-dac/lzw.h	Sun Dec 17 13:54:20 2000
+***************
+*** 38,42 ****
+  extern int maxbits;      /* max bits per code for LZW */
+  extern int block_mode;   /* block compress mode -C compatible with 2.0 */
+  
+! extern int lzw    OF((int in, int out));
+! extern int unlzw  OF((int in, int out));
+--- 38,42 ----
+  extern int maxbits;      /* max bits per code for LZW */
+  extern int block_mode;   /* block compress mode -C compatible with 2.0 */
+  
+! extern int lzw    OF((int in, int out, int noheader));
+! extern int unlzw  OF((int in, int out, int noheader));
+diff -r -c gzip-1.2.4/unlzh.c gzip-1.2.4-dac/unlzh.c
+*** gzip-1.2.4/unlzh.c	Fri Aug 13 08:35:37 1993
+--- gzip-1.2.4-dac/unlzh.c	Sun Dec 17 13:49:25 2000
+***************
+*** 382,390 ****
+  /* ===========================================================================
+   * Unlzh in to out. Return OK or ERROR.
+   */
+! int unlzh(in, out)
+      int in;
+      int out;
+  {
+      unsigned n;
+      ifd = in;
+--- 382,391 ----
+  /* ===========================================================================
+   * Unlzh in to out. Return OK or ERROR.
+   */
+! int unlzh(in, out, noheader)
+      int in;
+      int out;
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      unsigned n;
+      ifd = in;
+diff -r -c gzip-1.2.4/unlzw.c gzip-1.2.4-dac/unlzw.c
+*** gzip-1.2.4/unlzw.c	Fri Aug 13 09:31:10 1993
+--- gzip-1.2.4-dac/unlzw.c	Sun Dec 17 13:51:07 2000
+***************
+*** 189,196 ****
+   *   The magic header has already been checked and skipped.
+   *   bytes_in and bytes_out have been initialized.
+   */
+! int unlzw(in, out) 
+      int in, out;    /* input and output file descriptors */
+  {
+      REG2   char_type  *stackp;
+      REG3   code_int   code;
+--- 189,197 ----
+   *   The magic header has already been checked and skipped.
+   *   bytes_in and bytes_out have been initialized.
+   */
+! int unlzw(in, out, noheader) 
+      int in, out;    /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      REG2   char_type  *stackp;
+      REG3   code_int   code;
+diff -r -c gzip-1.2.4/unpack.c gzip-1.2.4-dac/unpack.c
+*** gzip-1.2.4/unpack.c	Fri Aug 13 08:35:38 1993
+--- gzip-1.2.4-dac/unpack.c	Sun Dec 17 13:49:04 2000
+***************
+*** 182,189 ****
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unpack(in, out)
+      int in, out;            /* input and output file descriptors */
+  {
+      int len;                /* Bit length of current code */
+      unsigned eob;           /* End Of Block code */
+--- 182,190 ----
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unpack(in, out, noheader)
+      int in, out;            /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      int len;                /* Bit length of current code */
+      unsigned eob;           /* End Of Block code */
+diff -r -c gzip-1.2.4/unzip.c gzip-1.2.4-dac/unzip.c
+*** gzip-1.2.4/unzip.c	Fri Aug 13 08:35:39 1993
+--- gzip-1.2.4-dac/unzip.c	Sat Dec 23 13:32:00 2000
+***************
+*** 96,103 ****
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unzip(in, out)
+      int in, out;   /* input and output file descriptors */
+  {
+      ulg orig_crc = 0;       /* original crc */
+      ulg orig_len = 0;       /* original uncompressed length */
+--- 96,104 ----
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unzip(in, out, noheader)
+      int in, out;   /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      ulg orig_crc = 0;       /* original crc */
+      ulg orig_len = 0;       /* original uncompressed length */
+***************
+*** 109,115 ****
+  
+      updcrc(NULL, 0);           /* initialize crc */
+  
+!     if (pkzip && !ext_header) {  /* crc and length at the end otherwise */
+  	orig_crc = LG(inbuf + LOCCRC);
+  	orig_len = LG(inbuf + LOCLEN);
+      }
+--- 110,116 ----
+  
+      updcrc(NULL, 0);           /* initialize crc */
+  
+!     if (!noheader && pkzip && !ext_header) {  /* crc and length at the end otherwise */ /* DAC 2000/12/23 add noheader */
+  	orig_crc = LG(inbuf + LOCCRC);
+  	orig_len = LG(inbuf + LOCLEN);
+      }
+***************
+*** 146,185 ****
+  	error("internal error, invalid method");
+      }
+  
+!     /* Get the crc and original length */
+!     if (!pkzip) {
+!         /* crc32  (see algorithm.doc)
+! 	 * uncompressed input size modulo 2^32
+!          */
+! 	for (n = 0; n < 8; n++) {
+! 	    buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+! 	}
+! 	orig_crc = LG(buf);
+! 	orig_len = LG(buf+4);
+! 
+!     } else if (ext_header) {  /* If extended header, check it */
+! 	/* signature - 4bytes: 0x50 0x4b 0x07 0x08
+! 	 * CRC-32 value
+!          * compressed size 4-bytes
+!          * uncompressed size 4-bytes
+! 	 */
+! 	for (n = 0; n < EXTHDR; n++) {
+! 	    buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+  	}
+- 	orig_crc = LG(buf+4);
+- 	orig_len = LG(buf+12);
+-     }
+  
+!     /* Validate decompression */
+!     if (orig_crc != updcrc(outbuf, 0)) {
+! 	error("invalid compressed data--crc error");
+!     }
+!     if (orig_len != (ulg)bytes_out) {
+! 	error("invalid compressed data--length error");
+      }
+  
+      /* Check if there are more entries in a pkzip file */
+!     if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
+  	if (to_stdout) {
+  	    WARN((stderr,
+  		  "%s: %s has more than one entry--rest ignored\n",
+--- 147,188 ----
+  	error("internal error, invalid method");
+      }
+  
+!     if (!noheader) {							/* DAC 2000/12/23 */
+! 	/* Get the crc and original length */
+! 	if (!pkzip) {
+! 	    /* crc32  (see algorithm.doc)
+! 	     * uncompressed input size modulo 2^32
+! 	     */
+! 	    for (n = 0; n < 8; n++) {
+! 		buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+! 	    }
+! 	    orig_crc = LG(buf);
+! 	    orig_len = LG(buf+4);
+! 
+! 	} else if (ext_header) {  /* If extended header, check it */
+! 	    /* signature - 4bytes: 0x50 0x4b 0x07 0x08
+! 	     * CRC-32 value
+! 	     * compressed size 4-bytes
+!  	     * uncompressed size 4-bytes
+! 	     */
+! 	    for (n = 0; n < EXTHDR; n++) {
+! 	        buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+! 	    }
+! 	    orig_crc = LG(buf+4);
+! 	    orig_len = LG(buf+12);
+  	}
+  
+! 	/* Validate decompression */
+! 	if (orig_crc != updcrc(outbuf, 0)) {
+! 	    error("invalid compressed data--crc error");
+! 	}
+! 	if (orig_len != (ulg)bytes_out) {
+! 	    error("invalid compressed data--length error");
+! 	}
+      }
+  
+      /* Check if there are more entries in a pkzip file */
+!     if (!noheader && pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {	/* DAC 2000/12/23 */
+  	if (to_stdout) {
+  	    WARN((stderr,
+  		  "%s: %s has more than one entry--rest ignored\n",
+diff -r -c gzip-1.2.4/util.c gzip-1.2.4-dac/util.c
+*** gzip-1.2.4/util.c	Fri Aug 13 08:35:40 1993
+--- gzip-1.2.4-dac/util.c	Sun Dec 17 13:52:46 2000
+***************
+*** 36,43 ****
+   * Copy input to output unchanged: zcat == cat with --force.
+   * IN assertion: insize bytes have already been read in inbuf.
+   */
+! int copy(in, out)
+      int in, out;   /* input and output file descriptors */
+  {
+      errno = 0;
+      while (insize != 0 && (int)insize != EOF) {
+--- 36,44 ----
+   * Copy input to output unchanged: zcat == cat with --force.
+   * IN assertion: insize bytes have already been read in inbuf.
+   */
+! int copy(in, out, noheader)
+      int in, out;   /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      errno = 0;
+      while (insize != 0 && (int)insize != EOF) {
+diff -r -c gzip-1.2.4/zip.c gzip-1.2.4-dac/zip.c
+*** gzip-1.2.4/zip.c	Fri Aug 13 08:35:40 1993
+--- gzip-1.2.4-dac/zip.c	Sat Dec 23 13:37:35 2000
+***************
+*** 30,37 ****
+   * IN assertions: the input and output buffers are cleared.
+   *   The variables time_stamp and save_orig_name are initialized.
+   */
+! int zip(in, out)
+      int in, out;            /* input and output file descriptors */
+  {
+      uch  flags = 0;         /* general purpose bit flags */
+      ush  attr = 0;          /* ascii/binary flag */
+--- 30,38 ----
+   * IN assertions: the input and output buffers are cleared.
+   *   The variables time_stamp and save_orig_name are initialized.
+   */
+! int zip(in, out, noheader)
+      int in, out;            /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      uch  flags = 0;         /* general purpose bit flags */
+      ush  attr = 0;          /* ascii/binary flag */
+***************
+*** 43,76 ****
+  
+      /* Write the header to the gzip file. See algorithm.doc for the format */
+  
+!     method = DEFLATED;
+!     put_byte(GZIP_MAGIC[0]); /* magic header */
+!     put_byte(GZIP_MAGIC[1]);
+!     put_byte(DEFLATED);      /* compression method */
+  
+!     if (save_orig_name) {
+! 	flags |= ORIG_NAME;
+      }
+-     put_byte(flags);         /* general flags */
+-     put_long(time_stamp);
+- 
+-     /* Write deflated file to zip file */
+-     crc = updcrc(0, 0);
+  
+      bi_init(out);
+      ct_init(&attr, &method);
+      lm_init(level, &deflate_flags);
+  
+!     put_byte((uch)deflate_flags); /* extra flags */
+!     put_byte(OS_CODE);            /* OS identifier */
+! 
+!     if (save_orig_name) {
+! 	char *p = basename(ifname); /* Don't save the directory part. */
+! 	do {
+  	    put_char(*p);
+! 	} while (*p++);
+      }
+-     header_bytes = (long)outcnt;
+  
+      (void)deflate();
+  
+--- 44,81 ----
+  
+      /* Write the header to the gzip file. See algorithm.doc for the format */
+  
+!     if (!noheader) {		/* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+! 	method = DEFLATED;
+! 	put_byte(GZIP_MAGIC[0]); /* magic header */
+! 	put_byte(GZIP_MAGIC[1]);
+! 	put_byte(DEFLATED);      /* compression method */
+! 
+! 	if (save_orig_name) {
+! 	    flags |= ORIG_NAME;
+! 	}
+! 	put_byte(flags);         /* general flags */
+! 	put_long(time_stamp);
+  
+! 	/* Write deflated file to zip file */
+! 	crc = updcrc(0, 0);
+      }
+  
+      bi_init(out);
+      ct_init(&attr, &method);
+      lm_init(level, &deflate_flags);
+  
+!     if (!noheader) {		/* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+! 	put_byte((uch)deflate_flags); /* extra flags */
+! 	put_byte(OS_CODE);            /* OS identifier */
+! 
+! 	if (save_orig_name) {
+! 	  char *p = basename(ifname); /* Don't save the directory part. */
+! 	  do {
+  	    put_char(*p);
+! 	  } while (*p++);
+! 	}
+! 	header_bytes = (long)outcnt;
+      }
+  
+      (void)deflate();
+  
+***************
+*** 85,94 ****
+      }
+  #endif
+  
+!     /* Write the crc and uncompressed size */
+!     put_long(crc);
+!     put_long(isize);
+!     header_bytes += 2*sizeof(long);
+  
+      flush_outbuf();
+      return OK;
+--- 90,101 ----
+      }
+  #endif
+  
+!     if (!noheader) {	/* DAC 2000/12/23: inflate/deflate only - don't write/check for gzip header */
+! 	/* Write the crc and uncompressed size */
+! 	put_long(crc);
+! 	put_long(isize);
+! 	header_bytes += 2*sizeof(long);
+!     }
+  
+      flush_outbuf();
+      return OK;
diff --git a/support/gzip-1.3.12-patchfornoheader b/support/gzip-1.3.12-patchfornoheader
new file mode 100644
index 0000000..d4e6c61
--- /dev/null
+++ b/support/gzip-1.3.12-patchfornoheader
@@ -0,0 +1,575 @@
+Only in gzip-1.3.12-dac: .deps
+Only in gzip-1.3.12-dac: Makefile
+Only in gzip-1.3.12-dac: config.log
+Only in gzip-1.3.12-dac: config.status
+Only in gzip-1.3.12-dac/doc: Makefile
+diff -rc gzip-1.3.12/gzip.1 gzip-1.3.12-dac/gzip.1
+*** gzip-1.3.12/gzip.1	2006-12-08 13:45:37.000000000 -0500
+--- gzip-1.3.12-dac/gzip.1	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 4,10 ****
+  .SH SYNOPSIS
+  .ll +8
+  .B gzip
+! .RB [ " \-acdfhlLnNrtvV19 " ]
+  .RB [ \-S\ suffix ]
+  [
+  .I "name \&..."
+--- 4,10 ----
+  .SH SYNOPSIS
+  .ll +8
+  .B gzip
+! .RB [ " \-acdfhlLnNrtvV19x " ]
+  .RB [ \-S\ suffix ]
+  [
+  .I "name \&..."
+***************
+*** 189,194 ****
+--- 189,198 ----
+  
+  .SH OPTIONS
+  .TP
++ .B \-x --no-header
++ Do not create or expect a gzip header ... write or read a purely compressed
++ bitstream only. Unless overridden, a suffix of ".dfl" will be added/expected.
++ .TP
+  .B \-a --ascii
+  Ascii text mode: convert end-of-lines using local conventions. This option
+  is supported only on some non-Unix systems. For MSDOS, CR LF is converted
+diff -rc gzip-1.3.12/gzip.c gzip-1.3.12-dac/gzip.c
+*** gzip-1.3.12/gzip.c	2007-03-20 01:09:51.000000000 -0400
+--- gzip-1.3.12-dac/gzip.c	2008-04-07 20:40:20.000000000 -0400
+***************
+*** 180,185 ****
+--- 180,186 ----
+  
+  		/* local variables */
+  
++ int noheader = 0;     /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  int ascii = 0;        /* convert end-of-lines to local OS conventions */
+  int to_stdout = 0;    /* output to stdout (-c) */
+  int decompress = 0;   /* decompress (-d) */
+***************
+*** 235,240 ****
+--- 236,242 ----
+  struct option longopts[] =
+  {
+   /* { name  has_arg  *flag  val } */
++     {"no-header",  0, 0, 'x'}, /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+      {"ascii",      0, 0, 'a'}, /* ascii text mode */
+      {"to-stdout",  0, 0, 'c'}, /* write output on standard output */
+      {"stdout",     0, 0, 'c'}, /* write output on standard output */
+***************
+*** 286,292 ****
+  local RETSIGTYPE abort_gzip_signal OF((int));
+  local void do_exit      OF((int exitcode)) ATTRIBUTE_NORETURN;
+        int main          OF((int argc, char **argv));
+! int (*work) OF((int infile, int outfile)) = zip; /* function to call */
+  
+  #if ! NO_DIR
+  local void treat_dir    OF((int fd, char *dir));
+--- 288,294 ----
+  local RETSIGTYPE abort_gzip_signal OF((int));
+  local void do_exit      OF((int exitcode)) ATTRIBUTE_NORETURN;
+        int main          OF((int argc, char **argv));
+! int (*work) OF((int infile, int outfile, int noheader)) = zip; /* function to call */
+  
+  #if ! NO_DIR
+  local void treat_dir    OF((int fd, char *dir));
+***************
+*** 335,340 ****
+--- 337,343 ----
+   "  -t, --test        test compressed file integrity",
+   "  -v, --verbose     verbose mode",
+   "  -V, --version     display version number",
++  "  -x, --no-header   inflate/deflate only - don't write/check for gzip header",	/* DAC 2008/04/07 */
+   "  -1, --fast        compress faster",
+   "  -9, --best        compress better",
+  #ifdef LZW
+***************
+*** 423,433 ****
+      z_suffix = Z_SUFFIX;
+      z_len = strlen(z_suffix);
+  
+!     while ((optc = getopt_long (argc, argv, "ab:cdfhH?lLmMnNqrS:tvVZ123456789",
+  				longopts, (int *)0)) != -1) {
+  	switch (optc) {
+!         case 'a':
+!             ascii = 1; break;
+  	case 'b':
+  	    maxbits = atoi(optarg);
+  	    for (; *optarg; optarg++)
+--- 426,440 ----
+      z_suffix = Z_SUFFIX;
+      z_len = strlen(z_suffix);
+  
+!     while ((optc = getopt_long (argc, argv, "xab:cdfhH?lLmMnNqrS:tvVZ123456789",
+  				longopts, (int *)0)) != -1) {
+  	switch (optc) {
+! 	case 'a':
+! 		ascii = 1; break;
+! 	case 'x':	/* DAC 2008/04/07: inflate/deflate only - don't write/check for gzip header */
+! 		z_suffix = ".dfl";
+! 		z_len = strlen(z_suffix);
+! 		noheader = 1; break;
+  	case 'b':
+  	    maxbits = atoi(optarg);
+  	    for (; *optarg; optarg++)
+***************
+*** 641,647 ****
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(fileno(stdin), fileno(stdout)) != OK) return;
+  
+  	if (input_eof ())
+  	  break;
+--- 648,654 ----
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(fileno(stdin), fileno(stdout), noheader) != OK) return;
+  
+  	if (input_eof ())
+  	  break;
+***************
+*** 806,812 ****
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(ifd, ofd) != OK) {
+  	    method = -1; /* force cleanup */
+  	    break;
+  	}
+--- 813,819 ----
+      /* Actually do the compression/decompression. Loop over zipped members.
+       */
+      for (;;) {
+! 	if ((*work)(ifd, ofd, noheader) != OK) {
+  	    method = -1; /* force cleanup */
+  	    break;
+  	}
+***************
+*** 1231,1236 ****
+--- 1238,1252 ----
+      int imagic1;   /* like magic[1], but can represent EOF */
+      ulg stamp;     /* time stamp */
+  
++     if (noheader) {		/* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
++ 	method = DEFLATED;
++ 	work=unzip;
++ 	flags=0;
++ 	inptr = 0;
++ 	last_member = 1;
++ 	return method;
++     }
++ 
+      /* If --force and --stdout, zcat == cat, so do not complain about
+       * premature end of file: use try_byte instead of get_byte.
+       */
+diff -rc gzip-1.3.12/gzip.h gzip-1.3.12-dac/gzip.h
+*** gzip-1.3.12/gzip.h	2007-03-20 01:09:51.000000000 -0400
+--- gzip-1.3.12-dac/gzip.h	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 283,300 ****
+  		   if (exit_code == OK) exit_code = WARNING;}
+  
+  	/* in zip.c: */
+! extern int zip        OF((int in, int out));
+  extern int file_read  OF((char *buf,  unsigned size));
+  
+  	/* in unzip.c */
+! extern int unzip      OF((int in, int out));
+  extern int check_zipfile OF((int in));
+  
+  	/* in unpack.c */
+! extern int unpack     OF((int in, int out));
+  
+  	/* in unlzh.c */
+! extern int unlzh      OF((int in, int out));
+  
+  	/* in gzip.c */
+  void abort_gzip OF((void)) ATTRIBUTE_NORETURN;
+--- 283,300 ----
+  		   if (exit_code == OK) exit_code = WARNING;}
+  
+  	/* in zip.c: */
+! extern int zip        OF((int in, int out, int noheader));
+  extern int file_read  OF((char *buf,  unsigned size));
+  
+  	/* in unzip.c */
+! extern int unzip      OF((int in, int out, int noheader));
+  extern int check_zipfile OF((int in));
+  
+  	/* in unpack.c */
+! extern int unpack     OF((int in, int out, int noheader));
+  
+  	/* in unlzh.c */
+! extern int unlzh      OF((int in, int out, int noheader));
+  
+  	/* in gzip.c */
+  void abort_gzip OF((void)) ATTRIBUTE_NORETURN;
+***************
+*** 317,323 ****
+  extern   int (*read_buf) OF((char *buf, unsigned size));
+  
+  	/* in util.c: */
+! extern int copy           OF((int in, int out));
+  extern ulg  updcrc        OF((uch *s, unsigned n));
+  extern void clear_bufs    OF((void));
+  extern int  fill_inbuf    OF((int eof_ok));
+--- 317,323 ----
+  extern   int (*read_buf) OF((char *buf, unsigned size));
+  
+  	/* in util.c: */
+! extern int copy           OF((int in, int out, int noheader));
+  extern ulg  updcrc        OF((uch *s, unsigned n));
+  extern void clear_bufs    OF((void));
+  extern int  fill_inbuf    OF((int eof_ok));
+Only in gzip-1.3.12-dac/lib: .deps
+Only in gzip-1.3.12-dac/lib: Makefile
+Only in gzip-1.3.12-dac/lib: config.h
+Only in gzip-1.3.12-dac/lib: stamp-h1
+diff -rc gzip-1.3.12/lzw.c gzip-1.3.12-dac/lzw.c
+*** gzip-1.3.12/lzw.c	1999-10-06 01:01:31.000000000 -0400
+--- gzip-1.3.12-dac/lzw.c	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 14,21 ****
+  static int msg_done = 0;
+  
+  /* Compress in to out with lzw method. */
+! int lzw(in, out)
+      int in, out;
+  {
+      if (msg_done) return ERROR;
+      msg_done = 1;
+--- 14,22 ----
+  static int msg_done = 0;
+  
+  /* Compress in to out with lzw method. */
+! int lzw(in, out, noheader)
+      int in, out;
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      if (msg_done) return ERROR;
+      msg_done = 1;
+diff -rc gzip-1.3.12/lzw.h gzip-1.3.12-dac/lzw.h
+*** gzip-1.3.12/lzw.h	2006-11-20 03:40:33.000000000 -0500
+--- gzip-1.3.12-dac/lzw.h	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 50,54 ****
+  extern int maxbits;      /* max bits per code for LZW */
+  extern int block_mode;   /* block compress mode -C compatible with 2.0 */
+  
+! extern int lzw    OF((int in, int out));
+! extern int unlzw  OF((int in, int out));
+--- 50,54 ----
+  extern int maxbits;      /* max bits per code for LZW */
+  extern int block_mode;   /* block compress mode -C compatible with 2.0 */
+  
+! extern int lzw    OF((int in, int out, int noheader));
+! extern int unlzw  OF((int in, int out, int noheader));
+diff -rc gzip-1.3.12/unlzh.c gzip-1.3.12-dac/unlzh.c
+*** gzip-1.3.12/unlzh.c	2006-11-20 03:40:34.000000000 -0500
+--- gzip-1.3.12-dac/unlzh.c	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 383,391 ****
+  /* ===========================================================================
+   * Unlzh in to out. Return OK or ERROR.
+   */
+! int unlzh(in, out)
+      int in;
+      int out;
+  {
+      unsigned n;
+      ifd = in;
+--- 383,392 ----
+  /* ===========================================================================
+   * Unlzh in to out. Return OK or ERROR.
+   */
+! int unlzh(in, out, noheader)
+      int in;
+      int out;
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      unsigned n;
+      ifd = in;
+diff -rc gzip-1.3.12/unlzw.c gzip-1.3.12-dac/unlzw.c
+*** gzip-1.3.12/unlzw.c	2006-12-11 13:54:39.000000000 -0500
+--- gzip-1.3.12-dac/unlzw.c	2008-04-07 20:24:18.000000000 -0400
+***************
+*** 188,195 ****
+   *   The magic header has already been checked and skipped.
+   *   bytes_in and bytes_out have been initialized.
+   */
+! int unlzw(in, out)
+      int in, out;    /* input and output file descriptors */
+  {
+      REG2   char_type  *stackp;
+      REG3   code_int   code;
+--- 188,196 ----
+   *   The magic header has already been checked and skipped.
+   *   bytes_in and bytes_out have been initialized.
+   */
+! int unlzw(in, out, noheader)
+      int in, out;    /* input and output file descriptors */
++ 	int noheader;	/* DAC 2008/04/07: inflate/deflate only - don't write/check for gzip header */
+  {
+      REG2   char_type  *stackp;
+      REG3   code_int   code;
+diff -rc gzip-1.3.12/unpack.c gzip-1.3.12-dac/unpack.c
+*** gzip-1.3.12/unpack.c	2006-11-20 03:40:34.000000000 -0500
+--- gzip-1.3.12-dac/unpack.c	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 200,207 ****
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unpack(in, out)
+      int in, out;            /* input and output file descriptors */
+  {
+      int len;                /* Bit length of current code */
+      unsigned eob;           /* End Of Block code */
+--- 200,208 ----
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unpack(in, out, noheader)
+      int in, out;            /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      int len;                /* Bit length of current code */
+      unsigned eob;           /* End Of Block code */
+diff -rc gzip-1.3.12/unzip.c gzip-1.3.12-dac/unzip.c
+*** gzip-1.3.12/unzip.c	2006-11-20 03:40:34.000000000 -0500
+--- gzip-1.3.12-dac/unzip.c	2008-04-07 20:44:55.000000000 -0400
+***************
+*** 113,120 ****
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unzip(in, out)
+      int in, out;   /* input and output file descriptors */
+  {
+      ulg orig_crc = 0;       /* original crc */
+      ulg orig_len = 0;       /* original uncompressed length */
+--- 113,121 ----
+   *   the compressed data, from offsets inptr to insize-1 included.
+   *   The magic header has already been checked. The output buffer is cleared.
+   */
+! int unzip(in, out, noheader)
+      int in, out;   /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      ulg orig_crc = 0;       /* original crc */
+      ulg orig_len = 0;       /* original uncompressed length */
+***************
+*** 127,133 ****
+  
+      updcrc(NULL, 0);           /* initialize crc */
+  
+!     if (pkzip && !ext_header) {  /* crc and length at the end otherwise */
+  	orig_crc = LG(inbuf + LOCCRC);
+  	orig_len = LG(inbuf + LOCLEN);
+      }
+--- 128,134 ----
+  
+      updcrc(NULL, 0);           /* initialize crc */
+  
+!     if (!noheader && pkzip && !ext_header) {  /* crc and length at the end otherwise */ /* DAC 2000/12/23 add noheader */
+  	orig_crc = LG(inbuf + LOCCRC);
+  	orig_len = LG(inbuf + LOCLEN);
+      }
+***************
+*** 161,167 ****
+  	gzip_error ("internal error, invalid method");
+      }
+  
+!     /* Get the crc and original length */
+      if (!pkzip) {
+          /* crc32  (see algorithm.doc)
+  	 * uncompressed input size modulo 2^32
+--- 162,169 ----
+  	gzip_error ("internal error, invalid method");
+      }
+  
+!     if (!noheader) {							/* DAC 2008/04/07 */
+! 	/* Get the crc and original length */
+      if (!pkzip) {
+          /* crc32  (see algorithm.doc)
+  	 * uncompressed input size modulo 2^32
+***************
+*** 184,190 ****
+  	orig_crc = LG(buf+4);
+  	orig_len = LG(buf+12);
+      }
+! 
+      /* Validate decompression */
+      if (orig_crc != updcrc(outbuf, 0)) {
+  	fprintf(stderr, "\n%s: %s: invalid compressed data--crc error\n",
+--- 186,192 ----
+  	orig_crc = LG(buf+4);
+  	orig_len = LG(buf+12);
+      }
+! 	
+      /* Validate decompression */
+      if (orig_crc != updcrc(outbuf, 0)) {
+  	fprintf(stderr, "\n%s: %s: invalid compressed data--crc error\n",
+***************
+*** 196,204 ****
+  		program_name, ifname);
+  	err = ERROR;
+      }
+  
+      /* Check if there are more entries in a pkzip file */
+!     if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
+  	if (to_stdout) {
+  	    WARN((stderr,
+  		  "%s: %s has more than one entry--rest ignored\n",
+--- 198,207 ----
+  		program_name, ifname);
+  	err = ERROR;
+      }
++ 	}
+  
+      /* Check if there are more entries in a pkzip file */
+!     if (!noheader && pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
+  	if (to_stdout) {
+  	    WARN((stderr,
+  		  "%s: %s has more than one entry--rest ignored\n",
+diff -rc gzip-1.3.12/util.c gzip-1.3.12-dac/util.c
+*** gzip-1.3.12/util.c	2006-12-11 13:54:39.000000000 -0500
+--- gzip-1.3.12-dac/util.c	2008-04-07 17:43:16.000000000 -0400
+***************
+*** 60,67 ****
+   * Copy input to output unchanged: zcat == cat with --force.
+   * IN assertion: insize bytes have already been read in inbuf.
+   */
+! int copy(in, out)
+      int in, out;   /* input and output file descriptors */
+  {
+      errno = 0;
+      while (insize != 0 && (int)insize != -1) {
+--- 60,68 ----
+   * Copy input to output unchanged: zcat == cat with --force.
+   * IN assertion: insize bytes have already been read in inbuf.
+   */
+! int copy(in, out, noheader)
+      int in, out;   /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      errno = 0;
+      while (insize != 0 && (int)insize != -1) {
+diff -rc gzip-1.3.12/zip.c gzip-1.3.12-dac/zip.c
+*** gzip-1.3.12/zip.c	2007-03-20 01:09:51.000000000 -0400
+--- gzip-1.3.12-dac/zip.c	2008-04-07 20:22:45.000000000 -0400
+***************
+*** 43,50 ****
+   * IN assertions: the input and output buffers are cleared.
+   *   The variables time_stamp and save_orig_name are initialized.
+   */
+! int zip(in, out)
+      int in, out;            /* input and output file descriptors */
+  {
+      uch  flags = 0;         /* general purpose bit flags */
+      ush  attr = 0;          /* ascii/binary flag */
+--- 43,51 ----
+   * IN assertions: the input and output buffers are cleared.
+   *   The variables time_stamp and save_orig_name are initialized.
+   */
+! int zip(in, out, noheader)
+      int in, out;            /* input and output file descriptors */
++     int noheader;	    /* DAC 2000/12/17: inflate/deflate only - don't write/check for gzip header */
+  {
+      uch  flags = 0;         /* general purpose bit flags */
+      ush  attr = 0;          /* ascii/binary flag */
+***************
+*** 57,63 ****
+  
+      /* Write the header to the gzip file. See algorithm.doc for the format */
+  
+!     method = DEFLATED;
+      put_byte(GZIP_MAGIC[0]); /* magic header */
+      put_byte(GZIP_MAGIC[1]);
+      put_byte(DEFLATED);      /* compression method */
+--- 58,65 ----
+  
+      /* Write the header to the gzip file. See algorithm.doc for the format */
+  
+!     if (!noheader) {		/* DAC 2008/04/07: inflate/deflate only - don't write/check for gzip header */
+! 	method = DEFLATED;
+      put_byte(GZIP_MAGIC[0]); /* magic header */
+      put_byte(GZIP_MAGIC[1]);
+      put_byte(DEFLATED);      /* compression method */
+***************
+*** 73,83 ****
+  
+      /* Write deflated file to zip file */
+      crc = updcrc(0, 0);
+! 
+      bi_init(out);
+      ct_init(&attr, &method);
+      lm_init(level, &deflate_flags);
+  
+      put_byte((uch)deflate_flags); /* extra flags */
+      put_byte(OS_CODE);            /* OS identifier */
+  
+--- 75,87 ----
+  
+      /* Write deflated file to zip file */
+      crc = updcrc(0, 0);
+! 	}
+! 	
+      bi_init(out);
+      ct_init(&attr, &method);
+      lm_init(level, &deflate_flags);
+  
++ 	if (!noheader) {		/* DAC 2008/04/07: inflate/deflate only - don't write/check for gzip header */
+      put_byte((uch)deflate_flags); /* extra flags */
+      put_byte(OS_CODE);            /* OS identifier */
+  
+***************
+*** 88,94 ****
+  	} while (*p++);
+      }
+      header_bytes = (off_t)outcnt;
+! 
+      (void)deflate();
+  
+  #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
+--- 92,99 ----
+  	} while (*p++);
+      }
+      header_bytes = (off_t)outcnt;
+! 	}
+! 	
+      (void)deflate();
+  
+  #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
+***************
+*** 101,111 ****
+      }
+  #endif
+  
+!     /* Write the crc and uncompressed size */
+      put_long(crc);
+      put_long((ulg)bytes_in);
+      header_bytes += 2*sizeof(long);
+! 
+      flush_outbuf();
+      return OK;
+  }
+--- 106,118 ----
+      }
+  #endif
+  
+!     if (!noheader) {	/* DAC 2008/04/07: inflate/deflate only - don't write/check for gzip header */
+! 	/* Write the crc and uncompressed size */
+      put_long(crc);
+      put_long((ulg)bytes_in);
+      header_bytes += 2*sizeof(long);
+! 	}
+! 	
+      flush_outbuf();
+      return OK;
+  }
diff --git a/support/linksb b/support/linksb
new file mode 100755
index 0000000..1a2c9f3
--- /dev/null
+++ b/support/linksb
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+sbdir=$1
+shift
+
+if [ ! -d $sbdir ]; then mkdir $sbdir; fi
+
+cd $sbdir
+
+for subdir in NewRoot Refd
+do
+	if [ ! -d $subdir ]; then mkdir $subdir; fi
+	for dir in $*
+	do
+		echo "Checking $dir for $subdir"
+		for file in `find ../$dir -name '*.bd' -print | grep $subdir`
+		do
+			if [ -f "$file" ]
+			then
+				cd $subdir
+				echo $file
+				if [ ! -f `basename $file` ]
+				then
+					ln -s ../$file
+				fi
+				cd ..
+			fi
+		done
+	done
+done
+
+exit 0
diff --git a/support/mktime.cc b/support/mktime.cc
new file mode 100755
index 0000000..152dd33
--- /dev/null
+++ b/support/mktime.cc
@@ -0,0 +1,71 @@
+#if USESTANDARDHEADERSWITHOUTEXTENSION == 1
+#include <ctime>
+#include <iostream>
+#include <cassert>
+#include <cstdlib>
+#else
+#include <time.h>
+#include <iostream.h>
+#include <assert.h>
+#include <stdlib.h>
+#endif
+
+#if EMITUSINGSTDNAMESPACE == 1
+using namespace std;
+#endif
+
+// specify string datetime (UTC) on command line
+
+// return seconds since 00:00:00 UTC, January 1, 1970
+
+time_t
+mktime_fromstrings(const char *yyyy,const char *mm,const char *dd,const char *hh,const char *min,const char *ss)
+{
+	struct tm sourcetime;
+
+	sourcetime.tm_isdst=-1;		// don't mess with DST
+	sourcetime.tm_year = 70;	/* years since 1900 */
+	sourcetime.tm_mon  = 0;		/* months since January [0, 11] */
+	sourcetime.tm_mday = 1;		/* day of the month [1, 31] */
+	sourcetime.tm_hour = 0;		/* hour since midnight [0, 23] */
+	sourcetime.tm_min  = 0;		/* minutes after the hour [0, 59] */
+	sourcetime.tm_sec  = 0;		/* seconds after the minute [0, 61]  */
+
+	time_t timezoneoffset=mktime(&sourcetime);
+	assert(timezoneoffset != -1);
+
+	sourcetime.tm_isdst=-1;			// don't mess with DST
+	sourcetime.tm_year = atoi(yyyy)-1900;	/* years since 1900 */
+	sourcetime.tm_mon  = atoi(mm)-1;	/* months since January [0, 11] */
+	sourcetime.tm_mday = atoi(dd);		/* day of the month [1, 31] */
+	sourcetime.tm_hour = atoi(hh);		/* hour since midnight [0, 23] */
+	sourcetime.tm_min  = atoi(min);		/* minutes after the hour [0, 59] */
+	sourcetime.tm_sec  = atoi(ss);		/* seconds after the minute [0, 61]  */
+
+	time_t value = mktime(&sourcetime);
+	assert(value != -1);
+
+	cout <<        sourcetime.tm_year+1900
+	     << "/" << sourcetime.tm_mon+1
+	     << "/" << sourcetime.tm_mday
+	     << " " << sourcetime.tm_hour
+	     << ":" << sourcetime.tm_min
+	     << ":" << sourcetime.tm_sec
+	     << " -> " << (value - timezoneoffset) << " seconds since 00:00:00, January 1, 1970"
+	     << endl;
+
+	return value;
+}
+
+int main(int argc,char **argv)
+{
+//cerr << "timezone = " << timezone << endl;
+//cerr << "daylight = " << daylight << endl;
+
+	if (argc == 7) {
+		(void)mktime_fromstrings(argv[1],argv[2],argv[3],argv[4],argv[5],argv[6]);
+	}
+	else {
+		assert(0);
+	}
+}
diff --git a/support/noincsub b/support/noincsub
new file mode 100755
index 0000000..0c793b5
--- /dev/null
+++ b/support/noincsub
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# recursively removes paths in #include "" from source files
+
+dodirectory() {
+	echo Directory `pwd`
+	for i in $*
+	do
+		if [ -d $i ]
+		then
+			(cd $i; dodirectory *)
+		fi
+	done
+
+	for i in *.h *.hpp *.c *.cc *.C *.CC *.cp *.cpp
+	do
+		if [ -f $i ]
+		then
+			echo Updating $i
+			rm -f $i.BAK
+			mv $i $i.BAK
+			nawk <$i.BAK >$i '
+				!/^[ 	]*\#include.*\"[^\"]*\//	{ print }
+				/^[ 	]*\#include.*\"[^\"]*\//	{
+					sub("^[ 	]*\#include.*\"[^\"]*\/","#include \"")
+					print
+				}
+			'
+			if [ -f $i ] ; then rm -f $i.BAK ; fi
+		fi
+	done
+}
+
+dodirectory $*
diff --git a/support/recurse b/support/recurse
new file mode 100755
index 0000000..635719a
--- /dev/null
+++ b/support/recurse
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# recursively executes command $1 on current and directories
+
+commandtodo="$1"
+
+dodirectory() {
+	# echo Directory `pwd`
+	for i in *
+	do
+		if [ -d $i ]
+		then
+			(cd $i; dodirectory)
+		fi
+	done
+
+	sh -c "$commandtodo"
+}
+
+dodirectory
diff --git a/support/setplatform b/support/setplatform
new file mode 100755
index 0000000..68637c8
--- /dev/null
+++ b/support/setplatform
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+PLATFORM=`uname -a | tr -d '"'`
+
+rm -f libsrc/src/generic/platform.cc
+
+echo  > libsrc/src/generic/platform.cc "// Automatically generated - EDITS WILL BE LOST"
+echo >> libsrc/src/generic/platform.cc ""
+echo >> libsrc/src/generic/platform.cc "// Generated by support/setplatform"
+echo >> libsrc/src/generic/platform.cc ""
+echo >> libsrc/src/generic/platform.cc "#include \"platform.h\""
+echo >> libsrc/src/generic/platform.cc ""
+echo >> libsrc/src/generic/platform.cc "const char* dicom3tools_platform_string = \"${PLATFORM}\";"
diff --git a/support/setversion b/support/setversion
new file mode 100755
index 0000000..aec19a1
--- /dev/null
+++ b/support/setversion
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION="1.00.snapshot."`date +%Y%m%d%H%M%S`
+
+rm -f libsrc/src/generic/version.cc
+
+echo  > libsrc/src/generic/version.cc "// Automatically generated - EDITS WILL BE LOST"
+echo >> libsrc/src/generic/version.cc ""
+echo >> libsrc/src/generic/version.cc "// Generated by support/setversion"
+echo >> libsrc/src/generic/version.cc ""
+echo >> libsrc/src/generic/version.cc "#include \"version.h\""
+echo >> libsrc/src/generic/version.cc ""
+echo >> libsrc/src/generic/version.cc "const char* dicom3tools_version_string = \"${VERSION}\";"
+
+rm VERSION
+
+echo "${VERSION}" >VERSION
diff --git a/support/stanford.pvrg.jpeg.ge.patch.19990405 b/support/stanford.pvrg.jpeg.ge.patch.19990405
new file mode 100755
index 0000000..b09600b
--- /dev/null
+++ b/support/stanford.pvrg.jpeg.ge.patch.19990405
@@ -0,0 +1,144 @@
+diff -r -c jpegdir/huffman.c jpegdir.ge/huffman.c
+*** jpegdir/huffman.c	Wed Mar  1 20:57:22 1995
+--- jpegdir.ge/huffman.c	Mon Jan  4 14:10:44 1999
+***************
+*** 57,62 ****
+--- 57,63 ----
+  extern void MakeDhuff();
+  extern void UseACHuffman();
+  extern void UseDCHuffman();
++ extern void UseDCHuffmanCheckingGEMSBug();
+  extern void SetACHuffman();
+  extern void SetDCHuffman();
+  extern void PrintHuffman();
+***************
+*** 678,684 ****
+--- 679,721 ----
+       int index;
+  {
+    BEGIN("UseDCHuffman");
++ index = 0;
++   Xhuff = CImage->DCXhuff[index];
++   Dhuff = CImage->DCDhuff[index];
++   Ehuff = CImage->DCEhuff[index];
++   if (!Dhuff && !Ehuff)
++     {
++       WHEREAMI();
++       printf("Reference to nonexistent table %d.\n",index);
++     }
++ }
+  
++ /*BFUNC
++ 
++ UseDCHuffmanCheckingGEMSBug() installs the DC Huffman structure from the CImage
++ structure.
++ 
++ EFUNC*/
++ 
++ void UseDCHuffmanCheckingGEMSBug(index,detected_gems_predictor_bug)
++      int index;
++      int *detected_gems_predictor_bug;
++ {
++   BEGIN("UseDCHuffmanCheckingGEMSBug");
++ 
++   if (index == 1
++    && !CImage->DCDhuff[index] && !CImage->DCEhuff[index]
++    && CImage->DCDhuff[0] && !CImage->DCEhuff[0])
++     {
++       index = 0;
++       *detected_gems_predictor_bug = 1;
++       printf("GE table selection bug detected - assuming predictor bug also\n",index);
++     }
++   else
++     {
++       *detected_gems_predictor_bug = 0;
++     }
++ 
+    Xhuff = CImage->DCXhuff[index];
+    Dhuff = CImage->DCDhuff[index];
+    Ehuff = CImage->DCEhuff[index];
+diff -r -c jpegdir/jpeg.c jpegdir.ge/jpeg.c
+*** jpegdir/jpeg.c	Wed Mar  1 20:57:21 1995
+--- jpegdir.ge/jpeg.c	Mon Jan  4 16:59:32 1999
+***************
+*** 1358,1363 ****
+--- 1358,1365 ----
+    int MaxElem,CurrentElem,NumberElem;
+    int StartofLine=1,UseType=1;              /* Start with type 1 coding */
+    int *input;
++   int last_pixel;				/* should initialize this sometime */
++   int detected_gems_predictor_bug;
+  
+    PointTransform=CScan->SAL;
+    for(j=0;j<CScan->NumberComponents;j++)    /* Important to rewind to start */
+***************
+*** 1379,1385 ****
+  	}
+      }
+    InstallIob(0);
+!   UseDCHuffman(CScan->td[0]);          /* Install DC table */
+    if (CScan->NumberComponents==1)
+      height=horfreq=1;
+    else
+--- 1381,1387 ----
+  	}
+      }
+    InstallIob(0);
+!   UseDCHuffmanCheckingGEMSBug(CScan->td[0],&detected_gems_predictor_bug);          /* Install DC table */
+    if (CScan->NumberComponents==1)
+      height=horfreq=1;
+    else
+***************
+*** 1466,1472 ****
+  	      px = input[width];
+  	      break;
+  	    case 2:
+! 	      px = input[1];
+  	      break;
+  	    case 3:
+  	      px = input[0];
+--- 1468,1475 ----
+  	      px = input[width];
+  	      break;
+  	    case 2:
+! 	    /*px = input[1];*/
+! 	      px = detected_gems_predictor_bug ? last_pixel : input[1];
+  	      break;
+  	    case 3:
+  	      px = input[0];
+***************
+*** 1493,1499 ****
+  	  else
+  	    {
+  	      value = LosslessDecodeDC();
+! 	      input[width+1] = (value+px)&0xffff;
+  	      if (Loud > MUTE)
+  		{
+  		  printf("OUT=%d  PX=%d  VAL: %d\n",
+--- 1496,1508 ----
+  	  else
+  	    {
+  	      value = LosslessDecodeDC();
+! 	      if (detected_gems_predictor_bug) {
+! 	        input[width+1] = (px-value)&0xffff;
+! 	        last_pixel = (px-value)&0xffff;
+! 	      }
+! 	      else {
+! 	        input[width+1] = (value+px)&0xffff;
+! 	      }
+  	      if (Loud > MUTE)
+  		{
+  		  printf("OUT=%d  PX=%d  VAL: %d\n",
+diff -r -c jpegdir/prototypes.h jpegdir.ge/prototypes.h
+*** jpegdir/prototypes.h	Wed Mar  1 20:57:18 1995
+--- jpegdir.ge/prototypes.h	Mon Jan  4 14:09:13 1999
+***************
+*** 85,90 ****
+--- 85,91 ----
+  extern void MakeDhuff();
+  extern void UseACHuffman();
+  extern void UseDCHuffman();
++ extern void UseDCHuffmanCheckingGEMSBug();
+  extern void SetACHuffman();
+  extern void SetDCHuffman();
+  extern void PrintHuffman();
diff --git a/support/testapp b/support/testapp
new file mode 100755
index 0000000..8f13ae1
--- /dev/null
+++ b/support/testapp
@@ -0,0 +1,198 @@
+#!/bin/sh
+
+# Usage: $0 testlist appname options imagedir testlogdir create|compare dump|cp|todc|ancp|filter
+
+TMPROOT="/tmp/`basename $0`.$$"
+
+bad="false"
+
+if [ "$#" != 7 ]
+then
+	bad="true"
+else
+	testlist="$1"	# eg. "testlist"
+	appname="$2"	# eg. ./dcdump or ./dccp or ./xxxxdump or ./xxxxtodc
+	options="$3"	# eg. "" or "-v -stamp 9999"
+	imagedir="$4"	# eg. $(TOPDIR)/images/dicom
+	testlogdir="$5"	# eg. $(TOPDIR)/test/$(CURRENT_DIR)
+	mode="$6"	# eg. create|compare
+	role="$7"	# eg. dump|cp|todc|ancp|filter
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	# ... allow any role ...
+	#elif [ "$role" != "cp" -a "$role" != "todc" -a "$role" != "dump" ]
+	#then
+	#	echo "$0: role not copy or dump" 1>&2
+	#	bad="true"
+	elif [ ! -d "$testlogdir" -a "$mode" = "create" ]
+	then
+		echo "$0: making test log directory \"$testlogdir\"" 1>&2
+		mkdirhier "$testlogdir"
+		#echo "$0: no such test log directory as \"$testlogdir\"" 1>&2
+		#bad="true"
+	elif [ ! -d "$imagedir" ]
+	then
+		echo "$0: no such image directory as \"$imagedir\"" 1>&2
+		bad="true"
+	elif [ ! -f "$imagedir/$testlist" ]
+	then
+			echo "$0: no testlist \"$testlist\" in \"$imagedir\"" 1>&2
+	bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 testlist appname options imagedir testlogdir create|compare dump|cp|todc|ancp|filter" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	if [ ! -d "$testlogdir" ]
+	then
+		mkdirhier "$testlogdir"
+	fi
+fi
+
+baseappname=`basename $appname`
+
+for filename in `cat $imagedir/$testlist`
+do
+	logname=`echo "$filename" | sed 's:/:.:g'`
+	tmpname="/tmp/`basename $0`.`basename $filename`.$$"
+	usefullname="$imagedir/$filename"
+	rmusefullname="no"
+	if [ ! -f "$usefullname" ]
+	then
+		if [ -f "$usefullname.z" ]
+		then
+			echo "$baseappname: decompressing $usefullname.z ..."
+			zcat $usefullname.z >$tmpname
+			usefullname=$tmpname
+			rmusefullname="yes"
+		elif [ -f "$usefullname.gz" ]
+		then
+			echo "$baseappname: decompressing $usefullname.gz ..."
+			zcat $usefullname.gz >$tmpname
+			usefullname=$tmpname
+			rmusefullname="yes"
+		elif [ -f "$usefullname.Z" ]
+		then
+			echo "$baseappname: decompressing $usefullname.Z ..."
+			zcat $usefullname.Z >$tmpname
+			usefullname=$tmpname
+			rmusefullname="yes"
+		else
+			echo "No such file as $usefullname or compressed variants" 1>&2
+			exit 1
+		fi
+	fi
+
+	if [ -f "$usefullname" ]
+	then
+		if [ "$mode" = "create" ]
+		then
+			stdout="$testlogdir/$logname.$baseappname.$role.stdout"
+			stderr="$testlogdir/$logname.$baseappname.$role.stderr"
+			outfile="$testlogdir/$logname.$baseappname.$role.outfile"
+		else
+			stdout="$TMPROOT.stdout"
+			stderr="$TMPROOT.stderr"
+			outfile="$TMPROOT.outfile"
+		fi
+
+		if [ "$role" = "cp" -o "$role" = "todc" -o "$role" = "ancp" ]
+		then
+			outused="$outfile"
+		else
+			outused=""
+		fi
+
+		echo "$baseappname: $usefullname ..."
+
+		if [ "$role" = "filter" ]
+		then
+			# grep out unnecessary extra assertion message that has been seen with Apple LLVM version 5.0, which interferes with comparison with previous logs :(
+			if $appname $options <$usefullname $outused 2>&1 >$stdout | fgrep -v 'Assertion failed: (libcompiler_rt abort)' >$stderr
+			then
+				echo "$baseappname:   succeeded"
+				success="true"
+			else
+				echo "$baseappname:   failed ****************************************************"
+				success="false"
+			fi
+		else
+			if $appname $options $usefullname $outused 2>&1 >$stdout | fgrep -v 'Assertion failed: (libcompiler_rt abort)' >$stderr
+			then
+				echo "$baseappname:   succeeded"
+				success="true"
+			else
+				echo "$baseappname:   failed ****************************************************"
+				success="false"
+			fi
+		fi
+
+		if [ "$mode" = "compare" ]
+		then
+			if [ "$role" = "cp" -o "$role" = "todc" -o "$role" = "ancp" ]
+			then
+				if [ -f $testlogdir/$logname.$baseappname.$role.outfile ]
+				then
+					echo "$baseappname:   comparing outfile"
+					if cmp -s $outfile $testlogdir/$logname.$baseappname.$role.outfile
+					then
+						true
+					else
+						echo "$baseappname:     different ****************************************************"
+					fi
+				else
+					echo "$baseappname:     nothing stored  to compare ($outfile)"
+				fi
+			fi
+			if [ -f $testlogdir/$logname.$baseappname.$role.stdout ]
+			then
+				echo "$baseappname:   comparing stdout"
+				#ls -l $stdout
+				if cmp -s $stdout $testlogdir/$logname.$baseappname.$role.stdout
+				#if diff $stdout $testlogdir/$logname.$baseappname.$role.stdout
+				then
+					true
+				else
+					echo "$baseappname:     different ****************************************************"
+				fi
+			else
+				echo "$baseappname:     nothing stored  to compare (stdout)"
+			fi
+			if [ -f $testlogdir/$logname.$baseappname.$role.stderr ]
+			then
+				echo "$baseappname:   comparing stderr"
+				if diff $stderr $testlogdir/$logname.$baseappname.$role.stderr
+				then
+					true
+				else
+					echo "$baseappname:     different ****************************************************"
+				fi
+			else
+				echo "$baseappname:     nothing stored  to compare (stderr)"
+				if [ "$success" = false ]
+				then
+					echo "$baseappname:     stderr was ..."
+					cat $stderr
+				fi
+			fi
+		fi
+		rm -f $TMPROOT.stdout $TMPROOT.stderr $TMPROOT.outfile
+	else
+		echo "No such file as $usefullname" 1>&2
+		exit 1
+	fi
+
+	if [ $rmusefullname = "yes" -a -f $usefullname ]
+	then
+		rm $usefullname
+	fi
+done
diff --git a/support/testapp.SChex0bug b/support/testapp.SChex0bug
new file mode 100755
index 0000000..a70a219
--- /dev/null
+++ b/support/testapp.SChex0bug
@@ -0,0 +1,182 @@
+#!/bin/sh
+
+# Usage: $0 testlist appname options imagedir testlogdir create|compare cp|todc|dump
+
+TMPROOT="/tmp/`basename $0`.$$"
+
+bad="false"
+
+if [ "$#" != 7 ]
+then
+	bad="true"
+else
+	testlist="$1"	# eg. "testlist"
+	appname="$2"	# eg. ./dcdump or ./dccp or ./xxxxdump or ./xxxxtodc
+	options="$3"	# eg. "" or "-v -stamp 9999"
+	imagedir="$4"	# eg. $(TOPDIR)/images/dicom
+	testlogdir="$5"	# eg. $(TOPDIR)/test/$(CURRENT_DIR)
+	mode="$6"	# eg. create|compare
+	role="$7"	# eg. dump|cp|todc
+
+	if [ "$mode" != "create" -a "$mode" != "compare" ]
+	then
+		echo "$0: mode not create or compare" 1>&2
+		bad="true"
+	# ... allow any role ...
+	#elif [ "$role" != "cp" -a "$role" != "todc" -a "$role" != "dump" ]
+	#then
+	#	echo "$0: role not copy or dump" 1>&2
+	#	bad="true"
+	elif [ ! -d "$testlogdir" -a "$mode" = "compare" ]
+	then
+		echo "$0: no such test log directory as \"$testlogdir\"" 1>&2
+		bad="true"
+	elif [ ! -d "$imagedir" ]
+	then
+		echo "$0: no such image directory as \"$imagedir\"" 1>&2
+		bad="true"
+	elif [ ! -f "$imagedir/$testlist" ]
+	then
+			echo "$0: no testlist \"$testlist\" in \"$imagedir\"" 1>&2
+	bad="true"
+	fi
+fi
+
+if [ "$bad" = "true" ]
+then
+	echo "Usage: $0 testlist appname options imagedir testlogdir create|compare cp|todc|dump" 1>&2
+	exit 1
+fi
+
+if [ "$mode" = "create" ]
+then
+	if [ ! -d "$testlogdir" ]
+	then
+		mkdirhier "$testlogdir"
+	fi
+fi
+
+baseappname=`basename $appname`
+
+for filename in `cat $imagedir/$testlist`
+do
+	logname=`echo "$filename" | sed 's:/:.:g'`
+	tmpname="/tmp/`basename $0`.`basename $filename`.$$"
+	usefullname="$imagedir/$filename"
+	rmusefullname="no"
+	if [ ! -f "$usefullname" ]
+	then
+		if [ -f "$usefullname.z" ]
+		then
+			echo "$baseappname: decompressing $usefullname.z ..."
+			zcat $usefullname.z >$tmpname
+			usefullname=$tmpname
+			rmusefullname="yes"
+		elif [ -f "$usefullname.gz" ]
+		then
+			echo "$baseappname: decompressing $usefullname.gz ..."
+			zcat $usefullname.gz >$tmpname
+			usefullname=$tmpname
+			rmusefullname="yes"
+		elif [ -f "$usefullname.Z" ]
+		then
+			echo "$baseappname: decompressing $usefullname.Z ..."
+			zcat $usefullname.Z >$tmpname
+			usefullname=$tmpname
+			rmusefullname="yes"
+		else
+			echo "No such file as $usefullname or compressed variants" 1>&2
+			exit 1
+		fi
+	fi
+
+	if [ -f "$usefullname" ]
+	then
+		if [ "$mode" = "create" ]
+		then
+			stdout="$testlogdir/$logname.$role.stdout"
+			stderr="$testlogdir/$logname.$role.stderr"
+			outfile="$testlogdir/$logname.$role.outfile"
+		else
+			stdout="$TMPROOT.stdout"
+			stderr="$TMPROOT.stderr"
+			outfile="$TMPROOT.outfile"
+		fi
+
+		if [ "$role" = "cp" -o "$role" = "todc" ]
+		then
+			outused="$outfile"
+		else
+			outused=""
+		fi
+
+		echo "$baseappname: $usefullname ..."
+		if $appname $options $usefullname $outused >$stdout 2>$stderr
+		then
+			echo "$baseappname:   succeeded"
+			success="true"
+		else
+			echo "$baseappname:   failed ****************************************************"
+			success="false"
+		fi
+		if [ "$mode" = "compare" ]
+		then
+			if [ "$role" = "cp" -o "$role" = "todc" ]
+			then
+				if [ -f $testlogdir/$logname.$role.outfile ]
+				then
+					echo "$baseappname:   comparing outfile"
+					if cmp -s $outfile $testlogdir/$logname.$role.outfile
+					then
+						true
+					else
+						echo "$baseappname:     different ****************************************************"
+					fi
+				else
+					echo "$baseappname:     nothing stored  to compare ($outfile)"
+				fi
+			fi
+			if [ -f $testlogdir/$logname.$role.stdout ]
+			then
+				echo "$baseappname:   comparing stdout"
+				if diff $stdout $testlogdir/$logname.$role.stdout
+				then
+					true
+				else
+					echo "$baseappname:     different ****************************************************"
+				fi
+			else
+				echo "$baseappname:     nothing stored  to compare (stdout)"
+			fi
+			if [ -f $testlogdir/$logname.$role.stderr ]
+			then
+				echo "$baseappname:   comparing stderr"
+				mv $stderr $stderr.bak
+				sed <$stderr.bak >$stderr -e 's/VL=<00/VL=<0x/g' -e 's/\[00/\[0x/g' -e 's/[(]00/(0x/g' -e 's/,00/,0x/g'
+				rm -f $stderr.bak
+				if diff $stderr $testlogdir/$logname.$role.stderr
+				then
+					true
+				else
+					echo "$baseappname:     different ****************************************************"
+				fi
+			else
+				echo "$baseappname:     nothing stored  to compare (stderr)"
+				if [ "$success" = false ]
+				then
+					echo "$baseappname:     stderr was ..."
+					cat $stderr
+				fi
+			fi
+		fi
+		rm -f $TMPROOT.stdout $TMPROOT.stderr $TMPROOT.outfile
+	else
+		echo "No such file as $usefullname" 1>&2
+		exit 1
+	fi
+
+	if [ $rmusefullname = "yes" -a -f $usefullname ]
+	then
+		rm $usefullname
+	fi
+done
diff --git a/support/updatecopyright b/support/updatecopyright
new file mode 100755
index 0000000..b794f57
--- /dev/null
+++ b/support/updatecopyright
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+# recursively updates all files & directories in current directory
+
+# uses VERSION and COPYRIGHT files if present
+
+# creates or updates a single copyright line, as follows:
+
+# - all header file copyright descriptions
+#   - defined as any C/C++ comment line (/* or //)
+#     containing the word "copyright" followed
+#     by four digits
+
+# - all awk script comments (#)
+#     containing the word "copyright" followed
+#     by four digits
+
+# - all C/C++ programs static CopyrightIdentifier string
+
+# - all man files Copyright string
+
+if [ -f VERSION ]
+then
+	version=`head -1 <VERSION`
+else
+	version="0.00"
+fi
+
+if [ -f COPYRIGHT ]
+then
+	copyright=`head -1 <COPYRIGHT`
+else
+	copyright='Copyright (c) 1993-2015, David A. Clunie DBA PixelMed Publishing. All rights reserved.'
+fi
+
+date=`date +%y/%m/%d`
+
+#idstring="$version $date $copyright"
+idstring="$copyright"
+
+dodirectory() {
+	echo Directory `pwd`
+	for i in $*
+	do
+		if [ -d $i ]
+		then
+			(cd $i; dodirectory *)
+		fi
+	done
+
+	for i in *.h
+	do
+		if [ -f $i ]
+		then
+			echo Updating $i
+			rm -f $i.BAK
+			mv $i $i.BAK
+			echo '/*' "$i $idstring" '*/' >>$i
+			grep -vi \
+			  '^[ 	]*/[*/].*copyright.*[0-9][0-9][0-9[0-9]' \
+				<$i.BAK >>$i
+			if [ -f $i ] ; then rm -f $i.BAK ; fi
+		fi
+	done
+
+	for i in *.awk
+	do
+		if [ -f $i ]
+		then
+			echo Updating $i
+			rm -f $i.BAK
+			mv $i $i.BAK
+			echo '# ' "$i $idstring" >>$i
+			grep -vi \
+			  '^[ 	]*#.*copyright.*[0-9][0-9][0-9[0-9]' \
+				<$i.BAK >>$i
+			if [ -f $i ] ; then rm -f $i.BAK ; fi
+		fi
+	done
+
+	for i in *.c *.cc *.C *.CC *.cp *.cpp
+	do
+		if [ -f $i ]
+		then
+			echo Updating $i
+			rm -f $i.BAK
+			mv $i $i.BAK
+			echo "static const char *CopyrightIdentifier(void) {" \
+				"return \"@(#)$i $idstring\"; }" >>$i
+			grep -v \
+				'^[ 	]*static [a-z ]*char [*]*CopyrightIdentifier' \
+				<$i.BAK >>$i
+			if [ -f $i ] ; then rm -f $i.BAK ; fi
+		fi
+	done
+
+	for i in *.man
+	do
+		if [ -f $i ]
+		then
+			echo Updating $i
+			sed -i "s/^Copyright ([Cc]) [0-9][0-9-]*.*Clunie.*\$/${copyright}/" $i
+		fi
+	done
+}
+
+dodirectory appsrc include libsrc scripts
diff --git a/support/xbmtocbm b/support/xbmtocbm
new file mode 100755
index 0000000..139b4c5
--- /dev/null
+++ b/support/xbmtocbm
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# convention in iconeditor is to use variables names with filename
+# in them which upsets C or CC if there is a period
+
+# also, the use of 0xff and the like in the initializer list upsets
+# compilers that consider this too large an initializer for a char
+# rather than an unsigned char
+
+sed -e 's/[.]xbm/_xbm/g' -e 's/static char/static unsigned char/g' <$1 >$2
diff --git a/support/xxxxto b/support/xxxxto
new file mode 100755
index 0000000..95af02c
--- /dev/null
+++ b/support/xxxxto
@@ -0,0 +1,121 @@
+#!/bin/sh
+
+if [ $# = 1 ]
+then
+	fromprefix="xxxx"
+	toprefix=$1
+	dstsubdir="$1"
+elif [ $# = 3 ]
+then
+	fromprefix="$1"
+	toprefix="$2"
+	dstsubdir="$3"
+else
+	echo "Usage: $0 toprefix | (fromprefix toprefix dstsubdir)"
+	exit 1
+fi
+
+echo "Converting files \"$fromprefix"'*'"\" to \"$toprefix"'*'"\""
+
+LIBSRCDIR="libsrc/src/dconvert/$fromprefix"
+LIBDSTDIR="libsrc/src/dconvert/$dstsubdir"
+APPSRCDIR="appsrc/dconvert/$fromprefix"
+APPDSTDIR="appsrc/dconvert/$dstsubdir"
+
+if [ ! -d "$LIBSRCDIR" ]
+then
+	echo "No source directory \"$LIBSRCDIR\""
+	exit 1;
+fi
+
+if [ ! -d "$APPSRCDIR" ]
+then
+	echo "No source directory \"$APPSRCDIR\""
+	exit 1;
+fi
+
+if [ ! -d "$LIBDSTDIR" ]; then mkdir "$LIBDSTDIR"; fi
+if [ ! -d "$APPDSTDIR" ]; then mkdir "$APPDSTDIR"; fi
+
+toalllower()	# Usage: toalllower src > from
+(
+	echo $1 | tr '[A-Z]' '[a-z]'
+)
+
+toallupper()	# Usage: toallupper src > from
+(
+	echo $1 | tr '[a-z]' '[A-Z]'
+)
+
+tofirstupper()	# Usage: tofirstupper src > from
+(
+	first=`echo $1 | sed 's/\(.\)\(.*\)/\1/' | tr '[a-z]' '[A-Z]'`
+	echo $first`echo $1 | sed 's/\(.\)\(.*\)/\2/'`
+)
+
+LALLFROM="$fromprefix"
+UALLFROM=`toallupper "$fromprefix"`
+UFSTFROM=`tofirstupper "$fromprefix"`
+LALLTO="$toprefix"
+UALLTO=`toallupper "$toprefix"`
+UFSTTO=`tofirstupper "$toprefix"`
+
+echo "Translating \"$LALLFROM\" to \"$LALLTO\""
+echo "Translating \"$UALLFROM\" to \"$UALLTO\""
+echo "Translating \"$UFSTFROM\" to \"$UFSTTO\""
+
+convertit() # srcdir dstdir
+(
+	srcdir="$1"
+	dstdir="$2"
+
+	echo "Converting in $srcdir to $dstdir"
+
+	for i in $srcdir/*
+	do
+		src=`basename $i`
+		if [ "$src" = "Imakefile" ]
+		then
+			echo "Ignoring Imakefile"
+			dst=""
+		elif [ "$src" = "Imakefile.tmpl" ]
+		then
+			echo "Converting Imakefile.tmpl to Imakefile"
+			dst=Imakefile
+		else
+			dst=`echo "$src" | sed "s/^$fromprefix/$toprefix/"`
+		fi
+		if [ -f "$i" -a ! -z "$dst" ]
+		then
+			echo "$i -> $dstdir/$dst"
+			sed <$i >"$dstdir/$dst" \
+				-e "s/$LALLFROM/$LALLTO/g" \
+				-e "s/$UALLFROM/$UALLTO/g" \
+				-e "s/$UFSTFROM/$UFSTTO/g"
+		fi
+	done
+)
+
+convertit $LIBSRCDIR $LIBDSTDIR
+convertit $APPSRCDIR $APPDSTDIR
+
+for f in libsrc/src/dconvert/Imakefile appsrc/dconvert/Imakefile
+do
+	if [ -f "$f" ]
+	then
+		if egrep "^[ 	]*SUBDIRS[ 	]*=.*$dstsubdir" \
+			< "$f" >/dev/null
+		then
+			echo "$f: already contains $dstsubdir in SUBDIRS"
+		else
+			echo "$f: adding $dstsubdir to SUBDIRS"
+			mv -f $f $f.bak
+			sed <$f.bak >$f  \
+				"/^[ 	]*SUBDIRS[ 	]*=/s/=.*/& $dstsubdir/"
+		fi
+	fi
+done
+
+echo
+echo
+echo "Directories and Imakefiles done ... now you need to remake Makefiles"
diff --git a/support/y2kcheck b/support/y2kcheck
new file mode 100755
index 0000000..453d9ca
--- /dev/null
+++ b/support/y2kcheck
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+for d in config libsrc appsrc support
+do
+	for i in `find "$d" -type f -print`
+	do
+		echo $i
+		egrep -ni 'date|year|month|day' $i | grep -vi update | grep -vi validate
+	done
+done

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/dicom3tools.git



More information about the debian-med-commit mailing list